public int WriteData(byte[] wData) { if (outputReportSize == 0) { return(402); } if (false == connected) { return(406); } if (wData.Length < outputReportSize) { return(403); } if (writeRing == null) { return(405); } if (errCodeW != 0) { return(errCodeW); } if (writeRing.putIfCan(wData) == 3) { System.Threading.Thread.Sleep(1); return(404); } FileIOApiDeclarations.SetEvent(writeEvent); return(0); }
protected Int32 SendSausageCommands(ushort[] commandSequence) { if (outputReportSize != 2 || hidUsagePage != 1 || hidUsage != 6) // hid page 1, usage 6 is keyboard { return(1302); } FileIOApiDeclarations.SECURITY_ATTRIBUTES securityAttributes = new FileIOApiDeclarations.SECURITY_ATTRIBUTES(); securityAttributes.lpSecurityDescriptor = IntPtr.Zero; securityAttributes.bInheritHandle = System.Convert.ToInt32(true); securityAttributes.nLength = Marshal.SizeOf(securityAttributes); SafeFileHandle hFile = FileIOApiDeclarations.CreateFile(path, FileIOApiDeclarations.GENERIC_WRITE, FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIOApiDeclarations.OPEN_EXISTING, 0, 0); if (hFile.IsInvalid) { return(1301);; } FileIOApiDeclarations.OVERLAPPED overlapped = new FileIOApiDeclarations.OVERLAPPED(); overlapped.hEvent = 0; // IntPtr.Zero; overlapped.Offset = 0; // ; // overlapped.OffsetHigh = 0; foreach (ushort command in commandSequence) { uint cmd = ((uint)command) << 16; uint bytesReturned = 0; if (!DeviceManagementApiDeclarations.DeviceIoControl(hFile, (uint)0x000b0008, ref cmd, 4, IntPtr.Zero, 0, ref bytesReturned, ref overlapped)) { int result = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); return(result); } } hFile.Close(); return(0); }
//------------------------------------------------------------------------------------------ //---------------------------------------------------------------------------------------- protected void DataEventThread() { Byte[] currBuff = new Byte[inputReportSize]; while (dataThreadActive) { if (readRing == null) { return; } if (callNever == false) { if (errCodeR != 0) { Array.Clear(currBuff, 0, inputReportSize); holdDataThreadOpen = true; registeredDataHandler.HandlePIEHidData(currBuff, this, errCodeR); holdDataThreadOpen = false; dataThreadActive = false; } else if (readRing.get(currBuff) == 0) { holdDataThreadOpen = true; registeredDataHandler.HandlePIEHidData(currBuff, this, 0); holdDataThreadOpen = false; } if (readRing.IsEmpty()) { FileIOApiDeclarations.ResetEvent(readEvent); } } // System.Threading.Thread.Sleep(10); FileIOApiDeclarations.WaitForSingleObject(readEvent, 100); } //while return; } //DataEventThread()
/// <summary> /// Enumerates all valid USB devics of the specified Vid. /// </summary> /// <returns>list of all devices found, ordered by USB port connection</returns> public static PIEDevice[] EnumeratePIE(Int32 vid) { LinkedList <PIEDevice> devices = new LinkedList <PIEDevice>(); // Get all device paths Guid guid = Guid.Empty; HidApiDeclarations.HidD_GetHidGuid(ref guid); IntPtr deviceInfoSet = DeviceManagementApiDeclarations.SetupDiGetClassDevs(ref guid, null, IntPtr.Zero, DeviceManagementApiDeclarations.DIGCF_PRESENT | DeviceManagementApiDeclarations.DIGCF_DEVICEINTERFACE); DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); //28; LinkedList <String> paths = new LinkedList <String>(); for (int i = 0; 0 != DeviceManagementApiDeclarations.SetupDiEnumDeviceInterfaces( deviceInfoSet, 0, ref guid, i, ref deviceInterfaceData); i++) { int buffSize = 0; DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref buffSize, IntPtr.Zero); // Use IntPtr to simulate detail data structure IntPtr detailBuffer = Marshal.AllocHGlobal(buffSize); // Simulate setting cbSize to 4 bytes + one character (seems to be what everyone has always done, even though it makes no sense) //onur modified for 64-bit compatibility - March 2009 if (IntPtr.Size == 8) //64-bit { Marshal.WriteInt32(detailBuffer, Marshal.SizeOf(typeof(IntPtr))); } else //32-bit { Marshal.WriteInt32(detailBuffer, 4 + Marshal.SystemDefaultCharSize); } if (DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, detailBuffer, buffSize, ref buffSize, IntPtr.Zero)) { // convert buffer (starting past the cbsize variable) to string path paths.AddLast(Marshal.PtrToStringAuto(new IntPtr(detailBuffer.ToInt32() + 4))); } } DeviceManagementApiDeclarations.SetupDiDestroyDeviceInfoList(deviceInfoSet); //Security attributes not used anymore - not necessary Onur March 2009 // Open each device file and test for vid FileIOApiDeclarations.SECURITY_ATTRIBUTES securityAttributes = new FileIOApiDeclarations.SECURITY_ATTRIBUTES(); securityAttributes.lpSecurityDescriptor = IntPtr.Zero; securityAttributes.bInheritHandle = System.Convert.ToInt32(true); securityAttributes.nLength = Marshal.SizeOf(securityAttributes); for (LinkedList <String> .Enumerator en = paths.GetEnumerator(); en.MoveNext();) { String path = en.Current; SafeFileHandle fileHandle = FileIOApiDeclarations.CreateFile(path, FileIOApiDeclarations.GENERIC_WRITE, FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIOApiDeclarations.OPEN_EXISTING, 0, 0); if (fileHandle.IsInvalid) { // Bad handle, try next path continue; } try { HidApiDeclarations.HIDD_ATTRIBUTES hidAttributes = new HidApiDeclarations.HIDD_ATTRIBUTES(); hidAttributes.Size = Marshal.SizeOf(hidAttributes); if (0 != HidApiDeclarations.HidD_GetAttributes(fileHandle, ref hidAttributes) && hidAttributes.VendorID == vid) { // Good attributes and right vid, try to get caps IntPtr pPerparsedData = new IntPtr(); if (HidApiDeclarations.HidD_GetPreparsedData(fileHandle, ref pPerparsedData)) { HidApiDeclarations.HIDP_CAPS hidCaps = new HidApiDeclarations.HIDP_CAPS(); if (0 != HidApiDeclarations.HidP_GetCaps(pPerparsedData, ref hidCaps)) { // Got Capabilities, add device to list byte[] Mstring = new byte[128]; String ssss = "";; if (0 != HidApiDeclarations.HidD_GetManufacturerString(fileHandle, ref Mstring[0], 128)) { for (int i = 0; i < 64; i++) { byte[] t = new byte[2]; t[0] = Mstring[2 * i]; t[1] = Mstring[2 * i + 1]; if (t[0] == 0) { break; } ssss += System.Text.Encoding.Unicode.GetString(t); } } byte[] Pstring = new byte[128]; String psss = ""; if (0 != HidApiDeclarations.HidD_GetProductString(fileHandle, ref Pstring[0], 128)) { // Pstring[0] = 0xa0; Test unicode // Pstring[1] = 0x03; for (int i = 0; i < 64; i++) { byte[] t = new byte[2]; t[0] = Pstring[2 * i]; t[1] = Pstring[2 * i + 1]; if (t[0] == 0) { break; } psss += System.Text.Encoding.Unicode.GetString(t); } // psss=(System.Text.Encoding.Unicode.GetString(Pstring)).Trim(new char[]{' '}); } devices.AddLast(new PIEDevice(path, hidAttributes.VendorID, hidAttributes.ProductID, hidAttributes.VersionNumber, hidCaps.Usage, hidCaps.UsagePage, hidCaps.InputReportByteLength, hidCaps.OutputReportByteLength, ssss, psss)); } } } } catch (Exception) { continue; } finally { fileHandle.Close(); } } PIEDevice[] ret = new PIEDevice[devices.Count]; devices.CopyTo(ret, 0); return(ret); }
public void CloseInterface() { if ((holdErrorThreadOpen) || (holdDataThreadOpen)) { return; } // Shut down event thread if (dataThreadActive) { dataThreadActive = false; FileIOApiDeclarations.SetEvent(readEvent); int n = 0; if (dataThreadHandle != null) { while (dataThreadHandle.IsAlive) { Thread.Sleep(10); n++; if (n == 10) { dataThreadHandle.Abort(); break; } } dataThreadHandle = null; } } // Shut down read thread if (readThreadActive) { readThreadActive = false; // Wait for thread to exit if (readThreadHandle != null) { int n = 0; while (readThreadHandle.IsAlive) { Thread.Sleep(10); n++; if (n == 10) { readThreadHandle.Abort(); break; } } readThreadHandle = null; } } if (writeThreadActive) { writeThreadActive = false; FileIOApiDeclarations.SetEvent(writeEvent); if (writeThreadHandle != null) { int n = 0; while (writeThreadHandle.IsAlive) { Thread.Sleep(10); n++; if (n == 10) { writeThreadHandle.Abort(); break; } } writeThreadHandle = null; } } if (errorThreadActive) { errorThreadActive = false; if (errorThreadHandle != null) { int n = 0; while (errorThreadHandle.IsAlive) { Thread.Sleep(10); n++; if (n == 10) { errorThreadHandle.Abort(); break; } } errorThreadHandle = null; } } if (writeRing != null) { writeRing = null; } if (readRing != null) { readRing = null; } // if (readEvent != null) {readEvent = null;} // if (writeEvent != null) { writeEvent = null; } if ((0x00FF != pid && 0x00FE != pid && 0x00FD != pid && 0x00FC != pid && 0x00FB != pid) || version > 272) { // it's not an old VEC foot pedal (those hang when closing the handle) if (readFileHandle != null) // 9/1/09 - readFileHandle != null ||added by Onur to avoid null reference exception { if (!readFileHandle.IsInvalid) { readFileHandle.Close(); } } if (writeFileHandle != null) { if (!writeFileHandle.IsInvalid) { writeFileHandle.Close(); } } } connected = false; }
} //DataEventThread() //---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------- /// <summary> /// Sets connection to the enumerated device. /// If inputReportSize greater than zero it generates a read handle. /// If outputReportSize greater than zero it generates a write handle. /// </summary> /// <returns></returns> public Int32 SetupInterface() { int retin = 0; int retout = 0; if (connected) { return(203); } if (inputReportSize > 0) { readFileHandle = FileIOApiDeclarations.CreateFile(path, FileIOApiDeclarations.GENERIC_READ, FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIOApiDeclarations.OPEN_EXISTING, FileIOApiDeclarations.FILE_FLAG_OVERLAPPED, 0); if (readFileHandle.IsInvalid) { //readEvent = null; //readFileHandle = null; readRing = null; //CloseInterface(); retin = 207; goto outputinit; } readEvent = FileIOApiDeclarations.CreateEvent(ref securityAttrUnused, 1, 0, ""); readRing = new RngBuf2(128, inputReportSize); readThreadHandle = new Thread(new ThreadStart(ReadThread)); readThreadHandle.IsBackground = true; readThreadHandle.Name = "PIEHidReadThread for " + pid; readThreadActive = true; readThreadHandle.Start(); } outputinit: if (outputReportSize > 0) { writeFileHandle = FileIOApiDeclarations.CreateFile(path, FileIOApiDeclarations.GENERIC_WRITE, FileIOApiDeclarations.FILE_SHARE_READ | FileIOApiDeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIOApiDeclarations.OPEN_EXISTING, FileIOApiDeclarations.FILE_FLAG_OVERLAPPED, 0); if (writeFileHandle.IsInvalid) { // writeEvent = null; // writeFileHandle = null; writeRing = null; //CloseInterface(); retout = 208; goto ErrorOut; } writeEvent = FileIOApiDeclarations.CreateEvent(ref securityAttrUnused, 1, 0, ""); writeRing = new RngBuf2(128, outputReportSize); writeThreadHandle = new Thread(new ThreadStart(WriteThread)); writeThreadHandle.IsBackground = true; writeThreadHandle.Name = "PIEHidWriteThread for " + pid; writeThreadActive = true; writeThreadHandle.Start(); } connected = true; ErrorOut: if ((retin == 0) && (retout == 0)) { return(0); } if ((retin == 207) && (retout == 208)) { return(209); } else { return(retin + retout); } }
protected void ReadThread() { // FileIOApiDeclarations.SECURITY_ATTRIBUTES securityAttrUnused = new FileIOApiDeclarations.SECURITY_ATTRIBUTES(); IntPtr overlapEvent = FileIOApiDeclarations.CreateEvent(ref securityAttrUnused, 1, 0, ""); FileIOApiDeclarations.OVERLAPPED overlapped = new FileIOApiDeclarations.OVERLAPPED(); overlapped.Offset = 0; //IntPtr.Zero; overlapped.OffsetHigh = 0; overlapped.hEvent = (Int32)overlapEvent; overlapped.Internal = 0; //IntPtr.Zero; overlapped.InternalHigh = 0; //IntPtr.Zero; if (inputReportSize == 0) { errCodeR = 302; errCodeRE = 302; return; } errCodeR = 0; errCodeRE = 0; byte[] buffer = new byte[inputReportSize]; GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); //onur March 2009 - pinning is reuired while (readThreadActive) { int dataRead = 0; if (0 == FileIOApiDeclarations.ReadFile(readFileHandle, gch.AddrOfPinnedObject(), inputReportSize, ref dataRead, ref overlapped)) //ref readFileBuffer[0] { int result = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (result != FileIOApiDeclarations.ERROR_IO_PENDING) //|| result == FileIOApiDeclarations.ERROR_DEVICE_NOT_CONNECTED) { errCodeR = 307; errCodeRE = 307; goto EXit; } else //if (result != .ERROR_IO_PENDING) { // gch.Free(); //onur while (readThreadActive) { result = FileIOApiDeclarations.WaitForSingleObject(overlapEvent, 50); if (FileIOApiDeclarations.WAIT_OBJECT_0 == result) { if (0 == FileIOApiDeclarations.GetOverlappedResult(readFileHandle, ref overlapped, ref dataRead, 0)) { result = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (result == FileIOApiDeclarations.ERROR_INVALID_HANDLE || result == FileIOApiDeclarations.ERROR_DEVICE_NOT_CONNECTED) { errCodeR = 307; errCodeRE = 307; goto EXit; } } // buffer[0] = 89; goto ReadCompleted; } } //while } //if (result != .ERROR_IO_PENDING)...else continue; } //buffer[0] = 90; ReadCompleted: if (dataRead != inputReportSize) { errCodeR = 310; errCodeRE = 310; goto EXit; } if (suppressDuplicateReports) { int r = readRing.putIfDiff(buffer); if (r == 0) { FileIOApiDeclarations.SetEvent(readEvent); } } else { readRing.put(buffer); FileIOApiDeclarations.SetEvent(readEvent); } } //while EXit: FileIOApiDeclarations.CancelIo(readFileHandle); readFileHandle = null; gch.Free(); //onur return; }
//------------------------------------------------------------------------------------------- /// <summary> /// Write Thread /// </summary> protected void WriteThread() { // FileIOApiDeclarations.SECURITY_ATTRIBUTES securityAttrUnused = new FileIOApiDeclarations.SECURITY_ATTRIBUTES(); IntPtr overlapEvent = FileIOApiDeclarations.CreateEvent(ref securityAttrUnused, 1, 0, ""); FileIOApiDeclarations.OVERLAPPED overlapped = new FileIOApiDeclarations.OVERLAPPED(); overlapped.Offset = 0; //IntPtr.Zero; overlapped.OffsetHigh = 0; overlapped.hEvent = (Int32)overlapEvent; overlapped.Internal = 0; //IntPtr.Zero; overlapped.InternalHigh = 0; //IntPtr.Zero; if (outputReportSize == 0) { return; } byte[] buffer = new byte[outputReportSize]; GCHandle wgch = GCHandle.Alloc(buffer, GCHandleType.Pinned); //onur March 2009 - pinning is reuired int byteCount = 0;; // int loopCount = 0; errCodeW = 0; errCodeWE = 0; while (writeThreadActive) { if (writeRing == null) { errCodeW = 407; errCodeWE = 407; goto Error; } while (writeRing.get((byte[])buffer) == 0) { if (0 == FileIOApiDeclarations.WriteFile( writeFileHandle, wgch.AddrOfPinnedObject(), outputReportSize, ref byteCount, ref overlapped)) { int result = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (result != FileIOApiDeclarations.ERROR_IO_PENDING) // if ((result == FileIOApiDeclarations.ERROR_INVALID_HANDLE) || // (result == FileIOApiDeclarations.ERROR_DEVICE_NOT_CONNECTED)) { if (result == 87) { errCodeW = 412; errCodeWE = 412; goto Error; } errCodeW = 408; errCodeWE = 408; goto Error; } //if (result == else { // loopCount = 0; // while (writeThreadActive) // { result = FileIOApiDeclarations.WaitForSingleObject(overlapEvent, 1000); if (result == FileIOApiDeclarations.WAIT_OBJECT_0) { // errCodeWE=1400+loopCount; goto WriteCompleted; } // loopCount++; // if (loopCount > 10) // { errCodeW = 411; errCodeWE = 411; goto Error; // } /* if (0 == FileIOApiDeclarations.GetOverlappedResult(readFileHandle, ref overlapped, ref byteCount, 0)) * { * result = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); * // if (result == ERROR_INVALID_HANDLE || result == ERROR_DEVICE_NOT_CONNECTED) * if (result != FileIOApiDeclarations.ERROR_IO_INCOMPLETE) * { * errCodeW = 409; * errCodeWE = 409; * * goto Error; * }//if(result == ERROR_INVALID_HANDLE * }//if(!GetOverlappedResult*/ // }//while // goto Error; } //else if(result==ERROR_IO_PENDING){ // continue; } else { if ((long)byteCount != outputReportSize) { errCodeW = 410; errCodeWE = 410; } //iface->errCodeWE=1399; } WriteCompleted :; } //while(get== FileIOApiDeclarations.WaitForSingleObject(writeEvent, 100); FileIOApiDeclarations.ResetEvent(writeEvent); // System.Threading.Thread.Sleep(100); } Error: wgch.Free(); //onur return; }