Bug 1714212 - Ensure COM initialized prior to showing skeleton UI r=Jamie,aklotz,tkikuchi

This implements Jamie's suggested fixes for a screenreader issue when the
skeleton UI is enabled. Most of the work here is just pulling out pieces from the
files we needed to include in mozglue so that any references to, say, nsString
or other pieces from libxul either no longer exist or are only included when
building libxul. In a few cases this meant creating whole files to house single
functions, which isn't so pretty, but it was the best I could come up with to
get the job done.

Differential Revision: https://phabricator.services.mozilla.com/D117663
This commit is contained in:
Doug Thayer 2021-06-26 04:10:50 +00:00
Родитель 31bbc107fb
Коммит c3702a9447
31 изменённых файлов: 582 добавлений и 344 удалений

Просмотреть файл

@ -8,7 +8,7 @@
#define mozilla_a11y_COMPtrTypes_h
#include "mozilla/a11y/AccessibleHandler.h"
#include "mozilla/a11y/Compatibility.h"
#include "mozilla/mscom/ActCtxResource.h"
#include "mozilla/Attributes.h"
#include "mozilla/mscom/ActivationContext.h"
#include "mozilla/mscom/COMPtrHolder.h"
@ -33,7 +33,7 @@ class MOZ_RAII IAccessibleEnvironment : public mscom::ProxyStream::Environment {
private:
static const mscom::ActivationContext& GetActCtx() {
static const mscom::ActivationContext sActCtx(
Compatibility::GetActCtxResourceId());
mscom::ActCtxResource::GetAccessibilityResource());
MOZ_DIAGNOSTIC_ASSERT(sActCtx);
return sActCtx;
}

Просмотреть файл

