Exemple #1
0
        public void ApplySerialParam(SerialTerminalSettings settings)
        {
            //paramの内容でDCBを更新してセットしなおす
            Win32Serial.DCB dcb = new Win32Serial.DCB();
            SerialPortUtil.FillDCB(_fileHandle, ref dcb);
            SerialPortUtil.UpdateDCB(ref dcb, settings);

            if (!Win32Serial.SetCommState(_fileHandle, ref dcb))
            {
                throw new ArgumentException(SerialPortPlugin.Instance.Strings.GetString("Message.SerialTerminalConnection.ConfigError"));
            }
        }
Exemple #2
0
 public void Close()
 {
     if (_writeOverlappedEvent != null)
     {
         if (_commEventOverlappedPinned.IsAllocated)
         {
             Win32Serial.CancelIoEx(_fileHandle, _commEventOverlappedPinned.AddrOfPinnedObject());
             _commEventOverlappedPinned.Free();
         }
         _writeOverlappedEvent.Close();
         _writeOverlappedEvent = null;
     }
 }
Exemple #3
0
 public static bool FillDCB(IntPtr handle, ref Win32Serial.DCB dcb)
 {
     dcb.DCBlength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32Serial.DCB)); //sizeofくらいunsafeでなくても使わせてくれよ
     return(Win32Serial.GetCommState(handle, ref dcb));
 }
Exemple #4
0
        public static SerialTerminalConnection CreateNewSerialConnection(IPoderosaMainWindow window, SerialTerminalParam param, SerialTerminalSettings settings)
        {
            bool       successful = false;
            FileStream strm       = null;

            try {
                StringResource sr = SerialPortPlugin.Instance.Strings;
                //Debug.WriteLine("OPENING COM"+param.Port);
                string portstr = String.Format("\\\\.\\{0}", param.PortName);
                IntPtr ptr     = Win32Serial.CreateFile(portstr, Win32.GENERIC_READ | Win32.GENERIC_WRITE, 0, IntPtr.Zero, Win32.OPEN_EXISTING, Win32.FILE_ATTRIBUTE_NORMAL | Win32.FILE_FLAG_OVERLAPPED, IntPtr.Zero);
                if (ptr == Win32.INVALID_HANDLE_VALUE)
                {
                    string msg = sr.GetString("Message.FailedToOpenSerial");
                    int    err = Marshal.GetLastWin32Error();
                    if (err == 2)
                    {
                        msg += sr.GetString("Message.NoSuchDevice");
                    }
                    else if (err == 5)
                    {
                        msg += sr.GetString("Message.DeviceIsBusy");
                    }
                    else
                    {
                        msg += "\nGetLastError=" + Marshal.GetLastWin32Error();
                    }
                    throw new Exception(msg);
                }
                //strm = new FileStream(ptr, FileAccess.Write, true, 8, true);
                Win32Serial.DCB dcb = new Win32Serial.DCB();
                FillDCB(ptr, ref dcb);
                UpdateDCB(ref dcb, settings);

                if (!Win32Serial.SetCommState(ptr, ref dcb))
                {
                    Win32.CloseHandle(ptr);
                    throw new Exception(sr.GetString("Message.FailedToConfigSerial"));
                }
                Win32Serial.COMMTIMEOUTS timeouts = new Win32Serial.COMMTIMEOUTS();
                Win32Serial.GetCommTimeouts(ptr, ref timeouts);
                timeouts.ReadIntervalTimeout         = 0xFFFFFFFF;
                timeouts.ReadTotalTimeoutConstant    = 0;
                timeouts.ReadTotalTimeoutMultiplier  = 0;
                timeouts.WriteTotalTimeoutConstant   = 100;
                timeouts.WriteTotalTimeoutMultiplier = 100;
                Win32Serial.SetCommTimeouts(ptr, ref timeouts);
                successful = true;
                SerialTerminalConnection r = new SerialTerminalConnection(param, settings, ptr);
                return(r);
            }
            catch (Exception ex) {
                RuntimeUtil.SilentReportException(ex);
                if (window != null)
                {
                    window.Warning(ex.Message);
                }
                else
                {
                    GUtil.Warning(Form.ActiveForm, ex.Message); //TODO 苦しい逃げ。IPoderosaFormを実装したベースクラスをCoreにでも持っていたほうがいいのか
                }
                return(null);
            }
            finally {
                if (!successful && strm != null)
                {
                    strm.Close();
                }
            }
        }
Exemple #5
0
        private void WriteMain(byte[] buf, int offset, int length)
        {
            byte[] bufToWrite;

            while (length > 0)
            {
                if (offset != 0)
                {
                    bufToWrite = new byte[length];
                    Buffer.BlockCopy(buf, offset, bufToWrite, 0, length);
                }
                else
                {
                    bufToWrite = buf;
                }

                int              wroteLength             = 0;
                GCHandle         wroteLengthPinned       = GCHandle.Alloc(wroteLength, GCHandleType.Pinned);
                int              transferredLength       = 0;
                GCHandle         transferredLengthPinned = GCHandle.Alloc(transferredLength, GCHandleType.Pinned);
                NativeOverlapped writeOverlapped         = new NativeOverlapped();
                writeOverlapped.EventHandle = _writeOverlappedEvent.SafeWaitHandle.DangerousGetHandle();
                GCHandle writeOverlappedPinned = GCHandle.Alloc(writeOverlapped, GCHandleType.Pinned);
                GCHandle bufToWritePinned      = GCHandle.Alloc(bufToWrite, GCHandleType.Pinned);

                // Note:
                //  GCHandle.Alloc(<struct>, GCHandleType.Pinned) makes a GCHandle for `Boxed' struct object.
                //  So if you want to read a value of the struct, you have to read it from `Boxed' struct object
                //  which is returned by GCHandle.Target.

                try {
                    bool success = Win32Serial.WriteFile(
                        _fileHandle,
                        bufToWritePinned.AddrOfPinnedObject(),
                        length,
                        wroteLengthPinned.AddrOfPinnedObject(),
                        writeOverlappedPinned.AddrOfPinnedObject());
                    if (!success)
                    {
                        int lastErr = Marshal.GetLastWin32Error();
                        if (lastErr != Win32.ERROR_IO_PENDING)
                        {
                            throw new IOException("WriteFile failed for " + lastErr);
                        }

                        success = Win32Serial.GetOverlappedResult(
                            _fileHandle,
                            writeOverlappedPinned.AddrOfPinnedObject(),
                            transferredLengthPinned.AddrOfPinnedObject(),
                            true);
                        if (!success)
                        {
                            lastErr = Marshal.GetLastWin32Error();
                            throw new Exception("GetOverlappedResult failed " + lastErr);
                        }
                        wroteLength = (int)transferredLengthPinned.Target;  // copy from pinned `boxed' Int32
                    }
                    else
                    {
                        wroteLength = (int)wroteLengthPinned.Target;    // copy from pinned `boxed' Int32
                    }
                }
                finally {
                    wroteLengthPinned.Free();
                    transferredLengthPinned.Free();
                    writeOverlappedPinned.Free();
                    bufToWritePinned.Free();
                }

                offset += wroteLength;
                length -= wroteLength;
            }
        }
