Search code examples
c#marshallingwlanapi

Find the total size of an array of objects with only a reference pointer?


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


Solution

  • 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;
    }