@ -5,8 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/a11y/AccessibleHandler.h"
#include "mozilla/a11y/Compatibility.h"
#include "mozilla/a11y/PlatformChild.h"
#include "mozilla/mscom/ActCtxResource.h"
#include "mozilla/mscom/EnsureMTA.h"
#include "mozilla/mscom/InterceptorLog.h"
@ -56,13 +56,13 @@ PlatformChild::PlatformChild()
mozilla::mscom::RegistrationFlags::eUseSystemDirectory)),
mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb")),
mSdnTypelib(mozilla::mscom::RegisterTypelib(L"AccessibleMarshal.dll")) {
WORD actCtxResourceId = Compatibility::GetActCtxResourceId();
auto actCtxResource = mscom::ActCtxResource::GetAccessibilityResource();
mozilla::mscom::MTADeletePtr<mozilla::mscom::ActivationContextRegion>
tmpActCtxMTA;
mozilla::mscom::EnsureMTA([actCtxResourceId, &tmpActCtxMTA]() -> void {
mozilla::mscom::EnsureMTA([actCtxResource, &tmpActCtxMTA]() -> void {
tmpActCtxMTA.reset(
new mozilla::mscom::ActivationContextRegion(actCtxResourceId));
new mozilla::mscom::ActivationContextRegion(actCtxResource));
});
mActCtxMTA = std::move(tmpActCtxMTA);

Просмотреть файл

@ -13,15 +13,6 @@ if CONFIG["COMPILE_ENVIRONMENT"] and CONFIG["ACCESSIBILITY"]:
if CONFIG["ACCESSIBILITY"]:
IPDL_SOURCES += ["PDocAccessible.ipdl"]
if not CONFIG["HAVE_64BIT_BUILD"]:
EXPORTS += [
"IAccessible32.manifest",
]
EXPORTS += [
"IAccessible64.manifest",
]
EXPORTS.mozilla.a11y += [
"COMPtrTypes.h",
"DocAccessibleChild.h",

Просмотреть файл

@ -225,175 +225,6 @@ void Compatibility::Init() {
}
}
#if !defined(HAVE_64BIT_BUILD)
static bool ReadCOMRegDefaultString(const nsString& aRegPath,
nsAString& aOutBuf) {
aOutBuf.Truncate();
nsAutoString fullyQualifiedRegPath;
fullyQualifiedRegPath.AppendLiteral(u"SOFTWARE\\Classes\\");
fullyQualifiedRegPath.Append(aRegPath);
// Get the required size and type of the registry value.
// We expect either REG_SZ or REG_EXPAND_SZ.
DWORD type;
DWORD bufLen = 0;
LONG result = ::RegGetValue(HKEY_LOCAL_MACHINE, fullyQualifiedRegPath.get(),
nullptr, RRF_RT_ANY, &type, nullptr, &bufLen);
if (result != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
return false;
}
// Now obtain the value
DWORD flags = type == REG_SZ ? RRF_RT_REG_SZ : RRF_RT_REG_EXPAND_SZ;
aOutBuf.SetLength((bufLen + 1) / sizeof(char16_t));
result =
::RegGetValue(HKEY_LOCAL_MACHINE, fullyQualifiedRegPath.get(), nullptr,
flags, nullptr, aOutBuf.BeginWriting(), &bufLen);
if (result != ERROR_SUCCESS) {
aOutBuf.Truncate();
return false;
}
// Truncate terminator
aOutBuf.Truncate((bufLen + 1) / sizeof(char16_t) - 1);
return true;
}
static bool IsSystemOleAcc(nsCOMPtr<nsIFile>& aFile) {
// Use FOLDERID_SystemX86 so that Windows doesn't give us a redirected
// system32 if we're a 32-bit process running on a 64-bit OS. This is
// necessary because the values that we are reading from the registry
// are not redirected; they reference SysWOW64 directly.
PWSTR systemPath = nullptr;
HRESULT hr =
::SHGetKnownFolderPath(FOLDERID_SystemX86, 0, nullptr, &systemPath);
if (FAILED(hr)) {
return false;
}
nsCOMPtr<nsIFile> oleAcc;
nsresult rv = NS_NewLocalFile(nsDependentString(systemPath), false,
getter_AddRefs(oleAcc));
::CoTaskMemFree(systemPath);
systemPath = nullptr;
if (NS_FAILED(rv)) {
return false;
}
rv = oleAcc->Append(u"oleacc.dll"_ns);
if (NS_FAILED(rv)) {
return false;
}
bool isEqual;
rv = oleAcc->Equals(aFile, &isEqual);
return NS_SUCCEEDED(rv) && isEqual;
}
static bool IsTypelibPreferred() {
// If IAccessible's Proxy/Stub CLSID is kUniversalMarshalerClsid, then any
// external a11y clients are expecting to use a typelib.
constexpr auto kUniversalMarshalerClsid =
u"{00020424-0000-0000-C000-000000000046}"_ns;
constexpr auto kIAccessiblePSClsidPath =
"Interface\\{618736E0-3C3D-11CF-810C-00AA00389B71}"
u"\\ProxyStubClsid32"_ns;
nsAutoString psClsid;
if (!ReadCOMRegDefaultString(kIAccessiblePSClsidPath, psClsid)) {
return false;
}
return psClsid.Equals(kUniversalMarshalerClsid,
nsCaseInsensitiveStringComparator);
}
static bool IsIAccessibleTypelibRegistered() {
// The system default IAccessible typelib is always registered with version
// 1.1, under the neutral locale (LCID 0).
constexpr auto kIAccessibleTypelibRegPath =
u"TypeLib\\{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}\\1.1\\0\\win32"_ns;
nsAutoString typelibPath;
if (!ReadCOMRegDefaultString(kIAccessibleTypelibRegPath, typelibPath)) {
return false;
}
nsCOMPtr<nsIFile> libTestFile;
nsresult rv =
NS_NewLocalFile(typelibPath, false, getter_AddRefs(libTestFile));
if (NS_FAILED(rv)) {
return false;
}
return IsSystemOleAcc(libTestFile);
}
static bool IsIAccessiblePSRegistered() {
constexpr auto kIAccessiblePSRegPath =
u"CLSID\\{03022430-ABC4-11D0-BDE2-00AA001A1953}\\InProcServer32"_ns;
nsAutoString proxyStubPath;
if (!ReadCOMRegDefaultString(kIAccessiblePSRegPath, proxyStubPath)) {
return false;
}
nsCOMPtr<nsIFile> libTestFile;
nsresult rv =
NS_NewLocalFile(proxyStubPath, false, getter_AddRefs(libTestFile));
if (NS_FAILED(rv)) {
return false;
}
return IsSystemOleAcc(libTestFile);
}
static bool UseIAccessibleProxyStub() {
// If a typelib is preferred then external clients are expecting to use
// typelib marshaling, so we should use that whenever available.
if (IsTypelibPreferred() && IsIAccessibleTypelibRegistered()) {
return false;
}
// Otherwise we try the proxy/stub
if (IsIAccessiblePSRegistered()) {
return true;
}
// If we reach this point then something is seriously wrong with the
// IAccessible configuration in the computer's registry. Let's annotate this
// so that we can easily determine this condition during crash analysis.
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::IAccessibleConfig, "NoSystemTypeLibOrPS"_ns);
return false;
}
#endif // !defined(HAVE_64BIT_BUILD)
uint16_t Compatibility::GetActCtxResourceId() {
#if defined(HAVE_64BIT_BUILD)
// The manifest for 64-bit Windows is embedded with resource ID 64.
return 64;
#else
// The manifest for 32-bit Windows is embedded with resource ID 32.
// Beginning with Windows 10 Creators Update, 32-bit builds always use the
// 64-bit manifest. Older builds of Windows may or may not require the 64-bit
// manifest: UseIAccessibleProxyStub() determines the course of action.
if (mozilla::IsWin10CreatorsUpdateOrLater() || UseIAccessibleProxyStub()) {
return 64;
}
return 32;
#endif // defined(HAVE_64BIT_BUILD)
}
// static
void Compatibility::GetHumanReadableConsumersStr(nsAString& aResult) {
bool appened = false;

Просмотреть файл

@ -9,7 +9,6 @@
#include <windows.h>
#include "mozilla/Maybe.h"
#include "nsString.h"
#include <stdint.h>
namespace mozilla {
@ -48,12 +47,6 @@ class Compatibility {
*/
static bool IsVisperoShared() { return !!(sConsumers & VISPEROSHARED); }
/**
* @return ID of a11y manifest resource to be passed to
* mscom::ActivationContext
*/
static uint16_t GetActCtxResourceId();
/**
* Return a string describing sConsumers suitable for about:support.
* Exposed through nsIXULRuntime.accessibilityInstantiator.

Просмотреть файл

@ -12,7 +12,6 @@
#if defined(XP_WIN)
# include <windows.h>
# include <stdlib.h>
# include "mozilla/PreXULSkeletonUI.h"
#elif defined(XP_UNIX)
# include <sys/resource.h>
# include <unistd.h>
@ -25,6 +24,7 @@
#include "nsCOMPtr.h"
#ifdef XP_WIN
# include "mozilla/PreXULSkeletonUI.h"
# include "freestanding/SharedSection.h"
# include "LauncherProcessWin.h"
# include "mozilla/WindowsDllBlocklist.h"
@ -377,6 +377,10 @@ int main(int argc, char* argv[], char* envp[]) {
int result = do_main(argc, argv, envp);
#if defined(XP_WIN)
CleanupProcessRuntime();
#endif
gBootstrap->NS_LogTerm();
#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST)

Просмотреть файл

@ -71,6 +71,7 @@
# endif
# include "mozilla/NativeNt.h"
# include "mozilla/CacheNtDllThunk.h"
#endif
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
@ -228,7 +229,7 @@ class WindowsProcessLauncher : public BaseProcessLauncher {
std::vector<std::string>&& aExtraOpts)
: BaseProcessLauncher(aHost, std::move(aExtraOpts)),
mProfileDir(aHost->mProfileDir),
mCachedNtdllThunk(aHost->sCachedNtDllThunk),
mCachedNtdllThunk(GetCachedNtDllThunk()),
mWerDataPointer(&(aHost->mWerData)) {}
protected:
@ -242,7 +243,7 @@ class WindowsProcessLauncher : public BaseProcessLauncher {
nsCOMPtr<nsIFile> mProfileDir;
const StaticAutoPtr<Buffer<IMAGE_THUNK_DATA>>& mCachedNtdllThunk;
const Buffer<IMAGE_THUNK_DATA>* mCachedNtdllThunk;
CrashReporter::WindowsErrorReportingData const* mWerDataPointer;
};
typedef WindowsProcessLauncher ProcessLauncher;
@ -351,51 +352,6 @@ mozilla::StaticAutoPtr<mozilla::LinkedList<GeckoChildProcessHost>>
mozilla::StaticMutex GeckoChildProcessHost::sMutex;
#ifdef XP_WIN
mozilla::StaticAutoPtr<Buffer<IMAGE_THUNK_DATA>>
GeckoChildProcessHost::sCachedNtDllThunk;
// This static method initializes sCachedNtDllThunk. Because it's called in
// XREMain::XRE_main, which happens long before WindowsProcessLauncher's ctor
// accesses sCachedNtDllThunk, there is no race on sCachedNtDllThunk, thus
// no mutex is needed.
/* static */
void GeckoChildProcessHost::CacheNtDllThunk() {
if (sCachedNtDllThunk) {
return;
}
do {
nt::PEHeaders ourExeImage(::GetModuleHandleW(nullptr));
if (!ourExeImage) {
break;
}
nt::PEHeaders ntdllImage(::GetModuleHandleW(L"ntdll.dll"));
if (!ntdllImage) {
break;
}
Maybe<Range<const uint8_t>> ntdllBoundaries = ntdllImage.GetBounds();
if (!ntdllBoundaries) {
break;
}
Maybe<Span<IMAGE_THUNK_DATA>> maybeNtDllThunks =
ourExeImage.GetIATThunksForModule("ntdll.dll", ntdllBoundaries.ptr());
if (maybeNtDllThunks.isNothing()) {
break;
}
sCachedNtDllThunk = new Buffer<IMAGE_THUNK_DATA>(maybeNtDllThunks.value());
return;
} while (false);
// Failed to cache IAT. Initializing the variable with nullptr.
sCachedNtDllThunk = new Buffer<IMAGE_THUNK_DATA>();
}
#endif
GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
bool aIsFileContent)
: mProcessType(aProcessType),

Просмотреть файл

@ -142,7 +142,6 @@ class GeckoChildProcessHost : public ChildProcessHost,
#endif
#ifdef XP_WIN
static void CacheNtDllThunk();
void AddHandleToShare(HANDLE aHandle) {
mLaunchOptions->handles_to_inherit.push_back(aHandle);
@ -291,9 +290,6 @@ class GeckoChildProcessHost : public ChildProcessHost,
static uint32_t sNextUniqueID;
static StaticAutoPtr<LinkedList<GeckoChildProcessHost>>
sGeckoChildProcessHosts;
#ifdef XP_WIN
static StaticAutoPtr<Buffer<IMAGE_THUNK_DATA>> sCachedNtDllThunk;
#endif
static StaticMutex sMutex;
};

Просмотреть файл

@ -13,23 +13,22 @@
namespace mozilla {
namespace mscom {
ActivationContext::ActivationContext(WORD aResourceId)
: ActivationContext(reinterpret_cast<HMODULE>(GetContainingModuleHandle()),
aResourceId) {}
ActivationContext::ActivationContext(ActCtxResource aResource)
: ActivationContext(aResource.mModule, aResource.mId) {}
ActivationContext::ActivationContext(HMODULE aLoadFromModule, WORD aResourceId)
: mActCtx(INVALID_HANDLE_VALUE) {
ACTCTX actCtx = {sizeof(actCtx)};
ACTCTXW actCtx = {sizeof(actCtx)};
actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
actCtx.lpResourceName = MAKEINTRESOURCE(aResourceId);
actCtx.lpResourceName = MAKEINTRESOURCEW(aResourceId);
actCtx.hModule = aLoadFromModule;
Init(actCtx);
}
void ActivationContext::Init(ACTCTX& aActCtx) {
void ActivationContext::Init(ACTCTXW& aActCtx) {
MOZ_ASSERT(mActCtx == INVALID_HANDLE_VALUE);
mActCtx = ::CreateActCtx(&aActCtx);
mActCtx = ::CreateActCtxW(&aActCtx);
MOZ_ASSERT(mActCtx != INVALID_HANDLE_VALUE);
}

Просмотреть файл

@ -10,6 +10,7 @@
#include <utility>
#include "mozilla/Attributes.h"
#include "mozilla/mscom/ActCtxResource.h"
#if defined(MOZILLA_INTERNAL_API)
# include "mozilla/ResultVariant.h"
@ -29,7 +30,7 @@ class ActivationContext final {
ActivationContext() : mActCtx(INVALID_HANDLE_VALUE) {}
explicit ActivationContext(WORD aResourceId);
explicit ActivationContext(ActCtxResource aResource);
explicit ActivationContext(HMODULE aLoadFromModule,
WORD aResourceId = kDllManifestDefaultResourceId);
@ -49,7 +50,7 @@ class ActivationContext final {
#endif // defined(MOZILLA_INTERNAL_API)
private:
void Init(ACTCTX& aActCtx);
void Init(ACTCTXW& aActCtx);
void AddRef();
void Release();

Просмотреть файл

@ -6,9 +6,11 @@
#include "mozilla/mscom/ProcessRuntime.h"
#if defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
# include "mozilla/a11y/Compatibility.h"
#endif // defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
#if defined(ACCESSIBILITY) && \
(defined(MOZILLA_INTERNAL_API) || defined(MOZ_HAS_MOZGLUE))
# include "mozilla/mscom/ActCtxResource.h"
#endif // defined(ACCESSIBILITY) && (defined(MOZILLA_INTERNAL_API) ||
// defined(MOZ_HAS_MOZGLUE))
#include "mozilla/Assertions.h"
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
#include "mozilla/mscom/ProcessRuntimeShared.h"
@ -49,13 +51,22 @@ ProcessRuntime::ProcessRuntime(const GeckoProcessType aProcessType)
#endif // defined(MOZILLA_INTERNAL_API)
ProcessRuntime::ProcessRuntime(const ProcessCategory aProcessCategory)
: mInitResult(CO_E_NOTINITIALIZED),
mProcessCategory(aProcessCategory)
#if defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
,
mActCtxRgn(a11y::Compatibility::GetActCtxResourceId())
#endif // defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
{
: mInitResult(CO_E_NOTINITIALIZED), mProcessCategory(aProcessCategory) {
#if defined(ACCESSIBILITY)
# if defined(MOZILLA_INTERNAL_API)
// If we're inside XUL, and we're the parent process, then we trust that
// this has already been initialized for us prior to XUL being loaded.
if (aProcessCategory != ProcessCategory::GeckoBrowserParent) {
mActCtxRgn.emplace(ActCtxResource::GetAccessibilityResource());
}
# elif defined(MOZ_HAS_MOZGLUE)
// If we're here, then we're in mozglue and initializing this for the parent
// process.
MOZ_ASSERT(aProcessCategory == ProcessCategory::GeckoBrowserParent);
mActCtxRgn.emplace(ActCtxResource::GetAccessibilityResource());
# endif
#endif // defined(ACCESSIBILITY)
#if defined(MOZILLA_INTERNAL_API)
MOZ_DIAGNOSTIC_ASSERT(!sInstance);
sInstance = this;
@ -120,11 +131,29 @@ ProcessRuntime::ProcessRuntime(const ProcessCategory aProcessCategory)
mAptRegion.Init(GetDesiredApartmentType(mProcessCategory));
// We must be the outermost COM initialization on this thread. The COM runtime
// cannot be configured once we start manipulating objects
MOZ_ASSERT(mAptRegion.IsValidOutermost());
// It can happen that we are not the outermost COM initialization on this
// thread. In fact it should regularly be the case that the outermost
// initialization occurs from outside of XUL, before we show the skeleton UI,
// at which point we still need to run some things here from within XUL.
if (!mAptRegion.IsValidOutermost()) {
mInitResult = mAptRegion.GetHResult();
#if defined(MOZILLA_INTERNAL_API)
MOZ_ASSERT(mProcessCategory == ProcessCategory::GeckoBrowserParent);
if (mProcessCategory != ProcessCategory::GeckoBrowserParent) {
// This is unexpected unless we're GeckoBrowserParent
return;
}
ProcessInitLock lock;
// Is another instance of ProcessRuntime responsible for the outer
// initialization?
const bool prevInit = lock.IsInitialized();
MOZ_ASSERT(prevInit);
if (prevInit) {
PostInit();
}
#endif // defined(MOZILLA_INTERNAL_API)
return;
}

Просмотреть файл

@ -8,9 +8,10 @@
#define mozilla_mscom_ProcessRuntime_h
#include "mozilla/Attributes.h"
#if defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
#if defined(ACCESSIBILITY)
# include "mozilla/mscom/ActivationContext.h"
#endif // defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
# include "mozilla/Maybe.h"
#endif // defined(ACCESSIBILITY)
#include "mozilla/mscom/ApartmentRegion.h"
#include "nsWindowsHelpers.h"
#if defined(MOZILLA_INTERNAL_API)
@ -76,9 +77,11 @@ class MOZ_NON_TEMPORARY_CLASS ProcessRuntime final {
private:
HRESULT mInitResult;
const ProcessCategory mProcessCategory;
#if defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
ActivationContextRegion mActCtxRgn;
#endif // defined(ACCESSIBILITY) && defined(MOZILLA_INTERNAL_API)
#if defined(ACCESSIBILITY) && \
(defined(MOZILLA_INTERNAL_API) || defined(MOZ_HAS_MOZGLUE))
Maybe<ActivationContextRegion> mActCtxRgn;
#endif // defined(ACCESSIBILITY) && (defined(MOZILLA_INTERNAL_API) ||
// defined(MOZ_HAS_MOZGLUE))
ApartmentRegion mAptRegion;
private:

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/Attributes.h"
#include <guiddef.h>
#include <stdint.h>
struct IStream;
struct IUnknown;

Просмотреть файл

@ -0,0 +1,219 @@
/* 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 "ActCtxResource.h"
#include <string>
#include "mozilla/GetKnownFolderPath.h"
#include "mozilla/WindowsVersion.h"
#include "nsWindowsHelpers.h"
namespace mozilla {
namespace mscom {
#if !defined(HAVE_64BIT_BUILD)
static bool ReadCOMRegDefaultString(const std::wstring& aRegPath,
std::wstring& aOutBuf) {
aOutBuf.clear();
std::wstring fullyQualifiedRegPath;
fullyQualifiedRegPath.append(L"SOFTWARE\\Classes\\");
fullyQualifiedRegPath.append(aRegPath);
// Get the required size and type of the registry value.
// We expect either REG_SZ or REG_EXPAND_SZ.
DWORD type;
DWORD bufLen = 0;
LONG result =
::RegGetValueW(HKEY_LOCAL_MACHINE, fullyQualifiedRegPath.c_str(), nullptr,
RRF_RT_ANY, &type, nullptr, &bufLen);
if (result != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
return false;
}
// Now obtain the value
DWORD flags = type == REG_SZ ? RRF_RT_REG_SZ : RRF_RT_REG_EXPAND_SZ;
aOutBuf.resize((bufLen + 1) / sizeof(char16_t));
result = ::RegGetValueW(HKEY_LOCAL_MACHINE, fullyQualifiedRegPath.c_str(),
nullptr, flags, nullptr, &aOutBuf[0], &bufLen);
if (result != ERROR_SUCCESS) {
aOutBuf.clear();
return false;
}
// Truncate terminator
aOutBuf.resize((bufLen + 1) / sizeof(char16_t) - 1);
return true;
}
static bool IsSystemOleAcc(HANDLE aFile) {
if (aFile == INVALID_HANDLE_VALUE) {
return false;
}
BY_HANDLE_FILE_INFORMATION info = {};
if (!::GetFileInformationByHandle(aFile, &info)) {
return false;
}
// Use FOLDERID_SystemX86 so that Windows doesn't give us a redirected
// system32 if we're a 32-bit process running on a 64-bit OS. This is
// necessary because the values that we are reading from the registry
// are not redirected; they reference SysWOW64 directly.
auto systemPath = GetKnownFolderPath(FOLDERID_SystemX86);
if (!systemPath) {
return false;
}
std::wstring oleAccPath(systemPath.get());
oleAccPath.append(L"\\oleacc.dll");
nsAutoHandle oleAcc(
::CreateFileW(oleAccPath.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
if (oleAcc.get() == INVALID_HANDLE_VALUE) {
return false;
}
BY_HANDLE_FILE_INFORMATION oleAccInfo = {};
if (!::GetFileInformationByHandle(oleAcc, &oleAccInfo)) {
return false;
}
return info.dwVolumeSerialNumber == oleAccInfo.dwVolumeSerialNumber &&
info.nFileIndexLow == oleAccInfo.nFileIndexLow &&
info.nFileIndexHigh == oleAccInfo.nFileIndexHigh;
}
static bool IsTypelibPreferred() {
// If IAccessible's Proxy/Stub CLSID is kUniversalMarshalerClsid, then any
// external a11y clients are expecting to use a typelib.
const wchar_t kUniversalMarshalerClsid[] =
L"{00020424-0000-0000-C000-000000000046}";
const wchar_t kIAccessiblePSClsidPath[] =
L"Interface\\{618736E0-3C3D-11CF-810C-00AA00389B71}"
L"\\ProxyStubClsid32";
std::wstring psClsid;
if (!ReadCOMRegDefaultString(kIAccessiblePSClsidPath, psClsid)) {
return false;
}
if (psClsid.size() !=
sizeof(kUniversalMarshalerClsid) / sizeof(kUniversalMarshalerClsid)[0] -
1) {
return false;
}
int index = 0;
while (kUniversalMarshalerClsid[index]) {
if (toupper(psClsid[index]) != kUniversalMarshalerClsid[index]) {
return false;
}
index++;
}
return true;
}
static bool IsIAccessibleTypelibRegistered() {
// The system default IAccessible typelib is always registered with version
// 1.1, under the neutral locale (LCID 0).
const wchar_t kIAccessibleTypelibRegPath[] =
L"TypeLib\\{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}\\1.1\\0\\win32";
std::wstring typelibPath;
if (!ReadCOMRegDefaultString(kIAccessibleTypelibRegPath, typelibPath)) {
return false;
}
nsAutoHandle libTestFile(
::CreateFileW(typelibPath.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
return IsSystemOleAcc(libTestFile);
}
static bool IsIAccessiblePSRegistered() {
const wchar_t kIAccessiblePSRegPath[] =
L"CLSID\\{03022430-ABC4-11D0-BDE2-00AA001A1953}\\InProcServer32";
std::wstring proxyStubPath;
if (!ReadCOMRegDefaultString(kIAccessiblePSRegPath, proxyStubPath)) {
return false;
}
nsAutoHandle libTestFile(
::CreateFileW(proxyStubPath.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
return IsSystemOleAcc(libTestFile);
}
static bool UseIAccessibleProxyStub() {
// If a typelib is preferred then external clients are expecting to use
// typelib marshaling, so we should use that whenever available.
if (IsTypelibPreferred() && IsIAccessibleTypelibRegistered()) {
return false;
}
// Otherwise we try the proxy/stub
if (IsIAccessiblePSRegistered()) {
return true;
}
return false;
}
#endif // !defined(HAVE_64BIT_BUILD)
#if defined(_MSC_VER)
extern "C" IMAGE_DOS_HEADER __ImageBase;
#endif
static HMODULE GetContainingModuleHandle() {
HMODULE thisModule = nullptr;
#if defined(_MSC_VER)
thisModule = reinterpret_cast<HMODULE>(&__ImageBase);
#else
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
reinterpret_cast<LPCTSTR>(&GetContainingModuleHandle),
&thisModule)) {
return 0;
}
#endif
return thisModule;
}
ActCtxResource ActCtxResource::GetAccessibilityResource() {
ActCtxResource result = {};
result.mModule = GetContainingModuleHandle();
#if defined(HAVE_64BIT_BUILD)
// The manifest for 64-bit Windows is embedded with resource ID 64.
result.mId = 64;
#else
// The manifest for 32-bit Windows is embedded with resource ID 32.
// Beginning with Windows 10 Creators Update, 32-bit builds always use the
// 64-bit manifest. Older builds of Windows may or may not require the 64-bit
// manifest: UseIAccessibleProxyStub() determines the course of action.
if (mozilla::IsWin10CreatorsUpdateOrLater() || UseIAccessibleProxyStub()) {
result.mId = 64;
} else {
result.mId = 32;
}
#endif // defined(HAVE_64BIT_BUILD)
return result;
}
} // namespace mscom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,29 @@
/* 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 ACT_CTX_RESOURCE_H
#define ACT_CTX_RESOURCE_H
#include <stdint.h>
#include <windows.h>
#include "mozilla/Types.h"
namespace mozilla {
namespace mscom {
struct ActCtxResource {
uint16_t mId;
HMODULE mModule;
/**
* @return ActCtxResource of a11y manifest resource to be passed to
* mscom::ActivationContext
*/
static MFBT_API ActCtxResource GetAccessibilityResource();
};
} // namespace mscom
} // namespace mozilla
#endif

Просмотреть файл

@ -7,9 +7,11 @@
FINAL_LIBRARY = "mozglue"
EXPORTS.mozilla.mscom += [
"ActCtxResource.h",
"ProcessRuntimeShared.h",
]
UNIFIED_SOURCES += [
"ActCtxResource.cpp",
"ProcessRuntimeShared.cpp",
]

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Mozilla.Firefox.xul" version="1.0.0.0" />
<file name="xul.dll" />
<assemblyIdentity type="win32" name="Mozilla.Firefox.mozglue" version="1.0.0.0" />
<file name="mozglue.dll" />
<comInterfaceExternalProxyStub
iid="{618736E0-3C3D-11CF-810C-00AA00389B71}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Mozilla.Firefox.xul" version="1.0.0.0" />
<file name="xul.dll" />
<assemblyIdentity type="win32" name="Mozilla.Firefox.mozglue" version="1.0.0.0" />
<file name="mozglue.dll" />
<comInterfaceExternalProxyStub
iid="{618736E0-3C3D-11CF-810C-00AA00389B71}"
proxyStubClsid32="{03022430-ABC4-11D0-BDE2-00AA001A1953}"

Просмотреть файл

@ -99,6 +99,18 @@ USE_LIBS += [
"mfbt",
]
if CONFIG["OS_ARCH"] == "WINNT":
RCINCLUDE = "/mozglue/mozglue.rc"
if not CONFIG["HAVE_64BIT_BUILD"]:
EXPORTS += [
"IAccessible32.manifest",
]
EXPORTS += [
"IAccessible64.manifest",
]
LIBRARY_DEFINES["IMPL_MFBT"] = True
LIBRARY_DEFINES["MOZ_HAS_MOZGLUE"] = True

Просмотреть файл

@ -0,0 +1,60 @@
/* -*- 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 "CacheNtDllThunk.h"
#include "mozilla/Maybe.h"
#include "mozilla/Span.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
static StaticAutoPtr<Buffer<IMAGE_THUNK_DATA>> sCachedNtDllThunk;
// This static method initializes sCachedNtDllThunk. Because it's called in
// XREMain::XRE_main, which happens long before WindowsProcessLauncher's ctor
// accesses sCachedNtDllThunk, there is no race on sCachedNtDllThunk, thus
// no mutex is needed.
static void CacheNtDllThunk() {
if (sCachedNtDllThunk) {
return;
}
do {
nt::PEHeaders ourExeImage(::GetModuleHandleW(nullptr));
if (!ourExeImage) {
break;
}
nt::PEHeaders ntdllImage(::GetModuleHandleW(L"ntdll.dll"));
if (!ntdllImage) {
break;
}
Maybe<Range<const uint8_t>> ntdllBoundaries = ntdllImage.GetBounds();
if (!ntdllBoundaries) {
break;
}
Maybe<Span<IMAGE_THUNK_DATA>> maybeNtDllThunks =
ourExeImage.GetIATThunksForModule("ntdll.dll", ntdllBoundaries.ptr());
if (maybeNtDllThunks.isNothing()) {
break;
}
sCachedNtDllThunk = new Buffer<IMAGE_THUNK_DATA>(maybeNtDllThunks.value());
return;
} while (false);
// Failed to cache IAT. Initializing the variable with nullptr.
sCachedNtDllThunk = new Buffer<IMAGE_THUNK_DATA>();
}
static Buffer<IMAGE_THUNK_DATA>* GetCachedNtDllThunk() {
return sCachedNtDllThunk;
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,21 @@
/* -*- 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_CacheNtDllThunk_h
#define mozilla_CacheNtDllThunk_h
#include "mozilla/Types.h"
#include "mozilla/Buffer.h"
#include "mozilla/NativeNt.h"
namespace mozilla {
MFBT_API void CacheNtDllThunk();
MFBT_API Buffer<IMAGE_THUNK_DATA>* GetCachedNtDllThunk();
}; // namespace mozilla
#endif // mozilla_CacheNtDllThunk_h

Просмотреть файл

@ -18,6 +18,11 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"]:
"WindowsFallbackLoaderAPI.cpp",
]
if not CONFIG["JS_STANDALONE"]:
UNIFIED_SOURCES += [
"CacheNtDllThunk.cpp",
]
OS_LIBS += [
"crypt32",
"ntdll",
@ -32,6 +37,7 @@ DELAYLOAD_DLLS += [
EXPORTS.mozilla += [
"Authenticode.h",
"CacheNtDllThunk.h",
"LoaderAPIInterfaces.h",
"ModuleLoadInfo.h",
"WindowsDllBlocklist.h",

Просмотреть файл

@ -0,0 +1,33 @@
/* 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 "GetKnownFolderPath.h"
namespace mozilla {
UniquePtr<wchar_t, LoadedCoTaskMemFreeDeleter> GetKnownFolderPath(
REFKNOWNFOLDERID folderId) {
static decltype(SHGetKnownFolderPath)* shGetKnownFolderPath = nullptr;
if (!shGetKnownFolderPath) {
// We could go out of our way to `FreeLibrary` on this, decrementing its
// ref count and potentially unloading it. However doing so would be either
// effectively a no-op, or counterproductive. Just let it get cleaned up
// when the process is terminated, because we're going to load it anyway
// elsewhere.
HMODULE shell32Dll = ::LoadLibraryW(L"shell32");
if (!shell32Dll) {
return nullptr;
}
shGetKnownFolderPath = reinterpret_cast<decltype(shGetKnownFolderPath)>(
::GetProcAddress(shell32Dll, "SHGetKnownFolderPath"));
if (!shGetKnownFolderPath) {
return nullptr;
}
}
PWSTR path = nullptr;
shGetKnownFolderPath(folderId, 0, nullptr, &path);
return UniquePtr<wchar_t, LoadedCoTaskMemFreeDeleter>(path);
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,45 @@
/* 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_GetKnownFolderPath_h
#define mozilla_GetKnownFolderPath_h
#include <windows.h>
#include <objbase.h>
#include <shlobj.h>
#include "mozilla/glue/Debug.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
struct LoadedCoTaskMemFreeDeleter {
void operator()(void* ptr) {
static decltype(CoTaskMemFree)* coTaskMemFree = nullptr;
if (!coTaskMemFree) {
// Just let this get cleaned up when the process is terminated, because
// we're going to load it anyway elsewhere.
HMODULE ole32Dll = ::LoadLibraryW(L"ole32");
if (!ole32Dll) {
printf_stderr(
"Could not load ole32 - will not free with CoTaskMemFree");
return;
}
coTaskMemFree = reinterpret_cast<decltype(coTaskMemFree)>(
::GetProcAddress(ole32Dll, "CoTaskMemFree"));
if (!coTaskMemFree) {
printf_stderr("Could not find CoTaskMemFree");
return;
}
}
coTaskMemFree(ptr);
}
};
UniquePtr<wchar_t, LoadedCoTaskMemFreeDeleter> GetKnownFolderPath(
REFKNOWNFOLDERID folderId);
} // namespace mozilla
#endif

Просмотреть файл

@ -17,12 +17,15 @@
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/BaseProfilerMarkers.h"
#include "mozilla/CacheNtDllThunk.h"
#include "mozilla/FStream.h"
#include "mozilla/GetKnownFolderPath.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/HelperMacros.h"
#include "mozilla/glue/Debug.h"
#include "mozilla/Maybe.h"
#include "mozilla/mscom/ProcessRuntime.h"
#include "mozilla/ResultVariant.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/UniquePtr.h"
@ -30,6 +33,7 @@
#include "mozilla/Unused.h"
#include "mozilla/WindowsDpiAwareness.h"
#include "mozilla/WindowsVersion.h"
#include "mozilla/WindowsProcessMitigations.h"
namespace mozilla {
@ -104,6 +108,7 @@ static LPWSTR const gIDCWait = MAKEINTRESOURCEW(32514);
static HANDLE sPreXULSKeletonUIAnimationThread;
static HANDLE sPreXULSKeletonUILockFile = INVALID_HANDLE_VALUE;
static mozilla::mscom::ProcessRuntime* sProcessRuntime;
static uint32_t* sPixelBuffer = nullptr;
static Vector<ColorRect>* sAnimatedRects = nullptr;
static int sTotalChromeHeight = 0;
@ -189,29 +194,6 @@ static const wchar_t* sThemeRegSuffix = L"|Theme";
static const wchar_t* sFlagsRegSuffix = L"|Flags";
static const wchar_t* sProgressSuffix = L"|Progress";
struct LoadedCoTaskMemFreeDeleter {
void operator()(void* ptr) {
static decltype(CoTaskMemFree)* coTaskMemFree = nullptr;
if (!coTaskMemFree) {
// Just let this get cleaned up when the process is terminated, because
// we're going to load it anyway elsewhere.
HMODULE ole32Dll = ::LoadLibraryW(L"ole32");
if (!ole32Dll) {
printf_stderr(
"Could not load ole32 - will not free with CoTaskMemFree");
return;
}
coTaskMemFree = reinterpret_cast<decltype(coTaskMemFree)>(
::GetProcAddress(ole32Dll, "CoTaskMemFree"));
if (!coTaskMemFree) {
printf_stderr("Could not find CoTaskMemFree");
return;
}
}
coTaskMemFree(ptr);
}
};
std::wstring GetRegValueName(const wchar_t* prefix, const wchar_t* suffix) {
std::wstring result(prefix);
result.append(suffix);
@ -255,30 +237,6 @@ static bool PreXULSkeletonUIDisallowed() {
*sErrorReason == PreXULSkeletonUIError::EnvVars);
}
static UniquePtr<wchar_t, LoadedCoTaskMemFreeDeleter> GetKnownFolderPath(
REFKNOWNFOLDERID folderId) {
static decltype(SHGetKnownFolderPath)* shGetKnownFolderPath = nullptr;
if (!shGetKnownFolderPath) {
// We could go out of our way to `FreeLibrary` on this, decrementing its
// ref count and potentially unloading it. However doing so would be either
// effectively a no-op, or counterproductive. Just let it get cleaned up
// when the process is terminated, because we're going to load it anyway
// elsewhere.
HMODULE shell32Dll = ::LoadLibraryW(L"shell32");
if (!shell32Dll) {
return nullptr;
}
shGetKnownFolderPath = reinterpret_cast<decltype(shGetKnownFolderPath)>(
::GetProcAddress(shell32Dll, "SHGetKnownFolderPath"));
if (!shGetKnownFolderPath) {
return nullptr;
}
}
PWSTR path = nullptr;
shGetKnownFolderPath(folderId, 0, nullptr, &path);
return UniquePtr<wchar_t, LoadedCoTaskMemFreeDeleter>(path);
}
// Note: this is specifically *not* a robust, multi-locale lowercasing
// operation. It is not intended to be such. It is simply intended to match the
// way in which we look for other instances of firefox to remote into.
@ -1307,6 +1265,12 @@ DWORD WINAPI AnimateSkeletonUI(void* aUnused) {
LRESULT WINAPI PreXULSkeletonUIProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam) {
// Exposing a generic oleacc proxy for the skeleton isn't useful and may cause
// screen readers to report spurious information when the skeleton appears.
if (msg == WM_GETOBJECT && sPreXULSkeletonUIWindow) {
return E_FAIL;
}
// NOTE: this block was copied from WinUtils.cpp, and needs to be kept in
// sync.
if (msg == WM_NCCREATE && sEnableNonClientDpiScaling) {
@ -1841,6 +1805,31 @@ static Result<Ok, PreXULSkeletonUIError> WriteRegBool(
static Result<Ok, PreXULSkeletonUIError> CreateAndStorePreXULSkeletonUIImpl(
HINSTANCE hInstance, int argc, char** argv) {
// Initializing COM below may load modules via SetWindowHookEx, some of
// which may modify the executable's IAT for ntdll.dll. If that happens,
// this browser process fails to launch sandbox processes because we cannot
// copy a modified IAT into a remote process (See SandboxBroker::LaunchApp).
// To prevent that, we cache the intact IAT before COM initialization.
// If EAF+ is enabled, CacheNtDllThunk() causes a crash, but EAF+ will
// also prevent an injected module from parsing the PE headers and modifying
// the IAT. Therefore, we can skip CacheNtDllThunk().
if (!mozilla::IsEafPlusEnabled()) {
CacheNtDllThunk();
}
// NOTE: it's important that we initialize sProcessRuntime before showing a
// window. Historically we ran into issues where showing the window would
// cause an accessibility win event to fire, which could cause in-process
// system or third party components to initialize COM and prevent us from
// initializing it with important settings we need.
// Some COM settings are global to the process and must be set before any non-
// trivial COM is run in the application. Since these settings may affect
// stability, we should instantiate COM ASAP so that we can ensure that these
// global settings are configured before anything can interfere.
sProcessRuntime = new mscom::ProcessRuntime(
mscom::ProcessRuntime::ProcessCategory::GeckoBrowserParent);
const TimeStamp skeletonStart = TimeStamp::NowUnfuzzed();
if (!IsWin10OrLater()) {
@ -2052,6 +2041,11 @@ void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance, int argc,
}
}
void CleanupProcessRuntime() {
delete sProcessRuntime;
sProcessRuntime = nullptr;
}
bool WasPreXULSkeletonUIMaximized() { return sMaximized; }
bool GetPreXULSkeletonUIWasShown() {

Просмотреть файл

@ -166,6 +166,7 @@ enum class PreXULSkeletonUIProgress : uint32_t {
MFBT_API void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance, int argc,
char** argv);
MFBT_API void CleanupProcessRuntime();
MFBT_API bool GetPreXULSkeletonUIWasShown();
MFBT_API HWND ConsumePreXULSkeletonUIHandle();
MFBT_API Maybe<PreXULSkeletonUIError> GetPreXULSkeletonUIErrorReason();

Просмотреть файл

@ -29,6 +29,7 @@ EXPORTS.mozilla.glue += [
if CONFIG["OS_ARCH"] == "WINNT":
EXPORTS.mozilla += [
"GetKnownFolderPath.h",
"PreXULSkeletonUI.h",
"StackWalk_windows.h",
"StackWalkThread.h",
@ -68,14 +69,26 @@ if CONFIG["OS_ARCH"] == "WINNT":
"WindowsUnicode.h",
]
SOURCES += [
"PreXULSkeletonUI.cpp",
"GetKnownFolderPath.cpp",
"TimeStamp_windows.cpp",
"WindowsDpiInitialization.cpp",
"WindowsMapRemoteView.cpp",
"WindowsProcessMitigations.cpp",
"WindowsUnicode.cpp",
]
OS_LIBS += ["dbghelp"]
OS_LIBS += [
"dbghelp",
"oleaut32",
"ole32",
]
if CONFIG["ACCESSIBILITY"]:
SOURCES += [
"/ipc/mscom/ActivationContext.cpp",
"/ipc/mscom/ProcessRuntime.cpp",
"PreXULSkeletonUI.cpp",
]
elif CONFIG["HAVE_CLOCK_MONOTONIC"]:
SOURCES += [
"TimeStamp_posix.cpp",

7
mozglue/mozglue.rc Normal file
Просмотреть файл

@ -0,0 +1,7 @@
#include "mozilla-config.h"
#ifdef ACCESSIBILITY
64 24 IAccessible64.manifest
#ifndef HAVE_64BIT_BUILD
32 24 IAccessible32.manifest
#endif
#endif

Просмотреть файл

@ -407,6 +407,8 @@ class ChildProcess final {
template <typename MMPolicy>
TestResult BasicTest(const MMPolicy& aMMPolicy) {
const bool isAppHelpLoaded = ::GetModuleHandleW(L"apphelp.dll");
// Use ntdll.dll because it does not have any forwarder RVA.
HMODULE ntdllImageBase = ::GetModuleHandleW(L"ntdll.dll");
auto ntdllExports = PEExportSection<MMPolicy>::Get(ntdllImageBase, aMMPolicy);
@ -417,6 +419,13 @@ TestResult BasicTest(const MMPolicy& aMMPolicy) {
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i) {
const auto name =
ntdllExports.template RVAToPtr<const char*>(tableOfNames[i]);
if (isAppHelpLoaded && strcmp(name, "NtdllDefWindowProc_W") == 0) {
// In this case, GetProcAddress will return
// apphelp!DWM8AND16BitHook_DefWindowProcW.
continue;
}
auto funcEntry = ntdllExports.FindExportAddressTableEntry(name);
if (ntdllExports.template RVAToPtr<const void*>(*funcEntry) !=
::GetProcAddress(ntdllImageBase, name)) {

Просмотреть файл

@ -6,8 +6,4 @@
#include "widget.rc"
#ifdef ACCESSIBILITY
1 typelib IGeckoCustom.tlb
64 24 IAccessible64.manifest
#ifndef HAVE_64BIT_BUILD
32 24 IAccessible32.manifest
#endif
#endif

Просмотреть файл

@ -5402,22 +5402,9 @@ int XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) {
mozilla::IOInterposerInit ioInterposerGuard;
#if defined(XP_WIN)
// Initializing COM below may load modules via SetWindowHookEx, some of
// which may modify the executable's IAT for ntdll.dll. If that happens,
// this browser process fails to launch sandbox processes because we cannot
// copy a modified IAT into a remote process (See SandboxBroker::LaunchApp).
// To prevent that, we cache the intact IAT before COM initialization.
// If EAF+ is enabled, CacheNtDllThunk() causes a crash, but EAF+ will
// also prevent an injected module from parsing the PE headers and modifying
// the IAT. Therefore, we can skip CacheNtDllThunk().
if (!mozilla::IsEafPlusEnabled()) {
mozilla::ipc::GeckoChildProcessHost::CacheNtDllThunk();
}
// Some COM settings are global to the process and must be set before any non-
// trivial COM is run in the application. Since these settings may affect
// stability, we should instantiate COM ASAP so that we can ensure that these
// global settings are configured before anything can interfere.
// We should have already done this when we created the skeleton UI. However,
// there is code in here which needs xul in order to work, like EnsureMTA. It
// should be setup that running it again is safe.
mozilla::mscom::ProcessRuntime msCOMRuntime;
#endif