Exemple #6
0
        private void AsyncEntry()
        {
            const int EV_RXCHAR = 1;

            ManualResetEvent commEventOverlappedEvent = null;
            ManualResetEvent readOverlappedEvent      = null;

            try {
                commEventOverlappedEvent = new ManualResetEvent(false);
                readOverlappedEvent      = new ManualResetEvent(false);

                NativeOverlapped commEventOverlapped = new NativeOverlapped();
                commEventOverlapped.EventHandle = commEventOverlappedEvent.SafeWaitHandle.DangerousGetHandle();

                NativeOverlapped readOverlapped = new NativeOverlapped();
                readOverlapped.EventHandle = readOverlappedEvent.SafeWaitHandle.DangerousGetHandle();

                GCHandle commEventOverlappedPinned = GCHandle.Alloc(commEventOverlapped, GCHandleType.Pinned); // Pin a boxed NativeOverlapped
                GCHandle readOverlappedPinned      = GCHandle.Alloc(readOverlapped, GCHandleType.Pinned);      // Pin a boxed NativeOverlapped
                int      commFlags               = 0;
                GCHandle commFlagsPinned         = GCHandle.Alloc(commFlags, GCHandleType.Pinned);             // Pin a boxed Int32
                int      readLength              = 0;
                GCHandle readLengthPinned        = GCHandle.Alloc(readLength, GCHandleType.Pinned);            // Pin a boxed Int32
                int      transferredLength       = 0;
                GCHandle transferredLengthPinned = GCHandle.Alloc(transferredLength, GCHandleType.Pinned);     // Pin a boxed Int32

                byte[]   buf       = new byte[128];
                GCHandle bufPinned = GCHandle.Alloc(buf, GCHandleType.Pinned);

                // Note:
                //  GCHandle.Alloc(<struct>, GCHandleType.Pinned) makes a GCHandle for `Boxed' struct object.
                //  So if you want to read a value of the struct, you have to read it from `Boxed' struct object
                //  which is returned by GCHandle.Target.

                try {
                    bool success = false;

                    success = Win32Serial.ClearCommError(_fileHandle, IntPtr.Zero, IntPtr.Zero);
                    if (!success)
                    {
                        throw new Exception("ClearCommError failed " + Marshal.GetLastWin32Error());
                    }
                    //このSetCommMaskを実行しないとWaitCommEventが失敗してしまう
                    success = Win32Serial.SetCommMask(_fileHandle, 0);
                    if (!success)
                    {
                        throw new Exception("SetCommMask failed " + Marshal.GetLastWin32Error());
                    }
                    success = Win32Serial.SetCommMask(_fileHandle, EV_RXCHAR);
                    if (!success)
                    {
                        throw new Exception("SetCommMask failed " + Marshal.GetLastWin32Error());
                    }

                    while (true)
                    {
                        commFlags = 0;
                        commFlagsPinned.Target           = commFlags;           // Pin a new boxed Int32
                        transferredLength                = 0;
                        transferredLengthPinned.Target   = transferredLength;   // Pin a new boxed Int32
                        commEventOverlappedPinned.Target = commEventOverlapped; // Pin a new boxed NativeOverlapped

                        success = Win32Serial.WaitCommEvent(
                            _fileHandle,
                            commFlagsPinned.AddrOfPinnedObject(),
                            commEventOverlappedPinned.AddrOfPinnedObject());
                        if (!success)
                        {
                            int lastErr = Marshal.GetLastWin32Error();
                            if (lastErr == Win32.ERROR_INVALID_HANDLE)
                            {
                                goto CLOSED;  // closed in another thread ?
                            }
                            if (lastErr != Win32.ERROR_IO_PENDING)
                            {
                                throw new Exception("WaitCommEvent failed " + lastErr);
                            }

                            success = Win32Serial.GetOverlappedResult(
                                _fileHandle,
                                commEventOverlappedPinned.AddrOfPinnedObject(),
                                transferredLengthPinned.AddrOfPinnedObject(),
                                true);
                            if (!success)
                            {
                                lastErr = Marshal.GetLastWin32Error();
                                if (lastErr == Win32.ERROR_INVALID_HANDLE || lastErr == Win32.ERROR_OPERATION_ABORTED)
                                {
                                    goto CLOSED;  // closed in another thread ?
                                }
                                throw new Exception("GetOverlappedResult failed " + lastErr);
                            }
                        }

                        if ((int)commFlagsPinned.Target != EV_RXCHAR)
                        {
                            goto CLOSED;
                        }

                        while (true)
                        {
                            readLength = 0;
                            readLengthPinned.Target        = readLength;        // Pin a new boxed Int32
                            transferredLength              = 0;
                            transferredLengthPinned.Target = transferredLength; // Pin a new boxed Int32
                            readOverlappedPinned.Target    = readOverlapped;    // Pin a new boxed NativeOverlapped

                            success = Win32Serial.ReadFile(
                                _fileHandle,
                                bufPinned.AddrOfPinnedObject(),
                                buf.Length,
                                readLengthPinned.AddrOfPinnedObject(),
                                readOverlappedPinned.AddrOfPinnedObject());
                            if (!success)
                            {
                                int lastErr = Marshal.GetLastWin32Error();
                                if (lastErr == Win32.ERROR_INVALID_HANDLE)
                                {
                                    goto CLOSED;  // closed in another thread ?
                                }
                                if (lastErr != Win32.ERROR_IO_PENDING)
                                {
                                    throw new Exception("ReadFile failed " + lastErr);
                                }

                                success = Win32Serial.GetOverlappedResult(
                                    _fileHandle,
                                    readOverlappedPinned.AddrOfPinnedObject(),
                                    transferredLengthPinned.AddrOfPinnedObject(),
                                    true);
                                if (!success)
                                {
                                    lastErr = Marshal.GetLastWin32Error();
                                    if (lastErr == Win32.ERROR_INVALID_HANDLE || lastErr == Win32.ERROR_OPERATION_ABORTED)
                                    {
                                        goto CLOSED;  // closed in another thread ?
                                    }
                                    throw new Exception("GetOverlappedResult failed " + lastErr);
                                }
                                readLength = (int)transferredLengthPinned.Target;   // copy from pinned `boxed' Int32
                            }
                            else
                            {
                                readLength = (int)readLengthPinned.Target;  // copy from pinned `boxed' Int32
                            }

                            if (readLength <= 0)
                            {
                                break;
                            }

                            _dataFragment.Set(buf, 0, readLength);
                            _callback.OnReception(_dataFragment);
                        }
                    }
                }
                finally {
                    commEventOverlappedPinned.Free();
                    readOverlappedPinned.Free();
                    commFlagsPinned.Free();
                    readLengthPinned.Free();
                    transferredLengthPinned.Free();
                    bufPinned.Free();
                }

CLOSED:
                ;
            }
            catch (Exception ex) {
                if (!_parent.IsClosed)
                {
                    _callback.OnAbnormalTermination(ex.Message);
                }
            }
            finally {
                if (commEventOverlappedEvent != null)
                {
                    commEventOverlappedEvent.Close();
                }
                if (readOverlappedEvent != null)
                {
                    readOverlappedEvent.Close();
                }
            }
        }
