RDX
RDX

Reputation: 419

Get full Device Instance id in Windows Device Driver(WDF)

I'm using WDK 8.1 for customize windows driver.

I want to get Device instance id in WDF/KMDF driver,which is unique for each device.

Is it possible to get full Device instance id for attached PCI device?

Can anyone suggest possible way so that I can get Device Instance Id using KMDF.

Upvotes: 1

Views: 7802

Answers (3)

Jimm Chen
Jimm Chen

Reputation: 3777

Since Device-id and Instance-Id are utterly determined by the PDO driver, we can query the PDO for these information. This is explicitly stated in MSDN(IRP_MN_QUERY_ID).

So the code to query Instance-id is like this:

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
    }
}

If you'd like to query Device-id, just replace BusQueryInstanceID with BusQueryDeviceID.

I've verified this myself. It surely works on every version of Windows since Windows 2000.

[2017-06-27] Hmm, I realize a problem regarding two confusing terms: "Device instance id" and "Device instance path" are NOT the same thing. See this post of mine: How to get Device Instance Path from Windows kernel driver?

Upvotes: 2

Wei
Wei

Reputation: 11

Use WdfDeviceAllocAndQueryPropertyEx with DEVPKEY_Device_InstanceId

Upvotes: 1

RDX
RDX

Reputation: 419

  • Yes,it's possible to get full Device instance id (Device id + Instance id).This solutions works and another way may be there.According to my solution check below:
  • For example :from PCI\VEN_1000&DEV_0001&SUBSYS_00000000&REV_02\1&08

    Device id : VEN_1000&DEV_0001&SUBSYS_00000000&REV_02 and instance id = 1&08 (unique id)

  • First step is to get Device id as mentioned in question and after that open registry from specific path HKLM/SYSTEM/CurrentControlSet/Enum/PCI/{device-id} in this case.Use below functions.

  • Use ZwOpenKey and ZwQueryKey and ZwEnumerateKey(for enumeration purpose).This functions can give information about opened registry path.

  • For getting subkeys in ZwQueryKey function's second argument use KEY_BASIC_INFORMATIONas KEY_INFORMATION_CLASS .

  • After that find subkeys using ZwEnumerateKey call for finding subkeys.And after that close handle using ZwClose.

  • Take reference check this CODE, for finding subkeys enumeration operaion.

Upvotes: 3

Related Questions