Ported more methods

This commit is contained in:
Benjamin Höglinger-Stelzer 2022-10-03 20:21:52 +02:00
parent 7b5449a95b
commit 1219c19acb
2 changed files with 25 additions and 45 deletions

View File

@ -12,8 +12,7 @@ using Nefarius.Peripherals.SerialPort.Win32PInvoke;
namespace Nefarius.Peripherals.SerialPort; namespace Nefarius.Peripherals.SerialPort;
/// <summary> /// <summary>
/// PInvokeSerialPort main class. /// Wrapper class around a serial (COM, RS-232) port.
/// Borrowed from http://msdn.microsoft.com/en-us/magazine/cc301786.aspx ;)
/// </summary> /// </summary>
public partial class SerialPort : IDisposable public partial class SerialPort : IDisposable
{ {
@ -415,29 +414,28 @@ public partial class SerialPort : IDisposable
private unsafe void ReceiveThread() private unsafe void ReceiveThread()
{ {
var buf = new byte[1]; var buf = stackalloc byte[1];
var sg = new AutoResetEvent(false); var sg = new AutoResetEvent(false);
var ov = new OVERLAPPED(); var ov = new NativeOverlapped
var unmanagedOv = Marshal.AllocHGlobal(Marshal.SizeOf(ov)); {
ov.Offset = 0; EventHandle = sg.SafeWaitHandle.DangerousGetHandle()
ov.OffsetHigh = 0; };
ov.hEvent = sg.SafeWaitHandle.DangerousGetHandle();
Marshal.StructureToPtr(ov, unmanagedOv, true);
uint eventMask = 0; COMM_EVENT_MASK eventMask = 0;
var uMask = Marshal.AllocHGlobal(Marshal.SizeOf(eventMask));
try try
{ {
while (true) while (true)
{ {
if (!Win32Com.SetCommMask(_hPort.DangerousGetHandle(), if (!PInvoke.SetCommMask(_hPort,
Win32Com.EV_RXCHAR | Win32Com.EV_TXEMPTY | Win32Com.EV_CTS | Win32Com.EV_DSR COMM_EVENT_MASK.EV_RXCHAR | COMM_EVENT_MASK.EV_TXEMPTY | COMM_EVENT_MASK.EV_CTS |
| Win32Com.EV_BREAK | Win32Com.EV_RLSD | Win32Com.EV_RING | Win32Com.EV_ERR)) 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]"); 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) if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
sg.WaitOne(); sg.WaitOne();
@ -445,8 +443,7 @@ public partial class SerialPort : IDisposable
throw new CommPortException("IO Error [002]"); throw new CommPortException("IO Error [002]");
} }
eventMask = (uint)Marshal.ReadInt32(uMask); if ((eventMask & COMM_EVENT_MASK.EV_ERR) != 0)
if ((eventMask & Win32Com.EV_ERR) != 0)
{ {
CLEAR_COMM_ERROR_FLAGS errs; CLEAR_COMM_ERROR_FLAGS errs;
if (PInvoke.ClearCommError(_hPort, &errs, null)) if (PInvoke.ClearCommError(_hPort, &errs, null))
@ -465,12 +462,12 @@ public partial class SerialPort : IDisposable
throw new CommPortException("IO Error [003]"); throw new CommPortException("IO Error [003]");
} }
if ((eventMask & Win32Com.EV_RXCHAR) != 0) if ((eventMask & COMM_EVENT_MASK.EV_RXCHAR) != 0)
{ {
uint gotbytes; uint gotbytes;
do 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) if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
{ {
@ -487,14 +484,14 @@ public partial class SerialPort : IDisposable
} while (gotbytes > 0); } while (gotbytes > 0);
} }
if ((eventMask & Win32Com.EV_TXEMPTY) != 0) OnTxDone(); if ((eventMask & COMM_EVENT_MASK.EV_TXEMPTY) != 0) OnTxDone();
if ((eventMask & Win32Com.EV_BREAK) != 0) OnBreak(); if ((eventMask & COMM_EVENT_MASK.EV_BREAK) != 0) OnBreak();
uint i = 0; uint i = 0;
if ((eventMask & Win32Com.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON; if ((eventMask & COMM_EVENT_MASK.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON;
if ((eventMask & Win32Com.EV_DSR) != 0) i |= Win32Com.MS_DSR_ON; if ((eventMask & COMM_EVENT_MASK.EV_DSR) != 0) i |= Win32Com.MS_DSR_ON;
if ((eventMask & Win32Com.EV_RLSD) != 0) i |= Win32Com.MS_RLSD_ON; if ((eventMask & COMM_EVENT_MASK.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_RING) != 0) i |= Win32Com.MS_RING_ON;
if (i != 0) if (i != 0)
{ {
uint f; uint f;
@ -506,8 +503,6 @@ public partial class SerialPort : IDisposable
} }
catch (Exception e) catch (Exception e)
{ {
if (uMask != IntPtr.Zero) Marshal.FreeHGlobal(uMask);
if (unmanagedOv != IntPtr.Zero) Marshal.FreeHGlobal(unmanagedOv);
if (!(e is ThreadAbortException)) if (!(e is ThreadAbortException))
{ {
_rxException = e; _rxException = e;

View File

@ -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;
}
}