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}