public unsafe override void Write(byte[] buffer, int offset, int count) { Throw.If.OutOfRange(buffer, offset, count); uint bytesTransferred; IntPtr @event = NativeMethods.CreateManualResetEventOrThrow(); HandleAcquireIfOpenOrFail(); UpdateSettings(); try { fixed(byte *ptr = buffer) { var overlapped = stackalloc NativeOverlapped[1]; overlapped[0].EventHandle = @event; NativeMethods.OverlappedOperation(_handle, @event, WriteTimeout, _closeEventHandle, NativeMethods.WriteFile(_handle, ptr + offset, count, IntPtr.Zero, overlapped), overlapped, out bytesTransferred); if (bytesTransferred != count) { throw new IOException("Write failed."); } } } finally { HandleRelease(); NativeMethods.CloseHandle(@event); } }
internal WinBleStream(WinBleDevice device, WinBleService service) : base(device, service) { _closeEventHandle = NativeMethods.CreateManualResetEventOrThrow(); _watchEventHandle = NativeMethods.CreateManualResetEventOrThrow(); _watchEvents = new Queue <BleEvent>(); _watchMap = new Dictionary <ushort, BleCharacteristic>(); }
public unsafe override void Write(byte[] buffer, int offset, int count) { Throw.If.OutOfRange(buffer, offset, count); uint bytesTransferred; IntPtr @event = NativeMethods.CreateManualResetEventOrThrow(); HandleAcquireIfOpenOrFail(); try { lock (_writeSync) { int minOut = Device.GetMaxOutputReportLength(); if (minOut <= 0) { throw new IOException("Can't write to this device."); } if (_writeBuffer == null || _writeBuffer.Length < Math.Max(count, minOut)) { Array.Resize(ref _writeBuffer, Math.Max(count, minOut)); } Array.Copy(buffer, offset, _writeBuffer, 0, count); if (count < minOut) { Array.Clear(_writeBuffer, count, minOut - count); count = minOut; } fixed(byte *ptr = _writeBuffer) { int offset0 = 0; while (count > 0) { var overlapped = stackalloc NativeOverlapped[1]; overlapped[0].EventHandle = @event; NativeMethods.OverlappedOperation(_handle, @event, WriteTimeout, _closeEventHandle, NativeMethods.WriteFile(_handle, ptr + offset0, Math.Min(minOut, count), IntPtr.Zero, overlapped), overlapped, out bytesTransferred); count -= (int)bytesTransferred; offset0 += (int)bytesTransferred; } } } } finally { HandleRelease(); NativeMethods.CloseHandle(@event); } }
// Buffer needs to be big enough for the largest report, plus a byte // for the Report ID. public unsafe override int Read(byte[] buffer, int offset, int count) { Throw.If.OutOfRange(buffer, offset, count); uint bytesTransferred; IntPtr @event = NativeMethods.CreateManualResetEventOrThrow(); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int minIn = Device.GetMaxInputReportLength(); if (minIn <= 0) { throw new IOException("Can't read from this device."); } if (_readBuffer == null || _readBuffer.Length < Math.Max(count, minIn)) { Array.Resize(ref _readBuffer, Math.Max(count, minIn)); } fixed(byte *ptr = _readBuffer) { var overlapped = stackalloc NativeOverlapped[1]; overlapped[0].EventHandle = @event; NativeMethods.OverlappedOperation(_handle, @event, ReadTimeout, _closeEventHandle, NativeMethods.ReadFile(_handle, ptr, Math.Max(count, minIn), IntPtr.Zero, overlapped), overlapped, out bytesTransferred); if (count > (int)bytesTransferred) { count = (int)bytesTransferred; } Array.Copy(_readBuffer, 0, buffer, offset, count); return(count); } } } finally { HandleRelease(); NativeMethods.CloseHandle(@event); } }
// Buffer needs to be big enough for the largest report, plus a byte // for the Report ID. public unsafe override int Read(byte[] buffer, int offset, int count) { Throw.If.OutOfRange(buffer, offset, count); uint bytesTransferred; IntPtr @event = NativeMethods.CreateManualResetEventOrThrow(); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int maxIn = _device.MaxInputReportLength; Array.Resize(ref _readBuffer, maxIn); if (count > maxIn) { count = maxIn; } fixed(byte *ptr = _readBuffer) { var overlapped = stackalloc NativeOverlapped[1]; overlapped[0].EventHandle = @event; NativeMethods.OverlappedOperation(_handle, @event, ReadTimeout, _closeEventHandle, NativeMethods.ReadFile(_handle, ptr, maxIn, IntPtr.Zero, overlapped), overlapped, out bytesTransferred); if (count > (int)bytesTransferred) { count = (int)bytesTransferred; } Array.Copy(_readBuffer, 0, buffer, offset, count); return(count); } } } finally { HandleRelease(); NativeMethods.CloseHandle(@event); } }
public unsafe override void Write(byte[] buffer, int offset, int count) { Throw.If.OutOfRange(buffer, offset, count); uint bytesTransferred; IntPtr @event = NativeMethods.CreateManualResetEventOrThrow(); HandleAcquireIfOpenOrFail(); try { lock (_writeSync) { int maxOut = _device.MaxOutputReportLength; Array.Resize(ref _writeBuffer, maxOut); if (count > maxOut) { count = maxOut; } Array.Copy(buffer, offset, _writeBuffer, 0, count); count = maxOut; fixed(byte *ptr = _writeBuffer) { int offset0 = 0; while (count > 0) { var overlapped = stackalloc NativeOverlapped[1]; overlapped[0].EventHandle = @event; NativeMethods.OverlappedOperation(_handle, @event, WriteTimeout, _closeEventHandle, NativeMethods.WriteFile(_handle, ptr + offset0, count, IntPtr.Zero, overlapped), overlapped, out bytesTransferred); count -= (int)bytesTransferred; offset0 += (int)bytesTransferred; } } } } finally { HandleRelease(); NativeMethods.CloseHandle(@event); } }
internal WinHidStream(WinHidDevice device) : base(device) { _closeEventHandle = NativeMethods.CreateManualResetEventOrThrow(); }
internal WinHidStream() { _closeEventHandle = NativeMethods.CreateManualResetEventOrThrow(); }
protected override void Run(Action readyCallback) { const string className = "HidSharpDeviceMonitor"; NativeMethods.WindowProc windowProc = DeviceMonitorWindowProc; var wc = new NativeMethods.WNDCLASS() { ClassName = className, WindowProc = windowProc }; RunAssert(0 != NativeMethods.RegisterClass(ref wc), "HidSharp RegisterClass failed."); var hwnd = NativeMethods.CreateWindowEx(0, className, className, 0, NativeMethods.CW_USEDEFAULT, NativeMethods.CW_USEDEFAULT, NativeMethods.CW_USEDEFAULT, NativeMethods.CW_USEDEFAULT, NativeMethods.HWND_MESSAGE, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); RunAssert(hwnd != IntPtr.Zero, "HidSharp CreateWindow failed."); var hidNotifyHandle = RegisterDeviceNotification(hwnd, NativeMethods.HidD_GetHidGuid()); var bleNotifyHandle = RegisterDeviceNotification(hwnd, NativeMethods.GuidForBluetoothLEDevice); #if BLUETOOTH_NOTIFY var bleHandles = new List <BleRadio>(); // FIXME: We don't handle the removal of USB Bluetooth dongles here, as far as notifications go. IntPtr searchHandle, radioHandle; var searchParams = new NativeMethods.BLUETOOTH_FIND_RADIO_PARAMS() { Size = Marshal.SizeOf(typeof(NativeMethods.BLUETOOTH_FIND_RADIO_PARAMS)) }; searchHandle = NativeMethods.BluetoothFindFirstRadio(ref searchParams, out radioHandle); if (searchHandle != IntPtr.Zero) { do { var radio = new BleRadio(); radio.RadioHandle = radioHandle; radio.NotifyHandle = RegisterDeviceNotification(hwnd, radioHandle); bleHandles.Add(radio); }while (NativeMethods.BluetoothFindNextRadio(searchHandle, out radioHandle)); NativeMethods.BluetoothFindRadioClose(searchHandle); } if (bleHandles.Count > 0) { HidSharpDiagnostics.Trace("Found {0} Bluetooth radio(s).", bleHandles.Count); } #endif //_bleDiscoveryThread = new Thread(BleDiscoveryThread) { IsBackground = true, Name = "HidSharp BLE Discovery" }; //_bleDiscoveryThread.Start(); _serialWatcherShutdownEvent = NativeMethods.CreateManualResetEventOrThrow(); _serialWatcherThread = new Thread(SerialWatcherThread) { IsBackground = true, Name = "HidSharp Serial Watcher" }; _serialWatcherThread.Start(); _hidNotifyObject = new object(); _serNotifyObject = new object(); _bleNotifyObject = new object(); _notifyThread = new Thread(DeviceMonitorEventThread) { IsBackground = true, Name = "HidSharp RaiseChanged" }; _notifyThread.Start(); readyCallback(); NativeMethods.MSG msg; while (true) { int result = NativeMethods.GetMessage(out msg, hwnd, 0, 0); if (result == 0 || result == -1) { break; } NativeMethods.TranslateMessage(ref msg); NativeMethods.DispatchMessage(ref msg); } //lock (_bleDiscoveryThread) { _bleDiscoveryShuttingDown = true; Monitor.Pulse(_bleDiscoveryThread); } lock (_notifyThread) { _notifyThreadShuttingDown = true; Monitor.Pulse(_notifyThread); } NativeMethods.SetEvent(_serialWatcherShutdownEvent); //_bleDiscoveryThread.Join(); _notifyThread.Join(); _serialWatcherThread.Join(); UnregisterDeviceNotification(hidNotifyHandle); UnregisterDeviceNotification(bleNotifyHandle); #if BLUETOOTH_NOTIFY foreach (var bleHandle in bleHandles) { UnregisterDeviceNotification(bleHandle.NotifyHandle); NativeMethods.CloseHandle(bleHandle.RadioHandle); } #endif RunAssert(NativeMethods.DestroyWindow(hwnd), "HidSharp DestroyWindow failed."); RunAssert(NativeMethods.UnregisterClass(className, IntPtr.Zero), "HidSharp UnregisterClass failed."); GC.KeepAlive(windowProc); }