我正在尝试从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调用上获取访问权限
答案 0 :(得分:5)
阅读documentation for WinUsb_GetDescriptor
。
看起来您的参数不正确。要获取设备描述符中的VID / PID,您需要为第二个参数(0x01)指定USB_DEVICE_DESCRIPTOR_TYPE
类型。如果要请求字符串描述符,也只需要指定语言ID。您的设备描述符的长度也是错误的,它应该是18(ushort
是2个字节,这可能是您的访问冲突的原因)。您还希望在byte
结构中使用Byte
而不是DeviceDescriptor
,您不希望.NET类表示字节,只需要类型值本身。
以下是可能适合您的更新代码:
success = WinUsb_GetDescriptor(myDevInfo.winUsbHandle,
0x01,
(byte)deviceIndex,
0,
ref deviceDescriptor,
18,
ref lengthTransferred);
答案 1 :(得分: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);