Search code examples
javac++libusb

How to connect to libusb device using symbolic link?


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());

Solution

  • 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;
    }