Hello,
Originally, I based my code over oshi-core implementation.
public enum NetworkAdapterConfigurationProperty {
InterfaceIndex,
IPAddress;
}
/* package for test */ Void wmiCmd2() {
final WmiQueryHandler instance = WmiQueryHandler.createInstance(); // src:
https://github.com/oshi/oshi/blob/master/oshi-core/src/main/java/oshi/util/platform/windows/WmiQueryHandler.java if (instance != null) {
final WmiQuery<NetworkAdapterConfigurationProperty> nacConfQuery = new WmiQuery<>(
"Win32_NetworkAdapterConfiguration" , NetworkAdapterConfigurationProperty.class);
final WmiResult<NetworkAdapterConfigurationProperty> nacConfRes = instance.queryWMI(nacConfQuery);
for (int i = 0; i < nacConfRes.getResultCount(); i++) {
final Object key = nacConfRes.getValue(NetworkAdapterConfigurationProperty.InterfaceIndex, i);
Object ip = nacConfRes.getValue(NetworkAdapterConfigurationProperty.IPAddress, i);
if (ip == null) {
System.err.println("CIMTYPE is : " + nacConfRes.getCIMType(NetworkAdapterConfigurationProperty.IPAddress));
System.err.println(" VtType is : " + nacConfRes.getVtType(NetworkAdapterConfigurationProperty.IPAddress));
} else if (ip instanceof SAFEARRAY) {
final SAFEARRAY arr = (SAFEARRAY) ip;
if (arr != null) {
System.err.println("dim: " + arr.getDimensionCount());
System.err.println("elm : " + arr.getElemsize());
System.err.println("vt : " + arr.getVarType());
System.err.println("from " + arr.getLBound(0) + " to " + arr.getUBound(0));
for (int ii = arr.getLBound(0); ii <= arr.getUBound(0); ii++) {
System.out.println("\t" + arr.getElement(ii));
}
}
} else {
System.err.println(" IP : " + ip.getClass());
}
System.err.println("+++++++++++++++++++++++");
}
}
return null;
}
Which provide this result :
Deal with Key #20
CIMTYPE is : 8200
VtType is : 8200
+++++++++++++++++++++++
Deal with Key #8
CIMTYPE is : 8200
VtType is : 8200
+++++++++++++++++++++++
Deal with Key #5
CIMTYPE is : 8200
VtType is : 8200
+++++++++++++++++++++++
So i edit WbemcliUtil WmiResult<T> enumerateProperties(IEnumWbemClassObject enumerator, Class<T> propertyEnum, int timeout) to add the following case:
case 8200:
values.add(vtType, cimType, property, pVal.getValue());
break;
doing so, the output changed, as ip is no longer null, but a SAFEARRAY:
Deal with Key #20
CIMTYPE is : 8200
VtType is : 8200
+++++++++++++++++++++++
Deal with Key #8
dim: 1
elm : 4
vt : 8
from 0 to 3
Exception in thread "main" com.sun.jna.platform.win32.COM.COMException: Paramètre incorrect.(HRESULT: 80070057)
at com.sun.jna.platform.win32.COM.COMUtils.checkRC(COMUtils.java:117)
at com.sun.jna.platform.win32.OaIdl$SAFEARRAY.getElement(OaIdl.java:821)
at fr.def.iss.ssiutils.network.adapters.WindowsNetworkAdapterConfTest.wmiCmd2(WindowsNetworkAdapterConfTest.java:135)
at fr.def.iss.ssiutils.network.adapters.WindowsNetworkAdapterConfTest.main(WindowsNetworkAdapterConfTest.java:34)
So I gave up there.
I adapt the code to use the expected "Win32_NetworkAdapterConfiguration" instead.
Which game me this code:
private static void pouet() throws Exception {
Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED);
// Connect to the server
Wbemcli.IWbemServices svc = WbemcliUtil.connectServer("ROOT\\CIMV2");
// Send query
try {
Wbemcli.IEnumWbemClassObject enumerator = svc.ExecQuery("WQL", "SELECT InterfaceIndex, IPAddress FROM Win32_NetworkAdapterConfiguration",
Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_RETURN_IMMEDIATELY, null);
try {
IWbemClassObject[] result;
VARIANT.ByReference pVal = new VARIANT.ByReference();
IntByReference pType = new IntByReference();
IntByReference plFlavor = new IntByReference();
while(true) {
result = enumerator.Next(0, 1);
if(result.length == 0) {
break;
}
COMUtils.checkRC(result[0].Get("InterfaceIndex", 0, pVal, pType, plFlavor));
System.out.println("---------" + pVal.getValue() + "-------------");
OleAuto.INSTANCE.VariantClear(pVal);
COMUtils.checkRC(result[0].Get("IPAddress", 0, pVal, pType, plFlavor));
SAFEARRAY safeArray = (SAFEARRAY) pVal.getValue();
if(safeArray != null) {
for(int i = safeArray.getLBound(0); i<=safeArray.getUBound(0); i++) {
System.out.println("\t" + safeArray.getElement(i));
}
}
OleAuto.INSTANCE.VariantClear(pVal);
result[0].Release();
}
} finally {
// Cleanup
enumerator.Release();
}
} finally {
// Cleanup
svc.Release();
}
}
Which doesn't work well either. By that I mean running it produces no result at all.
So i add some syserr / catchblock here and there :
private static void pouet() throws Exception {
Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED);
// Connect to the server
Wbemcli.IWbemServices svc = WbemcliUtil.connectServer("ROOT\\CIMV2");
// Send query
try {
Wbemcli.IEnumWbemClassObject enumerator = svc.ExecQuery("WQL", "SELECT InterfaceIndex, IPAddress, IPSubnet FROM Win32_NetworkAdapterConfiguration",
Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_RETURN_IMMEDIATELY, null);
try {
IWbemClassObject[] result;
VARIANT.ByReference pVal = new VARIANT.ByReference();
IntByReference pType = new IntByReference();
IntByReference plFlavor = new IntByReference();
while(true) {
result = enumerator.Next(0, 1);
if(result.length == 0) {
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! break");
break;
}
COMUtils.checkRC(result[0].Get("InterfaceIndex", 0, pVal, pType, plFlavor));
System.out.println("---------" + pVal.getValue() + "-------------");
OleAuto.INSTANCE.VariantClear(pVal);
COMUtils.checkRC(result[0].Get("IPAddress", 0, pVal, pType, plFlavor));
SAFEARRAY safeArray = (SAFEARRAY) pVal.getValue();
if(safeArray != null) {
for(int i = safeArray.getLBound(0); i<=safeArray.getUBound(0); i++) {
System.out.println("\t" + safeArray.getElement(i));
}
}
OleAuto.INSTANCE.VariantClear(pVal);
result[0].Release();
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Cleanup
enumerator.Release();
System.err.println("finaly2");
}
} catch (Throwable e1) {
e1.printStackTrace();
} finally {
// Cleanup
svc.Release();
System.err.println("finaly1");
}
}
And still using debugger (a breakpoint on the "Wbemcli.IEnumWbemClassObject enumerator" the going line per line), i get some answers :
---------20-------------
---------8-------------
192.168.1.39
fe80::a150:9e1:f91d:3ea0
2001:861:3840:1c90:dd15:c68:82f2:a947
2001:861:3840:1c90:50e5:9470:5c72:93ad
java.lang.Error: Invalid memory access
at com.sun.jna.Native.getShort(Native Method)
at com.sun.jna.Pointer.getShort(Pointer.java:568)
at com.sun.jna.Pointer.getValue(Pointer.java:378)
at com.sun.jna.Structure.readField(Structure.java:732)
at com.sun.jna.Structure.read(Structure.java:591)
at com.sun.jna.platform.win32.OaIdl$SAFEARRAY.read(OaIdl.java:586)
at com.sun.jna.Structure.autoRead(Structure.java:2203)
at com.sun.jna.Structure.conditionalAutoRead(Structure.java:561)
at com.sun.jna.Structure.updateStructureByReference(Structure.java:690)
at com.sun.jna.Pointer.getValue(Pointer.java:367)
at com.sun.jna.Structure.readField(Structure.java:732)
at com.sun.jna.Union.readField(Union.java:223)
at com.sun.jna.Structure.read(Structure.java:591)
at com.sun.jna.Pointer.getValue(Pointer.java:370)
at com.sun.jna.Structure.readField(Structure.java:732)
at com.sun.jna.Structure.read(Structure.java:591)
at com.sun.jna.Pointer.getValue(Pointer.java:370)
at com.sun.jna.Structure.readField(Structure.java:732)
at com.sun.jna.Union.readField(Union.java:223)
at com.sun.jna.Structure.read(Structure.java:591)
at com.sun.jna.Structure.autoRead(Structure.java:2203)
at com.sun.jna.Function.invoke(Function.java:381)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Function.invoke(Function.java:306)
at com.sun.jna.platform.win32.COM.COMInvoker._invokeNativeObject(COMInvoker.java:48)
at com.sun.jna.platform.win32.COM.Wbemcli$IWbemClassObject.Get(Wbemcli.java:120)
at com.sun.jna.platform.win32.COM.Wbemcli$IWbemClassObject.Get(Wbemcli.java:126)
at fr.def.iss.ssiutils.network.adapters.WindowsNetworkAdapterConfTest.pouet(WindowsNetworkAdapterConfTest.java:60)
at fr.def.iss.ssiutils.network.adapters.WindowsNetworkAdapterConfTest.main(WindowsNetworkAdapterConfTest.java:31)
Note:
* IPAddress values displayed are the expected one (none for 20, four different results for interfaceIndex 8).
* exception occured when going to the next result (interfaceIndex 5 in my case)
If i comment this block :
COMUtils.checkRC(result[0].Get("IPAddress", 0, pVal, pType, plFlavor));
SAFEARRAY safeArray = (SAFEARRAY) pVal.getValue();
if(safeArray != null) {
for(int i = safeArray.getLBound(0); i<=safeArray.getUBound(0); i++) {
System.out.println("\t" + safeArray.getElement(i));
}
}
OleAuto.INSTANCE.VariantClear(pVal);
The error doesn't appear (still using breakpoint, otherwise no result):
---------20-------------
---------8-------------
---------5-------------
---------13-------------
[...]
I manage to solve the java.lang.Error: Invalid memory access by moving
IWbemClassObject[] result;
VARIANT.ByReference pVal = new VARIANT.ByReference();
IntByReference pType = new IntByReference();
IntByReference plFlavor = new IntByReference();
Inside the while loop.
To sum up :
* I still don't get why the "running way" doesn't work. Why should i have to use a breakpoint on "Wbemcli.IEnumWbemClassObject enumerator" then go step by step ?
* I don't understand why oshi-core implementation doesn't work, as the minimal case provided for issue #1083 "works".