Получить полный идентификатор экземпляра устройства в драйвере устройства 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

Другие вопросы по тегам