Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't instantiate USBDevice when the device doesn't provide the language ids descriptor #38

Open
Konamiman opened this issue Jul 9, 2021 · 1 comment

Comments

@Konamiman
Copy link

Konamiman commented Jul 9, 2021

The CH372 processor (and the compatible ones CH375 and CH376, when configured in device mode) has an "internal firmware mode" in which the chip itself takes care of all the control transfers on endpoint 0. In this mode the processor doesn't provide any string descriptor at all, not even the language IDs descriptor: a request for this descriptor will always fail.

This makes it impossible to use WinUSBNet to access such a device. That's because the USBDevice constructor calls its GetDeviceDescriptor method, which will in turn call wuDevice.GetSupportedLanguageIDs(); this is going to throw, and thus GetDeviceDescriptor throws and the entire instantiation fails.

The following alternative implementation of USBDevice.GetDeviceDescriptor fixes the problem. If any string descriptor related operation fails the device object is still created without any string information whatsoever (it could be improved by wrapping a try around each string descriptor request, up to you):

private static USBDeviceDescriptor GetDeviceDescriptor(string devicePath)
{
    using (API.WinUSBDevice wuDevice = new API.WinUSBDevice())
    {
        API.USB_DEVICE_DESCRIPTOR deviceDesc;

        try {
            wuDevice.OpenDevice(devicePath);
            deviceDesc = wuDevice.GetDeviceDescriptor();
        }
        catch (API.APIException e) {
            throw new USBException("Failed to retrieve device descriptor.", e);
        }

        try {
            // Get first supported language ID
            ushort[] langIDs = wuDevice.GetSupportedLanguageIDs();
            ushort langID = 0;
            if (langIDs.Length > 0)
                langID = langIDs[0];

            string manufacturer = null, product = null, serialNumber = null;
            byte idx = 0;
            idx = deviceDesc.iManufacturer;
            if (idx > 0)
                manufacturer = wuDevice.GetStringDescriptor(idx, langID);

            idx = deviceDesc.iProduct;
            if (idx > 0)
                product = wuDevice.GetStringDescriptor(idx, langID);

            idx = deviceDesc.iSerialNumber;
            if (idx > 0)
                serialNumber = wuDevice.GetStringDescriptor(idx, langID);

            return new USBDeviceDescriptor(devicePath, deviceDesc, manufacturer, product, serialNumber);
        }
        catch (API.APIException) {
            return new USBDeviceDescriptor(devicePath, deviceDesc, null, null, null);
        }
    }
}
@madwizard-thomas
Copy link
Owner

Hi, thanks for your report. Is there a specific error code that is thrown in this case? It would be good to work around the issue but I'm a bit hesitant to blankly ignore all API errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants