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);