用SetupDi* 启用/禁用网卡

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <SetupAPI.h>
#include <cfgmgr32.h>   // cfgmgr32.h 在Microsoft Windows 2000 DDK 中.
#pragma comment(lib,"setupapi.lib")

BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo) ;

//////////////////////////////////////////////////////////////////////////
// 获得设备注册表中的内容
//////////////////////////////////////////////////////////////////////////
BOOL GetRegistryProperty( HDEVINFO DeviceInfoSet, 
                        PSP_DEVINFO_DATA DeviceInfoData, 
                        ULONG Property, 
                        PVOID Buffer, 
                        PULONG Length ) 
{ 
    while ( !SetupDiGetDeviceRegistryProperty( DeviceInfoSet, 
                                               DeviceInfoData, 
                                               Property, 
                                               NULL, 
                                               (BYTE *)*(TCHAR **)Buffer, 
                                               *Length, 
                                               Length)) 
    { 
        // 长度不够则重新分配缓冲区
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
        { 
            if (*(LPTSTR *)Buffer) 
                LocalFree(*(LPTSTR *)Buffer); 

            *(LPTSTR *)Buffer = (PCHAR)LocalAlloc(LPTR,*Length); 
        } 
        else 
        {
            return false; 
        }
    } 

    return (BOOL)(*(LPTSTR *)Buffer)[0]; 
} 

BOOL EnableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    return StateChange(DICS_ENABLE,dwDevID,hDevInfo);
}

BOOL DisableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    return StateChange(DICS_DISABLE,dwDevID,hDevInfo);
}

BOOL ControlDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    BOOL bCanDisable;
    bCanDisable = (IsDisableable(dwDevID,hDevInfo) && (!IsDisabled(dwDevID,hDevInfo)));
    if(bCanDisable)
        return DisableDevice(dwDevID,hDevInfo);
    else
        return EnableDevice(dwDevID,hDevInfo);
}



void EnumNetCards() 
{         
    
    DWORD Status, Problem; 
    LPTSTR Buffer = NULL; 
    DWORD BufSize = 0; 

    // 返回所有设备信息
    HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES) ; 

    if (INVALID_HANDLE_VALUE == hDevInfo )        
        return; 

    
    SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 

    
        

    //////////////////////////////////////////////////////////////////////////
    // 枚举设备
    //////////////////////////////////////////////////////////////////////////
    for ( DWORD DeviceId=0; 
        SetupDiEnumDeviceInfo( hDevInfo,DeviceId,&DeviceInfoData); 
        DeviceId++) 
    { 

        // 获得设备的状态
        if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst ,0) != CR_SUCCESS) 
            continue; 
                

        // 获取设备类名
        TCHAR szDevName [MAX_PATH] = _T("") ;
        if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize)) 
        {
            lstrcpyn( szDevName, Buffer, MAX_PATH ) ;            
        }


        if ( lstrcmp( szDevName, _T("Net") ) == 0 )            
        {             
            TCHAR szName [MAX_PATH] = _T("") ;
            if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize)) 
            {
                lstrcpyn( szName, Buffer, MAX_PATH ) ;
            }


            if ( lstrcmp( szName, _T("ROOT") ) != 0 )                
            { 

                if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize)) 
                {
                    lstrcpyn( szName, Buffer, MAX_PATH ) ;

                    // 获取设备描述
                    if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize)) 
                    {
                        
                        lstrcpyn( szName, Buffer, MAX_PATH ) ;

                        
                        if(ControlDevice(DeviceId,hDevInfo))
                        {
                            printf("Successful\n");
                        }
                        else 
                        {
                            printf("FAILED\n");        
                        }
                        
                    }                    
                }
            } 
        } 
    } 

    SetupDiDestroyDeviceInfoList(hDevInfo);
} 

BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_PROPCHANGE_PARAMS PropChangeParams;
    SP_DEVINFO_DATA        DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    SP_DEVINSTALL_PARAMS devParams;

    //查询设备信息
    if (!SetupDiEnumDeviceInfo( hDevInfo, dwDevID, &DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }

    //设置设备属性变化参数
    PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
    PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
    PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改的属性保存在所有的硬件属性文件
    PropChangeParams.StateChange = dwNewState;
    PropChangeParams.HwProfile = 0;


    //改变设备属性
    if (!SetupDiSetClassInstallParams( hDevInfo,
                                        &DevInfoData,
                                        (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
                                        sizeof(PropChangeParams)))
    {
        OutputDebugString("SetupDiSetClassInstallParams FAILED");
        return FALSE;
    }
    
    
    PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
    PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
    PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;//使修改的属性保存在指定的属性文件
    PropChangeParams.StateChange = dwNewState;
    PropChangeParams.HwProfile = 0;

    //改变设备属性并调用安装服务
    if (!SetupDiSetClassInstallParams( hDevInfo,
                                       &DevInfoData,
                                       (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
                                       sizeof(PropChangeParams)) ||
        !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DevInfoData))
    {
        OutputDebugString("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED");
        return TRUE;
    }
    else
    { 
        //判断是否需要重新启动
        devParams.cbSize = sizeof(devParams);
        if (!SetupDiGetDeviceInstallParams( hDevInfo, &DevInfoData, &devParams))
        {
            OutputDebugString("SetupDiGetDeviceInstallParams FAILED");
            return FALSE;
        }

        if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
        {
            OutputDebugString("Need Restart Computer");
            return TRUE;
        }
        return TRUE;
    }
}


BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    DWORD    dwDevStatus,dwProblem;
    if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }
    //查询设备状态
    if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
    {
        OutputDebugString("CM_GET_DevNode_Status FAILED");
        return FALSE;
    }
    return ((dwDevStatus & DN_DISABLEABLE) && (dwProblem != CM_PROB_HARDWARE_DISABLED));
}

BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    DWORD    dwDevStatus,dwProblem;
    if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }

    //查询设备状态
    if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
    {
        OutputDebugString("CM_GET_DevNode_Status FAILED");
        return FALSE;
    }
    return ((dwDevStatus & DN_HAS_PROBLEM) && (dwProblem == CM_PROB_DISABLED));
}

int main(int argc, char* argv[])
{        
    EnumNetCards() ;
    return 0 ;
}  

一个启用/禁用网卡的程序,在VC 6.0编译运行,需要安装windows DDK,更新VC库文件,安装windows SDK。

DDK与VC关联可以参考这里 http://zhidao.baidu.com/question/81623833

关于SDK在VC中配置参考这个http://blog.163.com/lwzy-crack/blog/static/95272042200972485152773/




