public override unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { SafeWinUsbInterfaceHandle ih = PrepareControlTransfer(requestType, index, ref buffer, offset, length); fixed(Byte *b = buffer) { if (!WinUsb_ControlTransfer(ih, new UsbSetupPacket((byte)requestType, request, value, index, (short)length), (IntPtr)(b + offset), length, out length, IntPtr.Zero)) { throw new Win32Exception(); } return(length); } }
public override unsafe IAsyncResult BeginControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length, AsyncCallback callback, Object state) { SafeWinUsbInterfaceHandle ih = PrepareControlTransfer(requestType, index, ref buffer, offset, length); WindowsOverlappedAsyncResult ar = new WindowsOverlappedAsyncResult(callback, state); try { fixed(Byte *b = buffer) { Boolean success = WinUsb_ControlTransfer(ih, new UsbSetupPacket((byte)requestType, request, value, index, (short)length), (IntPtr)(b + offset), length, out length, (IntPtr)ar.PackOverlapped(buffer)); ar.SyncResult(success, length); return(ar); } } catch { ar.ErrorCleanup(); throw; } }
SafeWinUsbInterfaceHandle PrepareControlTransfer(UsbControlRequestType requestType, short index, ref 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]; switch ((UsbControlRequestType)requestType & UsbControlRequestType.RecipMask) { case UsbControlRequestType.RecipInterface: ih = GetInterfaceHandle(index & 0xff); break; case UsbControlRequestType.RecipEndpoint: ih = GetInterfaceHandleForEndpoint(index & 0xff); break; case UsbControlRequestType.RecipOther: break; } return(ih); }
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) { if (!WinUsb_GetDescriptor(InterfaceHandles[0], descriptorType, index, (ushort)langId, (IntPtr)(b + offset), length, out length)) { throw new Win32Exception(); } } return(length); } unsafe Boolean BeginPipeTransfer(byte endpoint, byte[] buffer, int offset, ref int length, IntPtr overlapped) { 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 ((endpoint & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointOut) { return(WinUsb_WritePipe(ih, endpoint, (IntPtr)(b + offset), length, out length, overlapped)); } else { return(WinUsb_ReadPipe(ih, endpoint, (IntPtr)(b + offset), length, out length, overlapped)); } } }
private static extern bool WinUsb_WritePipe(SafeWinUsbInterfaceHandle InterfaceHandle, byte PipeID, IntPtr pBuffer, int BufferLength, out int LengthTransferred, IntPtr pOVERLAPPED);
private static extern bool WinUsb_ResetPipe(SafeWinUsbInterfaceHandle InterfaceHandle, byte PipeID);
private static extern bool WinUsb_GetDescriptor(SafeWinUsbInterfaceHandle InterfaceHandle, byte DescriptorType, byte Index, ushort LanguageID, IntPtr Buffer, int BufferLength, out int LengthTransferred);
private static extern bool WinUsb_ControlTransfer(SafeWinUsbInterfaceHandle InterfaceHandle, UsbSetupPacket SetupPacket, IntPtr Buffer, int BufferLength, out int LengthTransferred, IntPtr pOVERLAPPED);
internal static extern bool WinUsb_GetAssociatedInterface(SafeWinUsbInterfaceHandle InterfaceHandle, byte AssociatedInterfaceIndex, out SafeWinUsbInterfaceHandle AssociatedInterfaceHandle);
static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, out SafeWinUsbInterfaceHandle InterfaceHandle);