使用SetupDI* API列举系统中的设备
原文链接地址:https://blog.csdn.net/clteng/article/details/801012?utm_source=blogxgwz8
在Windows系统中提供一组有用的函数来撷取以安装设备(Device)的信息与增加或解除设备(Device)的安装。在本文中,我将显示如何使用SetupDIXXX与CM_XXX 等API来列举本机上的设备。
在范例程序中并无复杂的画面,只有一个简单的TreeView与ListView控件。TreeLivew控件用来显示所有安装的设备名称,ListView控件则用来显示在TreeView控件中所指定项目的相关信息。所有设备的相关信息(例如:名称,资源与图示等)都是从SetupDiXXX API中所取得的。
SetupDiXXX
设定安装程序接口(Setup Application Programming Interface)提供一组函数来让您的设定安装程序能执行安装的动作或取得设备的相关信息,类别(Class)与它的GUID值。
首先要取的所列举的设备的位图(Bitmap),我们可以呼叫以下的函数:
WINSETUPAPI BOOL SetupDiGetClassImageList(
PSP_CLASSIMAGELIST_DATA ClassImageListData
);
呼叫这个函数会取得每一个已安装设备的位图并建立位图串行。
BOOL SetupDiDestroyDeviceInfoList(
HDEVINFO DeviceInfoSet
);
呼叫这个函数会释放之前呼叫SetupDiGetClassImageList所占有的资源。
WINSETUPAPI BOOL SetupDiGetClassImageIndex(
PSP_CLASSIMAGELIST_DATA ClassImageListData,
const GUID *ClassGuid,
PINT ImageIndex
);
呼叫这个函数会取得每一个已安装设备的位图的索引值。
hDevInfo = SetupDiGetClassDevs(0L, 0L, _hDlg, DIGCF_PRESENT |
DIGCF_ALLCLASSES | DIGCF_PROFILE);
取得设备的信息。首次呼叫时,第一个参数与第二个参数将它们设为”0”,而第三个参数则设定DIGCF_ALLCLASSES旗标,设定此旗标代表要取得所有设备的信息。如果有设定此旗标此时第一个参数将会被忽略。
Geting the Info
呼叫SetupDiEnumDeviceInfo来列举本机上所有的设备。
SetupDiEnumDeviceInfo(hDevInfo, wIndex, &spDevInfoData))
第一个参数为之前呼叫SetupDiGetDevs函数所传回的代码(Handle)。第二个参数为以”0”为基底的索引值,第三个参数为指向SP_DEVINFO_DATA结构的指针。使用此结构时须先设定结构大小。
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiGetDeviceRegistryProperty(hDevInfo,
&spDevInfoData,
// Supplies one of the following values, indicating the property to be retrieved.
SPDRP_CLASS,
0L,
(PBYTE)szBuf,
,
);
呼叫SetupDiGetDeviceRegistreProperty函数从Registry中取得设备名称。第三个参数为指定要取得何种信息。
Device Resource
在系统中所有的设备会与类别设备结合在一起。请参下图。这个类别可以是GUID(可以在Registry中寻获)或是设备的描述。例如:”Ports”类别是描述(COM与LPT)。
要取得目前的设备的结构(Configuartion)我们可以呼叫CM_Get_First_Log_Conf函数来取得。然后呼叫CM_Get_Next_res_Des来取得目前设备结构的描述,重复呼叫直到浏览完所有的结构为止。
当此函数成功执行后,我们接着呼叫CM_Get_Res_Des_Data函数来取的资源的数据。
要安装驱动程序,我们可以透过Service API来达成,如果要安装WDM的程序,此时呼叫SetupDiGetINFClass函数先取得此驱动的GUID值,在呼叫SetupDiCreateDeviceInfoList来建立一个新的设备。如下列片断程序代码:
     if (!SetupDiGetINFClass(szINFName, &guid, className, MAX_CLASS_NAME_LEN, )){
         ShowErrorMsg(_hDlg, GetLastError(), "SetupDiGetINFClass");
         return ;
     };
     hDevInfo = SetupDiCreateDeviceInfoList(&guid, );
     if (hDevInfo == (void*)-) {
         ShowErrorMsg(_hDlg, GetLastError(), "SetupDiCreateDeviceInfoList");
         return ;
     };
     spDevData.cbSize = sizeof(SP_DEVINFO_DATA);
     if (!SetupDiCreateDeviceInfo(hDevInfo,
                                  className,
                                  &guid,
                                  0L, 0L, DICD_GENERATE_ID,
                                  &spDevData))
                          .
                          .
                          .
