/// <summary> /// Closes the device handle obtained with CreateFile and frees resources. /// </summary> /// <param name="deviceHandle"> Device handle obtained with CreateFile </param> /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> internal void CloseDeviceHandle(SafeFileHandle deviceHandle, SafeWinUsbHandle winUsbHandle) { try { if (!winUsbHandle.IsInvalid) { var thisLock = new Object(); lock (thisLock) { winUsbHandle.Close(); } } if (deviceHandle != null) { if (!(deviceHandle.IsInvalid)) { deviceHandle.Close(); } } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Attempts to read data from an isochronous IN endpoint. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDeviceInfo"> devInfo structure for the device </param> /// <param name="bytesToRead"> Number of bytes to read. </param> /// <param name="dataInBuffer"> Buffer for storing the bytes read. </param> /// <param name="bytesRead"> Number of bytes read. </param> /// /// <returns> true on success, false on failure </returns> /// internal void ReceiveDataViaIsochronousTransfer(SafeWinUsbHandle winUsbHandle, DeviceInfo myDeviceInfo, UInt32 bytesToRead, ref Byte[] dataInBuffer, ref UInt32 bytesRead, UInt32 numberOfPackets, ref Boolean succcess) { try { var success = false; var thisLock = new Object(); // Array that holds information about each received packet. var isoPacketDescriptors = new NativeMethods.USBD_ISO_PACKET_DESCRIPTOR[numberOfPackets]; lock (thisLock) { if (!(winUsbHandle.IsInvalid)) { IntPtr bufferHandle; success = NativeMethods.WinUsb_RegisterIsochBuffer (winUsbHandle, myDeviceInfo.IsochronousInPipe, dataInBuffer, (UInt32)dataInBuffer.Length, out bufferHandle); success = NativeMethods.WinUsb_ReadIsochPipeAsap (bufferHandle, 0, (UInt32)dataInBuffer.Length, false, numberOfPackets, ref isoPacketDescriptors[0], IntPtr.Zero); System.Console.WriteLine(Marshal.GetLastWin32Error()); success = NativeMethods.WinUsb_UnregisterIsochBuffer(bufferHandle); for (var i = 0; i <= numberOfPackets - 1; i++) { Debug.WriteLine("packet offset = " + isoPacketDescriptors[i].Offset); Debug.WriteLine("packet length = " + isoPacketDescriptors[i].Length); Debug.WriteLine("packet status = " + isoPacketDescriptors[i].Status); for (var j = 0; j < isoPacketDescriptors[i].Length; j++) { Debug.WriteLine(dataInBuffer[j]); } } } //return success; } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Attempts to send data via a bulk OUT endpoint. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDeviceInfo"> devInfo structure for the device </param> /// <param name="bytesToWrite"> Number of bytes to write. </param> /// <param name="dataBuffer"> Buffer containing the bytes to write. </param> /// <param name="bytesWritten"> The number of bytes written </param> /// <param name="success"> True on success </param> internal void SendDataViaBulkTransfer(SafeWinUsbHandle winUsbHandle, DeviceInfo myDeviceInfo, UInt32 bytesToWrite, Byte[] dataBuffer, ref UInt32 bytesWritten, ref Boolean success) { try { var thisLock = new Object(); lock (thisLock) { // *** // winusb function // summary // Attempts to write data to a device interface. // parameters // Device handle returned by WinUsb_Initialize. // Endpoint address. // Buffer with data to write. // Number of bytes to write. // Number of bytes written. // IntPtr.Zero for non-overlapped I/O. // Returns // True on success. // *** success = false; if (!(winUsbHandle.IsInvalid)) { success = NativeMethods.WinUsb_WritePipe (winUsbHandle, myDeviceInfo.BulkOutPipe, dataBuffer, bytesToWrite, ref bytesWritten, IntPtr.Zero); } if (!success) { System.Console.WriteLine(Marshal.GetLastWin32Error()); } } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Gets a value that corresponds to a USB_DEVICE_SPEED. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDevInfo"> devInfo structure for the device </param> internal static Boolean QueryDeviceSpeed(SafeWinUsbHandle winUsbHandle, ref DeviceInfo myDevInfo) { UInt32 length = 1; var speed = new Byte[1]; try { var success = false; var thisLock = new Object(); lock (thisLock) { // *** // winusb function // summary // Get the device speed. // (Normally not required but can be nice to know.) // parameters // Handle returned by WinUsb_Initialize // Requested information type. // Number of bytes to read. // Information to be returned. // returns // True on success. // *** if (!(winUsbHandle.IsInvalid)) { success = NativeMethods.WinUsb_QueryDeviceInformation (winUsbHandle, NativeMethods.DEVICE_SPEED, ref length, ref speed[0]); } if (success) { myDevInfo.DeviceSpeed = Convert.ToUInt32(speed[0]); } return(success); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Attempts to read data from an interrupt IN endpoint. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDeviceInfo"> devInfo structure for the device </param> /// <param name="bytesToRead"> Number of bytes to read. </param> /// <param name="dataBuffer"> Buffer for storing the bytes read. </param> /// <param name="bytesRead"> Number of bytes read. </param> /// /// <returns> true on success, false on failure </returns> /// internal Boolean ReceiveDataViaInterruptTransfer(SafeWinUsbHandle winUsbHandle, DeviceInfo myDeviceInfo, UInt32 bytesToRead, ref Byte[] dataBuffer, ref UInt32 bytesRead) { try { var success = false; var thisLock = new Object(); lock (thisLock) { // *** // winusb function // summary // Attempts to read data from a device interface. // parameters // Device handle returned by WinUsb_Initialize. // Endpoint address. // Buffer to store the data. // Maximum number of bytes to return. // Number of bytes read. // Null pointer for non-overlapped. // Returns // True on success. // *** if (!(winUsbHandle.IsInvalid)) { success = NativeMethods.WinUsb_ReadPipe (winUsbHandle, myDeviceInfo.InterruptInPipe, dataBuffer, bytesToRead, ref bytesRead, IntPtr.Zero); } return(success); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Sets pipe policy. /// Used when the value parameter is a Byte (all except PIPE_TRANSFER_TIMEOUT). /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="pipeId"> Pipe to set a policy for. </param> /// <param name="policyType"> POLICY_TYPE member. </param> /// <param name="value"> Policy value. </param> /// /// <returns> /// True on success, False on failure. /// </returns> /// private Boolean SetPipePolicy(SafeWinUsbHandle winUsbHandle, Byte pipeId, UInt32 policyType, Byte value) { try { var success = false; var thisLock = new Object(); lock (thisLock) { // *** // winusb function // summary // sets a pipe policy // parameters // handle returned by WinUsb_Initialize // identifies the pipe // POLICY_TYPE member. // length of value in bytes // value to set for the policy. // returns // True on success // *** if (!(winUsbHandle.IsInvalid)) { success = NativeMethods.WinUsb_SetPipePolicy (winUsbHandle, pipeId, policyType, 1, ref value); } return(success); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Attempts to send data via an isochronous OUT endpoint. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDeviceInfo"> devInfo structure for the device </param> /// <param name="bytesToWrite"> Number of bytes to write. </param> /// <param name="dataOutBuffer"> Buffer containing the bytes to write. </param> /// <param name="bytesWritten"> The number of bytes written </param> /// /// <returns> /// True on success, False on failure. /// </returns> internal Boolean SendDataViaIsochronousTransfer(SafeWinUsbHandle winUsbHandle, DeviceInfo myDeviceInfo, UInt32 bytesToWrite, Byte[] dataOutBuffer, ref UInt32 bytesWritten) { try { var success = false; var thisLock = new Object(); lock (thisLock) { if (!(winUsbHandle.IsInvalid)) { IntPtr bufferHandle; success = NativeMethods.WinUsb_RegisterIsochBuffer (winUsbHandle, myDeviceInfo.IsochronousOutPipe, dataOutBuffer, (UInt32)dataOutBuffer.Length, out bufferHandle); success = NativeMethods.WinUsb_WriteIsochPipeAsap (bufferHandle, 0, (UInt32)dataOutBuffer.Length, false, IntPtr.Zero); success = NativeMethods.WinUsb_UnregisterIsochBuffer(bufferHandle); } return(success); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
internal static extern Boolean WinUsb_SetCurrentAlternateSetting(SafeWinUsbHandle InterfaceHandle, Byte AlternateSetting);
internal static extern Boolean WinUsb_RegisterIsochBuffer(SafeWinUsbHandle InterfaceHandle, Byte PipeID, Byte[] Buffer, UInt32 BufferLength, out IntPtr BufferHandle);
internal static extern Boolean WinUsb_QueryPipe(SafeWinUsbHandle InterfaceHandle, Byte AlternateInterfaceNumber, Byte PipeIndex, ref WINUSB_PIPE_INFORMATION PipeInformation);
internal static extern Boolean WinUsb_QueryInterfaceSettings(SafeWinUsbHandle InterfaceHandle, Byte AlternateInterfaceNumber, ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);
internal static extern Boolean WinUsb_QueryDeviceInformation(SafeWinUsbHandle InterfaceHandle, UInt32 InformationType, ref UInt32 BufferLength, ref Byte Buffer);
internal static extern Boolean WinUsb_Initialize(SafeFileHandle DeviceHandle, ref SafeWinUsbHandle InterfaceHandle);
/// <summary> /// Initializes a device interface and obtains information about it. /// Calls these winusb API functions: /// WinUsb_Initialize /// WinUsb_QueryInterfaceSettings /// WinUsb_QueryPipe /// </summary> /// /// <param name="deviceHandle"> Device handle obtained with CreateFile </param> /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="myDeviceInfo"> devInfo structure for the device </param> /// <param name="pipeTimeout"> desired timeout in milliseconds for transfers </param> /// /// <returns> /// True on success, False on failure. /// </returns> internal Boolean InitializeDevice(SafeFileHandle deviceHandle, ref SafeWinUsbHandle winUsbHandle, ref DeviceInfo myDeviceInfo, UInt32 pipeTimeout) { try { // These arrays hold descriptors and pipe information for interface zero, alternate settings 0 and 1. var ifaceDescriptors = new NativeMethods.USB_INTERFACE_DESCRIPTOR[2]; var pipeInfo = new NativeMethods.WINUSB_PIPE_INFORMATION[2]; // *** // winusb function // summary // get a handle for communications with a winusb device ' // parameters // Handle returned by CreateFile. // Device handle to be returned. // returns // True on success. // *** // Lock access while attempting to create winUsbHandle. var thisLock = new Object(); lock (thisLock) { if (!winUsbHandle.IsClosed) { var success = NativeMethods.WinUsb_Initialize (deviceHandle, ref winUsbHandle); if (success) { // *** // winusb function // summary // Get a structure with information about the device interface. // parameters // handle returned by WinUsb_Initialize // alternate interface setting number // USB_INTERFACE_DESCRIPTOR structure to be returned. // returns // True on success. // Get information for the interface, including alternate setting 1 if present. // Switch to alternate setting 1 if present. //for (var interfaceSetting = 0; interfaceSetting <= 0; interfaceSetting++) for (var interfaceSetting = 0; interfaceSetting <= 1; interfaceSetting++)//original { success = NativeMethods.WinUsb_QueryInterfaceSettings (winUsbHandle, (Byte)interfaceSetting, ref ifaceDescriptors[interfaceSetting]); if (success) { // Get the transfer type, endpoint number, and direction for the interface's // endpoints. Set pipe policies. Repeat for the interface's alternate interface number. // *** // winusb function // summary // returns information about a USB pipe (endpoint address) // parameters // Handle returned by WinUsb_Initialize // Alternate interface setting number // Number of an endpoint address associated with the interface. // (The values count up from zero and are NOT the same as the endpoint address // in the endpoint descriptor.) // WINUSB_PIPE_INFORMATION structure to be returned // returns // True on success // *** for (var i = 0; i <= ifaceDescriptors[interfaceSetting].bNumEndpoints - 1; i++)//original //for (var i = 0; i <= ifaceDescriptors[interfaceSetting].bNumEndpoints - 2; i++) //for (var i = 0; i <= Math.Min(1, ifaceDescriptors[interfaceSetting].bNumEndpoints - 1); i++) //ATTENTION MODIF MANUELLE { NativeMethods.WinUsb_QueryPipe (winUsbHandle, (Byte)interfaceSetting, Convert.ToByte(i), ref pipeInfo[interfaceSetting]); if (((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionIn(pipeInfo[interfaceSetting].PipeId))) { myDeviceInfo.BulkInPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.BulkInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.BulkInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } else if (((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeBulk) & UsbEndpointDirectionOut(pipeInfo[interfaceSetting].PipeId))) { myDeviceInfo.BulkOutPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.BulkOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.BulkOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } else if ((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionIn(pipeInfo[interfaceSetting].PipeId)) { myDeviceInfo.InterruptInPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.InterruptInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.InterruptInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } else if ((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) & UsbEndpointDirectionOut(pipeInfo[interfaceSetting].PipeId)) { myDeviceInfo.InterruptOutPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.InterruptOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.InterruptOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } else if ((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeIsochronous) & UsbEndpointDirectionIn(pipeInfo[interfaceSetting].PipeId)) { myDeviceInfo.IsochronousInPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.IsochronousInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.IsochronousInPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } else if ((pipeInfo[interfaceSetting].PipeType == NativeMethods.USBD_PIPE_TYPE.UsbdPipeTypeIsochronous) & UsbEndpointDirectionOut(pipeInfo[interfaceSetting].PipeId)) { myDeviceInfo.IsochronousOutPipe = pipeInfo[interfaceSetting].PipeId; SetPipePolicy (winUsbHandle, myDeviceInfo.IsochronousOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.IGNORE_SHORT_PACKETS), Convert.ToByte(false)); SetPipePolicy (winUsbHandle, myDeviceInfo.IsochronousOutPipe, Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT), pipeTimeout); } } } if (interfaceSetting == 1) { // If possible, switch to alternate setting 1 to enable isochrononous transfers. success = NativeMethods.WinUsb_SetCurrentAlternateSetting (winUsbHandle, ifaceDescriptors[1].bAlternateSetting); } } } return(success); } return(false); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
/// <summary> /// Initiates a Control Write transfer. Data stage is host to device. /// </summary> /// /// <param name="winUsbHandle"> Handle for accessing the WinUSB device </param> /// <param name="dataStage"> The data to send. </param> /// /// <returns> /// True on success, False on failure. /// </returns> internal Boolean DoControlWriteTransfer(SafeWinUsbHandle winUsbHandle, Byte[] dataStage) { uint bytesReturned = 0; var value = Convert.ToUInt16(0); try { // Vendor-specific request to an interface with host-to-device Data stage. NativeMethods.WINUSB_SETUP_PACKET setupPacket; setupPacket.RequestType = 0X41; // The request number that identifies the specific request. setupPacket.Request = 1; // Command-specific value to send to the device. // For a request directed to an interface, the WinUSB driver uses this field to specify the interface number. // and will ignore a value set here. // For a request directed to the device, you can use this field for vendor-defined purposes. setupPacket.Index = 0; // Number of bytes in the request's Data stage. setupPacket.Length = Convert.ToUInt16(dataStage.Length); // Command-specific value to send to the device. setupPacket.Value = value; var success = false; var thisLock = new Object(); lock (thisLock) { // *** // winusb function // summary // Initiates a control transfer. // parameters // Device handle returned by WinUsb_Initialize. // WINUSB_SETUP_PACKET structure // Buffer containing the Data-stage data. // Number of data bytes to send in the Data stage. // Number of bytes sent in the Data stage. // Null pointer for non-overlapped. // Returns // True on success. // *** if (!(winUsbHandle.IsInvalid)) { success = NativeMethods.WinUsb_ControlTransfer (winUsbHandle, setupPacket, dataStage, Convert.ToUInt16(dataStage.Length), ref bytesReturned, IntPtr.Zero); } return(success); } } catch (Exception ex) { DisplayException(ModuleName, ex); throw; } }
internal static extern Boolean WinUsb_SetPipePolicy1(SafeWinUsbHandle InterfaceHandle, Byte PipeID, UInt32 PolicyType, UInt32 ValueLength, ref UInt32 Value);
internal static extern Boolean WinUsb_WritePipe(SafeWinUsbHandle InterfaceHandle, Byte PipeID, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);
internal static extern Boolean WinUsb_ControlTransfer(SafeWinUsbHandle InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);