Hi,
I am enumerating all device objects of a driver object using IoEnumerateDeviceObjectList. Further I wish to get some properties for each of those DOs using IoGetDeviceProperty, but that call can only be made to a PDO.
So I am planning to use IoGetLowerDeviceObject on each DO assuming a PDO will always return a NULL while a FDO won’t.
Is there a problem in this approach that I may be overseeing or any better approach possible? Thanks.
Regards,
Suresh
You assumption is not really the best because the device node might have lower filters.
First of all I believe that IoGetDeviceProperty is actually getting the info from the registry for whatever you are trying to query, but nevertheless you can use any DO in the stack of that PDO to query, because the IRP will eventually get to the PDO and then you will get your information.
The way you try to call, if the driver has N DOs that are part of different stacks or nodes then for you calling this should be OK for any of the DOs.
If you of course decide to be in a particular stack then you will know which is the PDO of course via the AddDevice routine.
Another thing from the way you ask the question you assume a DO can be a PDO or a FDO but it can also be just another filter, FiDO so don’t for get that, and with upper and lower filters your pbem gets even more complicated.
You could also roll your IRP and send the IRP_MN_QUERY_DEVICE_RELATIONS with TargetDeviceRelation as relations type and you should find the PDO as the first one in the list returned but better read the documentation actually of how this query works because it has more complications.
Well, I believe for a given stack the PDO is the bottom-most DO. Even for a lower filter, the IoGetLowerDeviceObject for that filter will give the PDO and not the other way round.
In the meantime I stumbled upon IoGetDeviceAttachmentBaseRef and probably this is the correct way of getting to the PDO, isn’t it?
>whatever you are trying to query, but nevertheless you can use any DO in the stack of that PDO to
query, because the IRP will eventually get to the PDO and then you will get your information.
No, it mandates the PDO and does not probably use IRPs.
You could also roll your IRP and send the IRP_MN_QUERY_DEVICE_RELATIONS with ?
TargetDeviceRelation
Yes, this is the documented way of finding a PDO below you.
–
Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com
> In the meantime I stumbled upon IoGetDeviceAttachmentBaseRef and probably this is the correct
way of getting to the PDO, isn’t it?
MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation is an official way
–
Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com
Just ask for a value in AddDevice and save it to your devext, then enumerate the saved values.
wrote in message news:xxxxx@ntdev…
> Hi,
>
> I am enumerating all device objects of a driver object using IoEnumerateDeviceObjectList. Further I wish to get some properties for each of those DOs using IoGetDeviceProperty, but that call can only be made to a PDO.
> So I am planning to use IoGetLowerDeviceObject on each DO assuming a PDO will always return a NULL while a FDO won’t.
> Is there a problem in this approach that I may be overseeing or any better approach possible? Thanks.
>
> Regards,
> Suresh
>
@Gabriel Bercea:
IoGetDeviceProperty will bugcheck if you give it non-PDO.
Thanks Maxim. Just wanted to note that neither the driver nor the DOs are my own. I am actually trying to query all PCI devices in the system, so I get hold of the PCI driver object, enumerate all its devices objects and now before sending IoGetDeviceProperty to each of them I want to ensure that the DO is actually a PDO.
From your response I get that sending MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation to each DO is the way.
Out of curiosity though, using IoGetDeviceAttachmentBaseRef or IoGetLowerDeviceObject looks so much straight forward. What problem they may give actually?
Is it system stability related or WHQL compliance? Thanks.
Why do this in kernel mode, if you have user-mode APIs of CM_xxx and SetupDiXxx to do this?
–
Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> Thanks Maxim. Just wanted to note that neither the driver nor the DOs are my own. I am actually trying to query all PCI devices in the system, so I get hold of the PCI driver object, enumerate all its devices objects and now before sending IoGetDeviceProperty to each of them I want to ensure that the DO is actually a PDO.
>
> From your response I get that sending MN_QUERY_DEVICE_RELATIONS/TargetDeviceRelation to each DO is the way.
>
> Out of curiosity though, using IoGetDeviceAttachmentBaseRef or IoGetLowerDeviceObject looks so much straight forward. What problem they may give actually?
> Is it system stability related or WHQL compliance? Thanks.
>
Well, I need this information in my AddDevice routine before creating my FDO. At this point I guess there is no channel open for communicating with a user mode component to get this information.
There is no supported way to iterate through all the devices in the system from kernel mode. Or a subset of all the devices in the system.
In the case of walking the driver’s object list, the PCI driver might choose to create a new device object while you’re walking the list. When that happens, crashes ensue.
The device you’re trying to query might be in the middle of building up or tearing down the device stack. You can’t synchronize with that because you’re not in the device stack (and you’re not PNP) so again it’s not particularly safe.
You might find a magical incantation that allows it to work today. In the world of the future it may blow up horribly.
There’s usually very little information a driver needs in AddDevice before creating its FDO. What is it that you need to find out from all the existing PCI devices before you even create a device object?
-p
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Tuesday, May 31, 2016 10:20 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Finding if given DO is a PDO or FDO
Well, I need this information in my AddDevice routine before creating my FDO. At this point I guess there is no channel open for communicating with a user mode component to get this information.
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>
Thanks Peter. Well, I need to continue with loading my driver only if a particular PCI device is ‘present’ in the system. So my plan is to iterate through all PDOs created by PCI driver and query device IDs to find the same.
I however don’t understand why IoEnumerateDeviceObjectList is not a ‘supported’ way. After all it is going to take a reference on each device object that it returns and so it can not disappear until I release that reference. At the least it is guaranteed to be present to fail my IoGetDeviceProperty if it is indeed in the middle of tearing down the stack.
Regards,
Suresh
An Ob ref does not guarantee state, just that the memory is still allocated. You could easily have a returned device which has not yet been reported to pnp, not yet initialized, or deleted in another thread right after the call returns to you. As Peter said, you have no way of knowing or synchronizing with the state of the pdo. If you want to change behavior based on the presence of the device, always load your driver, register for notifications on the interface the device driver for the pci device exposed and then turn on your magical behavior. Until notified, do nothing, be a no-op.
Sent from my Windows 10 phone
From: xxxxx@yahoo.commailto:xxxxx
Sent: Tuesday, May 31, 2016 8:47 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Finding if given DO is a PDO or FDO
Thanks Peter. Well, I need to continue with loading my driver only if a particular PCI device is ‘present’ in the system. So my plan is to iterate through all PDOs created by PCI driver and query device IDs to find the same.
I however don’t understand why IoEnumerateDeviceObjectList is not a ‘supported’ way. After all it is going to take a reference on each device object that it returns and so it can not disappear until I release that reference. At the least it is guaranteed to be present to fail my IoGetDeviceProperty if it is indeed in the middle of tearing down the stack.
Regards,
Suresh
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>
A device Object is a PDO iff it has a non NULL device node, so check:
BOOL IsPDO = DeviceObject->DeviceObjectExtension->DeviceNode != 0;
Thanks Doron, that makes it clear now!
Thanks Harald for the tip, but I guess accessing opaque members of a structure will be frowned upon.
You have no way of knowing if the DO will become a pdo in the future or if the pdo has just been deleted right after your check
Sent from my Windows 10 phone
From: xxxxx@live.commailto:xxxxx
Sent: Wednesday, June 1, 2016 1:57 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Finding if given DO is a PDO or FDO
A device Object is a PDO iff it has a non NULL device node, so check:
BOOL IsPDO = DeviceObject->DeviceObjectExtension->DeviceNode != 0;
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>
As doron pointed out, the reference to the object only means the memory won’t be freed. References do not provide mutual exclusion with any code in the PCI driver that might be modifying the list of device objects, or modifying the device objects themselves.
Can you load your driver as a filter on the PCI device that your driver is associated with? A lower PCI filter wouldn’t get in the way of the normal device drivers, and your driver would only be started when the PCI device was present.
Otherwise, as Doron mentioned, the right approach is for your driver to load, but to do nothing until you can have something else (say a user-mode service) scan the device tree, verify that your PCI device is present, and inform your driver.
-p
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Tuesday, May 31, 2016 8:47 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Finding if given DO is a PDO or FDO
Thanks Peter. Well, I need to continue with loading my driver only if a particular PCI device is ‘present’ in the system. So my plan is to iterate through all PDOs created by PCI driver and query device IDs to find the same.
I however don’t understand why IoEnumerateDeviceObjectList is not a ‘supported’ way. After all it is going to take a reference on each device object that it returns and so it can not disappear until I release that reference. At the least it is guaranteed to be present to fail my IoGetDeviceProperty if it is indeed in the middle of tearing down the stack.
Regards,
Suresh
—
NTDEV is sponsored by OSR
Visit the list online at: http:
MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:
To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>