我正在寻找一种以编程方式获取驱动程序版本号的方法。我想要设备管理器在设备的驱动程序属性中显示的相同数字。
背景:我有一个与某些自定义硬件对话的应用程序。自定义硬件的设备驱动程序在某个版本号之前已知错误。我希望应用程序检查驱动程序版本并警告用户是否需要更新它。该应用程序在Windows XP和7上运行,并以C ++编写。
我之前使用的hack是直接从system32 / drivers读取.sys文件并直接搜索“FileVersion”。这很糟糕,原因很多。特别是它似乎需要Windows 7上的管理员权限。
我知道班级GUID和硬件ID(即“USB \ VID_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 = %d\n", GetLastError());
printf("Driver version is %08x %08x\n", 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 - %d\n", GetLastError()); // Still fails with "no more items"
}
SetupDiDestroyDeviceInfoList(devInfoSet);
答案 0 :(得分:3)
您错误地将i
重新用作SetupDiEnumDriverInfo
中的索引。这应该是每个驱动程序的每个驱动程序信息元素的内部循环。因此,您无法检索设备#1的驱动程序信息#0。
但是,这并不能解释为什么设备#0的信息#0失败。为此,您必须查看SetupDiEnumDriverInfo
的第二个参数。这是您设备的SP_DEVINFO_DATA
结构,但您将其设置为NULL
。这将获得与设备类关联的驱动程序列表,而不是设备。即适用于具有类驱动程序的鼠标和USB记忆棒。您的设备可能具有特定于供应商的驱动程序,因此您需要该特定设备的驱动程序。