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 433117 bcab76b04fbf5e1846bdaa062fcfdd93b5b45a5f
parent 433116 8af47160570c05088128428bae1eb69bf48b0dc4
child 433118 6f63440391b0dc1b0f96628882ea5843bde02bcb
push id8114
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 16:33:21 +0000
treeherdermozilla-beta@73e0d89a540f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1383501
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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);
   }