//===================================================================================== /// <summary> /// Device-specific constructor used by the driver interface /// </summary> /// <param name="deviceNumber">The device number</param> //===================================================================================== internal McUsbInterop(DeviceInfo deviceInfo, CriticalParams criticalParams) : base(deviceInfo, criticalParams) { m_deviceInfo = deviceInfo; InitializeDevice(m_deviceInfo); if (m_errorCode == ErrorCodes.NoErrors && !m_deviceInitialized) m_errorCode = ErrorCodes.DeviceNotInitialized; // create a setup packet for reading device status m_statusPacket = new WindowsUsbSetupPacket(); m_statusPacket.RequestType = ControlRequestType.VENDOR_CONTROL_IN; m_statusPacket.Request = 0x44; m_statusPacket.Value = 0; m_statusPacket.Index = 0; m_statusPacket.Length = 2; m_statusBuffer = new byte[2]; m_maxTransferSize = 256000; }
//================================================================== /// <summary> /// Method for a USB control OUT request /// </summary> /// <returns>The result</returns> //================================================================== internal override ErrorCodes UsbControlOutRequest(UsbSetupPacket packet) { bool result; WindowsUsbSetupPacket winUsbPacket = new WindowsUsbSetupPacket(); winUsbPacket.RequestType = ControlRequestType.VENDOR_CONTROL_OUT; winUsbPacket.Request = packet.Request; winUsbPacket.Value = packet.Value; winUsbPacket.Index = packet.Index; winUsbPacket.Length = packet.Length; uint bytesTransfered = 0; //System.Diagnostics.Debug.WriteLine(String.Format("Starting Control Out transfer on thread {0}", Thread.CurrentThread.ManagedThreadId)); try { result = McUsb_ControlTransfer(m_deviceHandle, winUsbPacket, packet.Buffer, (ushort)winUsbPacket.Length, ref bytesTransfered, IntPtr.Zero); //System.Diagnostics.Debug.WriteLine(String.Format("Completed Control Out transfer on thread {0}", Thread.CurrentThread.ManagedThreadId)); } catch (Exception) { return ErrorCodes.UsbIOError; } packet.BytesTransfered = bytesTransfered; if (result == true) { return ErrorCodes.NoErrors; } else { int lastError = GetLastError(); if (lastError == 22 || lastError == 1176) return ErrorCodes.DeviceNotResponding; else if (lastError == 2 || lastError == 31) return ErrorCodes.InvalidMessage; else if (lastError == 6) return ErrorCodes.InvalidDeviceHandle; System.Diagnostics.Debug.Assert(false, String.Format("Unknown Error Code: {0}", lastError)); return ErrorCodes.UnknownError; } }
//==================================================================================================================================================================== /// <summary> /// Performs a control in or control out transfer /// </summary> /// <param name="deviceHandle">The device handle</param> /// <param name="setupPacket">A USB setup packet</param> /// <param name="buffer">The buffer containing data to send or to read back</param> /// <param name="bufferLength">The length of the buffer</param> /// <param name="lengthTransferred">The number of bytes transfered</param> /// <param name="overlapped">The overlapped struct</param> /// <returns>True if the call succeeded otherwise false</returns> //==================================================================================================================================================================== private static bool McUsb_ControlTransfer(SafeFileHandle deviceHandle, WindowsUsbSetupPacket setupPacket, byte[] buffer, uint bufferLength, ref uint lengthTransferred, IntPtr overlapped) { int bytesReturned = 0; byte[] inBuffer; byte[] outBuffer; if (setupPacket.RequestType == ControlRequestType.VENDOR_CONTROL_IN) { // Device to host - Control In Transfer inBuffer = new byte[MCWINUSB_CONTROL_TRANSFER_IN_BUFFER_SIZE + 4]; Array.Clear(inBuffer, 0, inBuffer.Length); inBuffer[0] = setupPacket.RequestType; inBuffer[1] = setupPacket.Request; inBuffer[2] = (byte)(setupPacket.Value & 0x00FF); inBuffer[3] = (byte)((setupPacket.Value >> 8) & 0x00FF); inBuffer[4] = (byte)(setupPacket.Index & 0x00FF); inBuffer[5] = (byte)((setupPacket.Index >> 8) & 0x00FF); outBuffer = new byte[MCWINUSB_CONTROL_TRANSFER_OUT_BUFFER_SIZE + bufferLength - 1]; Array.Clear(outBuffer, 0, outBuffer.Length); } else { // Host to device - Control Out Transfer inBuffer = new byte[MCWINUSB_CONTROL_TRANSFER_IN_BUFFER_SIZE + bufferLength - 1]; Array.Clear(inBuffer, 0, inBuffer.Length); inBuffer[0] = setupPacket.RequestType; inBuffer[1] = setupPacket.Request; inBuffer[2] = (byte)(setupPacket.Value & 0x00FF); inBuffer[3] = (byte)((setupPacket.Value >> 8) & 0x00FF); inBuffer[4] = (byte)(setupPacket.Index & 0x00FF); inBuffer[5] = (byte)((setupPacket.Index >> 8) & 0x00FF); // copy the length byte[] lengthParts = BitConverter.GetBytes(setupPacket.Length); Array.Copy(lengthParts, 0, inBuffer, CTRL_IN_MCLENGTH_OFFSET, lengthParts.Length); // copy the data Array.Copy(buffer, 0, inBuffer, CTRL_IN_BUFFER_OFFSET, bufferLength); outBuffer = new byte[MCWINUSB_CONTROL_TRANSFER_OUT_BUFFER_SIZE]; Array.Clear(outBuffer, 0, outBuffer.Length); } bool result; if (deviceHandle != null) { result = DeviceIoControl(deviceHandle, DeviceIOControlCodes.ControlTransfer, inBuffer, inBuffer.Length, outBuffer, outBuffer.Length, ref bytesReturned, IntPtr.Zero); } else { result = false; System.Diagnostics.Debug.Assert(false, "Device handle is null"); } // the number of bytes transferred is stored in the first four elements of outBuffer lengthTransferred = BitConverter.ToUInt32(outBuffer, 0); // get data from device to host transfer if (setupPacket.RequestType == ControlRequestType.VENDOR_CONTROL_IN) Array.Copy(outBuffer, 4, buffer, 0, lengthTransferred); return result; }