www.pudn.com > USBWinTest.rar > KHM32_USBHID.cs, change:2013-05-28,size:19810b


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Collections; 
using System.Threading; 
using System.ComponentModel; 
using System.Data; 
using System.Text.RegularExpressions; 
 
namespace KHM32_USBHID 
{ 
    public class UsbControl 
    { 
        #region Data Struct 
        // HIDP_CAPS 
        [StructLayout(LayoutKind.Sequential)] 
        internal unsafe struct HIDP_CAPS 
        { 
            public System.UInt16 Usage;					// USHORT 
            public System.UInt16 UsagePage;				// USHORT 
            public System.UInt16 InputReportByteLength; 
            public System.UInt16 OutputReportByteLength; 
            public System.UInt16 FeatureReportByteLength; 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] 
            public System.UInt16[] Reserved;				// USHORT  Reserved[17];			 
            public System.UInt16 NumberLinkCollectionNodes; 
            public System.UInt16 NumberInputButtonCaps; 
            public System.UInt16 NumberInputValueCaps; 
            public System.UInt16 NumberInputDataIndices; 
            public System.UInt16 NumberOutputButtonCaps; 
            public System.UInt16 NumberOutputValueCaps; 
            public System.UInt16 NumberOutputDataIndices; 
            public System.UInt16 NumberFeatureButtonCaps; 
            public System.UInt16 NumberFeatureValueCaps; 
            public System.UInt16 NumberFeatureDataIndices; 
        } 
 
