From 79b61f139183a9ded915024851ea36fa6fbd706b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 6 May 2026 14:38:10 +0800 Subject: [PATCH] Common (Windows): inits WinRT/COM globally --- src/common/windows/com.cpp | 48 +++++++++++---------------- src/common/windows/com.hpp | 1 + src/detection/media/media_windows.cpp | 14 ++------ 3 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/common/windows/com.cpp b/src/common/windows/com.cpp index 4ad067b8d..924baf414 100644 --- a/src/common/windows/com.cpp +++ b/src/common/windows/com.cpp @@ -1,40 +1,30 @@ #include "com.hpp" -#include "fastfetch.h" -#include +#include -// 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; } diff --git a/src/common/windows/com.hpp b/src/common/windows/com.hpp index 8a0de559f..eb6b10611 100644 --- a/src/common/windows/com.hpp +++ b/src/common/windows/com.hpp @@ -5,6 +5,7 @@ #include "common/attributes.h" #include +// Initialize COM & WinRT const char* ffInitCom(void); static inline void ffReleaseComObject(void* ppUnknown) { diff --git a/src/detection/media/media_windows.cpp b/src/detection/media/media_windows.cpp index 946b3e745..9a92440e3 100644 --- a/src/detection/media/media_windows.cpp +++ b/src/detection/media/media_windows.cpp @@ -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* FF_AUTO_RELEASE_COM_OBJECT managerStatics = NULL; HRESULT hr = ffGetActivationFactory(L"Windows.Media.Control.GlobalSystemMediaTransportControlsSessionManager", winrt::guid_of(), &managerStatics); @@ -325,10 +321,6 @@ static const char* getMedia(FFMediaResult* result, bool saveCover) { } } while (false); - if (shouldUninitialize) { - RoUninitialize(); - } - return error; } #else