Почему SetupDiEnumDriverInfo дает два номера версии для моего драйвера
Я пытаюсь получить номер версии драйвера программно. Кажется, что это делается с помощью 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
Вторая строка соответствует номеру, сообщенному диспетчером устройств.
Отказ от ответственности: я ранее задавал подобный вопрос. Это новый вопрос о том, почему SetupDiEnumDriverInfo возвращает более одной версии драйвера.
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
Я считаю решение очень сложным: 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.