        [StructLayout(LayoutKind.Sequential)] 
        internal class SP_DEVINFO_DATA 
        { 
            public int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); 
            public Guid classGuid = Guid.Empty; // temp 
            public int devInst = 0; // dumy 
            public int reserved = 0; 
        } 
 
        [StructLayout(LayoutKind.Sequential, Pack = 2)] 
        internal struct SP_DEVICE_INTERFACE_DETAIL_DATA 
        { 
            internal int cbSize; 
            internal short devicePath; 
        } 
 
        internal enum DIGCF 
        { 
            DIGCF_DEFAULT = 0x1, 
            DIGCF_PRESENT = 0x2, 
            DIGCF_ALLCLASSES = 0x4, 
            DIGCF_PROFILE = 0x8, 
            DIGCF_DEVICEINTERFACE = 0x10 
        } 
 
        internal struct SP_DEVICE_INTERFACE_DATA 
        { 
            public int cbSize; 
            public Guid interfaceClassGuid; 
            public int flags; 
            public int reserved; 
        } 
 
        public struct HIDD_ATTRIBUTES 
        { 
            int Size; 
            int VendorID; 
            int ProductID; 
            int VersionNumber; 
        } 
        [StructLayout(LayoutKind.Sequential)] 
        public struct LASTINPUTINFO 
        { 
            [MarshalAs(UnmanagedType.U4)] 
            public int cbSize; 
            [MarshalAs(UnmanagedType.U4)] 
            public uint dwTime; 
        } 
        #endregion 
          
        #region DllImport 
        //Get GUID 
        [DllImport("hid.dll")] 
        internal static extern void HidD_GetHidGuid(ref Guid HidGuid); 
 
        //Get Device Detail Information 
        [DllImport("hid.dll", SetLastError = true)] 
        internal unsafe static extern int HidP_GetCaps( 
            int pPHIDP_PREPARSED_DATA,					// IN PHIDP_PREPARSED_DATA  PreparsedData, 
            ref HIDP_CAPS myPHIDP_CAPS);				// OUT PHIDP_CAPS  Capabilities 
 
        [DllImport("hid.dll", SetLastError = true)] 
        internal unsafe static extern int HidD_GetPreparsedData( 
            int hObject,								// IN HANDLE  HidDeviceObject, 
            ref int pPHIDP_PREPARSED_DATA); 
 
        //Filter device 
        [DllImport("setupapi.dll", SetLastError = true)] 
        internal static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, uint Enumerator, IntPtr HwndParent, DIGCF Flags); 
 
        //Release device 
        [DllImport("setupapi.dll", SetLastError = true)] 
        internal static extern IntPtr SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); 
 
        //Get Device,true --Get success,false--Get NG 
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData); 
 
        // Get Interface detail information ,must use two timers,first for get length,second for get data 
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
        internal static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, 
            int deviceInterfaceDetailDataSize, ref int requiredSize, SP_DEVINFO_DATA deviceInfoData); 
 
        //Connect 
        [DllImport("kernel32.dll", SetLastError = true)] 
        internal static extern int CreateFile( 
            string lpFileName,							// file name 
            uint dwDesiredAccess,						// access mode 
            uint dwShareMode,							// share mode 
            uint lpSecurityAttributes,					// SD 
            uint dwCreationDisposition,					// how to create 
            uint dwFlagsAndAttributes,					// file attributes 
            uint hTemplateFile							// handle to template file 
            ); 
 
         
 
        [DllImport("hid.dll")] 
        static public extern bool HidD_GetAttributes(IntPtr handleid, ref HIDD_ATTRIBUTES hidd); 
 
        //Get Device Data 
        [DllImport("Kernel32.dll", SetLastError = true)] 
        internal static extern bool ReadFile 
            ( 
                IntPtr hFile, 
                byte[] lpBuffer, 
                uint nNumberOfBytesToRead, 
                ref uint lpNumberOfBytesRead, 
                IntPtr lpOverlapped 
            ); 
 
        //Release Data 
        [DllImport("hid.dll")] 
        internal static extern bool HidD_FreePreparsedData(ref IntPtr PreparsedData); 
 
        //Close (stop visit)  Device  
        [DllImport("kernel32.dll")] 
        internal static extern int CloseHandle(int hObject); 
 
 
 
        #endregion 
        #region Event 
        public class DataRevEventArgs : EventArgs 
        { 
            public int[] iDuty; 
            public DataRevEventArgs(int[] iDuty) 
            { 
                this.iDuty = iDuty; 
                return; 
            } 
        } 
        public delegate void DataRevEventHandler(object sender, DataRevEventArgs MRevEventArgs); 
        public event DataRevEventHandler MessageReceived; 
        private void EventTrigger(int[] data) 
        { 
            if (this.MessageReceived != null) 
            { 
                DataRevEventArgs objMRevEventArgs = new DataRevEventArgs(data); 
 
                this.MessageReceived(this, objMRevEventArgs); 
            } 
            return; 
        } 
        #endregion 
        public UsbControl() 
        { 
 
        } 
      //  TelIntaface _TheUser; 
 
        #region HID Control ID 
        internal int HidHandle = -1; 
         
        private const uint GENERIC_READ = 0x80000000; 
        private const uint GENERIC_WRITE = 0x40000000; 
        private const uint FILE_SHARE_READ = 0x00000001; 
        private const uint FILE_SHARE_WRITE = 0x00000002; 
        private const int OPEN_EXISTING = 3; 
        //read status, true--reading, false--no reading 
        private bool Status = false; 
        private ArrayList HIDUSBAddress = ArrayList.Synchronized(new ArrayList()); 
        #endregion 
 
        #region Global Variables 
        string InDriveName = ""; 
        Thread thread; 
        string giVID = ""; 
        string giPID = ""; 
 
        string giVIDCfg = "vid_"; 
        string giPIDCfg = "pid_"; 
 
        #endregion 
 
        #region Public Function for App Use 
        //Check Device ,0--OK,-1--false 
        public int OpenKHM32(string VID, string PID) 
        { 
            //int []data1 = new int[12]; 
            giVID = VID; 
            giPID = PID; 
           // EventTrigger(data1); 
            bool DivCheck = UsbConnect(VID,PID); 
            if(DivCheck == false) 
            { 
                return -1; 
            } 
            else 
            { 
                return 0; 
            } 
        } 
 
        //Close Device and Thread,0--OK,-1--false 
        public int CloseKHM32() 
        { 
            try 
            { 
                thread.Abort(); 
                EndUsbRead(); 
                return 0; 
            } 
            catch 
            { 
                return -1; 
            } 
        } 
        //Start read data from USB Device ,0--reading,-1--can't reading 
        public int StartCommunication() 
        { 
             
            if(InDriveName == "") 
            { 
                return -1; 
            } 
            else 
            { 
                thread = new Thread(new ThreadStart(BeginRead)); 
                thread.Start(); 
                return 0; 
            } 
        } 
        #endregion 
 
        #region private functon 
        private void BeginRead() 
        { 
            int[] data1 = new int[12]; 
            EventTrigger(data1); 
            while (true) 
            { 
                bool result = BeginUsbRead(); 
            } 
        }   
 
        //check VID,PID,DID 
        private bool CheckDeviceName(string Name, string VID, string PID) 
        { 
 
            string tmpVID = ""; 
            string tmpPID = ""; 
 
            int pivcount = 0;//position of the VID,PID,DID in Name 
 
            Regex VD = new Regex(giVIDCfg, RegexOptions.IgnoreCase); 
            Regex PD = new Regex(giPIDCfg, RegexOptions.IgnoreCase); 
 
 
            MatchCollection matches_VD = VD.Matches(Name); 
            MatchCollection matches_PD = PD.Matches(Name); 
 
            if (matches_VD.Count > 0) 
            { 
                char[] c = Name.ToCharArray(); 
                foreach (Match match in matches_VD) 
                { 
                    GroupCollection groups = match.Groups; 
                    pivcount = groups[0].Index + match.Length; 
                    for (int i = pivcount; i < pivcount + 4; i++) 
                    { 
                        tmpVID = tmpVID + c[i];//Get VID name 
                    } 
                } 
            } 
            if (matches_PD.Count > 0) 
            { 
                char[] c = Name.ToCharArray(); 
                foreach (Match match in matches_PD) 
                { 
                    GroupCollection groups = match.Groups; 
                    pivcount = groups[0].Index + match.Length; 
                    for (int i = pivcount; i < pivcount + 4; i++) 
                    { 
                        tmpPID = tmpPID + c[i];//Get PID name 
                    } 
                } 
            } 
 
            //check VID,PID,DID same? 
            if ((tmpVID == VID) && (tmpPID == PID)) 
            { 
                return true; 
            } 
            else 
            { 
                return false; 
            } 
        } 
 
 
        //read data 
        private bool BeginUsbRead() 
        { 
            if (HIDUSBAddress.Count > 0) 
            { 
                //建立连接并设置状态为true 
                int result = CT_CreateFile(HIDUSBAddress); 
                
                if (result != 1) 
                { 
                    return false; 
                } 
                else 
                { 
                    //get report length 
                    int reportLength = GetReportLenth(); 
                  //  if (reportLength != 200) 
                  //  { 
                  //      return false; 
                  //  } 
                    Status = true; 
                    //read data 
                    result = ReadUsbData(reportLength); 
                } 
                return true; 
            } 
            else 
            { 
                return false; 
            } 
        } 
 
        //get report length 
        private int GetReportLenth() 
        { 
            int myPtrToPreparsedData = -1; 
            int result1 = HidD_GetPreparsedData(HidHandle, ref myPtrToPreparsedData); 
            HIDP_CAPS myHIDP_CAPS = new HIDP_CAPS(); 
            int result2 = HidP_GetCaps(myPtrToPreparsedData, ref myHIDP_CAPS); 
            int reportLength = myHIDP_CAPS.InputReportByteLength; 
            return reportLength; 
        } 
 
        //end read 
        private void EndUsbRead() 
        { 
            //修改状态为false,读取数据循环自动结束 
            Status = false; 
 //           Thread.Sleep(10); 
            Dispost(); 
        } 
 
        //close device 
        private void Dispost() 
        { 
            //release resource 
            SetupDiDestroyDeviceInfoList(hDevInfo); 
            //close connect 
            CloseHandle(HidHandle); 
        } 
        #endregion 
 
        #region Device Operation  
        IntPtr hDevInfo; 
        private bool UsbConnect(string VID, string PID) 
        { 
            try 
            { 
                //Clear Device List 
                HIDUSBAddress.Clear(); 
                //Get HID Device 
                Guid guidHID = Guid.Empty; 
                HidD_GetHidGuid(ref guidHID); 
 
                //filter HID Device 
                hDevInfo = SetupDiGetClassDevs(ref guidHID, 0, IntPtr.Zero, DIGCF.DIGCF_PRESENT | DIGCF.DIGCF_DEVICEINTERFACE); 
 
                int index = 0; 
                while (true) 
                { 
                    //get device information 
                    SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); 
                    DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData); 
                    bool result = SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref guidHID, (UInt32)index, ref DeviceInterfaceData); 
                    //find no device ,break 
                    if (result == false) 
                        break; 
 
                    //get device path  
                    //first use return Size 
                    int bufferSize = 0; 
                    SP_DEVINFO_DATA strtInterfaceData = new SP_DEVINFO_DATA(); 
                    result = SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, strtInterfaceData); 
                    //second get value 
                    IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize); 
                    SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new SP_DEVICE_INTERFACE_DETAIL_DATA(); 
                    detailData.cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); 
                    Marshal.StructureToPtr(detailData, detailDataBuffer, false); 
                    result = SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, strtInterfaceData); 
                    //get device error ,return 
                    if (result == false) 
                        return false; 
 
                    //get device path 
                    IntPtr pdevicePathName = (IntPtr)((int)detailDataBuffer + 4); 
                    string devicePathName = Marshal.PtrToStringAuto(pdevicePathName); 
                    if(CheckDeviceName(devicePathName,VID,PID)) 
