Recommended

Multicore community

 

Articles

Intel.com

Microsoft.co.il

 

Community

Microsoft Forums

Intel's Forum

Intel's Multicore Community

 

Resources

http://msdn.com/concurrency

Intel Multicore

NVidia Multicore GPU

 

Downloads

.Net Parallel Extensions

Intel's TBB

WinModules   

 

Tools

AsyncOp Logger

Intel thread analysis

Intel VTune

 

Contact

Asaf Shelly

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ichilov

-->

 

 

 

 

 

 
2 / 1
 
 
 
 
 
 
 
    // /  This HTML file was produced by the ProjectPublisher WebService, By Asaf Shelly                   / //
   // /    WebService URL is: http://Services.AsyncOp.com/ProjectPublisher/ProjectPublisherWSvc.asmx      / //
  // /    Learn more and find the source code here: http://AsyncOp.com                                   / //


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections;

namespace WinUSBDeviceAPI
{

   public interface WinUSBDeviceAPINotification
   {
      void OnDeviceAttach();
      void OnDeviceDetach();
      void OnReadCompletion(int ep, byte[] buffer, int lastErrorCode, object userContext);
      void OnWriteCompletion(int ep, int byteCount, int lastErrorCode, object userContext);
   }

   public interface WinUSBNotifyDevice
   {
      void OnDeviceAttach();
      void OnDeviceDetach();
   }

   public delegate void ReadCompletionDelegate(byte[] buffer, int lastErrorCode, object userContext);
   public delegate void WriteCompletionDelegate(int byteCount, int lastErrorCode, object userContext);



















   public class WinUsbDeviceApi
   {
      private IntPtr hWinUsbDevice = IntPtr.Zero;
      private SafeFileHandle hDeviceFile = null;
      protected Guid DeviceGuid = Guid.Empty;
      string DevicePath = null;
      int InterfaceNumber = -1;

      public WinUsbDeviceApi(Guid deviceGuid)
      {
         DeviceGuid = deviceGuid;
      }

      public WinUsbDeviceApi(string deviceGuidString)
      {
         DeviceGuid = new Guid(deviceGuidString);
      }

      public WinUsbDeviceApi(Guid deviceGuid, int interfaceNumber)
      {
         if (Guid.Empty == deviceGuid) throw (new Exception("null deviceGuid"));
         DeviceGuid = deviceGuid;
         InterfaceNumber = interfaceNumber;
      }

      protected void CloseWinUSB()
      {
         if (IntPtr.Zero == hWinUsbDevice) return;
         WinUsbAPI.WinUsb_Free(hWinUsbDevice); hWinUsbDevice = IntPtr.Zero;
      }

      protected void CloseHandle()
      {
         if (null == hDeviceFile) return;
         if (IntPtr.Zero != hWinUsbDevice) CloseWinUSB();
         if ((hDeviceFile.IsInvalid) || (hDeviceFile.IsClosed)) return;
         hDeviceFile.Close(); hDeviceFile = null;
      }

      public bool IsEndpointDirIn(int epNumber)
      {
         return ((epNumber & 0X80) == 0X80);
      }

      protected bool SetPipePolicy(byte pipeId, WinUsbAPI.POLICY_TYPE policyType, bool value)
      {
         byte val = Convert.ToByte(value);
         return (WinUsbAPI.WinUsb_SetPipePolicy(hWinUsbDevice, pipeId, (uint)policyType, 1, ref val));
      }

      protected bool SetPipePolicy(byte pipeId, WinUsbAPI.POLICY_TYPE policyType, byte value)
      {
         return (WinUsbAPI.WinUsb_SetPipePolicy(hWinUsbDevice, pipeId, (uint)policyType, 1, ref value));
      }

      protected bool SetPipePolicy(byte pipeId, WinUsbAPI.POLICY_TYPE policyType, uint value)
      {
         return (WinUsbAPI.WinUsb_SetPipePolicyI(hWinUsbDevice, pipeId, (uint)policyType, 4, ref value));
      }

