using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace POSV.Common.Util { public class WiFiApi { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); /// /// 打开一个wifi句柄 /// /// 版本号 /// 保留 /// 支持的最高版本(输出) /// 句柄(要得到的)以后的句柄一般都是这个 /// [DllImport("Wlanapi", EntryPoint = "WlanOpenHandle")] public static extern uint WlanOpenHandle(uint dwClientVersion, IntPtr pReserved, [Out] out uint pdwNegotiatedVersion, ref IntPtr ClientHandle); /// /// 关闭打开的句柄 /// /// 句柄 /// 保留 /// [DllImport("Wlanapi", EntryPoint = "WlanCloseHandle")] public static extern uint WlanCloseHandle([In] IntPtr hClientHandle, IntPtr pReserved); /// /// 列举无线网络适配器 /// /// 句柄 /// 保留 /// 数据指针(非托管) /// [DllImport("Wlanapi", EntryPoint = "WlanEnumInterfaces")] public static extern uint WlanEnumInterfaces([In] IntPtr hClientHandle, IntPtr pReserved, ref IntPtr ppInterfaceList); /// /// 释放内存 /// /// 要释放的内存起始地址 [DllImport("Wlanapi", EntryPoint = "WlanFreeMemory")] public static extern void WlanFreeMemory([In] IntPtr pMemory); /// /// 获得可见的无线网络 /// /// 句柄 /// 适配器的guid号 /// 标志位 /// 保留 /// 无线网络的内存起始地址(非托管) /// [DllImport("Wlanapi", EntryPoint = "WlanGetAvailableNetworkList")] public static extern uint WlanGetAvailableNetworkList(IntPtr hClientHandle, ref Guid pInterfaceGuid, uint dwFlags, IntPtr pReserved, ref IntPtr ppAvailableNetworkList); /// /// 网络适配器的状态 /// public enum WLAN_INTERFACE_STATE { WLAN_INTERFACE_STATE_NOT_READY = 0, WLAN_INTERFACE_STATE_CONNECTED = 1, WLAN_INTERFACE_STATE_AD_HOC_NETWORK_FORMED = 2, WLAN_INTERFACE_STATE_DISCONNECTING = 3, WLAN_INTERFACE_STATE_DISCONNECTED = 4, WLAN_INTERFACE_STATE_ASSOCIATING = 5, WLAN_INTERFACE_STATE_DISCOVERING = 6, WLAN_INTERFACE_STATE_AUTHENTICATING = 7 } /// /// 一个适配器的信息 /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WLAN_INTERFACE_INFO { ///GUID->_GUID public Guid InterfaceGuid;//Guid自动生成代码 ///WCHAR[256] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string strInterfaceDescription; ///WLAN_INTERFACE_STATE public WLAN_INTERFACE_STATE isState; } /// /// 包含所有适配器 /// [StructLayout(LayoutKind.Sequential)] public struct WLAN_INTERFACE_INFO_LIST //struct结构 { public Int32 dwNumberOfItems; public Int32 dwIndex; public WLAN_INTERFACE_INFO[] InterfaceInfo; 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 * 532) + 8); WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO(); wii = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO)); InterfaceInfo[i] = wii; } } } /// /// 服务器标志(子网络标志号) /// [StructLayout(LayoutKind.Sequential)] public struct DOT11_SSID { public uint uSSIDLength; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] ucSSID; public byte[] ToBytes() { return (ucSSID != null) ? ucSSID.Take((int)uSSIDLength).ToArray() : null; } // UTF-8 code page private static Encoding _encoding = Encoding.GetEncoding(65001, EncoderFallback.ReplacementFallback, DecoderFallback.ExceptionFallback); public override string ToString() { if (ucSSID == null) return null; try { return _encoding.GetString(ToBytes()); } catch (DecoderFallbackException) { return null; } } } /// /// BSS类型 /// public enum DOT11_BSS_TYPE { DOT11_BSS_TYPE_INFRASTRUCTURE = 1, DOT11_BSS_TYPE_INDEPENDENT = 2, DOT11_BSS_TYPE_ANY = 3 } /// /// /// public enum DOT11_PHY_TYPE { DOT11_PHY_TYPE_UNKNOWN = 1, DOT11_PHY_TYPE_ANY, DOT11_PHY_TYPE_FHSS, DOT11_PHY_TYPE_DSSS, DOT11_PHY_TYPE_IRBASEHAND, DOT11_PHY_TYPE_OFDM, DOT11_PHY_TYPE_HRDSSS, DOT11_PHY_TYPE_ERP, DOT11_PHY_TYPE_HT, DOT11_PHY_TYPE_IHV_START, DOT11_PHY_TYPE_IHV_END } public enum DOT11_AUTH_ALGORITHM { DOT11_AUTH_ALGO_80211_OPEN = 1, DOT11_AUTH_ALGO_80211_SHARED_KEY = 2, DOT11_AUTH_ALGO_WPA = 3, DOT11_AUTH_ALGO_WPA_PSK = 4, DOT11_AUTH_ALGO_WPA_NONE = 5, DOT11_AUTH_ALOG_RSNA = 6, DOT11_AUTH_ALOG_RSNA_PSK = 7, DOT11_AUTH_ALOG_IHV_START = -2147483648, DOT11_AUTH_ALOG_IHV_END = -1 } public enum DOT11_CIPER_ALGORITHM { DOT11_CIPER_ALGO_NONE = 0, DOT11_CIPER_ALGO_WEP40 = 1, DOT11_CIPER_ALGO_TKIP = 2, DOT11_CIPER_ALGO_CCMP = 4, DOT11_CIPER_ALGO_WEP104 = 5, DOT11_CIPER_ALGO_WPA_USE_GROUP = 256, DOT11_CIPER_ALGO_RSN_USE_GROUP = 256, DOT11_CIPER_ALGO_WEP = 257, DOT11_CIPER_ALGO_IHV_START = -2147483648, DOT11_CIPER_ALGO_IHV_END = -1 } /// /// /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WLAN_AVAILABLE_NETWORK { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string strProfileName; public DOT11_SSID dot11Ssid; public DOT11_BSS_TYPE dot11BssType; public uint uNumberOfBssids; public bool bNetworkConnectable; public uint wlanNotConnectableReason; public uint uNumberOfPhyTypes; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public DOT11_PHY_TYPE[] dot11PhyTypes; public bool bMorePhyTypes; public uint wlanSignalQuality; public bool bSecurityEnabled; public DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm; public DOT11_CIPER_ALGORITHM dot11DefaultCipherAlgorithm; public uint dwFlags; public uint dwReserved; } /// /// /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct WLAN_AVALABLE_NETWORK_LIST { internal uint dwNumberOfItems; internal uint dwIndex; internal WLAN_AVAILABLE_NETWORK[] wlanAvailableNetwork; internal WLAN_AVALABLE_NETWORK_LIST(IntPtr ppAvailableNetworkList) { dwNumberOfItems = (uint)Marshal.ReadInt32(ppAvailableNetworkList); dwIndex = (uint)Marshal.ReadInt32(ppAvailableNetworkList, 4); wlanAvailableNetwork = new WLAN_AVAILABLE_NETWORK[dwNumberOfItems]; for (int i = 0; i < dwNumberOfItems; i++) { IntPtr pWlanAvailableNetwork = new IntPtr(ppAvailableNetworkList.ToInt32() + i * Marshal.SizeOf(typeof(WLAN_AVAILABLE_NETWORK)) + 8); wlanAvailableNetwork[i] = (WLAN_AVAILABLE_NETWORK)Marshal.PtrToStructure(pWlanAvailableNetwork, typeof(WLAN_AVAILABLE_NETWORK)); } } } /// /// 获取可用的SSID列表 /// public static bool Connected() { bool connected = false; try { uint serviceVersion = 0; IntPtr handle = IntPtr.Zero; int result; result = (int)WlanOpenHandle(2, IntPtr.Zero, out serviceVersion, ref handle); IntPtr ppInterfaceList = IntPtr.Zero; WLAN_INTERFACE_INFO_LIST interfaceList; if (WlanEnumInterfaces(handle, IntPtr.Zero, ref ppInterfaceList) == 0) { interfaceList = new WLAN_INTERFACE_INFO_LIST(ppInterfaceList); logger.Info("发现本机有{0}个无线网络适配器", interfaceList.dwNumberOfItems); for (int i = 0; i < interfaceList.dwNumberOfItems; i++) { IntPtr ppAvailableNetworkList = new IntPtr(); Guid pInterfaceGuid = interfaceList.InterfaceInfo[i].InterfaceGuid; WlanGetAvailableNetworkList(handle, ref pInterfaceGuid, 0x00000002, new IntPtr(), ref ppAvailableNetworkList); WLAN_AVALABLE_NETWORK_LIST wlanAvailableNetworkList = new WLAN_AVALABLE_NETWORK_LIST(ppAvailableNetworkList); WlanFreeMemory(ppAvailableNetworkList); WlanCloseHandle(handle, IntPtr.Zero); if (WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_CONNECTED == interfaceList.InterfaceInfo[i].isState) { logger.Info("无线网络适配器:{0}-->{1}", interfaceList.InterfaceInfo[i].strInterfaceDescription, getStateDescription(interfaceList.InterfaceInfo[i].isState)); connected = true; break; } } } } catch { } return connected; } /// /// 获取可用的SSID列表 /// public static List EnumerateAvailableNetwork() { List lists = new List(); try { uint serviceVersion = 0; IntPtr handle = IntPtr.Zero; int result; result = (int)WlanOpenHandle(2, IntPtr.Zero, out serviceVersion, ref handle); IntPtr ppInterfaceList = IntPtr.Zero; WLAN_INTERFACE_INFO_LIST interfaceList; if (WlanEnumInterfaces(handle, IntPtr.Zero, ref ppInterfaceList) == 0) { interfaceList = new WLAN_INTERFACE_INFO_LIST(ppInterfaceList); logger.Info("有{0}个无线网络适配器", interfaceList.dwNumberOfItems); Console.WriteLine("Enumerating Wireless Network Adapters..."); for (int i = 0; i < interfaceList.dwNumberOfItems; i++) { IntPtr ppAvailableNetworkList = new IntPtr(); Guid pInterfaceGuid = interfaceList.InterfaceInfo[i].InterfaceGuid; WlanGetAvailableNetworkList(handle, ref pInterfaceGuid, 0x00000002, new IntPtr(), ref ppAvailableNetworkList); WLAN_AVALABLE_NETWORK_LIST wlanAvailableNetworkList = new WLAN_AVALABLE_NETWORK_LIST(ppAvailableNetworkList); WlanFreeMemory(ppAvailableNetworkList); WlanCloseHandle(handle, IntPtr.Zero); for (int j = 0; j < wlanAvailableNetworkList.dwNumberOfItems; j++) { WLAN_AVAILABLE_NETWORK network = wlanAvailableNetworkList.wlanAvailableNetwork[j]; logger.Debug("Available Network:"); logger.Debug("SSID:" + network.dot11Ssid.ToString()); logger.Debug("StrProfile:" + network.strProfileName); logger.Debug("Encrypted:" + network.bSecurityEnabled); logger.Debug("Signal Strength:" + network.wlanSignalQuality); logger.Debug("Default Authentication:" + network.dot11DefaultAuthAlgorithm.ToString()); logger.Debug("Default Cipher:" + network.dot11DefaultCipherAlgorithm.ToString()); lists.Add(network.dot11Ssid.ToString()); } } } } catch { } return lists; } /// /// WLAN I/F status wording /// private static string getStateDescription(WLAN_INTERFACE_STATE state) { string stateDescription = string.Empty; switch (state) { case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_NOT_READY: stateDescription = "not ready to operate"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_CONNECTED: stateDescription = "connected"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_AD_HOC_NETWORK_FORMED: stateDescription = "first node in an adhoc network"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_DISCONNECTING: stateDescription = "disconnecting"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_DISCONNECTED: stateDescription = "disconnected"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_ASSOCIATING: stateDescription = "associating"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_DISCOVERING: stateDescription = "discovering"; break; case WLAN_INTERFACE_STATE.WLAN_INTERFACE_STATE_AUTHENTICATING: stateDescription = "authenticating"; break; } return stateDescription; } } }