зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1354077: Annotate crash reports with COM interface configuration information when marshaling fails; r=jimm
MozReview-Commit-ID: GCYLbtu1Nlb --HG-- extra : rebase_source : 565c598dcba929cb1b774b3440180c60e78da9cd extra : amend_source : dc0051579e0b005c89fd3835f0c2b0d4fd87a280
This commit is contained in:
Родитель
c220978a34
Коммит
d82e0194e8
|
@ -0,0 +1,362 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "InterfaceRegistrationAnnotator.h"
|
||||
|
||||
#include "mozilla/JSONWriter.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#include <oleauto.h>
|
||||
|
||||
namespace {
|
||||
|
||||
class CStringWriter final : public mozilla::JSONWriteFunc
|
||||
{
|
||||
public:
|
||||
void Write(const char* aStr) override
|
||||
{
|
||||
mBuf += aStr;
|
||||
}
|
||||
|
||||
const nsCString& Get() const
|
||||
{
|
||||
return mBuf;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString mBuf;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
static const char16_t kSoftwareClasses[] = u"SOFTWARE\\Classes";
|
||||
static const char16_t kInterface[] = u"\\Interface\\";
|
||||
static const char16_t kDefaultValue[] = u"";
|
||||
static const char16_t kThreadingModel[] = u"ThreadingModel";
|
||||
static const char16_t kBackslash[] = u"\\";
|
||||
static const char16_t kFlags[] = u"FLAGS";
|
||||
static const char16_t kProxyStubClsid32[] = u"\\ProxyStubClsid32";
|
||||
static const char16_t kClsid[] = u"\\CLSID\\";
|
||||
static const char16_t kInprocServer32[] = u"\\InprocServer32";
|
||||
static const char16_t kTypeLib[] = u"\\TypeLib";
|
||||
static const char16_t kVersion[] = u"Version";
|
||||
static const char16_t kWin32[] = u"Win32";
|
||||
static const char16_t kWin64[] = u"Win64";
|
||||
|
||||
template <size_t N>
|
||||
inline static bool
|
||||
GetStringValue(HKEY aBaseKey, const nsAString& aStrSubKey,
|
||||
const char16_t (&aValueName)[N], nsAString& aOutput)
|
||||
{
|
||||
return GetStringValue(aBaseKey, aStrSubKey,
|
||||
nsLiteralString(aValueName),
|
||||
aOutput);
|
||||
}
|
||||
|
||||
static bool
|
||||
GetStringValue(HKEY aBaseKey, const nsAString& aStrSubKey,
|
||||
const nsAString& aValueName, nsAString& aOutput)
|
||||
{
|
||||
const nsString& flatSubKey = PromiseFlatString(aStrSubKey);
|
||||
const nsString& flatValueName = PromiseFlatString(aValueName);
|
||||
LPCWSTR valueName = aValueName.IsEmpty() ? nullptr : flatValueName.get();
|
||||
|
||||
DWORD numBytes = 0;
|
||||
LONG result = RegGetValue(aBaseKey, flatSubKey.get(), valueName,
|
||||
RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ, nullptr,
|
||||
nullptr, &numBytes);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int numChars = (numBytes + 1) / sizeof(wchar_t);
|
||||
aOutput.SetLength(numChars);
|
||||
|
||||
result = RegGetValue(aBaseKey, flatSubKey.get(), valueName,
|
||||
RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ,
|
||||
nullptr, aOutput.BeginWriting(), &numBytes);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
// Truncate null terminator
|
||||
aOutput.SetLength(((numBytes + 1) / sizeof(wchar_t)) - 1);
|
||||
}
|
||||
|
||||
return result == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fails unless the entire string has been converted.
|
||||
* (eg, the string "FLAGS" will convert to 0xF but we will return false)
|
||||
*/
|
||||
static bool
|
||||
ConvertLCID(const wchar_t* aStr, NotNull<unsigned long*> aOutLcid)
|
||||
{
|
||||
wchar_t* endChar;
|
||||
*aOutLcid = wcstoul(aStr, &endChar, 16);
|
||||
return *endChar == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetLoadedPath(nsAString& aPath)
|
||||
{
|
||||
// These paths may be REG_EXPAND_SZ, so we expand any environment strings
|
||||
DWORD bufCharLen = ExpandEnvironmentStrings(PromiseFlatString(aPath).get(),
|
||||
nullptr, 0);
|
||||
|
||||
auto buf = MakeUnique<WCHAR[]>(bufCharLen);
|
||||
|
||||
if (!ExpandEnvironmentStrings(PromiseFlatString(aPath).get(), buf.get(),
|
||||
bufCharLen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use LoadLibrary so that the DLL is resolved using the loader's DLL search
|
||||
// rules
|
||||
nsModuleHandle mod(LoadLibrary(buf.get()));
|
||||
if (!mod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WCHAR finalPath[MAX_PATH + 1] = {};
|
||||
DWORD result = GetModuleFileNameW(mod, finalPath, ArrayLength(finalPath));
|
||||
if (!result || (result == ArrayLength(finalPath) &&
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aPath = nsDependentString(finalPath, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
AnnotateClsidRegistrationForHive(JSONWriter& aJson, HKEY aHive,
|
||||
const nsAString& aClsid,
|
||||
const JSONWriter::CollectionStyle aStyle)
|
||||
{
|
||||
nsAutoString clsidSubkey;
|
||||
clsidSubkey.AppendLiteral(kSoftwareClasses);
|
||||
clsidSubkey.AppendLiteral(kClsid);
|
||||
clsidSubkey.Append(aClsid);
|
||||
|
||||
nsAutoString className;
|
||||
if (GetStringValue(aHive, clsidSubkey, kDefaultValue, className)) {
|
||||
aJson.StringProperty("ClassName",
|
||||
NS_ConvertUTF16toUTF8(className).get());
|
||||
}
|
||||
|
||||
nsAutoString inprocServerSubkey(clsidSubkey);
|
||||
inprocServerSubkey.AppendLiteral(kInprocServer32);
|
||||
|
||||
nsAutoString pathToServerDll;
|
||||
if (GetStringValue(aHive, inprocServerSubkey, kDefaultValue, pathToServerDll)) {
|
||||
aJson.StringProperty("Path", NS_ConvertUTF16toUTF8(pathToServerDll).get());
|
||||
if (GetLoadedPath(pathToServerDll)) {
|
||||
aJson.StringProperty("LoadedPath",
|
||||
NS_ConvertUTF16toUTF8(pathToServerDll).get());
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString apartment;
|
||||
if (GetStringValue(aHive, inprocServerSubkey, kThreadingModel, apartment)) {
|
||||
aJson.StringProperty("ThreadingModel", NS_ConvertUTF16toUTF8(apartment).get());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CheckTlbPath(JSONWriter& aJson, const nsAString& aTypelibPath)
|
||||
{
|
||||
const nsString& flatPath = PromiseFlatString(aTypelibPath);
|
||||
DWORD bufCharLen = ExpandEnvironmentStrings(flatPath.get(), nullptr, 0);
|
||||
|
||||
auto buf = MakeUnique<WCHAR[]>(bufCharLen);
|
||||
|
||||
if (!ExpandEnvironmentStrings(flatPath.get(), buf.get(), bufCharLen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// See whether this tlb can actually be loaded
|
||||
RefPtr<ITypeLib> typeLib;
|
||||
HRESULT hr = LoadTypeLibEx(buf.get(), REGKIND_NONE, getter_AddRefs(typeLib));
|
||||
|
||||
nsPrintfCString loadResult("0x%08X", hr);
|
||||
aJson.StringProperty("LoadResult", loadResult.get());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static void
|
||||
AnnotateTypelibPlatform(JSONWriter& aJson, HKEY aBaseKey,
|
||||
const nsAString& aLcidSubkey,
|
||||
const char16_t (&aPlatform)[N],
|
||||
const JSONWriter::CollectionStyle aStyle)
|
||||
{
|
||||
nsLiteralString platform(aPlatform);
|
||||
|
||||
nsAutoString fullSubkey(aLcidSubkey);
|
||||
fullSubkey.AppendLiteral(kBackslash);
|
||||
fullSubkey.Append(platform);
|
||||
|
||||
nsAutoString tlbPath;
|
||||
if (GetStringValue(aBaseKey, fullSubkey, kDefaultValue, tlbPath)) {
|
||||
aJson.StartObjectProperty(NS_ConvertUTF16toUTF8(platform).get(), aStyle);
|
||||
aJson.StringProperty("Path", NS_ConvertUTF16toUTF8(tlbPath).get());
|
||||
CheckTlbPath(aJson, tlbPath);
|
||||
aJson.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AnnotateTypelibRegistrationForHive(JSONWriter& aJson, HKEY aHive,
|
||||
const nsAString& aTypelibId,
|
||||
const nsAString& aTypelibVersion,
|
||||
const JSONWriter::CollectionStyle aStyle)
|
||||
{
|
||||
nsAutoString typelibSubKey;
|
||||
typelibSubKey.AppendLiteral(kSoftwareClasses);
|
||||
typelibSubKey.AppendLiteral(kTypeLib);
|
||||
typelibSubKey.AppendLiteral(kBackslash);
|
||||
typelibSubKey.Append(aTypelibId);
|
||||
typelibSubKey.AppendLiteral(kBackslash);
|
||||
typelibSubKey.Append(aTypelibVersion);
|
||||
|
||||
nsAutoString typelibDesc;
|
||||
if (GetStringValue(aHive, typelibSubKey, kDefaultValue, typelibDesc)) {
|
||||
aJson.StringProperty("Description",
|
||||
NS_ConvertUTF16toUTF8(typelibDesc).get());
|
||||
}
|
||||
|
||||
nsAutoString flagsSubKey(typelibSubKey);
|
||||
flagsSubKey.AppendLiteral(kBackslash);
|
||||
flagsSubKey.AppendLiteral(kFlags);
|
||||
|
||||
nsAutoString typelibFlags;
|
||||
if (GetStringValue(aHive, flagsSubKey, kDefaultValue, typelibFlags)) {
|
||||
aJson.StringProperty("Flags", NS_ConvertUTF16toUTF8(typelibFlags).get());
|
||||
}
|
||||
|
||||
HKEY rawTypelibKey;
|
||||
LONG result = RegOpenKeyEx(aHive, typelibSubKey.get(), 0, KEY_READ,
|
||||
&rawTypelibKey);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
nsAutoRegKey typelibKey(rawTypelibKey);
|
||||
|
||||
const size_t kMaxLcidCharLen = 9;
|
||||
WCHAR keyName[kMaxLcidCharLen];
|
||||
|
||||
for (DWORD index = 0; result == ERROR_SUCCESS; ++index) {
|
||||
DWORD keyNameLength = ArrayLength(keyName);
|
||||
result = RegEnumKeyEx(typelibKey, index, keyName, &keyNameLength, nullptr,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
unsigned long lcid;
|
||||
if (result == ERROR_SUCCESS && ConvertLCID(keyName, WrapNotNull(&lcid))) {
|
||||
nsDependentString strLcid(keyName, keyNameLength);
|
||||
aJson.StartObjectProperty(NS_ConvertUTF16toUTF8(strLcid).get(), aStyle);
|
||||
AnnotateTypelibPlatform(aJson, typelibKey, strLcid, kWin32, aStyle);
|
||||
#if defined(HAVE_64BIT_BUILD)
|
||||
AnnotateTypelibPlatform(aJson, typelibKey, strLcid, kWin64, aStyle);
|
||||
#endif
|
||||
aJson.EndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AnnotateInterfaceRegistrationForHive(JSONWriter& aJson, HKEY aHive, REFIID aIid,
|
||||
const JSONWriter::CollectionStyle aStyle)
|
||||
{
|
||||
nsAutoString interfaceSubKey;
|
||||
interfaceSubKey.AppendLiteral(kSoftwareClasses);
|
||||
interfaceSubKey.AppendLiteral(kInterface);
|
||||
nsAutoString iid;
|
||||
GUIDToString(aIid, iid);
|
||||
interfaceSubKey.Append(iid);
|
||||
|
||||
nsAutoString interfaceName;
|
||||
if (GetStringValue(aHive, interfaceSubKey, kDefaultValue, interfaceName)) {
|
||||
aJson.StringProperty("InterfaceName",
|
||||
NS_ConvertUTF16toUTF8(interfaceName).get());
|
||||
}
|
||||
|
||||
nsAutoString psSubKey(interfaceSubKey);
|
||||
psSubKey.AppendLiteral(kProxyStubClsid32);
|
||||
|
||||
nsAutoString psClsid;
|
||||
if (GetStringValue(aHive, psSubKey, kDefaultValue, psClsid)) {
|
||||
aJson.StartObjectProperty("ProxyStub", aStyle);
|
||||
aJson.StringProperty("CLSID", NS_ConvertUTF16toUTF8(psClsid).get());
|
||||
AnnotateClsidRegistrationForHive(aJson, aHive, psClsid, aStyle);
|
||||
aJson.EndObject();
|
||||
}
|
||||
|
||||
nsAutoString typelibSubKey(interfaceSubKey);
|
||||
typelibSubKey.AppendLiteral(kTypeLib);
|
||||
|
||||
nsAutoString typelibId;
|
||||
bool haveTypelibId = GetStringValue(aHive, typelibSubKey, kDefaultValue,
|
||||
typelibId);
|
||||
|
||||
nsAutoString typelibVersion;
|
||||
bool haveTypelibVersion = GetStringValue(aHive, typelibSubKey, kVersion,
|
||||
typelibVersion);
|
||||
|
||||
if (haveTypelibId || haveTypelibVersion) {
|
||||
aJson.StartObjectProperty("TypeLib", aStyle);
|
||||
}
|
||||
|
||||
if (haveTypelibId) {
|
||||
aJson.StringProperty("ID", NS_ConvertUTF16toUTF8(typelibId).get());
|
||||
}
|
||||
|
||||
if (haveTypelibVersion) {
|
||||
aJson.StringProperty("Version", NS_ConvertUTF16toUTF8(typelibVersion).get());
|
||||
}
|
||||
|
||||
if (haveTypelibId && haveTypelibVersion) {
|
||||
AnnotateTypelibRegistrationForHive(aJson, aHive, typelibId, typelibVersion,
|
||||
aStyle);
|
||||
}
|
||||
|
||||
if (haveTypelibId || haveTypelibVersion) {
|
||||
aJson.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AnnotateInterfaceRegistration(REFIID aIid)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
const JSONWriter::CollectionStyle style = JSONWriter::MultiLineStyle;
|
||||
#else
|
||||
const JSONWriter::CollectionStyle style = JSONWriter::SingleLineStyle;
|
||||
#endif
|
||||
|
||||
JSONWriter json(MakeUnique<CStringWriter>());
|
||||
|
||||
json.Start(style);
|
||||
|
||||
json.StartObjectProperty("HKLM", style);
|
||||
AnnotateInterfaceRegistrationForHive(json, HKEY_LOCAL_MACHINE, aIid, style);
|
||||
json.EndObject();
|
||||
|
||||
json.StartObjectProperty("HKCU", style);
|
||||
AnnotateInterfaceRegistrationForHive(json, HKEY_CURRENT_USER, aIid, style);
|
||||
json.EndObject();
|
||||
|
||||
json.End();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("InterfaceRegistrationInfo"),
|
||||
static_cast<CStringWriter*>(json.WriteFunc())->Get());
|
||||
}
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_mscom_InterfaceRegistrationAnnotator_h
|
||||
#define mozilla_mscom_InterfaceRegistrationAnnotator_h
|
||||
|
||||
#if !defined(MOZ_CRASHREPORTER)
|
||||
#error "This header requires crash reporting to be enabled"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
void AnnotateInterfaceRegistration(REFIID aIid);
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_mscom_InterfaceRegistrationAnnotator_h
|
|
@ -10,7 +10,8 @@
|
|||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
#include "InterfaceRegistrationAnnotator.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#endif
|
||||
|
@ -36,6 +37,7 @@ ProxyStream::ProxyStream(const BYTE* aInitBuf, const int aInitBufSize)
|
|||
, mGlobalLockedBuf(nullptr)
|
||||
, mHGlobal(nullptr)
|
||||
, mBufSize(aInitBufSize)
|
||||
, mUnmarshalResult(E_UNEXPECTED)
|
||||
{
|
||||
if (!aInitBufSize) {
|
||||
// We marshaled a nullptr. Nothing else to do here.
|
||||
|
@ -49,8 +51,6 @@ ProxyStream::ProxyStream(const BYTE* aInitBuf, const int aInitBufSize)
|
|||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -59,10 +59,10 @@ ProxyStream::ProxyStream(const BYTE* aInitBuf, const int aInitBufSize)
|
|||
{
|
||||
// OK to forget mStream when calling into this function because the stream
|
||||
// gets released even if the unmarshaling part fails.
|
||||
unmarshalResult =
|
||||
mUnmarshalResult =
|
||||
::CoGetInterfaceAndReleaseStream(mStream.forget().take(), IID_IUnknown,
|
||||
getter_AddRefs(mUnmarshaledProxy));
|
||||
MOZ_ASSERT(SUCCEEDED(unmarshalResult));
|
||||
MOZ_ASSERT(SUCCEEDED(mUnmarshalResult));
|
||||
};
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
|
@ -75,8 +75,8 @@ ProxyStream::ProxyStream(const BYTE* aInitBuf, const int aInitBufSize)
|
|||
}
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
if (FAILED(unmarshalResult)) {
|
||||
nsPrintfCString hrAsStr("0x%08X", unmarshalResult);
|
||||
if (FAILED(mUnmarshalResult)) {
|
||||
nsPrintfCString hrAsStr("0x%08X", mUnmarshalResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("CoGetInterfaceAndReleaseStreamFailure"), hrAsStr);
|
||||
}
|
||||
|
@ -197,6 +197,12 @@ ProxyStream::GetInterface(REFIID aIID, void** aOutInterface) const
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
if (FAILED(mUnmarshalResult)) {
|
||||
AnnotateInterfaceRegistration(aIID);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mUnmarshaledProxy) {
|
||||
*aOutInterface = nullptr;
|
||||
return true;
|
||||
|
@ -269,6 +275,7 @@ ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject)
|
|||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
if (FAILED(marshalResult)) {
|
||||
AnnotateInterfaceRegistration(aIID);
|
||||
nsPrintfCString hrAsStr("0x%08X", marshalResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
|
||||
|
|
|
@ -55,6 +55,7 @@ private:
|
|||
HGLOBAL mHGlobal;
|
||||
int mBufSize;
|
||||
ProxyUniquePtr<IUnknown> mUnmarshaledProxy;
|
||||
HRESULT mUnmarshalResult;
|
||||
};
|
||||
|
||||
} // namespace mscom
|
||||
|
|
|
@ -74,7 +74,27 @@ IsValidGUID(REFGUID aCheckGuid)
|
|||
return version == 1 || version == 4;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
void
|
||||
GUIDToString(REFGUID aGuid, nsAString& aOutString)
|
||||
{
|
||||
// This buffer length is long enough to hold a GUID string that is formatted
|
||||
// to include curly braces and dashes.
|
||||
const int kBufLenWithNul = 39;
|
||||
aOutString.SetLength(kBufLenWithNul);
|
||||
int result = StringFromGUID2(aGuid, wwc(aOutString.BeginWriting()), kBufLenWithNul);
|
||||
MOZ_ASSERT(result);
|
||||
if (result) {
|
||||
// Truncate the terminator
|
||||
aOutString.SetLength(result - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
|
||||
static bool
|
||||
IsVtableIndexFromParentInterface(TYPEATTR* aTypeAttr,
|
||||
unsigned long aVtableIndex)
|
||||
|
@ -202,7 +222,8 @@ IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
|
|||
|
||||
return false;
|
||||
}
|
||||
#endif // ifdef ACCESSIBILITY
|
||||
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
#ifndef mozilla_mscom_Utils_h
|
||||
#define mozilla_mscom_Utils_h
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#include "nsString.h"
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
#include <guiddef.h>
|
||||
#endif
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
struct IUnknown;
|
||||
|
||||
|
@ -20,12 +24,16 @@ bool IsCurrentThreadMTA();
|
|||
bool IsProxy(IUnknown* aUnknown);
|
||||
bool IsValidGUID(REFGUID aCheckGuid);
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
void GUIDToString(REFGUID aGuid, nsAString& aOutString);
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
bool IsVtableIndexFromParentInterface(REFIID aInterface,
|
||||
unsigned long aVtableIndex);
|
||||
bool IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
|
||||
unsigned long aVtableIndexHint);
|
||||
#endif
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -25,6 +25,11 @@ UNIFIED_SOURCES += [
|
|||
'Utils.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_CRASHREPORTER']:
|
||||
UNIFIED_SOURCES += [
|
||||
'InterfaceRegistrationAnnotator.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ACCESSIBILITY']:
|
||||
DIRS += [
|
||||
'oop',
|
||||
|
|
Загрузка…
Ссылка в новой задаче