      protected WinUsbAPI.WINUSB_PIPE_INFORMATION[] Pipes = null;
      protected bool InitPipes(WinUsbAPI.USB_INTERFACE_DESCRIPTOR ifaceDescriptor)
      {
         Pipes = new WinUsbAPI.WINUSB_PIPE_INFORMATION[ifaceDescriptor.bNumEndpoints];
         Array.Clear(Pipes, 0, Pipes.Length);
         for (byte epIndex = 0; epIndex <= ifaceDescriptor.bNumEndpoints - 1; epIndex++)
         {
            if (WinUsbAPI.WinUsb_QueryPipe(hWinUsbDevice, 0, epIndex, ref Pipes[epIndex]))
            {
               if (WinUsbAPI.USBD_PIPE_TYPE.UsbdPipeTypeBulk == Pipes[epIndex].PipeType)
               {
                  if (IsEndpointDirIn(Pipes[epIndex].PipeId))
                  {
                     SetPipePolicy(Pipes[epIndex].PipeId, WinUsbAPI.POLICY_TYPE.IGNORE_SHORT_PACKETS, false);
                     SetPipePolicy(Pipes[epIndex].PipeId, WinUsbAPI.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, 1000);
                  }
               }
            }
         }
         return (true);
      }

      protected int FindPipeIndex(byte ep)
      {
         if (null == Pipes) return (-1);
         ep = (byte)(ep & 0x0F);
         for (int index = 0; index < Pipes.Length; index++)
         {
            if (((Pipes[index].PipeId) & 0x0F) == ep) return (index);
         }
         return (-1);
      }

      public bool SetPipeTimeout(byte ep, uint timeout)
      {
         int index = FindPipeIndex(ep);
         if (-1 == index) return (false);
         // Pipes[index].PipeId instead of ep to verify 0x82 instead of 0x02 for in pipes
         return (SetPipePolicy(Pipes[index].PipeId, WinUsbAPI.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, timeout));
      }

      public bool SetPipeTimeoutInfinite(byte ep)
      {
         return (SetPipeTimeout(ep, 0));
      }

      Control DeviceNotifyTarget = null;

      public bool Activate(Control deviceNotifyTarget)
      {
         WinUSBDeviceAPINotification host = deviceNotifyTarget as WinUSBDeviceAPINotification;     // verify conversion
         DeviceNotifyTarget = deviceNotifyTarget;
         bool retval = RegisterDeviceNotification(DeviceNotifyTarget.Handle);
         if (Open()) host.OnDeviceAttach();
         return (retval);
      }

      public void Deactivate()
      {
         Close();
         if (DeviceNotifyTarget != null) { DevMgmtAPI.UnregisterDeviceNotification(DeviceNotifyTarget.Handle); DeviceNotifyTarget = null; }
      }

      public bool Open()
      {
         if (hWinUsbDevice != IntPtr.Zero) return (true);
         DevicePath = DevMgmtAPI.GetDevicePath(DeviceGuid);
         if (null == DevicePath) return (false);
         string devicePath = DevicePath;
         if ((InterfaceNumber >= 0) && (InterfaceNumber < 9)) devicePath = devicePath + "MI_0" + InterfaceNumber.ToString();
         hDeviceFile = FileIO.CreateFile(devicePath, FileIO.GENERIC_WRITE | FileIO.GENERIC_READ,
                  FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING,
                  FileIO.FILE_ATTRIBUTE_NORMAL | FileIO.FILE_FLAG_OVERLAPPED, 0)
;
         if (hDeviceFile.IsInvalid) return (false);
         if (!WinUsbAPI.WinUsb_Initialize(hDeviceFile, ref hWinUsbDevice)) { CloseHandle(); return (false); }
         WinUsbAPI.USB_INTERFACE_DESCRIPTOR ifaceDescriptor = new WinUsbAPI.USB_INTERFACE_DESCRIPTOR(0);
         if (!WinUsbAPI.WinUsb_QueryInterfaceSettings(hWinUsbDevice, 0, ref ifaceDescriptor)) { CloseWinUSB(); CloseHandle(); return (false); }
         if (!InitPipes(ifaceDescriptor)) { CloseWinUSB(); CloseHandle(); return (false); }
         return (true);
      }

