6

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.

Giuseppe Guerrini
  • 4,274
  • 17
  • 32
  • I've not used it myself (hence a comment and not an answer), but you could have a look at the [Function Discovery](http://msdn.microsoft.com/en-us/library/aa814070.aspx) API. It allows you to discover PnP devices and so on. Ah wait, just read that you're looking for WinXP... Function Discovery is only Vista+. – icabod Feb 18 '14 at 12:14
  • Correct. Also, Vista extends the set of SetupAPI functions. Indeed there is a non-registry-based version of "SetupDiGetDeviceRegistryProperty" that retrieves properties directly from the kernel's database. But fortunately for my purpose the XP's registry-based version is enough. – Giuseppe Guerrini Feb 20 '14 at 15:58

1 Answers1

5

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.

Giuseppe Guerrini
  • 4,274
  • 17
  • 32