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.Pointer;
24 import com.sun.jna.WString;
25 import com.sun.jna.platform.win32.COM.COMException;
26 import com.sun.jna.platform.win32.COM.COMUtils;
27 import com.sun.jna.platform.win32.COM.Wbemcli;
28 import com.sun.jna.platform.win32.COM.Wbemcli.IEnumWbemClassObject;
29 import com.sun.jna.platform.win32.COM.Wbemcli.IWbemClassObject;
30 import com.sun.jna.platform.win32.COM.Wbemcli.IWbemContext;
31 import com.sun.jna.platform.win32.COM.Wbemcli.IWbemLocator;
32 import com.sun.jna.platform.win32.COM.Wbemcli.IWbemServices;
33 import com.sun.jna.platform.win32.Guid.CLSID;
34 import com.sun.jna.platform.win32.Guid.GUID;
35 import com.sun.jna.platform.win32.Ole32;
36 import com.sun.jna.platform.win32.OleAuto;
37 import com.sun.jna.platform.win32.Variant;
38 import com.sun.jna.platform.win32.Variant.VARIANT;
39 import com.sun.jna.platform.win32.Variant.VARIANT.ByReference;
40 import com.sun.jna.platform.win32.WTypes;
41 import com.sun.jna.platform.win32.WTypes.BSTR;
42 import com.sun.jna.platform.win32.WinNT.HRESULT;
43 import com.sun.jna.ptr.IntByReference;
44 import com.sun.jna.ptr.PointerByReference;
45 import java.nio.charset.Charset;
46 import java.util.ArrayList;
47 import java.util.Collections;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Set;
52 import java.util.concurrent.TimeoutException;
53 import java.util.function.Function;
54 import java.util.stream.Collectors;
55 import java.util.stream.Stream;
56 import org.metricshub.wmi.AutoCloseableReadWriteLock;
57 import org.metricshub.wmi.Utils;
58 import org.metricshub.wmi.WmiHelper;
59 import org.metricshub.wmi.WqlQuery;
60 import org.metricshub.wmi.exceptions.WmiComException;
61 import org.metricshub.wmi.exceptions.WqlQuerySyntaxException;
62 import org.metricshub.wmi.remotecommand.RemoteProcess;
63 import org.metricshub.wmi.windows.remote.WindowsRemoteCommandResult;
64 import org.metricshub.wmi.windows.remote.WindowsRemoteExecutor;
65
66
67
68
69
70 public class WmiWbemServices implements WindowsRemoteExecutor {
71
72
73
74
75
76
77 private static final Map<Long, String> MAP_HRESULT_MESSAGE;
78
79 static {
80 final Map<Long, String> map = new HashMap<>();
81 map.put(2147749889L, "WBEM_E_FAILED: Call failed. (0x80041001)");
82 map.put(2147749890L, "WBEM_E_NOT_FOUND: Object cannot be found. (0x80041002)");
83 map.put(
84 2147749891L,
85 "WBEM_E_ACCESS_DENIED: Current user does not have permission to perform the action. (0x80041003)"
86 );
87 map.put(
88 2147749892L,
89 "WBEM_E_PROVIDER_FAILURE: Provider has failed at some time other than during initialization. (0x80041004)"
90 );
91 map.put(2147749893L, "WBEM_E_TYPE_MISMATCH: Type mismatch occurred. (0x80041005)");
92 map.put(2147749894L, "WBEM_E_OUT_OF_MEMORY: Not enough memory for the operation. (0x80041006)");
93 map.put(2147749895L, "WBEM_E_INVALID_CONTEXT: The IWbemContext object is not valid. (0x80041007)");
94 map.put(2147749896L, "WBEM_E_INVALID_PARAMETER: One of the parameters to the call is not correct. (0x80041008)");
95 map.put(
96 2147749897L,
97 "WBEM_E_NOT_AVAILABLE: Resource, typically a remote server, is not currently available. (0x80041009)"
98 );
99 map.put(
100 2147749898L,
101 "WBEM_E_CRITICAL_ERROR: Internal, critical, and unexpected error occurred. Report the error to Microsoft Technical Support. (0x8004100A)"
102 );
103 map.put(
104 2147749899L,
105 "WBEM_E_INVALID_STREAM: One or more network packets were corrupted during a remote session. (0x8004100B)"
106 );
107 map.put(2147749900L, "WBEM_E_NOT_SUPPORTED: Feature or operation is not supported. (0x8004100C)");
108 map.put(2147749901L, "WBEM_E_INVALID_SUPERCLASS: Parent class specified is not valid. (0x8004100D)");
109 map.put(2147749902L, "WBEM_E_INVALID_NAMESPACE: Namespace specified cannot be found. (0x8004100E)");
110 map.put(2147749903L, "WBEM_E_INVALID_OBJECT: Specified instance is not valid. (0x8004100F)");
111 map.put(2147749904L, "WBEM_E_INVALID_CLASS: Specified class is not valid. (0x80041010)");
112 map.put(
113 2147749905L,
114 "WBEM_E_PROVIDER_NOT_FOUND: Provider referenced in the schema does not have a corresponding registration. (0x80041011)"
115 );
116 map.put(
117 2147749906L,
118 "WBEM_E_INVALID_PROVIDER_REGISTRATION: Provider referenced in the schema has an incorrect or incomplete registration. (0x80041012)"
119 );
120 map.put(
121 2147749907L,
122 "WBEM_E_PROVIDER_LOAD_FAILURE: COM cannot locate a provider referenced in the schema. (0x80041013)"
123 );
124 map.put(
125 2147749908L,
126 "WBEM_E_INITIALIZATION_FAILURE: Component, such as a provider, failed to initialize for internal reasons. (0x80041014)"
127 );
128 map.put(
129 2147749909L,
130 "WBEM_E_TRANSPORT_FAILURE: Networking error that prevents normal operation has occurred. (0x80041015)"
131 );
132 map.put(
133 2147749910L,
134 "WBEM_E_INVALID_OPERATION: Requested operation is not valid. This error usually applies to invalid attempts to delete classes or properties. (0x80041016)"
135 );
136 map.put(2147749911L, "WBEM_E_INVALID_QUERY: Query was not syntactically valid. (0x80041017)");
137 map.put(2147749912L, "WBEM_E_INVALID_QUERY_TYPE: Requested query language is not supported. (0x80041018)");
138 map.put(
139 2147749913L,
140 "WBEM_E_ALREADY_EXISTS: In a put operation, the wbemChangeFlagCreateOnly flag was specified, but the instance already exists. (0x80041019)"
141 );
142 map.put(
143 2147749914L,
144 "WBEM_E_OVERRIDE_NOT_ALLOWED: Not possible to perform the add operation on this qualifier because the owning object does not permit overrides. (0x8004101A)"
145 );
146 map.put(
147 2147749915L,
148 "WBEM_E_PROPAGATED_QUALIFIER: User attempted to delete a qualifier that was not owned. The qualifier was inherited from a parent class. (0x8004101B)"
149 );
150 map.put(
151 2147749916L,
152 "WBEM_E_PROPAGATED_PROPERTY: User attempted to delete a property that was not owned. The property was inherited from a parent class. (0x8004101C)"
153 );
154 map.put(
155 2147749917L,
156 "WBEM_E_UNEXPECTED: Client made an unexpected and illegal sequence of calls, such as calling EndEnumeration before calling BeginEnumeration. (0x8004101D)"
157 );
158 map.put(
159 2147749918L,
160 "WBEM_E_ILLEGAL_OPERATION: User requested an illegal operation, such as spawning a class from an instance. (0x8004101E)"
161 );
162 map.put(
163 2147749919L,
164 "WBEM_E_CANNOT_BE_KEY: Illegal attempt to specify a key qualifier on a" +
165 " property that cannot be a key. The keys are specified in the class " +
166 "definition for an object and cannot be altered on a per-instance basis. " +
167 "(0x8004101F)"
168 );
169 map.put(
170 2147749920L,
171 "WBEM_E_INCOMPLETE_CLASS: Current object is not a valid class definition. " +
172 "Either it is incomplete or it has not been registered with WMI using SWbemObject." +
173 "Put_. (0x80041020)"
174 );
175 map.put(2147749921L, "WBEM_E_INVALID_SYNTAX: Query is syntactically not valid. (0x80041021)");
176 map.put(2147749922L, "WBEM_E_NONDECORATED_OBJECT: Reserved for future use. (0x80041022)");
177 map.put(2147749923L, "WBEM_E_READ_ONLY: An attempt was made to modify a read-only property. (0x80041023)");
178 map.put(
179 2147749924L,
180 "WBEM_E_PROVIDER_NOT_CAPABLE: Provider cannot perform the requested operation. " +
181 "This can include a query that is too complex, retrieving an instance, creating or " +
182 "updating a class, deleting a class, or enumerating a class. (0x80041024)"
183 );
184 map.put(
185 2147749925L,
186 "WBEM_E_CLASS_HAS_CHILDREN: Attempt was made to make a change that invalidates a subclass. (0x80041025)"
187 );
188 map.put(
189 2147749926L,
190 "WBEM_E_CLASS_HAS_INSTANCES: Attempt was made to delete or modify a class that has instances. (0x80041026)"
191 );
192 map.put(2147749927L, "WBEM_E_QUERY_NOT_IMPLEMENTED: Reserved for future use. (0x80041027)");
193 map.put(
194 2147749928L,
195 "WBEM_E_ILLEGAL_NULL: Value of Nothing/NULL was specified for a property " +
196 "that must have a value, such as one " +
197 "that is marked by a Key, Indexed, or Not_Null qualifier. (0x80041028)"
198 );
199 map.put(
200 2147749929L,
201 "WBEM_E_INVALID_QUALIFIER_TYPE: Variant value for a qualifier was provided that is not a legal qualifier type. (0x80041029)"
202 );
203 map.put(2147749930L, "WBEM_E_INVALID_PROPERTY_TYPE: CIM type specified for a property is not valid. (0x8004102A)");
204 map.put(
205 2147749931L,
206 "WBEM_E_VALUE_OUT_OF_RANGE: Request was made with an out-of-range value or it is incompatible with the type. (0x8004102B)"
207 );
208 map.put(
209 2147749932L,
210 "WBEM_E_CANNOT_BE_SINGLETON: Illegal attempt was made to make a class singleton, such as when the class is derived from a non-singleton class. (0x8004102C)"
211 );
212 map.put(2147749933L, "WBEM_E_INVALID_CIM_TYPE: CIM type specified is not valid. (0x8004102D)");
213 map.put(2147749934L, "WBEM_E_INVALID_METHOD: Requested method is not available. (0x8004102E)");
214 map.put(
215 2147749935L,
216 "WBEM_E_INVALID_METHOD_PARAMETERS: Parameters provided for the method are not valid. (0x8004102F)"
217 );
218 map.put(
219 2147749936L,
220 "WBEM_E_SYSTEM_PROPERTY: There was an attempt to get qualifiers on a system property. (0x80041030)"
221 );
222 map.put(2147749937L, "WBEM_E_INVALID_PROPERTY: Property type is not recognized. (0x80041031)");
223 map.put(
224 2147749938L,
225 "WBEM_E_CALL_CANCELLED: Asynchronous process has been canceled internally or by the user." +
226 " Note that due to the timing and nature of the asynchronous operation, the operation may " +
227 "not have been truly canceled. (0x80041032)"
228 );
229 map.put(
230 2147749939L,
231 "WBEM_E_SHUTTING_DOWN: User has requested an operation while WMI is in the process of shutting down. (0x80041033)"
232 );
233 map.put(
234 2147749940L,
235 "WBEM_E_PROPAGATED_METHOD: Attempt was made to reuse an existing method name from a parent class and the signatures do not match. (0x80041034)"
236 );
237 map.put(
238 2147749941L,
239 "WBEM_E_UNSUPPORTED_PARAMETER: One or more parameter values, such as a " +
240 "query text, is too complex or unsupported. WMI is therefore requested " +
241 "to retry the operation with simpler parameters. (0x80041035)"
242 );
243 map.put(2147749942L, "WBEM_E_MISSING_PARAMETER_ID: Parameter was missing from the method call. (0x80041036)");
244 map.put(
245 2147749943L,
246 "WBEM_E_INVALID_PARAMETER_ID: Method parameter has an ID qualifier that is not valid. (0x80041037)"
247 );
248 map.put(
249 2147749944L,
250 "WBEM_E_NONCONSECUTIVE_PARAMETER_IDS: One or more of the method parameters have ID qualifiers that are out of sequence. (0x80041038)"
251 );
252 map.put(2147749945L, "WBEM_E_PARAMETER_ID_ON_RETVAL: Return value for a method has an ID qualifier. (0x80041039)");
253 map.put(2147749946L, "WBEM_E_INVALID_OBJECT_PATH: Specified object path was not valid. (0x8004103A)");
254 map.put(
255 2147749947L,
256 "WBEM_E_OUT_OF_DISK_SPACE: Disk is out of space or the 4 GB limit on WMI repository (CIM repository) size is reached. (0x8004103B)"
257 );
258 map.put(
259 2147749948L,
260 "WBEM_E_BUFFER_TOO_SMALL: Supplied buffer was too small to hold all of the objects in the enumerator or to read a string property. (0x8004103C)"
261 );
262 map.put(
263 2147749949L,
264 "WBEM_E_UNSUPPORTED_PUT_EXTENSION: Provider does not support the requested put operation. (0x8004103D)"
265 );
266 map.put(
267 2147749950L,
268 "WBEM_E_UNKNOWN_OBJECT_TYPE: Object with an incorrect type or version was encountered during marshaling. (0x8004103E)"
269 );
270 map.put(
271 2147749951L,
272 "WBEM_E_UNKNOWN_PACKET_TYPE: Packet with an incorrect type or version was encountered during marshaling. (0x8004103F)"
273 );
274 map.put(2147749952L, "WBEM_E_MARSHAL_VERSION_MISMATCH: Packet has an unsupported version. (0x80041040)");
275 map.put(2147749953L, "WBEM_E_MARSHAL_INVALID_SIGNATURE: Packet appears to be corrupt. (0x80041041)");
276 map.put(
277 2147749954L,
278 "WBEM_E_INVALID_QUALIFIER: Attempt was made to mismatch qualifiers, such as putting [key] on an object instead of a property. (0x80041042)"
279 );
280 map.put(
281 2147749955L,
282 "WBEM_E_INVALID_DUPLICATE_PARAMETER: Duplicate parameter was declared in a CIM method. (0x80041043)"
283 );
284 map.put(2147749956L, "WBEM_E_TOO_MUCH_DATA: Reserved for future use. (0x80041044)");
285 map.put(
286 2147749957L,
287 "WBEM_E_SERVER_TOO_BUSY: Call to IWbemObjectSink::Indicate has failed. The provider can refire the event. (0x80041045)"
288 );
289 map.put(2147749958L, "WBEM_E_INVALID_FLAVOR: Specified qualifier flavor was not valid. (0x80041046)");
290 map.put(
291 2147749959L,
292 "WBEM_E_CIRCULAR_REFERENCE: Attempt was made to create a reference that is circular (for example, deriving a class from itself). (0x80041047)"
293 );
294 map.put(2147749960L, "WBEM_E_UNSUPPORTED_CLASS_UPDATE: Specified class is not supported. (0x80041048)");
295 map.put(
296 2147749961L,
297 "WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE: Attempt was made to change a key when instances or subclasses are already using the key. (0x80041049)"
298 );
299 map.put(
300 2147749968L,
301 "WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE: An attempt was made to change an index when instances or subclasses are already using the index. (0x80041050)"
302 );
303 map.put(
304 2147749969L,
305 "WBEM_E_TOO_MANY_PROPERTIES: Attempt was made to create more properties than the current version of the class supports. (0x80041051)"
306 );
307 map.put(
308 2147749970L,
309 "WBEM_E_UPDATE_TYPE_MISMATCH: Property was redefined with a conflicting type in a derived class. (0x80041052)"
310 );
311 map.put(
312 2147749971L,
313 "WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED: Attempt was made in a derived class to override a qualifier that cannot be overridden. (0x80041053)"
314 );
315 map.put(
316 2147749972L,
317 "WBEM_E_UPDATE_PROPAGATED_METHOD: Method was re-declared with a conflicting signature in a derived class. (0x80041054)"
318 );
319 map.put(
320 2147749973L,
321 "WBEM_E_METHOD_NOT_IMPLEMENTED: Attempt was made to execute a method not marked with [implemented] in any relevant class. (0x80041055)"
322 );
323 map.put(
324 2147749974L,
325 "WBEM_E_METHOD_DISABLED: Attempt was made to execute a method marked with [disabled]. (0x80041056)"
326 );
327 map.put(2147749975L, "WBEM_E_REFRESHER_BUSY: Refresher is busy with another operation. (0x80041057)");
328 map.put(2147749976L, "WBEM_E_UNPARSABLE_QUERY: Filtering query is syntactically not valid. (0x80041058)");
329 map.put(
330 2147749977L,
331 "WBEM_E_NOT_EVENT_CLASS: The FROM clause of a filtering query references a class that is not an event class (not derived from __Event). (0x80041059)"
332 );
333 map.put(
334 2147749978L,
335 "WBEM_E_MISSING_GROUP_WITHIN: A GROUP BY clause was used without the corresponding GROUP WITHIN clause. (0x8004105A)"
336 );
337 map.put(
338 2147749979L,
339 "WBEM_E_MISSING_AGGREGATION_LIST: A GROUP BY clause was used. Aggregation on all properties is not supported. (0x8004105B)"
340 );
341 map.put(
342 2147749980L,
343 "WBEM_E_PROPERTY_NOT_AN_OBJECT: Dot notation was used on a property that is not an embedded object. (0x8004105C)"
344 );
345 map.put(
346 2147749981L,
347 "WBEM_E_AGGREGATING_BY_OBJECT: A GROUP BY clause references a property that is an embedded object without using dot notation. (0x8004105D)"
348 );
349 map.put(
350 2147749983L,
351 "WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY: Event provider registration " +
352 "query (__EventProviderRegistration) did not specify the classes " +
353 "for which events were provided. (0x8004105F)"
354 );
355 map.put(
356 2147749984L,
357 "WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING: Request was made to back up " +
358 "or restore the repository while it was in use by WinMgmt.exe, " +
359 "or by the SVCHOST process that contains the WMI service. (0x80041060)"
360 );
361 map.put(
362 2147749985L,
363 "WBEM_E_QUEUE_OVERFLOW: Asynchronous delivery queue overflowed from the event consumer being too slow. (0x80041061)"
364 );
365 map.put(
366 2147749986L,
367 "WBEM_E_PRIVILEGE_NOT_HELD: Operation failed because the client did not have the necessary security privilege. (0x80041062)"
368 );
369 map.put(2147749987L, "WBEM_E_INVALID_OPERATOR: Operator is not valid for this property type. (0x80041063)");
370 map.put(
371 2147749988L,
372 "WBEM_E_LOCAL_CREDENTIALS: User specified a username/password/authority on a local connection. " +
373 "The user must use a blank username/password and rely on default security. (0x80041064)"
374 );
375 map.put(
376 2147749989L,
377 "WBEM_E_CANNOT_BE_ABSTRACT: Class was made abstract when its parent class is not abstract. (0x80041065)"
378 );
379 map.put(
380 2147749990L,
381 "WBEM_E_AMENDED_OBJECT: Amended object was written without the WBEM_FLAG_USE_AMENDED_QUALIFIERS flag being specified. (0x80041066)"
382 );
383 map.put(
384 2147749991L,
385 "WBEM_E_CLIENT_TOO_SLOW: Client did not retrieve objects quickly enough from an enumeration. " +
386 "This constant is returned when a client creates an enumeration object, but does not retrieve " +
387 "objects from the enumerator in a timely fashion, causing the enumerator's object caches to back up. (0x80041067)"
388 );
389 map.put(2147749992L, "WBEM_E_NULL_SECURITY_DESCRIPTOR: Null security descriptor was used. (0x80041068)");
390 map.put(2147749993L, "WBEM_E_TIMED_OUT: Operation timed out. (0x80041069)");
391 map.put(2147749994L, "WBEM_E_INVALID_ASSOCIATION: Association is not valid. (0x8004106A)");
392 map.put(2147749995L, "WBEM_E_AMBIGUOUS_OPERATION: Operation was ambiguous. (0x8004106B)");
393 map.put(
394 2147749996L,
395 "WBEM_E_QUOTA_VIOLATION: WMI is taking up too much memory. This can be caused by low memory availability or excessive memory consumption by WMI. (0x8004106C)"
396 );
397 map.put(2147749997L, "WBEM_E_TRANSACTION_CONFLICT: Operation resulted in a transaction conflict. (0x8004106D)");
398 map.put(2147749998L, "WBEM_E_FORCED_ROLLBACK: Transaction forced a rollback. (0x8004106E)");
399 map.put(2147749999L, "WBEM_E_UNSUPPORTED_LOCALE: Locale used in the call is not supported. (0x8004106F)");
400 map.put(2147750000L, "WBEM_E_HANDLE_OUT_OF_DATE: Object handle is out-of-date. (0x80041070)");
401 map.put(2147750001L, "WBEM_E_CONNECTION_FAILED: Connection to the SQL database failed. (0x80041071)");
402 map.put(2147750002L, "WBEM_E_INVALID_HANDLE_REQUEST: Handle request was not valid. (0x80041072)");
403 map.put(
404 2147750003L,
405 "WBEM_E_PROPERTY_NAME_TOO_WIDE: Property name contains more than 255 characters. (0x80041073)"
406 );
407 map.put(2147750004L, "WBEM_E_CLASS_NAME_TOO_WIDE: Class name contains more than 255 characters. (0x80041074)");
408 map.put(2147750005L, "WBEM_E_METHOD_NAME_TOO_WIDE: Method name contains more than 255 characters. (0x80041075)");
409 map.put(
410 2147750006L,
411 "WBEM_E_QUALIFIER_NAME_TOO_WIDE: Qualifier name contains more than 255 characters. (0x80041076)"
412 );
413 map.put(
414 2147750007L,
415 "WBEM_E_RERUN_COMMAND: The SQL command must be rerun because there is a deadlock in SQL. This can be returned only when data is being stored in an SQL database. (0x80041077)"
416 );
417 map.put(
418 2147750008L,
419 "WBEM_E_DATABASE_VER_MISMATCH: The database version does not match the version that the repository driver processes. (0x80041078)"
420 );
421 map.put(
422 2147750009L,
423 "WBEM_E_VETO_DELETE: WMI cannot execute the delete operation because the provider does not allow it. (0x80041079)"
424 );
425 map.put(
426 2147750010L,
427 "WBEM_E_VETO_PUT: WMI cannot execute the put operation because the provider does not allow it. (0x8004107A)"
428 );
429 map.put(
430 2147750016L,
431 "WBEM_E_INVALID_LOCALE: Specified locale identifier was not valid for the operation. (0x80041080)"
432 );
433 map.put(2147750017L, "WBEM_E_PROVIDER_SUSPENDED: Provider is suspended. (0x80041081)");
434 map.put(
435 2147750018L,
436 "WBEM_E_SYNCHRONIZATION_REQUIRED: Object must be written to the WMI repository and retrieved again before the requested operation can succeed." +
437 " This constant is returned when an object must be committed and retrieved to see the property value. (0x80041082)"
438 );
439 map.put(2147750019L, "WBEM_E_NO_SCHEMA: Operation cannot be completed; no schema is available. (0x80041083)");
440 map.put(
441 2147750020L,
442 "WBEM_E_PROVIDER_ALREADY_REGISTERED: Provider cannot be registered because it is already registered. (0x119FD010)"
443 );
444 map.put(2147750021L, "WBEM_E_PROVIDER_NOT_REGISTERED: Provider was not registered. (0x80041085)");
445 map.put(2147750022L, "WBEM_E_FATAL_TRANSPORT_ERROR: A fatal transport error occurred. (0x80041086)");
446 map.put(
447 2147750023L,
448 "WBEM_E_ENCRYPTED_CONNECTION_REQUIRED: User attempted to set a computer name or domain without an encrypted connection. (0x80041087)"
449 );
450 map.put(
451 2147750024L,
452 "WBEM_E_PROVIDER_TIMED_OUT: A provider failed to report results within the specified timeout. (0x80041088)"
453 );
454 map.put(2147750025L, "WBEM_E_NO_KEY: User attempted to put an instance with no defined key. (0x80041089)");
455 map.put(
456 2147750026L,
457 "WBEM_E_PROVIDER_DISABLED: User attempted to register a provider instance but the COM server for the provider instance was unloaded. (0x8004108A)"
458 );
459 map.put(
460 2147753985L,
461 "WBEMESS_E_REGISTRATION_TOO_BROAD: Provider registration overlaps with the system event domain. (0x80042001)"
462 );
463 map.put(
464 2147753986L,
465 "WBEMESS_E_REGISTRATION_TOO_PRECISE: A WITHIN clause was not used in this query. (0x80042002)"
466 );
467 map.put(
468 2147753987L,
469 "WBEMESS_E_AUTHZ_NOT_PRIVILEGED: This computer does not have the necessary domain permissions " +
470 "to support the security functions that relate to the created subscription instance. Contact the " +
471 "Domain Administrator to get this computer added to the Windows Authorization Access Group. (0x80042003)"
472 );
473 map.put(2147758081L, "WBEM_E_RETRY_LATER: Reserved for future use. (0x80043001)");
474 map.put(2147758082L, "WBEM_E_RESOURCE_CONTENTION: Reserved for future use. (0x80043002)");
475 map.put(2147762177L, "WBEMMOF_E_EXPECTED_QUALIFIER_NAME: Expected a qualifier name. (0x80044001)");
476 map.put(2147762178L, "WBEMMOF_E_EXPECTED_SEMI: Expected semicolon or '='. (0x80044002)");
477 map.put(2147762179L, "WBEMMOF_E_EXPECTED_OPEN_BRACE: Expected an opening brace. (0x80044003)");
478 map.put(
479 2147762180L,
480 "WBEMMOF_E_EXPECTED_CLOSE_BRACE: Missing closing brace or an illegal array element (0x80044004)"
481 );
482 map.put(2147762181L, "WBEMMOF_E_EXPECTED_CLOSE_BRACKET: Expected a closing bracket. (0x80044005)");
483 map.put(2147762182L, "WBEMMOF_E_EXPECTED_CLOSE_PAREN: Expected closing parenthesis. (0x80044006)");
484 map.put(
485 2147762183L,
486 "WBEMMOF_E_ILLEGAL_CONSTANT_VALUE: Numeric value out of range or strings without quotes. (0x80044007)"
487 );
488 map.put(2147762184L, "WBEMMOF_E_EXPECTED_TYPE_IDENTIFIER: Expected a type identifiers. (0x80044008)");
489 map.put(2147762185L, "WBEMMOF_E_EXPECTED_OPEN_PAREN: Expected an open parenthesis. (0x80044009)");
490 map.put(2147762186L, "WBEMMOF_E_UNRECOGNIZED_TOKEN: Unexpected token in the file. (0x8004400A)");
491 map.put(2147762187L, "WBEMMOF_E_UNRECOGNIZED_TYPE: Unrecognized or unsupported type identifier. (0x8004400B)");
492 map.put(2147762188L, "WBEMMOF_E_EXPECTED_PROPERTY_NAME: Expected property or method name. (0x8004400C)");
493 map.put(
494 2147762189L,
495 "WBEMMOF_E_TYPEDEF_NOT_SUPPORTED: Typedefs and enumerated types are not supported. (0x8004400D)"
496 );
497 map.put(
498 2147762190L,
499 "WBEMMOF_E_UNEXPECTED_ALIAS: Only a reference to a class object can have an alias value. (0x8004400E)"
500 );
501 map.put(
502 2147762191L,
503 "WBEMMOF_E_UNEXPECTED_ARRAY_INIT: Unexpected array initialization. Arrays must be declared with []. (0x8004400F)"
504 );
505 map.put(2147762192L, "WBEMMOF_E_INVALID_AMENDMENT_SYNTAX: Namespace path syntax is not valid. (0x80044010)");
506 map.put(2147762193L, "WBEMMOF_E_INVALID_DUPLICATE_AMENDMENT: Duplicate amendment specifiers. (0x80044011)");
507 map.put(2147762194L, "WBEMMOF_E_INVALID_PRAGMA: #pragma must be followed by a valid keyword. (0x80044012)");
508 map.put(2147762195L, "WBEMMOF_E_INVALID_NAMESPACE_SYNTAX: Namespace path syntax is not valid. (0x80044013)");
509 map.put(
510 2147762196L,
511 "WBEMMOF_E_EXPECTED_CLASS_NAME: Unexpected character in class name must be an identifier. (0x80044014)"
512 );
513 map.put(
514 2147762197L,
515 "WBEMMOF_E_TYPE_MISMATCH: The value specified cannot be made into the appropriate type. (0x80044015)"
516 );
517 map.put(
518 2147762198L,
519 "WBEMMOF_E_EXPECTED_ALIAS_NAME: Dollar sign must be followed by an alias name as an identifier. (0x80044016)"
520 );
521 map.put(2147762199L, "WBEMMOF_E_INVALID_CLASS_DECLARATION: Class declaration is not valid. (0x80044017)");
522 map.put(
523 2147762200L,
524 "WBEMMOF_E_INVALID_INSTANCE_DECLARATION: The instance declaration is not valid. It must start with \"instance of\". (0x80044018)"
525 );
526 map.put(
527 2147762201L,
528 "WBEMMOF_E_EXPECTED_DOLLAR: Expected dollar sign. An alias in the form \"$name\" must follow the \"as\" keyword. (0x80044019)"
529 );
530 map.put(
531 2147762202L,
532 "WBEMMOF_E_CIMTYPE_QUALIFIER: \"CIMTYPE\" qualifier cannot be specified directly in a MOF file. Use standard type notation. (0x8004401A)"
533 );
534 map.put(2147762203L, "WBEMMOF_E_DUPLICATE_PROPERTY: Duplicate property name was found in the MOF. (0x8004401B)");
535 map.put(
536 2147762204L,
537 "WBEMMOF_E_INVALID_NAMESPACE_SPECIFICATION: Namespace syntax is not valid. References to other servers are not allowed. (0x8004401C)"
538 );
539 map.put(2147762205L, "WBEMMOF_E_OUT_OF_RANGE: Value out of range. (0x8004401D)");
540 map.put(
541 2147762206L,
542 "WBEMMOF_E_INVALID_FILE: The file is not a valid text MOF file or binary MOF file. (0x8004401E)"
543 );
544 map.put(2147762207L, "WBEMMOF_E_ALIASES_IN_EMBEDDED: Embedded objects cannot be aliases. (0x8004401F)");
545 map.put(2147762208L, "WBEMMOF_E_NULL_ARRAY_ELEM: NULL elements in an array are not supported. (0x80044020)");
546 map.put(
547 2147762209L,
548 "WBEMMOF_E_DUPLICATE_QUALIFIER: Qualifier was used more than once on the object. (0x80044021)"
549 );
550 map.put(
551 2147762210L,
552 "WBEMMOF_E_EXPECTED_FLAVOR_TYPE: Expected a flavor type such as ToInstance, ToSubClass, EnableOverride, or DisableOverride. (0x80044022)"
553 );
554 map.put(
555 2147762211L,
556 "WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES: Combining EnableOverride and DisableOverride on same qualifier is not legal. (0x80044023)"
557 );
558 map.put(2147762212L, "WBEMMOF_E_MULTIPLE_ALIASES: An alias cannot be used twice. (0x80044024)");
559 map.put(
560 2147762213L,
561 "WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2: Combining Restricted, and ToInstance or ToSubClass is not legal. (0x80044025)"
562 );
563 map.put(2147762214L, "WBEMMOF_E_NO_ARRAYS_RETURNED: Methods cannot return array values. (0x80044026)");
564 map.put(2147762215L, "WBEMMOF_E_MUST_BE_IN_OR_OUT: Arguments must have an In or Out qualifier. (0x80044027)");
565 map.put(2147762216L, "WBEMMOF_E_INVALID_FLAGS_SYNTAX: Flags syntax is not valid. (0x80044028)");
566 map.put(
567 2147762217L,
568 "WBEMMOF_E_EXPECTED_BRACE_OR_BAD_TYPE: The final brace and semi-colon for a class are missing. (0x80044029)"
569 );
570 map.put(
571 2147762218L,
572 "WBEMMOF_E_UNSUPPORTED_CIMV22_QUAL_VALUE: A CIM version 2.2 feature is not supported for a qualifier value. (0x8004402A)"
573 );
574 map.put(
575 2147762219L,
576 "WBEMMOF_E_UNSUPPORTED_CIMV22_DATA_TYPE: The CIM version 2.2 data type is not supported. (0x8004402B)"
577 );
578 map.put(
579 2147762220L,
580 "WBEMMOF_E_INVALID_DELETEINSTANCE_SYNTAX: The delete instance syntax is not valid. It should be #pragma DeleteInstance(\"instancepath\", FAIL|NOFAIL). (0x8004402C)"
581 );
582 map.put(
583 2147762221L,
584 "WBEMMOF_E_INVALID_QUALIFIER_SYNTAX: The qualifier syntax is not valid. It should be qualifiername:type=value,scope(class|instance), flavorname. (0x8004402D)"
585 );
586 map.put(
587 2147762222L,
588 "WBEMMOF_E_QUALIFIER_USED_OUTSIDE_SCOPE: The qualifier is used outside of its scope. (0x8004402E)"
589 );
590 map.put(
591 2147762223L,
592 "WBEMMOF_E_ERROR_CREATING_TEMP_FILE: Error creating temporary file. The temporary file is an intermediate stage in the MOF compilation. (0x8004402F)"
593 );
594 map.put(
595 2147762224L,
596 "WBEMMOF_E_ERROR_INVALID_INCLUDE_FILE: A file included in the MOF by the preprocessor command #include is not valid. (0x80044030)"
597 );
598 map.put(
599 2147762225L,
600 "WBEMMOF_E_INVALID_DELETECLASS_SYNTAX: The syntax for the preprocessor commands #pragma deleteinstance or #pragma deleteclass is not valid. (0x80044031)"
601 );
602 MAP_HRESULT_MESSAGE = Collections.unmodifiableMap(map);
603 }
604
605
606
607
608
609
610
611
612
613 static void checkHResult(final HRESULT hResult, final String message) throws WmiComException {
614 Utils.checkNonNull(hResult, "hResult");
615 if (COMUtils.FAILED(hResult)) {
616 throw new WmiComException("%s. %s", message, getWmiComErrorMessage(hResult));
617 }
618 }
619
620
621
622
623
624
625
626 static String getWmiComErrorMessage(final HRESULT hResult) {
627 final int code = hResult.intValue();
628 return MAP_HRESULT_MESSAGE.getOrDefault(
629 Integer.toUnsignedLong(code),
630 String.format("code: 0x%s.", Integer.toHexString(code))
631 );
632 }
633
634
635
636
637
638
639 private static final CLSID CLSID_WBEM_CONTEXT = new CLSID("674B6698-EE92-11D0-AD71-00C04FD8FDFF");
640
641
642
643
644
645
646 private static final GUID IID_WBEM_CONTEXT = new GUID("44ACA674-E8FC-11D0-A07C-00C04FB68820");
647
648
649 private static final String WBEMCONTEXT_NAME_FOR_PROVIDER_ARCHITECTURE = "__ProviderArchitecture";
650
651 private static final int SET_VALUE_FUNCTION_VTABLE_ID_IN_WBEM_CONTEXT_INTERFACE = 8;
652
653 private static final int WBEM_SERVICES_GET_OBJECT_VTABLE_ID = 6;
654 private static final int WBEM_SERVICES_EXEC_METHOD_VTABLE_ID = 24;
655
656 private static final int WBEM_CLASS_OBJECT_PUT_VTABLE_ID = 5;
657 private static final int WBEM_CLASS_OBJECT_SPAWN_INSTANCE_VTABLE_ID = 15;
658 private static final int WBEM_CLASS_OBJECT_GET_METHOD_VTABLE_ID = 19;
659
660
661
662
663
664
665 private static final int WBEM_FLAG_RETURN_WBEM_COMPLETE = 0;
666
667 private static final String WQL = "WQL";
668
669
670
671
672
673 private final String hostname;
674
675
676 private final String username;
677
678
679 private final char[] password;
680
681
682 private final IWbemServices wbemServices;
683
684
685 private final IWbemLocator wbemLocator;
686
687
688 private final IWbemContext context;
689
690
691 private final CoAuthIdentity authIdent;
692
693
694 private boolean isClosed = false;
695
696
697 private AutoCloseableReadWriteLock lock;
698
699
700
701
702
703
704
705
706
707
708
709
710 private WmiWbemServices(
711 final String networkResource,
712 final String username,
713 final char[] password,
714 final IWbemServices wbemServices,
715 final IWbemLocator wbemLocator,
716 final IWbemContext context,
717 final CoAuthIdentity authIdent
718 ) {
719 this.networkResource = networkResource;
720 this.username = username;
721 this.password = password;
722 this.wbemServices = wbemServices;
723 this.wbemLocator = wbemLocator;
724 this.context = context;
725 this.authIdent = authIdent;
726 this.hostname =
727 (networkResource != null && networkResource.startsWith("\\\\")) ? networkResource.split("\\\\")[2] : null;
728 this.lock = new AutoCloseableReadWriteLock();
729 }
730
731
732
733
734
735
736
737
738
739
740 public static WmiWbemServices getInstance(final String networkResource, final String username, final char[] password)
741 throws WmiComException {
742 Utils.checkNonNull(networkResource, "networkResource");
743
744
745 if (WmiHelper.isLocalNetworkResource(networkResource) && (username != null || password != null)) {
746 throw new IllegalArgumentException("A local resource must be accessed without specific credentials");
747 }
748
749 IWbemLocator jnaWbemLocator = null;
750 IWbemContext jnaWbemContext = null;
751 IWbemServices jnaWbemServices = null;
752
753 try {
754
755
756 WmiComHelper.initializeComLibrary();
757
758
759
760 jnaWbemLocator = IWbemLocator.create();
761 if (jnaWbemLocator == null) {
762 throw new COMException("Failed to create WbemLocator object.");
763 }
764
765
766 jnaWbemContext = createWbemContextFor64BitWbemProvider();
767
768
769 jnaWbemServices =
770 jnaWbemLocator.ConnectServer(
771 networkResource,
772 username,
773 password == null ? null : String.valueOf(password),
774 null,
775 0,
776 null,
777 jnaWbemContext
778 );
779
780 final CoAuthIdentity authIdent = username != null && !username.isEmpty()
781 ? new CoAuthIdentity(username, password)
782 : null;
783
784
785
786 WmiWbemServices.setProxySecurity(jnaWbemServices.getPointer(), authIdent);
787
788 return new WmiWbemServices(
789 networkResource,
790 username,
791 password,
792 jnaWbemServices,
793 jnaWbemLocator,
794 jnaWbemContext,
795 authIdent
796 );
797 } catch (final COMException e) {
798
799 if (jnaWbemServices != null) {
800 jnaWbemServices.Release();
801 }
802
803 if (jnaWbemLocator != null) {
804 jnaWbemLocator.Release();
805 }
806
807 if (jnaWbemContext != null) {
808 jnaWbemContext.Release();
809 }
810
811 throw new WmiComException(e, e.getMessage());
812 }
813 }
814
815
816
817
818 @Override
819 public synchronized void close() {
820 try (AutoCloseableReadWriteLock.AutoCloseableWriteLock writeLock = lock.write()) {
821 isClosed = true;
822
823 if (context != null) {
824 context.Release();
825 }
826
827 if (wbemServices != null) {
828 wbemServices.Release();
829 }
830
831 if (wbemLocator != null) {
832 wbemLocator.Release();
833 }
834 }
835 }
836
837
838
839
840 private void checkState() {
841 if (isClosed) {
842 throw new IllegalStateException("This instance was closed");
843 }
844 }
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859 @Override
860 public List<Map<String, Object>> executeWql(final String wql, final long timeout)
861 throws TimeoutException, WqlQuerySyntaxException, WmiComException {
862
863 WqlQuery wqlQuery = WqlQuery.newInstance(wql);
864
865 return executeWql(wqlQuery, timeout);
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 public List<Map<String, Object>> executeWql(final WqlQuery wqlQuery, final long timeout)
882 throws TimeoutException, WmiComException, WqlQuerySyntaxException {
883 try (AutoCloseableReadWriteLock.AutoCloseableReadLock readLock = lock.read()) {
884 checkState();
885
886
887 Utils.checkNonNullField(wbemServices, "wbemServices");
888 Utils.checkNonNullField(wqlQuery, "wqlQuery");
889 Utils.checkArgumentNotZeroOrNegative(timeout, "timeout");
890
891
892 IEnumWbemClassObject wbemClassObjectQueryResult = null;
893 try {
894
895 wbemClassObjectQueryResult =
896 wbemServices.ExecQuery(
897 WQL,
898 wqlQuery.getCleanWql(),
899 Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_RETURN_IMMEDIATELY,
900 null
901 );
902
903 return processWqlResult(wbemClassObjectQueryResult, authIdent, timeout, wqlQuery.getSubPropertiesMap());
904 } catch (final COMException e) {
905
906 throw new WmiComException(e, e.getClass().getSimpleName() + ": " + e.getMessage());
907 } finally {
908 if (wbemClassObjectQueryResult != null) {
909 wbemClassObjectQueryResult.Release();
910 }
911 }
912 }
913 }
914
915 @Override
916 public WindowsRemoteCommandResult executeCommand(
917 final String command,
918 final String workingDirectory,
919 final Charset charset,
920 final long timeout
921 ) throws WmiComException, TimeoutException {
922 RemoteProcess.executeCommand(command, hostname, username, password, workingDirectory, timeout);
923 return null;
924 }
925
926
927
928
929
930
931
932
933
934 static void setProxySecurity(final Pointer pProxy, final CoAuthIdentity authIdent) throws WmiComException {
935
936
937 final HRESULT hResult = Ole32Enhanced.INSTANCE.CoSetProxyBlanket(
938 pProxy,
939 Ole32Enhanced.RPC_C_AUTHN_DEFAULT,
940 Ole32Enhanced.RPC_C_AUTHZ_DEFAULT,
941 null,
942 Ole32.RPC_C_AUTHN_LEVEL_CALL,
943 Ole32.RPC_C_IMP_LEVEL_IMPERSONATE,
944 authIdent,
945 Ole32.EOAC_NONE
946 );
947 checkHResult(hResult, "Could not set proxy blanket");
948 }
949
950
951
952
953
954
955
956
957
958
959
960 static IWbemContext createWbemContextFor64BitWbemProvider() {
961
962 try {
963 WmiComHelper.initializeComLibrary();
964 } catch (final WmiComException e) {
965 return null;
966 }
967
968
969 final PointerByReference contextPointer = new PointerByReference();
970 final HRESULT hCoCreateInstanceResult = Ole32.INSTANCE.CoCreateInstance(
971 CLSID_WBEM_CONTEXT,
972 null,
973 WTypes.CLSCTX_INPROC_SERVER,
974 IID_WBEM_CONTEXT,
975 contextPointer
976 );
977 if (COMUtils.FAILED(hCoCreateInstanceResult)) {
978 return null;
979 }
980
981
982 final VARIANT value64 = new VARIANT(64);
983 final ByReference byReference64 = new ByReference(value64);
984 try {
985 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
986 contextPointer.getValue(),
987 SET_VALUE_FUNCTION_VTABLE_ID_IN_WBEM_CONTEXT_INTERFACE,
988 new Object[] {
989 contextPointer.getValue(),
990 new WString(WBEMCONTEXT_NAME_FOR_PROVIDER_ARCHITECTURE),
991 0,
992 byReference64
993 },
994 HRESULT.class
995 );
996 return COMUtils.FAILED(hResult) ? null : new IWbemContext(contextPointer.getValue());
997 } finally {
998 OleAuto.INSTANCE.VariantClear(byReference64);
999 OleAuto.INSTANCE.VariantClear(value64);
1000 }
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 private List<Map<String, Object>> processWqlResult(
1018 final IEnumWbemClassObject wbemClassObjectQueryResult,
1019 final CoAuthIdentity authIdent,
1020 final long timeout,
1021 final Map<String, Set<String>> properties
1022 ) throws TimeoutException, WmiComException, WqlQuerySyntaxException {
1023 final Pointer[] pointersOnWbemClassObject = new Pointer[1];
1024 final List<Map<String, Object>> resultRows = new ArrayList<>();
1025 String[] names = null;
1026 Map<String, Set<String>> normalizedProperties = null;
1027
1028 if (wbemClassObjectQueryResult.getPointer() != Pointer.NULL) {
1029 setProxySecurity(wbemClassObjectQueryResult.getPointer(), authIdent);
1030 }
1031
1032 while (wbemClassObjectQueryResult.getPointer() != Pointer.NULL) {
1033
1034 final HRESULT hResult = wbemClassObjectQueryResult.Next(
1035 (int) timeout,
1036 pointersOnWbemClassObject.length,
1037 pointersOnWbemClassObject,
1038 new IntByReference(0)
1039 );
1040
1041
1042 if (
1043 hResult == null ||
1044 hResult.intValue() == Wbemcli.WBEM_S_FALSE ||
1045 hResult.intValue() == Wbemcli.WBEM_S_NO_MORE_DATA
1046 ) {
1047 return resultRows;
1048 }
1049 if (hResult.intValue() == Wbemcli.WBEM_S_TIMEDOUT) {
1050 throw new TimeoutException("No results after " + timeout + " ms.");
1051 }
1052 if (Integer.toUnsignedLong(hResult.intValue()) == 2147749911L) {
1053 throw new WqlQuerySyntaxException("The query was not syntactically valid.");
1054 }
1055 checkHResult(hResult, "Failed to enumerate results");
1056
1057
1058 final IWbemClassObject wbemClassObject = new IWbemClassObject(pointersOnWbemClassObject[0]);
1059
1060 try {
1061
1062
1063 if (names == null) {
1064 try {
1065 names = wbemClassObject.GetNames(null, 0, null);
1066 } catch (final Throwable e) {
1067 names = wbemClassObject.GetNames(null, 0, null);
1068 }
1069 }
1070
1071 if (normalizedProperties == null) {
1072 normalizedProperties = normalizeProperties(names, properties);
1073 }
1074
1075
1076 final Map<String, Object> values = getPropertiesValues(normalizedProperties, wbemClassObject);
1077 resultRows.add(values);
1078 } finally {
1079
1080 wbemClassObject.Release();
1081 }
1082 }
1083
1084 return resultRows;
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094 private static HashMap<String, Object> getPropertiesValues(
1095 final Map<String, Set<String>> properties,
1096 final IWbemClassObject wbemClassObject
1097 ) {
1098 return properties
1099 .entrySet()
1100 .stream()
1101 .map(entry -> WmiCimTypeHandler.getPropertyValue(wbemClassObject, entry))
1102 .flatMap(map -> map.entrySet().stream())
1103 .collect(HashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), HashMap::putAll);
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113 private static Map<String, Set<String>> normalizeProperties(
1114 final String[] names,
1115 final Map<String, Set<String>> properties
1116 ) {
1117 final Map<String, String> propertiesNames = Stream
1118 .of(names)
1119 .collect(Collectors.toMap(String::toLowerCase, Function.identity()));
1120
1121 return properties == null || properties.isEmpty()
1122 ? propertiesNames.values().stream().collect(Collectors.toMap(Function.identity(), p -> Collections.emptySet()))
1123 : properties
1124 .entrySet()
1125 .stream()
1126 .collect(
1127 HashMap::new,
1128 (map, entry) -> map.put(propertiesNames.get(entry.getKey().toLowerCase()), entry.getValue()),
1129 HashMap::putAll
1130 );
1131 }
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 public Pointer getObject(final String objectPath) throws WmiComException {
1146 try (AutoCloseableReadWriteLock.AutoCloseableReadLock readLock = lock.read()) {
1147 checkState();
1148
1149 Utils.checkNonNull(objectPath, "objectPath");
1150
1151 final Pointer pWbemServices = wbemServices.getPointer();
1152
1153 final BSTR strObjectPath = OleAuto.INSTANCE.SysAllocString(objectPath);
1154 final int lFlags = WBEM_FLAG_RETURN_WBEM_COMPLETE;
1155 final Pointer pCtx = null;
1156 final PointerByReference ppObject = new PointerByReference();
1157 final PointerByReference ppCallResult = null;
1158
1159 try {
1160 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
1161 pWbemServices,
1162 WBEM_SERVICES_GET_OBJECT_VTABLE_ID,
1163 new Object[] { pWbemServices, strObjectPath, lFlags, pCtx, ppObject, ppCallResult },
1164 HRESULT.class
1165 );
1166 WmiWbemServices.checkHResult(hResult, "Fail to invoke WbemServices::GetObject method");
1167
1168 return ppObject.getValue();
1169 } finally {
1170 OleAuto.INSTANCE.SysFreeString(strObjectPath);
1171 }
1172 }
1173 }
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 public Map<String, Object> executeMethod(
1187 final String objectPath,
1188 final String className,
1189 final String methodName,
1190 final Map<String, Object> inputMap
1191 ) throws WmiComException {
1192 try (AutoCloseableReadWriteLock.AutoCloseableReadLock readLock = lock.read()) {
1193 checkState();
1194
1195
1196 final IWbemClassObject classDefinition = new IWbemClassObject(getObject(className));
1197
1198
1199 final IWbemClassObject methodDefinition;
1200 try {
1201 methodDefinition = new IWbemClassObject(getMethod(classDefinition.getPointer(), methodName));
1202 } finally {
1203 classDefinition.Release();
1204 }
1205
1206
1207 final IWbemClassObject methodInputs;
1208 try {
1209 methodInputs = new IWbemClassObject(spawnInstance(methodDefinition.getPointer()));
1210 } finally {
1211 methodDefinition.Release();
1212 }
1213
1214
1215 final Map<String, VARIANT> variantInputMap = new HashMap<>();
1216 inputMap.forEach((name, value) -> {
1217 VARIANT variant;
1218 if (value == null) {
1219 variant = new VARIANT();
1220 } else if (value instanceof String) {
1221 variant = new VARIANT((String) value);
1222 } else if (value instanceof Integer) {
1223 variant = new VARIANT((int) value);
1224 } else if (value instanceof Pointer) {
1225 variant = new VARIANT((Pointer) value);
1226 } else {
1227 throw new IllegalArgumentException("Unsupported object type for " + name);
1228 }
1229 variantInputMap.put(name, variant);
1230 });
1231
1232
1233 final IWbemClassObject methodOutputs;
1234 try {
1235 for (final Map.Entry<String, VARIANT> inputEntry : variantInputMap.entrySet()) {
1236 objectPut(methodInputs.getPointer(), inputEntry.getKey(), inputEntry.getValue());
1237 }
1238
1239 methodOutputs = new IWbemClassObject(executeMethod(objectPath, methodName, methodInputs.getPointer()));
1240 } finally {
1241 variantInputMap.forEach((name, value) -> OleAuto.INSTANCE.VariantClear(value));
1242 methodInputs.Release();
1243 }
1244
1245
1246 try {
1247 String[] properties;
1248 try {
1249 properties = methodOutputs.GetNames(null, 0, null);
1250 } catch (final Throwable e) {
1251 properties = methodOutputs.GetNames(null, 0, null);
1252 }
1253
1254 final Map<String, Set<String>> normalizedProperties = normalizeProperties(properties, null);
1255
1256 return getPropertiesValues(normalizedProperties, methodOutputs);
1257 } finally {
1258 methodOutputs.Release();
1259 }
1260 }
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 Pointer executeMethod(final String objectPath, final String methodName, final Pointer pInParams)
1279 throws WmiComException {
1280 Utils.checkNonNull(objectPath, "objectPath");
1281 Utils.checkNonNull(methodName, "methodName");
1282
1283 final Pointer pWbemServices = wbemServices.getPointer();
1284
1285 final BSTR strObjectPath = OleAuto.INSTANCE.SysAllocString(objectPath);
1286 final BSTR strMethodName = OleAuto.INSTANCE.SysAllocString(methodName);
1287 final int lFlags = 0;
1288 final Pointer pCtx = null;
1289 final PointerByReference ppOutParams = new PointerByReference();
1290 final PointerByReference ppCallResult = null;
1291
1292 try {
1293 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
1294 pWbemServices,
1295 WBEM_SERVICES_EXEC_METHOD_VTABLE_ID,
1296 new Object[] {
1297 pWbemServices,
1298 strObjectPath,
1299 strMethodName,
1300 lFlags,
1301 pCtx,
1302 pInParams,
1303 ppOutParams,
1304 ppCallResult
1305 },
1306 HRESULT.class
1307 );
1308 WmiWbemServices.checkHResult(hResult, "Failed to invoke WbemServices::ExecMethod method");
1309 return ppOutParams.getValue();
1310 } finally {
1311 OleAuto.INSTANCE.SysFreeString(strObjectPath);
1312 OleAuto.INSTANCE.SysFreeString(strMethodName);
1313 }
1314 }
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 public void objectPut(final Pointer pWbemClassObject, final String propertyName, final Variant.VARIANT pVal)
1329 throws WmiComException {
1330 try (AutoCloseableReadWriteLock.AutoCloseableReadLock readLock = lock.read()) {
1331 checkState();
1332
1333 Utils.checkNonNull(pWbemClassObject, "pWbemClassObject");
1334 Utils.checkNonNull(propertyName, "propertyName");
1335
1336 final WString wszName = new WString(propertyName);
1337
1338
1339
1340
1341 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
1342 pWbemClassObject,
1343 WBEM_CLASS_OBJECT_PUT_VTABLE_ID,
1344 new Object[] {
1345 pWbemClassObject,
1346 wszName,
1347 0,
1348 pVal,
1349 0
1350 },
1351 HRESULT.class
1352 );
1353 WmiWbemServices.checkHResult(hResult, "Fail to invoke IWbemClassObject::Put method");
1354 }
1355 }
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367 public Pointer spawnInstance(final Pointer pWbemClassObject) throws WmiComException {
1368 try (AutoCloseableReadWriteLock.AutoCloseableReadLock readLock = lock.read()) {
1369 checkState();
1370
1371 Utils.checkNonNull(pWbemClassObject, "pWbemClassObject");
1372
1373 final int lFlags = 0;
1374 final PointerByReference ppNewInstance = new PointerByReference();
1375
1376 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
1377 pWbemClassObject,
1378 WBEM_CLASS_OBJECT_SPAWN_INSTANCE_VTABLE_ID,
1379 new Object[] { pWbemClassObject, lFlags, ppNewInstance },
1380 HRESULT.class
1381 );
1382 WmiWbemServices.checkHResult(hResult, "Fail to invoke IWbemClassObject::SpawnInstance method");
1383
1384 return ppNewInstance.getValue();
1385 }
1386 }
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399 Pointer getMethod(final Pointer pWbemClassObject, final String methodName) throws WmiComException {
1400 Utils.checkNonNull(pWbemClassObject, "pWbemClassObject");
1401 Utils.checkNonNull(methodName, "methodName");
1402
1403 final WString wszName = new WString(methodName);
1404 final int lFlags = 0;
1405 final PointerByReference ppInSignature = new PointerByReference();
1406 final PointerByReference ppOutSignature = null;
1407
1408 final HRESULT hResult = (HRESULT) WmiComHelper.comInvokerInvokeNativeObject(
1409 pWbemClassObject,
1410 WBEM_CLASS_OBJECT_GET_METHOD_VTABLE_ID,
1411 new Object[] { pWbemClassObject, wszName, lFlags, ppInSignature, ppOutSignature },
1412 HRESULT.class
1413 );
1414 WmiWbemServices.checkHResult(hResult, "Fail to invoke IWbemClassObject::getMethod method");
1415 return ppInSignature.getValue();
1416 }
1417
1418 public String getNetworkResource() {
1419 return networkResource;
1420 }
1421
1422 @Override
1423 public String getHostname() {
1424 return hostname;
1425 }
1426
1427 @Override
1428 public String getUsername() {
1429 return username;
1430 }
1431
1432 @Override
1433 public char[] getPassword() {
1434 return password;
1435 }
1436
1437 public IWbemServices getWbemServices() {
1438 return wbemServices;
1439 }
1440
1441 public IWbemLocator getWbemLocator() {
1442 return wbemLocator;
1443 }
1444
1445 public IWbemContext getContext() {
1446 return context;
1447 }
1448
1449 public CoAuthIdentity getAuthIdent() {
1450 return authIdent;
1451 }
1452
1453 public boolean isClosed() {
1454 return isClosed;
1455 }
1456 }