      public void Close()
      {
         CloseWinUSB(); CloseHandle();
      }

      public uint ReadViaBulkTransfer(Byte pipeID, UInt32 bytesToRead, ref Byte[] buffer)
      {
         UInt32 bytesRead = 0;
         //if (!(WinUsbAPI.WinUsb_ReadPipe(hWinUsbDevice, pipeID, buffer, bytesToRead, ref bytesRead, IntPtr.Zero))) return (0);
//System.Diagnostics.Debug.WriteLine("[WinUSB] ReadViaBulkTransfer: GetLastError = "+Marshal.GetLastWin32Error().ToString());
         WinUsbAPI.WinUsb_ReadPipe(hWinUsbDevice, pipeID, buffer, bytesToRead, ref bytesRead, IntPtr.Zero);
System.Diagnostics.Debug.WriteLine("[WinUSB] ReadViaBulkTransfer: bytesRead = " + bytesRead.ToString() + " GetLastError = "+Marshal.GetLastWin32Error().ToString());
         return (bytesRead);
      }

      public uint WriteViaBulkTransfer(Byte pipeID, ref Byte[] buffer, UInt32 bytesToWrite)
      {
         UInt32 bytesWritten = 0;
         //if (!(WinUsbAPI.WinUsb_WritePipe(hWinUsbDevice, pipeID, buffer, bytesToWrite, ref bytesWritten, IntPtr.Zero))) return (0);
         WinUsbAPI.WinUsb_WritePipe(hWinUsbDevice, pipeID, buffer, bytesToWrite, ref bytesWritten, IntPtr.Zero);
         return (bytesWritten);
      }

      protected bool MatchDevice(Message msg)
      {
         int stringSize;
         DevMgmtAPI.DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new DevMgmtAPI.DEV_BROADCAST_DEVICEINTERFACE_1();
         DevMgmtAPI.DEV_BROADCAST_HDR devBroadcastHeader = new DevMgmtAPI.DEV_BROADCAST_HDR();
         Marshal.PtrToStructure(msg.LParam, devBroadcastHeader);
         if (devBroadcastHeader.dbch_devicetype != DevMgmtAPI.DBT_DEVTYP_DEVICEINTERFACE) return (false);
         stringSize = System.Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 2);
         devBroadcastDeviceInterface.dbcc_name = new Char[stringSize + 1];
         Marshal.PtrToStructure(msg.LParam, devBroadcastDeviceInterface);
         String DeviceNameString = new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
         //return(0==string.Compare(DeviceNameString,DevicePath,true));
         return (DeviceNameString.Contains(DeviceGuid.ToString()));
      }

      public bool WndProc(ref Message msg)
      {
         WinUSBDeviceAPINotification host = DeviceNotifyTarget as WinUSBDeviceAPINotification;
         if (msg.Msg == DevMgmtAPI.WM_DEVICECHANGE)
         {
            if ((msg.WParam.ToInt32() == DevMgmtAPI.DBT_DEVICEARRIVAL))
            {
               if (MatchDevice(msg))
               {
                  Open();
                  if (host != null) host.OnDeviceAttach();
                  return (true);
               }
               else return (false);
            }
            else if ((msg.WParam.ToInt32() == DevMgmtAPI.DBT_DEVICEREMOVECOMPLETE))
            {
               if (MatchDevice(msg))
               {
                  Close();
                  if (host != null) host.OnDeviceDetach();
                  return (true);
               }

               else return (false);
            }
            else return (false);
         }
         else return (false);
      }

      delegate void OnReadCompletionDelegate(int ep, byte[] buffer, int lastErrorCode, object userContext);
      delegate void OnWriteCompletionDelegate(int ep, int byteCount, int lastErrorCode, object userContext);


      IntPtr deviceNotificationHandle = IntPtr.Zero;

