在C++程序中开启和禁用Windows设备的无线网卡的方法
原文链接地址:https://www.jb51.net/article/81340.htm
1.列出当前网卡:SetupDiEnumDeviceInfo
2.找出当前无线网卡的名字(用natvie wifi api)
3.卸载\安装此驱动
问题:
log为:SetupDiSetClassInstallParams failed. -536870347
完整代码如下:
1 // ControlWirelessCard.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include <windows.h> 6 #include <SetupAPI.h> 7 #include <devguid.h> 8 #include <string> 9 #include <cfgmgr32.h> 10 #include <wlanapi.h> 11 #pragma comment(lib,"setupapi.lib") 12 #pragma comment(lib, "wlanapi.lib") 13 using namespace std; 14 15 wstring getWirelessNetworkCardName() 16 { 17 wstring wirelessName; 18 HANDLE hClient = NULL; 19 DWORD dwMaxClient = 2; // 20 DWORD dwCurVersion = 0; 21 DWORD dwResult = 0; 22 DWORD dwRetVal = 0; 23 int iRet = 0; 24 WCHAR GuidString[39] = {0}; 25 unsigned int i; 26 27 /* variables used for WlanEnumInterfaces */ 28 PWLAN_INTERFACE_INFO_LIST pIfList = NULL; 29 PWLAN_INTERFACE_INFO pIfInfo = NULL; 30 31 dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient); 32 if (dwResult != ERROR_SUCCESS) { 33 wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult); 34 return wirelessName; 35 } 36 37 dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); 38 if (dwResult != ERROR_SUCCESS) { 39 wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult); 40 return wirelessName; 41 } else { 42 PWLAN_AVAILABLE_NETWORK_LIST pWLAN_AVAILABLE_NETWORK_LIST = NULL; 43 dwResult = WlanGetAvailableNetworkList(hClient, &pIfList->InterfaceInfo[0].InterfaceGuid, 44 WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES, 45 NULL, &pWLAN_AVAILABLE_NETWORK_LIST); 46 if (dwResult != ERROR_SUCCESS) 47 { 48 printf("WlanGetAvailableNetworkList failed with error: %u\n",dwResult); 49 WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST); 50 return wirelessName; 51 } 52 53 for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) { 54 pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i]; 55 iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 56 sizeof(GuidString)/sizeof(*GuidString)); 57 58 wirelessName = pIfInfo->strInterfaceDescription; 59 } 60 } 61 return wirelessName; 62 } 63 64 BOOL changeStatus(DWORD NewStatus, DWORD SelectedItem, HDEVINFO hDevInfo) 65 { 66 LPTSTR lpszMsg = NULL; 67 HCURSOR hCursor = NULL; 68 try 69 { 70 SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)}; 71 SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 72 73 hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); 74 // Get a handle to the Selected Item. 75 if (!SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, &DeviceInfoData)) 76 { 77 wprintf(L"SetupDiEnumDeviceInfo failed. %d\n",GetLastError()); 78 throw lpszMsg; 79 } 80 81 // Set the PropChangeParams structure. 82 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 83 PropChangeParams.Scope = DICS_FLAG_GLOBAL; 84 PropChangeParams.StateChange = NewStatus; 85 86 if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData, (SP_CLASSINSTALL_HEADER *)&PropChangeParams, 87 sizeof(PropChangeParams))) 88 { 89 wprintf(L"SetupDiSetClassInstallParams failed. %d\n",GetLastError()); 90 throw lpszMsg; 91 } 92 // Call the ClassInstaller and perform the change. 93 if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&DeviceInfoData)) 94 { 95 wprintf(L"SetupDiCallClassInstaller failed. %d\n",GetLastError()); 96 throw lpszMsg; 97 } 98 SetCursor(hCursor); 99 return TRUE; 100 } 101 catch (TCHAR * pszError) 102 { 103 SetCursor(hCursor); 104 if (NULL != lpszMsg) 105 { 106 LocalFree((HLOCAL)lpszMsg); 107 } 108 return FALSE; 109 } 110 } 111 112 int _tmain(int argc, _TCHAR* argv[]) 113 { 114 LPTSTR lpszMsg = NULL; 115 try 116 { 117 /* 118 TCHAR * GUIDString = NULL; 119 GUID guid; 120 ZeroMemory(&guid, sizeof(GUID)); 121 GUIDString = _T("4d36e972-e325-11ce-bfc1-08002be10318"); 122 UuidFromString((unsigned char *)GUIDString, &guid); 123 */ 124 //GUID guid = getWirelessNetworkCardGUID(); 125 HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT); 126 //HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT); 127 if (INVALID_HANDLE_VALUE == hDevInfo) 128 { 129 wprintf(L"INVALID_HANDLE_VALUE"); 130 return -1; 131 } 132 133 DWORD i; 134 int Icount=0; 135 SP_DEVINFO_DATA DeviceInfoData; 136 ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); 137 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 138 139 for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i) 140 { 141 //Get DeviceInfo 142 LPTSTR buffer = NULL; 143 DWORD buffersize = 0; 144 DWORD Status, Problem; 145 BOOL bDisabled = FALSE; 146 while (!SetupDiGetDeviceRegistryProperty( 147 hDevInfo, 148 &DeviceInfoData, 149 SPDRP_DEVICEDESC, //Read the names of the designated card 150 NULL, 151 (PBYTE) buffer, 152 buffersize, 153 &buffersize) 154 ) 155 { 156 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) 157 { 158 if (buffer) LocalFree(buffer); 159 buffer=(LPTSTR)LocalAlloc(LPTR,buffersize); 160 } 161 else 162 { 163 wprintf(L"read network card failed!"); 164 } 165 } 166 167 std::wstring strEthernet = buffer; 168 //wprintf(L"the buffer is %ws\n",buffer); 169 170 wstring wirelessName = getWirelessNetworkCardName(); 171 if(wirelessName.empty()) 172 { 173 wprintf(L"wirelessName IS empty\n"); 174 return -1; 175 } 176 //wprintf(L"wirelessName is %ws\n",wirelessName); 177 178 if(wirelessName == buffer) 179 { 180 wprintf(L"Found the wireless card: %ws\n",wirelessName); 181 if (int i= CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS) 182 { 183 wprintf(L"CM_Get_DevNode_Status failed. %d\n",GetLastError()); 184 throw "failed\n"; 185 } 186 if (!((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem))) 187 { 188 bDisabled = FALSE; 189 } 190 if ((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem)) 191 { 192 bDisabled = TRUE; 193 } 194 if(bDisabled==FALSE) 195 { 196 wprintf(L"disable the network card\n"); 197 changeStatus(DICS_DISABLE, i, hDevInfo);//disable 198 } 199 if(bDisabled==TRUE) 200 { 201 wprintf(L"enable the network card\n"); 202 changeStatus(DICS_ENABLE, i, hDevInfo);// enable 203 } 204 } 205 } 206 return SetupDiDestroyDeviceInfoList(hDevInfo); 207 } 208 catch (TCHAR * pszError) 209 { 210 if (NULL != lpszMsg) 211 { 212 LocalFree((HLOCAL)lpszMsg); 213 } 214 return FALSE; 215 } 216 return 0;
一些常见错误解决
一、
从错误返回值入手。
-536870347,用windows自带计算器,选择程序员模式,将此十进制转换为16进制为E0000235.
用此错误号搜索,就是大名鼎鼎的32位程序跑在64位系统中报错。
虽然我用的64位win8下VS编译的程序,但是编译选项中仍然是WIN32程序。那么我们只需要修改成x64编译即可,操作如下。
BUILD-->Configuration Manager...-->找到要修改的project,将platform选择为x64.
如果没有,说明没有添加x64编译项,接着上面,在platform中选择<New...> -->New platform下选x64-->OK.
二、
编译64位程序,运行之。
仍然报错,返回值是5.ACCESS_DENIED.
权限不够,我们需要申请高权限。如下申请Admin权限:
你项目的Properties-->Linker-->Manifest File-->UAC Execution Level选requireAdministrator。
三、
继续运行。卸载无线网卡驱动成功。
但是上一篇的程序仍然有个问题,由于驱动卸载了,就不能用wlan api得到无线网卡名称,
所以程序加载无线网卡驱动就会失败。
我们可以用关键字“Wireless Network Adapter”来查找无线网卡,省掉使用wlan api那一步。