# HG changeset patch # User Aaron Klotz # Date 1517347390 25200 # Node ID 75b8883562094c9a3b5420078a33107e6bc07ba1 # Parent c2cecc0b10bf6c6bc355a40fa1f19138d7f3b35a Bug 1430857: Part 1 - Refactor DllServices to make it possible to obtain them from anywhere in Gecko; r=jimm MozReview-Commit-ID: GfWata0eCc5 diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp --- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -19,26 +19,25 @@ #include #pragma warning( push ) #pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h #include #pragma warning( pop ) #include "nsAutoPtr.h" - #include "nsWindowsDllInterceptor.h" #include "mozilla/Sprintf.h" #include "mozilla/StackWalk_windows.h" #include "mozilla/UniquePtr.h" #include "mozilla/WindowsVersion.h" #include "nsWindowsHelpers.h" #include "WindowsDllBlocklist.h" #include "mozilla/AutoProfilerLabel.h" -#include "mozilla/WindowsDllServices.h" +#include "mozilla/glue/WindowsDllServices.h" using namespace mozilla; #define ALL_VERSIONS ((unsigned long long)-1LL) // DLLs sometimes ship without a version number, particularly early // releases. Blocking "version <= 0" has the effect of blocking unversioned // DLLs (since the call to get version info fails), but not blocking @@ -933,17 +932,17 @@ DllBlocklist_CheckStatus() } // ============================================================================ // This section is for DLL Services // ============================================================================ static SRWLOCK gDllServicesLock = SRWLOCK_INIT; -static mozilla::detail::DllServicesBase* gDllServices; +static mozilla::glue::detail::DllServicesBase* gDllServices; class MOZ_RAII AutoSharedLock final { public: explicit AutoSharedLock(SRWLOCK& aLock) : mLock(aLock) { ::AcquireSRWLockShared(&aLock); @@ -1043,17 +1042,17 @@ DllLoadNotification(ULONG aReason, PCLDR return; } PCUNICODE_STRING fullDllName = aNotificationData->Loaded.FullDllName; gDllServices->DispatchDllLoadNotification(fullDllName); } MFBT_API void -DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc) +DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc) { AutoExclusiveLock lock(gDllServicesLock); if (aSvc && !gNotificationCookie) { auto pLdrRegisterDllNotification = reinterpret_cast( ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "LdrRegisterDllNotification")); diff --git a/mozglue/build/WindowsDllBlocklist.h b/mozglue/build/WindowsDllBlocklist.h --- a/mozglue/build/WindowsDllBlocklist.h +++ b/mozglue/build/WindowsDllBlocklist.h @@ -21,17 +21,19 @@ enum DllBlocklistInitFlags }; MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags = eDllBlocklistInitFlagDefault); MFBT_API void DllBlocklist_WriteNotes(HANDLE file); MFBT_API bool DllBlocklist_CheckStatus(); // Forward declaration namespace mozilla { +namespace glue { namespace detail { class DllServicesBase; } // namespace detail +} // namespace glue } // namespace mozilla -MFBT_API void DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc); +MFBT_API void DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc); #endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #endif // mozilla_windowsdllblocklist_h diff --git a/mozglue/build/WindowsDllServices.h b/mozglue/build/WindowsDllServices.h --- a/mozglue/build/WindowsDllServices.h +++ b/mozglue/build/WindowsDllServices.h @@ -1,32 +1,33 @@ /* -*- 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_WindowsDllServices_h -#define mozilla_WindowsDllServices_h +#ifndef mozilla_glue_WindowsDllServices_h +#define mozilla_glue_WindowsDllServices_h #include "mozilla/WindowsDllBlocklist.h" #if defined(MOZILLA_INTERNAL_API) #include "mozilla/SystemGroup.h" #include "nsISupportsImpl.h" #include "nsString.h" #include "nsThreadUtils.h" #endif // defined(MOZILLA_INTERNAL_API) // For PCUNICODE_STRING #include namespace mozilla { +namespace glue { namespace detail { class DllServicesBase { public: /** * WARNING: This method is called from within an unsafe context that holds * multiple locks inside the Windows loader. The only thing that @@ -81,11 +82,12 @@ protected: DllServices() = default; ~DllServices() = default; virtual void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) = 0; }; #endif // defined(MOZILLA_INTERNAL_API) +} // namespace glue } // namespace mozilla -#endif // mozilla_WindowsDllServices_h +#endif // mozilla_glue_WindowsDllServices_h diff --git a/mozglue/build/moz.build b/mozglue/build/moz.build --- a/mozglue/build/moz.build +++ b/mozglue/build/moz.build @@ -55,24 +55,26 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']: SOURCES += [ 'WindowsDllBlocklist.cpp', ] DisableStlWrapping() OS_LIBS += [ 'version', ] + EXPORTS.mozilla.glue += [ + 'WindowsDllServices.h', + ] EXPORTS.mozilla += [ 'arm.h', 'mips.h', 'SSE.h', 'WindowsCFGStatus.h', 'WindowsDllBlocklist.h', - 'WindowsDllServices.h', ] if CONFIG['CPU_ARCH'].startswith('x86'): SOURCES += [ 'SSE.cpp', ] if CONFIG['CPU_ARCH'] == 'arm': diff --git a/toolkit/xre/WinDllServices.cpp b/toolkit/xre/WinDllServices.cpp new file mode 100644 --- /dev/null +++ b/toolkit/xre/WinDllServices.cpp @@ -0,0 +1,54 @@ +/* -*- 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 https://mozilla.org/MPL/2.0/. */ + +#include "mozilla/WinDllServices.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Services.h" +#include "nsIObserverService.h" +#include "nsString.h" + +namespace mozilla { + +const char* DllServices::kTopicDllLoadedMainThread = "dll-loaded-main-thread"; +const char* DllServices::kTopicDllLoadedNonMainThread = "dll-loaded-non-main-thread"; + +static StaticRefPtr sInstance; + +DllServices* +DllServices::Get() +{ + if (sInstance) { + return sInstance; + } + + sInstance = new DllServices(); + ClearOnShutdown(&sInstance); + return sInstance; +} + +DllServices::DllServices() +{ + Enable(); +} + +void +DllServices::NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) +{ + const char* topic; + + if (aIsMainThread) { + topic = kTopicDllLoadedMainThread; + } else { + topic = kTopicDllLoadedNonMainThread; + } + + nsCOMPtr obsServ(mozilla::services::GetObserverService()); + obsServ->NotifyObservers(nullptr, topic, aDllName.get()); +} + +} // namespace mozilla + diff --git a/toolkit/xre/WinDllServices.h b/toolkit/xre/WinDllServices.h new file mode 100644 --- /dev/null +++ b/toolkit/xre/WinDllServices.h @@ -0,0 +1,31 @@ +/* -*- 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 https://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_WinDllServices_h +#define mozilla_WinDllServices_h + +#include "mozilla/glue/WindowsDllServices.h" + +namespace mozilla { + +class DllServices : public mozilla::glue::DllServices +{ +public: + static DllServices* Get(); + + static const char* kTopicDllLoadedMainThread; + static const char* kTopicDllLoadedNonMainThread; + +private: + DllServices(); + ~DllServices() = default; + + void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override; +}; + +} // namespace mozilla + +#endif // mozilla_WinDllServices_h diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build --- a/toolkit/xre/moz.build +++ b/toolkit/xre/moz.build @@ -31,21 +31,25 @@ EXPORTS += [ ] EXPORTS.mozilla += ['AutoSQLiteLifetime.h', 'Bootstrap.h'] if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']: EXPORTS += ['EventTracer.h'] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': + EXPORTS.mozilla += [ + 'WinDllServices.h', + ] SOURCES += [ '../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp', ] UNIFIED_SOURCES += [ 'nsNativeAppSupportWin.cpp', + 'WinDllServices.cpp', ] DEFINES['PROXY_PRINTING'] = 1 LOCAL_INCLUDES += [ '../../other-licenses/nsis/Contrib/CityHash/cityhash', '../components/printingui/win', ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': UNIFIED_SOURCES += [ diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -158,17 +158,17 @@ #include #include #include #endif #ifdef XP_WIN #include #include -#include "mozilla/WindowsDllServices.h" +#include "mozilla/WinDllServices.h" #include "nsThreadUtils.h" #include #include #include "WinUtils.h" #endif #ifdef XP_MACOSX #include "nsILocalFileMac.h" @@ -1663,50 +1663,16 @@ ScopedXPCOMStartup::CreateAppSupport(nsI if (!gNativeAppSupport) return NS_ERROR_NOT_INITIALIZED; return gNativeAppSupport->QueryInterface(aIID, aResult); } nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport; -#if defined(XP_WIN) - -class DllNotifications : public mozilla::DllServices -{ -public: - DllNotifications() - { - Enable(); - } - -private: - ~DllNotifications() = default; - - void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override; -}; - -void -DllNotifications::NotifyDllLoad(const bool aIsMainThread, - const nsString& aDllName) -{ - const char* topic; - - if (aIsMainThread) { - topic = "dll-loaded-main-thread"; - } else { - topic = "dll-loaded-non-main-thread"; - } - - nsCOMPtr obsServ(mozilla::services::GetObserverService()); - obsServ->NotifyObservers(nullptr, topic, aDllName.get()); -} - -#endif // defined(XP_WIN) - static void DumpArbitraryHelp() { nsresult rv; ScopedLogging log; { ScopedXPCOMStartup xpcom; @@ -4394,19 +4360,19 @@ void AddSandboxAnnotations() */ nsresult XREMain::XRE_mainRun() { nsresult rv = NS_OK; NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized."); #if defined(XP_WIN) - RefPtr dllNotifications(new DllNotifications()); - auto dllNotificationsDisable = MakeScopeExit([&dllNotifications]() { - dllNotifications->Disable(); + RefPtr dllServices(mozilla::DllServices::Get()); + auto dllServicesDisable = MakeScopeExit([&dllServices]() { + dllServices->Disable(); }); #endif // defined(XP_WIN) #ifdef NS_FUNCTION_TIMER // initialize some common services, so we don't pay the cost for these at odd times later on; // SetWindowCreator -> ChromeRegistry -> IOService -> SocketTransportService -> (nspr wspm init), Prefs { nsCOMPtr comp;