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?