【问题标题】:Why does SetupDiEnumDriverInfo give two version numbers for my driver为什么 SetupDiEnumDriverInfo 为我的驱动程序提供两个版本号
【发布时间】:2013-04-17 14:55:31
【问题描述】:

我正在尝试以编程方式获取驱动程序的版本号。这似乎是通过使用SetupDiEnumDriverInfo 来获得SP_DRVINFO_DATA 结构并检查DriverVersion field 来完成的。

以下代码有效,但为同一驱动程序返回两个不同版本。我的设备是一个自定义 USB 设备,只有一个 .sys 文件。只有一台设备连接到我的机器。我指定DIGCF_PRESENT 只查询当前连接设备的驱动程序。

int main(void)
{
    // Get the "device info set" for our driver GUID
    HDEVINFO devInfoSet = SetupDiGetClassDevs(
                              &GUID_DEVINTERFACE_USBSPI, NULL, NULL,
                              DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    // Cycle through all devices currently present
    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;

        // Build a list of driver info items that we will retrieve below
        if (!SetupDiBuildDriverInfoList(devInfoSet, 
                                        &devInfo, SPDIT_COMPATDRIVER))
            return -1; // Exit on error

        // Get all the info items for this driver 
        // (I don't understand why there is more than one)
        for (int j = 0; ; j++)
        {
            SP_DRVINFO_DATA drvInfo;
            drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
            if (!SetupDiEnumDriverInfo(devInfoSet, &devInfo, 
                                       SPDIT_COMPATDRIVER, j, &drvInfo))
                break;

            printf("Driver version is %08x %08x\n", 
                   (unsigned)(drvInfo.DriverVersion >> 32), 
                   (unsigned)(drvInfo.DriverVersion & 0xffffffffULL));
        }
    }

    SetupDiDestroyDeviceInfoList(devInfoSet);

    return 0;
}

在我的机器上打印:

Driver version is 00000000 000015d3
Driver version is 00020004 00000000

在朋友的机器上打印:

Driver version is 00020004 00000000
Driver version is 00020004 00000000

第二行与设备管理器报告的数字匹配。

免责声明:我之前问过similar question。这是一个关于为什么 SetupDiEnumDriverInfo 返回多个驱动程序版本的新问题。

【问题讨论】:

  • 是外循环还是内循环产生两个项目?该代码是否会为任何其他 USB 设备产生多个结果?您是否尝试过使用devcon findall * 检查是否实际上安装了两个驱动程序实例?
  • 抱歉含糊不清 - 它是产生两个项目的内部循环。其他设备也产生多个项目 - 混合了 1、2 和 3。devcon findall * 仅查找已安装驱动程序的单个实例。不管怎样,你给了我一个有用的方向。我会继续摆弄,可能会在今天晚些时候更新这个问题。谢谢。

标签: c++ c windows driver


【解决方案1】:

在编写代码时,所有可能的驱动程序都会被输出。尝试执行以下操作以仅过滤已安装的驱动程序:

SP_DEVINSTALL_PARAMS InstallParams;
if ( !SetupDiGetDeviceInstallParams( devInfoSet, &devInfo, &InstallParams ) )
{
   //Error
}
else
{
   InstallParams.FlagsEx |= DI_FLAGSEX_INSTALLEDDRIVER;
   if ( !SetupDiSetDeviceInstallParams( devInfoSet, &devInfo, &InstallParams) )
   {
      //Errror
   }
}

我在http://doxygen.reactos.org/df/db2/dll_2win32_2devmgr_2misc_8c_a1cd0b33c1785392a37689433dc99e482.html找到了这个

【讨论】:

  • 这看起来像是成功的答案。我现在不能轻易测试它。我会在某个时候发布更新。谢谢。
【解决方案2】:

我发现解决方案非常复杂: SetupDiBuildDriverInfoList、SetupDiEnumDriverInfo、SetupDiGetDeviceInstallParams、SetupDiSetDeviceInstallParams。

虽然安装了多个驱动程序,但还有另一个选项可以仅获取当前正在使用的驱动程序的版本。

SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfo, SPDRP_DRIVER, 
                                 NULL, (BYTE*)UnicodeBuf, BufferSize, NULL);

我在注册表中获取驱动程序路径,如下所示:

"{4D36E978-E325-11CE-BFC1-08002BE10318}\0000"

我将它加载到变量 s_DriverPath 中,然后直接从 HKEY_LOCAL_MACHINE 读取驱动程序版本:

CString s_RegPath = L"SYSTEM\\CurrentControlSet\\Control\\Class\\" + s_DriverPath;

“DriverVersion”键返回当前使用的驱动程序的版本。当您将驱动程序更新到较新版本时,Windows 会自动调整所有注册表项。所以这样你总能得到当前使用的驱动版本。

您可以阅读有关驱动程序的更多信息。条目“DriverDateData”是 8 个字节,其中包含驱动程序日期作为 FILETIME。所有这些信息都来自 INF 文件。

这适用于 Windows XP 到 Windows 10。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多