Bug 1383501: Obtain and report the current activation context's manifest path; r=jimm
authorAaron Klotz <aklotz@mozilla.com>
Tue, 19 Sep 2017 14:35:27 -0600
changeset 668864 bcab76b04fbf5e1846bdaa062fcfdd93b5b45a5f
parent 668797 8af47160570c05088128428bae1eb69bf48b0dc4
child 668865 6f63440391b0dc1b0f96628882ea5843bde02bcb
child 669027 4869a0fe4b071e6ea5a91ac99c69454dd175578e
child 669461 7859c2feb54dc88a58a41009f52cff849a64690d
push id81146
push userbmo:topwu.tw@gmail.com
push dateFri, 22 Sep 2017 05:24:51 +0000
reviewersjimm
bugs1383501
milestone58.0a1
Bug 1383501: Obtain and report the current activation context's manifest path; r=jimm MozReview-Commit-ID: HJ1zNoEMzvS
ipc/mscom/ActivationContext.cpp
ipc/mscom/ActivationContext.h
ipc/mscom/ProxyStream.cpp
--- a/ipc/mscom/ActivationContext.cpp
+++ b/ipc/mscom/ActivationContext.cpp
@@ -88,27 +88,91 @@ ActivationContext::Release()
   mActCtx = INVALID_HANDLE_VALUE;
 }
 
 ActivationContext::~ActivationContext()
 {
   Release();
 }
 
+#if defined(MOZILLA_INTERNAL_API)
+
 /* static */ Result<uintptr_t,HRESULT>
 ActivationContext::GetCurrent()
 {
   HANDLE actCtx;
   if (!::GetCurrentActCtx(&actCtx)) {
     return Result<uintptr_t,HRESULT>(HRESULT_FROM_WIN32(::GetLastError()));
   }
 
   return reinterpret_cast<uintptr_t>(actCtx);
 }
 
+/* static */ HRESULT
+ActivationContext::GetCurrentManifestPath(nsAString& aOutManifestPath)
+{
+  aOutManifestPath.Truncate();
+
+  SIZE_T bytesNeeded;
+  BOOL ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
+                           nullptr, ActivationContextDetailedInformation,
+                           nullptr, 0, &bytesNeeded);
+  if (!ok) {
+    DWORD err = ::GetLastError();
+    if (err != ERROR_INSUFFICIENT_BUFFER) {
+      return HRESULT_FROM_WIN32(err);
+    }
+  }
+
+  auto ctxBuf = MakeUnique<BYTE[]>(bytesNeeded);
+
+  ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr, nullptr,
+                      ActivationContextDetailedInformation, ctxBuf.get(),
+                      bytesNeeded, nullptr);
+  if (!ok) {
+    return HRESULT_FROM_WIN32(::GetLastError());
+  }
+
+  auto ctxInfo =
+    reinterpret_cast<ACTIVATION_CONTEXT_DETAILED_INFORMATION*>(ctxBuf.get());
+
+  // assemblyIndex is 1-based, and we want the last index, so we can just copy
+  // ctxInfo->ulAssemblyCount directly.
+  DWORD assemblyIndex = ctxInfo->ulAssemblyCount;
+  ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
+                      &assemblyIndex,
+                      AssemblyDetailedInformationInActivationContext, nullptr,
+                      0, &bytesNeeded);
+  if (!ok) {
+    DWORD err = ::GetLastError();
+    if (err != ERROR_INSUFFICIENT_BUFFER) {
+      return HRESULT_FROM_WIN32(err);
+    }
+  }
+
+  auto assemblyBuf = MakeUnique<BYTE[]>(bytesNeeded);
+
+  ok = ::QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, nullptr,
+                      &assemblyIndex,
+                      AssemblyDetailedInformationInActivationContext,
+                      assemblyBuf.get(), bytesNeeded, &bytesNeeded);
+  if (!ok) {
+    return HRESULT_FROM_WIN32(::GetLastError());
+  }
+
+  auto assemblyInfo =
+    reinterpret_cast<ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION*>(assemblyBuf.get());
+  aOutManifestPath = nsDependentString(assemblyInfo->lpAssemblyManifestPath,
+                                       (assemblyInfo->ulManifestPathLength + 1) / sizeof(wchar_t));
+
+  return S_OK;
+}
+
+#endif // defined(MOZILLA_INTERNAL_API)
+
 ActivationContextRegion::ActivationContextRegion(const ActivationContext& aActCtx)
   : mActCtx(aActCtx)
   , mActCookie(0)
 {
   Activate();
 }
 
 ActivationContextRegion::ActivationContextRegion(ActivationContext&& aActCtx)
--- a/ipc/mscom/ActivationContext.h
+++ b/ipc/mscom/ActivationContext.h
@@ -6,16 +6,20 @@
 
 #ifndef mozilla_mscom_ActivationContext_h
 #define mozilla_mscom_ActivationContext_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/Move.h"
 #include "mozilla/Result.h"
 
