summaryrefslogtreecommitdiffstats
path: root/toolkit/xre/dllservices/WinDllServices.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/xre/dllservices/WinDllServices.cpp')
-rw-r--r--toolkit/xre/dllservices/WinDllServices.cpp142
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