From 7b5449a95b3ea5d57197e06431958b9f11665bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Mon, 3 Oct 2022 19:23:48 +0200 Subject: [PATCH 01/13] Split class --- .../SerialPort.Properties.cs | 277 ++++++++++++++ Nefarius.Peripherals.SerialPort/SerialPort.cs | 353 ++---------------- 2 files changed, 313 insertions(+), 317 deletions(-) create mode 100644 Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs new file mode 100644 index 0000000..e24b6e4 --- /dev/null +++ b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs @@ -0,0 +1,277 @@ +using Nefarius.Peripherals.SerialPort.Win32PInvoke; + +namespace Nefarius.Peripherals.SerialPort; + +public partial class SerialPort +{ + /// + /// If true, the port will automatically re-open on next send if it was previously closed due + /// to an error (default: false) + /// + public bool AutoReopen { get; set; } + + /// + /// Baud Rate (default: 115200) + /// + /// Unsupported rates will throw "Bad settings". + public int BaudRate { get; set; } = 115200; + + /// + /// If true, subsequent Send commands wait for completion of earlier ones enabling the results + /// to be checked. If false, errors, including timeouts, may not be detected, but performance + /// may be better. + /// + public bool CheckAllSends { get; set; } = true; + + /// + /// Number of databits 1..8 (default: 8) unsupported values will throw "Bad settings" + /// + public int DataBits { get; set; } = 8; + + /// + /// The parity checking scheme (default: none) + /// + public Parity Parity { get; set; } = Parity.None; + + /// + /// If true, Xon and Xoff characters are sent to control the data flow from the remote station (default: false) + /// + public bool RxFlowX { get; set; } + + /// + /// If true, received characters are ignored unless DSR is asserted by the remote station (default: false) + /// + public bool RxGateDsr { get; set; } + + /// + /// The number of free bytes in the reception queue at which flow is disabled (default: 2048) + /// + public int RxHighWater { get; set; } = 2048; + + /// + /// The number of bytes in the reception queue at which flow is re-enabled (default: 512) + /// + public int RxLowWater { get; set; } = 512; + + /// + /// Requested size for receive queue (default: 0 = use operating system default) + /// + public int RxQueue { get; set; } + + /// + /// Constant. Max time for Send in ms = (Multiplier * Characters) + Constant (default: 0) + /// + public int SendTimeoutConstant { get; set; } + + /// + /// Multiplier. Max time for Send in ms = (Multiplier * Characters) + Constant + /// (default: 0 = No timeout) + /// + public int SendTimeoutMultiplier { get; set; } + + /// + /// Number of stop bits (default: one) + /// + public StopBits StopBits { get; set; } = StopBits.One; + + /// + /// If true, transmission is halted unless CTS is asserted by the remote station (default: false) + /// + public bool TxFlowCts { get; set; } + + /// + /// If true, transmission is halted unless DSR is asserted by the remote station (default: false) + /// + public bool TxFlowDsr { get; set; } + + /// + /// If true, transmission is halted when Xoff is received and restarted when Xon is received (default: false) + /// + public bool TxFlowX { get; set; } + + /// + /// Requested size for transmit queue (default: 0 = use operating system default) + /// + public int TxQueue { get; set; } + + /// + /// If false, transmission is suspended when this station has sent Xoff to the remote station (default: true) + /// Set false if the remote station treats any character as an Xon. + /// + public bool TxWhenRxXoff { get; set; } = true; + + /// + /// Specidies the use to which the DTR output is put (default: none) + /// + public HsOutput UseDtr { get; set; } = HsOutput.None; + + /// + /// Specifies the use to which the RTS output is put (default: none) + /// + public HsOutput UseRts { get; set; } = HsOutput.None; + + /// + /// The character used to signal Xoff for X flow control (default: DC3) + /// + public ASCII XoffChar { get; set; } = ASCII.DC3; + + /// + /// The character used to signal Xon for X flow control (default: DC1) + /// + public ASCII XonChar { get; set; } = ASCII.DC1; + + /// + /// True if online. + /// + public bool Online => _online && CheckOnline(); + + /// + /// True if the RTS pin is controllable via the RTS property + /// + protected bool RtSavailable => _stateRts < 2; + + /// + /// Set the state of the RTS modem control output + /// + protected bool Rts + { + set + { + if (_stateRts > 1) return; + CheckOnline(); + if (value) + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETRTS)) + _stateRts = 1; + else + ThrowException("Unexpected Failure"); + } + else + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRRTS)) + _stateRts = 1; + else + ThrowException("Unexpected Failure"); + } + } + get => _stateRts == 1; + } + + /// + /// True if the DTR pin is controllable via the DTR property + /// + protected bool DtrAvailable => _stateDtr < 2; + + /// + /// The state of the DTR modem control output + /// + protected bool Dtr + { + set + { + if (_stateDtr > 1) return; + CheckOnline(); + if (value) + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETDTR)) + _stateDtr = 1; + else + ThrowException("Unexpected Failure"); + } + else + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRDTR)) + _stateDtr = 0; + else + ThrowException("Unexpected Failure"); + } + } + get => _stateDtr == 1; + } + + /// + /// Assert or remove a break condition from the transmission line + /// + protected bool Break + { + set + { + if (_stateBrk > 1) return; + CheckOnline(); + if (value) + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETBREAK)) + _stateBrk = 0; + else + ThrowException("Unexpected Failure"); + } + else + { + if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRBREAK)) + _stateBrk = 0; + else + ThrowException("Unexpected Failure"); + } + } + get => _stateBrk == 1; + } + + /// + /// Port Name + /// + public string PortName { get; set; } + + public Handshake Handshake + { + get => _handShake; + set + { + _handShake = value; + switch (_handShake) + { + case Handshake.None: + TxFlowCts = false; + TxFlowDsr = false; + TxFlowX = false; + RxFlowX = false; + UseRts = HsOutput.Online; + UseDtr = HsOutput.Online; + TxWhenRxXoff = true; + RxGateDsr = false; + break; + case Handshake.XonXoff: + TxFlowCts = false; + TxFlowDsr = false; + TxFlowX = true; + RxFlowX = true; + UseRts = HsOutput.Online; + UseDtr = HsOutput.Online; + TxWhenRxXoff = true; + RxGateDsr = false; + XonChar = ASCII.DC1; + XoffChar = ASCII.DC3; + break; + case Handshake.CtsRts: + TxFlowCts = true; + TxFlowDsr = false; + TxFlowX = false; + RxFlowX = false; + UseRts = HsOutput.Handshake; + UseDtr = HsOutput.Online; + TxWhenRxXoff = true; + RxGateDsr = false; + break; + case Handshake.DsrDtr: + TxFlowCts = false; + TxFlowDsr = true; + TxFlowX = false; + RxFlowX = false; + UseRts = HsOutput.Online; + UseDtr = HsOutput.Handshake; + TxWhenRxXoff = true; + RxGateDsr = false; + break; + } + } + } +} \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index cfddb9a..2e17be4 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -15,8 +15,41 @@ namespace Nefarius.Peripherals.SerialPort; /// PInvokeSerialPort main class. /// Borrowed from http://msdn.microsoft.com/en-us/magazine/cc301786.aspx ;) /// -public class SerialPort : IDisposable +public partial class SerialPort : IDisposable { + private readonly ManualResetEvent _writeEvent = new(false); + private bool _auto; + private bool _checkSends = true; + + private Handshake _handShake; + private SafeFileHandle _hPort; + private bool _online; + private NativeOverlapped _ptrUwo; + private Exception _rxException; + private bool _rxExceptionReported; + private Thread _rxThread; + private int _stateBrk = 2; + private int _stateDtr = 2; + private int _stateRts = 2; + private int _writeCount; + + /// + /// Class constructor + /// + public SerialPort(string portName) + { + PortName = portName; + } + + /// + /// + /// Class constructor + /// + public SerialPort(string portName, int baudRate) : this(portName) + { + BaudRate = baudRate; + } + /// /// /// For IDisposable @@ -210,7 +243,7 @@ public class SerialPort : IDisposable } else { - if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING) + if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING) ThrowException("Unexpected failure"); } } @@ -291,8 +324,7 @@ public class SerialPort : IDisposable if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) ThrowException("Unexpected failure"); return new ModemStatus(f); } - - + /// /// Get the status of the queues /// @@ -506,317 +538,4 @@ public class SerialPort : IDisposable ThrowException("Offline"); return false; } - - #region Private fields - - private readonly ManualResetEvent _writeEvent = new(false); - private bool _auto; - private bool _checkSends = true; - - private Handshake _handShake; - private SafeFileHandle _hPort; - private bool _online; - private NativeOverlapped _ptrUwo; - private Exception _rxException; - private bool _rxExceptionReported; - private Thread _rxThread; - private int _stateBrk = 2; - private int _stateDtr = 2; - private int _stateRts = 2; - private int _writeCount; - - #endregion - - #region Public properties - - /// - /// Class constructor - /// - public SerialPort(string portName) - { - PortName = portName; - } - - /// - /// - /// Class constructor - /// - public SerialPort(string portName, int baudRate) : this(portName) - { - BaudRate = baudRate; - } - - /// - /// If true, the port will automatically re-open on next send if it was previously closed due - /// to an error (default: false) - /// - public bool AutoReopen { get; set; } - - /// - /// Baud Rate (default: 115200) - /// - /// Unsupported rates will throw "Bad settings". - public int BaudRate { get; set; } = 115200; - - /// - /// If true, subsequent Send commands wait for completion of earlier ones enabling the results - /// to be checked. If false, errors, including timeouts, may not be detected, but performance - /// may be better. - /// - public bool CheckAllSends { get; set; } = true; - - /// - /// Number of databits 1..8 (default: 8) unsupported values will throw "Bad settings" - /// - public int DataBits { get; set; } = 8; - - /// - /// The parity checking scheme (default: none) - /// - public Parity Parity { get; set; } = Parity.None; - - /// - /// If true, Xon and Xoff characters are sent to control the data flow from the remote station (default: false) - /// - public bool RxFlowX { get; set; } - - /// - /// If true, received characters are ignored unless DSR is asserted by the remote station (default: false) - /// - public bool RxGateDsr { get; set; } - - /// - /// The number of free bytes in the reception queue at which flow is disabled (default: 2048) - /// - public int RxHighWater { get; set; } = 2048; - - /// - /// The number of bytes in the reception queue at which flow is re-enabled (default: 512) - /// - public int RxLowWater { get; set; } = 512; - - /// - /// Requested size for receive queue (default: 0 = use operating system default) - /// - public int RxQueue { get; set; } - - /// - /// Constant. Max time for Send in ms = (Multiplier * Characters) + Constant (default: 0) - /// - public int SendTimeoutConstant { get; set; } - - /// - /// Multiplier. Max time for Send in ms = (Multiplier * Characters) + Constant - /// (default: 0 = No timeout) - /// - public int SendTimeoutMultiplier { get; set; } - - /// - /// Number of stop bits (default: one) - /// - public StopBits StopBits { get; set; } = StopBits.One; - - /// - /// If true, transmission is halted unless CTS is asserted by the remote station (default: false) - /// - public bool TxFlowCts { get; set; } - - /// - /// If true, transmission is halted unless DSR is asserted by the remote station (default: false) - /// - public bool TxFlowDsr { get; set; } - - /// - /// If true, transmission is halted when Xoff is received and restarted when Xon is received (default: false) - /// - public bool TxFlowX { get; set; } - - /// - /// Requested size for transmit queue (default: 0 = use operating system default) - /// - public int TxQueue { get; set; } - - /// - /// If false, transmission is suspended when this station has sent Xoff to the remote station (default: true) - /// Set false if the remote station treats any character as an Xon. - /// - public bool TxWhenRxXoff { get; set; } = true; - - /// - /// Specidies the use to which the DTR output is put (default: none) - /// - public HsOutput UseDtr { get; set; } = HsOutput.None; - - /// - /// Specifies the use to which the RTS output is put (default: none) - /// - public HsOutput UseRts { get; set; } = HsOutput.None; - - /// - /// The character used to signal Xoff for X flow control (default: DC3) - /// - public ASCII XoffChar { get; set; } = ASCII.DC3; - - /// - /// The character used to signal Xon for X flow control (default: DC1) - /// - public ASCII XonChar { get; set; } = ASCII.DC1; - - /// - /// True if online. - /// - public bool Online => _online && CheckOnline(); - - /// - /// True if the RTS pin is controllable via the RTS property - /// - protected bool RtSavailable => _stateRts < 2; - - /// - /// Set the state of the RTS modem control output - /// - protected bool Rts - { - set - { - if (_stateRts > 1) return; - CheckOnline(); - if (value) - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETRTS)) - _stateRts = 1; - else - ThrowException("Unexpected Failure"); - } - else - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRRTS)) - _stateRts = 1; - else - ThrowException("Unexpected Failure"); - } - } - get => _stateRts == 1; - } - - /// - /// True if the DTR pin is controllable via the DTR property - /// - protected bool DtrAvailable => _stateDtr < 2; - - /// - /// The state of the DTR modem control output - /// - protected bool Dtr - { - set - { - if (_stateDtr > 1) return; - CheckOnline(); - if (value) - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETDTR)) - _stateDtr = 1; - else - ThrowException("Unexpected Failure"); - } - else - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRDTR)) - _stateDtr = 0; - else - ThrowException("Unexpected Failure"); - } - } - get => _stateDtr == 1; - } - - /// - /// Assert or remove a break condition from the transmission line - /// - protected bool Break - { - set - { - if (_stateBrk > 1) return; - CheckOnline(); - if (value) - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETBREAK)) - _stateBrk = 0; - else - ThrowException("Unexpected Failure"); - } - else - { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRBREAK)) - _stateBrk = 0; - else - ThrowException("Unexpected Failure"); - } - } - get => _stateBrk == 1; - } - - - /// - /// Port Name - /// - public string PortName { get; set; } - - public Handshake Handshake - { - get => _handShake; - set - { - _handShake = value; - switch (_handShake) - { - case Handshake.None: - TxFlowCts = false; - TxFlowDsr = false; - TxFlowX = false; - RxFlowX = false; - UseRts = HsOutput.Online; - UseDtr = HsOutput.Online; - TxWhenRxXoff = true; - RxGateDsr = false; - break; - case Handshake.XonXoff: - TxFlowCts = false; - TxFlowDsr = false; - TxFlowX = true; - RxFlowX = true; - UseRts = HsOutput.Online; - UseDtr = HsOutput.Online; - TxWhenRxXoff = true; - RxGateDsr = false; - XonChar = ASCII.DC1; - XoffChar = ASCII.DC3; - break; - case Handshake.CtsRts: - TxFlowCts = true; - TxFlowDsr = false; - TxFlowX = false; - RxFlowX = false; - UseRts = HsOutput.Handshake; - UseDtr = HsOutput.Online; - TxWhenRxXoff = true; - RxGateDsr = false; - break; - case Handshake.DsrDtr: - TxFlowCts = false; - TxFlowDsr = true; - TxFlowX = false; - RxFlowX = false; - UseRts = HsOutput.Online; - UseDtr = HsOutput.Handshake; - TxWhenRxXoff = true; - RxGateDsr = false; - break; - } - } - } - - #endregion } \ No newline at end of file -- 2.45.2 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 02/13] 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 -- 2.45.2 From 19151056887c204870b48408bac656fec7faa748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 14:15:41 +0200 Subject: [PATCH 03/13] More fixes --- .gitignore | 1 + Nefarius.Peripherals.SerialPort/SerialPort.cs | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index af5c6a9..113e3ad 100755 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ _ReSharper*/ /.tmp *.DotSettings /misc +/.idea diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 16ae533..04f018f 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -317,11 +317,9 @@ public partial class SerialPort : IDisposable /// Modem status object protected ModemStatus GetModemStatus() { - uint f; - CheckOnline(); - if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) ThrowException("Unexpected failure"); - return new ModemStatus(f); + if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out var f)) ThrowException("Unexpected failure"); + return new ModemStatus((MODEM_STATUS_FLAGS)f); } /// @@ -497,7 +495,7 @@ public partial class SerialPort : IDisposable uint f; if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) throw new CommPortException("IO Error [005]"); - OnStatusChange(new ModemStatus(i), new ModemStatus(f)); + OnStatusChange(new ModemStatus((MODEM_STATUS_FLAGS)i), new ModemStatus((MODEM_STATUS_FLAGS)f)); } } } -- 2.45.2 From fa8e74a822dac698392de2fa0ad3dc1fa3d780b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 14:48:28 +0200 Subject: [PATCH 04/13] Updated to latest packages --- .editorconfig | 394 ++++++++++++++++++ .../Nefarius.Peripherals.SerialPort.csproj | 3 +- nuget.config | 9 + 3 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 .editorconfig create mode 100644 nuget.config diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2f1b6c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,394 @@ +root = true + +# All files +[*] +indent_style = space + +# Xml files +[*.xml] +indent_size = 2 + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### +[*.{cs,vb}] + +# Organize usings +dotnet_separate_import_directive_groups = true +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:warning + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Expression-level preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:warning + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +#### C# Coding Conventions #### +[*.cs] + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_local_function = true:warning +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_prefer_extended_property_pattern = true:suggestion + +#### Naming styles #### +[*.{cs,vb}] + +# Naming rules + +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = warning +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = warning +dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces +dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase + +dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = warning +dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters +dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase + +dotnet_naming_rule.methods_should_be_pascalcase.severity = warning +dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods +dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.properties_should_be_pascalcase.severity = warning +dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties +dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.events_should_be_pascalcase.severity = warning +dotnet_naming_rule.events_should_be_pascalcase.symbols = events +dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_variables_should_be_camelcase.severity = warning +dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables +dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase + +dotnet_naming_rule.local_constants_should_be_camelcase.severity = warning +dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants +dotnet_naming_rule.local_constants_should_be_camelcase.style = all_caps + +dotnet_naming_rule.parameters_should_be_camelcase.severity = warning +dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters +dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase + +dotnet_naming_rule.public_fields_should_be_pascalcase.severity = warning +dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields +dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_fields_should_be__camelcase.severity = warning +dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields +dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase + +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = warning +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = _camelcase + +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = warning +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = warning +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = warning +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = warning +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.enums_should_be_pascalcase.severity = warning +dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums +dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_functions_should_be_pascalcase.severity = warning +dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions +dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = warning +dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase + +# Symbol specifications + +dotnet_naming_symbols.interfaces.applicable_kinds = interface +dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interfaces.required_modifiers = + +dotnet_naming_symbols.enums.applicable_kinds = enum +dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.enums.required_modifiers = + +dotnet_naming_symbols.events.applicable_kinds = event +dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.events.required_modifiers = + +dotnet_naming_symbols.methods.applicable_kinds = method +dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.methods.required_modifiers = + +dotnet_naming_symbols.properties.applicable_kinds = property +dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.properties.required_modifiers = + +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_fields.required_modifiers = + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_fields.required_modifiers = + +dotnet_naming_symbols.private_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_fields.required_modifiers = static + +dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum +dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types_and_namespaces.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.type_parameters.applicable_kinds = namespace +dotnet_naming_symbols.type_parameters.applicable_accessibilities = * +dotnet_naming_symbols.type_parameters.required_modifiers = + +dotnet_naming_symbols.private_constant_fields.applicable_kinds = field +dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_constant_fields.required_modifiers = const + +dotnet_naming_symbols.local_variables.applicable_kinds = local +dotnet_naming_symbols.local_variables.applicable_accessibilities = local +dotnet_naming_symbols.local_variables.required_modifiers = + +dotnet_naming_symbols.local_constants.applicable_kinds = local +dotnet_naming_symbols.local_constants.applicable_accessibilities = local +dotnet_naming_symbols.local_constants.required_modifiers = const + +dotnet_naming_symbols.parameters.applicable_kinds = parameter +dotnet_naming_symbols.parameters.applicable_accessibilities = * +dotnet_naming_symbols.parameters.required_modifiers = + +dotnet_naming_symbols.public_constant_fields.applicable_kinds = field +dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_constant_fields.required_modifiers = const + +dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.local_functions.applicable_kinds = local_function +dotnet_naming_symbols.local_functions.applicable_accessibilities = * +dotnet_naming_symbols.local_functions.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascalcase.required_prefix = +dotnet_naming_style.pascalcase.required_suffix = +dotnet_naming_style.pascalcase.word_separator = +dotnet_naming_style.pascalcase.capitalization = pascal_case + +dotnet_naming_style.ipascalcase.required_prefix = I +dotnet_naming_style.ipascalcase.required_suffix = +dotnet_naming_style.ipascalcase.word_separator = +dotnet_naming_style.ipascalcase.capitalization = pascal_case + +dotnet_naming_style.tpascalcase.required_prefix = T +dotnet_naming_style.tpascalcase.required_suffix = +dotnet_naming_style.tpascalcase.word_separator = +dotnet_naming_style.tpascalcase.capitalization = pascal_case + +dotnet_naming_style._camelcase.required_prefix = _ +dotnet_naming_style._camelcase.required_suffix = +dotnet_naming_style._camelcase.word_separator = +dotnet_naming_style._camelcase.capitalization = camel_case + +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.capitalization = camel_case + +dotnet_naming_style.s_camelcase.required_prefix = s_ +dotnet_naming_style.s_camelcase.required_suffix = +dotnet_naming_style.s_camelcase.word_separator = +dotnet_naming_style.s_camelcase.capitalization = camel_case + +dotnet_naming_style.all_caps.required_prefix = +dotnet_naming_style.all_caps.required_suffix = +dotnet_naming_style.all_caps.word_separator = _ +dotnet_naming_style.all_caps.capitalization = all_caps + +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_style_allow_multiple_blank_lines_experimental = true:silent + +# Unnecessary usings +dotnet_diagnostic.IDE0005.severity = warning + +resharper_csharp_place_attribute_on_same_line = false + +csharp_style_prefer_primary_constructors = false \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj index 370ebf2..db2f479 100644 --- a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj +++ b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj @@ -31,8 +31,7 @@ - - + all diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..223d6b4 --- /dev/null +++ b/nuget.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file -- 2.45.2 From 286994c2b680f01f6c59c1e9049f270e490885b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 14:59:01 +0200 Subject: [PATCH 05/13] More clean-up --- .../NativeMethods.txt | 1 + .../Nefarius.Peripherals.SerialPort.csproj | 1 + Nefarius.Peripherals.SerialPort/SerialPort.cs | 214 +++++++++++++----- 3 files changed, 165 insertions(+), 51 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index e754077..aa60595 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -1,4 +1,5 @@ CreateFile +FILE_ACCESS_RIGHTS GetHandleInformation SetCommState SetCommTimeouts diff --git a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj index db2f479..0a6e29e 100644 --- a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj +++ b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj @@ -34,5 +34,6 @@ all + \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 04f018f..fbe1613 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -1,12 +1,16 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; using System.Threading; + using Windows.Win32; using Windows.Win32.Devices.Communication; using Windows.Win32.Foundation; using Windows.Win32.Storage.FileSystem; + using Microsoft.Win32.SafeHandles; + using Nefarius.Peripherals.SerialPort.Win32PInvoke; namespace Nefarius.Peripherals.SerialPort; @@ -14,6 +18,7 @@ namespace Nefarius.Peripherals.SerialPort; /// /// Wrapper class around a serial (COM, RS-232) port. /// +[SuppressMessage("ReSharper", "UnusedMember.Global")] public partial class SerialPort : IDisposable { private readonly ManualResetEvent _writeEvent = new(false); @@ -64,18 +69,25 @@ public partial class SerialPort : IDisposable /// false if the port could not be opened public bool Open() { - var portDcb = new DCB(); - var commTimeouts = new COMMTIMEOUTS(); + DCB portDcb = new(); + COMMTIMEOUTS commTimeouts = new(); - if (_online) return false; + if (_online) + { + return false; + } _hPort = PInvoke.CreateFile(PortName, - FILE_ACCESS_FLAGS.FILE_GENERIC_READ | FILE_ACCESS_FLAGS.FILE_GENERIC_WRITE, 0, + (uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), 0, null, FILE_CREATION_DISPOSITION.OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_OVERLAPPED, null); if (_hPort.IsInvalid) { - if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_ACCESS_DENIED) return false; + if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_ACCESS_DENIED) + { + return false; + } + throw new CommPortException("Port Open Failure"); } @@ -92,20 +104,28 @@ public partial class SerialPort : IDisposable portDcb.ByteSize = (byte)DataBits; portDcb.Parity = (DCB_PARITY)Parity; portDcb.StopBits = (DCB_STOP_BITS)StopBits; - portDcb.XoffChar = (CHAR)(byte)XoffChar; - portDcb.XonChar = (CHAR)(byte)XonChar; + portDcb.XoffChar = new CHAR((sbyte)XoffChar); + portDcb.XonChar = new CHAR((sbyte)XonChar); portDcb.XoffLim = (ushort)RxHighWater; portDcb.XonLim = (ushort)RxLowWater; if (RxQueue != 0 || TxQueue != 0) + { if (!PInvoke.SetupComm(_hPort, (uint)RxQueue, (uint)TxQueue)) + { ThrowException("Bad queue settings"); + } + } if (!PInvoke.SetCommState(_hPort, portDcb)) + { ThrowException("Bad com settings"); + } if (!PInvoke.SetCommTimeouts(_hPort, commTimeouts)) + { ThrowException("Bad timeout settings"); + } _stateBrk = 0; switch (UseDtr) @@ -135,12 +155,9 @@ public partial class SerialPort : IDisposable _rxException = null; _rxExceptionReported = false; - // TODO: utilize Task Parallel Library here _rxThread = new Thread(ReceiveThread) { - Name = "CommBaseRx", - Priority = ThreadPriority.AboveNormal, - IsBackground = true + Name = "CommBaseRx", Priority = ThreadPriority.AboveNormal, IsBackground = true }; _rxThread.Start(); @@ -211,14 +228,22 @@ public partial class SerialPort : IDisposable /// Description of fault protected void ThrowException(string reason) { - if (Thread.CurrentThread == _rxThread) throw new CommPortException(reason); + if (Thread.CurrentThread == _rxThread) + { + throw new CommPortException(reason); + } + if (_online) { BeforeClose(true); InternalClose(); } - if (_rxException == null) throw new CommPortException(reason); + if (_rxException == null) + { + throw new CommPortException(reason); + } + throw new CommPortException(_rxException); } @@ -228,7 +253,6 @@ public partial class SerialPort : IDisposable /// Array of bytes to be sent public unsafe void Write(byte[] toSend) { - uint sent; CheckOnline(); CheckResult(); _writeCount = toSend.GetLength(0); @@ -236,6 +260,7 @@ public partial class SerialPort : IDisposable fixed (byte* ptr = toSend) fixed (NativeOverlapped* ptrOl = &_ptrUwo) { + uint sent; if (PInvoke.WriteFile(_hPort, ptr, (uint)_writeCount, &sent, ptrOl)) { _writeCount -= (int)sent; @@ -243,7 +268,9 @@ public partial class SerialPort : IDisposable else { if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING) + { ThrowException("Unexpected failure"); + } } } } @@ -263,7 +290,7 @@ public partial class SerialPort : IDisposable /// Byte to be sent public void Write(byte toSend) { - var b = new byte[1]; + byte[] b = new byte[1]; b[0] = toSend; Write(b); } @@ -288,15 +315,25 @@ public partial class SerialPort : IDisposable private void CheckResult() { - if (_writeCount <= 0) return; - if (PInvoke.GetOverlappedResult(_hPort, _ptrUwo, out var sent, _checkSends)) + if (_writeCount <= 0) + { + return; + } + + if (PInvoke.GetOverlappedResult(_hPort, _ptrUwo, out uint sent, _checkSends)) { _writeCount -= (int)sent; - if (_writeCount != 0) ThrowException("Send Timeout"); + if (_writeCount != 0) + { + ThrowException("Send Timeout"); + } } else { - if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING) ThrowException("Unexpected failure"); + if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING) + { + ThrowException("Unexpected failure"); + } } } @@ -308,7 +345,10 @@ public partial class SerialPort : IDisposable public void SendImmediate(byte tosend) { CheckOnline(); - if (!Win32Com.TransmitCommChar(_hPort.DangerousGetHandle(), tosend)) ThrowException("Transmission failure"); + if (!Win32Com.TransmitCommChar(_hPort.DangerousGetHandle(), tosend)) + { + ThrowException("Transmission failure"); + } } /// @@ -318,7 +358,11 @@ public partial class SerialPort : IDisposable protected ModemStatus GetModemStatus() { CheckOnline(); - if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out var f)) ThrowException("Unexpected failure"); + if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out uint f)) + { + ThrowException("Unexpected failure"); + } + return new ModemStatus((MODEM_STATUS_FLAGS)f); } @@ -329,15 +373,19 @@ public partial class SerialPort : IDisposable protected unsafe QueueStatus GetQueueStatus() { COMSTAT cs; - var cp = new COMMPROP(); + COMMPROP cp = new(); CLEAR_COMM_ERROR_FLAGS er; CheckOnline(); if (!PInvoke.ClearCommError(_hPort, &er, &cs)) + { ThrowException("Unexpected failure"); + } - if (!PInvoke.GetCommProperties(_hPort, ref cp)) + if (!PInvoke.GetCommProperties(_hPort, &cp)) + { ThrowException("Unexpected failure"); + } return new QueueStatus(cs._bitfield, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue); } @@ -412,13 +460,10 @@ public partial class SerialPort : IDisposable private unsafe void ReceiveThread() { - var buf = stackalloc byte[1]; + byte* buf = stackalloc byte[1]; - var sg = new AutoResetEvent(false); - var ov = new NativeOverlapped - { - EventHandle = sg.SafeWaitHandle.DangerousGetHandle() - }; + AutoResetEvent sg = new(false); + NativeOverlapped ov = new() { EventHandle = sg.SafeWaitHandle.DangerousGetHandle() }; COMM_EVENT_MASK eventMask = 0; @@ -431,14 +476,20 @@ public partial class SerialPort : IDisposable 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]"); + } if (!PInvoke.WaitCommEvent(_hPort, ref eventMask, &ov)) { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) + { sg.WaitOne(); + } else + { throw new CommPortException("IO Error [002]"); + } } if ((eventMask & COMM_EVENT_MASK.EV_ERR) != 0) @@ -446,13 +497,37 @@ public partial class SerialPort : IDisposable CLEAR_COMM_ERROR_FLAGS errs; if (PInvoke.ClearCommError(_hPort, &errs, null)) { - var s = new StringBuilder("UART Error: ", 40); - if (((uint)errs & Win32Com.CE_FRAME) != 0) s = s.Append("Framing,"); - if (((uint)errs & Win32Com.CE_IOE) != 0) s = s.Append("IO,"); - if (((uint)errs & Win32Com.CE_OVERRUN) != 0) s = s.Append("Overrun,"); - if (((uint)errs & Win32Com.CE_RXOVER) != 0) s = s.Append("Receive Overflow,"); - if (((uint)errs & Win32Com.CE_RXPARITY) != 0) s = s.Append("Parity,"); - if (((uint)errs & Win32Com.CE_TXFULL) != 0) s = s.Append("Transmit Overflow,"); + StringBuilder s = new("UART Error: ", 40); + if (((uint)errs & Win32Com.CE_FRAME) != 0) + { + s = s.Append("Framing,"); + } + + if (((uint)errs & Win32Com.CE_IOE) != 0) + { + s = s.Append("IO,"); + } + + if (((uint)errs & Win32Com.CE_OVERRUN) != 0) + { + s = s.Append("Overrun,"); + } + + if (((uint)errs & Win32Com.CE_RXOVER) != 0) + { + s = s.Append("Receive Overflow,"); + } + + if (((uint)errs & Win32Com.CE_RXPARITY) != 0) + { + s = s.Append("Parity,"); + } + + if (((uint)errs & Win32Com.CE_TXFULL) != 0) + { + s = s.Append("Transmit Overflow,"); + } + s.Length -= 1; throw new CommPortException(s.ToString()); } @@ -462,15 +537,15 @@ public partial class SerialPort : IDisposable if ((eventMask & COMM_EVENT_MASK.EV_RXCHAR) != 0) { - uint gotbytes; + uint gotBytes; do { - if (!PInvoke.ReadFile(_hPort, buf, 1, &gotbytes, &ov)) + if (!PInvoke.ReadFile(_hPort, buf, 1, &gotBytes, &ov)) { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) { Win32Com.CancelIo(_hPort.DangerousGetHandle()); - gotbytes = 0; + gotBytes = 0; } else { @@ -478,30 +553,59 @@ public partial class SerialPort : IDisposable } } - if (gotbytes == 1) OnRxChar(buf[0]); - } while (gotbytes > 0); + if (gotBytes == 1) + { + OnRxChar(buf[0]); + } + } while (gotBytes > 0); } - if ((eventMask & COMM_EVENT_MASK.EV_TXEMPTY) != 0) OnTxDone(); - if ((eventMask & COMM_EVENT_MASK.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 & 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 ((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; if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) + { throw new CommPortException("IO Error [005]"); + } + OnStatusChange(new ModemStatus((MODEM_STATUS_FLAGS)i), new ModemStatus((MODEM_STATUS_FLAGS)f)); } } } catch (Exception e) { - if (!(e is ThreadAbortException)) + if (e is not ThreadAbortException) { _rxException = e; OnRxException(e); @@ -519,16 +623,24 @@ public partial class SerialPort : IDisposable if (_online) { - uint f; - if (Win32Com.GetHandleInformation(_hPort.DangerousGetHandle(), out f)) return true; + if (Win32Com.GetHandleInformation(_hPort.DangerousGetHandle(), out uint _)) + { + return true; + } + ThrowException("Offline"); return false; } if (_auto) + { if (Open()) + { return true; + } + } + ThrowException("Offline"); return false; } -} \ No newline at end of file +} -- 2.45.2 From c171f2a31635c6f4f03595cdc962242eab2a0031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 14:59:53 +0200 Subject: [PATCH 06/13] Removed migrated types --- .../Win32PInvoke/Win32Com.cs | 124 +++++++----------- 1 file changed, 46 insertions(+), 78 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index a8ee677..98b2284 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -1,91 +1,59 @@ using System; using System.Runtime.InteropServices; -namespace Nefarius.Peripherals.SerialPort.Win32PInvoke +namespace Nefarius.Peripherals.SerialPort.Win32PInvoke; + +internal class Win32Com { - internal class Win32Com - { + // Constants for dwFunc: + internal const UInt32 SETXOFF = 1; + internal const UInt32 SETXON = 2; + internal const UInt32 SETRTS = 3; + internal const UInt32 CLRRTS = 4; + internal const UInt32 SETDTR = 5; + internal const UInt32 CLRDTR = 6; + internal const UInt32 RESETDEV = 7; + internal const UInt32 SETBREAK = 8; + internal const UInt32 CLRBREAK = 9; - [DllImport("kernel32.dll")] - internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags); + // Constants for lpModemStat: + internal const UInt32 MS_CTS_ON = 0x0010; + internal const UInt32 MS_DSR_ON = 0x0020; + internal const UInt32 MS_RING_ON = 0x0040; + internal const UInt32 MS_RLSD_ON = 0x0080; - - [DllImport("kernel32.dll")] - internal static extern Boolean SetCommMask(IntPtr hFile, UInt32 dwEvtMask); + //Constants for lpErrors: + internal const UInt32 CE_RXOVER = 0x0001; + internal const UInt32 CE_OVERRUN = 0x0002; + internal const UInt32 CE_RXPARITY = 0x0004; + internal const UInt32 CE_FRAME = 0x0008; + internal const UInt32 CE_BREAK = 0x0010; + internal const UInt32 CE_TXFULL = 0x0100; + internal const UInt32 CE_PTO = 0x0200; + internal const UInt32 CE_IOE = 0x0400; + internal const UInt32 CE_DNS = 0x0800; + internal const UInt32 CE_OOP = 0x1000; + internal const UInt32 CE_MODE = 0x8000; - // Constants for dwEvtMask: - internal const UInt32 EV_RXCHAR = 0x0001; - internal const UInt32 EV_RXFLAG = 0x0002; - internal const UInt32 EV_TXEMPTY = 0x0004; - internal const UInt32 EV_CTS = 0x0008; - internal const UInt32 EV_DSR = 0x0010; - internal const UInt32 EV_RLSD = 0x0020; - internal const UInt32 EV_BREAK = 0x0040; - internal const UInt32 EV_ERR = 0x0080; - internal const UInt32 EV_RING = 0x0100; - internal const UInt32 EV_PERR = 0x0200; - internal const UInt32 EV_RX80FULL = 0x0400; - internal const UInt32 EV_EVENT1 = 0x0800; - internal const UInt32 EV_EVENT2 = 0x1000; + [DllImport("kernel32.dll")] + internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags); - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern Boolean WaitCommEvent(IntPtr hFile, IntPtr lpEvtMask, IntPtr lpOverlapped); + [DllImport("kernel32.dll")] + internal static extern Boolean CancelIo(IntPtr hFile); - [DllImport("kernel32.dll")] - internal static extern Boolean CancelIo(IntPtr hFile); + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, UInt32 nNumberOfBytesToRead, + out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped); - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, UInt32 nNumberOfBytesToRead, - out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped); + [DllImport("kernel32.dll")] + internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar); - [DllImport("kernel32.dll")] - internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar); + /// + /// Control port functions. + /// + [DllImport("kernel32.dll")] + internal static extern Boolean EscapeCommFunction(IntPtr hFile, UInt32 dwFunc); - /// - /// Control port functions. - /// - [DllImport("kernel32.dll")] - internal static extern Boolean EscapeCommFunction(IntPtr hFile, UInt32 dwFunc); - - // Constants for dwFunc: - internal const UInt32 SETXOFF = 1; - internal const UInt32 SETXON = 2; - internal const UInt32 SETRTS = 3; - internal const UInt32 CLRRTS = 4; - internal const UInt32 SETDTR = 5; - internal const UInt32 CLRDTR = 6; - internal const UInt32 RESETDEV = 7; - internal const UInt32 SETBREAK = 8; - internal const UInt32 CLRBREAK = 9; - - [DllImport("kernel32.dll")] - internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat); - - // Constants for lpModemStat: - internal const UInt32 MS_CTS_ON = 0x0010; - internal const UInt32 MS_DSR_ON = 0x0020; - internal const UInt32 MS_RING_ON = 0x0040; - internal const UInt32 MS_RLSD_ON = 0x0080; - - /// - /// Status Functions. - /// - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern Boolean GetOverlappedResult(IntPtr hFile, IntPtr lpOverlapped, - out UInt32 nNumberOfBytesTransferred, Boolean bWait); - - //Constants for lpErrors: - internal const UInt32 CE_RXOVER = 0x0001; - internal const UInt32 CE_OVERRUN = 0x0002; - internal const UInt32 CE_RXPARITY = 0x0004; - internal const UInt32 CE_FRAME = 0x0008; - internal const UInt32 CE_BREAK = 0x0010; - internal const UInt32 CE_TXFULL = 0x0100; - internal const UInt32 CE_PTO = 0x0200; - internal const UInt32 CE_IOE = 0x0400; - internal const UInt32 CE_DNS = 0x0800; - internal const UInt32 CE_OOP = 0x1000; - internal const UInt32 CE_MODE = 0x8000; - - } + [DllImport("kernel32.dll")] + internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat); } \ No newline at end of file -- 2.45.2 From 3394e70767915d8c0d7e8f8f2fd4a5911456dd90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:07:34 +0200 Subject: [PATCH 07/13] More migration --- .../NativeMethods.txt | 3 ++- .../Nefarius.Peripherals.SerialPort.csproj | 1 + Nefarius.Peripherals.SerialPort/SerialPort.cs | 19 ++++++++----------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index aa60595..15e5192 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -15,4 +15,5 @@ GetCommModemStatus GetOverlappedResult ClearCommError GetCommProperties -WIN32_ERROR \ No newline at end of file +WIN32_ERROR +GetHandleInformation \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj index 0a6e29e..91af2d0 100644 --- a/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj +++ b/Nefarius.Peripherals.SerialPort/Nefarius.Peripherals.SerialPort.csproj @@ -35,5 +35,6 @@ all + \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index fbe1613..7dde20b 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -257,11 +257,10 @@ public partial class SerialPort : IDisposable CheckResult(); _writeCount = toSend.GetLength(0); - fixed (byte* ptr = toSend) fixed (NativeOverlapped* ptrOl = &_ptrUwo) { uint sent; - if (PInvoke.WriteFile(_hPort, ptr, (uint)_writeCount, &sent, ptrOl)) + if (PInvoke.WriteFile(_hPort, toSend.AsSpan(), &sent, ptrOl)) { _writeCount -= (int)sent; } @@ -460,17 +459,16 @@ public partial class SerialPort : IDisposable private unsafe void ReceiveThread() { - byte* buf = stackalloc byte[1]; - + byte[] buffer = new byte[1]; AutoResetEvent sg = new(false); NativeOverlapped ov = new() { EventHandle = sg.SafeWaitHandle.DangerousGetHandle() }; - COMM_EVENT_MASK eventMask = 0; - try { while (true) { + COMM_EVENT_MASK eventMask = 0; + if (!PInvoke.SetCommMask(_hPort, COMM_EVENT_MASK.EV_RXCHAR | COMM_EVENT_MASK.EV_TXEMPTY | COMM_EVENT_MASK.EV_CTS | COMM_EVENT_MASK.EV_DSR @@ -540,7 +538,7 @@ public partial class SerialPort : IDisposable uint gotBytes; do { - if (!PInvoke.ReadFile(_hPort, buf, 1, &gotBytes, &ov)) + if (!PInvoke.ReadFile(_hPort, buffer, &gotBytes, &ov)) { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) { @@ -555,7 +553,7 @@ public partial class SerialPort : IDisposable if (gotBytes == 1) { - OnRxChar(buf[0]); + OnRxChar(buffer[0]); } } while (gotBytes > 0); } @@ -593,8 +591,7 @@ public partial class SerialPort : IDisposable if (i != 0) { - uint f; - if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) + if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out uint f)) { throw new CommPortException("IO Error [005]"); } @@ -643,4 +640,4 @@ public partial class SerialPort : IDisposable ThrowException("Offline"); return false; } -} +} \ No newline at end of file -- 2.45.2 From cd6fecd8fb57d2c129679698a9c7318282c4a0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:12:45 +0200 Subject: [PATCH 08/13] Migrated more types --- .../NativeMethods.txt | 25 ++++++++++--------- Nefarius.Peripherals.SerialPort/SerialPort.cs | 12 ++++----- .../Win32PInvoke/Win32Com.cs | 6 ----- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index 15e5192..3194ae2 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -1,19 +1,20 @@ -CreateFile +CancelIo +ClearCommError +EscapeCommFunction FILE_ACCESS_RIGHTS +GetCommModemStatus +GetCommProperties GetHandleInformation +GetHandleInformation +GetOverlappedResult +MODEM_STATUS_FLAGS +ReadFile +SetCommMask SetCommState SetCommTimeouts SetupComm -WriteFile -SetCommMask -WaitCommEvent -CancelIo -ReadFile TransmitCommChar -EscapeCommFunction -GetCommModemStatus -GetOverlappedResult -ClearCommError -GetCommProperties WIN32_ERROR -GetHandleInformation \ No newline at end of file +WaitCommEvent +WriteFile +CreateFile \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 7dde20b..8c8d25d 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -568,25 +568,25 @@ public partial class SerialPort : IDisposable OnBreak(); } - uint i = 0; + MODEM_STATUS_FLAGS i = 0; if ((eventMask & COMM_EVENT_MASK.EV_CTS) != 0) { - i |= Win32Com.MS_CTS_ON; + i |= MODEM_STATUS_FLAGS.MS_CTS_ON; } if ((eventMask & COMM_EVENT_MASK.EV_DSR) != 0) { - i |= Win32Com.MS_DSR_ON; + i |= MODEM_STATUS_FLAGS.MS_DSR_ON; } if ((eventMask & COMM_EVENT_MASK.EV_RLSD) != 0) { - i |= Win32Com.MS_RLSD_ON; + i |= MODEM_STATUS_FLAGS.MS_RLSD_ON; } if ((eventMask & COMM_EVENT_MASK.EV_RING) != 0) { - i |= Win32Com.MS_RING_ON; + i |= MODEM_STATUS_FLAGS.MS_RING_ON; } if (i != 0) @@ -596,7 +596,7 @@ public partial class SerialPort : IDisposable throw new CommPortException("IO Error [005]"); } - OnStatusChange(new ModemStatus((MODEM_STATUS_FLAGS)i), new ModemStatus((MODEM_STATUS_FLAGS)f)); + OnStatusChange(new ModemStatus(i), new ModemStatus((MODEM_STATUS_FLAGS)f)); } } } diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index 98b2284..010308c 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -16,12 +16,6 @@ internal class Win32Com internal const UInt32 SETBREAK = 8; internal const UInt32 CLRBREAK = 9; - // Constants for lpModemStat: - internal const UInt32 MS_CTS_ON = 0x0010; - internal const UInt32 MS_DSR_ON = 0x0020; - internal const UInt32 MS_RING_ON = 0x0040; - internal const UInt32 MS_RLSD_ON = 0x0080; - //Constants for lpErrors: internal const UInt32 CE_RXOVER = 0x0001; internal const UInt32 CE_OVERRUN = 0x0002; -- 2.45.2 From 5e30d626519093dc20e6c80ef9133c3d65800157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:19:01 +0200 Subject: [PATCH 09/13] More type migrations --- .../NativeMethods.txt | 4 +++- .../SerialPort.Properties.cs | 17 ++++++++++------- .../Win32PInvoke/Win32Com.cs | 17 ----------------- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index 3194ae2..9de20e0 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -17,4 +17,6 @@ TransmitCommChar WIN32_ERROR WaitCommEvent WriteFile -CreateFile \ No newline at end of file +CreateFile +ESCAPE_COMM_FUNCTION +EscapeCommFunction \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs index e24b6e4..d44f695 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs @@ -1,4 +1,7 @@ -using Nefarius.Peripherals.SerialPort.Win32PInvoke; +using Windows.Win32; +using Windows.Win32.Devices.Communication; + +using Nefarius.Peripherals.SerialPort.Win32PInvoke; namespace Nefarius.Peripherals.SerialPort; @@ -141,14 +144,14 @@ public partial class SerialPort CheckOnline(); if (value) { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETRTS)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.SETRTS)) _stateRts = 1; else ThrowException("Unexpected Failure"); } else { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRRTS)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.CLRRTS)) _stateRts = 1; else ThrowException("Unexpected Failure"); @@ -173,14 +176,14 @@ public partial class SerialPort CheckOnline(); if (value) { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETDTR)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.SETDTR)) _stateDtr = 1; else ThrowException("Unexpected Failure"); } else { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRDTR)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.CLRDTR)) _stateDtr = 0; else ThrowException("Unexpected Failure"); @@ -200,14 +203,14 @@ public partial class SerialPort CheckOnline(); if (value) { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETBREAK)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.SETBREAK)) _stateBrk = 0; else ThrowException("Unexpected Failure"); } else { - if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRBREAK)) + if (PInvoke.EscapeCommFunction(_hPort, ESCAPE_COMM_FUNCTION.CLRBREAK)) _stateBrk = 0; else ThrowException("Unexpected Failure"); diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index 010308c..a535791 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -5,17 +5,6 @@ namespace Nefarius.Peripherals.SerialPort.Win32PInvoke; internal class Win32Com { - // Constants for dwFunc: - internal const UInt32 SETXOFF = 1; - internal const UInt32 SETXON = 2; - internal const UInt32 SETRTS = 3; - internal const UInt32 CLRRTS = 4; - internal const UInt32 SETDTR = 5; - internal const UInt32 CLRDTR = 6; - internal const UInt32 RESETDEV = 7; - internal const UInt32 SETBREAK = 8; - internal const UInt32 CLRBREAK = 9; - //Constants for lpErrors: internal const UInt32 CE_RXOVER = 0x0001; internal const UInt32 CE_OVERRUN = 0x0002; @@ -42,12 +31,6 @@ internal class Win32Com [DllImport("kernel32.dll")] internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar); - /// - /// Control port functions. - /// - [DllImport("kernel32.dll")] - internal static extern Boolean EscapeCommFunction(IntPtr hFile, UInt32 dwFunc); - [DllImport("kernel32.dll")] internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat); } \ No newline at end of file -- 2.45.2 From eec290ae8fac3ef0a3a34a78181c7679467bee9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:19:51 +0200 Subject: [PATCH 10/13] More migrations --- Nefarius.Peripherals.SerialPort/SerialPort.cs | 4 ++-- Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 8c8d25d..9dbe232 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -190,7 +190,7 @@ public partial class SerialPort : IDisposable private void InternalClose() { - Win32Com.CancelIo(_hPort.DangerousGetHandle()); + PInvoke.CancelIo(_hPort); if (_rxThread != null) { _rxThread.Abort(); @@ -542,7 +542,7 @@ public partial class SerialPort : IDisposable { if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) { - Win32Com.CancelIo(_hPort.DangerousGetHandle()); + PInvoke.CancelIo(_hPort); gotBytes = 0; } else diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index a535791..9d34003 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -20,14 +20,7 @@ internal class Win32Com [DllImport("kernel32.dll")] internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags); - - [DllImport("kernel32.dll")] - internal static extern Boolean CancelIo(IntPtr hFile); - - [DllImport("kernel32.dll", SetLastError = true)] - internal static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, UInt32 nNumberOfBytesToRead, - out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped); - + [DllImport("kernel32.dll")] internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar); -- 2.45.2 From a8068becba12277dbf186aa5239c36055110eff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:22:16 +0200 Subject: [PATCH 11/13] More migration fun --- Nefarius.Peripherals.SerialPort/NativeMethods.txt | 3 ++- Nefarius.Peripherals.SerialPort/SerialPort.cs | 8 ++++---- Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs | 5 ----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index 9de20e0..0794950 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -19,4 +19,5 @@ WaitCommEvent WriteFile CreateFile ESCAPE_COMM_FUNCTION -EscapeCommFunction \ No newline at end of file +EscapeCommFunction +CLEAR_COMM_ERROR_FLAGS \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index 9dbe232..d5bc17d 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -496,7 +496,7 @@ public partial class SerialPort : IDisposable if (PInvoke.ClearCommError(_hPort, &errs, null)) { StringBuilder s = new("UART Error: ", 40); - if (((uint)errs & Win32Com.CE_FRAME) != 0) + if (((uint)errs & (uint)CLEAR_COMM_ERROR_FLAGS.CE_FRAME) != 0) { s = s.Append("Framing,"); } @@ -506,17 +506,17 @@ public partial class SerialPort : IDisposable s = s.Append("IO,"); } - if (((uint)errs & Win32Com.CE_OVERRUN) != 0) + if (((uint)errs & (uint)CLEAR_COMM_ERROR_FLAGS.CE_OVERRUN) != 0) { s = s.Append("Overrun,"); } - if (((uint)errs & Win32Com.CE_RXOVER) != 0) + if (((uint)errs & (uint)CLEAR_COMM_ERROR_FLAGS.CE_RXOVER) != 0) { s = s.Append("Receive Overflow,"); } - if (((uint)errs & Win32Com.CE_RXPARITY) != 0) + if (((uint)errs & (uint)CLEAR_COMM_ERROR_FLAGS.CE_RXPARITY) != 0) { s = s.Append("Parity,"); } diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index 9d34003..2fae8d2 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -6,11 +6,6 @@ namespace Nefarius.Peripherals.SerialPort.Win32PInvoke; internal class Win32Com { //Constants for lpErrors: - internal const UInt32 CE_RXOVER = 0x0001; - internal const UInt32 CE_OVERRUN = 0x0002; - internal const UInt32 CE_RXPARITY = 0x0004; - internal const UInt32 CE_FRAME = 0x0008; - internal const UInt32 CE_BREAK = 0x0010; internal const UInt32 CE_TXFULL = 0x0100; internal const UInt32 CE_PTO = 0x0200; internal const UInt32 CE_IOE = 0x0400; -- 2.45.2 From 086633b8a26c1ecfc0586554b8f2b40e9390231b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:24:30 +0200 Subject: [PATCH 12/13] More type migration --- Nefarius.Peripherals.SerialPort/NativeMethods.txt | 8 +++++++- Nefarius.Peripherals.SerialPort/SerialPort.cs | 4 ++-- Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs | 9 +-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index 0794950..88e99b5 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -20,4 +20,10 @@ WriteFile CreateFile ESCAPE_COMM_FUNCTION EscapeCommFunction -CLEAR_COMM_ERROR_FLAGS \ No newline at end of file +CLEAR_COMM_ERROR_FLAGS +CE_TXFULL +CE_PTO +CE_IOE +CE_DNS +CE_OOP +CE_MODE \ No newline at end of file diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index d5bc17d..a98a6da 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -501,7 +501,7 @@ public partial class SerialPort : IDisposable s = s.Append("Framing,"); } - if (((uint)errs & Win32Com.CE_IOE) != 0) + if (((uint)errs & PInvoke.CE_IOE) != 0) { s = s.Append("IO,"); } @@ -521,7 +521,7 @@ public partial class SerialPort : IDisposable s = s.Append("Parity,"); } - if (((uint)errs & Win32Com.CE_TXFULL) != 0) + if (((uint)errs & PInvoke.CE_TXFULL) != 0) { s = s.Append("Transmit Overflow,"); } diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs index 2fae8d2..5603c89 100644 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs @@ -3,16 +3,9 @@ using System.Runtime.InteropServices; namespace Nefarius.Peripherals.SerialPort.Win32PInvoke; +[Obsolete("use CsWin32 instead.")] internal class Win32Com { - //Constants for lpErrors: - internal const UInt32 CE_TXFULL = 0x0100; - internal const UInt32 CE_PTO = 0x0200; - internal const UInt32 CE_IOE = 0x0400; - internal const UInt32 CE_DNS = 0x0800; - internal const UInt32 CE_OOP = 0x1000; - internal const UInt32 CE_MODE = 0x8000; - [DllImport("kernel32.dll")] internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags); -- 2.45.2 From 7eee997084080180721bf0f0c5e9ce5779732f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 13 Jul 2024 15:28:19 +0200 Subject: [PATCH 13/13] Migrated all legacy PInvoke --- .../NativeMethods.txt | 1 - Nefarius.Peripherals.SerialPort/QueueStatus.cs | 2 +- .../SerialPort.Properties.cs | 2 -- Nefarius.Peripherals.SerialPort/SerialPort.cs | 14 ++++++-------- .../Win32PInvoke/Win32Com.cs | 17 ----------------- 5 files changed, 7 insertions(+), 29 deletions(-) delete mode 100644 Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs diff --git a/Nefarius.Peripherals.SerialPort/NativeMethods.txt b/Nefarius.Peripherals.SerialPort/NativeMethods.txt index 88e99b5..48e53bd 100644 --- a/Nefarius.Peripherals.SerialPort/NativeMethods.txt +++ b/Nefarius.Peripherals.SerialPort/NativeMethods.txt @@ -5,7 +5,6 @@ FILE_ACCESS_RIGHTS GetCommModemStatus GetCommProperties GetHandleInformation -GetHandleInformation GetOverlappedResult MODEM_STATUS_FLAGS ReadFile diff --git a/Nefarius.Peripherals.SerialPort/QueueStatus.cs b/Nefarius.Peripherals.SerialPort/QueueStatus.cs index 63469fd..661b5dc 100644 --- a/Nefarius.Peripherals.SerialPort/QueueStatus.cs +++ b/Nefarius.Peripherals.SerialPort/QueueStatus.cs @@ -1,5 +1,5 @@ using System.Text; -using Nefarius.Peripherals.SerialPort.Win32PInvoke; + namespace Nefarius.Peripherals.SerialPort { diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs index d44f695..55214cf 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs @@ -1,8 +1,6 @@ using Windows.Win32; using Windows.Win32.Devices.Communication; -using Nefarius.Peripherals.SerialPort.Win32PInvoke; - namespace Nefarius.Peripherals.SerialPort; public partial class SerialPort diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs index a98a6da..75114e8 100644 --- a/Nefarius.Peripherals.SerialPort/SerialPort.cs +++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs @@ -11,8 +11,6 @@ using Windows.Win32.Storage.FileSystem; using Microsoft.Win32.SafeHandles; -using Nefarius.Peripherals.SerialPort.Win32PInvoke; - namespace Nefarius.Peripherals.SerialPort; /// @@ -344,7 +342,7 @@ public partial class SerialPort : IDisposable public void SendImmediate(byte tosend) { CheckOnline(); - if (!Win32Com.TransmitCommChar(_hPort.DangerousGetHandle(), tosend)) + if (!PInvoke.TransmitCommChar(_hPort, new CHAR((sbyte)tosend))) { ThrowException("Transmission failure"); } @@ -357,12 +355,12 @@ public partial class SerialPort : IDisposable protected ModemStatus GetModemStatus() { CheckOnline(); - if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out uint f)) + if (!PInvoke.GetCommModemStatus(_hPort, out MODEM_STATUS_FLAGS f)) { ThrowException("Unexpected failure"); } - return new ModemStatus((MODEM_STATUS_FLAGS)f); + return new ModemStatus(f); } /// @@ -591,12 +589,12 @@ public partial class SerialPort : IDisposable if (i != 0) { - if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out uint f)) + if (!PInvoke.GetCommModemStatus(_hPort, out MODEM_STATUS_FLAGS f)) { throw new CommPortException("IO Error [005]"); } - OnStatusChange(new ModemStatus(i), new ModemStatus((MODEM_STATUS_FLAGS)f)); + OnStatusChange(new ModemStatus(i), new ModemStatus(f)); } } } @@ -620,7 +618,7 @@ public partial class SerialPort : IDisposable if (_online) { - if (Win32Com.GetHandleInformation(_hPort.DangerousGetHandle(), out uint _)) + if (PInvoke.GetHandleInformation(_hPort, out uint _)) { return true; } diff --git a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs b/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs deleted file mode 100644 index 5603c89..0000000 --- a/Nefarius.Peripherals.SerialPort/Win32PInvoke/Win32Com.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Nefarius.Peripherals.SerialPort.Win32PInvoke; - -[Obsolete("use CsWin32 instead.")] -internal class Win32Com -{ - [DllImport("kernel32.dll")] - internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags); - - [DllImport("kernel32.dll")] - internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar); - - [DllImport("kernel32.dll")] - internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat); -} \ No newline at end of file -- 2.45.2