Skip to content

Commit 529b716

Browse files
Merge pull request #1474 from rchateauneu/wbem_classes_and_methods
Added WBEM methods and a class.
2 parents 673079f + 58dc89d commit 529b716

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Features
1010
* [#1454](https://github.com/java-native-access/jna/pull/1454): Add `c.s.j.p.win32.Psapi.QueryWorkingSetEx` and associated Types - [@crain-32](https://github.com/Crain-32).
1111
* [#1459](https://github.com/java-native-access/jna/pull/1459): Add `VirtualLock` and `VirtualUnlock` in `c.s.j.p.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
1212
* [#1471](https://github.com/java-native-access/jna/pull/1471): Add `c.s.j.p.win32.Advapi32Util#isCurrentProcessElevated` and associated Types - [@dbwiddis](https://github.com/dbwiddis).
13+
* [#1474](https://github.com/java-native-access/jna/pull/1474): Add `c.s.j.p.win32.WbemCli#IWbemClassObject.IWbemQualifierSet`, `IWbemServices.GetObject`, `IWbemContext.SetValue` and associated methods - [@rchateauneu](https://github.com/rchateauneu).
1314

1415
Bug Fixes
1516
---------

contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java

+157
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
import com.sun.jna.Pointer;
2727
import com.sun.jna.WString;
28+
import com.sun.jna.platform.win32.*;
29+
import com.sun.jna.platform.win32.COM.COMUtils;
30+
import com.sun.jna.platform.win32.COM.Unknown;
2831
import com.sun.jna.platform.win32.Guid.CLSID;
2932
import com.sun.jna.platform.win32.Guid.GUID;
3033
import com.sun.jna.platform.win32.OaIdl.SAFEARRAY;
@@ -45,8 +48,16 @@
4548
*/
4649
public interface Wbemcli {
4750

51+
public static final int WBEM_FLAG_RETURN_WBEM_COMPLETE = 0x00000000;
4852
public static final int WBEM_FLAG_RETURN_IMMEDIATELY = 0x00000010;
4953
public static final int WBEM_FLAG_FORWARD_ONLY = 0x00000020;
54+
public static final int WBEM_FLAG_NO_ERROR_OBJECT = 0x00000040;
55+
public static final int WBEM_FLAG_SEND_STATUS = 0x00000080;
56+
public static final int WBEM_FLAG_ENSURE_LOCATABLE = 0x00000100;
57+
public static final int WBEM_FLAG_DIRECT_READ = 0x00000200;
58+
public static final int WBEM_MASK_RESERVED_FLAGS = 0x0001F000;
59+
public static final int WBEM_FLAG_USE_AMENDED_QUALIFIERS = 0x00020000;
60+
public static final int WBEM_FLAG_STRONG_VALIDATION = 0x00100000;
5061
public static final int WBEM_INFINITE = 0xFFFFFFFF;
5162

5263
// Non-error constants
@@ -146,6 +157,88 @@ public String[] GetNames(String wszQualifierName, int lFlags, VARIANT.ByReferenc
146157
}
147158
return names;
148159
}
160+
161+
public HRESULT GetQualifierSet(PointerByReference ppQualSet) {
162+
// Get is the fourth method of IWbemClassObjectVtbl in WbemCli.h :
163+
return (HRESULT) _invokeNativeObject(3,
164+
new Object[] { getPointer(), ppQualSet }, HRESULT.class);
165+
}
166+
167+
public IWbemQualifierSet GetQualifierSet() {
168+
PointerByReference ppQualSet = new PointerByReference();
169+
HRESULT hr = GetQualifierSet(ppQualSet);
170+
COMUtils.checkRC(hr);
171+
IWbemQualifierSet qualifier = new IWbemQualifierSet(ppQualSet.getValue());
172+
173+
return qualifier;
174+
}
175+
176+
/*
177+
// https://docs.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-iwbemclassobject-getpropertyqualifierset
178+
HRESULT GetPropertyQualifierSet(
179+
[in] LPCWSTR wszProperty,
180+
[out] IWbemQualifierSet **ppQualSet
181+
);
182+
*/
183+
public HRESULT GetPropertyQualifierSet(WString wszProperty, PointerByReference ppQualSet) {
184+
// Get is 12th method of IWbemClassObjectVtbl in WbemCli.h :
185+
return (HRESULT) _invokeNativeObject(11,
186+
new Object[] { getPointer(), wszProperty, ppQualSet }, HRESULT.class);
187+
}
188+
189+
public IWbemQualifierSet GetPropertyQualifierSet(String strProperty) {
190+
WString wszProperty = new WString(strProperty);
191+
PointerByReference ppQualSet = new PointerByReference();
192+
193+
COMUtils.checkRC(GetPropertyQualifierSet(wszProperty, ppQualSet));
194+
IWbemQualifierSet qualifier = new IWbemQualifierSet(ppQualSet.getValue());
195+
return qualifier;
196+
}
197+
}
198+
199+
class IWbemQualifierSet extends Unknown {
200+
public IWbemQualifierSet(Pointer pvInstance) {
201+
super(pvInstance);
202+
}
203+
204+
public HRESULT Get(WString wszName, int lFlags, VARIANT.ByReference pVal, IntByReference plFlavor) {
205+
return (HRESULT) _invokeNativeObject(3,
206+
new Object[] { getPointer(), wszName, lFlags, pVal, plFlavor }, HRESULT.class);
207+
}
208+
209+
public String Get(String wszName) {
210+
WString wszNameStr = new WString(wszName);
211+
Variant.VARIANT.ByReference pQualifierVal = new Variant.VARIANT.ByReference();
212+
HRESULT hres = Get(wszNameStr, 0, pQualifierVal, null);
213+
if(hres.intValue() == 0x80041002) {
214+
// This error for some classes only.
215+
return null;
216+
}
217+
int qualifierInt = pQualifierVal.getVarType().intValue();
218+
switch(qualifierInt) {
219+
case Wbemcli.CIM_BOOLEAN:
220+
return String.valueOf(pQualifierVal.booleanValue());
221+
case Wbemcli.CIM_STRING:
222+
return pQualifierVal.stringValue();
223+
}
224+
return null;
225+
}
226+
227+
public HRESULT GetNames(int lFlags, PointerByReference pNames) {
228+
return (HRESULT) _invokeNativeObject(6,
229+
new Object[] { getPointer(), lFlags, pNames }, HRESULT.class);
230+
}
231+
232+
public String[] GetNames() {
233+
PointerByReference pbr = new PointerByReference();
234+
COMUtils.checkRC(GetNames(0, pbr));
235+
Object[] nameObjects = (Object[]) OaIdlUtil.toPrimitiveArray(new SAFEARRAY(pbr.getValue()), true);
236+
String[] qualifierNames = new String[nameObjects.length];
237+
for(int i = 0; i < nameObjects.length; i++) {
238+
qualifierNames[i] = (String) nameObjects[i];
239+
}
240+
return qualifierNames;
241+
}
149242
}
150243

151244
/**
@@ -278,19 +371,83 @@ public IEnumWbemClassObject ExecQuery(String strQueryLanguage, String strQuery,
278371
OleAuto.INSTANCE.SysFreeString(strQueryBSTR);
279372
}
280373
}
374+
375+
public HRESULT GetObject(BSTR strObjectPath, int lFlags, IWbemContext pCtx,
376+
PointerByReference ppObject, PointerByReference ppCallResult) {
377+
// GetObject is the 7th method of IWbemServicesVtbl in WbemCli.h
378+
return (HRESULT) _invokeNativeObject(6,
379+
new Object[] { getPointer(), strObjectPath, lFlags, pCtx, ppObject, ppCallResult}, HRESULT.class);
380+
}
381+
382+
public IWbemClassObject GetObject(String strObjectPath, int lFlags, IWbemContext pCtx) {
383+
BSTR strObjectPathBSTR = OleAuto.INSTANCE.SysAllocString(strObjectPath);
384+
try {
385+
PointerByReference ppObject = new PointerByReference();
386+
HRESULT res = GetObject(strObjectPathBSTR, lFlags, pCtx, ppObject, null);
387+
COMUtils.checkRC(res);
388+
return new IWbemClassObject(ppObject.getValue());
389+
} finally {
390+
OleAuto.INSTANCE.SysFreeString(strObjectPathBSTR);
391+
}
392+
}
281393
}
282394

283395
/**
284396
* Optionally used to communicate additional context information to
285397
* providers when submitting IWbemServices calls to WMI
286398
*/
287399
class IWbemContext extends Unknown {
400+
public static final CLSID CLSID_WbemContext = new CLSID("674B6698-EE92-11D0-AD71-00C04FD8FDFF");
401+
public static final GUID IID_IWbemContext = new GUID("44aca674-e8fc-11d0-a07c-00c04fb68820");
288402

289403
public IWbemContext() {
290404
}
291405

406+
public static IWbemContext create() {
407+
PointerByReference pbr = new PointerByReference();
408+
409+
HRESULT hres = Ole32.INSTANCE.CoCreateInstance(CLSID_WbemContext, null, WTypes.CLSCTX_INPROC_SERVER,
410+
IID_IWbemContext, pbr);
411+
if (COMUtils.FAILED(hres)) {
412+
return null;
413+
}
414+
415+
return new IWbemContext(pbr.getValue());
416+
}
417+
292418
public IWbemContext(Pointer pvInstance) {
293419
super(pvInstance);
294420
}
421+
422+
public void SetValue(String wszName, int lFlag, Variant.VARIANT pValue) {
423+
BSTR wszNameBSTR = OleAuto.INSTANCE.SysAllocString(wszName);
424+
try {
425+
// SetValue is the 9th method of IWbemContextVtbl in WbemCli.h
426+
HRESULT res = (HRESULT) _invokeNativeObject(8,
427+
new Object[] { getPointer(), wszNameBSTR, lFlag, pValue}, HRESULT.class);
428+
COMUtils.checkRC(res);
429+
} finally {
430+
OleAuto.INSTANCE.SysFreeString(wszNameBSTR);
431+
}
432+
}
433+
434+
public void SetValue(String wszName, int lFlag, boolean pValue) {
435+
Variant.VARIANT aVariant = new Variant.VARIANT();
436+
aVariant.setValue(Variant.VT_BOOL, pValue ? Variant.VARIANT_TRUE : Variant.VARIANT_FALSE);
437+
SetValue(wszName, lFlag, aVariant);
438+
OleAuto.INSTANCE.VariantClear(aVariant);
439+
}
440+
441+
public void SetValue(String wszName, int lFlag, String pValue) {
442+
Variant.VARIANT aVariant = new Variant.VARIANT();
443+
BSTR strValue = OleAuto.INSTANCE.SysAllocString(pValue);
444+
try {
445+
aVariant.setValue(Variant.VT_LPSTR, strValue);
446+
SetValue(wszName, lFlag, aVariant);
447+
}
448+
finally {
449+
OleAuto.INSTANCE.SysFreeString(strValue);
450+
}
451+
}
295452
}
296453
}

contrib/platform/test/com/sun/jna/platform/win32/COM/WbemcliTest.java

+141
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,20 @@
3636
import org.junit.Before;
3737
import org.junit.Test;
3838

39+
import static com.sun.jna.platform.win32.Variant.VT_ARRAY;
40+
import static com.sun.jna.platform.win32.Variant.VT_BSTR;
41+
3942
import com.sun.jna.platform.win32.Ole32;
4043
import com.sun.jna.platform.win32.Variant;
4144
import com.sun.jna.platform.win32.COM.Wbemcli.IEnumWbemClassObject;
4245
import com.sun.jna.platform.win32.COM.Wbemcli.IWbemClassObject;
4346
import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiQuery;
4447
import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;
4548
import com.sun.jna.platform.win32.OleAuto;
49+
import com.sun.jna.platform.win32.OaIdl.SAFEARRAY;
50+
import com.sun.jna.platform.win32.WTypes;
51+
import com.sun.jna.platform.win32.Kernel32;
52+
import com.sun.jna.platform.win32.WinNT;
4653
import com.sun.jna.ptr.IntByReference;
4754
import java.util.Arrays;
4855
import java.util.HashSet;
@@ -309,4 +316,138 @@ public void testUnsupportedValues() {
309316
assertNull(result.getValue(Win32_DiskDrive_Values.CAPABILITIES, i));
310317
}
311318
}
319+
320+
@Test
321+
public void testIWbemClassObjectGetQualifierSet() {
322+
323+
Wbemcli.IWbemServices svc = null;
324+
Wbemcli.IEnumWbemClassObject enumRes = null;
325+
Variant.VARIANT.ByReference pVal = new Variant.VARIANT.ByReference();
326+
IntByReference pType = new IntByReference();
327+
IntByReference plFlavor = new IntByReference();
328+
329+
boolean foundWin32_Process = false;
330+
try {
331+
svc = connectServerEnglishLocale(WbemcliUtil.DEFAULT_NAMESPACE);
332+
enumRes = svc.ExecQuery(
333+
"WQL",
334+
"SELECT * FROM meta_class",
335+
Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_USE_AMENDED_QUALIFIERS, null);
336+
337+
while (true) {
338+
Wbemcli.IWbemClassObject[] results = enumRes.Next(Wbemcli.WBEM_INFINITE, 1);
339+
if (results.length == 0) {
340+
break;
341+
}
342+
343+
Wbemcli.IWbemClassObject classObject = results[0];
344+
Variant.VARIANT.ByReference pQualifierVal = new Variant.VARIANT.ByReference();
345+
346+
COMUtils.checkRC(classObject.Get("__CLASS", 0, pVal, pType, plFlavor));
347+
String className = pVal.stringValue();
348+
if(! className.equals("Win32_Process")) {
349+
continue;
350+
}
351+
foundWin32_Process = true;
352+
OleAuto.INSTANCE.VariantClear(pVal);
353+
354+
COMUtils.checkRC(classObject.Get("__SUPERCLASS", 0, pVal, pType, plFlavor));
355+
Object baseClass = pVal.getValue();
356+
OleAuto.INSTANCE.VariantClear(pVal);
357+
assertEquals("CIM_Process", baseClass.toString());
358+
359+
String[] propertyNames = classObject.GetNames(null, 0, pQualifierVal);
360+
assertTrue(Arrays.asList(propertyNames).contains("ProcessId"));
361+
362+
Wbemcli.IWbemQualifierSet classQualifiersSet = classObject.GetQualifierSet();
363+
String[] classQualifiersNames = classQualifiersSet.GetNames();
364+
assertTrue(Arrays.asList(classQualifiersNames).contains("DisplayName"));
365+
String classDisplayName = classQualifiersSet.Get("DisplayName");
366+
assertEquals("Processes", classDisplayName);
367+
368+
Wbemcli.IWbemQualifierSet propertyQualifiersSet = classObject.GetPropertyQualifierSet("ProcessId");
369+
String[] propertyQualifierNames = propertyQualifiersSet.GetNames();
370+
371+
assertTrue(Arrays.asList(propertyQualifierNames).contains("DisplayName"));
372+
String propertyDisplayName = propertyQualifiersSet.Get("DisplayName");
373+
assertEquals("Process Id", propertyDisplayName);
374+
375+
assertTrue(Arrays.asList(propertyQualifierNames).contains("CIMTYPE"));
376+
String propertyCIMTYPE = propertyQualifiersSet.Get("CIMTYPE");
377+
assertEquals("uint32", propertyCIMTYPE);
378+
379+
classObject.Release();
380+
}
381+
} finally {
382+
if (svc != null) svc.Release();
383+
if (enumRes != null) enumRes.Release();
384+
}
385+
assertTrue(foundWin32_Process);
386+
}
387+
388+
@Test
389+
public void testIWbemContextSetValue() {
390+
long currentPid = Kernel32.INSTANCE.GetCurrentProcessId();
391+
String objectPath = String.format("\\\\.\\%s:Win32_Process.Handle=\"%d\"", WbemcliUtil.DEFAULT_NAMESPACE, currentPid);
392+
393+
// This context object retrieves only parts of a WMI instance.
394+
Wbemcli.IWbemContext pctxDrive = new Wbemcli.IWbemContext().create();
395+
pctxDrive.SetValue("__GET_EXTENSIONS", 0, true);
396+
pctxDrive.SetValue("__GET_EXT_CLIENT_REQUEST", 0, true);
397+
398+
// Create a safe array of just one property to retrieve.
399+
SAFEARRAY psaProperties = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(VT_BSTR), 1);
400+
OleAuto.INSTANCE.SafeArrayLock(psaProperties);
401+
try {
402+
WTypes.BSTR strPropertyBSTR = OleAuto.INSTANCE.SysAllocString("ProcessId");
403+
try {
404+
psaProperties.putElement(strPropertyBSTR, 0);
405+
} finally {
406+
OleAuto.INSTANCE.SysFreeString(strPropertyBSTR);
407+
}
408+
} finally {
409+
OleAuto.INSTANCE.SafeArrayUnlock(psaProperties);
410+
}
411+
412+
Variant.VARIANT.ByReference vPropertyList = new Variant.VARIANT.ByReference();
413+
vPropertyList.setVarType((short) (VT_ARRAY | VT_BSTR));
414+
vPropertyList.setValue(psaProperties);
415+
pctxDrive.SetValue("__GET_EXT_PROPERTIES", 0, vPropertyList);
416+
psaProperties.destroy();
417+
418+
Variant.VARIANT.ByReference pVal = new Variant.VARIANT.ByReference();
419+
Wbemcli.IWbemServices svc = null;
420+
try {
421+
svc = WbemcliUtil.connectServer(WbemcliUtil.DEFAULT_NAMESPACE);
422+
Wbemcli.IWbemClassObject classObject = svc.GetObject(objectPath, Wbemcli.WBEM_FLAG_RETURN_WBEM_COMPLETE, pctxDrive);
423+
// The properties "Handle" and "PropertyId" must have the same values with different types.
424+
COMUtils.checkRC(classObject.Get("ProcessId", 0, pVal, null, null));
425+
}
426+
finally {
427+
if (svc != null) svc.Release();
428+
}
429+
assertEquals(currentPid, pVal.longValue());
430+
}
431+
432+
/**
433+
* Copy from WbemcliUtil#connectServer with American English selected as
434+
* locale.
435+
*/
436+
private static Wbemcli.IWbemServices connectServerEnglishLocale(String namespace) {
437+
Wbemcli.IWbemLocator loc = Wbemcli.IWbemLocator.create();
438+
if (loc == null) {
439+
throw new COMException("Failed to create WbemLocator object.");
440+
}
441+
442+
Wbemcli.IWbemServices services = loc.ConnectServer(namespace, null, null, "MS_409", 0, null, null);
443+
loc.Release();
444+
445+
WinNT.HRESULT hres = Ole32.INSTANCE.CoSetProxyBlanket(services, Ole32.RPC_C_AUTHN_WINNT, Ole32.RPC_C_AUTHZ_NONE, null,
446+
Ole32.RPC_C_AUTHN_LEVEL_CALL, Ole32.RPC_C_IMP_LEVEL_IMPERSONATE, null, Ole32.EOAC_NONE);
447+
if (COMUtils.FAILED(hres)) {
448+
services.Release();
449+
throw new COMException("Could not set proxy blanket.", hres);
450+
}
451+
return services;
452+
}
312453
}

0 commit comments

Comments
 (0)