4

我正在尝试从 Winusb 设备获取供应商和产品 ID,并且在尝试使用 winusb_GetDesicriptor() 时遇到 accessviolationexception,并且无法弄清楚为什么我会收到该异常。

这是我的声明:

    internal devInfo myDevInfo = new devInfo();
    USB_INTERFACE_DESCRIPTOR ifaceDescriptor;
    USB_DEVICE_DESCRIPTOR deviceDescriptor;


    internal struct USB_INTERFACE_DESCRIPTOR
    {
        internal Byte bLength;
        internal Byte bDescriptorType;
        internal Byte bInterfaceNumber;
        internal Byte bAlternateSetting;
        internal Byte bNumEndpoints;
        internal Byte bInterfaceClass;
        internal Byte bInterfaceSubClass;
        internal Byte bInterfaceProtocol;
        internal Byte iInterface;
    }


    [StructLayout(LayoutKind.Explicit, Size = 18, CharSet = CharSet.Auto)]
    internal struct USB_DEVICE_DESCRIPTOR
    {
        [FieldOffset(0)]internal byte bLength;
        [FieldOffset(1)]internal byte bDescriptorType;
        [FieldOffset(2)]internal ushort bcdUSB;
        [FieldOffset(4)]internal byte bDeviceClass;
        [FieldOffset(5)]internal byte bDeviceSubClass;
        [FieldOffset(6)]internal byte bDeviceProtocol;
        [FieldOffset(7)]internal byte bMaxPacketSize0;
        [FieldOffset(8)]internal ushort idVendor;
        [FieldOffset(10)]internal ushort idProduct;
        [FieldOffset(12)]internal ushort bcdDevice;
        [FieldOffset(14)]internal byte iManufacturer;
        [FieldOffset(15)]internal byte iProduct;
        [FieldOffset(16)]internal byte iSerialNumber;
        [FieldOffset(17)]internal byte bNumConfigurations;
    }

    [DllImport("winusb.dll", SetLastError = true)]
    internal static extern Boolean WinUsb_Initialize(SafeFileHandle DeviceHandle, ref IntPtr InterfaceHandle);

    [DllImport("winusb.dll", SetLastError = true)]
    internal static extern Boolean WinUsb_QueryInterfaceSettings(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);

    [DllImport("winusb.dll", SetLastError = true)]
    internal static extern Boolean WinUsb_GetDescriptor(IntPtr InterfaceHandle, byte DescriptorType, byte Index, ushort LanguageID, ref USB_DEVICE_DESCRIPTOR UsbAltDeviceDescriptor, ulong BufferLength, ref long LengthTransferred);

然后这是我要运行的代码:

deviceHandle = CreateFile
                   (devicePathName,
                   (GENERIC_WRITE | GENERIC_READ),
                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                   IntPtr.Zero,
                   OPEN_EXISTING,
                   FILE_FLAG_OVERLAPPED,
                   0);

            success = WinUsb_Initialize(deviceHandle, ref myDevInfo.winUsbHandle);
            success = WinUsb_QueryInterfaceSettings(myDevInfo.winUsbHandle, 0, ref ifaceDescriptor);
            success = WinUsb_GetDescriptor(myDevInfo.winUsbHandle,
                           0x01,
                           (byte)deviceIndex,
                           0,
                           ref deviceDescriptor,
                           18,
                           ref lengthTransferred);

我正在完成初始化并从 queryinterfacesettings 中取回值,但是在 GetDescriptor 调用中获得了访问冲突

4

2 回答 2

5

阅读. _WinUsb_GetDescriptor

看起来你的参数不正确。要获取设备描述符中的 VID/PID,您需要指定USB_DEVICE_DESCRIPTOR_TYPE第二个参数 (0x01) 的类型。如果您请求字符串描述符,您也只需要指定语言 ID。您的设备描述符的长度也错误,它应该是 18(ushort是 2 个字节,这可能是您访问冲突的原因)。您还想使用byte而不是Byte在您的DeviceDescriptor结构中,您不想要字节的 .NET 类表示,只想要类型值本身。