接下来我们要呼叫SetupDiSetDeviceRegistryProperty函数来设定Registry中的内容。设定完成后,呼叫SetupDiCallClassInstaller函数依据Registry的内容来安装驱动程序。最后呼叫UpdateDriverForPlugAndPlayDevices函数来更新设备串行的内容。
if (!SetupDiSetDeviceRegistryProperty(hDevInfo,
&spDevData,
SPDRP_HARDWAREID,
(PBYTE)pHID,
(strlen(_szHardware[wLoop])**sizeof(char)))) {
ShowErrorMsg(_hDlg, GetLastError(), "SetupDiSetDeviceRegistryProperty");
SetupDiDestroyDeviceInfoList(hDevInfo);
LocalFree(pHID);
return ;
};
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
hDevInfo, &spDevData)) {
ShowErrorMsg(_hDlg, GetLastError(), "SetupDiCallClassInstaller");
SetupDiDestroyDeviceInfoList(hDevInfo);
LocalFree(pHID);
return ;
};
bRebootRequired = ;
if (!UpdateDriverForPlugAndPlayDevices(0L, _szHardware[wLoop],
.
.
.
使用SetupDI* API列举系统中的设备的更多相关文章
- Linux系统中存储设备的两种表示方法
		
转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...
 - Web系统中Mic设备的应用实例
		
>>>>>>>>>>>>>>>>>>>>>>>>> ...
 - 重新指派usb转串口模块在linux系统中的设备调用名称
		
How to remap /dev/ttyUSB* to a specific name to be called by my program. How to map /dev/ttyUSB* to ...
 - 【转载】取得系统中网卡MAC地址的三种方法
		
From:http://blog.csdn.net/zhangting1987/article/details/2732135 网卡地址这个概念有点混淆不清.因为实际上有两个地址,mac地址和物理地址 ...
 - ASP.NET Web API路由系统:路由系统的几个核心类型
		
虽然ASP.NET Web API框架采用与ASP.NET MVC框架类似的管道式设计,但是ASP.NET Web API管道的核心部分(定义在程序集System.Web.Http.dll中)已经移除 ...
 - ASP.NET Web API路由系统:Web Host下的URL路由
		
ASP.NET Web API提供了一个独立于执行环境的抽象化的HTTP请求处理管道,而ASP.NET Web API自身的路由系统也不依赖于ASP.NET路由系统,所以它可以采用不同的寄宿方式运行于 ...
 - Fedora 手动删除系统中不再需要的包
		
最新文章:Virson‘s Blog 1.安装yum-utils yum install yum-utils 2.使用package-cleanup --leaves列举系统中不再需要的包 packa ...
 - Windows下USB磁盘开发系列二:枚举系统中所有USB设备
		
上篇 <Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>介绍了很简单的获取系统U盘盘符的办法,现在介绍下如何枚举系统中所有USB设备(不光是U盘). 主要调用的API如下: 1 ...
 - Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息
		
前面我们介绍了枚举系统中的U盘盘符(见<Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>).以及获取USB设备的信息(见<Windows下USB磁盘开发系列二:枚举系统中 ...
 
随机推荐
- 【MySQL函数】MySQL 5.5从零开始学第六章
			
说明:本文总结自:<MySQL 5.5从零开始学>第六章 MySQL中的函数包括: 数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数和加密函数等. 函数: 表示对输入参数值 ...
 - 第三篇 Python关于mysql的API--pymysql模块, mysql事务
			
python关于mysql的API--pymysql模块 pymysql是Python中操作MySQL的模块,其使用方法和py2的MySQLdb几乎相同. 模块安装 pip install pymys ...
 - 生成dataset的几种方式
			
1.常用的方式通过sparksession读取外部文件或者数据生成dataset(这里就不讲了) 注: 生成Row对象的方法提一下:RowFactory.create(x,y,z),取Row中的数据 ...
 - 当git遇上中文乱码
			
git有个比较奇怪的问题,当目录或者文件名中出现了中文的时候,在执行git status 的时候,会返回一串unicode码,这段unicode码就读不懂了,必须解决. git status显示uni ...
 - Python os.makedirs() 方法
			
os.makedirs() 方法用于递归创建目录.像 mkdir(), 但创建的所有intermediate-level文件夹需要包含子目录. 语法 makedirs()方法语法格式如下: os.ma ...
 - Kafka安装之三 spring-kafka实践
			
一.spring-kafka配置详解 1.1 要是用spring-kafka 我们首先要在pom要.xml中引入spring-kafka包 <dependencies> <depen ...
 - 使用 Mesos 管理虚拟机
			
摘要 为了满足渲染.基因测序等计算密集型服务的需求,UCloud 推出了“计算工厂”产品,让用户可以快速创建大量的计算资源(虚拟机).该产品的背后,是一套基于 Mesos 的计算资源管理系统.本文简要 ...
 - netty初认识
			
Netty是什么? 本质:JBoss做的一个Jar包 目的:快速开发高性能.高可靠性的网络服务器和客户端程序 优点:提供异步的.事件驱动的网络应用程序框架和工具 通俗的说:一个好使的处理Socket的 ...
 - Alpha发布用户使用报告
			
此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2325] 组名:可以低头,但没必要 组长:付佳 组员:张俊余 李文涛 孙 ...
 - CS小分队第二阶段冲刺站立会议(5月29日)
			
昨日成果:昨天在为主界面设计自主添加应用快捷方式功能,连续遇到困难. 遇到的困难:1.string字符串数组无法在单击事件中使用,提示string无法在eventargs中检索,尝试了各种方式都不行 ...