From 1219c19acb27639951115b4df56d05d3eee4b228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Mon, 3 Oct 2022 20:21:52 +0200 Subject: [PATCH] Ported more methods --- Nefarius.Peripherals.SerialPort/SerialPort.cs | 55 +++++++++---------- .../Win32PInvoke/OVERLAPPED.cs | 15 ----- 2 files changed, 25 insertions(+), 45 deletions(-) delete mode 100644 Nefarius.Peripherals.SerialPort/Win32PInvoke/OVERLAPPED.cs diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 2e17be4..16ae533 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -12,8 +12,7 @@ using Nefarius.Peripherals.SerialPort.Win32PInvoke; namespace Nefarius.Peripherals.SerialPort; /// -/// PInvokeSerialPort main class. -/// Borrowed from http://msdn.microsoft.com/en-us/magazine/cc301786.aspx ;) +/// Wrapper class around a serial (COM, RS-232) port. /// public partial class SerialPort : IDisposable { @@ -32,7 +31,7 @@ public partial class SerialPort : IDisposable private int _stateDtr = 2; private int _stateRts = 2; private int _writeCount; - + /// /// Class constructor /// @@ -324,7 +323,7 @@ public partial class SerialPort : IDisposable if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) ThrowException("Unexpected failure"); return new ModemStatus(f); } - + /// /// Get the status of the queues /// @@ -415,29 +414,28 @@ public partial class SerialPort : IDisposable private unsafe void ReceiveThread() { - var buf = new byte[1]; + var buf = stackalloc byte[1]; var sg = new AutoResetEvent(false); - var ov = new OVERLAPPED(); - var unmanagedOv = Marshal.AllocHGlobal(Marshal.SizeOf(ov)); - ov.Offset = 0; - ov.OffsetHigh = 0; - ov.hEvent = sg.SafeWaitHandle.DangerousGetHandle(); - Marshal.StructureToPtr(ov, unmanagedOv, true); + var ov = new NativeOverlapped + { + EventHandle = sg.SafeWaitHandle.DangerousGetHandle() + }; - uint eventMask = 0; - var uMask = Marshal.AllocHGlobal(Marshal.SizeOf(eventMask)); + COMM_EVENT_MASK eventMask = 0; try { while (true) { - if (!Win32Com.SetCommMask(_hPort.DangerousGetHandle(), - Win32Com.EV_RXCHAR | Win32Com.EV_TXEMPTY | Win32Com.EV_CTS | Win32Com.EV_DSR - | Win32Com.EV_BREAK | Win32Com.EV_RLSD | Win32Com.EV_RING | Win32Com.EV_ERR)) + if (!PInvoke.SetCommMask(_hPort, + COMM_EVENT_MASK.EV_RXCHAR | COMM_EVENT_MASK.EV_TXEMPTY | COMM_EVENT_MASK.EV_CTS | + COMM_EVENT_MASK.EV_DSR + | COMM_EVENT_MASK.EV_BREAK | COMM_EVENT_MASK.EV_RLSD | COMM_EVENT_MASK.EV_RING | + COMM_EVENT_MASK.EV_ERR)) throw new CommPortException("IO Error [001]"); - Marshal.WriteInt32(uMask, 0); - if (!Win32Com.WaitCommEvent(_hPort.DangerousGetHandle(), uMask, unmanagedOv)) + + if (!PInvoke.WaitCommEvent(_hPort, ref eventMask, &ov)) { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) sg.WaitOne(); @@ -445,8 +443,7 @@ public partial class SerialPort : IDisposable throw new CommPortException("IO Error [002]"); } - eventMask = (uint)Marshal.ReadInt32(uMask); - if ((eventMask & Win32Com.EV_ERR) != 0) + if ((eventMask & COMM_EVENT_MASK.EV_ERR) != 0) { CLEAR_COMM_ERROR_FLAGS errs; if (PInvoke.ClearCommError(_hPort, &errs, null)) @@ -465,12 +462,12 @@ public partial class SerialPort : IDisposable throw new CommPortException("IO Error [003]"); } - if ((eventMask & Win32Com.EV_RXCHAR) != 0) + if ((eventMask & COMM_EVENT_MASK.EV_RXCHAR) != 0) { uint gotbytes; do { - if (!Win32Com.ReadFile(_hPort.DangerousGetHandle(), buf, 1, out gotbytes, unmanagedOv)) + if (!PInvoke.ReadFile(_hPort, buf, 1, &gotbytes, &ov)) { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) { @@ -487,14 +484,14 @@ public partial class SerialPort : IDisposable } while (gotbytes > 0); } - if ((eventMask & Win32Com.EV_TXEMPTY) != 0) OnTxDone(); - if ((eventMask & Win32Com.EV_BREAK) != 0) OnBreak(); + if ((eventMask & COMM_EVENT_MASK.EV_TXEMPTY) != 0) OnTxDone(); + if ((eventMask & COMM_EVENT_MASK.EV_BREAK) != 0) OnBreak(); uint i = 0; - if ((eventMask & Win32Com.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON; - if ((eventMask & Win32Com.EV_DSR) != 0) i |= Win32Com.MS_DSR_ON; - if ((eventMask & Win32Com.EV_RLSD) != 0) i |= Win32Com.MS_RLSD_ON; - if ((eventMask & Win32Com.EV_RING) != 0) i |= Win32Com.MS_RING_ON; + if ((eventMask & COMM_EVENT_MASK.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON; + if ((eventMask & COMM_EVENT_MASK.EV_DSR) != 0) i |= Win32Com.MS_DSR_ON; + if ((eventMask & COMM_EVENT_MASK.EV_RLSD) != 0) i |= Win32Com.MS_RLSD_ON; + if ((eventMask & COMM_EVENT_MASK.EV_RING) != 0) i |= Win32Com.MS_RING_ON; if (i != 0) { uint f; @@ -506,8 +503,6 @@ public partial class SerialPort : IDisposable } catch (Exception e) { - if (uMask != IntPtr.Zero) Marshal.FreeHGlobal(uMask); - if (unmanagedOv != IntPtr.Zero) Marshal.FreeHGlobal(unmanagedOv); if (!(e is ThreadAbortException)) { _rxException = e; diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/OVERLAPPED.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/OVERLAPPED.cs deleted file mode 100644 index 8bd992a..0000000 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/OVERLAPPED.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Nefarius.Peripherals.SerialPort.Win32PInvoke -{ - [StructLayout(LayoutKind.Sequential)] - internal struct OVERLAPPED - { - internal UIntPtr Internal; - internal UIntPtr InternalHigh; - internal UInt32 Offset; - internal UInt32 OffsetHigh; - internal IntPtr hEvent; - } -} \ No newline at end of file