Get all PCI Devices

Hi List,

I need to get all pci devices in the system for reading their configuration
space on Windows XP and Vista.

I found how to read the pci configuration space at:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q253232
using BUS_INTERFACE_STANDARD or IRP_MN_READ_CONFIG.

My question is: how do I get the DeviceObject for every PCI device in the
system?

I tried to use the IoGetDeviceInterfaces function but it didn’t work, here is
how I used it:

NTSTATUS status;
PWSTR symbolicLinkList=NULL;

status = IoGetDeviceInterfaces(
&GUID_BUS_TYPE_PCI,
NULL,
DEVICE_INTERFACE_INCLUDE_NONACTIVE,
&symbolicLinkList);

The function is returning NT_SUCCESS, but the symbolicLinkList is empty. Also,
I have tried with different GUIDs, for example, GUID_PCI_BUS_INTERFACE_STANDARD
and GUID_PCI_DEVICE_PRESENT_INTERFACE without any luck.

Please, any idea or suggestion is very welcomed,
Rodolfo.


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Rodolfo Martinez wrote:

I need to get all pci devices in the system for reading their configuration
space on Windows XP and Vista.

I found how to read the pci configuration space at:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q253232
using BUS_INTERFACE_STANDARD or IRP_MN_READ_CONFIG.

My question is: how do I get the DeviceObject for every PCI device in the
system?

You don’t need the DeviceObject for every PCI device. All you need is
the DeviceObject for the PCI bus driver. He’s the one who responds to
IRP_MN_READ_CONFIG, and there’s only one of him.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> I need to get all pci devices in the system for reading their configuration

space on Windows XP and Vista.

The Windows OS does not support this, period. You can only do some hacks like
accessing the ports 0xcf8/0xcfc directly, but you cannot grab the lock which
guards them, so there are chances you will interfere the normal OS’s work with
them and will cause a hang or a crash.

The driver can only read the PCI config space of its device, not of all devices
on a bus.

If you need something like a hardware inventory, then write your own Device
Manager, the DEVCON sample from the DDK is the command-line tool which does
exactly this.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Hi Maxim,

Thanks for your answer.

What I wanted to do is read the PCI Extended Configuration Space throught
BUS_INTERFACE_STANDARD or IRP_MN_READ_CONFIG interface – this is only possible
on Windows Vista/LH. I think accessing ports 0xcf8/0xcfc does not support
reading beyond the 256 bytes boundary.

I think a driver can read the PCI config space from any device if it can
obtain a DeviceObject from the device it wants to read the config space. Here
is how I solved my problem:


int i;
UNICODE_STRING devName;
WCHAR devNumber[10];
WCHAR nameBuf[50];
NTSTATUS status;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;

for (i=0; i < 10000 ; i++){// for each possible driver index
// All PCI devices are handled by the PnP Manager
// and enumerates them as \Device\NTPNP_PCIxxxx
swprintf(devNumber, L"%04d", i);
swprintf(nameBuf, L"\Device\NTPNP_PCI");
wcscat(nameBuf, devNumber);
RtlInitUnicodeString(&devName, nameBuf);

status = IoGetDeviceObjectPointer(
&devName,
FILE_READ_DATA,
&pFileObject,
&pDeviceObject);
if (NT_SUCCESS(status)){
// We have a DeviceObject for device
// \Device\NTPNP_PCIxxx
}
}

Regards,

— “Maxim S. Shatskih” wrote:

> > I need to get all pci devices in the system for reading their configuration
> > space on Windows XP and Vista.
>
> The Windows OS does not support this, period. You can only do some hacks like
> accessing the ports 0xcf8/0xcfc directly, but you cannot grab the lock which
> guards them, so there are chances you will interfere the normal OS’s work
> with
> them and will cause a hang or a crash.
>
> The driver can only read the PCI config space of its device, not of all
> devices
> on a bus.
>
> If you need something like a hardware inventory, then write your own Device
> Manager, the DEVCON sample from the DDK is the command-line tool which does
> exactly this.
>
> Maxim Shatskih, Windows DDK MVP

================================
Rodolfo Martinez Cardenas.
================================

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Note that IoGetDeviceObjectPtr will result in an IRP_MJ_CREATE being
send to the device stack. Unfortunately, not all device stacks honor the
“open” request. If any driver (usually the FDO) in the stack fails the
request, no device obj will be returned.

To access arbitrary PCI device in windows, the good old Hal call should
still work fine.

Calvin Guan
NetXtreme Vista/LH Server Miniport
Broadcom Corporation
Connecting Everything(r)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-255406-
xxxxx@lists.osr.com] On Behalf Of Rodolfo Martinez
Sent: Monday, July 03, 2006 9:03 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Get all PCI Devices

Hi Maxim,

Thanks for your answer.

What I wanted to do is read the PCI Extended Configuration Space
throught
BUS_INTERFACE_STANDARD or IRP_MN_READ_CONFIG interface – this is only
possible
on Windows Vista/LH. I think accessing ports 0xcf8/0xcfc does not
support
reading beyond the 256 bytes boundary.

I think a driver can read the PCI config space from any device if it
can
obtain a DeviceObject from the device it wants to read the config
space.
Here
is how I solved my problem:


int i;
UNICODE_STRING devName;
WCHAR devNumber[10];
WCHAR nameBuf[50];
NTSTATUS status;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;

for (i=0; i < 10000 ; i++){// for each possible driver index
// All PCI devices are handled by the PnP Manager
// and enumerates them as \Device\NTPNP_PCIxxxx
swprintf(devNumber, L"%04d", i);
swprintf(nameBuf, L"\Device\NTPNP_PCI");
wcscat(nameBuf, devNumber);
RtlInitUnicodeString(&devName, nameBuf);

status = IoGetDeviceObjectPointer(
&devName,
FILE_READ_DATA,
&pFileObject,
&pDeviceObject);
if (NT_SUCCESS(status)){
// We have a DeviceObject for device
// \Device\NTPNP_PCIxxx
}
}

Regards,

— “Maxim S. Shatskih” wrote:
>
> > > I need to get all pci devices in the system for reading their
> configuration
> > > space on Windows XP and Vista.
> >
> > The Windows OS does not support this, period. You can only do some
hacks
> like
> > accessing the ports 0xcf8/0xcfc directly, but you cannot grab the
lock
> which
> > guards them, so there are chances you will interfere the normal OS’s
> work
> > with
> > them and will cause a hang or a crash.
> >
> > The driver can only read the PCI config space of its device, not of
all
> > devices
> > on a bus.
> >
> > If you need something like a hardware inventory, then write your own
> Device
> > Manager, the DEVCON sample from the DDK is the command-line tool
which
> does
> > exactly this.
> >
> > Maxim Shatskih, Windows DDK MVP
>
>
> ================================
> Rodolfo Martinez Cardenas.
> ================================
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer