gpt4 book ai didi

c++ - 如何从 C++ 获取 Windows 上的驱动程序版本

转载 作者:可可西里 更新时间:2023-11-01 14:14:56 26 4
gpt4 key购买 nike

我正在寻找一种获取驱动程序版本号的编程方式。我想要设备管理器在设备的驱动程序属性中显示的相同编号。

背景:我有一个与某些自定义硬件对话的应用程序。自定义硬件的设备驱动程序在特定版本号之前存在已知错误。我希望应用程序检查驱动程序版本并在用户需要更新时警告用户。该应用程序在 Windows XP 和 7 上运行,并使用 C++ 编写。

我以前使用的技巧是直接从 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);

最佳答案

您错误地将 i 用作 SetupDiEnumDriverInfo 中的索引。对于每个驱动程序的每个驱动程序信息元素,这应该是一个内部循环。因此,您无法检索设备 #1 的驱动程序信息 #0。

不过,这并不能解释为什么设备 #0 的信息 #0 失败。为此,您必须查看 SetupDiEnumDriverInfo 的第二个参数。这是您设备的 SP_DEVINFO_DATA 结构,但您将其设置为 NULL。这将为您提供与设备类相关联的驱动程序列表,而不是设备。 IE。适用于具有类驱动程序的鼠标和 USB 内存棒。您的设备可能有供应商特定的驱动程序,因此您需要该特定设备的驱动程序。

关于c++ - 如何从 C++ 获取 Windows 上的驱动程序版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16032789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com