在C++程序中開啟和禁用Windows設(shè)備的無線網(wǎng)卡的方法
1.列出當(dāng)前網(wǎng)卡:SetupDiEnumDeviceInfo
2.找出當(dāng)前無線網(wǎng)卡的名字(用natvie wifi api)
3.卸載\安裝此驅(qū)動(dòng)
問題:
log為:SetupDiSetClassInstallParams failed. -536870347
完整代碼如下:
// ControlWirelessCard.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <SetupAPI.h>
#include <devguid.h>
#include <string>
#include <cfgmgr32.h>
#include <wlanapi.h>
#pragma comment(lib,"setupapi.lib")
#pragma comment(lib, "wlanapi.lib")
using namespace std;
wstring getWirelessNetworkCardName()
{
wstring wirelessName;
HANDLE hClient = NULL;
DWORD dwMaxClient = 2; //
DWORD dwCurVersion = 0;
DWORD dwResult = 0;
DWORD dwRetVal = 0;
int iRet = 0;
WCHAR GuidString[39] = {0};
unsigned int i;
/* variables used for WlanEnumInterfaces */
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 wirelessName;
}
dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);
return wirelessName;
} else {
PWLAN_AVAILABLE_NETWORK_LIST pWLAN_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("WlanGetAvailableNetworkList failed with error: %u\n",dwResult);
WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST);
return wirelessName;
}
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;
}
}
return wirelessName;
}
BOOL changeStatus(DWORD NewStatus, DWORD SelectedItem, HDEVINFO hDevInfo)
{
LPTSTR lpszMsg = NULL;
HCURSOR hCursor = NULL;
try
{
SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
// Get a handle to the Selected Item.
if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData))
{
wprintf(L"SetupDiEnumDeviceInfo failed. %d\n",GetLastError());
throw lpszMsg;
}
// Set the PropChangeParams structure.
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"SetupDiSetClassInstallParams failed. %d\n",GetLastError());
throw lpszMsg;
}
// Call the ClassInstaller and perform the change.
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&DeviceInfoData))
{
wprintf(L"SetupDiCallClassInstaller failed. %d\n",GetLastError());
throw lpszMsg;
}
SetCursor(hCursor);
return TRUE;
}
catch (TCHAR * pszError)
{
SetCursor(hCursor);
if (NULL != lpszMsg)
{
LocalFree((HLOCAL)lpszMsg);
}
return FALSE;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR lpszMsg = NULL;
try
{
/*
TCHAR * GUIDString = NULL;
GUID guid;
ZeroMemory(&guid, sizeof(GUID));
GUIDString = _T("4d36e972-e325-11ce-bfc1-08002be10318");
UuidFromString((unsigned char *)GUIDString, &guid);
*/
//GUID guid = getWirelessNetworkCardGUID();
HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT);
//HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT);
if (INVALID_HANDLE_VALUE == hDevInfo)
{
wprintf(L"INVALID_HANDLE_VALUE");
return -1;
}
DWORD i;
int Icount=0;
SP_DEVINFO_DATA DeviceInfoData;
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
{
//Get DeviceInfo
LPTSTR buffer = NULL;
DWORD buffersize = 0;
DWORD Status, Problem;
BOOL bDisabled = FALSE;
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC, //Read the names of the designated card
NULL,
(PBYTE) buffer,
buffersize,
&buffersize)
)
{
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
{
if (buffer) LocalFree(buffer);
buffer=(LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
wprintf(L"read network card failed!");
}
}
std::wstring strEthernet = buffer;
//wprintf(L"the buffer is %ws\n",buffer);
wstring wirelessName = getWirelessNetworkCardName();
if(wirelessName.empty())
{
wprintf(L"wirelessName IS empty\n");
return -1;
}
//wprintf(L"wirelessName is %ws\n",wirelessName);
if(wirelessName == buffer)
{
wprintf(L"Found the wireless card: %ws\n",wirelessName);
if (int i= CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS)
{
wprintf(L"CM_Get_DevNode_Status failed. %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"disable the network card\n");
changeStatus(DICS_DISABLE, i, hDevInfo);//disable
}
if(bDisabled==TRUE)
{
wprintf(L"enable the network card\n");
changeStatus(DICS_ENABLE, i, hDevInfo);// enable
}
}
}
return SetupDiDestroyDeviceInfoList(hDevInfo);
}
catch (TCHAR * pszError)
{
if (NULL != lpszMsg)
{
LocalFree((HLOCAL)lpszMsg);
}
return FALSE;
}
return 0;
}
一些常見錯(cuò)誤解決
一、
從錯(cuò)誤返回值入手。
-536870347,用windows自帶計(jì)算器,選擇程序員模式,將此十進(jìn)制轉(zhuǎn)換為16進(jìn)制為E0000235.
用此錯(cuò)誤號(hào)搜索,就是大名鼎鼎的32位程序跑在64位系統(tǒng)中報(bào)錯(cuò)。
雖然我用的64位win8下VS編譯的程序,但是編譯選項(xiàng)中仍然是WIN32程序。那么我們只需要修改成x64編譯即可,操作如下。
BUILD-->Configuration Manager...-->找到要修改的project,將platform選擇為x64.
如果沒有,說明沒有添加x64編譯項(xiàng),接著上面,在platform中選擇<New...> -->New platform下選x64-->OK.
二、
編譯64位程序,運(yùn)行之。
仍然報(bào)錯(cuò),返回值是5.ACCESS_DENIED.
權(quán)限不夠,我們需要申請(qǐng)高權(quán)限。如下申請(qǐng)Admin權(quán)限:
你項(xiàng)目的Properties-->Linker-->Manifest File-->UAC Execution Level選requireAdministrator。
三、
繼續(xù)運(yùn)行。卸載無線網(wǎng)卡驅(qū)動(dòng)成功。
但是上一篇的程序仍然有個(gè)問題,由于驅(qū)動(dòng)卸載了,就不能用wlan api得到無線網(wǎng)卡名稱,
所以程序加載無線網(wǎng)卡驅(qū)動(dòng)就會(huì)失敗。
我們可以用關(guān)鍵字“Wireless Network Adapter”來查找無線網(wǎng)卡,省掉使用wlan api那一步。
相關(guān)文章
深入探究協(xié)程在C++中的實(shí)現(xiàn)方式
協(xié)程可以被看作是計(jì)算機(jī)程序中的獨(dú)立功能塊,它們?cè)趫?zhí)行過程中能夠暫停和恢復(fù),與傳統(tǒng)的函數(shù)調(diào)用相比,協(xié)程更像是一種輕量級(jí)的線程,本文我們將深入探究協(xié)程在C++中的實(shí)現(xiàn)方式,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12
vc中SendMessage自定義消息函數(shù)用法實(shí)例
這篇文章主要介紹了vc中SendMessage自定義消息函數(shù)用法,以實(shí)例實(shí)行詳細(xì)講述了SendMessage的定義、原理與用法,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10
QT5實(shí)現(xiàn)簡單的TCP通信的實(shí)現(xiàn)
本文主要介紹了QT5實(shí)現(xiàn)簡單的TCP通信的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Assert(斷言實(shí)現(xiàn)機(jī)制深入剖析)
言前后最好空一格[編程風(fēng)格的問題,按你自已的喜好,適合自已就最好]。斷言只是用來檢查程序的邏輯正確性,不能代替條件替換。斷言比printf語句這種形式的打印好使2013-09-09
FFmpeg實(shí)現(xiàn)變速播放的兩種方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了FFmpeg中實(shí)現(xiàn)變速播放的兩種方法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下2023-07-07
C++的std::transform()的實(shí)現(xiàn)
在 C++ 標(biāo)準(zhǔn)庫中,std::transform() 是一個(gè)非常有用的算法函數(shù),它能夠?qū)⒔o定范圍中的每個(gè)元素進(jìn)行變換,并將變換后的結(jié)果存儲(chǔ)到另一個(gè)范圍中,本文就詳細(xì)的介紹一下具體用法,感興趣的可以了解一下2023-08-08
使用C語言的fork()函數(shù)在Linux中創(chuàng)建進(jìn)程的實(shí)例講解
這篇文章主要介紹了使用C語言的fork()函數(shù)在Linux中創(chuàng)建進(jìn)程的實(shí)例講解,fork在父進(jìn)程下創(chuàng)建出的子進(jìn)程可以與父進(jìn)程一起來多進(jìn)程運(yùn)行同一個(gè)程序,需要的朋友可以參考下2016-06-06

