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")); } }
public void Close() { if (_writeOverlappedEvent != null) { if (_commEventOverlappedPinned.IsAllocated) { Win32Serial.CancelIoEx(_fileHandle, _commEventOverlappedPinned.AddrOfPinnedObject()); _commEventOverlappedPinned.Free(); } _writeOverlappedEvent.Close(); _writeOverlappedEvent = null; } }
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)); }
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(); } } }
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; } }
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(); } } }
public void SendBreak() { Win32Serial.SetCommBreak(_fileHandle); System.Threading.Thread.Sleep(500); //500ms待機 Win32Serial.ClearCommBreak(_fileHandle); }
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; } }
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); }
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; } }