Hi all,
on Windows Vista I can use IoGetDeviceObjectPointer to get the Driver Device of an enumerated physical Driver Device Name.
RtlInitString(&string_name, &name_buffer[i]);
RtlAnsiStringToUnicodeString(&name, &string_name, TRUE);
function_status = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &pFile, &CPU_Driver_Device);
On Windows XP this request fails with the error STATUS_INVALID_DEVICE_REQUEST… but the OSR’s DeviceTree can get the DeviceObjectPointer. I have read here in the past that it’s possible to get the DeviceObject with the functions ObOpenObjectByName, ObQueryNameString and ObOpenObjectByPointer.
How do I include and use the ObOpenObjectByName function?
It would be great if anybody can help me out on this!
Best Wishes,
John
Does the target driver support IRP_MJ_CREATE? If not there’s not much you
can do. If it does, I’d set a breakpoint there and see if the create is
making it to the target.
-scott
–
Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com
Looking forward to seeing you at the next OSR Kernel Debugging Class April
6, 2009 in Portland, OR!
wrote in message news:xxxxx@ntdev…
> Hi all,
>
> on Windows Vista I can use IoGetDeviceObjectPointer to get the Driver
> Device of an enumerated physical Driver Device Name.
>
> RtlInitString(&string_name, &name_buffer[i]);
> RtlAnsiStringToUnicodeString(&name, &string_name, TRUE);
> function_status = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES,
> &pFile, &CPU_Driver_Device);
>
> On Windows XP this request fails with the error
> STATUS_INVALID_DEVICE_REQUEST… but the OSR’s DeviceTree can get the
> DeviceObjectPointer. I have read here in the past that it’s possible to
> get the DeviceObject with the functions ObOpenObjectByName,
> ObQueryNameString and ObOpenObjectByPointer.
>
> How do I include and use the ObOpenObjectByName function?
>
> It would be great if anybody can help me out on this!
> Best Wishes,
> John
>
>
Hello,
Sometimes the function IoGetDeviceObjectPointer fails to get the Device Object (because this function has some restrictions)
With the following code you can bypass this issue.
(if you know the driver name)
STRING string_driver_name;
UNICODE_STRING driver_name;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDirectory = NULL;
POBJECT_DIRECTORY pDirectoryObject = NULL;
NTSTATUS nt_status = UNKNOWN_STATUS;
// 1. get the unicode name of the driver
RtlInitString(&string_driver_name, &(name_buffer[0]));
RtlAnsiStringToUnicodeString(&driver_name, &string_driver_name, TRUE);
// 2. get the handle of the driver
InitializeObjectAttributes(&ObjectAttributes, &driver_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
nt_status = ObOpenObjectByName(&ObjectAttributes, NULL, KernelMode, NULL, 0x80000000, NULL, &hDirectory);
if (NT_SUCCESS(nt_status) == TRUE)
{
// 3 Get pointer of the driver from the driver handle
nt_status = ObReferenceObjectByHandle(hDirectory, FILE_ANY_ACCESS, NULL, KernelMode, &pDirectoryObject, NULL);
if (NT_SUCCESS(nt_status) == TRUE)
{
// 4 Get driver device object
PDRIVER_OBJECT driver_object = (PDRIVER_OBJECT)pDirectoryObject;
PDEVICE_OBJECT device_object_01 = driver_object->DeviceObject;
if (device_object_01 != NULL)
{
PDEVICE_OBJECT device_object_02 = device_object_01->NextDevice;
}
}
}
michi
aaaahhhhh…
“Restrictions” probably isn’t the right way to describe it. The device object has to be accessible, because IoGetDeviceObjectPointer basically just does a ZwCreateFile request for the named device.
The example provided by Michi relies on opening the driver object, and then traversing the chain of device objects owned by the driver object. That PRETTY MUCH works, but note that you’re running a singly linked list (headed in DriverObject->DeviceObject and linked through DeviceObject->NextDevice) without the necessary lock to that list. Which is not a good thing.
Better to figure out why IoGetDeviceObjectPointer isn’t working in the case you need,
Peter
OSR
@Peter
Do you mean protect/lock the list with KeRaiseIrql and KeLowerIrql ?
{
KIRQL OldIrql;
KeRaiseIrql(APC_LEVEL,&OldIrql); // raise irql too to protect the list from kernel APC access
{
… code …
}
KeLowerIrql(OldIrql); // adjust back the irql
}
michi
No… I mean that there’s an internal lock the I/O Manager uses to protect this list, and external drivers don’t have access to it. Consider what would happen if a Device Object were removed or added for this driver while you were attempting to traverse the list.
In other words, there’s no good way to make the code you posted “safe.” That’s WHY the I/O Manager provides you the function IoGetDeviceObjectPointer, instead of just saying “hey, look through the list that’s headed in the Driver Object.”
Peter
OSR
yes, you’re right 
IoGetDeviceObjectPointer give us the DeviceObject and we have to use ObDereferenceObject to free the pointer. The pointer is valid until we free it up with ObDereferenceObject.
If we read the pointer from the list, the pointer can be invalid on the next requests? we have no check Maybe we can use IoRegisterPlugPlayNotification to have a check; but I think using IoGetDeviceObjectPointer (and finding out the error why it is not working on XP) is the better way.
michi
Right! Glad you understand.
You can’t really use IoRegisterPlugPlayNotification, because you can’t be SURE you’d get the notification in time (you could, after all, be right in the midst of the list traversal process).
Peter
OSR
> RtlInitString(&string_name, &name_buffer[i]);
RtlAnsiStringToUnicodeString(&name, &string_name, TRUE);
I would never use any ANSI strings in Windows kernel code.
On Windows XP this request fails with the error STATUS_INVALID_DEVICE_REQUEST…
Then MJ_CREATE is not supported on this driver.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com