C++程序中使用Windows系统Native Wifi API的基本教程
Windows应用想要实现连接wifi,监听wifi信号,断开连接等功能,用NativeWifi API是个不错的选择。 打开MSDN,搜索NativeWifi Api,找到Native Wifi页。在这里。 信息量很大,如果像我着急实现上述功能,看海量的文档有些来不及。如果直接给我例子,在运行中调试,阅读代码,效率会更高。 看来还是自己动手吧。看相关API,如果不懂,就找有经验人的例子。 几经周折,终于实现我的需求。让我慢慢道来。 DWORD WINAPI WlanGetAvailableNetworkList( _In_ HANDLE hClientHandle,_In_ const GUID *pInterfaceGuid,_In_ DWORD dwFlags,_Reserved_ PVOID pReserved,_Out_ PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList ); 由可用列表便可以找到当前哪个AP正在连接,并显示信号强度。 bool isConnect = false; int numberOfItems = pWLAN_AVAILABLE_NETWORK_LIST->dwNumberOfItems; for(int i = 0; i <= numberOfItems; i++) { WLAN_AVAILABLE_NETWORK wlanAN = pWLAN_AVAILABLE_NETWORK_LIST->Network[i]; if(wlanAN.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) { Wprintf(WLAN signal is %s:%dn",wlanAN.strProfileName,wlanAN.wlanSignalQuality); isConnect = true; } } if(!isConnect){ wprintf("Wifi is disconnected!n");} 3.断开连接 DWORD WINAPI WlanDisconnect( _In_ HANDLE hClientHandle,_Reserved_ PVOID pReserved ); 代码演示在后面。 DWORD WINAPI WlanConnect( _In_ HANDLE hClientHandle,_In_ const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,_Reserved_ PVOID pReserved ); 但参数PWLAN_CONNECTION_PARAMETERS却是很复杂,只要有一个配错,连接就会失败。
还好我的需求还是蛮简单的,只要连接已有的profile的AP。那么我的工作就会有针对性的开展。挫折了好多天,每次都连接失败,原因是ERROR_INVALID_PARAMETER。 就在今天,我终于成功了。真是会者不难,难者不会啊。 看看连接参数的结构体: typedef struct _WLAN_CONNECTION_PARAMETERS { WLAN_CONNECTION_MODE wlanConnectionMode; LPCWSTR strProfile; PDOT11_SSID pDot11Ssid; PDOT11_BSSID_LIST pDesiredBssidList; DOT11_BSS_TYPE dot11BssType; DWORD dwFlags; } WLAN_CONNECTION_PARAMETERS,*PWLAN_CONNECTION_PARAMETERS; 为了实现我的要求,可以这样赋值: // #include "stdafx.h" #include <windows.h> #include <wlanapi.h> #include <objbase.h> #include <wtypes.h> #include <string> #include <stdio.h> #include <stdlib.h> // Need to link with Wlanapi.lib and Ole32.lib #pragma comment(lib,"wlanapi.lib") #pragma comment(lib,"ole32.lib") using namespace std; int listenStatus() { HANDLE hClient = NULL; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; DWORD dwResult = 0; DWORD dwRetVal = 0; int iRet = 0; WCHAR GuidString[39] = {0}; //Listen the status of the AP you connected. while(1){ Sleep(5000); PWLAN_INTERFACE_INFO_LIST pIfList = NULL;//I think wlan interface means network card PWLAN_INTERFACE_INFO pIfInfo = NULL; DWORD dwFlags = 0; dwResult = WlanOpenHandle(dwMaxClient,NULL,&dwCurVersion,&hClient); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanOpenHandle failed with error: %un",dwResult); return 1; } dwResult = WlanEnumInterfaces(hClient,&pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %un",dwResult); return 1; } else { wprintf(L"WLAN_INTERFACE_INFO_LIST for this systemn"); wprintf(L"Num Entries: %lun",pIfList->dwNumberOfItems); wprintf(L"Current Index: %lunn",pIfList->dwIndex); int i; for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) { pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i]; wprintf(L" Interface Index[%u]:t %lun",i,i); iRet = StringFromGUID2(pIfInfo->InterfaceGuid,(LPOLESTR) &GuidString,sizeof(GuidString)/sizeof(*GuidString)); if (iRet == 0) wprintf(L"StringFromGUID2 failedn"); else { wprintf(L" InterfaceGUID[%d]: %wsn",GuidString); } wprintf(L" Interface Description[%d]: %ws",pIfInfo->strInterfaceDescription); wprintf(L"n"); wprintf(L" Interface State[%d]:t ",i); switch (pIfInfo->isState) { case wlan_interface_state_not_ready: wprintf(L"Not readyn"); break; case wlan_interface_state_connected: wprintf(L"Connectedn"); break; case wlan_interface_state_ad_hoc_network_formed: wprintf(L"First node in a ad hoc networkn"); break; case wlan_interface_state_disconnecting: wprintf(L"Disconnectingn"); break; case wlan_interface_state_disconnected: wprintf(L"Not connectedn"); break; case wlan_interface_state_associating: wprintf(L"Attempting to associate with a networkn"); break; case wlan_interface_state_discovering: wprintf(L"Auto configuration is discovering settings for the networkn"); break; case wlan_interface_state_authenticating: wprintf(L"In process of authenticatingn"); break; default: wprintf(L"Unknown state %ldn",pIfInfo->isState); break; } } } } } int _tmain(int argc,_TCHAR* argv[]) { HANDLE hClient = NULL; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; DWORD dwResult = 0; DWORD dwRetVal = 0; int iRet = 0; /* variables used for WlanEnumInterfaces */ PWLAN_INTERFACE_INFO_LIST pIfList = NULL; PWLAN_INTERFACE_INFO pIfInfo = NULL; LPCWSTR pProfileName = NULL; LPWSTR pProfileXml = NULL; DWORD dwFlags = 0; pProfileName = argv[1]; wprintf(L"Information for profile: %wsnn",pProfileName); dwResult = WlanOpenHandle(dwMaxClient,&hClient); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanOpenHandle failed with error: %un",dwResult); return 1; } dwResult = WlanEnumInterfaces(hClient,&pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %un",dwResult); return 1; } else { dwResult = WlanDisconnect(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,NULL);//DISCONNECT FIRST if(dwResult != ERROR_SUCCESS) { printf("WlanDisconnect failed with error: %un",dwResult); return -1; } PWLAN_AVAILABLE_NETWORK_LIST pWLAN_AVAILABLE_NETWORK_LIST = NULL; dwResult = WlanGetAvailableNetworkList(hClient,WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,&pWLAN_AVAILABLE_NETWORK_LIST); if (dwResult != ERROR_SUCCESS) { printf("WlanGetAvailableNetworkList failed with error: %un",dwResult); WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST); return -1; } WLAN_AVAILABLE_NETWORK wlanAN = pWLAN_AVAILABLE_NETWORK_LIST->Network[0];//PLEASE CHECK THIS YOURSELF if(pProfileName == NULL) pProfileName = wlanAN.strProfileName; WLAN_CONNECTION_PARAMETERS wlanConnPara; wlanConnPara.wlanConnectionMode =wlan_connection_mode_profile ; //YES,WE CONNECT AP VIA THE PROFILE wlanConnPara.strProfile =pProfileName; // set the profile name wlanConnPara.pDot11Ssid = NULL; // SET SSID NULL wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure; //dot11_BSS_type_any,I do not need it this time. wlanConnPara.pDesiredBssidList = NULL; // the desired BSSID list is empty wlanConnPara.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK; //it works on my WIN78 dwResult=WlanConnect(hClient,&wlanConnPara,NULL); if (dwResult==ERROR_SUCCESS) { printf("WlanConnect success!n"); } else { printf("WlanConnect failed err is %dn",dwResult); } } listenStatus(); //LISTEN THE STATUS if (pProfileXml != NULL) { WlanFreeMemory(pProfileXml); pProfileXml = NULL; } if (pIfList != NULL) { WlanFreeMemory(pIfList); pIfList = NULL; } return dwRetVal; } ShellExecute( NULL,L"open",L"shell:::{21EC2020-3AEA-1069-A2DD-08002B30309D}::{38a98528-6cbf-4ca9-8dc0-b1e1d10f7b1b}",SW_SHOWNORMAL); 6.RSSI if (pBssEntry->wlanSignalQuality == 0) iRSSI = -100; else if (pBssEntry->wlanSignalQuality == 100) iRSSI = -50; else iRSSI = -100 + (pBssEntry->wlanSignalQuality/2); wprintf(L" Signal Quality[%u]:t %u (RSSI: %i dBm)n",j,pBssEntry->wlanSignalQuality,iRSSI); DWORD WINAPI WlanSetInterface( _In_ HANDLE hClientHandle,_In_ WLAN_INTF_OPCODE OpCode,_In_ DWORD dwDataSize,_In_ const PVOID pData,_Reserved_ PVOID pReserved ); 重点说一下三个参数: typedef struct _WLAN_PHY_RADIO_STATE { DWORD dwPhyIndex; DOT11_RADIO_STATE dot11SoftwareRadioState; DOT11_RADIO_STATE dot11HardwareRadioState; } WLAN_PHY_RADIO_STATE,*PWLAN_PHY_RADIO_STATE; Index设为0. typedef enum _DOT11_RADIO_STATE { dot11_radio_state_unknown,dot11_radio_state_on,dot11_radio_state_off } DOT11_RADIO_STATE,*PDOT11_RADIO_STATE; 与前几个API(比如wlanconnect)相比,这个函数的使用简单多了。全部源码如下: // ManageWirelessNetwork.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include <wlanapi.h> // Need to link with shell32.lib #pragma comment(lib,"shell32.lib") #pragma comment(lib,"wlanapi.lib") int _tmain(int argc,_TCHAR* argv[]) { DWORD dwResult = 0; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; HANDLE hClient = NULL; PWLAN_INTERFACE_INFO_LIST pIfList = NULL; PWLAN_INTERFACE_INFO pIfInfo = NULL; dwResult = WlanOpenHandle(dwMaxClient,dwResult); return false; } dwResult = WlanEnumInterfaces(hClient,dwResult); return false; } WLAN_PHY_RADIO_STATE state; state.dwPhyIndex = 0; state.dot11SoftwareRadioState = dot11_radio_state_on; PVOID pData = &state; dwResult = WlanSetInterface(hClient,wlan_intf_opcode_radio_state,sizeof(WLAN_PHY_RADIO_STATE),pData,NULL); if(dwResult == ERROR_SUCCESS) { wprintf(L"set state success!n"); } else { wprintf(L"set state failed!err is %dn",dwResult); } return 0; } 8.GOTO在释放资源时的作用 // ManageWirelessNetwork.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include <wlanapi.h> // Need to link with shell32.lib #pragma comment(lib,_TCHAR* argv[]) { DWORD dwResult = 0; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; HANDLE hClient = NULL; PWLAN_INTERFACE_INFO_LIST pIfList = NULL; PWLAN_INTERFACE_INFO pIfInfo = NULL; dwResult = WlanOpenHandle(dwMaxClient,&hClient); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanOpenHandle failed with error: %un",dwResult); return false; } dwResult = WlanEnumInterfaces(hClient,&pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %un",dwResult); goto RELEASE_RESOURCE; } WLAN_PHY_RADIO_STATE state; state.dwPhyIndex = 0; state.dot11SoftwareRadioState = dot11_radio_state_on;//off here too. PVOID pData = &state; dwResult = WlanSetInterface(hClient,NULL); if(dwResult == ERROR_SUCCESS) { wprintf(L"set state success!n"); } else { wprintf(L"set state failed!err is %dn",dwResult); } RELEASE_RESOURCE: if(hClient) { WlanCloseHandle(hClient,NULL); hClient = NULL; } if(pIfList) { WlanFreeMemory(pIfList); pIfList = NULL; } if(pIfInfo) { WlanFreeMemory(pIfInfo); pIfInfo = NULL; } return 0; } 最后,goto还会用来跳出多重循环。但需要注意的是,只能从内层跳到外层,不可逆操作。 后记: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |