none
Use Native WLAN API in managed code

    Question

  • Has anyone here used the new Native WLAN API from a C# .NET application?
    I'm trying to p/invoke the functions, but have limited success; when calling the WlanEnumInterfaces function it  won't return me a proper WLAN_INTERFACE_INFO_LIST.

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanOpenHandle(
    [
    In] UInt32 dwClientVersion,
    [In,Out] IntPtr pReserved,
    [Out] out UInt32 pdwNegotiatedVersion,
    [
    Out] out IntPtr phClientHandle);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanEnumInterfaces(
    [
    In] IntPtr hClientHandle,
    [
    In,Out] IntPtr pReserved,
    [Out] out WLAN_INTERFACE_INFO_LIST ppInterfaceList);

    public struct WLAN_INTERFACE_INFO_LIST
    {
    public int dwNumberOfItems;
    public int dwIndex;
    public WLAN_INTERFACE_INFO[] InterfaceInfo;
    }

    public struct WLAN_INTERFACE_INFO
    {
    public Guid InterfaceGuid;
    public string strInterfaceDescription;
    public WLAN_INTERFACE_STATE isState;
    }

    public enum WLAN_INTERFACE_STATE
    {
    wlan_interface_state_not_ready,
    wlan_interface_state_connected,
    wlan_interface_state_ad_hoc_network_formed,
    wlan_interface_state_disconnecting,
    wlan_interface_state_disconnected,
    wlan_interface_state_associating,
    wlan_interface_state_discovering,
    wlan_interface_state_authenticating
    }

    uint ver = 0;

    ret = WlanOpenHandle(1, IntPtr.Zero, out ver, out this.clientHandle);

    WLAN_INTERFACE_INFO_LIST wIIL;

    ret = WlanEnumInterfaces(this.clientHandle, IntPtr.Zero, out wIIL);

    Wednesday, December 20, 2006 3:40 PM

All replies

  • I figured out what I was doing wrong; I probably misread the documentation, because WlanEnumInterfaces returns a pointer to the WLAN_INTERFACE_INFO_LIST data, not an actual object.
    So I need to use the pointer to retrieve the data using the Marshal functions available in .NET.
    Wednesday, December 20, 2006 5:41 PM
  • I'm afraid I have to reopen my own topic again. Has anyone implemented these functions in managed code (C#)? I'm having trouble finding the right types needed to p/invoke the API functions in the right way. This is what I have so far:

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanOpenHandle(
    [
    In] UInt32 dwClientVersion,
    [In,Out] IntPtr pReserved,
    [Out] out UInt32 pdwNegotiatedVersion,
    [
    Out] out IntPtr phClientHandle);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanCloseHandle(
    [
    In] IntPtr hClientHandle,
    [
    In,Out] IntPtr pReserved);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanEnumInterfaces(
    [
    In] IntPtr hClientHandle,
    [
    In,Out] IntPtr pReserved,
    [Out] out IntPtr ppInterfaceList);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanQueryInterface(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] WLAN_INTF_OPCODE opCode,
    [
    In,Out] IntPtr pReserved,
    [Out] out UInt32 pdwDataSize,
    [
    Out] out IntPtr ppData,
    [
    Out] out WLAN_OPCODE_VALUE_TYPE pWlanOpcodeValueType);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanSetInterface(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] WLAN_INTF_OPCODE opCode,
    [
    In] uint dwDataSize,
    [
    In] IntPtr pData,
    [
    In,Out] IntPtr pReserved);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanScan(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] IntPtr pDot11Ssid,
    [In] IntPtr pIeData,
    [In,Out] IntPtr pReserved);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanGetAvailableNetworkList(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] uint dwFlags,
    [
    In,Out] IntPtr pReserved,
    [Out] out IntPtr ppAvailableNetworkList);

    private static uint WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES = 0x00000001;
    private static uint WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES = 0x00000002;

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanSetProfile(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] uint dwFlags,
    [In] string strProfileXml,
    [
    In] string strAllUserProfileSecurity,
    [In] bool bOverwrite,
    [
    In,Out] IntPtr pReserved,
    [Out] out uint pdwReasonCode);

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanGetProfile(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] string strProfileName,
    [
    In] IntPtr pReserved,
    [Out] out IntPtr pstrProfileXml,
    [
    Out] out IntPtr pdwFlags,
    [
    Out] out IntPtr pdwGrantedAccess);

    Friday, January 05, 2007 11:45 AM
  • I got everything working except for the WlanSetProfile function. This is the code:

    // set new profile
    StringWriter sw = new StringWriter();
    XmlWriter xw = XmlWriter.Create(sw);
    xw.WriteStartDocument();
    xw.WriteStartElement(
    "WLANProfile",http://www.microsoft.com/networking/WLAN/profile/v1);
    xw.WriteElementString(
    "name", "MyNetwork");
    xw.WriteStartElement(
    "SSIDConfig");
    xw.WriteStartElement(
    "SSID");
    xw.WriteElementString("name", "MyNetworkSSID");
    xw.WriteEndElement();
    xw.WriteEndElement();
    xw.WriteElementString(
    "connectionType", "ESS");
    xw.WriteStartElement(
    "MSM");
    xw.WriteStartElement(
    "security");
    xw.WriteStartElement(
    "authEncryption");
    xw.WriteElementString(
    "authentication", "open");
    xw.WriteElementString(
    "encryption", "WEP");
    xw.WriteEndElement();
    xw.WriteStartElement(
    "sharedKey");
    xw.WriteElementString(
    "keyType", "networkKey");
    xw.WriteElementString(
    "protected", "false");
    xw.WriteElementString(
    "keyMaterial", "MyNetworkKey");
    xw.WriteEndElement();
    xw.WriteElementString(
    "keyIndex", "0");
    xw.WriteEndElement();
    xw.WriteEndElement();
    xw.WriteEndElement();
    xw.WriteEndDocument();
    xw.Close();

    IntPtr profPtr = Marshal.StringToHGlobalUni(sw.ToString());
    IntPtr reasonCode = IntPtr.Zero;
    ret = WlanSetProfile(
    this.clientHandle, this.interfacePtr, 0, profPtr, IntPtr.Zero, true, IntPtr.Zero, out reasonCode);


    The problem is that the return value always is 2 (ERROR_FILE_NOT_FOUND), but I have absolutely no clue why it is happening.
    To be complete, this is the WlanSetProfile function specified:

    [
    DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanSetProfile(
    [
    In] IntPtr hClientHandle,
    [
    In] IntPtr pInterfaceGuid,
    [
    In] uint dwFlags,
    [In] IntPtr strProfileXml,
    [
    In] IntPtr strAllUserProfileSecurity,
    [In] bool bOverwrite,
    [
    In] IntPtr pReserved,
    [Out] out IntPtr pdwReasonCode);

    Does anyone have an idea where I'm going wrong?

     

    Tuesday, January 09, 2007 6:19 PM
  • Unfortunately I don't have a clue, but another problem ;-)

    I'm also trying to access the native wifi api from C#. But I'm already failing at the WlanEnumInterfaces function. To be exact, the function returns ok, but I have trouble converting the pointer to the WLAN_INTERFACE_INFO_LIST structure, just like you had before... When I do something like this:

    WLAN_INTERFACE_INFO_LIST interfaceList = new WLAN_INTERFACE_INFO_LIST();
    IntPtr
    interfaceListPtr;
    WlanEnumInterfaces(handle,
    IntPtr.Zero, out interfaceListPtr); // returns 0 = OK
    interfaceList = (WLAN_INTERFACE_INFO_LIST) Marshal.PtrToStructure(interfaceListPtr, typeof(WLAN_INTERFACE_INFO_LIST));

    I always get an AccessViolationException. I also tried with Marshal.Alloc...ating some memory for the pointer, still the same. Here's my C# definition of the structs:

    [StructLayout(LayoutKind.Sequential)]
    public struct WLAN_INTERFACE_INFO
    {
      public Guid InterfaceGuid;
      [
    MarshalAs(UnmanagedType.LPWStr, SizeConst=256)]
      public string strInterfaceDescription;
      public WLAN_INTERFACE_STATE isState;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WLAN_INTERFACE_INFO_LIST
    {
      public int dwNumberOfItems;
      public int dwIndex;
      // maybe I need some MarshalAs description here?
      public WLAN_INTERFACE_INFO[] InterfaceInfo;
    }

    Funny thing is, if I change the last field from WLAN_INTERFACE_INFO[] to WLAN_INTERFACE_INFO, it works. As most computers only have one WLAN adapter anyway, this could be used as a workaround, but I really would like to get it right. So it seems there is some problem with the marshalling of the array, probably because the size is unknown. You mentioned you got it all working except for some other error, maybe you could post the code that works for you (the structs, the dllimports, how you create the struct from the pointer)?

    Thanks in advance,
    Patrick

    Thursday, January 11, 2007 12:42 AM
  • Patrick, I created a constructor in the WLAN_INTERFACE_INFO_LIST struct which reads out all the variables manually:

    public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
    {
    dwNumberOfItems = Marshal.ReadInt32(pList, 0);
    dwIndex = Marshal.ReadInt32(pList, 4);
    InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberOfItems];

    for (int i = 0; i < dwNumberOfItems; i++)
    {
      IntPtr pItemList = new IntPtr(pList.ToInt32() + (i * 284));
      WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO();
     
      byte[] intGuid = new byte[16];
      for (int j = 0; j < 16; j++)
      {
        intGuid[j] = Marshal.ReadByte(pItemList, 8 + j);
      }
      wii.InterfaceGuid = new Guid(intGuid);
      wii.InterfacePtr = new IntPtr(pItemList.ToInt32() + 8);
      wii.strInterfaceDescription =
        Marshal.PtrToStringUni(new IntPtr(pItemList.ToInt32() + 24), 256).Replace("\0", "");
      wii.isState = (WLAN_INTERFACE_STATE)Marshal.ReadInt32(pItemList, 280);

      InterfaceInfo[ i ] = wii;
    }
    }

    I like your solution more, but as you say, there needs to be a way of detecting the number of WLAN_INTERFACE_INFO items for the marshalling.

    Thursday, January 11, 2007 12:41 PM
  • After some more investigation I do think that a MarshalAs should be possible to solve this problem. There is a SizeParamIndex field which can be set in the MarshalAs attribute. In our case it should be set to 0, because the first parameter of the struct (dwNumberOfItems) tells us the size of the array.

    But I'm still playing around with the UnmanagedType, because setting it to LPArray results in a runtime error: "Cannot marshal field 'InterfaceInfo' of type 'WLAN_INTERFACE_INFO_LIST': Invalid managed/unmanaged type combination  (Arrays fields must be paired with ByValArray or SafeArray)."
    Thursday, January 11, 2007 3:37 PM
  • Thanks for your quick answer, I tried that and it works fine. But now I'm stuck at getting the available network list. I'm only able to get the first network on the list, I have no idea where I can get the rest of them. So basically this is what I do:

    public static WLAN_AVAILABLE_NETWORK_LIST GetAvailableNetworkList(IntPtr handle, WLAN_INTERFACE_INFO wii)
    {
      IntPtr ppAvailableNetworkList;
      if (WlanGetAvailableNetworkList(handle, wii.InterfacePtr, 0, IntPtr.Zero, out ppAvailableNetworkList) != 0)
        throw new System.IO.IOException("Error getting network list");
      return new WLAN_AVAILABLE_NETWORK_LIST(ppAvailableNetworkList);
    }

    In the WLAN_AVAILABLE_NETWORK_LIST constructor I try to get the WLAN_AVAILABLE_NETWORKs just like with the interfaces, but somehow it doesn't work. I can get the number of available networks and the first network, but I don't know how to setup the pointer for the next item:

    public WLAN_AVAILABLE_NETWORK_LIST(IntPtr pList)
    {
      dwNumberOfItems =
    Marshal.ReadInt32(pList, 0);
      dwIndex =
    Marshal.ReadInt32(pFirstNetwork, 4);
      Network =
    new WLAN_AVAILABLE_NETWORK[dwNumberOfItems];
      for (int i = 0; i < dwNumberOfItems; i++)
      {
        NetworkIdea =
    new WLAN_AVAILABLE_NETWORK(new IntPtr(pList.toInt32() + 8 + ...));  // <-- What do I have to insert here?
      }
    }

    The problem is that the WLAN_AVAILABLA_NETWORK struct obviously doesn't have a fixed size. I've tried getting the offset from the WLAN_AVAILABLE_NETWORK constructor, doesn't work. My guess is that there are actually several WLAN_AVAILABLE_NETWORK_LIST structs in memory, each with a different dwIndex and exactly one WLAN_AVAILABLE_NETWORK struct, could that be? The MSDN specification of WLAN_AVAILABLE_NETWORK_LIST defines the size of the WLAN_AVAILABLE_NETWORK array as 1, that's also a hint at that. Now if that were the case, where can I find those ...LIST structs? The pointer returned by WlanGetAvailableNetworkList points exactly on the first ...LIST struct. Could it be that the pointer to the next struct is just behind this pointer in memory? If that is so, how can I access that from C# (if at all)? Or am I maybe completely on the wrong track?

    Thanks again,
    Patrick

    Thursday, January 11, 2007 7:02 PM
  • Uh, hadn't read your last post. I thought about that too, and I also tried some combination of the unmanaged array types and parameters, but couldn't get it to work. My guess is that it isn't possible if the marshaller doesn't know the size of the array, but if you find a way I'd be glad to hear. Your solution with the constructor is probably fine for most uses, the only thing is, it relies on an exact number of bytes for the fields, so it probably is very platform-dependent. Shouldn't be to much of a problem though, as these APIs are very platform-dependent, too.
    Thursday, January 11, 2007 7:12 PM
  • What makes you think that the WLAN_AVAILABLE_NETWORK struct doesn't have a fixed length?
    All the strings and arrays have a maximum length, so each struct should just be the maximum number of bytes, but of course with empty ones when the actual values are shorter.

    (I haven't actually implemented this function yet, so maybe I'm missing something).

    Thursday, January 11, 2007 7:20 PM
  • Ok, your're right, it does have a maximum size, but I doubt that that is the size for all of the elements (although it could be). The main reason for this is the DOT11_PHY_TYPE array, with the ulong (64-bit!) uNumberOfPhyTypes variable counting the elements. Of course this array is maxed to WLAN_MAX_PHY_TYPE_NUMBER, but I have no idea what this usually is since I don't have the Wlanapi.h file. But I also tried reading the memory after the first WLAN_AVAILABLE_NETWORK struct bytewise searching for the SSID of the second network, which should be at the beginning of the next struct, and i can't find it (yes I considered it is in unicode). So it seems either the struct is somewhere completely else in memory or the other networks are not returned, which would be strange as the dwNumberOfItems in the WLAN_AVAILABLE_NETWORK_LIST is about right.

    I'm really beginning to get frustrated, I just want to get the available networks and connect to one (at first). I've tried every approach from NDIS over WMI and WZC to the Native Wifi API, and nothing seems to work as it should. Well, maybe it's just me not getting it right... Unfortunately there don't seem to be working code samples around, too...

    FYI, I use the Native Wifi LAN API for XP SP2.

    Patrick

    Thursday, January 11, 2007 7:44 PM
  • According to the MSDN documentation WLAN_MAX_PHY_TYPE_NUMBER has a value of 8 (you must have read past it).

    I know the frustation you feel. I have exactly the same thing; it seems like no one else has used the WLAN API in managed code.
    Anyway, I'll continue to do some more investigation tomorrow (UK here) on this WlanGetAvailableNetworkList function.

    Thursday, January 11, 2007 10:53 PM
  • I finally found the solution for my first problem: it turns out that you don't pass in the interfaceGuid as an IntPtr but as a 'ref Guid'. This makes the WlanSetProfile function working as it should do.

    But the WlanGetAvailableNetworkList still baffles me. I see exactly the same things as you do, Patrick. The number of items seems correct, but when I then look down the line I can't see all the SSIDs it has found.

     

    Friday, January 12, 2007 11:54 AM
  • Has anyone had luck with the WlanConnect function in .NET?  I am getting an unknown error (1168) when calling the function.  I have successfully called the WlanOpenHandle function.  I have been using the example in the SDK as guidance, but I am now stuck.  Any help would be great!  Thanks!

    Monday, January 22, 2007 8:28 PM
  • Was anyone able to create a working C# wrapper for the native wireless api?

    I followed the code on this thread but was unable to make it function as expected.

    Thanks!
    Monday, January 29, 2007 3:10 PM
  • Is there anyone that has written the wrapper for c# language?
    Wednesday, March 14, 2007 10:43 AM
  • With these code, I got the WlanGetAvailableNetworkList working properly. And I have to figure out that the WCHAR is 2bytes, not 1byte.

     

    [StructLayout(LayoutKind.Sequential)]
            public struct DOT11_SSID // size 36
            {
                public UInt32 uSSIDLength; // size 4
                public char[] ucSSID;  // size is 32*1

                public DOT11_SSID(IntPtr p)
                {
                    uSSIDLength = System.Convert.ToUInt32(Marshal.ReadInt32(p, 0));
                    ucSSID = new char[32];
                    //if (uSSIDLength <= 32)
                    //{
                        for (int i = 0; i < 32; i++)
                        {
                            ucSSIDIdea = (char)Marshal.ReadByte(p, 4 + i);
                        }
                    //}
                }
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct WLAN_AVAILABLE_NETWORK_LIST
            {
                public int dwNumberOfItems;
                public int dwIndex;
                public WLAN_AVAILABLE_NETWORK[] NetWork;

                public WLAN_AVAILABLE_NETWORK_LIST(IntPtr pList)
                {
                    dwNumberOfItems = Marshal.ReadInt32(pList, 0);
                    dwIndex = Marshal.ReadInt32(pList, 4);

                    NetWork = new WLAN_AVAILABLE_NETWORK[dwNumberOfItems];

                    for (int i = 0; i < dwNumberOfItems; i++)
                    {
                        IntPtr pItemList = new IntPtr(pList.ToInt32() + 8 + (i * 628));
                        WLAN_AVAILABLE_NETWORK wan = new WLAN_AVAILABLE_NETWORK();
                        wan.strProfileName = Marshal.PtrToStringUni(pItemList, 256).Replace("\0", "");
                        wan.dot11Ssid = new DOT11_SSID(new IntPtr(pItemList.ToInt32() + 512));  // now is 512+36=548
                        wan.dot11BssType =(DOT11_BSS_TYPE) Marshal.ReadInt32(pItemList, 548); // off 552
                        wan.uNumberOfBssids = (uint)Marshal.ReadInt32(pItemList, 552); // off 556
                        wan.bNetworkConnectable = System.Convert.ToBoolean(Marshal.ReadInt32(pItemList, 556)); // off 560
                        wan.wlanNotConnectableReason = (UInt32)Marshal.ReadInt32(pItemList, 560); // off 564
                        wan.uNumberOfPhyTypes = (UInt32)Marshal.ReadInt32(pItemList, 564); // off 568
                        wan.dot11PhyTypes = new DOT11_PHY_TYPEMusic;// off 600
                        for (int j = 0; j < wan.uNumberOfPhyTypes; j++)
                        {
                            wan.dot11PhyTypes[j] = (DOT11_PHY_TYPE)Marshal.ReadInt32(pItemList, 568 + j * 4);
                        }
                        wan.bMorePhyTypes = System.Convert.ToBoolean(Marshal.ReadInt32(pItemList, 600)); // off 604
                        wan.wlanSignalQuality = (UInt32)Marshal.ReadInt32(pItemList, 604); // off 608
                        wan.bSecurityEnabled = System.Convert.ToBoolean(Marshal.ReadInt32(pItemList, 608)); // off 612
                        wan.dot11DefaultAuthAlgorithm = (DOT11_AUTH_ALGORITHM)Marshal.ReadInt32(pItemList, 612); //616
                        wan.dot11DefaultCipherAlgorithm = (DOT11_CIPHER_ALGORITHM)Marshal.ReadInt32(pItemList, 616); // off 620
                        wan.dwFlags = (UInt32)Marshal.ReadInt32(pItemList, 620); // off 624
                        wan.dwReserved = 0; // off 628
                        NetWorkIdea = wan;
                    }

                }
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct WLAN_AVAILABLE_NETWORK // size 628 in byte
            {
                [MarshalAs(UnmanagedType.LPWStr, SizeConst = 256)]
                public string strProfileName; // size 512
                public DOT11_SSID dot11Ssid; // size 36
                public DOT11_BSS_TYPE dot11BssType; // size 4
                public UInt32 uNumberOfBssids; // 4
                public bool bNetworkConnectable; // 4
                public UInt32 wlanNotConnectableReason; // 4
                public UInt32 uNumberOfPhyTypes; // 4
                public DOT11_PHY_TYPE[] dot11PhyTypes; // max is 8, size is 8*4 = 32
                public bool bMorePhyTypes;// 4
                public UInt32 wlanSignalQuality; // see doc, size 4
                public bool bSecurityEnabled;// 4
                public DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;// 4
                public DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;// 4
                public UInt32 dwFlags;// 4
                public UInt32 dwReserved;// 4
            }

    Tuesday, March 27, 2007 8:09 AM
  • Hi guys, I've been reading the post and I'm wondering if you finally could obtain the list of networks? I've tried the code that you paste but the DOT11_BSS_TYPE, DOT11_PHY_TYPE, DOT11_AUTH_ALGORITHM, DOT11_CIPHER_ALGORITHM doesn't exists. Do you have the declaration?

    Thanks,
    Nelson
    Monday, April 02, 2007 6:44 PM
  • Hi , You don't need to worry about that "Funny thing is, if I change the last field from WLAN_INTERFACE_INFO[] to WLAN_INTERFACE_INFO" .
    you don't need to rewrite any constructure

    You just change your orginal structure
    [StructLayout(LayoutKind.Sequential)]
    public struct WLAN_INTERFACE_INFO_LIST
    {
      public int dwNumberOfItems;
      public int dwIndex;
      // maybe I need some MarshalAs description here?
      public WLAN_INTERFACE_INFO[] InterfaceInfo;
    }


    to below (which I wrote by vb.net )
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure WLAN_INTERFACE_INFO_LIST
            <MarshalAs(UnmanagedType.I4)> Public dwNumberOfItems As Int32
            <MarshalAs(UnmanagedType.I4)> Public dwIndex As Int32
            <MarshalAs(UnmanagedType.ByValArray)> Public InterfaceInfo() As WLAN_INTERFACE_INFO
        End Structure

    Everythig will be ok  and smooth !
    Wednesday, April 04, 2007 3:01 PM
  • Code Snippet

    [StructLayout(LayoutKind.Sequential)]
    public struct WLAN_INTERFACE_INFO_LIST
    {
     [MarshalAs(UnmanagedType.I4)]
     public Int32 dwNumberOfItems;
     [MarshalAs(UnmanagedType.I4)]
     public Int32 dwIndex;
     [MarshalAs(UnmanagedType.ByValArray)]
     public WLAN_INTERFACE_INFO[] InterfaceInfo;
    }

    Thursday, April 05, 2007 3:27 PM
  •  Nelson wrote:
    Hi guys, I've been reading the post and I'm wondering if you finally could obtain the list of networks? I've tried the code that you paste but the DOT11_BSS_TYPE, DOT11_PHY_TYPE, DOT11_AUTH_ALGORITHM, DOT11_CIPHER_ALGORITHM doesn't exists. Do you have the declaration?

    Thanks,
    Nelson

     

    Hi man, you can find the declaration in wlanapi.h or the MSDN.

     

    And now I have a new question:

    this struct :

    struct _WLAN_BSS_ENTRY {
      DOT11_SSID dot11Ssid;
      ULONG uPhyId;
      DOT11_MAC_ADDRESS dot11Bssid;
      DOT11_BSS_TYPE dot11BssType;
      LONG lRssi;
      ULONG uLinkQuality;
      BOOLEAN bInRegDomain;
      USHORT usBeaconPeriod;
      ULONGLONG ullTimestamp;
      ULONGLONG ullHostTimestamp;
      USHORT usCapabilityInformation;
      ULONG ulChCenterFrequency;
      WLAN_RATE_SET wlanRateSet;
      ULONG ulIeOffset;
      ULONG ulIeSize;
    }

     

    this struct is used in WlanGetNetworkBssList, and I don't know what the data that starts at ulIeOffset with the ulIeSize size contains.

    Does it contain the security infomation?

    Saturday, April 07, 2007 9:09 AM
  •  Nelson wrote:
    Hi guys, I've been reading the post and I'm wondering if you finally could obtain the list of networks? I've tried the code that you paste but the DOT11_BSS_TYPE, DOT11_PHY_TYPE, DOT11_AUTH_ALGORITHM, DOT11_CIPHER_ALGORITHM doesn't exists. Do you have the declaration?

    Thanks,
    Nelson

     

    Hi man, you can find the declaration in wlanapi.h or the MSDN.

     

    And now I have a new question:

    this struct :

    struct _WLAN_BSS_ENTRY {
      DOT11_SSID dot11Ssid;
      ULONG uPhyId;
      DOT11_MAC_ADDRESS dot11Bssid;
      DOT11_BSS_TYPE dot11BssType;
      LONG lRssi;
      ULONG uLinkQuality;
      BOOLEAN bInRegDomain;
      USHORT usBeaconPeriod;
      ULONGLONG ullTimestamp;
      ULONGLONG ullHostTimestamp;
      USHORT usCapabilityInformation;
      ULONG ulChCenterFrequency;
      WLAN_RATE_SET wlanRateSet;
      ULONG ulIeOffset;
      ULONG ulIeSize;
    }

     

    this struct is used in WlanGetNetworkBssList, and I don't know what the data that starts at ulIeOffset with the ulIeSize size contains.

    Does it contain the security infomation?

    Saturday, April 07, 2007 9:10 AM
  • Hi ,
    is there anyone successfully implement wlanconnect, which is a WiFi's function in wlanapi.dll, using C# or vb.net
    could you show your partical code or give me a hit ?

    Because that function of wlanconnect I always get 87(invalid parameter) error code  !
    below it is my partical code for wlanconnect in vb.net

        ''----------------------------------------------------------------------------------
        ''--------------------------------Native WiFi Functions----------------------------
        ''----------------------------------------------------------------------------------
        <DllImport("wlanapi.dll", SetLastError:=True)> _
        Public Shared Function WlanConnect( _
            <[In]()> ByVal hClientHandle As IntPtr, _
            <[In]()> ByVal pInterfaceGuid As IntPtr, _
            <[In]()> ByVal pConnectionParameters As IntPtr, _
            <[In]()> ByRef pReserved As IntPtr) As Int32
        End Function
        ''----------------------------------------------------------------------------------
        ''--------------------------------Native WiFi Structures----------------------------
        ''----------------------------------------------------------------------------------
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure WLAN_CONNECTION_PARAMETERS
            Public wlanConnectionMode As WLAN_CONNECTION_MODE
            Public strProfile As IntPtr
            Public pDot11Ssid As IntPtr
            Public pDesiredBssidList As IntPtr
            Public dot11BssType As DOT11_BSS_TYPE
            Public dwFlags As Int32
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure DOT11_BSSID_LIST
            Public Header As NDIS_OBJECT_HEADER
            Public uNumOfEntries As UInt32
            Public uTotalNumOfEntries As UInt32
            Public BSSIDs As IntPtr
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure DOT11_MAC_ADDRESS
            <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.U8, SizeConst:=6)> Public ucDot11MacAddress() As SByte
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure NDIS_OBJECT_HEADER
            Public Type As SByte
            Public Revision As SByte
            Public Size As SByte
        End Structure
        Public Enum WLAN_CONNECTION_MODE
            wlan_connection_mode_profile
            wlan_connection_mode_temporary_profile
            wlan_connection_mode_discovery_secure
            wlan_connection_mode_discovery_unsecure
            wlan_connection_mode_auto
            wlan_connection_mode_invalid
        End Enum
        Public Enum DOT11_BSS_TYPE
            dot11_BSS_type_infrastructure
            dot11_BSS_type_independent
            dot11_BSS_type_any
        End Enum
        '----------------------------------------------------------------------------------
        '----------------------------------- Form for UI ----------------------------------
        '----------------------------------------------------------------------------------
        Private Sub btCon_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCon.Click
            Dim clienthandle As IntPtr = IntPtr.Zero
            Dim dwError As Int32 = 0
            Dim wiil As WiFi.WLAN_INTERFACE_INFO_LIST = Nothing
     
            dwError = WiFi.wlanInterface_start(wiil)
     
            Dim Ptr_net As IntPtr
            Dim numOfNetworks As Integer
            dwError = getNumOfNetworks(wiil, numOfNetworks, Ptr_net)
            Dim Ptr_myNetwork(numOfNetworks) As IntPtr
            Dim myNetwork(numOfNetworks) As WiFi.WLAN_AVAILABLE_NETWORK
            dwError = getVisibleNetworksPtr(wiil, Ptr_net, numOfNetworks, Ptr_myNetwork)
            Dim i As Integer = 0
            For i = 0 To numOfNetworks - 1
                'convert address of network field in WiFi.WLAN_AVAILABLE_NETWORK_LIST to Structure of WiFi.WLAN_AVAILABLE_NETWORK
                'move Ptr to the next data of WiFi.WLAN_AVAILABLE_NETWORK
                myNetwork(i) = CType(Marshal.PtrToStructure(Ptr_myNetwork(i), GetType(WiFi.WLAN_AVAILABLE_NETWORK)), WiFi.WLAN_AVAILABLE_NETWORK)
            Next
     
            Dim wcp As WLAN_CONNECTION_PARAMETERS = Nothing
            Dim Ptr_wcp As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wcp))
            Marshal.StructureToPtr(wcp, Ptr_wcp, True)
     
            wcp.wlanConnectionMode = WLAN_CONNECTION_MODE.wlan_connection_mode_profile
            'wcp.strProfile = New String(WiFi.SsidToStringW(myNetwork(0).dot11Ssid)).Replace(Chr(0), "")
            wcp.strProfile = Marshal.StringToHGlobalUni("HG2414")
            wcp.pDot11Ssid = Ptr_myNetwork(0).ToInt32 + (256 * 2)
            Dim DBssidL As DOT11_BSSID_LIST = Nothing
            Dim Ptr_DBssidL As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(DBssidL))
            Marshal.StructureToPtr(DBssidL, Ptr_DBssidL, True)
     
            wcp.pDesiredBssidList = Ptr_DBssidL
            wcp.dot11BssType = DOT11_BSS_TYPE.dot11_BSS_type_independent
            wcp.dwFlags = 0
     
            'Dim test As WiFi.WLAN_INTERFACE_INFO = CType(Marshal.PtrToS tructure(Ptr_Guid, GetType(WiFi.WLAN_INTERFACE_INFO)), WiFi.WLAN_INTERFACE_INFO)
            'Dim test1 As WLAN_CONNECTION_PARAMETERS = CType(Marshal.PtrToStructure(Ptr_wcp, GetType(WLAN_CONNECTION_PARAMETERS)), WLAN_CONNECTION_PARAMETERS)
     
            dwError = WiFi.get_clientHandle(clienthandle)
            dwError = WlanConnect(clienthandle, WiFi.GetGuidPtr(wiil), Ptr_wcp, IntPtr.Zero)
            ' MsgBox(dwError & "," & New Win32Exception(dwError).Message)
            dwError = WiFi.close_clientHandle(clienthandle)
            WiFi.WlanFreeMemory(Ptr_wcp)
            WiFi.WlanFreeMemory(clienthandle)
        End Sub
    Tuesday, April 17, 2007 7:11 AM
  • is there someone help me to deal it !Please
    Thanks !
    Friday, April 20, 2007 3:47 AM
  •  
    I have cheched many situation about error code 87(invalid parameter)
    but I stiil cannot deal with it !
    someone help me about wlanconnect fuction  ...
     
    Return code Description
    ERROR_INVALID_PARAMETER One of the following conditions occurred:

    • hClientHandle is NULL or invalid.
    • pInterfaceGuid is NULL.
    • pConnectionParameters is NULL.
    • The dwFlags member of the structure pointed to by pConnectionParameters is not set to one of the values specified on the WLAN_CONNECTION_PARAMETERS page.
    • The wlanConnectionMode member of the structure pointed to by pConnectionParameters is set to wlan_connection_mode_discovery_secure or wlan_connection_mode_discovery_unsecure, and the pDot11Ssid member of the same structure is NULL.
    • The wlanConnectionMode member of the structure pointed to by pConnectionParameters is set to wlan_connection_mode_discovery_secure or wlan_connection_mode_discovery_unsecure, and the dot11BssType member of the same structure is set to dot11_BSS_type_any.
    • The wlanConnectionMode member of the structure pointed to by pConnectionParameters is set to wlan_connection_mode_profile, and the strProfile member of the same structure is NULL or the length of the profile exceeds WLAN_MAX_NAME_LENGTH.
    • The wlanConnectionMode member of the structure pointed to by pConnectionParameters is set to wlan_connection_mode_profile, and the strProfile member of the same structure is NULL or the length of the profile is zero.
    • The wlanConnectionMode member of the structure pointed to by pConnectionParameters is set to wlan_connection_mode_invalid.
    • The dot11BssType member of the structure pointed to by pConnectionParameters is set to dot11_BSS_type_infrastructure, and the dwFlags member of the same structure is set to WLAN_CONNECTION_ADHOC_JOIN_ONLY.
    • The dot11BssType member of the structure pointed to by pConnectionParameters is set to dot11_BSS_type_independent, and the dwFlags member of the same structure is set to WLAN_CONNECTION_HIDDEN_NETWORK.
    • The dwFlags member of the structure pointed to by pConnectionParameters is set to WLAN_CONNECTION_IGNORE_PRIVACY_BIT, and either the wlanConnectionMode member of the same structure is not set to wlan_connection_mode_temporary_profile or the dot11BssType member of the same structure is set to dot11_BSS_type_independent.

    Friday, April 20, 2007 3:57 AM
  •  
    Hi ,
    is there anyone successfully implement wlanconnect, which is a WiFi's function in wlanapi.dll, using C# or vb.net
    could you show your partical code or give me a hit ?     Thanks !

    Because that function of wlanconnect I always get 87(invalid parameter) error code  !
    below it is my partical code for wlanconnect in vb.net

        ''----------------------------------------------------------------------------------
        ''--------------------------------Native WiFi Functions----------------------------
        ''----------------------------------------------------------------------------------
        <DllImport("wlanapi.dll", SetLastError:=True)> _
        Public Shared Function WlanConnect( _
            <[In]()> ByVal hClientHandle As IntPtr, _
            <[In]()> ByVal pInterfaceGuid As IntPtr, _
            <[In]()> ByVal pConnectionParameters As IntPtr, _
            <[In]()> ByRef pReserved As IntPtr) As Int32
        End Function
        ''----------------------------------------------------------------------------------
        ''--------------------------------Native WiFi Structures----------------------------
        ''----------------------------------------------------------------------------------
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure WLAN_CONNECTION_PARAMETERS
            Public wlanConnectionMode As WLAN_CONNECTION_MODE
            Public strProfile As IntPtr
            Public pDot11Ssid As IntPtr
            Public pDesiredBssidList As IntPtr
            Public dot11BssType As DOT11_BSS_TYPE
            Public dwFlags As Int32
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure DOT11_BSSID_LIST
            Public Header As NDIS_OBJECT_HEADER
            Public uNumOfEntries As UInt32
            Public uTotalNumOfEntries As UInt32
            Public BSSIDs As IntPtr
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure DOT11_MAC_ADDRESS
            <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.U8, SizeConst:=6)> Public ucDot11MacAddress() As SByte
        End Structure
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure NDIS_OBJECT_HEADER
            Public Type As SByte
            Public Revision As SByte
            Public Size As SByte
        End Structure
        Public Enum WLAN_CONNECTION_MODE
            wlan_connection_mode_profile
            wlan_connection_mode_temporary_profile
            wlan_connection_mode_discovery_secure
            wlan_connection_mode_discovery_unsecure
            wlan_connection_mode_auto
            wlan_connection_mode_invalid
        End Enum
        Public Enum DOT11_BSS_TYPE
            dot11_BSS_type_infrastructure
            dot11_BSS_type_independent
            dot11_BSS_type_any
        End Enum
        '----------------------------------------------------------------------------------
        '----------------------------------- Form for UI ----------------------------------
        '----------------------------------------------------------------------------------
        Private Sub btCon_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCon.Click
            Dim clienthandle As IntPtr = IntPtr.Zero
            Dim dwError As Int32 = 0
            Dim wiil As WiFi.WLAN_INTERFACE_INFO_LIST = Nothing
     
            dwError = WiFi.wlanInterface_start(wiil)
     
            Dim Ptr_net As IntPtr
            Dim numOfNetworks As Integer
            dwError = getNumOfNetworks(wiil, numOfNetworks, Ptr_net)
            Dim Ptr_myNetwork(numOfNetworks) As IntPtr
            Dim myNetwork(numOfNetworks) As WiFi.WLAN_AVAILABLE_NETWORK
            dwError = getVisibleNetworksPtr(wiil, Ptr_net, numOfNetworks, Ptr_myNetwork)
            Dim i As Integer = 0
            For i = 0 To numOfNetworks - 1
                'convert address of network field in WiFi.WLAN_AVAILABLE_NETWORK_LIST to Structure of WiFi.WLAN_AVAILABLE_NETWORK
                'move Ptr to the next data of WiFi.WLAN_AVAILABLE_NETWORK
                myNetwork(i) = CType(Marshal.PtrToStructure(Ptr_myNetwork(i), GetType(WiFi.WLAN_AVAILABLE_NETWORK)), WiFi.WLAN_AVAILABLE_NETWORK)
            Next
     
            Dim wcp As WLAN_CONNECTION_PARAMETERS = Nothing
            Dim Ptr_wcp As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wcp))
            Marshal.StructureToPtr(wcp, Ptr_wcp, True)
     
            wcp.wlanConnectionMode = WLAN_CONNECTION_MODE.wlan_connection_mode_profile
            'wcp.strProfile = New String(WiFi.SsidToStringW(myNetwork(0).dot11Ssid)).Replace(Chr(0), "")
            wcp.strProfile = Marshal.StringToHGlobalUni("HG2414")
            wcp.pDot11Ssid = Ptr_myNetwork(0).ToInt32 + (256 * 2)
            Dim DBssidL As DOT11_BSSID_LIST = Nothing
            Dim Ptr_DBssidL As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(DBssidL))
            Marshal.StructureToPtr(DBssidL, Ptr_DBssidL, True)
     
            wcp.pDesiredBssidList = Ptr_DBssidL
            wcp.dot11BssType = DOT11_BSS_TYPE.dot11_BSS_type_independent
            wcp.dwFlags = 0
     
            'Dim test As WiFi.WLAN_INTERFACE_INFO = CType(Marshal.PtrToS tructure(Ptr_Guid, GetType(WiFi.WLAN_INTERFACE_INFO)), WiFi.WLAN_INTERFACE_INFO)
            'Dim test1 As WLAN_CONNECTION_PARAMETERS = CType(Marshal.PtrToStructure(Ptr_wcp, GetType(WLAN_CONNECTION_PARAMETERS)), WLAN_CONNECTION_PARAMETERS)
     
            dwError = WiFi.get_clientHandle(clienthandle)
            dwError = WlanConnect(clienthandle, WiFi.GetGuidPtr(wiil), Ptr_wcp, IntPtr.Zero)
            ' MsgBox(dwError & "," & New Win32Exception(dwError).Message)
            dwError = WiFi.close_clientHandle(clienthandle)
            WiFi.WlanFreeMemory(Ptr_wcp)
            WiFi.WlanFreeMemory(clienthandle)
        End Sub
     
    Friday, April 20, 2007 4:11 AM
  • Thanks for everyone !
    I have done it .

    Thanks again , That main problem was Guid pointer and dot11Bsstype must set it the same as networkAP which write at http://msdn2.microsoft.com/en-us/library/ms706851.aspx

    dot11BssType
    A DOT11_BSS_TYPE value that indicates the BSS type of the network. If a profile is provided, this BSS type must be the same as the one in the profile.
    Saturday, April 21, 2007 12:18 PM
  • Thanks for everyone !
    I have done it .

    Thanks again , That main problem was Guid pointer and dot11Bsstype must set it the same as networkAP which write at http://msdn2.microsoft.com/en-us/library/ms706851.aspx

    dot11BssType
    A DOT11_BSS_TYPE value that indicates the BSS type of the network. If a profile is provided, this BSS type must be the same as the one in the profile.
    Sunday, April 22, 2007 3:11 AM
  • Hi Tom,

    I am getting problem while using WlanSetProfile function.it is returning me error code 1206(ERROR_BAD_PROFILE) and reason code 524289.

    Can you  plz tell me what is the problem and how can i solve it.but same profile worls in C++ application.

     

    Waiting for ur help.

    Bye

    vinit

    Tuesday, May 08, 2007 12:28 PM
  • Hi m0929823923,

    What did you do to solve the above problem(removing error code 87).i am facing the same problem.Its urgent.Please.........................

     

     

     

    Vinit

    Tuesday, May 08, 2007 2:26 PM
  • Hi, well, I've been trying to implement the "WlanConnect" method in C#. I'm always receiving error 87. Here is the code:

    [DllImport("wlanapi.dll", SetLastError = true)]
    private static extern int WlanConnect(
    [In] IntPtr hClientHandle,
    [In] IntPtr pInterfaceGuid,
    [In] //[System.Runtime.InteropServices.MarshalAsAttribute(UnmanagedType.Struct)]
    //WLAN_CONNECTION_PARAMETERS pConnectionParameters,
    IntPtr pConnectionParameters,
    [In] IntPtr pReserved
    );
    [StructLayout(LayoutKind.Sequential)]
    public struct DOT11_SSID
    {
    public UInt32 uSSIDLength;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = DOT11_SSID_MAX_LENGTH)]
    public SByte[] ucSSID;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WLAN_CONNECTION_PARAMETERS
    {
    public WLAN_CONNECTION_MODE wlanConnectionMode;
    public IntPtr strProfile;
    public IntPtr dot11Ssid;
    public IntPtr pDesiredBssidList;
    public DOT11_BSS_TYPE dot11BssType;
    public Int32 dwFlags;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct DOT11_BSSID_LIST
    {
    public NDIS_OBJECT_HEADER Header;
    public UInt32 uNumOfEntries;
    public UInt32 uTotalNumOfEntries;
    public IntPtr BSSIDs;//1
    }
    public int WlanConnect(ref Guid InterfaceGuid, IntPtr oWCP)
    {
    IntPtr ptrGuid = Marshal.AllocHGlobal(Marshal.SizeOf(InterfaceGuid));

    Marshal.StructureToPtr(InterfaceGuid, ptrGuid, true);


    return WlanConnect(phClientHandle,
    ptrGuid,
    oWCP,
    IntPtr.Zero);
    }
    private void btnConnect_Click(object sender, EventArgs e)
    {

    Guid gInt = new Guid(cboInterfaces.Text);
    IntPtr clienthandle = IntPtr.Zero;
    Int32 dwError = 0;

    WlanapiWrapper.WLAN_CONNECTION_PARAMETERS wcp;
    wcp = new WlanapiWrapper.WLAN_CONNECTION_PARAMETERS();
    IntPtr Ptr_wcp = Marshal.AllocHGlobal(Marshal.SizeOf(wcp));
    Marshal.StructureToPtr(wcp, Ptr_wcp, true);

    wcp.wlanConnectionMode = WlanapiWrapper.WLAN_CONNECTION_MODE.wlan_connection_mode_profile;
    wcp.strProfile = Marshal.StringToHGlobalUni("WPAUNsecure");
    wcp.dot11BssType = WlanapiWrapper.DOT11_BSS_TYPE.dot11_BSS_type_infrastructure;
    wcp.dwFlags = 0;
    dwError = oLANWRAPP.WlanConnect(
    ref gInt,
    Ptr_wcp);
    }


    When I click on my connect button I always receive error 87. Does anybody know what is happening or what can be the problem? I developed a testing application that opens the handle, enumerate the wireless interfaces installed on my machine, and enumerates the wireless networks that the selected wireless card is detecting. Then, when I click on connect to the selected network "WPAUNsecure" I always receive the error. This is driving me crazy. I'll appreciate any help.

    Nelson
    Wednesday, May 16, 2007 2:34 PM
  • Code Snippet

    uint x = 0;
                IntPtr clientHandle;

                IntPtr infoList = new IntPtr();

                Int32 a = WlanOpenHandle(1, IntPtr.Zero, out x, out clientHandle);
               
                Int32 b = WlanEnumInterfaces(clientHandle, IntPtr.Zero, out infoList);

                WLAN_INTERFACE_INFO_LIST t = new WLAN_INTERFACE_INFO_LIST();
                t = (WLAN_INTERFACE_INFO_LIST)Marshal.PtrToStructure(infoList, typeof(WLAN_INTERFACE_INFO_LIST));
               
                Marshal.FreeHGlobal(infoList);
                WlanCloseHandle(clientHandle, IntPtr.Zero);

    Have you guys gotten this working? Using the quoted structure, it works half the time. The other half of the time I get the Memory error.

    a and b return 0, so it runs fine.
    When it runs successfully, t.dwIndex and t.NumberOfItems return 0?! But I get an array with one element. It has a Guid, but no description or anything.

    When I plug in my wireless usb adapter, the code doesn't even run at all...
    Monday, May 21, 2007 1:32 AM
  • Hello,

     

    Can you please explain me...why are you using this statement?

     

    wii.InterfacePtr = new IntPtr(pItemList.ToInt32() + 8);

    wii interface doesn't provide any InterfacePtr data member.

     

    I have used the above code snippet. But I am getting some junk values for strInterfaceDescription if there are more than one wireless interface cards.

     

    The initial part of the 2nd wireless interface (strInterfaceDescription) contains some junk characters. Also GUID is empty. I think GUID data is coming as part of strInterfaceDescription.

     

    Is the above code snippet is working for you?

     

    Thanks

    Monday, May 21, 2007 4:06 AM
  • Hello,

     

    I am trying to access current wireless connection attributes using Wi-Fi API. For that , I am using WlanQueryInterface() function with WLAN_INTF_OPCODE as wlan_intf_opcode_current_connection value.

     

    I am writing a C# wrapper for this function. WlanQueryInterface() returns the attributes as ppData output argument. So I am trying to access each attribute by calculating memory offset.

     

    ppData represents the following structure:

     

    [StructLayout(LayoutKind.Sequential)]

    public struct WLAN_CONNECTION_ATTRIBUTES

    {

       public WLAN_INTERFACE_STATE isState;

       public WLAN_CONNECTION_MODE wlanconnectionMode;

       [MarshalAs(UnManagedType.LPWStr,SizeConst=WLAN_MAX_NAME_LENGTH)]

       public string strProfileName;

       public WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;

       public WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;

    }

     

    [StructLayout(LayoutKind.Sequential)]

    public struct WLAN_ASSOCIATION_ATTRIBUTES

    {

      public DOT11_SSID dot11SSID;

      public DOT11_BSS_TYPE dot11BssType;

      public DOT11_MAC_ADDRESS dot11MacAddress;

      public DOT11_PHY_TYPE dot11phyType;

      public UInt32  dot11phyType;

      public UInt32  dot11PhyIndex;

      public UInt32  wlanSignalQuality;

      public UInt32  ulRxrate;

      public UInt32  ulTxRate;

    }

     

    [StructLayout(LayoutKind.Sequential)]

    public struct WLAN_SECURITY_ATTRIBUTES

    {

     public Int32 bsecurityenabled;

     public Int32 bOneXenabled;

     public DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;

     public DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;

    }

     

    [StructLayout(LayoutKind.Sequential)]

    public struct DOT11_SSID

    {

     public UInt32 uSSIDLength;

    [MarshalAs(UnManagedType.LPArray,SizeConst=DOT11_SSID_MAX_LENGTH)]

    public char [] ucSSID;

    }

     

    I have added constructor for WLAN_CONNECTION_ATTRIBUTES structure which will read all attributes using memory offset calculation.

     

    The following is the constructor definition for WLAN_CONNECTION_ATTRIBUTES structure. This accepts ppData as input argument.

     

    /// <summary>
           /// structure WLAN_CONNECTION_ATTRIBUTES defines attributes of a wireless connection
            /// </summary>
           [StructLayout(LayoutKind.Sequential)]
           public struct WLAN_CONNECTION_ATTRIBUTES
           {
                public WLAN_INTERFACE_STATE isState;            // offset - 0
                public WLAN_CONNECTION_MODE wlanConnectionMode; // offset - 4
               [MarshalAs(UnmanagedType.LPWStr,SizeConst=WLAN_MAX_NAME_LENGTH)]
                public string strProfileName;                   // offset - 8
                public WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;   //offset - 520
                public WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes

    public WLAN_CONNECTION_ATTRIBUTES(IntPtr pData)
      {
      
    //read interface state
       isState = (WLAN_INTERFACE_STATE)Marshal.ReadInt32(pData, 0);

     //read connection mode
       wlanConnectionMode = (WLAN_CONNECTION_MODE)Marshal.ReadInt32(pData, 4);

                   //read profile name
                   strProfileName = Marshal.PtrToStringUni(new IntPtr(pData.ToInt32() + 8), WLAN_MAX_NAME_LENGTH).Replace("\0", "");

                   //assigning association attributes
                   //SSID length & SSID
                   wlanAssociationAttributes.dot11Ssid.uSSIDLength = (UInt32)Marshal.ReadInt32(pData, 520);
                   wlanAssociationAttributes.dot11Ssid.ucSSID = new char[DOT11_SSID_MAX_LENGTH];
                   for (int index = 0; index < DOT11_SSID_MAX_LENGTH; index++)
                   {
                       wlanAssociationAttributes.dot11Ssid.ucSSID[index] = (char)Marshal.ReadByte(pData, 524 + index);
                   }
                   //BSS type
                   wlanAssociationAttributes.dot11BssType = (DOT11_BSS_TYPE)Marshal.ReadInt32(pData, 556);

                   //MAC Address
                   wlanAssociationAttributes.dot11Bssid.ucDot11MacAddress = new char;
                   for (int index = 0; index < 6; index++)
                       wlanAssociationAttributes.dot11Bssid.ucDot11MacAddress[index] = (char)Marshal.ReadByte(pData, 560 + index);

                   int iiii = sizeof(uint);
                  
                   //Phy Type
                   int phyType = Marshal.ReadInt32(pData, 566);
                   wlanAssociationAttributes.dot11PhyType = (DOT11_PHY_TYPE)Marshal.ReadInt32(pData, 566);

                   //Dot11 phy index
                   wlanAssociationAttributes.uDot11PhyIndex = (UInt32)Marshal.ReadInt32(pData, 570);

                   //wlan Signal Quality
                   wlanAssociationAttributes.wlanSignalQuality = (UInt32)Marshal.ReadInt32(pData, 574);

                   //Received rate
                   wlanAssociationAttributes.ulRxRate = (UInt32)Marshal.ReadInt32(pData, 578);

                   //Transmission rate
                   wlanAssociationAttributes.ulTxRate = (UInt32)Marshal.ReadInt32(pData, 582);

                   //assigning security attributes
                   //Security enabled
                   wlanSecurityAttributes.bSecurityEnabled = Marshal.ReadInt32(pData, 586);
                   //Onexenabled
                   wlanSecurityAttributes.bOneXEnabled = Marshal.ReadInt32(pData, 590);
                   //dot11authalgorithm
                   wlanSecurityAttributes.dot11AuthAlgorithm = (DOT11_AUTH_ALGORITHM)Marshal.ReadInt32(pData, 594);
                   //dot11cipheralgorithm
                   wlanSecurityAttributes.dot11CipherAlgorithm = (DOT11_CIPHER_ALGORITHM)Marshal.ReadInt32(pData, 598);
               }

     

    Here the main problem appears in dot11PhyType data member. Please check the bold statements in constructor. After reading MacAddress, I am reading dot11PhyType, wlanSignalQuality etc. These fields are returning 8 byte instead of 4 byte value.

     

    i.e. I am getting wlanSignalQuality as 0x00500000 instead of 0x50. Similarly for dot11PhyType 0x00060000 instead of 0x6. I have cross-checked these value by writing a Managed C++ application. In that application, it returns 0x50 and 0x6 properly.

     

    Is there anything wrong in the above code snippet?

     

    Or

     

    Do I need to provide Structure Layout as explicit and manually I should specify offset values?

     

    Any idea regarding the above issue is appreciated.

     

    Thanks

    Thursday, May 24, 2007 4:00 AM
  • Hi,

     

    I am trying to get current connection attributes using WlanQueryInterace function. This function returns output WLAN_CONNECTION_ATTRIBUTES as pData output argument.

     

    I am reading each data member of WLAN_CONNECTION_ATTRIBUTES using Marshal class. The structure of WLAN_CONNECTION_ATTRIBUTES is given below:

     

    [StructLayout(LayoutKind.Explicit)]

    public struct WLAN_CONNECTION_ATTRIBUTES

    {

       [FieldOffset(0)]public WLAN_INTERFACE_STATE isState;

       [FieldOffset(4)]public WLAN_CONNECTION_MODE wlanconnectionMode;

       [MarshalAs(UnManagedType.LPWStr,SizeConst=WLAN_MAX_NAME_LENGTH)]

       [FieldOffset(8)]public string strProfileName;

       [FieldOffset(520)]public WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;

       [FieldOffset(586)]public WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;

     

       public WLAN_CONNECTION_ATTRIBUTES(IntPtr pData)

       {

         isState = (WLAN_INTERFACE_STATE) Marshal.ReadInt32(pData,0);

         wlanconnectionMode = (WLAN_CONNECTION_MODE)Marshal.ReadInt32(pData,4);

     

         strProfileName = Marshal.PtrToStringUni(new IntPtr(pData.ToInt32() + 8),256).Replace("\0","");

     

         wlanAssociationAttributes = new WLAN_ASSOCIATION_ATTRIBUTES(new IntPtr(pData.ToInt32() + 520));

         wlanSecurityAttributes = new WLAN_SECURITY_ATTRIBUTES(new IntPtr(pData.ToInt32() + 586));

       }

    }

     

    [StructLayout(LayoutKind.Explicit)]

    public struct WLAN_ASSOCIATION_ATTRIBUTES

    {

      [FieldOffset(0)] public DOT11_SSID dot11SSID;

      [FieldOffset(36)]public DOT11_BSS_TYPE dot11BssType;

      [FieldOffset(40)]public DOT11_MAC_ADDRESS dot11MacAddress;

      [FieldOffset(46)]public DOT11_PHY_TYPE dot11phyType;

      [FieldOffset(50)]public UInt32  dot11PhyIndex;

      [FieldOffset(54)]public UInt32  wlanSignalQuality;

      [FieldOffset(58)]public UInt32  ulRxrate;

      [FieldOffset(62)]public UInt32  ulTxRate;

     

    public WLAN_ASSOCIATION_ATTRIBUTES(IntPtr pAssociationData)

    {
      //The below 3 data member values are correct.

    dot11SSID = new DOT11_SSID(new IntPtr(pAssociationData.ToInt32() + 0));

    dot11BssType = (DOT11_BSS_TYPE)Marshal.ReadInt32(pAssociationData,36);

    dot11Bssid = new DOT11_MAC_ADDRESS(new IntPtr(pAssociationData.ToInt32() + 40));

     

    //This statement is returning 0x00060000, 0x00000000, 0x00500000, 0x2af80000, 0x2af80000

    //But it should return 0x6,0x0,0x50,0x2af8,0x2af8

    //

    dot11PhyType = (DOT11_PHY_TYPE)Marshal.ReadInt32(pAssociationData,46);

    dot11PhyIndex = (UInt32) Marshal.ReadInt32(pAssociationData,50);

    wlanSignalQuality = (UInt32) Marshal.ReadInt32(pAssociationData,54);

    ulRxRate = (UInt32) Marshal.ReadInt32(pAssociationData,58);

    ulTxRate = (UInt32) Marshal.ReadInt32(pAssociationData,62);

    }

     

    }

     

    [StructLayout(LayoutKind.Explicit)]

    public struct WLAN_SECURITY_ATTRIBUTES

    {

     [FieldOffset(0)]public Int32 bsecurityenabled;

     [FieldOffset(4)]public Int32 bOneXenabled;

     [FieldOffset(8)]public DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;

     [FieldOffset(12)]public DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;

     

    public WLAN_SECURITY_ATTRIBUTES(IntPtr pSecurityAttributes)

    {

     

    }

     

    Here the problem is with WLAN_ASSOCIATION_ATTRIBUTES. This structure is padding 4 zeros with the following data members - dot11PhyType, dot11PhyIndex,wlanSignalQuality,ulRxRate,ulTxrate.

     

    This data member are of 32-bit size and it should return values in 4 bytes. I have specified offset position also. I don't know how to solve this issue.

     

    Any idea is welcome.

     

    Thanks in advance

     

     

    }

     

     

    Thursday, May 24, 2007 10:38 AM
  • public enum DOT11_BSS_TYPE

    {

    dot11_BSS_type_infrastructure = 1,

    dot11_BSS_type_independent = 2,

    dot11_BSS_type_any = 3

    }

     

    make sure your BSS Type is correct.

    Tuesday, June 05, 2007 2:52 PM
  • Yes, it is correct. I tried with the wlsample code that comes with the SDK Windows Vista and it works with the same parameters. Any idea?

    Tuesday, June 05, 2007 5:07 PM
  • If anyone search an managed API for the native wifi (Vista & XP SP2) should use this: http://www.codeplex.com/managedwifi

    It works great Smile

    Saturday, July 21, 2007 7:30 PM
  •  

    It may work for profiling and controlling a LAN but those are not my immediate interest. I am very much more interested in getting a managed WlanGetAvailableNetworkList or to get a BSSlist. The API works really well when operating in an unmanaged enviroment. The problem is in getting the data back to the managed side. I'd like to see it done in VB.
    Monday, August 27, 2007 3:08 AM
  • Hope I didn't confuse your discussion. Maybe my question is somewhat off-topic.

    I just want to ask a question on the WLAN_CONNECTION_IGNORE_PRIVACY_BIT.

    I am developing my WiFi easy config module on Vista. I found Vista SDK
    defines WLAN_CONNECTION_IGNORE_PRIVACY_BIT. In wlanapi.h, it is said that
    this flag is for easy config association.

    But when I use this flag in my code, it doesn't take effect: I create a
    temporary profile with OPEN Authentication and NONE encryption. Then use
    WlanConnect with this profile to connect to a WPAPSK-AP. WlanConnect returns
    SUCCESS, but I cannot capture any authentication request and association
    request sent out.

    Can anyone help on this issue? Is there any example on how to use this bit?

    Here is part of my code:

    pWriter->WriteStartDocument(XmlStandalone_Omit);

    pWriter->WriteStartElement(NULL,L"WLANProfile",NULL);

    pWriter->WriteAttributeString(L"p1",L"xmlns",NULL,L"http://www.microsoft.com/networking/WLAN/profile/v1");

    ReadWriteXML_Name(TRUE,xmlToWlan,L"name",pWriter);
    ReadWriteXML_SSID(TRUE,xmlToWlan,L"SSIDConfig",pWriter);

    pWriter->WriteStartElement(NULL,L"connectionType",NULL);
    pWriter->WriteString(L"ESS");

    pWriter->WriteFullEndElement();

    pWriter->WriteStartElement(NULL,L"connectionMode",NULL);
    pWriter->WriteString(L"auto");
    pWriter->WriteFullEndElement();

    pWriter->WriteStartElement(NULL,L"MSM",NULL);
    pWriter->WriteStartElement(NULL,L"security",NULL);

    pWriter->WriteStartElement(NULL,L"authEncryption",NULL);

    pWriter->WriteStartElement(NULL,L"authentication",NULL);
    pWriter->WriteString(L"open");
    pWriter->WriteFullEndElement();

    pWriter->WriteStartElement(NULL,L"encryption",NULL);
    pWriter->WriteString(L"none");
    pWriter->WriteFullEndElement();

    pWriter->WriteStartElement(NULL,L"useOneX",NULL);
    pWriter->WriteString(L"false");
    pWriter->WriteFullEndElement(); //useOneX

    pWriter->WriteFullEndElement(); //authEncryption

    pWriter->WriteFullEndElement(); // security
    pWriter->WriteFullEndElement(); // MSM
    pWriter->WriteFullEndElement(); // wlanProfile
    pWriter->WriteEndDocument();
    pWriter->Flush();

    // create a COM object to read the XML file
    hr = CoCreateInstance(
    CLSID_DOMDocument60,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument2,
    (void**)&pXmlDoc
    );
    if (hr != S_OK)
    {
    dwError = WIN32_FROM_HRESULT(hr);
    return dwError;
    }
    hr = pXmlDoc->load((CComVariant)TempStr, &vbSuccess);
    if (hr != S_OK || vbSuccess != VARIANT_TRUE)
    {
    dwError = ERROR_BAD_PROFILE;
    return dwError;
    }

    hr = pXmlDoc->get_xml(&bstrXml);
    if (hr != S_OK)
    {
    dwError = ERROR_BAD_PROFILE;
    return dwError;

    }

    ZeroMemory(&dot11Ssid,sizeof(DOT11_SSID));
    StringWToSsid(xmlToWlan->SSID,&dot11Ssid);
    wlanConnPara.wlanConnectionMode = wlan_connection_mode_temporary_profile;
    wlanConnPara.pDot11Ssid = &dot11Ssid;
    wlanConnPara.strProfile = bstrXml;
    wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure;
    wlanConnPara.pDesiredBssidList = NULL;
    wlanConnPara.dwFlags = WLAN_CONNECTION_IGNORE_PRIVACY_BIT;

    dwError = WlanConnect(
    wlandevice,
    &AdapterGUID,
    &wlanConnPara,
    NULL // reserved
    );


    Friday, August 31, 2007 9:33 AM
  • I'm wondering if anyone has ever successbully obtained channed information from a BSS_Entry? If so, I have several questions.

     

    1. What does the entity look like in Hex?

    2.) What is it's offset?

    3.) What is its size in bytes?  In some places on the net I see it referred to as in int32 and others I see it being referred as an Int64.

     

    I've see other references in here to actual returned structures in memory being different than what is in WlanApil,h. I'm definitely finding that to be the case in the bssentry. There seems to be undocumented padding to 4 byte boundaries.

     

    I also notice that nowhere in the Vista SDK Sample do they display Channel information. I am wondering if that was because it wasn't implemented? That would be very consistent with what I am seeing. 

     

     

     

    Tuesday, September 04, 2007 8:13 PM
  •  

    It's an unsigned long as advertized and it's at offest 90. BSSEntry appears to have undocumented padding explins some of the problems that developers are reporting here,
    Wednesday, September 05, 2007 4:54 PM
  • Hi chaps,

    Thanks for the code samples - helping a lot with a similar problem I'm having!

    Just one point - I think Tom's code which marshals the WLAN_INTERFACE_INFO_LIST needs tweaking.

    The description field is a 256-character (max) unicode string; thus 512 bytes, not 256. As written, it would've corrupted the state parameter, as well as any interface details beyond the first index.

    I've changed it to the code below, and it seems to work. Hope this helps!

    // Prepare the variable-length array of INTERFACE_INFO structs

    WLAN_INTERFACE_INFO[] wiiCollection = new WLAN_INTERFACE_INFO[dwNumberOfItems];

    for (int i = 0; i < dwNumberOfItems; i++)

    {

    WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO();

    // create a pointer to the wii data, based on offset from

    IntPtr pItemList = new IntPtr(interfaceList.ToInt32() + 8 + (i * 532)); // 8 is size of dwNumItems + dwIndex

    // read in the 128-bit guid

    byte[] intGuid = new byte[16];

    for (int j = 0; j < 16; j++)

    {

    intGuid[j] = Marshal.ReadByte(pItemList, j);

    }

    wii.interfaceGuid = new Guid(intGuid);

    // read in the 256-char (512 byte) description

    wii.interfaceDescription = Marshal.PtrToStringUni(new IntPtr(pItemList.ToInt32() + 16) // 16 is size of guid

    , 256).Replace("\0", "");

    // read in the 32-bit state enum

    wii.state = (WLAN_INTERFACE_STATE)Marshal.ReadInt32(pItemList, 512 + 16);

    wiiCollection[i] = wii;

    }

    Saturday, January 17, 2009 3:34 PM
  • Hi

    I got problem to implement same thing.
    Would you like please to share your full source code with us ?
    It would be great help for us

    thanks

    just impossible is impossible
    Tuesday, November 10, 2009 10:39 AM
  • Hi I am getting the same error while connecting with a XML profile schema.

    Can you please point me to where the error is coming from .

    Thanks in advance,

    Alok

    Monday, December 16, 2013 5:38 PM