A blog by Devendra Tewari
winusbnet throws an exception when reading string descriptors using the WinUsb_GetDescriptor call. Basically, that WinUsb call returns false as it is called with a Language ID of 0, a reserved value.
The GetStringDescriptor
method does not accept a language ID, so we need to patch it to fix that. That change is reproduced below.
public string GetStringDescriptor(byte index, ushort languageID)
{
byte[] buffer = new byte[256];
uint transfered;
bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE,
index, languageID, buffer, (uint)buffer.Length, out transfered);
if (!success)
throw APIException.Win32("Failed to get USB string descriptor (" + index + ").");
int length = buffer[0] - 2;
if (length <= 0)
return null;
char[] chars = System.Text.Encoding.Unicode.GetChars(buffer, 2, length);
return new string(chars);
}
Tha patched GetDeviceDescriptor
queries the available languages by calling GetStringDescriptor
with an index of 0. It then uses the first language ID to recover other string descriptors.
private static USBDeviceDescriptor GetDeviceDescriptor(string devicePath)
{
try
{
USBDeviceDescriptor descriptor;
using (API.WinUSBDevice wuDevice = new API.WinUSBDevice())
{
wuDevice.OpenDevice(devicePath);
API.USB_DEVICE_DESCRIPTOR deviceDesc = wuDevice.GetDeviceDescriptor();
string q = wuDevice.GetStringDescriptor(0, 0);
if (q.Length == 0)
throw new USBException("Failed to get USB string descriptor (0).");
// TODO: Using the first language id. Need to improve API.
ushort langID = q[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);
descriptor = new USBDeviceDescriptor(devicePath, deviceDesc, manufacturer, product, serialNumber);
}
return descriptor;
}
catch (API.APIException e)
{
throw new USBException("Failed to retrieve device descriptor.", e);
}
}
The patch is available on GitHub.