以下是可能对您有用的更新代码:

success = WinUsb_GetDescriptor(myDevInfo.winUsbHandle,
                               0x01, 
                               (byte)deviceIndex,
                               0,
                               ref deviceDescriptor,
                               18,
                               ref lengthTransferred);
于 2013-12-10T18:01:51.380 回答
0

这是一个用于 USB 调用的类,包括用于获取其他描述符信息的帮助代码。

public static partial class WinUsbApiCalls
{
    #region Constants
    public const int EnglishLanguageID = 1033;
    public const uint DEVICE_SPEED = 1;
    public const byte USB_ENDPOINT_DIRECTION_MASK = 0X80;
    public const byte WritePipeId = 0x80;

    /// <summary>
    /// Not sure where this constant is defined...
    /// </summary>
    public const int DEFAULT_DESCRIPTOR_TYPE = 0x01;
    public const int USB_STRING_DESCRIPTOR_TYPE = 0x03;
    #endregion

    #region API Calls
    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, byte[] Buffer, uint BufferLength, ref uint LengthTransferred, IntPtr Overlapped);

    [DllImport("winusb.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool WinUsb_GetAssociatedInterface(SafeFileHandle InterfaceHandle, byte AssociatedInterfaceIndex, out SafeFileHandle AssociatedInterfaceHandle);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_GetDescriptor(SafeFileHandle InterfaceHandle, byte DescriptorType, byte Index, ushort LanguageID, out USB_DEVICE_DESCRIPTOR deviceDesc, uint BufferLength, out uint LengthTransfered);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_GetDescriptor(SafeFileHandle InterfaceHandle, byte DescriptorType, byte Index, UInt16 LanguageID, byte[] Buffer, UInt32 BufferLength, out UInt32 LengthTransfered);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_Free(SafeFileHandle InterfaceHandle);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, out SafeFileHandle InterfaceHandle);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_QueryDeviceInformation(IntPtr InterfaceHandle, uint InformationType, ref uint BufferLength, ref byte Buffer);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_QueryInterfaceSettings(SafeFileHandle InterfaceHandle, byte AlternateInterfaceNumber, out USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_QueryPipe(SafeFileHandle InterfaceHandle, byte AlternateInterfaceNumber, byte PipeIndex, out WINUSB_PIPE_INFORMATION PipeInformation);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_ReadPipe(SafeFileHandle InterfaceHandle, byte PipeID, byte[] Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_SetPipePolicy(SafeFileHandle InterfaceHandle, byte PipeID, uint PolicyType, uint ValueLength, ref uint Value);

    [DllImport("winusb.dll", SetLastError = true)]
    public static extern bool WinUsb_WritePipe(SafeFileHandle InterfaceHandle, byte PipeID, byte[] Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped);
    #endregion

    #region Public Methods
    public static string GetDescriptor(SafeFileHandle defaultInterfaceHandle, byte index, string errorMessage)
    {
        var buffer = new byte[256];
        var isSuccess = WinUsb_GetDescriptor(defaultInterfaceHandle, USB_STRING_DESCRIPTOR_TYPE, index, EnglishLanguageID, buffer, (uint)buffer.Length, out var transfered);
        WindowsDeviceBase.HandleError(isSuccess, errorMessage);
        var descriptor = new string(Encoding.Unicode.GetChars(buffer, 2, (int)transfered));
        return descriptor.Substring(0, descriptor.Length - 1);
    }
    #endregion
} 

用法

        var isSuccess2 = WinUsbApiCalls.WinUsb_GetDescriptor(defaultInterfaceHandle, WinUsbApiCalls.DEFAULT_DESCRIPTOR_TYPE, 0, WinUsbApiCalls.EnglishLanguageID, out var _UsbDeviceDescriptor, bufferLength, out var lengthTransferred);

代码来自这里,是Usb.Net框架的一部分。要连接枚举并使用它获取 USB 设备,您可以查看wiki

于 2019-08-12T08:27:37.780 回答