Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving PCI coordinates by Windows' API (user mode)

Is there a way to obtain PCI coordinates (bus/slot/function numbers) of devices by using Windows c/c++ API (e.g PnP Configuration Manager API)? I already know how to do it in kernel mode, I need an user-mode solution. My target system is Windows XP-32 bit.

like image 279
Giuseppe Guerrini Avatar asked Feb 18 '14 11:02

Giuseppe Guerrini


People also ask

How do I find PCI in Windows?

You can also access the Device Manager by pressing "Windows-X" and selecting "Device Manager" from the menu. You can also visually identify the connected PCI cards in a computer by opening the casing and examining devices connected to the computer's PCI buses.

How do I find my PCI bus number?

Each PCI-X host bridge adapter number is "stamped" at the back of the I/O brick. Indicates the logical PCI-X bus number on the host bridge adapter. Each PCI-X host bridge adapter has two PCI-X buses -- bus 1 and bus 2. This number is also "stamped" on the back panel of the I/O brick.

What is PCI command?

Peripheral Component Interconnect (PCI) is a local computer bus for attaching hardware devices in a computer and is part of the PCI Local Bus standard. The PCI bus supports the functions found on a processor bus but in a standardized format that is independent of any given processor's native bus.

How do I enable a PCI device?

From the System Utilities screen, select System Configuration > BIOS/Platform Configuration (RBSU) > PCI Device Enabled/Disable and press Enter. Select a device on the system from the list and press Enter. Select Enable or Disable and press Enter.


1 Answers

I've eventually found a simple solution (it was just a matter of digging into MSDN).

This minimal code finds the device's PCI coordinates in terms of bus/slot/function:

DWORD bus, addr, slot, func;
HDEVINFO h; // Obtained by SetupDiGetClassDevs
SP_DEVINFO_DATA d; // Filled by SetupDiGetDeviceInterfaceDetail

SetupDiGetDeviceRegistryProperty(h,&d,SPDRP_BUSNUMBER,NULL,&bus,sizeof(bus),NULL);
SetupDiGetDeviceRegistryProperty(h,&d,SPDRP_ADDRESS,NULL,&addr,sizeof(addr),NULL);
slot = (addr >> 16) & 0xFFFF;
func = addr & 0xFFFF;

Note: for real production the output buffer's size must be obtained by a previous call of the API function in order to allocate it dynamically, and error checks must be added, of course.

like image 195
Giuseppe Guerrini Avatar answered Sep 27 '22 22:09

Giuseppe Guerrini