1

我目前正在使用 kernel32.dll 中的 DeviceIOControl API 来获取已连接 USB 设备列表的字符串描述符。

public static String GetStringDescriptor(IntPtr deviceHandle, Int32 ConnectionIndex, Byte DescriptorIndex, UInt16 LanguageID)
    {        
        USB_DESCRIPTOR_REQUEST Buffer = new USB_DESCRIPTOR_REQUEST();
        Buffer.ConnectionIndex = ConnectionIndex;
        Buffer.SetupPacket.wValue = (UInt16)((USB_STRING_DESCRIPTOR_TYPE << 8) | DescriptorIndex);
        Buffer.SetupPacket.wIndex = LanguageID;
        Buffer.SetupPacket.wLength = MAXIMUM_USB_STRING_LENGTH;
        Int32 nBytesReturned;
        Boolean Status = DeviceIoControl(deviceHandle,
                IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
                ref Buffer,
                Marshal.SizeOf(Buffer),
                ref Buffer,
                Marshal.SizeOf(Buffer),
                out nBytesReturned,
                IntPtr.Zero);
        if (Status)
            return Buffer.Data.bString;
        else
            return null;
    }

我们使用此函数来获取描述符详细信息,例如语言 ID、序列号、制造商和产品字符串。仅在请求序列号时,返回的状态为 TRUE,我们得到预期值。但语言 ID、制造商和产品字符串的状态返回 false。

我使用以下方法检查了 DeviceIoControl 返回的错误状态:

int error = Marshal.GetLastWin32Error();

它返回 31 作为错误代码,这意味着设备无法正常工作/设备的驱动程序未正确安装。

我尝试了所有明显的解决方案,例如重新安装设备的驱动程序并重新启动 PC 等,但似乎没有一个有效。我确信设备或代码中没有问题,因为它在 Windows 7 PC 中完美运行。另外,由于我能够获得序列号,我认为设备句柄也是正确的。

我无法继续进行任何进一步的调试。Windows 10 中的 DeviceIoControl 功能是否有一些更新?还是在 Windows 10 中更改语言 ID、制造商和产品字符串的方式?

4

1 回答 1

0

您尝试从中获取字符串描述符的设备很可能处于低功耗状态。首先检查其当前的电源状态,如果它与“ PowerDeviceD0 ”不同 - 可能无法获取字符串描述符(取决于设备,实际上和实际电源状态级别 D1、D2、D3)。这可能是来自 DeviceIOControl() 的错误代码 31 的原因。

尝试先唤醒设备或使用 SetupAPI 获取一些存储的字符串。

于 2020-02-01T13:03:02.447 回答