Reputation: 419
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
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
Reputation: 419
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_INFORMATION
as 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