Question

I am writing a program in C# to perform a hardware audit across many Windows XP workstations.

I need to determine which PCI devices are actual cards connected via a motherboard slot - NOT onboard devices that also use the PCI buses (built into the motherboard).

I can successfully list all devices that use all the PCI buses using a variety of WMI classes, but none provide any indication of what is onboard vs. what is connected via a slot.

I am not fussy about how the information is retrieved or from where it sourced (e.g. Pinvoke, WMI, registry, etc) as long as it's reliable.

Thank you!

Was it helpful?

Solution

After many hours I came up with a 'reasonably' reliable approach.

This logic fundamentally assumes that the slotted PCI device bus ID is unique and separate from all other (onboard) PCI bus IDs. So far my tests have shown this to be the case; regardless this is still an assumption.

My code is rather long and I'm sure it could be improved so instead I'll explain the process in pseudo-code:

  1. Determine how many slots are in use (and only proceed if at least one slot is actually in use):

    "SELECT SlotDesignation FROM Win32_SystemSlot WHERE CurrentUsage = 4"

  2. Store all the device IDs that belong to the PCI bus:

    "SELECT DeviceID FROM Win32_Bus where BusType = 5"

  3. Capture all system and logical device associations:

    "SELECT * FROM Win32_DeviceBus"

  4. Search all system and logical device associations (antecedent property) and count each time each deviceID occurs.

  5. You can now determine the DeviceID where the slotted PCI devices reside by finding the DeviceID that occurs the same number of times as the number of devices found in the system slots.

  6. For each of the Win32_DeviceBus results that contain the DeviceID (in the antecedent property) the dependent property will reference another DeviceID to be used for the Win32_PnPEntity class.

  7. Query the Win32_PnPEntity with the newly captured DeviceID and you now have all your device info (or rather, all information the the Win32_PnPEntity provides)!

    "SELECT * FROM Win32_PnPEntity WHERE DeviceID = '" + deviceID + "'"

Unfortunately I could not find ANY way to utilize the severely limited information returned by the Win32_SystemSlot class (that would have made life too easy!) other than the count of results returned by the 'in use' query.

Note that it may be possible to encounter more than one PCI bus that has the same number of devices as the count of slots that are in use. If this scenario were to arise (I haven't encountered it yet) then it'd suggest raising an exception rather than continuing and assuming you're querying the correct PCI bus.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top