在C++程序中开启和禁用Windows设备的无线网卡的方法
1.列出当前网卡:SetupDiEnumDeviceInfo
2.找出当前无线网卡的名字(用natviewifiapi)
3.卸载\安装此驱动
问题:
log为:SetupDiSetClassInstallParamsfailed.-536870347
完整代码如下:
//ControlWirelessCard.cpp:Definestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include<windows.h>
#include<SetupAPI.h>
#include<devguid.h>
#include<string>
#include<cfgmgr32.h>
#include<wlanapi.h>
#pragmacomment(lib,"setupapi.lib")
#pragmacomment(lib,"wlanapi.lib")
usingnamespacestd;
wstringgetWirelessNetworkCardName()
{
wstringwirelessName;
HANDLEhClient=NULL;
DWORDdwMaxClient=2;//
DWORDdwCurVersion=0;
DWORDdwResult=0;
DWORDdwRetVal=0;
intiRet=0;
WCHARGuidString[39]={0};
unsignedinti;
/*variablesusedforWlanEnumInterfaces*/
PWLAN_INTERFACE_INFO_LISTpIfList=NULL;
PWLAN_INTERFACE_INFOpIfInfo=NULL;
dwResult=WlanOpenHandle(dwMaxClient,NULL,&dwCurVersion,&hClient);
if(dwResult!=ERROR_SUCCESS){
wprintf(L"WlanOpenHandlefailedwitherror:%u\n",dwResult);
returnwirelessName;
}
dwResult=WlanEnumInterfaces(hClient,NULL,&pIfList);
if(dwResult!=ERROR_SUCCESS){
wprintf(L"WlanEnumInterfacesfailedwitherror:%u\n",dwResult);
returnwirelessName;
}else{
PWLAN_AVAILABLE_NETWORK_LISTpWLAN_AVAILABLE_NETWORK_LIST=NULL;
dwResult=WlanGetAvailableNetworkList(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,
NULL,&pWLAN_AVAILABLE_NETWORK_LIST);
if(dwResult!=ERROR_SUCCESS)
{
printf("WlanGetAvailableNetworkListfailedwitherror:%u\n",dwResult);
WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST);
returnwirelessName;
}
for(i=0;i<(int)pIfList->dwNumberOfItems;i++){
pIfInfo=(WLAN_INTERFACE_INFO*)&pIfList->InterfaceInfo[i];
iRet=StringFromGUID2(pIfInfo->InterfaceGuid,(LPOLESTR)&GuidString,
sizeof(GuidString)/sizeof(*GuidString));
wirelessName=pIfInfo->strInterfaceDescription;
}
}
returnwirelessName;
}
BOOLchangeStatus(DWORDNewStatus,DWORDSelectedItem,HDEVINFOhDevInfo)
{
LPTSTRlpszMsg=NULL;
HCURSORhCursor=NULL;
try
{
SP_PROPCHANGE_PARAMSPropChangeParams={sizeof(SP_CLASSINSTALL_HEADER)};
SP_DEVINFO_DATADeviceInfoData={sizeof(SP_DEVINFO_DATA)};
hCursor=SetCursor(LoadCursor(NULL,IDC_WAIT));
//GetahandletotheSelectedItem.
if(!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
{
wprintf(L"SetupDiEnumDeviceInfofailed.%d\n",GetLastError());
throwlpszMsg;
}
//SetthePropChangeParamsstructure.
PropChangeParams.ClassInstallHeader.InstallFunction=DIF_PROPERTYCHANGE;
PropChangeParams.Scope=DICS_FLAG_GLOBAL;
PropChangeParams.StateChange=NewStatus;
if(!SetupDiSetClassInstallParams(hDevInfo,&DeviceInfoData,(SP_CLASSINSTALL_HEADER*)&PropChangeParams,
sizeof(PropChangeParams)))
{
wprintf(L"SetupDiSetClassInstallParamsfailed.%d\n",GetLastError());
throwlpszMsg;
}
//CalltheClassInstallerandperformthechange.
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&DeviceInfoData))
{
wprintf(L"SetupDiCallClassInstallerfailed.%d\n",GetLastError());
throwlpszMsg;
}
SetCursor(hCursor);
returnTRUE;
}
catch(TCHAR*pszError)
{
SetCursor(hCursor);
if(NULL!=lpszMsg)
{
LocalFree((HLOCAL)lpszMsg);
}
returnFALSE;
}
}
int_tmain(intargc,_TCHAR*argv[])
{
LPTSTRlpszMsg=NULL;
try
{
/*
TCHAR*GUIDString=NULL;
GUIDguid;
ZeroMemory(&guid,sizeof(GUID));
GUIDString=_T("4d36e972-e325-11ce-bfc1-08002be10318");
UuidFromString((unsignedchar*)GUIDString,&guid);
*/
//GUIDguid=getWirelessNetworkCardGUID();
HDEVINFOhDevInfo=SetupDiGetClassDevs(&GUID_DEVCLASS_NET,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT);
//HDEVINFOhDevInfo=SetupDiGetClassDevs(&guid,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT);
if(INVALID_HANDLE_VALUE==hDevInfo)
{
wprintf(L"INVALID_HANDLE_VALUE");
return-1;
}
DWORDi;
intIcount=0;
SP_DEVINFO_DATADeviceInfoData;
ZeroMemory(&DeviceInfoData,sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
for(i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);++i)
{
//GetDeviceInfo
LPTSTRbuffer=NULL;
DWORDbuffersize=0;
DWORDStatus,Problem;
BOOLbDisabled=FALSE;
while(!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC,//Readthenamesofthedesignatedcard
NULL,
(PBYTE)buffer,
buffersize,
&buffersize)
)
{
if(GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
if(buffer)LocalFree(buffer);
buffer=(LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
wprintf(L"readnetworkcardfailed!");
}
}
std::wstringstrEthernet=buffer;
//wprintf(L"thebufferis%ws\n",buffer);
wstringwirelessName=getWirelessNetworkCardName();
if(wirelessName.empty())
{
wprintf(L"wirelessNameISempty\n");
return-1;
}
//wprintf(L"wirelessNameis%ws\n",wirelessName);
if(wirelessName==buffer)
{
wprintf(L"Foundthewirelesscard:%ws\n",wirelessName);
if(inti=CM_Get_DevNode_Status(&Status,&Problem,DeviceInfoData.DevInst,0)!=CR_SUCCESS)
{
wprintf(L"CM_Get_DevNode_Statusfailed.%d\n",GetLastError());
throw"failed\n";
}
if(!((Status&DN_HAS_PROBLEM)&&(CM_PROB_DISABLED==Problem)))
{
bDisabled=FALSE;
}
if((Status&DN_HAS_PROBLEM)&&(CM_PROB_DISABLED==Problem))
{
bDisabled=TRUE;
}
if(bDisabled==FALSE)
{
wprintf(L"disablethenetworkcard\n");
changeStatus(DICS_DISABLE,i,hDevInfo);//disable
}
if(bDisabled==TRUE)
{
wprintf(L"enablethenetworkcard\n");
changeStatus(DICS_ENABLE,i,hDevInfo);//enable
}
}
}
returnSetupDiDestroyDeviceInfoList(hDevInfo);
}
catch(TCHAR*pszError)
{
if(NULL!=lpszMsg)
{
LocalFree((HLOCAL)lpszMsg);
}
returnFALSE;
}
return0;
}
一些常见错误解决
一、
从错误返回值入手。
-536870347,用windows自带计算器,选择程序员模式,将此十进制转换为16进制为E0000235.
用此错误号搜索,就是大名鼎鼎的32位程序跑在64位系统中报错。
虽然我用的64位win8下VS编译的程序,但是编译选项中仍然是WIN32程序。那么我们只需要修改成x64编译即可,操作如下。
BUILD-->ConfigurationManager...-->找到要修改的project,将platform选择为x64.
如果没有,说明没有添加x64编译项,接着上面,在platform中选择<New...>-->Newplatform下选x64-->OK.
二、
编译64位程序,运行之。
仍然报错,返回值是5.ACCESS_DENIED.
权限不够,我们需要申请高权限。如下申请Admin权限:
你项目的Properties-->Linker-->ManifestFile-->UACExecutionLevel选requireAdministrator。
三、
继续运行。卸载无线网卡驱动成功。
但是上一篇的程序仍然有个问题,由于驱动卸载了,就不能用wlanapi得到无线网卡名称,
所以程序加载无线网卡驱动就会失败。
我们可以用关键字“WirelessNetworkAdapter”来查找无线网卡,省掉使用wlanapi那一步。