1 package org.metricshub.wmi.wbem;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import com.sun.jna.Native;
24 import com.sun.jna.Pointer;
25 import com.sun.jna.platform.win32.COM.COMUtils;
26 import com.sun.jna.platform.win32.Ole32;
27 import com.sun.jna.platform.win32.WinError;
28 import com.sun.jna.platform.win32.WinNT.HRESULT;
29 import org.metricshub.wmi.exceptions.WmiComException;
30
31
32
33
34 public class WmiComHelper {
35
36
37
38
39 private WmiComHelper() {}
40
41
42
43
44 private static ThreadLocal<Boolean> comLibraryInitialized = ThreadLocal.withInitial(() -> false);
45
46
47
48
49
50
51
52
53
54
55
56
57 public static void initializeComLibrary() throws WmiComException {
58
59 if (Boolean.TRUE.equals(comLibraryInitialized.get())) {
60 return;
61 }
62
63
64
65 final HRESULT hCoInitResult = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED);
66 final int coInitResult = hCoInitResult.intValue();
67 if (coInitResult == WinError.RPC_E_CHANGED_MODE) {
68 throw new IllegalStateException("CoInitializeEx() has already been called with a different threading model");
69 } else if (coInitResult != COMUtils.S_OK && coInitResult != COMUtils.S_FALSE) {
70 throw new WmiComException(
71 "Failed to initialize the COM Library (HRESULT=0x%s)",
72 Integer.toHexString(coInitResult)
73 );
74 }
75
76
77
78
79
80 final HRESULT hResult = Ole32.INSTANCE.CoInitializeSecurity(
81 null,
82 -1,
83 null,
84 null,
85 Ole32.RPC_C_AUTHN_LEVEL_DEFAULT,
86 Ole32.RPC_C_IMP_LEVEL_IMPERSONATE,
87 null,
88 Ole32.EOAC_NONE,
89 null
90 );
91
92
93
94
95
96 if (COMUtils.FAILED(hResult) && hResult.intValue() != WinError.RPC_E_TOO_LATE) {
97 unInitializeCom();
98 throw new WmiComException(
99 "Failed to initialize security (HRESULT=0x%s)",
100 Integer.toHexString(hResult.intValue())
101 );
102 }
103
104
105 comLibraryInitialized.set(true);
106 }
107
108
109
110
111 public static void unInitializeCom() {
112
113 if (Boolean.FALSE.equals(comLibraryInitialized.get())) {
114 return;
115 }
116
117 Ole32.INSTANCE.CoUninitialize();
118 comLibraryInitialized.set(false);
119 }
120
121
122
123
124 public static boolean isComInitialized() {
125 return comLibraryInitialized.get();
126 }
127
128
129
130
131
132
133
134
135
136
137 public static Object comInvokerInvokeNativeObject(
138 final Pointer contextPointer,
139 final int vtableId,
140 final Object[] args,
141 final Class<?> returnType
142 ) {
143 final Pointer vptr = contextPointer.getPointer(0);
144 final com.sun.jna.Function func = com.sun.jna.Function.getFunction(
145 vptr.getPointer(vtableId * Native.POINTER_SIZE * 1L)
146 );
147 return func.invoke(returnType, args);
148 }
149 }