I am trying catch a BDN (Bios Device Name) from PDO in a driver on Kernel Mode, but alwalys trigger a BSOD after call IoGetDevicePropertyData function, the PDO was created with IoGetDeviceObjectPointer.
First, if you are asking about a BSOD you should, at the minimum, include what the bugcheck code and bugcheck parameters were. Ideally your should paste the output from the debugger !analyze -v command.
You appear to be calling IoGetDevicePropertyData at DISPATCH_LEVEL, which is prohibited by the docs for IoGetDevicePropertyData.
KIRQL irql = KeRaiseIrqlToDpcLevel(); // <<<< why are you doing this?
DWORD size = 8;
UCHAR* data = (PUCHAR)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(UCHAR) * size, 'ONEL');
if (IoGetDevicePropertyData(pdo, &devPropKey, LOCALE_NEUTRAL, 0, 8, data, &size, &type) == STATUS_BUFFER_TOO_SMALL) {
The second call to IoGetDevicePropertyData is interesting in that it has at least three obvious bugs:
An error return will satisfy the if condition, STATUS_SUCCESS will branch to the else statement.
You hardcoded the data size to 8, instead of using the value of ‘size’, guaranteeing failure if 8 is not large enough.
You preset the output ‘type’ parameter to the value you expect, consequently you are going to pass the test for this value after ignoring the error return from the second call, due to defect (1).
You don't have a PDO. There is a device stack with an FDO layered on top of the PDO (with any number of filter DOs layered between the PDO and FDO and also above the FDO. You get a pointer to the device object that happens to be on the top of the stack of device objects.
You don’t have to walk down the stack manually. Send a irp mn query device relations/ targetdevicerelations to retrieve the pdo. Remember to Ob Deref the pdo upon success.