1. 程式人生 > >VC++玩轉Native Wifi API 2---Wifi on與wifi off

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的狀態。
果然,這一切都有了了斷。