master
c 110 lines 2.55 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "windows-wmi.h"
4
5 #if defined(OS_WINDOWS)
6
7 __thread ND_WMI nd_wmi = { 0 };
8
9 HRESULT InitializeWMI(void) {
10 if(nd_wmi.pLoc && nd_wmi.pSvc) return S_OK;
11 CleanupWMI();
12
13 IWbemLocator **pLoc = &nd_wmi.pLoc;
14 IWbemServices **pSvc = &nd_wmi.pSvc;
15
16 HRESULT hr;
17
18 // Initialize COM
19 hr = CoInitializeEx(0, COINIT_MULTITHREADED);
20 if (FAILED(hr)) {
21 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Failed to initialize COM library. Error code = 0x%X", hr);
22 CleanupWMI();
23 return hr;
24 }
25
26 // Set COM security levels
27 hr = CoInitializeSecurity(
28 NULL,
29 -1,
30 NULL,
31 NULL,
32 RPC_C_AUTHN_LEVEL_DEFAULT,
33 RPC_C_IMP_LEVEL_IMPERSONATE,
34 NULL,
35 EOAC_NONE,
36 NULL
37 );
38 if (FAILED(hr)) {
39 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Failed to initialize security. Error code = 0x%X", hr);
40 CleanupWMI();
41 return hr;
42 }
43
44 // Obtain the initial locator to WMI
45 hr = CoCreateInstance(
46 &CLSID_WbemLocator, 0,
47 CLSCTX_INPROC_SERVER,
48 &IID_IWbemLocator, (LPVOID *)pLoc
49 );
50 if (FAILED(hr)) {
51 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Failed to create IWbemLocator object. Error code = 0x%X", hr);
52 CleanupWMI();
53 return hr;
54 }
55
56 // Connect to WMI
57 BSTR namespacePath = SysAllocString(L"ROOT\\CIMV2");
58 hr = (*pLoc)->lpVtbl->ConnectServer(
59 *pLoc,
60 namespacePath,
61 NULL,
62 NULL,
63 0,
64 0,
65 0,
66 0,
67 pSvc
68 );
69 SysFreeString(namespacePath);
70
71 if (FAILED(hr)) {
72 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Could not connect to WMI server. Error code = 0x%X", hr);
73 CleanupWMI();
74 return hr;
75 }
76
77 // Set security levels on the proxy
78 hr = CoSetProxyBlanket(
79 (IUnknown *)*pSvc,
80 RPC_C_AUTHN_WINNT,
81 RPC_C_AUTHZ_NONE,
82 NULL,
83 RPC_C_AUTHN_LEVEL_CALL,
84 RPC_C_IMP_LEVEL_IMPERSONATE,
85 NULL,
86 EOAC_NONE
87 );
88 if (FAILED(hr)) {
89 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Could not set proxy blanket. Error code = 0x%X", hr);
90 CleanupWMI();
91 return hr;
92 }
93
94 return S_OK;
95 }
96
97 void CleanupWMI(void) {
98 if(nd_wmi.pLoc)
99 nd_wmi.pLoc->lpVtbl->Release(nd_wmi.pLoc);
100
101 if (nd_wmi.pSvc)
102 nd_wmi.pSvc->lpVtbl->Release(nd_wmi.pSvc);
103
104 nd_wmi.pLoc = NULL;
105 nd_wmi.pSvc = NULL;
106
107 CoUninitialize();
108 }
109
110 #endif