Merge pull request #498 from Unroll-Me/master
[mono.git] / mcs / class / System / System.IO.Ports / WinSerialStream.cs
index c517b289aecfb7da4cd801d80b35fd554791b756..fc0d45dbd20adb9314b7128203680ccf64373f88 100644 (file)
@@ -14,8 +14,6 @@ using System.Runtime.InteropServices;
 using System.Threading;
 using System.ComponentModel;
 
-#if NET_2_0
-
 namespace System.IO.Ports
 {
        class WinSerialStream : Stream, ISerialStream, IDisposable
@@ -25,8 +23,8 @@ namespace System.IO.Ports
                const uint GenericWrite = 0x40000000;
                const uint OpenExisting = 3;
                const uint FileFlagOverlapped = 0x40000000;
-               const uint PurgeRxClear = 0x0004;
-               const uint PurgeTxClear = 0x0008;
+               const uint PurgeRxClear = 0x0008;
+               const uint PurgeTxClear = 0x0004;
                const uint WinInfiniteTimeout = 0xFFFFFFFF;
                const uint FileIOPending = 997;
 
@@ -74,11 +72,13 @@ namespace System.IO.Ports
                [DllImport("kernel32", SetLastError = true)]
                static extern bool SetCommTimeouts(int handle, Timeouts timeouts);
 
-               public WinSerialStream (string port_name, int baud_rate, int data_bits, Parity parity,
-                               StopBits sb, Handshake hs, int read_timeout, int write_timeout,
+               public WinSerialStream (string port_name, int baud_rate, int data_bits, Parity parity, StopBits sb,
+                               bool dtr_enable, bool rts_enable, Handshake hs, int read_timeout, int write_timeout,
                                int read_buffer_size, int write_buffer_size)
                {
-                       handle = CreateFile (port_name, GenericRead | GenericWrite, 0, 0, OpenExisting,
+                       handle = CreateFile (port_name != null && !port_name.StartsWith(@"\\.\")
+                                       ? @"\\.\" + port_name : port_name,
+                                       GenericRead | GenericWrite, 0, 0, OpenExisting,
                                        FileFlagOverlapped, 0);
 
                        if (handle == -1)
@@ -99,16 +99,23 @@ namespace System.IO.Ports
                        if (!SetCommTimeouts(handle, timeouts))
                                ReportIOError (null);
 
+                       /// Set DTR and RTS
+                       SetSignal(SerialSignal.Dtr, dtr_enable);
+
+                       if (hs != Handshake.RequestToSend &&
+                                       hs != Handshake.RequestToSendXOnXOff)
+                               SetSignal(SerialSignal.Rts, rts_enable);
+
                        // Init overlapped structures
                        NativeOverlapped wo = new NativeOverlapped ();
                        write_event = new ManualResetEvent (false);
-                       wo.EventHandle = (int) write_event.Handle;
+                       wo.EventHandle = write_event.Handle;
                        write_overlapped = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (NativeOverlapped)));
                        Marshal.StructureToPtr (wo, write_overlapped, true);
 
                        NativeOverlapped ro = new NativeOverlapped ();
                        read_event = new ManualResetEvent (false);
-                       ro.EventHandle = (int) read_event.Handle;
+                       ro.EventHandle = read_event.Handle;
                        read_overlapped = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (NativeOverlapped)));
                        Marshal.StructureToPtr (ro, read_overlapped, true);
                }
@@ -368,17 +375,18 @@ namespace System.IO.Ports
 
                public void DiscardOutBuffer ()
                {
-                       if (!PurgeComm (handle, PurgeRxClear))
+                       if (!PurgeComm (handle, PurgeTxClear))
                                ReportIOError (null);
                }
 
                [DllImport ("kernel32", SetLastError=true)]
-               static extern bool ClearCommError (int handle, out CommStat stat);
+               static extern bool ClearCommError (int handle, out uint errors, out CommStat stat);
 
                public int BytesToRead {
                        get {
+                               uint errors;
                                CommStat stat;
-                               if (!ClearCommError (handle, out stat))
+                               if (!ClearCommError (handle, out errors, out stat))
                                        ReportIOError (null);
 
                                return (int)stat.BytesIn;
@@ -387,8 +395,9 @@ namespace System.IO.Ports
 
                public int BytesToWrite {
                        get {
+                               uint errors;
                                CommStat stat;
-                               if (!ClearCommError (handle, out stat))
+                               if (!ClearCommError (handle, out errors, out stat))
                                        ReportIOError (null);
 
                                return (int)stat.BytesOut;
@@ -420,7 +429,7 @@ namespace System.IO.Ports
 
                public void SetSignal (SerialSignal signal, bool value)
                {
-                       if (signal != SerialSignal.Rts || signal != SerialSignal.Dtr)
+                       if (signal != SerialSignal.Rts && signal != SerialSignal.Dtr)
                                throw new Exception ("Wrong internal value");
 
                        uint flag;
@@ -429,7 +438,7 @@ namespace System.IO.Ports
                                        flag = SetRts;
                                else
                                        flag = ClearRts;
-                       else 
+                       else
                                if (value)
                                        flag = SetDtr;
                                else
@@ -466,6 +475,23 @@ namespace System.IO.Ports
                public byte evt_char;
                public short w_reserved1;
 
+               // flags:
+               //const int fBinary = 0x0001;
+               //const int fParity = 0x0002;
+               const int fOutxCtsFlow = 0x0004;
+               //const int fOutxDsrFlow1 = 0x0008;
+               //const int fOutxDsrFlow2 = 0x0010;
+               //const int fDtrControl = 0x00020;
+               //const int fDsrSensitivity = 0x0040;
+               //const int fTXContinueOnXoff = 0x0080;
+               const int fOutX = 0x0100;
+               const int fInX = 0x0200;
+               //const int fErrorChar = 0x0400;
+               //const int fNull = 0x0800;
+               //const int fRtsControl1 = 0x1000;
+               const int fRtsControl2 = 0x2000;
+               //const int fAbortOnError = 0x4000;
+
                public void SetValues (int baud_rate, Parity parity, int byte_size, StopBits sb, Handshake hs)
                {
                        switch (sb) {
@@ -483,10 +509,30 @@ namespace System.IO.Ports
                        }
 
                        this.baud_rate = baud_rate;
-                       this.parity = (byte) parity;
-                       this.byte_size = (byte) byte_size;
-               }
+                       this.parity = (byte)parity;
+                       this.byte_size = (byte)byte_size;
+
+                       // Clear Handshake flags
+                       flags &= ~(fOutxCtsFlow | fOutX | fInX | fRtsControl2);
 
+                       // Set Handshake flags
+                       switch (hs)
+                       {
+                               case Handshake.None:
+                                       break;
+                               case Handshake.XOnXOff:
+                                       flags |= fOutX | fInX;
+                                       break;
+                               case Handshake.RequestToSend:
+                                       flags |= fOutxCtsFlow | fRtsControl2;
+                                       break;
+                               case Handshake.RequestToSendXOnXOff:
+                                       flags |= fOutxCtsFlow | fOutX | fInX | fRtsControl2;
+                                       break;
+                               default: // Shouldn't happen
+                                       break;
+                       }
+               }
        }
        
        [StructLayout (LayoutKind.Sequential)]
@@ -520,7 +566,7 @@ namespace System.IO.Ports
        }
 
        [StructLayout (LayoutKind.Sequential)]
-       class CommStat
+       struct CommStat
        {
                public uint flags;
                public uint BytesIn;
@@ -528,5 +574,4 @@ namespace System.IO.Ports
        }
 }
 
-#endif