玩转VC++ 实现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的状态。
果然,这一切都有了了断。


玩转VC++ 实现Wifi on与wifi off,布布扣,bubuko.com

玩转VC++ 实现Wifi on与wifi off

上一篇:Effective C++:条款35:考虑virtual函数以外的其他选择


下一篇:spring+struts2+ibatis整合