diff options
Diffstat (limited to 'toolkit/xre/dllservices/WinDllServices.cpp')
-rw-r--r-- | toolkit/xre/dllservices/WinDllServices.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/toolkit/xre/dllservices/WinDllServices.cpp b/toolkit/xre/dllservices/WinDllServices.cpp new file mode 100644 index 0000000000..b98a15252b --- /dev/null +++ b/toolkit/xre/dllservices/WinDllServices.cpp @@ -0,0 +1,142 @@ +/* -*- 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 <windows.h> +#include <psapi.h> + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/SchedulerGroup.h" +#include "mozilla/Services.h" +#include "mozilla/StaticLocalPtr.h" +#include "mozilla/UntrustedModulesProcessor.h" +#include "nsCOMPtr.h" +#include "nsIObserverService.h" +#include "nsString.h" +#include "nsXULAppAPI.h" + +namespace mozilla { + +const char* DllServices::kTopicDllLoadedMainThread = "dll-loaded-main-thread"; +const char* DllServices::kTopicDllLoadedNonMainThread = + "dll-loaded-non-main-thread"; + +/* static */ +DllServices* DllServices::Get() { + static StaticLocalRefPtr<DllServices> sInstance( + []() -> already_AddRefed<DllServices> { + RefPtr<DllServices> dllSvc(new DllServices()); + // Full DLL services require XPCOM, which GMP doesn't have + if (XRE_IsGMPluginProcess()) { + dllSvc->EnableBasic(); + } else { + dllSvc->EnableFull(); + } + + auto setClearOnShutdown = [ptr = &sInstance]() -> void { + ClearOnShutdown(ptr); + }; + + if (NS_IsMainThread()) { + setClearOnShutdown(); + return dllSvc.forget(); + } + + SchedulerGroup::Dispatch( + TaskCategory::Other, + NS_NewRunnableFunction("mozilla::DllServices::Get", + std::move(setClearOnShutdown))); + + return dllSvc.forget(); + }()); + + return sInstance; +} + +DllServices::~DllServices() { DisableFull(); } + +void DllServices::StartUntrustedModulesProcessor(bool aIsStartingUp) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mUntrustedModulesProcessor); + mUntrustedModulesProcessor = UntrustedModulesProcessor::Create(aIsStartingUp); +} + +bool DllServices::IsReadyForBackgroundProcessing() const { + return mUntrustedModulesProcessor && + mUntrustedModulesProcessor->IsReadyForBackgroundProcessing(); +} + +RefPtr<UntrustedModulesPromise> DllServices::GetUntrustedModulesData() { + if (!mUntrustedModulesProcessor) { + return UntrustedModulesPromise::CreateAndReject(NS_ERROR_NOT_IMPLEMENTED, + __func__); + } + + return mUntrustedModulesProcessor->GetProcessedData(); +} + +void DllServices::DisableFull() { + if (XRE_IsGMPluginProcess()) { + return; + } + + if (mUntrustedModulesProcessor) { + mUntrustedModulesProcessor->Disable(); + } + + glue::DllServices::DisableFull(); +} + +RefPtr<ModulesTrustPromise> DllServices::GetModulesTrust( + ModulePaths&& aModPaths, bool aRunAtNormalPriority) { + if (!mUntrustedModulesProcessor) { + return ModulesTrustPromise::CreateAndReject(NS_ERROR_NOT_IMPLEMENTED, + __func__); + } + + return mUntrustedModulesProcessor->GetModulesTrust(std::move(aModPaths), + aRunAtNormalPriority); +} + +void DllServices::NotifyDllLoad(glue::EnhancedModuleLoadInfo&& aModLoadInfo) { + MOZ_ASSERT(NS_IsMainThread()); + + const char* topic; + + if (aModLoadInfo.mNtLoadInfo.mThreadId == ::GetCurrentThreadId()) { + topic = kTopicDllLoadedMainThread; + } else { + topic = kTopicDllLoadedNonMainThread; + } + + // We save the path to a nsAutoString because once we have submitted + // aModLoadInfo for processing there is no guarantee that the original + // buffer will continue to be valid. + nsAutoString dllFilePath(aModLoadInfo.GetSectionName()); + + if (mUntrustedModulesProcessor) { + mUntrustedModulesProcessor->Enqueue(std::move(aModLoadInfo)); + } + + nsCOMPtr<nsIObserverService> obsServ(mozilla::services::GetObserverService()); + if (!obsServ) { + return; + } + + obsServ->NotifyObservers(nullptr, topic, dllFilePath.get()); +} + +void DllServices::NotifyModuleLoadBacklog(ModuleLoadInfoVec&& aEvents) { + MOZ_ASSERT(NS_IsMainThread()); + if (!mUntrustedModulesProcessor) { + return; + } + + mUntrustedModulesProcessor->Enqueue(std::move(aEvents)); +} + +} // namespace mozilla |