SetupDiEnumDeviceInterfaces返回false WIN7/WIN8 The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set. BOOL SetupDiEnumDeviceInterfaces( _In_      HDEVINFO DeviceInfoSet, _In 阅读详情

相关推荐

SetupDiEnumDeviceInfo

枚举设备信息

CAir2的专栏 2400

Windows驱动SetupDi系列函数之枚举USB/PCIe设备

Windows开发过程中,有时候需要进行设备信息的管理,那么SetupDi系列函数能够满足你的要求。

Zander0的博客 5550

SetupDiEnumDeviceInfo-使用SetupDi系列函数进行设备信息的管理(二)

BOOLEAN    SetupDiEnumDeviceInfo(        IN HDEVINFO  DeviceInfoSet,        IN DWORD  MemberIndex,        OUT PSP_DEVINFO_DATA  DeviceInfoData        );   SetupDiEnumDeviceInfo  枚举指定设备信息集合的成员,并将数据放在

6019

关于SetupDiEnumDeviceInfo枚举设备返回false问题的解决办法

现象:我的程序中有个功能是要枚举设备。代码如下, 在XP 32位系统下运行没有问题,到Win7 64位系统时则不能枚举。调试发现SetupDiEnumDeviceInfo返回false。         public static List GetDeviceProperty(string portname) { List HWList = new Lis

小雷的学习空间 1万+

windows禁用启用网卡API

bool CNetCardStateSet::NetCardStateChange(bool Enabled, const char* dev_des) { //--------------------------------------------------------------------------- //功能:NetCardStateChange 网卡启用禁用 //参数:dev_des 是 设备描述,就是设备管理器显示的名称 //参数:Enabled true = 启用 false

woody218的博客 1618

禁用c语言,C语言辅导:用C语言实现禁用网卡的代码

#include#include#includevoid EnumDevices(HDEVINFO hDevInfo){SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};LPOLESTR guid;char devName[128];char instanceId[128];for (int i=0;SetupDiEnumDevi...

weixin_42102933的博客 272

Windows设备管理

熟悉Windows系统的都应该使用过设备管理器。设备管理器将操作系统中所有已安装的设备分类展现出来。同时提供了安装、卸载、启用禁用的功能。那么,我们应该如何通过C++编程的方式实现这种功能呢?答案很简单,那就是使用SetupDi函数族。

qq_38933606的博客 2078

SetupDiGetDeviceInstanceId获取ID的疑问

之前写获取usb的实例路径,运用setupdi**的api去实现 但是遍历盘符时用的函数是GetLogicalDriveStrings() 只能实现对类似C:\,D:\这样的盘符起作用,遇到像Apple iPad 就不能获取它的ID,所以重新看了看,用SetupDiGetDeviceInstanceId() 来实现ID的获取类似(USB\VID_****&PID_****\编号) 在

5738

Windows下枚举USB设备信息Demo

Windows开发过程中,有时候需要进行设备信息的管理,那么SetupDi系列函数能够满足你的要求。

mickey2007的博客 1484

函数 SetupDiEnumDeviceInterfaces 总返回false,ERRORCODE1784

主要原因应该是64位系统分配错误 其中定义SP_DEVICE_INTERFACE_DATA中int 类型更换为uint,并添加Pack =1,PACK=8应该是32位系统。这里我就解决了返回FALSE,错误代码1784的问题 [StructLayout(LayoutKind.Sequential,Pack =1)] public struct SP_DEVICE_INTERFACE_DATA { public uint cbSize; ...

1937

关于Windows下USB函数SetupDiEnumDeviceInfo()与SetupDiEnumDeviceInterfaces()的心得

笔者曾经意为  SetupDiEnumDeviceInterfaces()函数是枚举某一设备下的全部接口,因此代码中结合了SetupDiEnumDeviceInfo()。但实际调试时发现  SetupDiEnumDeviceInterfaces()并不和SetupDiEnumDeviceInfo()存在联系。参照https://msdn.microsoft.com/en-us/li

phmatthaus的专栏 2万+

USB设备的枚举

我最近在做一个操作USB设备的程序,但在打开设备时遇到了问题.步骤如下, 1.调用SetupDiGetClassDevs.这一部正常获得句柄 2.调用SetupDiEnumDeviceInterfaces,枚举设备.3.两次调用SetupDiGetDeviceInterfaceDetail,获取设备详细信息,设备名. 代码例子: #define MAX_SLOT_NUM

wdt3385的专栏 2295

windows下设备信息管理系列函数——用于设备枚举

usb设备枚举编程 IN HWND

tianshi_1988的专栏 3479

使用SetupDi系列函数进行设备信息的管理

 HDEVINFO hDevInfo;  SP_DEVINFO_DATA  DeviceInfoData;         int  bRet;  WCHAR   DeviceDriver[MAX_PATH]; WCHAR   DeviceName[MAX_PATH];  memset(&DeviceInfoData, 0 , sizeof(DeviceInfoData)); DeviceInfo

1507

VC++实现启用与停用设备

前些日子在研究USB设备,就顺便研究了一些如何在应用程序实现USB设备的启用与停用,然后稍微深入,于是有了本文。想要实现类似设备管理器的功能,其实也不是很难,无非就是调用一些API函数,就像本文描述的,采用的API函数就是SetupDi系列的函数。不过这类函数有很多,具体的请参见MSDN,而实现设备启用、停用仅需要用到的就只有5个函数:       SetupDiGetClassDevs   

jiangdf的专栏 6997

C# USB转串口编程 - 查找COM口

参考文档 https://www.cnblogs.com/catzhou/archive/2018/06/08/9156863.html 1. 新建类SetupAPI.cs,处理SetupAPI.dll对应的操作 a. API函数SetupDiGetClassDevs [DllImport("SetupAPI.dll")] public static extern IntPtr SetupDiGetClassDevs( ref Guid ClassGuid, [Marshal.

pq的博客 4987

函数 SetupDiEnumDeviceInterfaces 总返回false

在网上查了好多方法,返回值还是false,最后将主程序编译为32位后,获取到了连接设备列表。

淡淡的幸福 4322

SetupDiEnumDeviceInterfaces 返回259

禁用强制签名,再安装驱动,安装完成后,SetupDiEnumDeviceInterfaces返回值由0变为1.今天学习驱动开发时遇到SetupDiEnumDeviceInterfaces 返回259。由于网上很多说法都是旧的方式注册安装驱动程序。

rjc_lihui的专栏 628
上一篇: SetupDi* 启用与停用设备
下一篇: 参考文献中各字母的含义
eric422113
博客等级 码龄17年 11粉丝 1原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值