Question

I'm trying to map the Windows Native Wifi API in Java but I'm having problems with the WlanEnumInterfaces function. Basically, this function outputs a WLAN_INTERFACE_INFO_LIST structure containing an array of WLAN_INTERFACE_INFO structures. When I call the WlanEnumInterfaces in my Java program, its return value indicates that the function succeeds, but when I check the number of items in the WLAN_INTERFACE_INFO array, I get inconsistent values like 1367280 or 4000000. This value should be 1 as I have only one wireless interface on my machine. Here it's my mapping of the WlanEnumInterfaces function:

public int WlanEnumInterfaces(
        HANDLE hClientHandle,
        PointerByReference pReserved,
        WLAN_INTERFACE_INFO_LIST.ByReference ppInterfaceList);

Implementation of WLAN_INTERFACE_INFO_LIST:

public static class WLAN_INTERFACE_INFO_LIST extends Structure {
    public static class ByReference extends WLAN_INTERFACE_INFO_LIST implements Structure.ByReference{}
    public int dwNumberOfItems;
    public int dwIndex;
    public WLAN_INTERFACE_INFO[] InterfaceInfo = new WLAN_INTERFACE_INFO[10];


    @Override
    protected List getFieldOrder() {
        return Arrays.asList(new String[] {"dwNumberOfItems","dwIndex","InterfaceInfo"});
    }
}

And part of the code that calls the function:

HANDLE wlanHandle = getWlanHandle();
WLAN_INTERFACE_INFO_LIST.ByReference ppInterfaceList = new WLAN_INTERFACE_INFO_LIST.ByReference();

int ret = Wlanapi.INSTANCE.WlanEnumInterfaces(wlanHandle,null,ppInterfaceList);
System.out.println("Return: " + ret);    
System.out.println("WlanEnumInterfaces->number of items: "+ppInterfaceList.dwNumberOfItems);

Does anyone know what is happening? Thanks!

Was it helpful?

Solution

The WlanEnumInterfaces populates the field you provide it with the address of a struct. You are passing in the address of a struct rather than the address of an address.

Use PointerByReference to get the address of the struct, e.g.

PointerByReference pref = new PointerByReference();
Wlanapi.INSTANCE.WlanEnumInterfaces(handle, null, pref);
WLAN_INTERFACE_INFO_LIST list = new WLAN_INTERFACE_INFO_LIST(pref.getValue());

Then you need a Pointer-based constructor for WLAN_INTERFACE_INFO_LIST, i.e.

WLAN_INTERFACE_INFO_LIST(Pointer p) {
    super(p);
    this.dwNumberOfItems = p.readInt(0);
    this.InterfaceInfo = new WLAN_INTERFACE_INFO[this.dwNumberOfItems];
    read();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top