Exemple #7
0
 public void SendBreak()
 {
     Win32Serial.SetCommBreak(_fileHandle);
     System.Threading.Thread.Sleep(500); //500ms待機
     Win32Serial.ClearCommBreak(_fileHandle);
 }
Exemple #8
0
 public static void UpdateDCB(ref Win32Serial.DCB dcb, SerialTerminalSettings param)
 {
     dcb.BaudRate = (uint)param.BaudRate;
     dcb.ByteSize = param.ByteSize;
     dcb.Parity = (byte)param.Parity;
     dcb.StopBits = (byte)param.StopBits;
     //フロー制御:TeraTermのソースからちょっぱってきた
     if (param.FlowControl == FlowControl.Xon_Xoff) {
         //dcb.fOutX = TRUE;
         //dcb.fInX = TRUE;
         //dcbを完全にコントロールするオプションが必要かもな
         dcb.Misc |= 0x300; //上記2行のかわり
         dcb.XonLim = 2048; //CommXonLim;
         dcb.XoffLim = 2048; //CommXoffLim;
         dcb.XonChar = 0x11;
         dcb.XoffChar = 0x13;
     }
     else if (param.FlowControl == FlowControl.Hardware) {
         //dcb.fOutxCtsFlow = TRUE;
         //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
         dcb.Misc |= 0x4 | 0x2000;
     }
 }
Exemple #9
0
 public static bool FillDCB(IntPtr handle, ref Win32Serial.DCB dcb)
 {
     dcb.DCBlength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32Serial.DCB)); //sizeofくらいunsafeでなくても使わせてくれよ
     return Win32Serial.GetCommState(handle, ref dcb);
 }
Exemple #10
0
 public static void UpdateDCB(ref Win32Serial.DCB dcb, SerialTerminalSettings param)
 {
     dcb.BaudRate = (uint)param.BaudRate;
     dcb.ByteSize = param.ByteSize;
     dcb.Parity = (byte)param.Parity;
     dcb.StopBits = (byte)param.StopBits;
     //�t���[����FTeraTerm�̃\�[�X���炿����ς��Ă���
     if (param.FlowControl == FlowControl.Xon_Xoff) {
         //dcb.fOutX = TRUE;
         //dcb.fInX = TRUE;
         //dcb����S�ɃR���g���[������I�v�V�������K�v�����
         dcb.Misc |= 0x300; //��L�Q�s�̂����
         dcb.XonLim = 2048; //CommXonLim;
         dcb.XoffLim = 2048; //CommXoffLim;
         dcb.XonChar = 0x11;
         dcb.XoffChar = 0x13;
     }
     else if (param.FlowControl == FlowControl.Hardware) {
         //dcb.fOutxCtsFlow = TRUE;
         //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
         dcb.Misc |= 0x4 | 0x2000;
     }
 }