//                    if (devicePathName.IndexOf(DriveName.ToLower()) > 0) 
                    { 
                        InDriveName = devicePathName; 
                        HIDUSBAddress.Add(devicePathName); 
                        break;  
                    } 
                    index++; 
                } 
                if (HIDUSBAddress.Count > 0) 
                { 
                    return true; 
                } 
                else 
                { 
                    return false; 
                } 
            } 
            catch 
            { 
                return false; 
            } 
        } 
 
        private int ReadUsbData(int reportLength) //report length 
        { 
            try 
            { 
                while (Status) 
                { 
                    try 
                    { 
                        if (HidHandle == -1) 
                        { 
                            Thread.Sleep(1000); 
                            if (UsbConnect(giVID, giPID)) 
                            { 
                                CT_CreateFile(HIDUSBAddress); 
                                if (HidHandle != -1) 
                                    reportLength = GetReportLenth(); 
                            } 
                            continue; 
                        } 
                        uint read = 0; 
                        Byte[] m_rd_data = new Byte[reportLength]; 
                        bool isread = ReadFile((IntPtr)HidHandle, m_rd_data, (uint)reportLength, ref read, IntPtr.Zero); 
    
                        Byte[] m_rd_dataout = new Byte[read]; 
                        Array.Copy(m_rd_data, m_rd_dataout, read); 
 
                        //get data error ,device can't find ,reconnect device till get end Instruction   
                        if (m_rd_dataout.Length == 0) 
                        { 
                            Thread.Sleep(1000); 
                            if (UsbConnect(giVID, giPID)) 
                            { 
                                CT_CreateFile(HIDUSBAddress); 
                                if (HidHandle != -1) 
                                    reportLength = GetReportLenth(); 
                            } 
                            continue; 
                        } 
 
                        int[] data = new int[reportLength]; 
                        for (int i = 0; i < reportLength; i++) 
                        { 
                            data[i] = (Convert.ToInt32("0x" + m_rd_dataout[i].ToString("X2"), 16)); 
                        } 
                        EventTrigger(data); 
 //                       _TheUser.DealData(data); 
                    } 
                    catch 
                    { 
                        if (UsbConnect(giVID, giPID)) 
                        { 
                            CT_CreateFile(HIDUSBAddress); 
                            if (HidHandle != -1) 
                                reportLength = GetReportLenth(); 
                        } 
                        continue; 
                    } 
                } 
                return 0;//dead data end 
            } 
            catch (Exception ex) 
            { 
                throw ex; 
            } 
        } 
 
        private unsafe int CT_CreateFile(ArrayList list) 
        { 
            bool IsFind = false; 
            foreach (object o in list) 
            { 
                string DeviceName = (string)o; 
                int Handle = CreateFile( 
                    DeviceName, 
                    GENERIC_READ,// | GENERIC_WRITE, 
                    FILE_SHARE_READ,// | FILE_SHARE_WRITE, 
                    0, 
                    OPEN_EXISTING, 
                    0, 
                    0); 
                if (Handle == -1) 
                { 
 
                } 
                else 
                { 
                    HIDD_ATTRIBUTES hidd_my = new HIDD_ATTRIBUTES(); 
                    HidD_GetAttributes((IntPtr)Handle, ref hidd_my); 
                    HidHandle = Handle; 
                    IsFind = true; 
                } 
            } 
            if (IsFind == true) 
                return 1; 
            else 
                return 0; 
        } 
        #endregion 
    } 
}