VC++玩轉Native Wifi API 2---Wifi on與wifi off
有心栽花花不開,無心插柳柳成排。
今天要說的這個wifi on\off是在軟體層面控制無線網絡卡的開和關。
問題聽起來簡單,調查起來複雜,但解決起來卻也簡單。關鍵函式便是Native wifi api中的WlanSetInterface。其實這個API功能也是非
常強大的,我只用到其中控制wifi radio state的功能。官網文件在此。
函式原型:
DWORD WINAPI WlanSetInterface( _In_ HANDLE hClientHandle, _In_ const GUID *pInterfaceGuid, _In_ WLAN_INTF_OPCODE OpCode, _In_ DWORD dwDataSize, _In_ const PVOID pData, _Reserved_ PVOID pReserved );
重點說一下三個引數:
1. OpCode,指定要設定的引數。我們選擇wlan_intf_opcode_radio_state
2. DwDataSize,pData的size。傳入時用sizeof得到。
3. pData,radio state對應的data是WLAN_PHY_RADIO_STATE。
看看這個state結構體:
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.
State設定如下:
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, NULL, &dwCurVersion, &hClient); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult); return false; } dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult); return false; } WLAN_PHY_RADIO_STATE state; state.dwPhyIndex = 0; state.dot11SoftwareRadioState = dot11_radio_state_on; PVOID pData = &state; dwResult = WlanSetInterface(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid, 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 %d\n",dwResult); } return 0; }
後記:
其實幾個月前就要實現windows上的wifi on和off,問了許多人,發了許多帖子,最後都不了了之。之後的日子裡也發生了許多事。國內的
搜尋無果,加上google的無法使用,都對調查增加了些許難度。我們把重點先放到了native wifi api的幾個方法,見上一篇玩轉文章。但
那並不是我想要的。
原以為windows也會想android一樣,普通應用沒有許可權來控制wifi的開關呢,結果並不是這樣。這也宣告了之前我的判斷失誤。
直到今天,通過Bing發現了幾條線索。那是通過C#呼叫native wifi api的問題,裡面提及了之前並沒有重視的wlansetinterface。
Interface,在這裡我覺得可以理解成無線網絡卡。類似的WlanEnumInterfaces中實現的功能是羅列出當前無線網絡卡。
無線網絡卡的設定,其中有一項是radio的狀態。
果然,這一切都有了了斷。