Use Native WLAN API in managed code
-
Wednesday, December 20, 2006 3:40 PM
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);
All Replies
-
Wednesday, December 20, 2006 5:41 PMI 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. -
Friday, January 05, 2007 11:45 AM
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); -
Tuesday, January 09, 2007 6:19 PM
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?
-
Thursday, January 11, 2007 12:42 AM
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:41 PM
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 3:37 PMAfter 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 7:02 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++)
{
Network
= 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:12 PMUh, 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:20 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:44 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 10:53 PMAccording 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. -
Friday, January 12, 2007 11:54 AM
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.
-
Monday, January 22, 2007 8:28 PM
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 29, 2007 3:10 PMWas 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! -
Wednesday, March 14, 2007 10:43 AMIs there anyone that has written the wrapper for c# language?
-
Tuesday, March 27, 2007 8:09 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*1public 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++)
{
ucSSID
= (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_TYPE
;// 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
NetWork
= 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
} -
Monday, April 02, 2007 6:44 PMHi 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 -
Wednesday, April 04, 2007 3:01 PMHi , 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 ! -
Thursday, April 05, 2007 3:27 PMCode 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;
} -
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,
NelsonHi 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
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,
NelsonHi 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?
-
Tuesday, April 17, 2007 7:11 AMHi ,is there anyone successfully implement wlanconnect, which is a WiFi's function in wlanapi.dll, using C# or vb.netcould 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 StructurePublic 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 EnumPublic 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 = NothingdwError = 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)
NextDim 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 3:47 AMis there someone help me to deal it !Please
Thanks ! -
Friday, April 20, 2007 3:57 AMI 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 4:11 AMHi ,is there anyone successfully implement wlanconnect, which is a WiFi's function in wlanapi.dll, using C# or vb.netcould 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 StructurePublic 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 EnumPublic 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 = NothingdwError = 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)
NextDim 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 -
Saturday, April 21, 2007 12:18 PMThanks 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 AMThanks 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.
-
Tuesday, May 08, 2007 12:28 PM
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 2:26 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
-
Wednesday, May 16, 2007 2:34 PMHi, 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 -
Monday, May 21, 2007 1:32 AMHave 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.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);
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 4:06 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
-
Thursday, May 24, 2007 4:00 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 wlanSecurityAttributespublic 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 10:38 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
}
-
Tuesday, June 05, 2007 2:52 PMpublic 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 5:07 PMYes, 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?
-
Saturday, July 21, 2007 7:30 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

-
Monday, August 27, 2007 3:08 AM
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. -
Friday, August 31, 2007 9:33 AMHope 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
); -
Tuesday, September 04, 2007 8:13 PM
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.
-
Wednesday, September 05, 2007 4:54 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, -
Saturday, January 17, 2009 3:34 PMHi 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;
}
-
Tuesday, November 10, 2009 10:39 AMHiI got problem to implement same thing.Would you like please to share your full source code with us ?It would be great help for usthanks
just impossible is impossible


