├── .gitignore ├── .gitmodules ├── README.md ├── AssemblyInfo.cs ├── InterfaceNotificationEventsArgs.cs ├── SudoInterface.cs ├── ManagedWifi.csproj ├── WlanClient.cs ├── IEParser.cs ├── WlanInterface.cs └── Wlan.cs /.gitignore: -------------------------------------------------------------------------------- 1 | *.vs10x 2 | *.user 3 | bin 4 | obj 5 | 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools"] 2 | path = tools 3 | url = git@codebasehq.com:metageek/nutbrown/toolsdir.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ManagedWifi 2 | =========== 3 | 4 | Copyright 2009-2013 MetaGeek, LLC 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | -------------------------------------------------------------------------------- /AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.Reflection.AssemblyVersion("2012.1.31.1372")] 2 | [assembly: System.Reflection.AssemblyConfiguration("")] 3 | [assembly: System.Runtime.CompilerServices.CompilationRelaxations(8)] 4 | [assembly: System.Reflection.AssemblyTitle("Managed Wifi API")] 5 | [assembly: System.Reflection.AssemblyDescription(".NET managed wrapper for Windows Native Wifi API.")] 6 | [assembly: System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows = true)] 7 | [assembly: System.Reflection.AssemblyCompany("Monfort Software Engineering")] 8 | [assembly: System.Reflection.AssemblyProduct("Managed Wifi API")] 9 | [assembly: System.Reflection.AssemblyCopyright("Copyright © Monfort Software Engineering 2007")] 10 | [assembly: System.Reflection.AssemblyTrademark("")] 11 | [assembly: System.Runtime.InteropServices.ComVisible(false)] 12 | [assembly: System.Runtime.InteropServices.Guid("e7646a9f-2d07-455a-b9ae-51eaf7281d2f")] 13 | [assembly: System.Reflection.AssemblyFileVersion("1.1.1.1372")] 14 | [assembly: System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] 15 | -------------------------------------------------------------------------------- /InterfaceNotificationEventsArgs.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (c) 2007-2010 MetaGeek, LLC 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | //////////////////////////////////////////////////////////////// 18 | namespace ManagedWifi 19 | { 20 | using System; 21 | 22 | public class InterfaceNotificationEventsArgs : EventArgs 23 | { 24 | #region Fields 25 | 26 | public Guid ItsGuid; 27 | 28 | #endregion Fields 29 | 30 | #region Constructors 31 | 32 | public InterfaceNotificationEventsArgs(Guid id) 33 | { 34 | ItsGuid = id; 35 | } 36 | 37 | #endregion Constructors 38 | } 39 | } -------------------------------------------------------------------------------- /SudoInterface.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.NetworkInformation; 3 | 4 | namespace ManagedWifi 5 | { 6 | class SudoInterface : NetworkInterface 7 | { 8 | #region Fields 9 | 10 | private readonly string _desc; 11 | private readonly string _id; 12 | private readonly string _name; 13 | 14 | #endregion Fields 15 | 16 | #region Properties 17 | 18 | public override string Description 19 | { 20 | get { return _desc; } 21 | } 22 | 23 | public override string Id 24 | { 25 | get { return _id; } 26 | } 27 | 28 | public override bool IsReceiveOnly 29 | { 30 | get { return false; } 31 | } 32 | 33 | public override string Name 34 | { 35 | get { return _name; } 36 | } 37 | 38 | public override NetworkInterfaceType NetworkInterfaceType 39 | { 40 | get { return NetworkInterfaceType.Wireless80211; } 41 | } 42 | 43 | public override OperationalStatus OperationalStatus 44 | { 45 | get { return OperationalStatus.Up; } 46 | } 47 | 48 | public override long Speed 49 | { 50 | get { return 0; } 51 | } 52 | 53 | public override bool SupportsMulticast 54 | { 55 | get { return false; } 56 | } 57 | 58 | #endregion Properties 59 | 60 | #region Constructors 61 | 62 | public SudoInterface(WlanInterface wlan) 63 | { 64 | _id = wlan.InterfaceGuid.ToString(); 65 | _desc = wlan.InterfaceDescription; 66 | } 67 | 68 | public SudoInterface(string id, string description, string name) 69 | { 70 | _id = id; 71 | _name = name; 72 | _desc = description; 73 | } 74 | 75 | #endregion Constructors 76 | 77 | #region Public Methods 78 | 79 | public override IPInterfaceProperties GetIPProperties() 80 | { 81 | return null; 82 | } 83 | 84 | public override IPv4InterfaceStatistics GetIPv4Statistics() 85 | { 86 | throw new NotImplementedException(); 87 | } 88 | 89 | public override PhysicalAddress GetPhysicalAddress() 90 | { 91 | return PhysicalAddress.None; 92 | } 93 | 94 | public override bool Supports(NetworkInterfaceComponent networkInterfaceComponent) 95 | { 96 | return true; 97 | } 98 | 99 | #endregion Public Methods 100 | } 101 | } -------------------------------------------------------------------------------- /ManagedWifi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | bin\x86\Debug\ 6 | DEBUG;TRACE 7 | true 8 | full 9 | x86 10 | true 11 | GlobalSuppressions.cs 12 | prompt 13 | 14 | 15 | bin\x86\Release\ 16 | TRACE 17 | true 18 | true 19 | x86 20 | true 21 | GlobalSuppressions.cs 22 | prompt 23 | 24 | 25 | local 26 | 7.10.3077 27 | 2.0 28 | {B290695E-0DD1-4912-88DE-7AA6DC7AF0A5} 29 | Debug 30 | AnyCPU 31 | ManagedWifi 32 | JScript 33 | Grid 34 | IE50 35 | false 36 | Library 37 | 38 | 39 | 3.5 40 | 41 | 42 | false 43 | v3.5 44 | 45 | 46 | publish\ 47 | true 48 | Disk 49 | false 50 | Foreground 51 | 7 52 | Days 53 | false 54 | false 55 | true 56 | 0 57 | 1.0.0.%2a 58 | false 59 | true 60 | 61 | 62 | 63 | ..\lib\MetaGeek.Diagnostics.dll 64 | 65 | 66 | System 67 | 68 | 69 | 3.5 70 | 71 | 72 | 73 | 74 | Code 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | False 86 | .NET Framework 3.5 SP1 Client Profile 87 | false 88 | 89 | 90 | False 91 | .NET Framework 2.0 %28x86%29 92 | true 93 | 94 | 95 | False 96 | .NET Framework 3.0 %28x86%29 97 | false 98 | 99 | 100 | False 101 | .NET Framework 3.5 102 | false 103 | 104 | 105 | False 106 | .NET Framework 3.5 SP1 107 | false 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /WlanClient.cs: -------------------------------------------------------------------------------- 1 | #region Header 2 | 3 | // 4 | // Copyright (c) 2007-2010 MetaGeek, LLC 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | // 18 | 19 | #endregion Header 20 | 21 | using System; 22 | using System.Collections.Generic; 23 | using System.ComponentModel; 24 | using System.Runtime.InteropServices; 25 | using System.Text; 26 | using MetaGeek.Diagnostics; 27 | using MetaGeek.Diagnostics.Event; 28 | 29 | namespace ManagedWifi 30 | { 31 | public class WlanClient 32 | { 33 | #region Fields 34 | 35 | private readonly IntPtr _clientHandle; 36 | private readonly Dictionary _ifaces = new Dictionary(); 37 | private uint _negotiatedVersion; 38 | 39 | #endregion Fields 40 | 41 | #region Properties 42 | 43 | public WlanInterface[] Interfaces 44 | { 45 | get 46 | { 47 | IntPtr ptr; 48 | WlanInterface[] interfaceArray2; 49 | Wlan.ThrowIfError(Wlan.WlanEnumInterfaces(_clientHandle, IntPtr.Zero, out ptr)); 50 | try 51 | { 52 | Wlan.WlanInterfaceInfoListHeader structure = (Wlan.WlanInterfaceInfoListHeader)Marshal.PtrToStructure(ptr, typeof(Wlan.WlanInterfaceInfoListHeader)); 53 | long num = ptr.ToInt64() + Marshal.SizeOf(structure); 54 | WlanInterface[] interfaceArray = new WlanInterface[structure.numberOfItems]; 55 | List list = new List(); 56 | for (int i = 0; i < structure.numberOfItems; i++) 57 | { 58 | Wlan.WlanInterfaceInfo info = (Wlan.WlanInterfaceInfo)Marshal.PtrToStructure(new IntPtr(num), typeof(Wlan.WlanInterfaceInfo)); 59 | num += Marshal.SizeOf(info); 60 | list.Add(info.interfaceGuid); 61 | WlanInterface interface2 = _ifaces.ContainsKey(info.interfaceGuid) ? _ifaces[info.interfaceGuid] : new WlanInterface(this, info); 62 | interfaceArray[i] = interface2; 63 | _ifaces[info.interfaceGuid] = interface2; 64 | } 65 | Queue queue = new Queue(); 66 | foreach (Guid guid in _ifaces.Keys) 67 | { 68 | if (!list.Contains(guid)) 69 | { 70 | queue.Enqueue(guid); 71 | } 72 | } 73 | while (queue.Count != 0) 74 | { 75 | Guid key = queue.Dequeue(); 76 | _ifaces.Remove(key); 77 | } 78 | interfaceArray2 = interfaceArray; 79 | } 80 | finally 81 | { 82 | Wlan.WlanFreeMemory(ptr); 83 | } 84 | return interfaceArray2; 85 | } 86 | } 87 | 88 | public IntPtr ItsClientHandle 89 | { 90 | get { return _clientHandle; } 91 | } 92 | 93 | private Logger ItsLogger 94 | { 95 | get; 96 | set; 97 | } 98 | 99 | private Wlan.WlanNotificationCallbackDelegate WlanNotificationCallback 100 | { 101 | get; 102 | set; 103 | } 104 | 105 | #endregion Properties 106 | 107 | #region Event Fields 108 | 109 | public RegisteredEventHandler InterfaceArrivedEvent = new RegisteredEventHandler(); 110 | public RegisteredEventHandler InterfaceRemovedEvent = new RegisteredEventHandler(); 111 | 112 | #endregion Event Fields 113 | 114 | #region Constructors 115 | 116 | public WlanClient() 117 | { 118 | ItsLogger = new Logger(this); 119 | 120 | try 121 | { 122 | Wlan.ThrowIfError(Wlan.WlanOpenHandle(1, IntPtr.Zero, out _negotiatedVersion, out _clientHandle)); 123 | WlanNotificationCallback = new Wlan.WlanNotificationCallbackDelegate(OnWlanNotification); 124 | 125 | Wlan.WlanNotificationSource source; 126 | Wlan.ThrowIfError(Wlan.WlanRegisterNotification(_clientHandle, Wlan.WlanNotificationSource.All, false, WlanNotificationCallback, IntPtr.Zero, IntPtr.Zero, out source)); 127 | } 128 | catch (Win32Exception ex) 129 | { 130 | Wlan.WlanCloseHandle(_clientHandle, IntPtr.Zero); 131 | ItsLogger.Warn(ex.Message); 132 | throw; 133 | } 134 | } 135 | 136 | ~WlanClient() 137 | { 138 | Wlan.WlanCloseHandle(_clientHandle, IntPtr.Zero); 139 | } 140 | 141 | #endregion Constructors 142 | 143 | #region Public Methods 144 | 145 | public string GetStringForReasonCode(Wlan.WlanReasonCode reasonCode) 146 | { 147 | StringBuilder stringBuffer = new StringBuilder(0x400); 148 | Wlan.ThrowIfError(Wlan.WlanReasonCodeToString(reasonCode, stringBuffer.Capacity, stringBuffer, IntPtr.Zero)); 149 | return stringBuffer.ToString(); 150 | } 151 | 152 | #endregion Public Methods 153 | 154 | #region Private Methods 155 | 156 | private void OnWlanNotification(ref Wlan.WlanNotificationData notifyData, IntPtr context) 157 | { 158 | WlanInterface interface2 = _ifaces.ContainsKey(notifyData.interfaceGuid) ? _ifaces[notifyData.interfaceGuid] : null; 159 | switch (notifyData.notificationSource) 160 | { 161 | case Wlan.WlanNotificationSource.Acm: 162 | switch (notifyData.notificationCode) 163 | { 164 | case 8: 165 | if (notifyData.dataSize >= Marshal.SizeOf(0)) 166 | { 167 | Wlan.WlanReasonCode reasonCode = (Wlan.WlanReasonCode)Marshal.ReadInt32(notifyData.dataPtr); 168 | if (interface2 != null) 169 | { 170 | interface2.OnWlanReason(notifyData, reasonCode); 171 | } 172 | } 173 | goto Label_0194; 174 | 175 | case 9: 176 | case 10: 177 | case 11: 178 | case 20: 179 | case 0x15: 180 | { 181 | Wlan.WlanConnectionNotificationData? nullable = ParseWlanConnectionNotification(ref notifyData); 182 | if (nullable.HasValue && (interface2 != null)) 183 | { 184 | interface2.OnWlanConnection(notifyData, nullable.Value); 185 | } 186 | goto Label_0194; 187 | } 188 | case 12: 189 | case 15: 190 | case 0x10: 191 | case 0x11: 192 | case 0x12: 193 | case 0x13: 194 | goto Label_0194; 195 | 196 | case 13: 197 | InterfaceArrivedEvent.Raise(this, new InterfaceNotificationEventsArgs(notifyData.interfaceGuid)); 198 | goto Label_0194; 199 | 200 | case 14: 201 | InterfaceRemovedEvent.Raise(this, new InterfaceNotificationEventsArgs(notifyData.interfaceGuid)); 202 | goto Label_0194; 203 | } 204 | break; 205 | 206 | case Wlan.WlanNotificationSource.Msm: 207 | switch (notifyData.notificationCode) 208 | { 209 | case 1: 210 | case 2: 211 | case 3: 212 | case 4: 213 | case 5: 214 | case 6: 215 | case 9: 216 | case 10: 217 | case 11: 218 | case 12: 219 | case 13: 220 | { 221 | Wlan.WlanConnectionNotificationData? nullable2 = ParseWlanConnectionNotification(ref notifyData); 222 | if (nullable2.HasValue && (interface2 != null)) 223 | { 224 | interface2.OnWlanConnection(notifyData, nullable2.Value); 225 | } 226 | goto Label_0194; 227 | } 228 | case 7: 229 | case 8: 230 | goto Label_0194; 231 | } 232 | goto Label_0194; 233 | } 234 | Label_0194: 235 | if (interface2 != null) 236 | { 237 | interface2.OnWlanNotification(notifyData); 238 | } 239 | } 240 | 241 | private Wlan.WlanConnectionNotificationData? ParseWlanConnectionNotification(ref Wlan.WlanNotificationData notifyData) 242 | { 243 | int num = Marshal.SizeOf(typeof(Wlan.WlanConnectionNotificationData)); 244 | if (notifyData.dataSize < num) 245 | { 246 | return null; 247 | } 248 | Wlan.WlanConnectionNotificationData data = (Wlan.WlanConnectionNotificationData)Marshal.PtrToStructure(notifyData.dataPtr, typeof(Wlan.WlanConnectionNotificationData)); 249 | if (data.wlanReasonCode == Wlan.WlanReasonCode.Success) 250 | { 251 | IntPtr ptr = new IntPtr(notifyData.dataPtr.ToInt64() + Marshal.OffsetOf(typeof(Wlan.WlanConnectionNotificationData), "profileXml").ToInt64()); 252 | data.profileXml = Marshal.PtrToStringUni(ptr); 253 | } 254 | return data; 255 | } 256 | 257 | #endregion Private Methods 258 | } 259 | } -------------------------------------------------------------------------------- /IEParser.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////// 2 | 3 | #region Header 4 | 5 | // 6 | // Copyright (c) 2007-2010 MetaGeek, LLC 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | 21 | #endregion Header 22 | 23 | //////////////////////////////////////////////////////////////// 24 | using System; 25 | using System.Collections; 26 | using System.Collections.Generic; 27 | using System.Globalization; 28 | using System.IO; 29 | 30 | namespace ManagedWifi 31 | { 32 | public static class IeParser 33 | { 34 | 35 | public struct InformationElement 36 | { 37 | public ushort ItsNumber { get; set; } 38 | public ushort ItsLength { get; set; } 39 | public byte[] ItsData { get; set; } 40 | } 41 | 42 | #region Public Methods 43 | 44 | public static TypeNSettings Parse(byte[] ies) 45 | { 46 | 47 | var informationElements = BuildInformationElements(ies); 48 | var settings = new TypeNSettings(); 49 | bool returnNull = true; 50 | 51 | foreach (var informationElement in informationElements) 52 | { 53 | switch (informationElement.ItsNumber) 54 | { 55 | case 45: //HT Capabilities 56 | ParseHTCapabilities(informationElement, settings); 57 | returnNull = false; 58 | break; 59 | case 61: //HT Information 60 | ParseHTOperation(informationElement, settings); 61 | returnNull = false; 62 | break; 63 | } 64 | } 65 | 66 | return returnNull ? null : settings; 67 | } 68 | 69 | public static TypeACSettings ParseAC(byte[] ies) 70 | { 71 | 72 | var informationElements = BuildInformationElements(ies); 73 | var settings = new TypeACSettings(); 74 | bool returnNull = true; 75 | 76 | foreach (var informationElement in informationElements) 77 | { 78 | switch (informationElement.ItsNumber) 79 | { 80 | case 45: //HT Capabilities 81 | ParseHTCapabilities(informationElement, settings); 82 | returnNull = false; 83 | break; 84 | case 61: //HT Information 85 | ParseHTOperation(informationElement, settings); 86 | returnNull = false; 87 | break; 88 | case 191: //VHT Capabilities 89 | ParseVHTCapabilities(informationElement, settings); 90 | break; 91 | case 192: //VHT Operation 92 | ParseVHTOperation(informationElement, settings); 93 | break; 94 | } 95 | } 96 | 97 | return returnNull ? null : settings; 98 | } 99 | 100 | 101 | 102 | private static void ParseVHTOperation(InformationElement ie, TypeACSettings settings) 103 | { 104 | settings.Operations = new TypeACSettings.VHTOperations(); 105 | 106 | var operations = new byte[4]; 107 | Array.Copy(ie.ItsData, 0, operations, 0, 3); 108 | 109 | var basicMCSSet = new byte[8]; 110 | Array.Copy(ie.ItsData, 3, basicMCSSet, 0, 2); 111 | 112 | settings.Operations.ChannelWidth = 113 | (TypeACSettings.VHTOperations.VHTChannelWidth) Enum.Parse( 114 | typeof(TypeACSettings.VHTOperations.VHTChannelWidth), 115 | operations[0].ToString(CultureInfo.InvariantCulture) 116 | ); 117 | } 118 | 119 | private static void ParseVHTCapabilities(InformationElement ie, TypeACSettings settings) 120 | { 121 | settings.Capabilities = new TypeACSettings.VHTCapabilities(); 122 | 123 | var capabilities = new byte[4]; 124 | Array.Copy(ie.ItsData, 0, capabilities, 0, 4); 125 | 126 | var supportedMCS = new byte[8]; 127 | Array.Copy(ie.ItsData, 4, supportedMCS, 0, 8); 128 | 129 | var supportedChannelWidth = ( capabilities[0] & 0x0C ) >> 2; 130 | 131 | switch (supportedChannelWidth) 132 | { 133 | case 1: 134 | settings.Capabilities.Supports160Mhz = true; 135 | break; 136 | case 2: 137 | settings.Capabilities.Supports80Plus80Mhz = true; 138 | settings.Capabilities.Supports160Mhz = true; 139 | break; 140 | } 141 | 142 | settings.Capabilities. ShortGi160MHz = (capabilities[0] & 0x40) == 0x40; 143 | settings.Capabilities.ShortGi80MHz = (capabilities[0] & 0x20) == 0x20; 144 | 145 | settings.Capabilities.MaxRecieveRate = BitConverter.ToUInt16(supportedMCS, 2); 146 | settings.Capabilities.MaxTransmitRate = BitConverter.ToUInt16(supportedMCS, 6); 147 | } 148 | 149 | private static void ParseHTOperation(InformationElement ie, TypeNSettings settings) 150 | { 151 | const int channel = 0; 152 | const int subset1 = 1; 153 | 154 | //Primary channel 155 | settings.PrimaryChannel = ie.ItsData[0]; 156 | 157 | //Secondary channel location 158 | settings.SecondaryChannelLower = (ie.ItsData[channel] & 0x03) == 0x03; 159 | 160 | //Check if there is no secondary channel and set 40MHz to false 161 | if (settings.Is40Mhz) 162 | settings.Is40Mhz = (ie.ItsData[subset1] & 0x03) == 0x03 || (ie.ItsData[subset1] & 0x01) == 0x01; 163 | } 164 | 165 | private static void ParseHTCapabilities(InformationElement ie, TypeNSettings settings) 166 | { 167 | settings.Is40Mhz = ((ie.ItsData[0] & 0x02) == 0x02); 168 | 169 | settings.ShortGi20MHz = (ie.ItsData[0] & 0x20) == 0x20; 170 | settings.ShortGi40MHz = (ie.ItsData[0] & 0x40) == 0x40; 171 | 172 | //Get supported MCS indexes 173 | //1 bit per index 174 | 175 | byte[] bits = new byte[4]; 176 | //Array.ConstrainedCopy(ies, index + 5, bits, 0, 4); 177 | Array.Copy(ie.ItsData, 4, bits, 0, 4); 178 | 179 | BitArray b = new BitArray(bits); 180 | //settings.Rates = new List(); 181 | 182 | //The MCS indexes are in little endian, 183 | //so this loop will start at the lowest rates 184 | for (int i = 0; i < b.Length; i++) 185 | { 186 | //If the MCS index bit is 0, skip it 187 | if (b[i] == false) continue; 188 | 189 | //Add the rate 190 | settings.Rates.Add(McsSet.GetSpeed((uint) i, settings.ShortGi20MHz, settings.ShortGi40MHz, 191 | settings.Is40Mhz)); 192 | } 193 | } 194 | 195 | private static IEnumerable BuildInformationElements(byte[] ies) 196 | { 197 | var informationElements = new List(); 198 | 199 | var index = 0; 200 | 201 | while (index < ies.Length) 202 | { 203 | var ie = new InformationElement(); 204 | ie.ItsNumber = ies[index]; 205 | ie.ItsLength = ies[index + 1]; 206 | ie.ItsData = new byte[ie.ItsLength]; 207 | Array.Copy(ies, index + 2, ie.ItsData, 0, ie.ItsLength); 208 | 209 | informationElements.Add(ie); 210 | index += ie.ItsLength + 2; 211 | } 212 | return informationElements; 213 | } 214 | 215 | 216 | public class TypeNSettings 217 | { 218 | public bool Is40Mhz; 219 | public bool ShortGi20MHz; 220 | public bool ShortGi40MHz; 221 | public uint PrimaryChannel; 222 | public bool SecondaryChannelLower; 223 | 224 | //public uint MaxMcs; 225 | public List Rates; 226 | 227 | //public static TypeNSettings Empty = new TypeNSettings() { Rates = new List() }; 228 | public TypeNSettings() 229 | { 230 | Rates = new List(); 231 | } 232 | 233 | public TypeNSettings(TypeNSettings settings) 234 | { 235 | Is40Mhz = settings.Is40Mhz; 236 | ShortGi20MHz = settings.ShortGi20MHz; 237 | ShortGi40MHz = settings.ShortGi40MHz; 238 | PrimaryChannel = settings.PrimaryChannel; 239 | SecondaryChannelLower = settings.SecondaryChannelLower; 240 | //MaxMcs = settings.MaxMcs; 241 | Rates = settings.Rates; 242 | } 243 | 244 | public override bool Equals(object obj) 245 | { 246 | if (obj is TypeNSettings) 247 | { 248 | TypeNSettings set = (TypeNSettings)obj; 249 | bool yes = set.Is40Mhz == Is40Mhz; 250 | yes &= set.ShortGi20MHz == ShortGi20MHz; 251 | yes &= set.ShortGi40MHz == ShortGi40MHz; 252 | yes &= set.PrimaryChannel == PrimaryChannel; 253 | yes &= set.SecondaryChannelLower == SecondaryChannelLower; 254 | //Don't compare rates 255 | 256 | return yes; 257 | } 258 | return false; 259 | } 260 | } 261 | 262 | public class TypeACSettings : TypeNSettings 263 | { 264 | public class VHTCapabilities 265 | { 266 | public bool ShortGi80MHz; 267 | public bool ShortGi160MHz; 268 | public bool Supports160Mhz; 269 | public bool Supports80Plus80Mhz; 270 | public ushort MaxRecieveRate; 271 | public ushort MaxTransmitRate; 272 | } 273 | 274 | public class VHTOperations 275 | { 276 | public enum VHTChannelWidth : byte 277 | { 278 | TwentyOrForty = 0x00, 279 | Eighty = 0x01, 280 | OneSixty = 0x02, 281 | EightyPlusEighty = 0x03 282 | } 283 | 284 | public VHTChannelWidth ChannelWidth; 285 | } 286 | 287 | public VHTCapabilities Capabilities { get; set; } 288 | public VHTOperations Operations { get; set; } 289 | } 290 | 291 | 292 | #endregion Public Methods 293 | 294 | #region Private Methods 295 | 296 | private class McsSet 297 | { 298 | //20MHz long GI 299 | private static readonly Dictionary LGiTable20 = new Dictionary 300 | { 301 | {0, 6f},//6.5 302 | {1, 13f}, 303 | {2, 19f}, //19.5 304 | {3, 26f}, 305 | {4, 39f}, 306 | {5, 52f}, 307 | {6, 58f}, 308 | {7, 65f} 309 | }; 310 | 311 | //20MHz short GI 312 | private static readonly Dictionary SGiTable20 = new Dictionary 313 | { 314 | {0, 7f}, //7.2 315 | {1, 14f},//14.4 316 | {2, 22f},//21.7 317 | {3, 29f},//28.9 318 | {4, 43f},//43.3 319 | {5, 58f},//57.8 320 | {6, 65f}, 321 | {7, 72f} //72.2 322 | }; 323 | 324 | //40MHz long GI 325 | private static readonly Dictionary LGiTable40 = new Dictionary 326 | { 327 | {0, 13f}, //13.5 328 | {1, 27f}, 329 | {2, 40f},//40.5 330 | {3, 54f}, 331 | {4, 81f}, 332 | {5, 108f}, 333 | {6, 121f}, 334 | {7, 135f} 335 | }; 336 | 337 | //40MHz short GI 338 | private static readonly Dictionary SGiTable40 = new Dictionary 339 | { 340 | {0, 15f}, 341 | {1, 30f}, 342 | {2, 45f}, 343 | {3, 60f}, 344 | {4, 90f}, 345 | {5, 120f}, 346 | {6, 135f}, 347 | {7, 150f} 348 | }; 349 | 350 | public static float GetSpeed(uint index, bool shortGi20MHz, bool shortGi40MHz, bool fortyMHz) 351 | { 352 | float output; 353 | 354 | if (index > 32) return 0f; 355 | int streams = 0; 356 | 357 | if (index >= 0 && index < 8) 358 | { 359 | streams = 1; 360 | } 361 | else if (index >= 8 && index < 16) 362 | { 363 | streams = 2; 364 | index -= 8; 365 | } 366 | else if (index >= 16 && index < 24) 367 | { 368 | streams = 3; 369 | index -= 16; 370 | } 371 | else if (index >= 24 && index < 32) 372 | { 373 | streams = 4; 374 | index -= 24; 375 | } 376 | 377 | if (fortyMHz) 378 | { 379 | if (shortGi40MHz) 380 | { 381 | output = SGiTable40[index]; 382 | output *= streams; 383 | } 384 | else 385 | { 386 | output = LGiTable40[index]; 387 | output *= streams; 388 | } 389 | } 390 | else //20 MHz channel 391 | { 392 | if (shortGi20MHz) 393 | { 394 | output = SGiTable20[index]; 395 | output *= streams; 396 | } 397 | else 398 | { 399 | output = LGiTable20[index]; 400 | output *= streams; 401 | } 402 | } 403 | 404 | return output; 405 | } 406 | } 407 | 408 | #endregion Private Methods 409 | } 410 | 411 | 412 | } -------------------------------------------------------------------------------- /WlanInterface.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.NetworkInformation; 4 | using System.Runtime.InteropServices; 5 | using System.Threading; 6 | 7 | namespace ManagedWifi 8 | { 9 | public class WlanInterface 10 | { 11 | #region Fields 12 | 13 | private readonly WlanClient _client; 14 | private readonly Queue _eventQueue = new Queue(); 15 | private readonly AutoResetEvent _eventQueueFilled = new AutoResetEvent(false); 16 | private Wlan.WlanInterfaceInfo _info; 17 | 18 | #endregion Fields 19 | 20 | #region Properties 21 | 22 | public bool Autoconf 23 | { 24 | get 25 | { 26 | return (GetInterfaceInt(Wlan.WlanIntfOpcode.AutoconfEnabled) != 0); 27 | } 28 | set 29 | { 30 | SetInterfaceInt(Wlan.WlanIntfOpcode.AutoconfEnabled, value ? 1 : 0); 31 | } 32 | } 33 | 34 | public Wlan.Dot11BssType BssType 35 | { 36 | get 37 | { 38 | return (Wlan.Dot11BssType)GetInterfaceInt(Wlan.WlanIntfOpcode.BssType); 39 | } 40 | set 41 | { 42 | SetInterfaceInt(Wlan.WlanIntfOpcode.BssType, (int)value); 43 | } 44 | } 45 | 46 | public int Channel 47 | { 48 | get 49 | { 50 | return GetInterfaceInt(Wlan.WlanIntfOpcode.ChannelNumber); 51 | } 52 | } 53 | 54 | public Wlan.WlanConnectionAttributes CurrentConnection 55 | { 56 | get 57 | { 58 | int num; 59 | IntPtr ptr; 60 | Wlan.WlanOpcodeValueType type; 61 | Wlan.WlanConnectionAttributes attributes = new Wlan.WlanConnectionAttributes(); 62 | int code = Wlan.WlanQueryInterface(_client.ItsClientHandle, _info.interfaceGuid, 63 | Wlan.WlanIntfOpcode.CurrentConnection, IntPtr.Zero, out num, 64 | out ptr, out type); 65 | // 0x0000139F is the code returned when not connected 66 | if (code != 0x0000139F) 67 | { 68 | Wlan.ThrowIfError(code); 69 | try 70 | { 71 | attributes = 72 | (Wlan.WlanConnectionAttributes) 73 | Marshal.PtrToStructure(ptr, typeof(Wlan.WlanConnectionAttributes)); 74 | } 75 | finally 76 | { 77 | Wlan.WlanFreeMemory(ptr); 78 | } 79 | } 80 | return attributes; 81 | } 82 | } 83 | 84 | public Wlan.Dot11OperationMode CurrentOperationMode 85 | { 86 | get 87 | { 88 | return (Wlan.Dot11OperationMode)GetInterfaceInt(Wlan.WlanIntfOpcode.CurrentOperationMode); 89 | } 90 | } 91 | 92 | public string InterfaceDescription 93 | { 94 | get 95 | { 96 | return _info.interfaceDescription; 97 | } 98 | } 99 | 100 | public Guid InterfaceGuid 101 | { 102 | get 103 | { 104 | return _info.interfaceGuid; 105 | } 106 | } 107 | 108 | //public string InterfaceName 109 | //{ 110 | // get 111 | // { 112 | // return NetworkInterface.Name; 113 | // } 114 | //} 115 | public Wlan.WlanInterfaceState InterfaceState 116 | { 117 | get 118 | { 119 | return (Wlan.WlanInterfaceState)GetInterfaceInt(Wlan.WlanIntfOpcode.InterfaceState); 120 | } 121 | } 122 | 123 | public NetworkInterface NetworkInterface 124 | { 125 | get 126 | { 127 | var nd = NetworkInterface.GetAllNetworkInterfaces(); 128 | foreach (NetworkInterface interface2 in nd) 129 | { 130 | if (interface2.NetworkInterfaceType != NetworkInterfaceType.Loopback) 131 | { 132 | Guid guid = new Guid(interface2.Id); 133 | if (guid.Equals(_info.interfaceGuid)) 134 | { 135 | return interface2; 136 | } 137 | } 138 | } 139 | //We haven't found one yet, create one. 140 | return new SudoInterface(this); 141 | 142 | //return null; 143 | } 144 | } 145 | 146 | public int Rssi 147 | { 148 | get 149 | { 150 | return GetInterfaceInt(Wlan.WlanIntfOpcode.Rssi); 151 | } 152 | } 153 | 154 | #endregion Properties 155 | 156 | #region Event Related 157 | 158 | #region Event Fields 159 | 160 | private bool _queueEvents; 161 | 162 | #endregion Event Fields 163 | 164 | #region Events 165 | 166 | public event WlanConnectionNotificationEventHandler WlanConnectionNotification; 167 | 168 | public event WlanNotificationEventHandler WlanNotification; 169 | 170 | public event WlanReasonNotificationEventHandler WlanReasonNotification; 171 | 172 | #endregion Events 173 | 174 | #endregion Event Related 175 | 176 | #region Delegates 177 | 178 | public delegate void WlanConnectionNotificationEventHandler(Wlan.WlanNotificationData notifyData, Wlan.WlanConnectionNotificationData connNotifyData); 179 | 180 | public delegate void WlanNotificationEventHandler(Wlan.WlanNotificationData notifyData); 181 | 182 | public delegate void WlanReasonNotificationEventHandler(Wlan.WlanNotificationData notifyData, Wlan.WlanReasonCode reasonCode); 183 | 184 | #endregion Delegates 185 | 186 | #region Constructors 187 | 188 | public WlanInterface(WlanClient client, Wlan.WlanInterfaceInfo info) 189 | { 190 | _client = client; 191 | _info = info; 192 | } 193 | 194 | #endregion Constructors 195 | 196 | #region Public Methods 197 | 198 | public void Connect(Wlan.WlanConnectionMode connectionMode, Wlan.Dot11BssType bssType, Wlan.Dot11Ssid ssid, Wlan.WlanConnectionFlags flags) 199 | { 200 | Wlan.WlanConnectionParameters parameters2 = new Wlan.WlanConnectionParameters 201 | { 202 | wlanConnectionMode = connectionMode, 203 | dot11SsidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ssid)), 204 | dot11BssType = bssType, 205 | flags = flags 206 | }; 207 | Wlan.WlanConnectionParameters connectionParams = parameters2; 208 | this.Connect(connectionParams); 209 | Marshal.StructureToPtr(ssid, connectionParams.dot11SsidPtr, false); 210 | Marshal.DestroyStructure(connectionParams.dot11SsidPtr, ssid.GetType()); 211 | Marshal.FreeHGlobal(connectionParams.dot11SsidPtr); 212 | } 213 | 214 | public bool ConnectSynchronously(Wlan.WlanConnectionMode connectionMode, Wlan.Dot11BssType bssType, string profile, int connectTimeout) 215 | { 216 | _queueEvents = true; 217 | try 218 | { 219 | Connect(connectionMode, bssType, profile); 220 | while (_queueEvents && _eventQueueFilled.WaitOne(connectTimeout, true)) 221 | { 222 | lock (_eventQueue) 223 | { 224 | while (_eventQueue.Count != 0) 225 | { 226 | object obj2 = _eventQueue.Dequeue(); 227 | if (obj2 is WlanConnectionNotificationEventData) 228 | { 229 | WlanConnectionNotificationEventData data = (WlanConnectionNotificationEventData)obj2; 230 | if (((data.NotifyData.notificationSource != Wlan.WlanNotificationSource.Acm) || (data.NotifyData.notificationCode != 10)) || data.ConnNotifyData.profileName != profile) 231 | { 232 | break; 233 | } 234 | return true; 235 | } 236 | } 237 | continue; 238 | } 239 | } 240 | } 241 | finally 242 | { 243 | _queueEvents = false; 244 | _eventQueue.Clear(); 245 | } 246 | return false; 247 | } 248 | 249 | public void DeleteProfile(string profileName) 250 | { 251 | Wlan.ThrowIfError(Wlan.WlanDeleteProfile(_client.ItsClientHandle, _info.interfaceGuid, profileName, IntPtr.Zero)); 252 | } 253 | 254 | public IEnumerable GetAvailableNetworkList(Wlan.WlanGetAvailableNetworkFlags flags) 255 | { 256 | IntPtr ptr; 257 | Wlan.WlanAvailableNetwork[] networkArray; 258 | Wlan.ThrowIfError(Wlan.WlanGetAvailableNetworkList(_client.ItsClientHandle, _info.interfaceGuid, flags, IntPtr.Zero, out ptr)); 259 | try 260 | { 261 | networkArray = ConvertAvailableNetworkListPtr(ptr); 262 | } 263 | finally 264 | { 265 | Wlan.WlanFreeMemory(ptr); 266 | } 267 | return networkArray; 268 | } 269 | 270 | public IEnumerable GetNetworkBssList() 271 | { 272 | IntPtr ptr; 273 | Wlan.WlanBssEntryN[] entryArray; 274 | Wlan.ThrowIfError(Wlan.WlanGetNetworkBssList(_client.ItsClientHandle, _info.interfaceGuid, IntPtr.Zero, Wlan.Dot11BssType.Any, false, IntPtr.Zero, out ptr)); 275 | try 276 | { 277 | entryArray = ConvertBssListPtr(ptr); 278 | } 279 | finally 280 | { 281 | Wlan.WlanFreeMemory(ptr); 282 | } 283 | return entryArray; 284 | } 285 | 286 | public Wlan.WlanBssEntryN[] GetNetworkBssList(Wlan.Dot11Ssid ssid, Wlan.Dot11BssType bssType, bool securityEnabled) 287 | { 288 | Wlan.WlanBssEntryN[] entryArray; 289 | IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ssid)); 290 | Marshal.StructureToPtr(ssid, ptr, false); 291 | try 292 | { 293 | IntPtr ptr2; 294 | Wlan.ThrowIfError(Wlan.WlanGetNetworkBssList(_client.ItsClientHandle, _info.interfaceGuid, ptr, bssType, securityEnabled, IntPtr.Zero, out ptr2)); 295 | try 296 | { 297 | entryArray = ConvertBssListPtr(ptr2); 298 | } 299 | finally 300 | { 301 | Wlan.WlanFreeMemory(ptr2); 302 | } 303 | } 304 | finally 305 | { 306 | Marshal.FreeHGlobal(ptr); 307 | } 308 | return entryArray; 309 | } 310 | 311 | public Wlan.WlanProfileInfo[] GetProfiles() 312 | { 313 | IntPtr ptr; 314 | Wlan.WlanProfileInfo[] infoArray2; 315 | Wlan.ThrowIfError(Wlan.WlanGetProfileList(_client.ItsClientHandle, _info.interfaceGuid, IntPtr.Zero, out ptr)); 316 | try 317 | { 318 | Wlan.WlanProfileInfoListHeader structure = (Wlan.WlanProfileInfoListHeader)Marshal.PtrToStructure(ptr, typeof(Wlan.WlanProfileInfoListHeader)); 319 | Wlan.WlanProfileInfo[] infoArray = new Wlan.WlanProfileInfo[structure.numberOfItems]; 320 | long num = ptr.ToInt64() + Marshal.SizeOf(structure); 321 | for (int i = 0; i < structure.numberOfItems; i++) 322 | { 323 | Wlan.WlanProfileInfo info = (Wlan.WlanProfileInfo)Marshal.PtrToStructure(new IntPtr(num), typeof(Wlan.WlanProfileInfo)); 324 | infoArray[i] = info; 325 | num += Marshal.SizeOf(info); 326 | } 327 | infoArray2 = infoArray; 328 | } 329 | finally 330 | { 331 | Wlan.WlanFreeMemory(ptr); 332 | } 333 | return infoArray2; 334 | } 335 | 336 | public string GetProfileXml(string profileName) 337 | { 338 | IntPtr ptr; 339 | Wlan.WlanProfileFlags flags; 340 | Wlan.WlanAccess access; 341 | string str; 342 | Wlan.ThrowIfError(Wlan.WlanGetProfile(_client.ItsClientHandle, _info.interfaceGuid, profileName, IntPtr.Zero, out ptr, out flags, out access)); 343 | try 344 | { 345 | str = Marshal.PtrToStringUni(ptr); 346 | } 347 | finally 348 | { 349 | Wlan.WlanFreeMemory(ptr); 350 | } 351 | return str; 352 | } 353 | 354 | public void Scan() 355 | { 356 | Wlan.ThrowIfError(Wlan.WlanScan(_client.ItsClientHandle, _info.interfaceGuid, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)); 357 | } 358 | 359 | public Wlan.WlanReasonCode SetProfile(Wlan.WlanProfileFlags flags, string profileXml, bool overwrite) 360 | { 361 | Wlan.WlanReasonCode code; 362 | Wlan.ThrowIfError(Wlan.WlanSetProfile(_client.ItsClientHandle, _info.interfaceGuid, flags, profileXml, null, overwrite, IntPtr.Zero, out code)); 363 | return code; 364 | } 365 | 366 | #endregion Public Methods 367 | 368 | #region Private Methods 369 | 370 | private void Connect(Wlan.WlanConnectionParameters connectionParams) 371 | { 372 | Wlan.ThrowIfError(Wlan.WlanConnect(_client.ItsClientHandle, _info.interfaceGuid, ref connectionParams, IntPtr.Zero)); 373 | } 374 | 375 | private void Connect(Wlan.WlanConnectionMode connectionMode, Wlan.Dot11BssType bssType, string profile) 376 | { 377 | Wlan.WlanConnectionParameters parameters2 = new Wlan.WlanConnectionParameters 378 | { 379 | wlanConnectionMode = connectionMode, 380 | profile = profile, 381 | dot11BssType = bssType, 382 | flags = 0 383 | }; 384 | Wlan.WlanConnectionParameters connectionParams = parameters2; 385 | Connect(connectionParams); 386 | } 387 | 388 | private Wlan.WlanAvailableNetwork[] ConvertAvailableNetworkListPtr(IntPtr availNetListPtr) 389 | { 390 | Wlan.WlanAvailableNetworkListHeader header = (Wlan.WlanAvailableNetworkListHeader)Marshal.PtrToStructure(availNetListPtr, typeof(Wlan.WlanAvailableNetworkListHeader)); 391 | long num = availNetListPtr.ToInt64() + Marshal.SizeOf(typeof(Wlan.WlanAvailableNetworkListHeader)); 392 | Wlan.WlanAvailableNetwork[] networkArray = new Wlan.WlanAvailableNetwork[header.numberOfItems]; 393 | for (int i = 0; i < header.numberOfItems; i++) 394 | { 395 | networkArray[i] = (Wlan.WlanAvailableNetwork)Marshal.PtrToStructure(new IntPtr(num), typeof(Wlan.WlanAvailableNetwork)); 396 | num += Marshal.SizeOf(typeof(Wlan.WlanAvailableNetwork)); 397 | } 398 | return networkArray; 399 | } 400 | 401 | private Wlan.WlanBssEntryN[] ConvertBssListPtr(IntPtr bssListPtr) 402 | { 403 | Wlan.WlanBssListHeader header = (Wlan.WlanBssListHeader)Marshal.PtrToStructure(bssListPtr, typeof(Wlan.WlanBssListHeader)); 404 | long num = bssListPtr.ToInt64() + Marshal.SizeOf(typeof(Wlan.WlanBssListHeader)); 405 | Wlan.WlanBssEntryN[] entryArray = new Wlan.WlanBssEntryN[header.numberOfItems]; 406 | for (int i = 0; i < header.numberOfItems; i++) 407 | { 408 | entryArray[i] = new Wlan.WlanBssEntryN((Wlan.WlanBssEntry)Marshal.PtrToStructure(new IntPtr(num), typeof(Wlan.WlanBssEntry))); 409 | 410 | int size = (int)entryArray[i].BaseEntry.ieSize; 411 | entryArray[i].IEs = new byte[size]; 412 | 413 | Marshal.Copy(new IntPtr(num + entryArray[i].BaseEntry.ieOffset), entryArray[i].IEs, 0, size); 414 | 415 | num += Marshal.SizeOf(typeof(Wlan.WlanBssEntry)); 416 | } 417 | return entryArray; 418 | } 419 | 420 | private void EnqueueEvent(object queuedEvent) 421 | { 422 | lock (_eventQueue) 423 | { 424 | _eventQueue.Enqueue(queuedEvent); 425 | } 426 | _eventQueueFilled.Set(); 427 | } 428 | 429 | private int GetInterfaceInt(Wlan.WlanIntfOpcode opCode) 430 | { 431 | IntPtr ptr; 432 | int num; 433 | Wlan.WlanOpcodeValueType type; 434 | int num2; 435 | Wlan.ThrowIfError(Wlan.WlanQueryInterface(_client.ItsClientHandle, _info.interfaceGuid, opCode, IntPtr.Zero, out num, out ptr, out type)); 436 | try 437 | { 438 | num2 = Marshal.ReadInt32(ptr); 439 | } 440 | finally 441 | { 442 | Wlan.WlanFreeMemory(ptr); 443 | } 444 | return num2; 445 | } 446 | 447 | internal void OnWlanConnection(Wlan.WlanNotificationData notifyData, Wlan.WlanConnectionNotificationData connNotifyData) 448 | { 449 | if (WlanConnectionNotification != null) 450 | { 451 | WlanConnectionNotification(notifyData, connNotifyData); 452 | } 453 | if (_queueEvents) 454 | { 455 | WlanConnectionNotificationEventData data2 = new WlanConnectionNotificationEventData 456 | { 457 | NotifyData = notifyData, 458 | ConnNotifyData = connNotifyData 459 | }; 460 | WlanConnectionNotificationEventData queuedEvent = data2; 461 | EnqueueEvent(queuedEvent); 462 | } 463 | } 464 | 465 | internal void OnWlanNotification(Wlan.WlanNotificationData notifyData) 466 | { 467 | if (WlanNotification != null) 468 | { 469 | WlanNotification(notifyData); 470 | } 471 | } 472 | 473 | internal void OnWlanReason(Wlan.WlanNotificationData notifyData, Wlan.WlanReasonCode reasonCode) 474 | { 475 | if (WlanReasonNotification != null) 476 | { 477 | WlanReasonNotification(notifyData, reasonCode); 478 | } 479 | if (_queueEvents) 480 | { 481 | WlanReasonNotificationData data2 = new WlanReasonNotificationData 482 | { 483 | NotifyData = notifyData, 484 | ReasonCode = reasonCode 485 | }; 486 | WlanReasonNotificationData queuedEvent = data2; 487 | EnqueueEvent(queuedEvent); 488 | } 489 | } 490 | 491 | private void SetInterfaceInt(Wlan.WlanIntfOpcode opCode, int value) 492 | { 493 | IntPtr ptr = Marshal.AllocHGlobal(4); 494 | Marshal.WriteInt32(ptr, value); 495 | try 496 | { 497 | Wlan.ThrowIfError(Wlan.WlanSetInterface(_client.ItsClientHandle, _info.interfaceGuid, opCode, 4, ptr, IntPtr.Zero)); 498 | } 499 | finally 500 | { 501 | Marshal.FreeHGlobal(ptr); 502 | } 503 | } 504 | 505 | [StructLayout(LayoutKind.Sequential)] 506 | private struct WlanConnectionNotificationEventData 507 | { 508 | public Wlan.WlanNotificationData NotifyData; 509 | public Wlan.WlanConnectionNotificationData ConnNotifyData; 510 | } 511 | 512 | [StructLayout(LayoutKind.Sequential)] 513 | private struct WlanReasonNotificationData 514 | { 515 | public Wlan.WlanNotificationData NotifyData; 516 | public Wlan.WlanReasonCode ReasonCode; 517 | } 518 | 519 | #endregion Private Methods 520 | } 521 | } -------------------------------------------------------------------------------- /Wlan.cs: -------------------------------------------------------------------------------- 1 | #region Header 2 | 3 | // 4 | // Copyright (c) 2007-2010 MetaGeek, LLC 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | // 18 | 19 | #endregion Header 20 | 21 | using System; 22 | using System.ComponentModel; 23 | using System.Diagnostics; 24 | using System.Net.NetworkInformation; 25 | using System.Runtime.InteropServices; 26 | using System.Text; 27 | 28 | namespace ManagedWifi 29 | { 30 | public static class Wlan 31 | { 32 | #region Fields 33 | 34 | public const uint WlanClientVersionLonghorn = 2; 35 | public const uint WlanClientVersionXpSp2 = 1; 36 | 37 | #endregion Fields 38 | 39 | #region Enumerations 40 | 41 | public enum Dot11AuthAlgorithm : uint 42 | { 43 | IEEE80211_Open = 1, 44 | IEEE80211_SharedKey = 2, 45 | IHV_End = 0xffffffff, 46 | IHV_Start = 0x80000000, 47 | RSNA = 6, 48 | RSNA_PSK = 7, 49 | WPA = 3, 50 | WPA_None = 5, 51 | WPA_PSK = 4 52 | } 53 | 54 | public enum Dot11BssType 55 | { 56 | Any = 3, 57 | Independent = 2, 58 | Infrastructure = 1 59 | } 60 | 61 | public enum Dot11CipherAlgorithm : uint 62 | { 63 | CCMP = 4, 64 | IHV_End = 0xffffffff, 65 | IHV_Start = 0x80000000, 66 | None = 0, 67 | RSN_UseGroup = 0x100, 68 | TKIP = 2, 69 | WEP = 0x101, 70 | WEP104 = 5, 71 | WEP40 = 1, 72 | WPA_UseGroup = 0x100 73 | } 74 | 75 | [Flags] 76 | public enum Dot11OperationMode : uint 77 | { 78 | Ap = 2, 79 | ExtensibleStation = 4, 80 | NetworkMonitor = 0x80000000, 81 | Station = 1, 82 | Unknown = 0 83 | } 84 | 85 | public enum Dot11PhyType : uint 86 | { 87 | Any = 0, 88 | Dsss = 2, 89 | Erp = 6, 90 | Fhss = 1, 91 | Hrdsss = 5, 92 | Ht = 7, 93 | IhvEnd = 0xffffffff, 94 | IhvStart = 0x80000000, 95 | IrBaseband = 3, 96 | Ofdm = 4, 97 | Unknown = 0 98 | } 99 | 100 | [Flags] 101 | public enum WlanAccess 102 | { 103 | ExecuteAccess = 0x20021, 104 | ReadAccess = 0x20001, 105 | WriteAccess = 0x70023 106 | } 107 | 108 | public enum WlanAdhocNetworkState 109 | { 110 | Formed, 111 | Connected 112 | } 113 | 114 | [Flags] 115 | public enum WlanConnectionFlags 116 | { 117 | AdhocJoinOnly = 2, 118 | EapolPassthrough = 8, 119 | HiddenNetwork = 1, 120 | IgnorePrivacyBit = 4 121 | } 122 | 123 | public enum WlanConnectionMode 124 | { 125 | Profile, 126 | TemporaryProfile, 127 | DiscoverySecure, 128 | DiscoveryUnsecure, 129 | Auto, 130 | Invalid 131 | } 132 | 133 | /* 134 | public class WlanException : Exception 135 | { 136 | private readonly Wlan.WlanReasonCode reasonCode; 137 | 138 | private WlanException(Wlan.WlanReasonCode reasonCode) 139 | { 140 | this.reasonCode = reasonCode; 141 | } 142 | 143 | public override string Message 144 | { 145 | get 146 | { 147 | StringBuilder stringBuffer = new StringBuilder(0x400); 148 | if (Wlan.WlanReasonCodeToString(this.reasonCode, stringBuffer.Capacity, stringBuffer, IntPtr.Zero) == 0) 149 | { 150 | return stringBuffer.ToString(); 151 | } 152 | return string.Empty; 153 | } 154 | } 155 | 156 | public Wlan.WlanReasonCode ReasonCode 157 | { 158 | get 159 | { 160 | return this.reasonCode; 161 | } 162 | } 163 | } 164 | */ 165 | [Flags] 166 | public enum WlanGetAvailableNetworkFlags 167 | { 168 | IncludeAllAdhocProfiles = 1, 169 | IncludeAllManualHiddenProfiles = 2 170 | } 171 | 172 | public enum WlanInterfaceState 173 | { 174 | NotReady, 175 | Connected, 176 | AdHocNetworkFormed, 177 | Disconnecting, 178 | Disconnected, 179 | Associating, 180 | Discovering, 181 | Authenticating 182 | } 183 | 184 | public enum WlanIntfOpcode 185 | { 186 | AutoconfEnabled = 1, 187 | BackgroundScanEnabled = 2, 188 | BssType = 5, 189 | ChannelNumber = 8, 190 | CurrentConnection = 7, 191 | CurrentOperationMode = 12, 192 | IhvEnd = 0x3fffffff, 193 | IhvStart = 0x30000000, 194 | InterfaceState = 6, 195 | MediaStreamingMode = 3, 196 | RadioState = 4, 197 | Rssi = 0x10000102, 198 | SecurityEnd = 0x2fffffff, 199 | SecurityStart = 0x20010000, 200 | Statistics = 0x10000101, 201 | SupportedAdhocAuthCipherPairs = 10, 202 | SupportedCountryOrRegionStringList = 11, 203 | SupportedInfrastructureAuthCipherPairs = 9 204 | } 205 | 206 | public enum WlanNotificationCodeAcm 207 | { 208 | AdhocNetworkStateChange = 0x16, 209 | AutoconfDisabled = 2, 210 | AutoconfEnabled = 1, 211 | BackgroundScanDisabled = 4, 212 | BackgroundScanEnabled = 3, 213 | BssTypeChange = 5, 214 | ConnectionAttemptFail = 11, 215 | ConnectionComplete = 10, 216 | ConnectionStart = 9, 217 | Disconnected = 0x15, 218 | Disconnecting = 20, 219 | FilterListChange = 12, 220 | InterfaceArrival = 13, 221 | InterfaceRemoval = 14, 222 | NetworkAvailable = 0x13, 223 | NetworkNotAvailable = 0x12, 224 | PowerSettingChange = 6, 225 | ProfileChange = 15, 226 | ProfileNameChange = 0x10, 227 | ProfilesExhausted = 0x11, 228 | ScanComplete = 7, 229 | ScanFail = 8 230 | } 231 | 232 | public enum WlanNotificationCodeMsm 233 | { 234 | AdapterOperationModeChange = 14, 235 | AdapterRemoval = 13, 236 | Associated = 2, 237 | Associating = 1, 238 | Authenticating = 3, 239 | Connected = 4, 240 | Disassociating = 9, 241 | Disconnected = 10, 242 | PeerJoin = 11, 243 | PeerLeave = 12, 244 | RadioStateChange = 7, 245 | RoamingEnd = 6, 246 | RoamingStart = 5, 247 | SignalQualityChange = 8 248 | } 249 | 250 | [Flags] 251 | public enum WlanNotificationSource 252 | { 253 | Acm = 8, 254 | All = 0xffff, 255 | Ihv = 0x40, 256 | Msm = 0x10, 257 | None = 0, 258 | Security = 0x20 259 | } 260 | 261 | public enum WlanOpcodeValueType 262 | { 263 | QueryOnly, 264 | SetByGroupPolicy, 265 | SetByUser, 266 | Invalid 267 | } 268 | 269 | [Flags] 270 | public enum WlanProfileFlags 271 | { 272 | AllUser, 273 | GroupPolicy, 274 | User 275 | } 276 | 277 | public enum WlanReasonCode 278 | { 279 | AcBase = 0x20000, 280 | AcConnectBase = 0x28000, 281 | AcEnd = 0x2ffff, 282 | AdhocSecurityFailure = 0x3800a, 283 | AssociationFailure = 0x38002, 284 | AssociationTimeout = 0x38003, 285 | AutoSwitchSetForAdhoc = 0x80010, 286 | AutoSwitchSetForManualConnection = 0x80011, 287 | Base = 0x20000, 288 | BssTypeNotAllowed = 0x28005, 289 | BssTypeUnmatch = 0x30003, 290 | ConflictSecurity = 0x8000b, 291 | ConnectCallFail = 0x28009, 292 | DatarateUnmatch = 0x30005, 293 | DisconnectTimeout = 0x3800f, 294 | DriverDisconnected = 0x3800b, 295 | DriverOperationFailure = 0x3800c, 296 | GpDenied = 0x28003, 297 | IhvNotAvailable = 0x3800d, 298 | IhvNotResponding = 0x3800e, 299 | IhvOuiMismatch = 0x80008, 300 | IhvOuiMissing = 0x80009, 301 | IhvSecurityNotSupported = 0x80007, 302 | IhvSecurityOnexMissing = 0x80012, 303 | IhvSettingsMissing = 0x8000a, 304 | InBlockedList = 0x28007, 305 | InFailedList = 0x28006, 306 | InternalFailure = 0x38010, 307 | InvalidAdhocConnectionMode = 0x8000e, 308 | InvalidBssType = 0x8000d, 309 | InvalidPhyType = 0x80005, 310 | InvalidProfileName = 0x80003, 311 | InvalidProfileSchema = 0x80001, 312 | InvalidProfileType = 0x80004, 313 | KeyMismatch = 0x2800d, 314 | MsmBase = 0x30000, 315 | MsmConnectBase = 0x38000, 316 | MsmEnd = 0x3ffff, 317 | MsmSecurityMissing = 0x80006, 318 | MsmsecAuthStartTimeout = 0x48002, 319 | MsmsecAuthSuccessTimeout = 0x48003, 320 | MsmsecBase = 0x40000, 321 | MsmsecCancelled = 0x48011, 322 | MsmsecCapabilityDiscovery = 0x40015, 323 | MsmsecCapabilityNetwork = 0x40012, 324 | MsmsecCapabilityNic = 0x40013, 325 | MsmsecCapabilityProfile = 0x40014, 326 | MsmsecCapabilityProfileAuth = 0x4001e, 327 | MsmsecCapabilityProfileCipher = 0x4001f, 328 | MsmsecConnectBase = 0x48000, 329 | MsmsecDowngradeDetected = 0x48013, 330 | MsmsecEnd = 0x4ffff, 331 | MsmsecForcedFailure = 0x48015, 332 | MsmsecG1MissingGrpKey = 0x4800d, 333 | MsmsecG1MissingKeyData = 0x4800c, 334 | MsmsecKeyFormat = 0x48012, 335 | MsmsecKeyStartTimeout = 0x48004, 336 | MsmsecKeySuccessTimeout = 0x48005, 337 | MsmsecM3MissingGrpKey = 0x48008, 338 | MsmsecM3MissingIe = 0x48007, 339 | MsmsecM3MissingKeyData = 0x48006, 340 | MsmsecMax = 0x4ffff, 341 | MsmsecMin = 0x40000, 342 | MsmsecMixedCell = 0x40019, 343 | MsmsecNicFailure = 0x48010, 344 | MsmsecNoAuthenticator = 0x4800f, 345 | MsmsecNoPairwiseKey = 0x4800b, 346 | MsmsecPeerIndicatedInsecure = 0x4800e, 347 | MsmsecPrIeMatching = 0x48009, 348 | MsmsecProfileAuthTimersInvalid = 0x4001a, 349 | MsmsecProfileDuplicateAuthCipher = 0x40007, 350 | MsmsecProfileInvalidAuthCipher = 0x40009, 351 | MsmsecProfileInvalidGkeyIntv = 0x4001b, 352 | MsmsecProfileInvalidKeyIndex = 0x40001, 353 | MsmsecProfileInvalidPmkcacheMode = 0x4000c, 354 | MsmsecProfileInvalidPmkcacheSize = 0x4000d, 355 | MsmsecProfileInvalidPmkcacheTtl = 0x4000e, 356 | MsmsecProfileInvalidPreauthMode = 0x4000f, 357 | MsmsecProfileInvalidPreauthThrottle = 0x40010, 358 | MsmsecProfileKeyLength = 0x40003, 359 | MsmsecProfileKeyUnmappedChar = 0x4001d, 360 | MsmsecProfileKeymaterialChar = 0x40017, 361 | MsmsecProfileNoAuthCipherSpecified = 0x40005, 362 | MsmsecProfileOnexDisabled = 0x4000a, 363 | MsmsecProfileOnexEnabled = 0x4000b, 364 | MsmsecProfilePassphraseChar = 0x40016, 365 | MsmsecProfilePreauthOnlyEnabled = 0x40011, 366 | MsmsecProfilePskLength = 0x40004, 367 | MsmsecProfilePskPresent = 0x40002, 368 | MsmsecProfileRawdataInvalid = 0x40008, 369 | MsmsecProfileTooManyAuthCipherSpecified = 0x40006, 370 | MsmsecProfileWrongKeytype = 0x40018, 371 | MsmsecPskMismatchSuspected = 0x48014, 372 | MsmsecSecIeMatching = 0x4800a, 373 | MsmsecSecurityUiFailure = 0x48016, 374 | MsmsecTransitionNetwork = 0x4001c, 375 | MsmsecUiRequestFailure = 0x48001, 376 | NetworkNotAvailable = 0x2800b, 377 | NetworkNotCompatible = 0x20001, 378 | NoAutoConnection = 0x28001, 379 | NonBroadcastSetForAdhoc = 0x8000f, 380 | NotVisible = 0x28002, 381 | PhyTypeUnmatch = 0x30004, 382 | PreSecurityFailure = 0x38004, 383 | ProfileBase = 0x80000, 384 | ProfileChangedOrDeleted = 0x2800c, 385 | ProfileConnectBase = 0x88000, 386 | ProfileEnd = 0x8ffff, 387 | ProfileMissing = 0x80002, 388 | ProfileNotCompatible = 0x20002, 389 | ProfileSsidInvalid = 0x80013, 390 | RangeSize = 0x10000, 391 | RoamingFailure = 0x38008, 392 | RoamingSecurityFailure = 0x38009, 393 | ScanCallFail = 0x2800a, 394 | SecurityFailure = 0x38006, 395 | SecurityMissing = 0x8000c, 396 | SecurityTimeout = 0x38007, 397 | SsidListTooLong = 0x28008, 398 | StartSecurityFailure = 0x38005, 399 | Success = 0, 400 | TooManySecurityAttempts = 0x38012, 401 | TooManySsid = 0x80014, 402 | UiRequestTimeout = 0x38011, 403 | Unknown = 0x10001, 404 | UnsupportedSecuritySet = 0x30002, 405 | UnsupportedSecuritySetByOs = 0x30001, 406 | UserCancelled = 0x38001, 407 | UserDenied = 0x28004, 408 | UserNotRespond = 0x2800e 409 | } 410 | 411 | [Flags] 412 | private enum WlanAvailableNetworkFlags 413 | { 414 | Connected = 1, 415 | HasProfile = 2 416 | } 417 | 418 | #endregion Enumerations 419 | 420 | #region Delegates 421 | 422 | public delegate void WlanNotificationCallbackDelegate(ref Wlan.WlanNotificationData notificationData, IntPtr context); 423 | 424 | #endregion Delegates 425 | 426 | #region Public Methods 427 | 428 | [StructLayout(LayoutKind.Sequential)] 429 | public struct Dot11Ssid 430 | { 431 | public readonly uint SSIDLength; 432 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=0x20)] 433 | public readonly byte[] SSID; 434 | } 435 | 436 | [StructLayout(LayoutKind.Sequential)] 437 | public struct WlanAssociationAttributes 438 | { 439 | private readonly Dot11Ssid dot11Ssid; 440 | private readonly Dot11BssType dot11BssType; 441 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] 442 | private readonly byte[] dot11Bssid; 443 | private readonly Dot11PhyType dot11PhyType; 444 | private readonly uint dot11PhyIndex; 445 | private readonly uint wlanSignalQuality; 446 | private readonly uint rxRate; 447 | private readonly uint txRate; 448 | 449 | public PhysicalAddress Dot11Bssid 450 | { 451 | get 452 | { 453 | return dot11Bssid != null 454 | ? new PhysicalAddress(dot11Bssid) 455 | : new PhysicalAddress(new byte[] {0, 0, 0, 0, 0, 0}); 456 | } 457 | } 458 | } 459 | 460 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 461 | public struct WlanAvailableNetwork 462 | { 463 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x100)] 464 | private readonly string profileName; 465 | public Dot11Ssid dot11Ssid; 466 | private readonly Dot11BssType dot11BssType; 467 | private readonly uint numberOfBssids; 468 | private readonly bool networkConnectable; 469 | private readonly WlanReasonCode wlanNotConnectableReason; 470 | private readonly uint numberOfPhyTypes; 471 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=8)] 472 | private readonly Dot11PhyType[] dot11PhyTypes; 473 | private readonly bool morePhyTypes; 474 | public readonly uint wlanSignalQuality; 475 | private readonly bool securityEnabled; 476 | public readonly Dot11AuthAlgorithm dot11DefaultAuthAlgorithm; 477 | public readonly Dot11CipherAlgorithm dot11DefaultCipherAlgorithm; 478 | private readonly WlanAvailableNetworkFlags flags; 479 | private readonly uint reserved; 480 | 481 | public Dot11PhyType[] Dot11PhyTypes 482 | { 483 | get 484 | { 485 | Dot11PhyType[] destinationArray = new Dot11PhyType[numberOfPhyTypes]; 486 | Array.Copy(dot11PhyTypes, destinationArray, numberOfPhyTypes); 487 | return destinationArray; 488 | } 489 | } 490 | } 491 | 492 | [StructLayout(LayoutKind.Sequential)] 493 | public struct WlanBssEntry 494 | { 495 | public Dot11Ssid dot11Ssid; 496 | private readonly uint phyId; 497 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] 498 | public readonly byte[] dot11Bssid; 499 | public readonly Dot11BssType dot11BssType; 500 | public readonly Dot11PhyType dot11BssPhyType; 501 | public readonly int rssi; 502 | public readonly uint linkQuality; 503 | private readonly bool inRegDomain; 504 | private readonly ushort beaconPeriod; 505 | private readonly ulong timestamp; 506 | private readonly ulong hostTimestamp; 507 | private readonly ushort capabilityInformation; 508 | public readonly uint chCenterFrequency; 509 | public WlanRateSet wlanRateSet; 510 | public readonly uint ieOffset; 511 | public readonly uint ieSize; 512 | } 513 | 514 | //Added 7-29-10 by Tyler 515 | public class WlanBssEntryN 516 | { 517 | public WlanBssEntry BaseEntry; 518 | public IeParser.TypeNSettings NSettings; 519 | public byte[] IEs; 520 | 521 | public WlanBssEntryN(WlanBssEntry bssEntry) 522 | { 523 | BaseEntry = bssEntry; 524 | } 525 | } 526 | 527 | [DllImport("wlanapi.dll")] 528 | public static extern int WlanCloseHandle([In] IntPtr clientHandle, [In, Out] IntPtr pReserved); 529 | 530 | [DllImport("wlanapi.dll")] 531 | public static extern int WlanConnect([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] ref WlanConnectionParameters connectionParameters, IntPtr pReserved); 532 | 533 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 534 | public struct WlanConnectionAttributes 535 | { 536 | public readonly WlanInterfaceState isState; 537 | public readonly WlanConnectionMode wlanConnectionMode; 538 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x100)] 539 | private readonly string profileName; 540 | public readonly WlanAssociationAttributes wlanAssociationAttributes; 541 | private readonly WlanSecurityAttributes wlanSecurityAttributes; 542 | } 543 | 544 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 545 | public struct WlanConnectionNotificationData 546 | { 547 | private readonly WlanConnectionMode wlanConnectionMode; 548 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x20)] 549 | public readonly string profileName; 550 | private readonly Dot11Ssid dot11Ssid; 551 | private readonly Dot11BssType dot11BssType; 552 | private readonly bool securityEnabled; 553 | public readonly WlanReasonCode wlanReasonCode; 554 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=1)] 555 | public string profileXml; 556 | } 557 | 558 | [StructLayout(LayoutKind.Sequential)] 559 | public struct WlanConnectionParameters 560 | { 561 | public WlanConnectionMode wlanConnectionMode; 562 | [MarshalAs(UnmanagedType.LPWStr)] 563 | public string profile; 564 | public IntPtr dot11SsidPtr; 565 | private IntPtr desiredBssidListPtr; 566 | public Dot11BssType dot11BssType; 567 | public WlanConnectionFlags flags; 568 | } 569 | 570 | [DllImport("wlanapi.dll")] 571 | public static extern int WlanDeleteProfile([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In, MarshalAs(UnmanagedType.LPWStr)] string profileName, IntPtr reservedPtr); 572 | 573 | [DllImport("wlanapi.dll")] 574 | public static extern int WlanEnumInterfaces([In] IntPtr clientHandle, [In, Out] IntPtr pReserved, out IntPtr ppInterfaceList); 575 | 576 | [DllImport("wlanapi.dll")] 577 | public static extern void WlanFreeMemory(IntPtr pMemory); 578 | 579 | [DllImport("wlanapi.dll")] 580 | public static extern int WlanGetAvailableNetworkList([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] WlanGetAvailableNetworkFlags flags, [In, Out] IntPtr reservedPtr, out IntPtr availableNetworkListPtr); 581 | 582 | [DllImport("wlanapi.dll")] 583 | public static extern int WlanGetNetworkBssList([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] IntPtr dot11SsidInt, [In] Dot11BssType dot11BssType, [In] bool securityEnabled, IntPtr reservedPtr, out IntPtr wlanBssList); 584 | 585 | [DllImport("wlanapi.dll")] 586 | public static extern int WlanGetProfile([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In, MarshalAs(UnmanagedType.LPWStr)] string profileName, [In] IntPtr pReserved, out IntPtr profileXml, [Optional] out WlanProfileFlags flags, [Optional] out WlanAccess grantedAccess); 587 | 588 | [DllImport("wlanapi.dll")] 589 | public static extern int WlanGetProfileList([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] IntPtr pReserved, out IntPtr profileList); 590 | 591 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 592 | public struct WlanInterfaceInfo 593 | { 594 | public Guid interfaceGuid; 595 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x100)] 596 | public readonly string interfaceDescription; 597 | private readonly WlanInterfaceState isState; 598 | } 599 | 600 | [StructLayout(LayoutKind.Sequential)] 601 | public struct WlanNotificationData 602 | { 603 | public readonly WlanNotificationSource notificationSource; 604 | public readonly int notificationCode; 605 | public Guid interfaceGuid; 606 | public readonly int dataSize; 607 | public IntPtr dataPtr; 608 | 609 | public object NotificationCode 610 | { 611 | get 612 | { 613 | if (notificationSource == WlanNotificationSource.Msm) 614 | { 615 | return (WlanNotificationCodeMsm) notificationCode; 616 | } 617 | if (notificationSource == WlanNotificationSource.Acm) 618 | { 619 | return (WlanNotificationCodeAcm) notificationCode; 620 | } 621 | return notificationCode; 622 | } 623 | } 624 | } 625 | 626 | [DllImport("wlanapi.dll")] 627 | public static extern int WlanOpenHandle([In] uint clientVersion, [In, Out] IntPtr pReserved, out uint negotiatedVersion, out IntPtr clientHandle); 628 | 629 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 630 | public struct WlanProfileInfo 631 | { 632 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x100)] 633 | private readonly string profileName; 634 | private readonly WlanProfileFlags profileFlags; 635 | } 636 | 637 | [DllImport("wlanapi.dll")] 638 | public static extern int WlanQueryInterface([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] WlanIntfOpcode opCode, [In, Out] IntPtr pReserved, out int dataSize, out IntPtr ppData, out WlanOpcodeValueType wlanOpcodeValueType); 639 | 640 | [StructLayout(LayoutKind.Sequential)] 641 | public struct WlanRateSet 642 | { 643 | private readonly uint rateSetLength; 644 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=0x7e)] 645 | private readonly ushort[] rateSet; 646 | 647 | public ushort[] Rates 648 | { 649 | get 650 | { 651 | ushort[] destinationArray = new ushort[rateSetLength]; 652 | Array.Copy(rateSet, destinationArray, destinationArray.Length); 653 | return destinationArray; 654 | } 655 | } 656 | 657 | public double GetRateInMbps(int rate) 658 | { 659 | return ((rateSet[rate] & 0x7fff) * 0.5); 660 | } 661 | } 662 | 663 | [DllImport("wlanapi.dll")] 664 | public static extern int WlanReasonCodeToString([In] WlanReasonCode reasonCode, [In] int bufferSize, [In, Out] StringBuilder stringBuffer, IntPtr pReserved); 665 | 666 | [DllImport("wlanapi.dll")] 667 | public static extern int WlanRegisterNotification([In] IntPtr clientHandle, [In] WlanNotificationSource notifSource, [In] bool ignoreDuplicate, [In] WlanNotificationCallbackDelegate funcCallback, [In] IntPtr callbackContext, [In] IntPtr reserved, out WlanNotificationSource prevNotifSource); 668 | 669 | [DllImport("wlanapi.dll")] 670 | public static extern int WlanScan([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] IntPtr pDot11Ssid, [In] IntPtr pIeData, [In, Out] IntPtr pReserved); 671 | 672 | [DllImport("wlanapi.dll")] 673 | public static extern int WlanSetInterface([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] WlanIntfOpcode opCode, [In] uint dataSize, [In] IntPtr pData, [In, Out] IntPtr pReserved); 674 | 675 | [DllImport("wlanapi.dll")] 676 | public static extern int WlanSetProfile([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] WlanProfileFlags flags, [In, MarshalAs(UnmanagedType.LPWStr)] string profileXml, [In, Optional, MarshalAs(UnmanagedType.LPWStr)] string allUserProfileSecurity, [In] bool overwrite, [In] IntPtr pReserved, out WlanReasonCode reasonCode); 677 | 678 | #endregion Public Methods 679 | 680 | #region Private Methods 681 | 682 | [DebuggerStepThrough] 683 | internal static void ThrowIfError(int win32ErrorCode) 684 | { 685 | if (win32ErrorCode != 0) 686 | { 687 | throw new Win32Exception(win32ErrorCode); 688 | } 689 | } 690 | 691 | [StructLayout(LayoutKind.Sequential)] 692 | internal struct WlanAvailableNetworkListHeader 693 | { 694 | public readonly uint numberOfItems; 695 | private uint index; 696 | } 697 | 698 | [StructLayout(LayoutKind.Sequential)] 699 | internal struct WlanBssListHeader 700 | { 701 | private readonly uint totalSize; 702 | internal readonly uint numberOfItems; 703 | } 704 | 705 | [StructLayout(LayoutKind.Sequential)] 706 | internal struct WlanInterfaceInfoListHeader 707 | { 708 | public readonly uint numberOfItems; 709 | private readonly uint index; 710 | } 711 | 712 | [StructLayout(LayoutKind.Sequential)] 713 | internal struct WlanProfileInfoListHeader 714 | { 715 | public readonly uint numberOfItems; 716 | private readonly uint index; 717 | } 718 | 719 | [StructLayout(LayoutKind.Sequential)] 720 | private struct WlanSecurityAttributes 721 | { 722 | [MarshalAs(UnmanagedType.Bool)] 723 | private readonly bool securityEnabled; 724 | [MarshalAs(UnmanagedType.Bool)] 725 | private readonly bool oneXEnabled; 726 | private readonly Dot11AuthAlgorithm dot11AuthAlgorithm; 727 | private readonly Dot11CipherAlgorithm dot11CipherAlgorithm; 728 | } 729 | 730 | #endregion Private Methods 731 | } 732 | } --------------------------------------------------------------------------------