Migrated to CsWin32 #1
@ -1,4 +1,5 @@
|
|||||||
CreateFile
|
CreateFile
|
||||||
|
FILE_ACCESS_RIGHTS
|
||||||
GetHandleInformation
|
GetHandleInformation
|
||||||
SetCommState
|
SetCommState
|
||||||
SetCommTimeouts
|
SetCommTimeouts
|
||||||
|
@ -34,5 +34,6 @@
|
|||||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.123">
|
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.123">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="61.0.15-preview" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,12 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using Windows.Win32;
|
using Windows.Win32;
|
||||||
using Windows.Win32.Devices.Communication;
|
using Windows.Win32.Devices.Communication;
|
||||||
using Windows.Win32.Foundation;
|
using Windows.Win32.Foundation;
|
||||||
using Windows.Win32.Storage.FileSystem;
|
using Windows.Win32.Storage.FileSystem;
|
||||||
|
|
||||||
using Microsoft.Win32.SafeHandles;
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
|
||||||
using Nefarius.Peripherals.SerialPort.Win32PInvoke;
|
using Nefarius.Peripherals.SerialPort.Win32PInvoke;
|
||||||
|
|
||||||
namespace Nefarius.Peripherals.SerialPort;
|
namespace Nefarius.Peripherals.SerialPort;
|
||||||
@ -14,6 +18,7 @@ namespace Nefarius.Peripherals.SerialPort;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wrapper class around a serial (COM, RS-232) port.
|
/// Wrapper class around a serial (COM, RS-232) port.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
public partial class SerialPort : IDisposable
|
public partial class SerialPort : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _writeEvent = new(false);
|
private readonly ManualResetEvent _writeEvent = new(false);
|
||||||
@ -64,18 +69,25 @@ public partial class SerialPort : IDisposable
|
|||||||
/// <returns>false if the port could not be opened</returns>
|
/// <returns>false if the port could not be opened</returns>
|
||||||
public bool Open()
|
public bool Open()
|
||||||
{
|
{
|
||||||
var portDcb = new DCB();
|
DCB portDcb = new();
|
||||||
var commTimeouts = new COMMTIMEOUTS();
|
COMMTIMEOUTS commTimeouts = new();
|
||||||
|
|
||||||
if (_online) return false;
|
if (_online)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_hPort = PInvoke.CreateFile(PortName,
|
_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);
|
null, FILE_CREATION_DISPOSITION.OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_OVERLAPPED, null);
|
||||||
|
|
||||||
if (_hPort.IsInvalid)
|
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");
|
throw new CommPortException("Port Open Failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,20 +104,28 @@ public partial class SerialPort : IDisposable
|
|||||||
portDcb.ByteSize = (byte)DataBits;
|
portDcb.ByteSize = (byte)DataBits;
|
||||||
portDcb.Parity = (DCB_PARITY)Parity;
|
portDcb.Parity = (DCB_PARITY)Parity;
|
||||||
portDcb.StopBits = (DCB_STOP_BITS)StopBits;
|
portDcb.StopBits = (DCB_STOP_BITS)StopBits;
|
||||||
portDcb.XoffChar = (CHAR)(byte)XoffChar;
|
portDcb.XoffChar = new CHAR((sbyte)XoffChar);
|
||||||
portDcb.XonChar = (CHAR)(byte)XonChar;
|
portDcb.XonChar = new CHAR((sbyte)XonChar);
|
||||||
portDcb.XoffLim = (ushort)RxHighWater;
|
portDcb.XoffLim = (ushort)RxHighWater;
|
||||||
portDcb.XonLim = (ushort)RxLowWater;
|
portDcb.XonLim = (ushort)RxLowWater;
|
||||||
|
|
||||||
if (RxQueue != 0 || TxQueue != 0)
|
if (RxQueue != 0 || TxQueue != 0)
|
||||||
|
{
|
||||||
if (!PInvoke.SetupComm(_hPort, (uint)RxQueue, (uint)TxQueue))
|
if (!PInvoke.SetupComm(_hPort, (uint)RxQueue, (uint)TxQueue))
|
||||||
|
{
|
||||||
ThrowException("Bad queue settings");
|
ThrowException("Bad queue settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!PInvoke.SetCommState(_hPort, portDcb))
|
if (!PInvoke.SetCommState(_hPort, portDcb))
|
||||||
|
{
|
||||||
ThrowException("Bad com settings");
|
ThrowException("Bad com settings");
|
||||||
|
}
|
||||||
|
|
||||||
if (!PInvoke.SetCommTimeouts(_hPort, commTimeouts))
|
if (!PInvoke.SetCommTimeouts(_hPort, commTimeouts))
|
||||||
|
{
|
||||||
ThrowException("Bad timeout settings");
|
ThrowException("Bad timeout settings");
|
||||||
|
}
|
||||||
|
|
||||||
_stateBrk = 0;
|
_stateBrk = 0;
|
||||||
switch (UseDtr)
|
switch (UseDtr)
|
||||||
@ -135,12 +155,9 @@ public partial class SerialPort : IDisposable
|
|||||||
_rxException = null;
|
_rxException = null;
|
||||||
_rxExceptionReported = false;
|
_rxExceptionReported = false;
|
||||||
|
|
||||||
// TODO: utilize Task Parallel Library here
|
|
||||||
_rxThread = new Thread(ReceiveThread)
|
_rxThread = new Thread(ReceiveThread)
|
||||||
{
|
{
|
||||||
Name = "CommBaseRx",
|
Name = "CommBaseRx", Priority = ThreadPriority.AboveNormal, IsBackground = true
|
||||||
Priority = ThreadPriority.AboveNormal,
|
|
||||||
IsBackground = true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_rxThread.Start();
|
_rxThread.Start();
|
||||||
@ -211,14 +228,22 @@ public partial class SerialPort : IDisposable
|
|||||||
/// <param name="reason">Description of fault</param>
|
/// <param name="reason">Description of fault</param>
|
||||||
protected void ThrowException(string reason)
|
protected void ThrowException(string reason)
|
||||||
{
|
{
|
||||||
if (Thread.CurrentThread == _rxThread) throw new CommPortException(reason);
|
if (Thread.CurrentThread == _rxThread)
|
||||||
|
{
|
||||||
|
throw new CommPortException(reason);
|
||||||
|
}
|
||||||
|
|
||||||
if (_online)
|
if (_online)
|
||||||
{
|
{
|
||||||
BeforeClose(true);
|
BeforeClose(true);
|
||||||
InternalClose();
|
InternalClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rxException == null) throw new CommPortException(reason);
|
if (_rxException == null)
|
||||||
|
{
|
||||||
|
throw new CommPortException(reason);
|
||||||
|
}
|
||||||
|
|
||||||
throw new CommPortException(_rxException);
|
throw new CommPortException(_rxException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +253,6 @@ public partial class SerialPort : IDisposable
|
|||||||
/// <param name="toSend">Array of bytes to be sent</param>
|
/// <param name="toSend">Array of bytes to be sent</param>
|
||||||
public unsafe void Write(byte[] toSend)
|
public unsafe void Write(byte[] toSend)
|
||||||
{
|
{
|
||||||
uint sent;
|
|
||||||
CheckOnline();
|
CheckOnline();
|
||||||
CheckResult();
|
CheckResult();
|
||||||
_writeCount = toSend.GetLength(0);
|
_writeCount = toSend.GetLength(0);
|
||||||
@ -236,6 +260,7 @@ public partial class SerialPort : IDisposable
|
|||||||
fixed (byte* ptr = toSend)
|
fixed (byte* ptr = toSend)
|
||||||
fixed (NativeOverlapped* ptrOl = &_ptrUwo)
|
fixed (NativeOverlapped* ptrOl = &_ptrUwo)
|
||||||
{
|
{
|
||||||
|
uint sent;
|
||||||
if (PInvoke.WriteFile(_hPort, ptr, (uint)_writeCount, &sent, ptrOl))
|
if (PInvoke.WriteFile(_hPort, ptr, (uint)_writeCount, &sent, ptrOl))
|
||||||
{
|
{
|
||||||
_writeCount -= (int)sent;
|
_writeCount -= (int)sent;
|
||||||
@ -243,10 +268,12 @@ public partial class SerialPort : IDisposable
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING)
|
if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
ThrowException("Unexpected failure");
|
ThrowException("Unexpected failure");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queues string for transmission.
|
/// Queues string for transmission.
|
||||||
@ -263,7 +290,7 @@ public partial class SerialPort : IDisposable
|
|||||||
/// <param name="toSend">Byte to be sent</param>
|
/// <param name="toSend">Byte to be sent</param>
|
||||||
public void Write(byte toSend)
|
public void Write(byte toSend)
|
||||||
{
|
{
|
||||||
var b = new byte[1];
|
byte[] b = new byte[1];
|
||||||
b[0] = toSend;
|
b[0] = toSend;
|
||||||
Write(b);
|
Write(b);
|
||||||
}
|
}
|
||||||
@ -288,15 +315,25 @@ public partial class SerialPort : IDisposable
|
|||||||
|
|
||||||
private void CheckResult()
|
private void CheckResult()
|
||||||
{
|
{
|
||||||
if (_writeCount <= 0) return;
|
if (_writeCount <= 0)
|
||||||
if (PInvoke.GetOverlappedResult(_hPort, _ptrUwo, out var sent, _checkSends))
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PInvoke.GetOverlappedResult(_hPort, _ptrUwo, out uint sent, _checkSends))
|
||||||
{
|
{
|
||||||
_writeCount -= (int)sent;
|
_writeCount -= (int)sent;
|
||||||
if (_writeCount != 0) ThrowException("Send Timeout");
|
if (_writeCount != 0)
|
||||||
|
{
|
||||||
|
ThrowException("Send Timeout");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
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)
|
public void SendImmediate(byte tosend)
|
||||||
{
|
{
|
||||||
CheckOnline();
|
CheckOnline();
|
||||||
if (!Win32Com.TransmitCommChar(_hPort.DangerousGetHandle(), tosend)) ThrowException("Transmission failure");
|
if (!Win32Com.TransmitCommChar(_hPort.DangerousGetHandle(), tosend))
|
||||||
|
{
|
||||||
|
ThrowException("Transmission failure");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -318,7 +358,11 @@ public partial class SerialPort : IDisposable
|
|||||||
protected ModemStatus GetModemStatus()
|
protected ModemStatus GetModemStatus()
|
||||||
{
|
{
|
||||||
CheckOnline();
|
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);
|
return new ModemStatus((MODEM_STATUS_FLAGS)f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,15 +373,19 @@ public partial class SerialPort : IDisposable
|
|||||||
protected unsafe QueueStatus GetQueueStatus()
|
protected unsafe QueueStatus GetQueueStatus()
|
||||||
{
|
{
|
||||||
COMSTAT cs;
|
COMSTAT cs;
|
||||||
var cp = new COMMPROP();
|
COMMPROP cp = new();
|
||||||
CLEAR_COMM_ERROR_FLAGS er;
|
CLEAR_COMM_ERROR_FLAGS er;
|
||||||
|
|
||||||
CheckOnline();
|
CheckOnline();
|
||||||
if (!PInvoke.ClearCommError(_hPort, &er, &cs))
|
if (!PInvoke.ClearCommError(_hPort, &er, &cs))
|
||||||
|
{
|
||||||
ThrowException("Unexpected failure");
|
ThrowException("Unexpected failure");
|
||||||
|
}
|
||||||
|
|
||||||
if (!PInvoke.GetCommProperties(_hPort, ref cp))
|
if (!PInvoke.GetCommProperties(_hPort, &cp))
|
||||||
|
{
|
||||||
ThrowException("Unexpected failure");
|
ThrowException("Unexpected failure");
|
||||||
|
}
|
||||||
|
|
||||||
return new QueueStatus(cs._bitfield, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue);
|
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()
|
private unsafe void ReceiveThread()
|
||||||
{
|
{
|
||||||
var buf = stackalloc byte[1];
|
byte* buf = stackalloc byte[1];
|
||||||
|
|
||||||
var sg = new AutoResetEvent(false);
|
AutoResetEvent sg = new(false);
|
||||||
var ov = new NativeOverlapped
|
NativeOverlapped ov = new() { EventHandle = sg.SafeWaitHandle.DangerousGetHandle() };
|
||||||
{
|
|
||||||
EventHandle = sg.SafeWaitHandle.DangerousGetHandle()
|
|
||||||
};
|
|
||||||
|
|
||||||
COMM_EVENT_MASK eventMask = 0;
|
COMM_EVENT_MASK eventMask = 0;
|
||||||
|
|
||||||
@ -431,28 +476,58 @@ public partial class SerialPort : IDisposable
|
|||||||
COMM_EVENT_MASK.EV_DSR
|
COMM_EVENT_MASK.EV_DSR
|
||||||
| COMM_EVENT_MASK.EV_BREAK | COMM_EVENT_MASK.EV_RLSD | COMM_EVENT_MASK.EV_RING |
|
| COMM_EVENT_MASK.EV_BREAK | COMM_EVENT_MASK.EV_RLSD | COMM_EVENT_MASK.EV_RING |
|
||||||
COMM_EVENT_MASK.EV_ERR))
|
COMM_EVENT_MASK.EV_ERR))
|
||||||
|
{
|
||||||
throw new CommPortException("IO Error [001]");
|
throw new CommPortException("IO Error [001]");
|
||||||
|
}
|
||||||
|
|
||||||
if (!PInvoke.WaitCommEvent(_hPort, ref eventMask, &ov))
|
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();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
throw new CommPortException("IO Error [002]");
|
throw new CommPortException("IO Error [002]");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_ERR) != 0)
|
if ((eventMask & COMM_EVENT_MASK.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))
|
||||||
{
|
{
|
||||||
var s = new StringBuilder("UART Error: ", 40);
|
StringBuilder s = new("UART Error: ", 40);
|
||||||
if (((uint)errs & Win32Com.CE_FRAME) != 0) s = s.Append("Framing,");
|
if (((uint)errs & Win32Com.CE_FRAME) != 0)
|
||||||
if (((uint)errs & Win32Com.CE_IOE) != 0) s = s.Append("IO,");
|
{
|
||||||
if (((uint)errs & Win32Com.CE_OVERRUN) != 0) s = s.Append("Overrun,");
|
s = s.Append("Framing,");
|
||||||
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,");
|
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;
|
s.Length -= 1;
|
||||||
throw new CommPortException(s.ToString());
|
throw new CommPortException(s.ToString());
|
||||||
}
|
}
|
||||||
@ -462,15 +537,15 @@ public partial class SerialPort : IDisposable
|
|||||||
|
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_RXCHAR) != 0)
|
if ((eventMask & COMM_EVENT_MASK.EV_RXCHAR) != 0)
|
||||||
{
|
{
|
||||||
uint gotbytes;
|
uint gotBytes;
|
||||||
do
|
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)
|
if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
Win32Com.CancelIo(_hPort.DangerousGetHandle());
|
Win32Com.CancelIo(_hPort.DangerousGetHandle());
|
||||||
gotbytes = 0;
|
gotBytes = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -478,30 +553,59 @@ public partial class SerialPort : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gotbytes == 1) OnRxChar(buf[0]);
|
if (gotBytes == 1)
|
||||||
} while (gotbytes > 0);
|
{
|
||||||
|
OnRxChar(buf[0]);
|
||||||
|
}
|
||||||
|
} while (gotBytes > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_TXEMPTY) != 0) OnTxDone();
|
if ((eventMask & COMM_EVENT_MASK.EV_TXEMPTY) != 0)
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_BREAK) != 0) OnBreak();
|
{
|
||||||
|
OnTxDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((eventMask & COMM_EVENT_MASK.EV_BREAK) != 0)
|
||||||
|
{
|
||||||
|
OnBreak();
|
||||||
|
}
|
||||||
|
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON;
|
if ((eventMask & COMM_EVENT_MASK.EV_CTS) != 0)
|
||||||
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;
|
i |= Win32Com.MS_CTS_ON;
|
||||||
if ((eventMask & COMM_EVENT_MASK.EV_RING) != 0) i |= Win32Com.MS_RING_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)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
uint f;
|
uint f;
|
||||||
if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f))
|
if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f))
|
||||||
|
{
|
||||||
throw new CommPortException("IO Error [005]");
|
throw new CommPortException("IO Error [005]");
|
||||||
|
}
|
||||||
|
|
||||||
OnStatusChange(new ModemStatus((MODEM_STATUS_FLAGS)i), new ModemStatus((MODEM_STATUS_FLAGS)f));
|
OnStatusChange(new ModemStatus((MODEM_STATUS_FLAGS)i), new ModemStatus((MODEM_STATUS_FLAGS)f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (!(e is ThreadAbortException))
|
if (e is not ThreadAbortException)
|
||||||
{
|
{
|
||||||
_rxException = e;
|
_rxException = e;
|
||||||
OnRxException(e);
|
OnRxException(e);
|
||||||
@ -519,15 +623,23 @@ public partial class SerialPort : IDisposable
|
|||||||
|
|
||||||
if (_online)
|
if (_online)
|
||||||
{
|
{
|
||||||
uint f;
|
if (Win32Com.GetHandleInformation(_hPort.DangerousGetHandle(), out uint _))
|
||||||
if (Win32Com.GetHandleInformation(_hPort.DangerousGetHandle(), out f)) return true;
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ThrowException("Offline");
|
ThrowException("Offline");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_auto)
|
if (_auto)
|
||||||
|
{
|
||||||
if (Open())
|
if (Open())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ThrowException("Offline");
|
ThrowException("Offline");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user