private bool WriteData(byte[] data, int timeout) { if (_deviceCapabilities.OutputReportByteLength <= 0) { return(false); } uint bytesWritten = 0; // Optimization: Don't create a new buffer & copy if given data array is of sufficient size. byte[] buffer; if (data.Length == _deviceCapabilities.OutputReportByteLength) { buffer = data; } else { buffer = CreateOutputBuffer(); Array.Copy(data, 0, buffer, 0, Math.Min(data.Length, _deviceCapabilities.OutputReportByteLength)); } // TODO: Do that thing that tells the CLR not to move the 'byte[] data' object around in memory. // As there may be a race condition if the location moves during the Write() Win32 call. if (_deviceWriteMode == DeviceMode.Overlapped) { var security = new NativeMethods.SECURITY_ATTRIBUTES(); var overlapped = new NativeOverlapped(); var overlapTimeout = timeout <= 0 ? NativeMethods.WAIT_INFINITE : timeout; security.lpSecurityDescriptor = IntPtr.Zero; security.bInheritHandle = true; security.nLength = Marshal.SizeOf(security); overlapped.OffsetLow = 0; overlapped.OffsetHigh = 0; overlapped.EventHandle = NativeMethods.CreateEvent(ref security, Convert.ToInt32(false), Convert.ToInt32(true), ""); try { NativeMethods.WriteFile(Handle, buffer, (uint)buffer.Length, out bytesWritten, ref overlapped); } catch { return(false); } var result = NativeMethods.WaitForSingleObject(overlapped.EventHandle, overlapTimeout); switch (result) { case NativeMethods.WAIT_OBJECT_0: NativeMethods.CloseHandle(overlapped.EventHandle); return(true); case NativeMethods.WAIT_TIMEOUT: return(false); case NativeMethods.WAIT_FAILED: return(false); default: return(false); } } else { try { var overlapped = new NativeOverlapped(); return(NativeMethods.WriteFile(Handle, buffer, (uint)buffer.Length, out bytesWritten, ref overlapped)); } catch { return(false); } } }
private static void CloseDeviceIO(IntPtr handle) { NativeMethods.CloseHandle(handle); }