1

So as an overview, I am working with the Wlanapi and I am fairly new to it (native apis in general). I am running into a problem converting a structure from c++ to c#. Right now I have:

Original:

typedef struct _WLAN_BSS_LIST {
    DWORD          dwTotalSize;
    DWORD          dwNumberOfItems;
    WLAN_BSS_ENTRY wlanBssEntries[1];
} WLAN_BSS_LIST, *PWLAN_BSS_LIST;

Conversion:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct WLAN_BSS_LIST 
{
    internal uint             dwTotalSize;
    internal uint             dwNumberOfItems;
    internal WLAN_BSS_ENTRY[] wlanBssEntries;

    internal WLAN_BSS_LIST(IntPtr ppBssList)
    {
        dwNumberOfItems = (uint)Marshal.ReadInt32(ppBssList);
        //I need to set the value of dwTotalSize but I dunno how
        wlanBssEntries = new WLAN_BSS_ENTRY[dwNumberOfItems];

        for (int i = 0; i < dwNumberOfItems; i++)
        {
            IntPtr pWlanBssEntry = new IntPtr(ppBssList.ToInt32() + i * 
                Marshal.SizeOf(typeof(WLAN_BSS_ENTRY)) + 8);
            wlanBssEntries[i] = (WLAN_BSS_ENTRY)Marshal.
                                    PtrToStructure(pWlanBssEntry, 
                                        typeof(WLAN_BSS_ENTRY));
        }
    }
}

I just don't know how to get the total size of the array referenced by ppBssList :(

As an fyi, I will be extremely disappointed if someone points me to an existing library.

Edited to add original struct

FlyingStreudel
  • 4,434
  • 4
  • 33
  • 55

2 Answers2

0

I'm not sure if your twTotalSize reflects the amount of memory allocated for the entries in wlanBssEntries, if so, a simple calculation would be sufficient,

 sizeof(typeof(WLAN_BSS_ENTRY)) * dwNumberOfItems + 8

otherwise, I suggest that you post the original native data structure, maybe, there is a much better alternative for marshaling it from the memory block.

Waleed
  • 3,105
  • 2
  • 24
  • 31
  • So there is no additional information in an array beyond the actual items contained in it? – FlyingStreudel Jun 13 '11 at 15:35
  • this depends on the native struct being marshaled, if you are able to marshal each element manually, I guess you know your stuct. I'm not sure, you need to make your own calculations based on the WLAN_BSS_ENTRY structure – Waleed Jun 13 '11 at 15:37
0

So I figured it out, I dunno what I was thinking...

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct WLAN_BSS_LIST
{
    internal uint dwTotalSize;
    internal uint dwNumberOfItems;
    internal WLAN_BSS_ENTRY[] wlanBssEntries;

    internal WLAN_BSS_LIST(IntPtr ppBssList)
    {
        dwTotalSize = (uint)Marshal.ReadInt32(ppBssList);
        dwNumberOfItems = (uint)Marshal.ReadInt32(ppBssList, 4);
        wlanBssEntries = new WLAN_BSS_ENTRY[dwNumberOfItems];
        for (int i = 0; i < dwNumberOfItems; i++)
        {
            IntPtr pWlanBssEntry = new IntPtr(ppBssList.ToInt32() + i * 
                Marshal.SizeOf(typeof(WLAN_BSS_ENTRY)) + 8);
            wlanBssEntries[i] = (WLAN_BSS_ENTRY)Marshal.
                PtrToStructure(pWlanBssEntry, typeof(WLAN_BSS_ENTRY));
        }
    }
}

And

[StructLayout(LayoutKind.Sequential)]
public struct WLAN_BSS_ENTRY
{
    public DOT11_SSID dot11Ssid;
    public uint uPhyId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] dot11Bssid;
    public DOT11_BSS_TYPE dot11BssType;
    public DOT11_PHY_TYPE dot11BssPhyType;
    public int lRssi;
    public uint uLinkQuality;
    public bool bInRegDomain;
    public UInt16 usBeaconPeriod;
    public UInt64 ullTimestamp;
    public UInt64 ullHostTimestamp;
    public UInt16 usCapabilityInformation;
    public uint ulChCenterFrequency;
    public WLAN_RATE_SET wlanRateSet;
    public uint ulIeOffset;
    public uint ulIeSize;
}
FlyingStreudel
  • 4,434
  • 4
  • 33
  • 55