Common (Windows): inits WinRT/COM globally

This commit is contained in:
李通洲
2026-05-06 14:38:10 +08:00
parent ba54763dde
commit 79b61f1391
3 changed files with 23 additions and 40 deletions
+19 -29
View File
@@ -1,40 +1,30 @@
#include "com.hpp"
#include "fastfetch.h"
#include <stdlib.h>
#include <roapi.h>
// https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
// https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
static void CoUninitializeWrap(void) {
CoUninitialize();
static void RoUninitializeWrap(void) {
RoUninitialize();
}
static const char* doInitCom() {
// Initialize COM
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
return "CoInitializeEx() failed";
HRESULT res = RoInitialize(RO_INIT_MULTITHREADED);
if (FAILED(res)) {
switch (res) {
case E_INVALIDARG:
return "RoInitialize() failed: invalid argument";
case E_OUTOFMEMORY:
return "RoInitialize() failed: out of memory";
case E_UNEXPECTED:
return "RoInitialize() failed: unexpected error";
case RPC_E_CHANGED_MODE:
// COM was already initialized with a different concurrency model
return NULL;
default:
return "RoInitialize() failed: unknown error";
}
}
// Set general COM security levels
HRESULT hRes = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hRes) && hRes != RPC_E_TOO_LATE /* Has been set by a random dll */) {
CoUninitialize();
return "CoInitializeSecurity() failed";
}
atexit(CoUninitializeWrap);
atexit(RoUninitializeWrap);
return NULL;
}
+1
View File
@@ -5,6 +5,7 @@
#include "common/attributes.h"
#include <unknwn.h>
// Initialize COM & WinRT
const char* ffInitCom(void);
static inline void ffReleaseComObject(void* ppUnknown) {
+3 -11
View File
@@ -208,15 +208,11 @@ static HRESULT ffSaveThumbnailToTempPath(
}
static const char* getMedia(FFMediaResult* result, bool saveCover) {
// RO_INIT_MULTITHREADED is required for IRandomAccessStreamReference::OpenReadAsync to work correctly
HRESULT initHr = RoInitialize(RO_INIT_MULTITHREADED);
bool shouldUninitialize = SUCCEEDED(initHr);
if (FAILED(initHr) && initHr != RPC_E_CHANGED_MODE) {
return "winrt: RoInitialize() failed";
const char* error = ffInitCom();
if (error) {
return error;
}
const char* error = NULL;
do {
abi_t<winrt::Windows::Media::Control::IGlobalSystemMediaTransportControlsSessionManagerStatics>* FF_AUTO_RELEASE_COM_OBJECT managerStatics = NULL;
HRESULT hr = ffGetActivationFactory(L"Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager", winrt::guid_of<winrt::Windows::Media::Control::IGlobalSystemMediaTransportControlsSessionManagerStatics>(), &managerStatics);
@@ -325,10 +321,6 @@ static const char* getMedia(FFMediaResult* result, bool saveCover) {
}
} while (false);
if (shouldUninitialize) {
RoUninitialize();
}
return error;
}
#else