是否有Windows API可列出设备管理器中的设备驱动及安装日期、签名者信息?
嘿,刚好我之前折腾过这个需求!你用SetupDiGetClassDevs()拿到设备基础信息后,确实得搭配其他几个Windows API才能挖到驱动的安装日期、签名者这些细节,我给你梳理下具体的步骤和用到的接口:
1. 先枚举设备(衔接你已有的操作)
你已经通过SetupDiGetClassDevs()拿到了设备信息集合(HDEVINFO句柄),接下来要用SetupDiEnumDeviceInfo()逐个遍历设备,拿到每个设备对应的SP_DEVINFO_DATA结构体——这个结构体是后续所有操作的核心标识,一定要保存好。
2. 提取驱动安装日期、版本这类基础属性
用SetupDiGetDeviceRegistryProperty()就能直接读取这些属性,只需要指定对应的属性ID:
- 驱动安装日期:传
SPDRP_INSTALL_DATE,返回的是FILETIME格式数据,你需要自己调用FileTimeToSystemTime()转换成可读的日期字符串。 - 驱动版本号:传
SPDRP_DRIVER_VERSION,返回的是DWORD类型的版本值,拆解成主版本、次版本、修订号这些格式就行。
3. 获取驱动签名者信息
签名信息的获取要多走几步:
首先调用SetupDiGetDeviceDriverInfo(),传入之前的HDEVINFO和SP_DEVINFO_DATA,拿到SP_DRVINFO_DATA结构体,它包含了驱动的基本元信息。
接着用SetupDiGetDriverInfoDetail(),基于上面的SP_DRVINFO_DATA,获取SP_DRVINFO_DETAIL_DATA——这里面有驱动文件的具体路径(DrvFilePath字段)。
拿到驱动文件路径后,就可以用WinVerifyTrust() API来验证签名并提取签名者信息;另外也可以用GetFileVersionInfo()+VerQueryValue()组合读取文件的数字签名元数据,不过WinVerifyTrust()更适配驱动签名的场景。
简单的代码示例(C++伪代码)
// 假设你已经获取了HDEVINFO hDevInfo和SP_DEVINFO_DATA DeviceInfoData SP_DRVINFO_DATA drvInfoData = {0}; drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); // 获取驱动基础信息 if (SetupDiGetDeviceDriverInfo(hDevInfo, &DeviceInfoData, &drvInfoData, sizeof(drvInfoData), NULL)) { SP_DRVINFO_DETAIL_DATA drvDetailData = {0}; drvDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); // 获取驱动详细信息(包含文件路径) if (SetupDiGetDriverInfoDetail(hDevInfo, &DeviceInfoData, &drvInfoData, &drvDetailData, sizeof(drvDetailData), NULL)) { // 现在可以用drvDetailData.DrvFilePath去处理签名验证 // 调用WinVerifyTrust获取签名者信息 } } // 获取驱动安装日期 FILETIME installDate; if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_INSTALL_DATE, NULL, (PBYTE)&installDate, sizeof(installDate), NULL)) { SYSTEMTIME localTime; FileTimeToSystemTime(&installDate, &localTime); // 格式化localTime为"YYYY-MM-DD HH:MM:SS"这类可读格式 }
注意事项
- 所有SetupDi系列API需要包含头文件
setupapi.h,并链接setupapi.lib;WinVerifyTrust()需要wintrust.h和wintrust.lib。 - 部分接口(比如读取签名信息)需要管理员权限才能正常调用,记得让你的程序以管理员身份运行。
这样操作下来,就能拿到设备管理器里显示的那些驱动详细信息了,我之前做类似工具的时候亲测有效!
内容的提问来源于stack exchange,提问作者gajapathy p

