在C++程序中开启和禁用Windows设备的无线网卡的方法

1.列出当前网卡:SetupDiEnumDeviceInfo
2.找出当前无线网卡的名字(用natvie wifi api)
3.卸载\安装此驱动
问题:
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;
}

一些常见错误解决
一、
从错误返回值入手。
-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那一步。

(0)

相关推荐

  • 深入解析C++的WNDCLASS结构体及其在Windows中的应用

    WNDCLASS是一个由系统支持的结构,用来储存某一类窗口的信息,如ClassStyle,消息处理函数,Icon,Cursor,背景Brush等.也就是说,CreateWindow只是将某个WNDCLASS定义的窗体变成实例.要得到某一窗口的WNDCLASS数据,可以用GetClassLong(); RegisterClass()就是在系统注册某一类型的窗体.也就是将你提供的WNDCLASS数据注册为一个窗口类,在WNDCLASS.lpszClassName中定义该WNDCLASS的标识,无论C

  • C++ 学习之旅 Windows程序内部运行原理

    学习C++与.net不同的是,一定要搞清楚Windows程序内部运行原理,因为他所涉及大多数是操作系统的调用,而.net毕竟是在.netFrameWork上唱戏. 那Windows应用程序,操作系统,计算机硬件之间的相互关系究竟什么了,下面的图就给予很好的解释. 向下箭头①是 应用程序运行判断处理的结果,输出到输出的设备. 向上箭头②是输入设备,输入到操作系统中. 向下箭头③代表API,我们要解释以下API是什么.API是应用程序接口, 表示应用程序可以通知操作系统执行某个具体的动作,如操作系统

  • C++程序中使用Windows系统Native Wifi API的基本教程

    Windows应用想要实现连接wifi,监听wifi信号,断开连接等功能,用NativeWifi API是个不错的选择. 打开MSDN,搜索NativeWifi Api,找到Native Wifi页.在这里. 信息量很大,如果像我着急实现上述功能,看海量的文档有些来不及.如果直接给我例子,在运行中调试,阅读代码,效率会更高. 但是,我并没有成功.首先,Sample在SDK中,参见这里.我下载几次都失败了,最后放弃这条路.后来同事给了我一份Sample,我不敢确定是否就是这个,但是代码写的也是很晦

  • Visual C++程序设计中Windows GDI贴图闪烁的解决方法

    本文实例讲述了Visual C++程序设计中Windows GDI贴图闪烁的解决方法.分享给大家供大家参考.具体如下: 一般的windows 复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁. 先来谈谈闪烁产生的原因 原因一: 如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕 上只是写到了显存里,而显卡每隔一段时间把显存的内容输出到屏幕上,这就是刷新周期. 一般显卡的刷新周期是 1/80秒左右,具体数字可以自己设置的. 这样

  • 基于Windows C++ 应用程序通用日志组件的使用详解

    引言 在如何记录程序日志方面,通常有三种选择: 1.采用Log4CXX等公共开源日志组件:这类日志组件的特点是跨平台且功能比较强大,例如可以把日志发往另一台服务器或记录到数据库中等:另外,可配置性较高,可以通过配置文件或程序代码对日志进行很多个性化设置.但从另外一个角度看,由于这些优点往往也导致了在使用方面的缺点.首先,对于一般应用程序来说,它们并不需要太多的功能,通常只需要把日志记录到文件或反馈到应用程序,功能太多反正让用户使用起来觉得繁琐还得背负很多从来都用不到的代码.其次,这类日志组件通常

  • c++利用windows函数实现计时示例

    复制代码 代码如下: //Windows系统下可以用 time(),clock(),timeGetTime(),GetTickCount(),QueryPerformanceCounter()来对一段程序代码进行计时 #include <stdio.h>#include <windows.h>#include <time.h>                   //time_t time()  clock_t clock()    #include <Mmsys

  • 在C++程序中开启和禁用Windows设备的无线网卡的方法

    1.列出当前网卡:SetupDiEnumDeviceInfo 2.找出当前无线网卡的名字(用natvie wifi api) 3.卸载\安装此驱动 问题: log为:SetupDiSetClassInstallParams failed. -536870347   完整代码如下: // ControlWirelessCard.cpp : Defines the entry point for the console application. // #include "stdafx.h"

  • 微信小程序中使元素占满整个屏幕高度实现方法

    微信小程序中使元素占满整个屏幕高度实现方法 在项目中经常要用到一个容器元素占满屏幕高度和宽度,然后再在这个容器元素里放置其他元素. 宽度很简单就是width:100% 但是高度呢,我们知道的是height:100%必须是在父元素的高度给定了的情况下才可以. 以前我的做法是用js获取屏幕的高度,然后将其赋值给height, 屏幕高度在网页中为:window.innerHeight; 在微信小程序中则需要调用wx.getSystemInfo接口,然后通过setData赋值 但是显然通过js来进行的,

  • 微信小程序中使用自定义图标(阿里icon)的方法

    weui提供的图标比较少,有时我们需要更多的图标,可以使用以下方法自定义图标库: 1,到阿里巴巴矢量图标库(http://iconfont.cn/)生成自己的字体图标,下载代码,解压,打开iconfont.css 2,在wxss文件中引用字体 <style type="less"> @font-face { font-family: 'iconfont'; src: url(data:font/truetype;charset=utf-8;base64,AAEAAAANAI

  • 解析Java程序中对象内存的分配和控制的基本方法

    一.对象与内存控制的知识点 1.java变量的初始化过程,包括局部变量,成员变量(实例变量和类变量). 2.继承关系中,当使用的对象引用变量编译时类型和运行时类型不同时,访问该对象的属性和方法是有区别的. 3.final修饰符特性. 二.java变量的划分与初始化过程 java程序的变量大体可以分为成员变量和局部变量,成员变量可以分为实例变量(非静态变量)和类变量(静态变量),一般我们遇到的局部变量会在下列几种情况中出现: (1)形参:在方法签名中定义的局部变量,由调用方为其赋值,随着方法结束消

  • C#程序中session的基本设置示例及清除session的方法

    session的基本设置: using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.SessionState; namespace OAFrameWork { public class CSession { public static object Get(string Key) { return HttpContext.Current.Sessio

  • 深入解析Java并发程序中线程的同步与线程锁的使用

    synchronized关键字 synchronized,我们谓之锁,主要用来给方法.代码块加锁.当某个方法或者代码块使用synchronized时,那么在同一时刻至多仅有有一个线程在执行该段代码.当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段.但是,其余线程是可以访问该对象中的非加锁代码块的. synchronized主要包括两种方法:synchronized 方法.synchronized 块. synchron

  • c#中禁用windows的任务管理器的方法

    以前制作的桌面锁屏软件虽然也禁用过任务管理器,但是采取的是比较笨的方法,而且对操作系统还有一定的危害.因为任务管理也是一个窗体也就是说它中也是一个独立进程,所以只需要强制性关闭这个进程即可以关闭任务管理器了,任务管理的进程名称为"taskmgr",在程序用一个单独的计时器,每100毫秒遍历一次系统开启的所有的进程,但凡出现进程的名称与任务管理器名称相同直接关闭.这样就可以间接的达到禁用任务管理的作用,然而这种方法不能够常用,如果经常强制性的关闭任务管理的进程会错乱操作系统的消息处理.所

  • windows系统下,如何在C#程序中自动安装字体

    1.1.使用代码安装字体 注意:安装字体时,需要windows的管理员权限. [DllImport("kernel32.dll", SetLastError = true)] public static extern int WriteProfileString(string lpszSection, string lpszKeyName, string lpszString); [DllImport("gdi32")] public static extern i

  • MySQL在线开启或禁用GTID模式

    目录 基本概述 在线开启GTID 1. 设置GTID校验ENFORCE_GTID_CONSISTENCY为WARN 2. 设置GTID校验ENFORCE_GTID_CONSISTENCY为ON 3. 设置GTID_MODE为OFF_PERMISSIVE 4. 设置GTID_MODE为ON_PERMISSIVE 5. (关键点)确保匿名事务回放完毕 6. 触发一轮日志切换FLUSH LOGS 7. 正式开启GTID_MODE为ON 8. 修改配置文件确保GTID参数持久化 9. 修改复制模式为GT

  • “/”应用程序中的服务器错误和Server Error in ''/'' Application.的终极解决方法

    "/"应用程序中的服务器错误. 运行时错误 说明: 服务器上出现应用程序错误.此应用程序的当前自定义错误设置禁止远程查看应用程序错误的详细信息(出于安全原因).但可以通过在本地服务器计算机上运行的浏览器查看. 详细信息: 若要使他人能够在远程计算机上查看此特定错误信息的详细信息,请在位于当前 Web 应用程序根目录下的"web.config"配置文件中创建一个 <customErrors> 标记.然后应将此 <customErrors> 标记

随机推荐