+#if defined(MOZILLA_INTERNAL_API)
+#include "nsString.h"
+#endif // defined(MOZILLA_INTERNAL_API)
+
 #include <windows.h>
 
 namespace mozilla {
 namespace mscom {
 
 class ActivationContext final
 {
 public:
@@ -30,17 +34,20 @@ public:
 
   ~ActivationContext();
 
   explicit operator bool() const
   {
     return mActCtx != INVALID_HANDLE_VALUE;
   }
 
+#if defined(MOZILLA_INTERNAL_API)
   static Result<uintptr_t,HRESULT> GetCurrent();
+  static HRESULT GetCurrentManifestPath(nsAString& aOutManifestPath);
+#endif // defined(MOZILLA_INTERNAL_API)
 
 private:
   void Init(ACTCTX& aActCtx);
   void AddRef();
   void Release();
 
 private:
   HANDLE mActCtx;
--- a/ipc/mscom/ProxyStream.cpp
+++ b/ipc/mscom/ProxyStream.cpp
@@ -78,37 +78,40 @@ ProxyStream::ProxyStream(REFIID aIID, co
                                        NS_LITERAL_CSTRING("!mStream"));
 #endif // defined(MOZ_CRASHREPORTER)
     return;
   }
 
 #if defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
   const uint32_t expectedStreamLen = GetOBJREFSize(WrapNotNull(mStream));
   nsAutoCString strActCtx;
+  nsAutoString manifestPath;
 #endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
 
   HRESULT unmarshalResult = S_OK;
 
   // We need to convert to an interface here otherwise we mess up const
   // correctness with IPDL. We'll request an IUnknown and then QI the
   // actual interface later.
 
 #if defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
-  auto marshalFn = [this, &strActCtx, &unmarshalResult, &aIID]() -> void
+  auto marshalFn = [this, &strActCtx, &manifestPath, &unmarshalResult, &aIID]() -> void
 #else
   auto marshalFn = [this, &unmarshalResult, &aIID]() -> void
 #endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
   {
 #if defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
     auto curActCtx = ActivationContext::GetCurrent();
     if (curActCtx.isOk()) {
       strActCtx.AppendPrintf("0x%p", curActCtx.unwrap());
     } else {
       strActCtx.AppendPrintf("HRESULT 0x%08X", curActCtx.unwrapErr());
     }
+
+    ActivationContext::GetCurrentManifestPath(manifestPath);
 #endif // defined(ACCESSIBILITY) && defined(MOZ_CRASHREPORTER)
 
     unmarshalResult =
       ::CoUnmarshalInterface(mStream, aIID, getter_AddRefs(mUnmarshaledProxy));
     MOZ_ASSERT(SUCCEEDED(unmarshalResult));
   };
 
   if (XRE_IsParentProcess()) {
@@ -132,16 +135,18 @@ ProxyStream::ProxyStream(REFIID aIID, co
       CrashReporter::AnnotateCrashReport(kCrashReportKey,
                                          NS_LITERAL_CSTRING("!mUnmarshaledProxy"));
     }
 
 #if defined(ACCESSIBILITY)
     AnnotateClassRegistration(CLSID_AccessibleHandler);
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtx"),
                                        strActCtx);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtxManifestPath"),
+                                       NS_ConvertUTF16toUTF8(manifestPath));
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("A11yHandlerRegistered"),
                                        a11y::IsHandlerRegistered() ?
                                        NS_LITERAL_CSTRING("true") :
                                        NS_LITERAL_CSTRING("false"));
 
     nsAutoCString strExpectedStreamLen;
     strExpectedStreamLen.AppendInt(expectedStreamLen);
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ExpectedStreamLen"),
@@ -280,23 +285,38 @@ ProxyStream::ProxyStream(REFIID aIID, IU
   int streamSize = 0;
   DWORD mshlFlags = mPreserveStream ? MSHLFLAGS_TABLESTRONG : MSHLFLAGS_NORMAL;
 
   HRESULT createStreamResult = S_OK;
   HRESULT marshalResult = S_OK;
   HRESULT statResult = S_OK;
   HRESULT getHGlobalResult = S_OK;
 
-  auto marshalFn = [&]() -> void
+#if defined(MOZ_CRASHREPORTER)
+  nsAutoString manifestPath;
+
+  auto marshalFn = [this, &aIID, aObject, mshlFlags, &stream, &streamSize,
+                    &hglobal, &createStreamResult, &marshalResult, &statResult,
+                    &getHGlobalResult, &manifestPath]() -> void
+#else
+  auto marshalFn = [this, &aIID, aObject, mshlFlags, &stream, &streamSize,
+                    &hglobal, &createStreamResult, &marshalResult, &statResult,
+                    &getHGlobalResult]() -> void
+#endif // defined(MOZ_CRASHREPORTER)
   {
-    createStreamResult = ::CreateStreamOnHGlobal(nullptr, TRUE, getter_AddRefs(stream));
+    createStreamResult = ::CreateStreamOnHGlobal(nullptr, TRUE,
+                                                 getter_AddRefs(stream));
     if (FAILED(createStreamResult)) {
       return;
     }
 
+#if defined(MOZ_CRASHREPORTER)
+    ActivationContext::GetCurrentManifestPath(manifestPath);
+#endif // defined(MOZ_CRASHREPORTER)
+
     marshalResult = ::CoMarshalInterface(stream, aIID, aObject, MSHCTX_LOCAL,
                                          nullptr, mshlFlags);
     MOZ_DIAGNOSTIC_ASSERT(marshalResult != E_INVALIDARG);
     if (FAILED(marshalResult)) {
       return;
     }
 
     STATSTG statstg;
@@ -328,16 +348,18 @@ ProxyStream::ProxyStream(REFIID aIID, IU
         hrAsStr);
   }
 
   if (FAILED(marshalResult)) {
     AnnotateInterfaceRegistration(aIID);
     nsPrintfCString hrAsStr("0x%08X", marshalResult);
     CrashReporter::AnnotateCrashReport(
         NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"),
+                                       NS_ConvertUTF16toUTF8(manifestPath));
   }
 
   if (FAILED(statResult)) {
     nsPrintfCString hrAsStr("0x%08X", statResult);
     CrashReporter::AnnotateCrashReport(
         NS_LITERAL_CSTRING("StatFailure"),
         hrAsStr);
   }