我如何从c++获得Windows上的驱动程序版本?
How do I get the version of a driver on Windows from C++
我正在寻找一种编程方式来获取驱动程序的版本号。我想要与设备管理器在设备的驱动程序属性中显示的数字相同。
背景:我有一个与一些自定义硬件对话的应用程序。自定义硬件的设备驱动程序在某个版本号之前有已知的错误。我希望应用程序检查驱动程序版本并警告用户,如果他们需要更新它。该应用程序运行在Windows XP和Windows 7上,使用c++编写。
我以前使用的一个hack是直接从system32/drivers读取。sys文件,并直接搜索"FileVersion"。这是不好的,原因有很多。特别是在Windows 7上,它似乎需要管理员权限。
我知道类GUID和硬件ID(即"USBVID_1234&PID_5678")。
应用程序目前使用SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces和SetupDiGetDeviceInterfaceDetail来获取"DevicePath"。然后使用该路径调用CreateFile来与驱动程序对话。
看起来我需要从某个地方获得SP_DRVINFO_DATA结构。我尝试了setupapi.h中的各种功能,例如SetupDiGetDeviceInterfaceDetail。以下是我尝试过的一些失败的代码:
int main(void)
{
HDEVINFO DeviceInfoSet = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_INTERFACE_DEVICE_DATA InterfaceDeviceData;
InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
// Cycle through all devices.
for (int i = 0; i < 32; i++)
{
if (!SetupDiEnumDeviceInterfaces(DeviceInfoSet, 0, (LPGUID)&GUID_DEVINTERFACE_USBSPI, i, &InterfaceDeviceData))
break;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
DWORD RequiredSize;
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, NULL, 0, &RequiredSize, NULL);
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, RequiredSize);
try
{
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL);
// Try to get the driver info. This part always fails with code
// 259 (ERROR_NO_MORE_ITEMS).
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER, i, &drvInfo))
printf("error = %dn", GetLastError());
printf("Driver version is %08x %08xn", drvInfo.DriverVersion >> 32, drvInfo.DriverVersion & 0xffffffff);
}
catch(...)
{
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
throw;
}
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return 0;
}
编辑 -我更新的代码现在看起来像这样:
HDEVINFO devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
// Cycle through all devices.
for (int i = 0; ; i++)
{
// Get the device info for this device
SP_DEVINFO_DATA devInfo;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(devInfoSet, i, &devInfo))
break;
// Get the first info item for this driver
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(devInfoSet, &devInfo, SPDIT_COMPATDRIVER, 0, &drvInfo))
printf("err - %dn", GetLastError()); // Still fails with "no more items"
}
SetupDiDestroyDeviceInfoList(devInfoSet);
您错误地重用i
作为SetupDiEnumDriverInfo
的索引。这应该是每个驱动程序的每个驱动程序信息元素的内部循环。因此,您无法检索设备#1的驱动程序信息#0。
但是,这并不能解释为什么设备#0的信息#0失败了。为此,你必须看SetupDiEnumDriverInfo
的第二个参数。这是您的设备的SP_DEVINFO_DATA
结构,但您将其设置为NULL
。那让你获得与设备类关联的驱动程序列表,而不是设备。也就是说,这适用于鼠标和USB棒,它们有类驱动程序。您的设备可能有特定于供应商的驱动程序,因此您需要该特定设备的驱动程序。
你问了一个几乎相同的问题,我只在这里贴出我的答案的链接:
为什么SetupDiEnumDriverInfo给出我的驱动程序的两个版本号
- Mongodb c++驱动程序:如何查询元素的数组
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 使用mongocxx驱动程序时包含头文件问题
- void*到驱动程序中的UnicodeString
- C++驱动程序看不到头文件
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 员工测试驱动程序数据结构
- 获取 OID(类型::b_oid)作为 MongoDB C++驱动程序中的字符串
- 如何在 c++ 中映射驱动程序?
- 在Visual Studio中单实例Qt应用程序版本5.11.1中,在所有其他窗口的顶部打开Qt MainWindow
- 如何在 cuda 中将 kd 树从主机复制到驱动程序
- Visual Studio 如何在内核模式驱动程序项目中使用C++标准库?
- 为什么我的驱动程序只读取部分字符串?
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 如何在C++中将OID_PM_WOL_PATTERN_LIST发送到NDIS驱动程序?
- C++ 创建 NdisProt 驱动程序的句柄
- 使用 mongo c++ 驱动程序查询嵌套的 BSON 文档
- Mongodb Cxx 驱动程序测试在发布版本中崩溃 [ 在调试中工作正常]
- 微筛选器驱动程序不阻止文件版本
- 我如何从c++获得Windows上的驱动程序版本?