IoGetDeviceProperty requires a PDO, not all devices returned by IoEnumerateDeviceObjectList will be a PDO. Passing a non PDO to IoGetDeviceProperty can cause a bugcheck (esp with DV or a chk kernel) or undefined behavior. For each device passed in that list, you need to send a IRP_MJ_PNP/IRP_MN_QUERY_DEVICE_RELATIONS(TargetDeviceRelations) to get the PDO first. Also, mind you that just b/c you have the list of devices does not meant the state of those devices will remain the same. God knows how pci would handle you sending query device relations or a QI to a PDO it just deleted.
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mark Fontana
Sent: Thursday, February 11, 2010 6:14 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Accessing PCI Config Space for another device.
On Thu, 2010-02-11 at 19:05 -0500, xxxxx@hotmail.com wrote:
If you have a Device Object of the bridge it would be easy. The
problem is getting this Device Object. You need a filter for the
bridge. In this case you could get the Device Object. And after that
you could have access to PCI Configuration of the bridge.
One way to obtain PCI device objects without a filter is as follows:
First, get the driver object of Windows’ PCI driver:
UNICODE_STRING uszName;
PDRIVER_OBJECT pci_do;
RtlInitUnicodeString(&uszName, L"\Driver\PCI");
ObReferenceObjectByName(&uszName,
OBJ_CASE_INSENSITIVE,
NULL,
0,
*IoDriverObjectType,
KernelMode,
NULL,
(PVOID *) &pci_do);
Use it to enumerate the device objects of all the PCI devices in the
system by calling IoEnumerateDeviceObjectList().
Then call IoGetDeviceProperty() on those device objects to locate the
devices of interest. Given a device object, you can obtain a reference
to its BUS_INTERFACE_STANDARD, which you could use to access the
device’s config space.
Don’t forget to clean up- you must dereference each
BUS_INTERFACE_STANDARD interface when you’re done with it, plus call
ObDereferenceObject() on each device object referenced by
IoEnumerateDeviceObjectList() AND on the PCI driver object you obtained
using ObReferenceObjectByName(). Finish your business and dereference
all of these items as quickly as possible.
It’s seriously asking for trouble to mess with another device’s config
space from your driver. Apart from that usage, this PCI device
enumeration technique could be useful in certain situations and seems to
be not well-known.
Mark Fontana
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer