public void Open() { fileHandle = SafeNativeMethods.CreateFile(fileName, SafeNativeMethods.GENERIC_READ | SafeNativeMethods.GENERIC_WRITE, SafeNativeMethods.FILE_SHARE_READ | SafeNativeMethods.FILE_SHARE_WRITE, 0, SafeNativeMethods.OPEN_EXISTING, SafeNativeMethods.FILE_FLAG_OVERLAPPED, IntPtr.Zero); int errorCode; if (fileHandle.IsInvalid) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"Error opening COM port. Last Win32 error code is {errorCode}."); } ComStat comStat = default; int errors = 0; if (SafeNativeMethods.ClearCommError(fileHandle, ref errors, ref comStat) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"ClearCommError returned FALSE. Last Win32 error code is {errorCode}. Error buffer from method contains {errors}."); } if (SafeNativeMethods.PurgeComm(fileHandle, SafeNativeMethods.PURGE_RXCLEAR | SafeNativeMethods.PURGE_TXCLEAR) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"PurgeComm returned FALSE. Last Win32 error code is {errorCode}."); } DCB dcb = default; if (SafeNativeMethods.GetCommState(fileHandle, ref dcb) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"GetCommState returned FALSE. Last Win32 error code is {errorCode}."); } //Parity in the DCB format is a single character, which happens to correspond to the first character of the enum symbols. var dcbString = $"baud={baudRate} parity={parity.ToString()[0]} data={dataBits} stop={(int)stopBits}"; if (SafeNativeMethods.BuildCommDCB(dcbString, ref dcb) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"BuildCommDCB returned FALSE. Last Win32 error code is {errorCode}."); } if (SafeNativeMethods.SetCommState(fileHandle, ref dcb) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"SetCommState returned FALSE. Last Win32 error code is {errorCode}."); } if (SafeNativeMethods.SetupComm(fileHandle, (uint)bufferSize, (uint)bufferSize) == 0) { errorCode = Marshal.GetLastWin32Error(); throw new InvalidOperationException($"SetupComm returned FALSE. Last Win32 error code is {errorCode}."); } }
internal static extern int ClearCommError( SafeHandle hFile, ref int lpErrors, ref ComStat lpComStat);