我如何获得一个驱动程序的版本在Windows上从C ++(How do I get the vers

2019-08-31 08:09发布

我在找一个纲领性的方式来获得驱动程序的版本号。 我想是设备管理器显示的设备驱动程序属性相同的号码。

背景:我有一个会谈到一些自定义硬件的应用程序。 自定义硬件设备驱动程序之前,一定版本号已知的bug。 我希望应用程序检查驱动程序版本,并警告用户,如果他们需要更新它。 该应用程序运行在Windows XP和7,并用C ++编写。

我用了以前的黑客是阅读的.sys直接从SYSTEM32 /驱动程序文件,并搜索直接“文件版本”。 这是不好的原因有很多。 特别地,它似乎需要在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);

Answer 1:

你错误地重用i作为指数SetupDiEnumDriverInfo 。 这应该是每驱动器每个驱动程序信息元素的内部循环。 其结果是,你无法检索驱动器信息#0#1设备。

不过,这并不能解释为什么对设备#0的INFO#0失败。 对于这一点,你必须看的第二个参数SetupDiEnumDriverInfo 。 这是一个SP_DEVINFO_DATA为您的设备结构,但你把它设置为NULL 。 这让你与设备类,而不是设备相关的驱动程序列表。 即小鼠和USB记忆棒,其中有类驱动程序的工作原理。 您的设备可能有一个供应商特定的驱动程序,所以您需要为特定设备的驱动程序。



文章来源: How do I get the version of a driver on Windows from C++