master ohmu/fastfetch-openbsd / src / common / windows / com.c
ohmu  ·  2026-10-15
 1#include "com.h"
 2#include "common/debug.h"
 3
 4#include <stdlib.h>
 5
 6#if FF_HAVE_WINRT
 7    #include <roapi.h>
 8
 9static void RoUninitializeWrap(void) {
10    RoUninitialize();
11}
12
13static const char* doInitCom() {
14    HRESULT res = RoInitialize(RO_INIT_MULTITHREADED);
15    if (FAILED(res)) {
16        switch (res) {
17            case E_INVALIDARG:
18                FF_DEBUG("RoInitialize() failed: invalid argument: 0x%08lX (%s)", res, ffDebugHResult(res));
19                return "RoInitialize() failed: invalid argument";
20            case E_OUTOFMEMORY:
21                FF_DEBUG("RoInitialize() failed: out of memory: 0x%08lX (%s)", res, ffDebugHResult(res));
22                return "RoInitialize() failed: out of memory";
23            case E_UNEXPECTED:
24                FF_DEBUG("RoInitialize() failed: unexpected error: 0x%08lX (%s)", res, ffDebugHResult(res));
25                return "RoInitialize() failed: unexpected error";
26            case RPC_E_CHANGED_MODE:
27                // COM was already initialized with a different concurrency model
28                return nullptr;
29            default:
30                FF_DEBUG("RoInitialize() failed: unknown error: 0x%08lX (%s)", res, ffDebugHResult(res));
31                return "RoInitialize() failed: unknown error";
32        }
33    }
34
35    atexit(RoUninitializeWrap);
36    return nullptr;
37}
38#else
39    #include <combaseapi.h>
40
41static void CoUninitializeWrap(void) {
42    CoUninitialize();
43}
44
45static const char* doInitCom() {
46    HRESULT res = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
47    if (FAILED(res)) {
48        switch (res) {
49            case E_INVALIDARG:
50                FF_DEBUG("CoInitializeEx() failed: invalid argument: 0x%08lX (%s)", res, ffDebugHResult(res));
51                return "CoInitializeEx() failed: invalid argument";
52            case E_OUTOFMEMORY:
53                FF_DEBUG("CoInitializeEx() failed: out of memory: 0x%08lX (%s)", res, ffDebugHResult(res));
54                return "CoInitializeEx() failed: out of memory";
55            case RPC_E_CHANGED_MODE:
56                // COM was already initialized with a different concurrency model
57                return nullptr;
58            default:
59                FF_DEBUG("CoInitializeEx() failed: unknown error: 0x%08lX (%s)", res, ffDebugHResult(res));
60                return "CoInitializeEx() failed: unknown error";
61        }
62    }
63
64    atexit(CoUninitializeWrap);
65    return nullptr;
66}
67#endif
68
69const char* ffInitCom(void) {
70    static const char* error = "";
71    if (error && error[0] == '\0') {
72        error = doInitCom();
73    }
74    return error;
75}