Skip to content

Commit

Permalink
Include CIM Type in WMI results
Browse files Browse the repository at this point in the history
  • Loading branch information
dbwiddis committed Aug 26, 2018
1 parent 777644a commit b549fda
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 25 deletions.
25 changes: 23 additions & 2 deletions contrib/platform/src/com/sun/jna/platform/win32/COM/Wbemcli.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ public interface Wbemcli {
public static final int WBEM_E_INVALID_CLASS = 0x80041010;
public static final int WBEM_E_INVALID_QUERY = 0x80041017;

// CIM Types
public static final int CIM_ILLEGAL = 0xfff;
public static final int CIM_EMPTY = 0;
public static final int CIM_SINT8 = 16;
public static final int CIM_UINT8 = 17;
public static final int CIM_SINT16 = 2;
public static final int CIM_UINT16 = 18;
public static final int CIM_SINT32 = 3;
public static final int CIM_UINT32 = 19;
public static final int CIM_SINT64 = 20;
public static final int CIM_UINT64 = 21;
public static final int CIM_REAL32 = 4;
public static final int CIM_REAL64 = 5;
public static final int CIM_BOOLEAN = 11;
public static final int CIM_STRING = 8;
public static final int CIM_DATETIME = 101;
public static final int CIM_REFERENCE = 102;
public static final int CIM_CHAR16 = 103;
public static final int CIM_OBJECT = 13;
public static final int CIM_FLAG_ARRAY = 0x2000;

/**
* Holds a row of results of a WMI query
*/
Expand All @@ -68,11 +89,11 @@ public IWbemClassObject(Pointer pvInstance) {
super(pvInstance);
}

public HRESULT Get(WString wszName, int lFlags, VARIANT.ByReference pVal, IntByReference pvtType,
public HRESULT Get(WString wszName, int lFlags, VARIANT.ByReference pVal, IntByReference pType,
IntByReference plFlavor) {
// Get is 5th method of IWbemClassObjectVtbl in WbemCli.h
return (HRESULT) _invokeNativeObject(4,
new Object[] { getPointer(), wszName, lFlags, pVal, pvtType, plFlavor }, HRESULT.class);
new Object[] { getPointer(), wszName, lFlags, pVal, pType, plFlavor }, HRESULT.class);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* Utility class providing access to Windows Management Interface (WMI) via COM.
*/
public class WbemcliUtil {

/**
* Instance to generate the WmiQuery class.
*/
Expand Down Expand Up @@ -137,6 +138,7 @@ public void setWmiClassName(String wmiClassName) {
public class WmiResult<T extends Enum<T>> {
private Map<T, List<Object>> propertyMap;
private Map<T, Integer> vtTypeMap;
private Map<T, Integer> cimTypeMap;
private int resultCount = 0;

/**
Expand All @@ -146,9 +148,11 @@ public class WmiResult<T extends Enum<T>> {
public WmiResult(Class<T> propertyEnum) {
propertyMap = new EnumMap<T, List<Object>>(propertyEnum);
vtTypeMap = new EnumMap<T, Integer>(propertyEnum);
for (T type : propertyEnum.getEnumConstants()) {
propertyMap.put(type, new ArrayList<Object>());
vtTypeMap.put(type, Variant.VT_NULL);
cimTypeMap = new EnumMap<T, Integer>(propertyEnum);
for (T prop : propertyEnum.getEnumConstants()) {
propertyMap.put(prop, new ArrayList<Object>());
vtTypeMap.put(prop, Variant.VT_NULL);
cimTypeMap.put(prop, Wbemcli.CIM_EMPTY);
}
}

Expand Down Expand Up @@ -182,21 +186,38 @@ public int getVtType(T property) {
return this.vtTypeMap.get(property);
}

/**
* Gets the CIM type from the WmiResult. The integer value is defined as
* a CIM_* constant in the {@link Wbemcli} interface.
*
* @param property
* The property (column) whose type to fetch
* @return An integer representing the CIM type
*/
public int getCIMType(T property) {
return this.cimTypeMap.get(property);
}

/**
* Adds a value to the WmiResult at the next index for that property
*
* @param vtType
* The Variant type of this object
* @param cimType
* The CIM type of this property
* @param property
* The property (column) to store
* @param o
* The object to store
*/
private void add(int vtType, T property, Object o) {
private void add(int vtType, int cimType, T property, Object o) {
this.propertyMap.get(property).add(o);
if (vtType != Variant.VT_NULL && this.vtTypeMap.get(property).equals(Variant.VT_NULL)) {
this.vtTypeMap.put(property, vtType);
}
if (this.cimTypeMap.get(property).equals(Wbemcli.CIM_EMPTY)) {
this.cimTypeMap.put(property, cimType);
}
}

/**
Expand Down Expand Up @@ -508,40 +529,42 @@ public static <T extends Enum<T>> WmiResult<T> enumerateProperties(IEnumWbemClas
}

VARIANT.ByReference pVal = new VARIANT.ByReference();
IntByReference pType = new IntByReference();

// Get the value of the properties
IWbemClassObject clsObj = new IWbemClassObject(pclsObj.getValue());
for (T property : propertyEnum.getEnumConstants()) {
clsObj.Get(wstrMap.get(property), 0, pVal, null, null);
int type = (pVal.getValue() == null ? Variant.VT_NULL : pVal.getVarType()).intValue();
switch (type) {
clsObj.Get(wstrMap.get(property), 0, pVal, pType, null);
int vtType = (pVal.getValue() == null ? Variant.VT_NULL : pVal.getVarType()).intValue();
int cimType = pType.getValue();
switch (vtType) {
case Variant.VT_BSTR:
values.add(type, property, pVal.stringValue());
values.add(vtType, cimType, property, pVal.stringValue());
break;
case Variant.VT_I4:
values.add(type, property, pVal.intValue());
values.add(vtType, cimType, property, pVal.intValue());
break;
case Variant.VT_UI1:
values.add(type, property, pVal.byteValue());
values.add(vtType, cimType, property, pVal.byteValue());
break;
case Variant.VT_I2:
values.add(type, property, pVal.shortValue());
values.add(vtType, cimType, property, pVal.shortValue());
break;
case Variant.VT_BOOL:
values.add(type, property, pVal.booleanValue());
values.add(vtType, cimType, property, pVal.booleanValue());
break;
case Variant.VT_R4:
values.add(type, property, pVal.floatValue());
values.add(vtType, cimType, property, pVal.floatValue());
break;
case Variant.VT_R8:
values.add(type, property, pVal.doubleValue());
values.add(vtType, cimType, property, pVal.doubleValue());
break;
case Variant.VT_NULL:
values.add(type, property, null);
values.add(vtType, cimType, property, null);
break;
// Unimplemented type. User must cast
default:
values.add(type, property, pVal.getValue());
values.add(vtType, cimType, property, pVal.getValue());
}
OleAuto.INSTANCE.VariantClear(pVal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@

import com.sun.jna.platform.win32.Ole32;
import com.sun.jna.platform.win32.Variant;
import com.sun.jna.platform.win32.COM.COMException;
import com.sun.jna.platform.win32.COM.COMUtils;
import com.sun.jna.platform.win32.COM.Wbemcli;
import com.sun.jna.platform.win32.COM.WbemcliUtil;
import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiQuery;
import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;

Expand All @@ -58,7 +54,7 @@ enum ProcessProperty {
PROCESSID, // UINT32
WORKINGSETSIZE, // UINT64
CREATIONDATE, // DATETIME
EXECUTIONSTATE, // Always NULL
EXECUTIONSTATE, // UINT16, Always NULL
COMMANDLINE; // STRING
}

Expand Down Expand Up @@ -140,21 +136,25 @@ public void testWmiProcesses() {
int lastProcessIndex = processes.getResultCount() - 1;

// PID is UINT32 = VT_I4
assertEquals(Wbemcli.CIM_UINT32, processes.getCIMType(ProcessProperty.PROCESSID));
assertEquals(Variant.VT_I4, processes.getVtType(ProcessProperty.PROCESSID));
assertTrue((Integer) processes.getValue(ProcessProperty.PROCESSID, lastProcessIndex) >= 0);

// WSS is UINT64 = STRING
assertEquals(Wbemcli.CIM_UINT64, processes.getCIMType(ProcessProperty.WORKINGSETSIZE));
assertEquals(Variant.VT_BSTR, processes.getVtType(ProcessProperty.WORKINGSETSIZE));
String wssStr = (String) processes.getValue(ProcessProperty.WORKINGSETSIZE, lastProcessIndex);
assertTrue(Long.parseLong(wssStr) > 0);

// EXECUTIONSTATE is always null
// EXECUTIONSTATE is UINT16 but is always null
assertEquals(Wbemcli.CIM_UINT16, processes.getCIMType(ProcessProperty.EXECUTIONSTATE));
assertEquals(Variant.VT_NULL, processes.getVtType(ProcessProperty.EXECUTIONSTATE));
Object state = processes.getValue(ProcessProperty.EXECUTIONSTATE, lastProcessIndex);
assertNull(state);

// CreationDate is DATETIME = STRING
// and be in CIM_DATETIME format yyyymmddhhmmss.mmmmmm+zzz
assertEquals(Wbemcli.CIM_DATETIME, processes.getCIMType(ProcessProperty.CREATIONDATE));
assertEquals(Variant.VT_BSTR, processes.getVtType(ProcessProperty.CREATIONDATE));
String cdate = (String) processes.getValue(ProcessProperty.CREATIONDATE, lastProcessIndex);

Expand All @@ -175,15 +175,18 @@ public void testWmiOperatingSystem() {
assertTrue(os.getResultCount() > 0);

// ForegroundApplicationBoost is UINT8 = VT_UI1
assertEquals(Wbemcli.CIM_UINT8, os.getCIMType(OperatingSystemProperty.FOREGROUNDAPPLICATIONBOOST));
assertEquals(Variant.VT_UI1, os.getVtType(OperatingSystemProperty.FOREGROUNDAPPLICATIONBOOST));
assertTrue((Byte) os.getValue(OperatingSystemProperty.FOREGROUNDAPPLICATIONBOOST, 0) >= 0);

// OSTYPE is UINT16 = VT_I4
assertEquals(Wbemcli.CIM_UINT16, os.getCIMType(OperatingSystemProperty.OSTYPE));
assertEquals(Variant.VT_I4, os.getVtType(OperatingSystemProperty.OSTYPE));
assertTrue((Integer) os.getValue(OperatingSystemProperty.OSTYPE, 0) >= 0);

// PRIMARY is BOOLEAN = VT_BOOL
assertEquals(Wbemcli.CIM_BOOLEAN, os.getCIMType(OperatingSystemProperty.PRIMARY));
assertEquals(Variant.VT_BOOL, os.getVtType(OperatingSystemProperty.PRIMARY));
assertNotNull((Boolean) os.getValue(OperatingSystemProperty.PRIMARY, 0));
assertNotNull(os.getValue(OperatingSystemProperty.PRIMARY, 0));
}
}

0 comments on commit b549fda

Please sign in to comment.