When going to Windows' "Device manager" and clicking on (almost) any device in the list one piece of information in the "General" tab is called "Location". That is a string that is either:
- human-readable, like "on NVIDIA GeForce GTX 1080"
- semi-useful, like "Location 0 (Internal High Definition Audio Bus)" or "PCI bus 9, device 0, function 0"
- a USB location, like "Port_#0004.Hub_#0015" or even a "0009.0000.0000.004.000.000.000.000.000"
That info is available through Windows' Unified device property model APIs.
What I'm looking for is to get that information from a given IMFActivate
object.
Is there a way to do so? I can't find how to get "device" info from that activation object. The only piece of data I have is it's "symbolic link" (in my case, this string: \\?\usb#vid_04b4&pid_8888&mi_00#9&4fe28be&0&0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\global
) but that link's format is nothing like the string I see in "Location".
Thus my question: how to get device's "Location" string, given its IMFActivate
object?
UPDATE
Here's the code I'm using to "convert" the symbolic link, provided by IMFActivate
to a device id string, recognizable by setup-api functions and then extracting the "location string":
CString symLink2Location(const CString & _symLink)
{
DEVINST di;
CString devId = _symLink;
devId = devId.Left( devId.Find(L"#{") );
devId.Replace(L"\\\\?\\", L"");
devId.Replace(L"#", L"\\");
const auto rc = CM_Locate_DevNodeW(&di, devId.GetBuffer(), CM_LOCATE_DEVNODE_NORMAL);
if(rc == CR_SUCCESS){
DEVPROPTYPE dpt;
ULONG sz = MAX_PATH;
WCHAR prop[MAX_PATH];
if(CM_Get_DevNode_PropertyW(di, &DEVPKEY_Device_LocationInfo, &dpt, (PBYTE)&prop, &sz, 0) == CR_SUCCESS){
if(dpt == DEVPROP_TYPE_STRING){
return prop;
}
}
}
return L"";
}
UPDATE 2
Here are the 3 audio input devices as seen in devmgmt.msc
under "Sound, video and game controllers":
- MS LifeCam Cinema (TM), location: 0000.0014.0000.013.003.000.000.000.000 (symlink:
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{751fe058-cef2-4d28-bbeb-e438981938d7}#{2eef81be-33fa-4800-9670-1cd474972c3f}
) - MS LifeCam Studio (TM), location: 0000.0014.0000.013.004.004.000.000.000 (symlink:
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{59267d2e-940b-45f5-8655-45372787bd85}#{2eef81be-33fa-4800-9670-1cd474972c3f}
) - SUB2r USB 3.0 HD Webcam, location: 0009.0000.0000.004.000.000.000.000.000 (symlink:
\\?\SWD#MMDEVAPI#{0.0.1.00000000}.{26a4f608-cbd8-4206-b958-d57ee6847153}#{2eef81be-33fa-4800-9670-1cd474972c3f}
)
All 3 are USB devices, all 3 are listed when calling MFEnumDeviceSources
but their "symbolic link" doesn't resolve into a hardware device.
CM_Locate_DevNodeW(&dnDevInst, sz, CM_LOCATE_DEVNODE_NORMAL)
and thenCM_Get_DevNode_PropertyW(dnDevInst, &DEVPKEY_Device_LocationInfo, &PropertyType, pb, &rcb, 0)
and you got location – RbMmCM_Locate_DevNodeW()
returnsCR_INVALID_DEVICE_ID
. I suppose the "symbolic link" provided by theIMFActivation
object is not what the setup-api expects :( (see my original post for a sample of what that link looks like) – YePhIcKusb\vid_04b4&pid_8888&mi_00\9&4fe28be&0&0000
exactly – RbMm{e5323777-f976-4f5b-9b55-b94699c46e44}
(STATIC_KSCATEGORY_VIDEO_CAMERA) but how do this in documented way not sure – RbMmCM_Get_Device_Interface_PropertyW(pszDeviceInterface, &DEVPKEY_Device_InstanceId
with string returned byIMFAttributes::Get[Allocated]String
and then already use returned device id in callCM_Locate_DevNodeW
+CM_Get_DevNode_PropertyW
– RbMm