Получить полный идентификатор экземпляра устройства в драйвере устройства Windows (WDF)
Я использую WDK 8.1 для настройки драйвера Windows.
Я хочу получить идентификатор экземпляра устройства в драйвере WDF / KMDF, который уникален для каждого устройства.
- ОС: Windows 7(x64 бит)
- Идентификатор экземпляра устройства: { идентификатор устройства} \ {идентификатор экземпляра}
- Существует запись реестра устройства в: HKLM / SYSTEM / CurrentControlSet / Enum / PCI /
- В разделе HKLM/SYSTEM/CurrentControlSet/Enum//PCI для каждого идентификатора устройства идентификатор экземпляра указан как Subkey.
- Используя WdfDeviceAllocAndQueryProperty и WdfMemoryGetBuffer, можно получить определенный идентификатор устройства, но теперь можно получить идентификатор конкретного экземпляра.
Можно ли получить полный идентификатор экземпляра устройства для подключенного устройства PCI?
Может кто-нибудь предложить возможный способ, чтобы я мог получить идентификатор экземпляра устройства с помощью KMDF.
3 ответа
- Да, возможно получить полный идентификатор экземпляра устройства (идентификатор устройства + идентификатор экземпляра). Это решение работает, и может существовать другой способ. В соответствии с моим решением проверьте ниже:
Например: из
PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02\1&08
Идентификатор устройства:
VEN_1000&DEV_0001&SUBSYS_00000000&REV_02
и идентификатор экземпляра =1&08
(уникальный идентификатор)Первый шаг - получить идентификатор устройства, как указано в вопросе, и после этого открыть реестр по указанному пути.
HKLM/SYSTEM/CurrentControlSet/Enum/PCI/{device-id}
в этом случае. Используйте ниже функции.Используйте ZwOpenKey и ZwQueryKey и ZwEnumerateKey(для целей перечисления). Эти функции могут предоставлять информацию об открытом пути реестра.
Для получения подключей в
ZwQueryKey
использование второго аргумента функцииKEY_BASIC_INFORMATION
какKEY_INFORMATION_CLASS
,После этого найдите подразделы, используя
ZwEnumerateKey
вызов для поиска подразделов. И после этого закройте дескриптор, используя ZwClose.Возьмите ссылку, проверьте этот КОД, чтобы найти операции перечисления подразделов.
Поскольку Device-id и Instance-Id полностью определяются драйвером PDO, мы можем запросить у PDO эту информацию. Это явно указано в MSDN ( IRP_MN_QUERY_ID).
Таким образом, код для запроса идентификатора экземпляра выглядит следующим образом:
void testGetInstanceId(WDFDEVICE wdfdevice)
{
DEVICE_OBJECT *pdo = WdfDeviceWdmGetPhysicalDevice(wdfdevice);
KEVENT ke;
KeInitializeEvent(&ke, NotificationEvent, FALSE);
IO_STATUS_BLOCK iosb = {};
PIRP Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pdo,
NULL, 0, NULL,
&ke, &iosb
);
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; // required initialize
PIO_STACK_LOCATION stack= IoGetNextIrpStackLocation(Irp);
stack->MinorFunction = IRP_MN_QUERY_ID;
stack->Parameters.QueryId.IdType = BusQueryInstanceID;
NTSTATUS nts = IoCallDriver(pdo, Irp);
if(nts==STATUS_PENDING)
{ // Normally, we will not meet this, bcz QueryId should not be a "slow" operation.
KeWaitForSingleObject(&ke, Executive, KernelMode, FALSE, NULL);
}
if(NT_SUCCESS(nts))
{
WCHAR *pInstanceId = (WCHAR*)iosb.Information;
DbgPrint("InstanceId = %ws\n", pInstanceId); // tested.
ExFreePool(pInstanceId); // IRP_MN_QUERY_ID require this
}
}
Если вы хотите запросить идентификатор устройства, просто замените BusQueryInstanceID
с BusQueryDeviceID
,
Я сам это проверил. Это, безусловно, работает на каждой версии Windows, начиная с Windows 2000.
[2017-06-27] Хм, я понимаю проблему, касающуюся двух запутанных терминов: "Идентификатор экземпляра устройства" и "Путь к экземпляру устройства" - это НЕ одно и то же. Смотрите мой пост: Как получить путь к экземпляру устройства из драйвера ядра Windows?
Использование WdfDeviceAllocAndQueryPropertyEx с DEVPKEY_Device_InstanceId