      internal bool RegisterDeviceNotification(IntPtr formHandle)
      {
         DevMgmtAPI.DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DevMgmtAPI.DEV_BROADCAST_DEVICEINTERFACE();
         IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
         Int32 size = 0;
         try
         {
            size = Marshal.SizeOf(devBroadcastDeviceInterface);
            devBroadcastDeviceInterface.dbcc_size = size;
            devBroadcastDeviceInterface.dbcc_devicetype = DevMgmtAPI.DBT_DEVTYP_DEVICEINTERFACE;
            devBroadcastDeviceInterface.dbcc_reserved = 0;
            devBroadcastDeviceInterface.dbcc_classguid = DeviceGuid;
            devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true);
            deviceNotificationHandle = DevMgmtAPI.RegisterDeviceNotification(formHandle, devBroadcastDeviceInterfaceBuffer, DevMgmtAPI.DEVICE_NOTIFY_WINDOW_HANDLE);
            Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface);
            return (deviceNotificationHandle != IntPtr.Zero);
         }
         catch
         {
            if (deviceNotificationHandle != IntPtr.Zero) UnregisterDeviceNotification(deviceNotificationHandle);
            throw;
         }
         finally
         {
            if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero)
            {
               Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
            }
         }
      }

      internal void UnregisterDeviceNotification(IntPtr deviceNotificationHandle)
      {
         DevMgmtAPI.UnregisterDeviceNotification(deviceNotificationHandle);
         deviceNotificationHandle = IntPtr.Zero;
      }

      public int LastError
      {
         get
         {
            return (Marshal.GetLastWin32Error());
         }
      }

      protected delegate void DeviceRWDelegate(ref Byte pipeID, ref Byte[] buffer, ref int byteCount, ref int lastError, ref object userContext);


      public byte[] ReadBlocking(byte pipeID, int byteCount)
      {
         Byte[] buffer = new Byte[byteCount];
         int lastError = -1;
         DeviceRWDelegate reader = new DeviceRWDelegate(ReadBulk);
         pipeID += (byte)0x80;      // direction:in pipe
         object userContext = null;
         IAsyncResult async = reader.BeginInvoke(ref pipeID, ref buffer, ref byteCount, ref lastError, ref userContext, null, null);
         async.AsyncWaitHandle.WaitOne();    // WinUSB sub system has timeout for each pipe
         byte[] retval = ReadCompletion(reader, async, true);
         async.AsyncWaitHandle.Close();
         System.Diagnostics.Debug.WriteLine("[WinUSB] ReadBlocking: byteCount = " + retval.Length.ToString());
         return (retval);
      }

      public void Read(Byte pipeID, int byteCount)
      {
         Read(pipeID, byteCount, null);
      }

      public void Read(Byte pipeID, int byteCount, object userContext)
      {
         Byte[] buffer = new Byte[byteCount];
         int lastError = -1;
         DeviceRWDelegate reader = new DeviceRWDelegate(ReadBulk);
         pipeID += (byte)0x80;      // direction:in pipe
         IAsyncResult async = reader.BeginInvoke(ref pipeID, ref buffer, ref byteCount, ref lastError, ref userContext, new AsyncCallback(AsyncReadCompletion), reader);
      }

      void ReadBulk(ref Byte pipeID, ref Byte[] buffer, ref int byteCount, ref int lastError, ref object userContext)
      {
         byteCount = (int)ReadViaBulkTransfer(pipeID, (uint)buffer.Length, ref buffer);
         lastError = Marshal.GetLastWin32Error();
      }

      void AsyncReadCompletion(IAsyncResult async)
      {
         ReadCompletion(async.AsyncState as DeviceRWDelegate, async, false);
      }

      byte[] ReadCompletion(DeviceRWDelegate reader, IAsyncResult async, bool blocking)
      {
         byte[] buffer = null;
         int byteCount = 0;
         int lastError = 0;
         byte[] rcvBuffer = null;
         object userContext = null;
         byte ep = 0;
         reader.EndInvoke(ref ep, ref buffer, ref byteCount, ref lastError, ref userContext, async);
System.Diagnostics.Debug.WriteLine("[WinUSB] ReadCompletion: byteCount = " + byteCount.ToString() + " / lastError = " + lastError.ToString());
         if ((997 == lastError) || ((121 == lastError) && (0 != byteCount))) lastError = 0;
            //if ((lastError != 0)&&(lastError != 997/*Pending*/)) rcvBuffer = new byte[0];
         if (lastError != 0) rcvBuffer = new byte[0];
         else if (byteCount < 1) { rcvBuffer = new byte[0]; lastError = -1; }
         else
         {
            rcvBuffer = new byte[byteCount];
            Array.Copy(buffer, rcvBuffer, rcvBuffer.Length);      // assuming that byteCount is no more than buffer.Length
         }
         if (!blocking)
         {
            if (DeviceNotifyTarget != null) DeviceNotifyTarget.Invoke(new OnReadCompletionDelegate((DeviceNotifyTarget as WinUSBDeviceAPINotification).OnReadCompletion), new object[] { ep & 0x0F, rcvBuffer, lastError, userContext });
         }
         return (rcvBuffer);
      }

      public int WriteBlocking(Byte pipeID, byte[] buffer)
      {
         return (WriteBlocking(pipeID, buffer, buffer.Length));
      }

      public int WriteBlocking(byte pipeID, byte[] buffer, int byteCount)
      {
         int lastError = -1;
         DeviceRWDelegate writer = new DeviceRWDelegate(WriteBulk);
         object userContext = null;
         IAsyncResult async = writer.BeginInvoke(ref pipeID, ref buffer, ref byteCount, ref lastError, ref userContext, null, null);
         async.AsyncWaitHandle.WaitOne();    // WinUSB sub system has timeout for each pipe
         int retval = WriteCompletion(writer, async, true);
         async.AsyncWaitHandle.Close();
         return (retval);
      }

      public void Write(Byte pipeID, byte[] buffer)
      {
         Write(pipeID, buffer, buffer.Length, null);
      }

      public void Write(Byte pipeID, byte[] buffer, object userContext)
      {
         Write(pipeID, buffer, buffer.Length, userContext);
      }

      public void Write(Byte pipeID, byte[] buffer, int byteCount)
      {
         Write(pipeID, buffer, byteCount, null);
      }

      public void Write(Byte pipeID, byte[] buffer, int byteCount, object userContext)
      {
         int lastError = -1;
         DeviceRWDelegate writer = new DeviceRWDelegate(WriteBulk);
         IAsyncResult async = writer.BeginInvoke(ref pipeID, ref buffer, ref byteCount, ref lastError, ref userContext, new AsyncCallback(AsyncWriteCompletion), writer);
      }

      void WriteBulk(ref Byte pipeID, ref Byte[] buffer, ref int byteCount, ref int lastError, ref object userContext)
      {
         byteCount = (int)WriteViaBulkTransfer(pipeID, ref buffer, (uint)buffer.Length);
         lastError = Marshal.GetLastWin32Error();
      }

      void AsyncWriteCompletion(IAsyncResult async)
      {
         WriteCompletion(async.AsyncState as DeviceRWDelegate, async, false);
      }

      int WriteCompletion(DeviceRWDelegate writer, IAsyncResult async, bool blocking)
      {
         byte[] buffer = null;
         int byteCount = 0;
         int lastError = 0;
         object userContext = null;
         byte ep = 0;
         writer.EndInvoke(ref ep, ref buffer, ref byteCount, ref lastError, ref userContext, async);
         if (997 == lastError) lastError = 0;
         if (lastError != 0) byteCount = 0;
         if (!blocking)
         {
            if (DeviceNotifyTarget != null) DeviceNotifyTarget.Invoke(new OnWriteCompletionDelegate((DeviceNotifyTarget as WinUSBDeviceAPINotification).OnWriteCompletion), new object[] { ep, byteCount, lastError, userContext });
         }
         return (byteCount);
      }




   }


















   public class WinUsbAPI
   {
      internal const UInt32 DEVICE_SPEED = ((UInt32)(1));
      internal const Byte USB_ENDPOINT_DIRECTION_MASK = ((Byte)(0X80));

      public enum POLICY_TYPE
      {
         SHORT_PACKET_TERMINATE = 1,
         AUTO_CLEAR_STALL,
         PIPE_TRANSFER_TIMEOUT,
         IGNORE_SHORT_PACKETS,
         ALLOW_PARTIAL_READS,
         AUTO_FLUSH,
         RAW_IO,
      }

      internal enum USBD_PIPE_TYPE
      {
         UsbdPipeTypeControl,
         UsbdPipeTypeIsochronous,
         UsbdPipeTypeBulk,
         UsbdPipeTypeInterrupt,
      }

      internal enum USB_DEVICE_SPEED
      {
         UsbLowSpeed = 1,
         UsbFullSpeed,
         UsbHighSpeed,
      }

      [StructLayout(LayoutKind.Sequential)]
      internal struct USB_CONFIGURATION_DESCRIPTOR
      {
         internal Byte bLength;
         internal Byte bDescriptorType;
         internal ushort wTotalLength;
         internal Byte bNumInterfaces;
         internal Byte bConfigurationValue;
         internal Byte iConfiguration;
         internal Byte bmAttributes;
         internal Byte MaxPower;
      }

      [StructLayout(LayoutKind.Sequential)]
      public 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;
         public USB_INTERFACE_DESCRIPTOR(byte initVal)
         {
            bLength = initVal;
            bDescriptorType = initVal;
            bInterfaceNumber = initVal;
            bAlternateSetting = initVal;
            bNumEndpoints = initVal;
            bInterfaceClass = initVal;
            bInterfaceSubClass = initVal;
            bInterfaceProtocol = initVal;
            iInterface = initVal;
         }
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct WINUSB_PIPE_INFORMATION
      {
         internal USBD_PIPE_TYPE PipeType;
         internal Byte PipeId;
         internal ushort MaximumPacketSize;
         internal Byte Interval;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      internal struct WINUSB_SETUP_PACKET
      {
         internal Byte RequestType;
         internal Byte Request;
         internal ushort Value;
         internal ushort Index;
         internal ushort Length;
      }

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_Free(IntPtr InterfaceHandle);

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_Initialize(SafeFileHandle DeviceHandle, ref IntPtr InterfaceHandle);

      // Use this declaration to retrieve DEVICE_SPEED (the only currently defined InformationType).

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_QueryDeviceInformation(IntPtr InterfaceHandle, UInt32 InformationType, ref UInt32 BufferLength, ref Byte Buffer);

      [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_QueryPipe(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, Byte PipeIndex, ref WINUSB_PIPE_INFORMATION PipeInformation);

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_ReadPipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);

      // Two declarations for WinUsb_SetPipePolicy.
      // Use this one when the returned Value is a Byte (all except PIPE_TRANSFER_TIMEOUT):

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_SetPipePolicy(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, UInt32 ValueLength, ref Byte Value);

      // Use this alias when the returned Value is a UInt32 (PIPE_TRANSFER_TIMEOUT only):

      [DllImport("winusb.dll", SetLastError = true, EntryPoint = "WinUsb_SetPipePolicy")]
      internal static extern Boolean WinUsb_SetPipePolicyI(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, UInt32 ValueLength, ref UInt32 Value);

      [DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_WritePipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);
   }




















   public class DevMgmtAPI
   {
      // from dbt.h

      internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
      internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
      internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
      internal const Int32 DBT_DEVTYP_HANDLE = 6;
      internal const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
      internal const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1;
      internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
      internal const Int32 WM_DEVICECHANGE = 0X219;

      // from setupapi.h

      internal const Int32 DIGCF_PRESENT = 2;
      internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;

      // Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure.

      // Use this one in the call to RegisterDeviceNotification() and
      // in checking dbch_devicetype in a DEV_BROADCAST_HDR structure:

      [StructLayout(LayoutKind.Sequential)]
      internal class DEV_BROADCAST_DEVICEINTERFACE
      {
         internal Int32 dbcc_size;
         internal Int32 dbcc_devicetype;
         internal Int32 dbcc_reserved;
         internal Guid dbcc_classguid;
         internal Int16 dbcc_name;
      }

      // Use this to read the dbcc_name String and classguid:

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
      internal class DEV_BROADCAST_DEVICEINTERFACE_1
      {
         internal Int32 dbcc_size;
         internal Int32 dbcc_devicetype;
         internal Int32 dbcc_reserved;
         [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
         internal Byte[] dbcc_classguid;
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
         internal Char[] dbcc_name;
      }

      [StructLayout(LayoutKind.Sequential)]
      internal class DEV_BROADCAST_HDR
      {
         internal Int32 dbch_size;
         internal Int32 dbch_devicetype;
         internal Int32 dbch_reserved;
      }

      internal struct SP_DEVICE_INTERFACE_DATA
      {
         internal Int32 cbSize;
         internal System.Guid InterfaceClassGuid;
         internal Int32 Flags;
         internal IntPtr Reserved;
      }

      internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
      {
         internal Int32 cbSize;
         internal String DevicePath;
      }

      internal struct SP_DEVINFO_DATA
      {
         internal Int32 cbSize;
         internal System.Guid ClassGuid;
         internal Int32 DevInst;
         internal Int32 Reserved;
      }

      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      internal static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);

      [DllImport("setupapi.dll", SetLastError = true)]
      internal static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent);

      [DllImport("setupapi.dll", SetLastError = true)]
      internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

      [DllImport("setupapi.dll", SetLastError = true)]
      internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);

      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
      internal static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);

      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
      internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);

      [DllImport("user32.dll", SetLastError = true)]
      internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle);

      internal static Boolean FindDeviceByGuid(System.Guid myGuid, ref String[] devicePathNames)
      {
         Int32 bufferSize = 0;
         IntPtr detailDataBuffer = IntPtr.Zero;
         Boolean deviceFound;
         IntPtr deviceInfoSet = new System.IntPtr();
         Boolean lastDevice = false;
         Int32 memberIndex = 0;
         SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
         Boolean success;
         ArrayList devicePathArray = new ArrayList();
         String devicePathName = null;

         devicePathNames = null;

         try
         {
            deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
            deviceFound = false;
            memberIndex = 0;
            MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData);
            do
            {
               success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref myGuid, memberIndex, ref MyDeviceInterfaceData);
               if (!success) lastDevice = true;
               else
               {
                  success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);
                  detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
                  Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
                  success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero);
                  IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);
                  devicePathName = Marshal.PtrToStringAuto(pDevicePathName);
                  deviceFound = true;
                  devicePathArray.Add(devicePathName);
               }
               memberIndex = memberIndex + 1;
            }
            while (!((lastDevice == true)));

            devicePathNames = new string[devicePathArray.Count];
            devicePathArray.CopyTo(devicePathNames);

            return deviceFound;
         }
         catch
         {
            devicePathNames = null;
            throw;
         }
         finally
         {
            if (detailDataBuffer != IntPtr.Zero) Marshal.FreeHGlobal(detailDataBuffer);
            if (deviceInfoSet != IntPtr.Zero) SetupDiDestroyDeviceInfoList(deviceInfoSet);
         }

      }

      internal static string GetDevicePath(System.Guid guid)
      {
         String[] devicePathNames = null;
         if (!FindDeviceByGuid(guid, ref devicePathNames)) return (null);
         if (null == devicePathNames) return (null);
         return (devicePathNames[0]);
      }






   }





















   internal class FileIO
   {
      internal const Int32 FILE_ATTRIBUTE_NORMAL = 0X80;
      internal const Int32 FILE_FLAG_OVERLAPPED = 0X40000000;
      internal const Int32 FILE_SHARE_READ = 1;
      internal const Int32 FILE_SHARE_WRITE = 2;
      internal const UInt32 GENERIC_READ = 0X80000000;
      internal const UInt32 GENERIC_WRITE = 0X40000000;
      internal const Int32 INVALID_HANDLE_VALUE = -1;
      internal const Int32 OPEN_EXISTING = 3;

      [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      internal static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, Int32 hTemplateFile);
   }



}