# HG changeset patch # User Ivo Smits # Date 1381878709 -7200 # Node ID 2d16447eff12354705d3a421bd6ecfe5a1184c8c # Parent b7bc27c6734eece4cff8a9466e8fbfa217bc624a Simplified USB communication code, added functions to abort pipe transfers diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/IUsbDevice.cs --- a/USBLib/Communication/IUsbDevice.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/IUsbDevice.cs Wed Oct 16 01:11:49 2013 +0200 @@ -13,19 +13,13 @@ Byte Configuration { get; } void Close(); - //int ControlTransfer(byte requestType, byte request, short value, short index, Byte[] buffer, int offset, int length); int GetDescriptor(byte descriptorType, byte index, short langId, Byte[] buffer, int offset, int length); - int BulkWrite(Byte endpoint, Byte[] buffer, int offset, int length); - int BulkRead(Byte endpoint, Byte[] buffer, int offset, int length); - void BulkReset(Byte endpoint); - int InterruptWrite(Byte endpoint, Byte[] buffer, int offset, int length); - int InterruptRead(Byte endpoint, Byte[] buffer, int offset, int length); - void InterruptReset(Byte endpoint); - int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, Byte[] buffer, int offset, int length); - int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, Byte[] buffer, int offset, int length); + int PipeTransfer(Byte endpoint, Byte[] buffer, int offset, int length); + void PipeReset(Byte endpoint); + void PipeAbort(Byte endpoint); + int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, Byte[] buffer, int offset, int length); - UsbPipeStream GetBulkStream(Byte endpoint); - UsbPipeStream GetInterruptStream(Byte endpoint); + UsbPipeStream GetPipeStream(Byte endpoint); } } diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/LibUsb0/LibUsbDevice.cs --- a/USBLib/Communication/LibUsb0/LibUsbDevice.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/LibUsb0/LibUsbDevice.cs Wed Oct 16 01:11:49 2013 +0200 @@ -7,7 +7,6 @@ namespace UCIS.USBLib.Communication.LibUsb { public class LibUsb0Device : UsbInterface, IUsbDevice { - //private readonly List mClaimedInterfaces = new List(); public string DeviceFilename { get; private set; } public IUsbDeviceRegistry Registry { get; private set; } private SafeFileHandle DeviceHandle; @@ -81,25 +80,13 @@ } return ret; } - public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { - return PipeTransfer(endpoint, false, false, buffer, offset, length, 0); - } - public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { - return PipeTransfer(endpoint, true, false, buffer, offset, length, 0); - } - public override void BulkReset(byte endpoint) { - PipeReset(endpoint); + public override int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + if ((requestType & UsbControlRequestType.EndpointMask) == UsbControlRequestType.EndpointIn) + return ControlRead(requestType, request, value, index, buffer, offset, length); + else + return ControlWrite(requestType, request, value, index, buffer, offset, length); } - public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { - return PipeTransfer(endpoint, false, false, buffer, offset, length, 0); - } - public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { - return PipeTransfer(endpoint, true, false, buffer, offset, length, 0); - } - public override void InterruptReset(byte endpoint) { - PipeReset(endpoint); - } - public unsafe override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public unsafe int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { if (buffer == null) buffer = new Byte[0]; if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); int code; @@ -111,7 +98,7 @@ } return ret; } - public unsafe override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public unsafe int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { Byte[] inbuffer = new Byte[length + LibUsbRequest.Size]; if (length > 0) Buffer.BlockCopy(buffer, offset, inbuffer, LibUsbRequest.Size, length); int code; @@ -201,6 +188,10 @@ } } + public override int PipeTransfer(Byte epnum, Byte[] buffer, int offset, int length) { + return PipeTransfer(epnum, (epnum & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointOut, false, buffer, offset, length, 0); + } + unsafe int PipeTransfer(Byte epnum, Boolean write, Boolean isochronous, Byte[] buffer, int offset, int length, int packetsize) { if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); LibUsbRequest req = new LibUsbRequest(); @@ -228,13 +219,20 @@ } } } - public void PipeReset(byte pipeID) { + public override void PipeReset(byte pipeID) { LibUsbRequest req = new LibUsbRequest(); req.Endpoint.ID = pipeID; req.Timeout = UsbConstants.DEFAULT_TIMEOUT; int ret; DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret); } + public override void PipeAbort(byte pipeID) { + LibUsbRequest req = new LibUsbRequest(); + req.Endpoint.ID = pipeID; + req.Timeout = UsbConstants.DEFAULT_TIMEOUT; + int ret; + DeviceIoControl(DeviceHandle, LibUsbIoCtl.ABORT_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret); + } private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) { fixed (LibUsbRequest* InBufferPtr = &InBuffer) { diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/LibUsb1/LibUsb1Device.cs --- a/USBLib/Communication/LibUsb1/LibUsb1Device.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/LibUsb1/LibUsb1Device.cs Wed Oct 16 01:11:49 2013 +0200 @@ -17,52 +17,22 @@ if (Handle != null) Handle.Close(); } - public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { - return BulkTransfer(endpoint, buffer, offset, length); - } - public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { - return BulkTransfer(endpoint, buffer, offset, length); - } - public override void BulkReset(byte endpoint) { + public override void PipeReset(byte endpoint) { int ret = libusb1.libusb_clear_halt(Handle, endpoint); if (ret < 0) throw new Exception("libusb_clear_halt returned " + ret.ToString()); } - private int BulkTransfer(byte endpoint, byte[] buffer, int offset, int length) { + public override int PipeTransfer(byte endpoint, byte[] buffer, int offset, int length) { if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); if (length == 0) return 0; fixed (Byte* b = buffer) { int ret = libusb1.libusb_bulk_transfer(Handle, endpoint, b + offset, length, out length, 0); + //libusb1.libusb_interrupt_transfer(Handle, endpoint, b + offset, length, out length, 0); if (ret < 0) throw new Exception("libusb_bulk_transfer returned " + ret.ToString()); } return length; } - public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { - return InterruptTransfer(endpoint, buffer, offset, length); - } - public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { - return InterruptTransfer(endpoint, buffer, offset, length); - } - public override void InterruptReset(byte endpoint) { - BulkReset(endpoint); - } - private int InterruptTransfer(byte endpoint, byte[] buffer, int offset, int length) { - if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); - if (length == 0) return 0; - fixed (Byte* b = buffer) { - int ret = libusb1.libusb_interrupt_transfer(Handle, endpoint, b + offset, length, out length, 0); - if (ret < 0) throw new Exception("libusb_interrupt_transfer returned " + ret.ToString()); - } - return length; - } - - public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } - public override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } - private int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public override int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { if (buffer == null) buffer = new Byte[0]; if (offset < 0 || length < 0 || length > ushort.MaxValue || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length"); fixed (Byte* b = buffer) { diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/LibUsbDotNet.cs --- a/USBLib/Communication/LibUsbDotNet.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/LibUsbDotNet.cs Wed Oct 16 01:11:49 2013 +0200 @@ -34,11 +34,7 @@ } } public bool ControlTransfer(ref UsbSetupPacket setupPacket, Byte[] buffer, int bufferLength, out int lengthTransferred) { - if ((setupPacket.RequestType & 128) != 0) { - lengthTransferred = Device.ControlRead((UsbControlRequestType)setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, 0, bufferLength); - } else { - lengthTransferred = Device.ControlWrite((UsbControlRequestType)setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, 0, bufferLength); - } + lengthTransferred = Device.ControlTransfer((UsbControlRequestType)setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, 0, bufferLength); return true; } public UsbEndpointReader OpenEndpointReader(ReadEndpointID readEndpointID, int buffersize, EndpointType endpointType) { @@ -139,11 +135,7 @@ ReadBufferSize = 4096; } public ErrorCode Read(byte[] buffer, int offset, int count, int timeout, out int transferLength) { - switch (EndpointType) { - case EndpointType.Bulk: transferLength = Device.BulkRead(EndpointID, buffer, offset, count); break; - case EndpointType.Interrupt: transferLength = Device.InterruptRead(EndpointID, buffer, offset, count); break; - default: transferLength = 0; return ErrorCode.Error; - } + transferLength = Device.PipeTransfer(EndpointID, buffer, offset, count); return ErrorCode.Ok; } public void Dispose() { DataReceivedEnabled = false; } diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/USBIO/USBIODevice.cs --- a/USBLib/Communication/USBIO/USBIODevice.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/USBIO/USBIODevice.cs Wed Oct 16 01:11:49 2013 +0200 @@ -28,6 +28,7 @@ static readonly int IOCTL_USBIO_RESET_DEVICE = _USBIO_IOCTL_CODE(21, METHOD_BUFFERED); static readonly int IOCTL_USBIO_BIND_PIPE = _USBIO_IOCTL_CODE(30, METHOD_BUFFERED); static readonly int IOCTL_USBIO_RESET_PIPE = _USBIO_IOCTL_CODE(32, METHOD_BUFFERED); + static readonly int IOCTL_USBIO_ABORT_PIPE = _USBIO_IOCTL_CODE(33, METHOD_BUFFERED); [DllImport("kernel32.dll", SetLastError = true)] static unsafe extern bool ReadFile(SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); @@ -150,31 +151,7 @@ return DeviceIoControl(DeviceHandle, IOCTL_USBIO_GET_DESCRIPTOR, (IntPtr)(&req), sizeof(USBIO_DESCRIPTOR_REQUEST), (IntPtr)(b + offset), length); } } - public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { - return PipeRead(endpoint, buffer, offset, length); - } - public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { - return PipeWrite(endpoint, buffer, offset, length); - } - public override void BulkReset(byte endpoint) { - PipeReset(endpoint); - } - public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { - return PipeRead(endpoint, buffer, offset, length); - } - public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { - return PipeWrite(endpoint, buffer, offset, length); - } - public override void InterruptReset(byte endpoint) { - PipeReset(endpoint); - } - public unsafe override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } - public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } - private unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public override unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { if (buffer == null) { if (offset != 0 || length != 0) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); } else { @@ -245,28 +222,28 @@ return handle; } } - unsafe int PipeRead(Byte epnum, Byte[] buffer, int offset, int length) { + public unsafe override int PipeTransfer(Byte epnum, Byte[] buffer, int offset, int length) { if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); SafeFileHandle handle = GetHandleForPipe(epnum); uint ret; fixed (Byte* b = buffer) { - if (!ReadFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); + Boolean success; + if ((epnum & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointIn) + success = ReadFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero); + else + success = WriteFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero); + if (!success) throw new Win32Exception(Marshal.GetLastWin32Error()); } return (int)ret; } - unsafe int PipeWrite(Byte epnum, Byte[] buffer, int offset, int length) { - if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); - SafeFileHandle handle = GetHandleForPipe(epnum); - uint ret; - fixed (Byte* b = buffer) { - if (!WriteFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); - } - return (int)ret; - } - public void PipeReset(byte pipeID) { + public override void PipeReset(byte pipeID) { SafeFileHandle handle = GetHandleForPipe(pipeID); DeviceIoControl(handle, IOCTL_USBIO_RESET_PIPE, IntPtr.Zero, 0, IntPtr.Zero, 0); } + public override void PipeAbort(byte pipeID) { + SafeFileHandle handle = GetHandleForPipe(pipeID); + DeviceIoControl(handle, IOCTL_USBIO_ABORT_PIPE, IntPtr.Zero, 0, IntPtr.Zero, 0); + } private unsafe int DeviceIoControl(SafeHandle hDevice, int IoControlCode, IntPtr InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize) { int pBytesReturned; @@ -275,16 +252,13 @@ throw new Win32Exception(Marshal.GetLastWin32Error()); } - public override UsbPipeStream GetBulkStream(byte endpoint) { - return new PipeStream(this, endpoint, false, GetHandleForPipe(endpoint)); - } - public override UsbPipeStream GetInterruptStream(byte endpoint) { - return new PipeStream(this, endpoint, true, GetHandleForPipe(endpoint)); + public override UsbPipeStream GetPipeStream(byte endpoint) { + return new PipeStream(this, endpoint, GetHandleForPipe(endpoint)); } class PipeStream : UsbPipeStream { private SafeFileHandle Handle; - public PipeStream(IUsbInterface device, Byte endpoint, Boolean interrupt, SafeFileHandle handle) : base(device, endpoint, interrupt) { + public PipeStream(IUsbInterface device, Byte endpoint, SafeFileHandle handle) : base(device, endpoint) { this.Handle = handle; } diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/UsbInterface.cs --- a/USBLib/Communication/UsbInterface.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/UsbInterface.cs Wed Oct 16 01:11:49 2013 +0200 @@ -7,7 +7,7 @@ public virtual byte Configuration { get { byte[] buf = new byte[1]; - int tl = ControlRead( + int tl = ControlTransfer( UsbControlRequestType.EndpointIn | UsbControlRequestType.TypeStandard | UsbControlRequestType.RecipDevice, (byte)UsbStandardRequest.GetConfiguration, 0, 0, buf, 0, buf.Length); @@ -19,31 +19,24 @@ } } public virtual int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) { - return ControlRead( + return ControlTransfer( UsbControlRequestType.EndpointIn | UsbControlRequestType.RecipDevice | UsbControlRequestType.TypeStandard, (Byte)UsbStandardRequest.GetDescriptor, (short)((descriptorType << 8) | index), langId, buffer, offset, length); } - public virtual int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index) { - return ControlWrite(requestType, request, value, index, null, 0, 0); + public virtual int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index) { + return ControlTransfer(requestType, request, value, index, null, 0, 0); } public abstract void Close(); - public abstract int BulkWrite(Byte endpoint, Byte[] buffer, int offset, int length); - public abstract int BulkRead(Byte endpoint, Byte[] buffer, int offset, int length); - public virtual void BulkReset(Byte endpoint) { throw new NotImplementedException(); } - public abstract int InterruptWrite(Byte endpoint, Byte[] buffer, int offset, int length); - public abstract int InterruptRead(Byte endpoint, Byte[] buffer, int offset, int length); - public virtual void InterruptReset(Byte endpoint) { throw new NotImplementedException(); } - public abstract int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length); - public abstract int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length); + public abstract int PipeTransfer(Byte endpoint, Byte[] buffer, int offset, int length); + public virtual void PipeReset(Byte endpoint) { throw new NotImplementedException(); } + public virtual void PipeAbort(Byte endpoint) { throw new NotImplementedException(); } + public abstract int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length); - public virtual UsbPipeStream GetBulkStream(Byte endpoint) { - return new UsbPipeStream(this, endpoint, false); - } - public virtual UsbPipeStream GetInterruptStream(Byte endpoint) { - return new UsbPipeStream(this, endpoint, true); + public virtual UsbPipeStream GetPipeStream(Byte endpoint) { + return new UsbPipeStream(this, endpoint); } public void Dispose() { diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/UsbPipeStream.cs --- a/USBLib/Communication/UsbPipeStream.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/UsbPipeStream.cs Wed Oct 16 01:11:49 2013 +0200 @@ -5,12 +5,10 @@ public class UsbPipeStream : Stream { public IUsbInterface Device { get; private set; } public Byte Endpoint { get; private set; } - public Boolean InterruptEndpoint { get; private set; } - public UsbPipeStream(IUsbInterface device, Byte endpoint, Boolean interrupt) { + public UsbPipeStream(IUsbInterface device, Byte endpoint) { this.Device = device; this.Endpoint = endpoint; - this.InterruptEndpoint = interrupt; } public override bool CanRead { @@ -35,12 +33,17 @@ set { throw new NotImplementedException(); } } + public void Abort() { + Device.PipeAbort(Endpoint); + } + + public void ClearHalt() { + Device.PipeReset(Endpoint); + } + public override int Read(byte[] buffer, int offset, int count) { - if (InterruptEndpoint) { - return Device.InterruptRead(Endpoint, buffer, offset, count); - } else { - return Device.BulkRead(Endpoint, buffer, offset, count); - } + if (!CanRead) throw new InvalidOperationException("Can not read from an output endpoint"); + return Device.PipeTransfer(Endpoint, buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { @@ -52,13 +55,14 @@ } public override void Write(byte[] buffer, int offset, int count) { - int written; - if (InterruptEndpoint) { - written = Device.InterruptWrite(Endpoint, buffer, offset, count); - } else { - written = Device.BulkWrite(Endpoint, buffer, offset, count); - } + if (!CanWrite) throw new InvalidOperationException("Can not write to an input endpoint"); + int written = Device.PipeTransfer(Endpoint, buffer, offset, count); if (written != count) throw new EndOfStreamException("Could not write all data"); } + + protected override void Dispose(bool disposing) { + if (disposing) try { Abort(); } catch { } + base.Dispose(disposing); + } } } diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/VBoxUSB.cs --- a/USBLib/Communication/VBoxUSB.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/VBoxUSB.cs Wed Oct 16 01:11:49 2013 +0200 @@ -308,6 +308,7 @@ static readonly int SUPUSB_IOCTL_USB_SET_CONFIG = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60A, METHOD_BUFFERED, FILE_WRITE_ACCESS); static readonly int SUPUSB_IOCTL_USB_SELECT_INTERFACE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x609, METHOD_BUFFERED, FILE_WRITE_ACCESS); static readonly int SUPUSB_IOCTL_SEND_URB = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x607, METHOD_BUFFERED, FILE_WRITE_ACCESS); + static readonly int SUPUSB_IOCTL_USB_ABORT_ENDPOINT = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x610, METHOD_BUFFERED, FILE_WRITE_ACCESS); const UInt32 USBDRV_MAJOR_VERSION = 4; const UInt32 USBDRV_MINOR_VERSION = 0; @@ -426,12 +427,13 @@ hDev.Close(); } - public unsafe override void BulkReset(byte endpoint) { + public unsafe override void PipeReset(byte endpoint) { USBSUP_CLEAR_ENDPOINT inp = new USBSUP_CLEAR_ENDPOINT() { bEndpoint = endpoint }; SyncIoControl(hDev, SUPUSB_IOCTL_USB_CLEAR_ENDPOINT, &inp, sizeof(USBSUP_CLEAR_ENDPOINT), null, 0); } - public override void InterruptReset(byte endpoint) { - BulkReset(endpoint); + public unsafe override void PipeAbort(byte endpoint) { + USBSUP_CLEAR_ENDPOINT inp = new USBSUP_CLEAR_ENDPOINT() { bEndpoint = endpoint }; + SyncIoControl(hDev, SUPUSB_IOCTL_USB_ABORT_ENDPOINT, &inp, sizeof(USBSUP_CLEAR_ENDPOINT), null, 0); } public unsafe void ResetDevice() { @@ -476,19 +478,11 @@ } } - public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { - return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_BULK, USBSUP_DIRECTION.USBSUP_DIRECTION_OUT, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); - } - public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { - return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_BULK, USBSUP_DIRECTION.USBSUP_DIRECTION_IN, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); + public override int PipeTransfer(byte endpoint, byte[] buffer, int offset, int length) { + return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_BULK, (endpoint & 0x80) == 0 ? USBSUP_DIRECTION.USBSUP_DIRECTION_OUT : USBSUP_DIRECTION.USBSUP_DIRECTION_IN, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); + //return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_INTR, USBSUP_DIRECTION.USBSUP_DIRECTION_OUT, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); } - public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { - return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_INTR, USBSUP_DIRECTION.USBSUP_DIRECTION_OUT, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); - } - public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { - return BlockTransfer(USBSUP_TRANSFER_TYPE.USBSUP_TRANSFER_TYPE_INTR, USBSUP_DIRECTION.USBSUP_DIRECTION_IN, USBSUP_XFER_FLAG.USBSUP_FLAG_NONE, endpoint, buffer, offset, length); - } - private unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public override unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { Byte[] bigbuffer = new Byte[sizeof(UsbSetupPacket) + length]; Boolean isout = (requestType & UsbControlRequestType.EndpointMask) == UsbControlRequestType.EndpointOut; if (isout && length > 0) Buffer.BlockCopy(buffer, offset, bigbuffer, sizeof(UsbSetupPacket), length); @@ -500,12 +494,6 @@ if (!isout) Buffer.BlockCopy(bigbuffer, sizeof(UsbSetupPacket), buffer, offset, dlen); return dlen; } - public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } - public override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer(requestType, request, value, index, buffer, offset, length); - } public void ClaimInterface(int interfaceID) { bInterfaceNumber = (Byte)interfaceID; diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Communication/WinUsb/WinUsbDevice.cs --- a/USBLib/Communication/WinUsb/WinUsbDevice.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Communication/WinUsb/WinUsbDevice.cs Wed Oct 16 01:11:49 2013 +0200 @@ -145,7 +145,7 @@ } } - public unsafe int ControlTransfer(byte requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { + public override unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { if (buffer == null) buffer = new Byte[0]; if (offset < 0 || length < 0 || length > short.MaxValue || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length"); SafeWinUsbInterfaceHandle ih = InterfaceHandles[0]; @@ -156,21 +156,13 @@ } fixed (Byte* b = buffer) { if (!WinUsb_ControlTransfer(ih, - new UsbSetupPacket(requestType, request, value, index, (short)length), + new UsbSetupPacket((byte)requestType, request, value, index, (short)length), (IntPtr)(b + offset), length, out length, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error(), "Control transfer failed"); return length; } } - public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer((byte)(requestType | UsbControlRequestType.EndpointOut), request, value, index, buffer, offset, length); - } - - public override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { - return ControlTransfer((byte)(requestType | UsbControlRequestType.EndpointIn), request, value, index, buffer, offset, length); - } - public unsafe override int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) { if (length > short.MaxValue || offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length"); fixed (Byte* b = buffer) { @@ -180,48 +172,27 @@ return length; } - public unsafe int PipeWrite(byte endpoint, byte[] buffer, int offset, int length) { + public override unsafe int PipeTransfer(byte endpoint, byte[] buffer, int offset, int length) { if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); SafeWinUsbInterfaceHandle ih = GetInterfaceHandleForEndpoint(endpoint); fixed (Byte* b = buffer) { - if (!WinUsb_WritePipe(ih, endpoint, (IntPtr)(b + offset), length, out length, IntPtr.Zero)) - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - return length; - } - - public unsafe int PipeRead(byte endpoint, byte[] buffer, int offset, int length) { - if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); - SafeWinUsbInterfaceHandle ih = GetInterfaceHandleForEndpoint(endpoint); - fixed (Byte* b = buffer) { - if (!WinUsb_ReadPipe(ih, endpoint, (IntPtr)(b + offset), length, out length, IntPtr.Zero)) - throw new Win32Exception(Marshal.GetLastWin32Error()); + Boolean success; + if ((endpoint & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointOut) + success = WinUsb_WritePipe(ih, endpoint, (IntPtr)(b + offset), length, out length, IntPtr.Zero); + else + success = WinUsb_ReadPipe(ih, endpoint, (IntPtr)(b + offset), length, out length, IntPtr.Zero); + if (!success) throw new Win32Exception(Marshal.GetLastWin32Error()); } return length; } - public void PipeReset(byte endpoint) { + public override void PipeReset(byte endpoint) { SafeWinUsbInterfaceHandle ih = GetInterfaceHandleForEndpoint(endpoint); WinUsb_ResetPipe(ih, endpoint); } - - public override int BulkWrite(Byte endpoint, Byte[] buffer, int offset, int length) { - return PipeWrite(endpoint, buffer, offset, length); - } - public override int BulkRead(Byte endpoint, Byte[] buffer, int offset, int length) { - return PipeRead(endpoint, buffer, offset, length); - } - public override void BulkReset(Byte endpoint) { - PipeReset(endpoint); - } - public override int InterruptWrite(Byte endpoint, Byte[] buffer, int offset, int length) { - return PipeWrite(endpoint, buffer, offset, length); - } - public override int InterruptRead(Byte endpoint, Byte[] buffer, int offset, int length) { - return PipeRead(endpoint, buffer, offset, length); - } - public override void InterruptReset(Byte endpoint) { - PipeReset(endpoint); + public override void PipeAbort(byte endpoint) { + SafeWinUsbInterfaceHandle ih = GetInterfaceHandleForEndpoint(endpoint); + WinUsb_AbortPipe(ih, endpoint); } } } \ No newline at end of file diff -r b7bc27c6734e -r 2d16447eff12 USBLib/Windows/USB/UsbDevice.cs --- a/USBLib/Windows/USB/UsbDevice.cs Tue Oct 15 16:22:54 2013 +0200 +++ b/USBLib/Windows/USB/UsbDevice.cs Wed Oct 16 01:11:49 2013 +0200 @@ -157,19 +157,14 @@ void IUsbDevice.ResetDevice() { throw new NotImplementedException(); } IUsbDeviceRegistry IUsbDevice.Registry { get { throw new NotImplementedException(); } } void IUsbInterface.Close() { } - int IUsbInterface.BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - int IUsbInterface.BulkRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - void IUsbInterface.BulkReset(byte endpoint) { throw new NotImplementedException(); } - int IUsbInterface.InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - int IUsbInterface.InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - void IUsbInterface.InterruptReset(byte endpoint) { throw new NotSupportedException(); } - int IUsbInterface.ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - int IUsbInterface.ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } - UsbPipeStream IUsbInterface.GetBulkStream(byte endpoint) { throw new NotSupportedException(); } - UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotSupportedException(); } + int IUsbInterface.PipeTransfer(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } + void IUsbInterface.PipeReset(byte endpoint) { throw new NotImplementedException(); } + void IUsbInterface.PipeAbort(byte endpoint) { throw new NotImplementedException(); } + int IUsbInterface.ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotSupportedException(); } + UsbPipeStream IUsbInterface.GetPipeStream(byte endpoint) { throw new NotSupportedException(); } void IDisposable.Dispose() { } void IUsbDevice.ClaimInterface(int interfaceID) { } - void IUsbDevice.ReleaseInterface(int interfaceID) { } + void IUsbDevice.ReleaseInterface(int interfaceID) { } #endregion } }