I have a video-streaming device that I am accessing using Microsoft Media Foundation. It has additional functionality using bulk. I want to connect to it using libusb. My problem is that I need to connect precisely to the same device as with IMFMediaSource
. Connecting 2 same devices I can't find a way to separate them. VID and PID are the same. The only thing I have from MF is a symlink: \\?\usb#vid_----&pid_----&mi_00#8&20ba1d94&0&0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\global
(removed vid and pid). With libusb using device descriptor I can read Serial: $Rev:0001_CID:0009011D01502130_SN:76543210$
. On connected devices they are different, but the problem is that I can't find a way to check or connect those two strings to see if it's the same device.
Code where I get symlink:
IMFAttributes* pAttributes = NULL;
IMFActivate** ppDevices = NULL;
HRESULT hr = EnumerateVideoDevices(pAttributes, ppDevices, availDeviceCount);
availDevice = new Device[availDeviceCount]; // initialise empty return array
// populate return array w/ devices
for (int i = 0; i < availDeviceCount; i++)
{
wchar_t* deviceFriendlyName;
UINT len = 0;
hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &deviceFriendlyName, &len);
Device newDevice{ i, ToNarrow(deviceFriendlyName), NULL, 0 }; // TODO: check that change from unicode to String doesn't screw anything up (see ToNarrow, misc.h)
// retain for device change notificatios
ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
&newDevice.g_pwszSymbolicLink, &newDevice.g_cchSymbolicLink);
availDevice[i] = newDevice;
}
This is how I get serial using libusb:
String serial = LibUsb.getStringDescriptor(handle, descriptor.iSerialNumber());
So after some time, I discovered that the video streaming device is a child of the whole USB device. So this is how I get same serial number same as libusb:
CONFIGRET LocateParent(PCWSTR pszDeviceInterface, WCHAR* parentDeviceID)
{
WCHAR buf[1024];
DEVPROPTYPE PropertyType;
ULONG BufferSize = sizeof(buf);
CONFIGRET err;
if (!(err = CM_Get_Device_Interface_Property(pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, (PBYTE)buf, &BufferSize, 0))) {
if (PropertyType == DEVPROP_TYPE_STRING) {
DEVINST dnDevInst;
if (!(err = CM_Locate_DevNode(&dnDevInst, buf, CM_LOCATE_DEVNODE_NORMAL))) {
// Get Parent Device ID
DEVINST devInstParent;
err = CM_Get_Parent(&devInstParent, dnDevInst, 0);
if (err == CR_SUCCESS) {
return CM_Get_Device_ID(devInstParent, parentDeviceID, 1024, 0);
}
}
}
else {
err = CR_WRONG_TYPE;
}
}
return err;
}