代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
通过SetupAPI扫描/禁用/恢复设备
作者:
mousekitty
/ 发布于
2014/3/11
/
827
#include <stdafx.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include <TCHAR.H> #include <SetupAPI.h> #include <cfgmgr32.h>// cfgmgr32.h 在Microsoft Windows 2000 DDK 中. #include <regstr.h> #pragma comment(lib,"setupapi.lib") #define UNKNOWNDEVICE _T("<Unknown Device>") typedef struct _DEVICE_INFO { SP_DEVINFO_DATADevInfoData;//设备信息包括实例句柄和设备类的GUID DWORDDevID;//在此次全局的枚举中设备ID TCHAR*lpszDevName;//设备的名称 ULONGulDevNameLen;//设备名称的长度 BOOLbDisableable;//是否可以被禁用 BOOLbDisabled;//是否已经被禁用 struct _DEVICE_INFO*pNextDevInfo;//下一个结构块 } DEVICE_INFO,*LPDEVICE_INFO; DEVICE_INFODevInfo; //设备链表头 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_DATADevInfoData = {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)}; DWORDdwDevStatus,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)}; DWORDdwDevStatus,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)); } void GuidCopy(GUID guidSrc, GUID *guidDest) { guidDest->Data1 = guidSrc.Data1; guidDest->Data2 = guidSrc.Data2; guidDest->Data3 = guidSrc.Data3; memcpy(guidDest->Data4,guidSrc.Data4,8); } BOOL ConstructDeviceName(HDEVINFO DevInfoSet, PSP_DEVINFO_DATA DevInfoData, PVOID pBuffer, PULONG Length) { //尝试通过各种类型的设备描述获得其设备名称 if (!GetRegistryProperty( DevInfoSet, DevInfoData, SPDRP_FRIENDLYNAME ,//设备的现实名称 pBuffer, Length)) { if (!GetRegistryProperty( DevInfoSet, DevInfoData, SPDRP_DEVICEDESC ,//设备的描述 pBuffer, Length)) { if (!GetRegistryProperty( DevInfoSet, DevInfoData, SPDRP_CLASS ,//设备类名 pBuffer, Length)) { if (!GetRegistryProperty( DevInfoSet, DevInfoData, SPDRP_CLASSGUID ,//设备的GUID pBuffer, Length)) { //什么都没找到就返回UnknownDevice *Length = (lstrlen(UNKNOWNDEVICE)+1)*sizeof(TCHAR); *(LPTSTR *)pBuffer = (PCHAR)LocalAlloc(LPTR,*Length); _tcscpy(*(LPTSTR *)pBuffer,UNKNOWNDEVICE); } } } } return TRUE; } BOOL EnumDevices(HDEVINFO hDevInfo) { DWORD dwDevID ; //, dwStatus, dwProblem; SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)}; LPDEVICE_INFOpDevInfo, pPreDevInfo; TCHAR*DeviceName = NULL ; ULONGulNameLen = 256; pPreDevInfo = &DevInfo; //穷举每个设备 for(dwDevID = 0;SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData);dwDevID++) { //构造设备信息块 pDevInfo = (LPDEVICE_INFO)malloc(sizeof(DEVICE_INFO)); pDevInfo->pNextDevInfo = NULL; pDevInfo->DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); pDevInfo->ulDevNameLen; pDevInfo->DevID = dwDevID; GuidCopy(DevInfoData.ClassGuid,&pDevInfo->DevInfoData.ClassGuid); pDevInfo->DevInfoData.DevInst = DevInfoData.DevInst; pDevInfo->DevInfoData.Reserved = DevInfoData.Reserved; //这里有个问题,如果用设备信息块结构中的字符串指针 //SetupDiGetDeviceRegistyProperty函数就会返回数据无效,不知道为什么。 //所以下面只能在重新复制一遍了。 ConstructDeviceName(hDevInfo,&DevInfoData,&DeviceName,&ulNameLen); pDevInfo->ulDevNameLen = ulNameLen; pDevInfo->lpszDevName = (TCHAR *)malloc(ulNameLen*sizeof(TCHAR)); memcpy(pDevInfo->lpszDevName,DeviceName,ulNameLen); pDevInfo->bDisableable = IsDisableable(dwDevID, hDevInfo); pDevInfo->bDisabled = IsDisabled(dwDevID, hDevInfo); pPreDevInfo->pNextDevInfo = pDevInfo; pPreDevInfo = pDevInfo; } return FALSE; } int main(int argc, char* argv[]) { HDEVINFOhDevInfo = NULL ; LPDEVICE_INFO pDevInfo = NULL ; EnumNetCards() ; return 0 ; //返回设备信息 hDevInfo = SetupDiGetClassDevs(NULL,NULL,NULL,DIGCF_PRESENT|DIGCF_ALLCLASSES); DevInfo.DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DevInfo.ulDevNameLen = 256; DevInfo.pNextDevInfo = NULL; //枚举系统设备 EnumDevices(hDevInfo); pDevInfo = DevInfo.pNextDevInfo; while(pDevInfo) { //从系统设备中查找usb mass storage设备 TCHAR szDebugStr [512] = _T("") ; _stprintf(szDebugStr,"DevID : %d GUID:%x-%x-%x-%x%x%x%x%x%x%x%x DevInst : %x,DevName:%s IsDisableable:%d, IsDisabled:%d" ,pDevInfo->DevID ,pDevInfo->DevInfoData.ClassGuid.Data1 ,pDevInfo->DevInfoData.ClassGuid.Data2 ,pDevInfo->DevInfoData.ClassGuid.Data3 ,pDevInfo->DevInfoData.ClassGuid.Data4[0] ,pDevInfo->DevInfoData.ClassGuid.Data4[1] ,pDevInfo->DevInfoData.ClassGuid.Data4[2] ,pDevInfo->DevInfoData.ClassGuid.Data4[3] ,pDevInfo->DevInfoData.ClassGuid.Data4[4] ,pDevInfo->DevInfoData.ClassGuid.Data4[5] ,pDevInfo->DevInfoData.ClassGuid.Data4[6] ,pDevInfo->DevInfoData.ClassGuid.Data4[7] ,pDevInfo->DevInfoData.DevInst ,pDevInfo->lpszDevName ,pDevInfo->bDisableable ,pDevInfo->bDisabled); OutputDebugString(szDebugStr); printf( "Device name=%s\n", pDevInfo->lpszDevName ) ; pDevInfo = pDevInfo->pNextDevInfo; } SetupDiDestroyDeviceInfoList(hDevInfo); return 0 ; }
试试其它关键字
SetupAPI
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
mousekitty
贡献的其它代码
(
13
)
.
MouseClick事件触发右键菜单
.
通过SetupAPI扫描/禁用/恢复设备
.
利用WebService下载文件
.
遍历文件夹得到所有文件
.
写Windows服务
.
截屏(基于MFC)
.
截取Char[]
.
Java Socket多线程——服务器端
.
List和String互相转换
.
自定义函数Split
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3