Given a device instance ID for a network card, I would like to know its MAC address. Example device instance ID on my system for integrated Intel Gigabit card:
I wound up using SetupDiGetDeviceRegistryProperty
to read SPDRP_FRIENDLYNAME
. If that's not found, then I read SPDRP_DEVICEDESC
instead. Ultimately, this gets me a string like "VirtualBox Host-Only Ethernet Adapter #2". I then match this against the InstanceName property in the WMI NDIS classes (MSNdis_EthernetPermanentAddress
WMI class). Both properties must be read in case there are multiple adapters sharing the same driver (i.e. "#2", "#3", etc.) - if there's only one adapter then SPDRP_FRIENDLYNAME
isn't available, but if there is more than one then SPDRP_FRIENDLYNAME
is required to differentiate them.
The method makes me a little nervous because I'm comparing what seems like a localized string, and there's no documentation that I've found that guarantees what I'm doing will always work. Unfortunately, I haven't found any better ways that are documented to work, either.
A couple other alternate methods involve groveling in undocumented registry locations. One method is spencercw's method, and the other would be to read SPDRP_DRIVER
, which is the name of a subkey under HKLM\SYSTEM\CurrentControlSet\Control\Class
. Underneath the driver key, look for the Linkage\Export
value which then seems like it could be matched to the DeviceName
property of the MSNdis_EnumerateAdapter
class. But there's no documentation I could find that says these values can be legally matched. Furthermore, the only documentation I found about Linkage\Export
was from the Win2000 registry reference and explicitly said that applications shouldn't rely on it.
Another method would be to look at my original question, step 4: "SetupDiGetDeviceInterfaceDetail
for this returned device interface". The device interface path actually can be used to reconstruct the device path. Start with device interface path: \\?\pci#ven_8086&dev_10cc&subsys_00008086&rev_00#3&33fd14ca&0&c8#{ad498944-762f-11d0-8dcb-00c04fc3358c}\{28fd5409-15bd-4c06-b62f-004d3a06f852}
. Then, remove everything before the final slash, leaving you with: {28fd5409-15bd-4c06-b62f-004d3a06f852}
. Finally, prepend \Device\
to this string and match it against the WMI NDIS classes. Again, however, this seems to be undocumented and relying on an implementation detail of a device interface path.
In the end, the other methods I investigated had their own undocumented complications that sounded at least as serious as matching the SPDRP_FRIENDLYNAME
/ SPDRP_DEVICEDESC
strings. So I opted for the simpler approach, which was to just match those strings against the WMI NDIS classes.