Eric Pouech : ntdll/kernel32: SetCommState & IOCTL_SET_CHARS

Alexandre Julliard julliard at wine.codeweavers.com
Tue May 9 14:15:45 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: a05a3435fdf425c2bafe3559b5b9427801f7d7a2
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=a05a3435fdf425c2bafe3559b5b9427801f7d7a2

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Sun May  7 14:10:43 2006 +0200

ntdll/kernel32: SetCommState & IOCTL_SET_CHARS

- implemented ntdll's serial IOCTL SET_CHARS
- used this IOCTL in kernel32.SetCommState

---

 dlls/kernel/comm.c  |   55 +++++++++++++++------------------------------------
 dlls/ntdll/serial.c |   34 ++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c
index 58e1b13..c6ac9f7 100644
--- a/dlls/kernel/comm.c
+++ b/dlls/kernel/comm.c
@@ -983,13 +983,10 @@ static void dump_dcb(const DCB* lpdcb)
  */
 BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb)
 {
-     struct termios port;
-     int fd;
-     BOOL ret;
-
     SERIAL_BAUD_RATE           sbr;
     SERIAL_LINE_CONTROL        slc;
     SERIAL_HANDFLOW            shf;
+    SERIAL_CHARS               sc;
 
     if (lpdcb == NULL)
     {
@@ -1040,44 +1037,24 @@ BOOL WINAPI SetCommState( HANDLE handle,
     shf.XonLimit = lpdcb->XonLim;
     shf.XoffLimit = lpdcb->XoffLim;
 
+    sc.EofChar = lpdcb->EofChar;
+    sc.ErrorChar = lpdcb->ErrorChar;
+    sc.BreakChar = 0;
+    sc.EventChar = lpdcb->EvtChar;
+    sc.XonChar = lpdcb->XonChar;
+    sc.XoffChar = lpdcb->XoffChar;
+
     /* note: change DTR/RTS lines after setting the comm attributes,
      * so flow control does not interfere.
      */
-    if (!DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE,
-                         &sbr, sizeof(sbr), NULL, 0, NULL, NULL))
-        return FALSE;
-    if (!DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL,
-                         &slc, sizeof(slc), NULL, 0, NULL, NULL))
-        return FALSE;
-
-    if (!DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW,
-                         &shf, sizeof(shf), NULL, 0, NULL, NULL))
-        return FALSE;
-
-     fd = get_comm_fd( handle, FILE_READ_DATA );
-     if (fd < 0) return FALSE;
-
-     if ((tcgetattr(fd,&port)) == -1) {
-         int save_error = errno;
-         release_comm_fd( handle, fd );
-         ERR("tcgetattr error '%s'\n", strerror(save_error));
-         return FALSE;
-     }
-
-	port.c_cc[VMIN] = 0;
-	port.c_cc[VTIME] = 1;
-
-	if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
-                ERR("tcsetattr error '%s'\n", strerror(errno));
-		ret = FALSE;
-	} else {
-                ClearCommError(handle, NULL, NULL);
-		ret = TRUE;
-	}
-
-        release_comm_fd( handle, fd );
-        return ret;
-
+    return (DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE,
+                            &sbr, sizeof(sbr), NULL, 0, NULL, NULL) &&
+            DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL,
+                            &slc, sizeof(slc), NULL, 0, NULL, NULL) &&
+            DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW,
+                            &shf, sizeof(shf), NULL, 0, NULL, NULL) &&
+            DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS,
+                            &sc, sizeof(sc), NULL, 0, NULL, NULL));
 }
 
 
diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c
index 0225ba8..351b7e4 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -540,6 +540,34 @@ #endif
     return STATUS_SUCCESS;
 }
 
+static NTSTATUS set_special_chars(int fd, const SERIAL_CHARS* sc)
+{
+    struct termios port;
+    
+    if (tcgetattr(fd, &port) == -1)
+    {
+        ERR("tcgetattr error '%s'\n", strerror(errno));
+        return FILE_GetNtStatus();
+    }
+    
+    port.c_cc[VMIN  ] = 0;
+    port.c_cc[VTIME ] = 1;
+    
+    port.c_cc[VEOF  ] = sc->EofChar;
+    /* FIXME: sc->ErrorChar is not supported */
+    /* FIXME: sc->BreakChar is not supported */
+    /* FIXME: sc->EventChar is not supported */
+    port.c_cc[VSTART] = sc->XonChar;
+    port.c_cc[VSTOP ] = sc->XoffChar;
+    
+    if (tcsetattr(fd, TCSANOW, &port) == -1)
+    {
+        ERR("tcsetattr error '%s'\n", strerror(errno));
+        return FILE_GetNtStatus();
+    }
+    return STATUS_SUCCESS;
+}
+
 static NTSTATUS set_wait_mask(HANDLE hDevice, DWORD mask)
 {
     NTSTATUS status;
@@ -658,6 +686,12 @@ #else
 	status = STATUS_NOT_SUPPORTED;
 #endif
         break;
+    case IOCTL_SERIAL_SET_CHARS:
+        if (lpInBuffer && nInBufferSize == sizeof(SERIAL_CHARS))
+            status = set_special_chars(fd, (const SERIAL_CHARS*)lpInBuffer);
+        else
+            status = STATUS_INVALID_PARAMETER;
+        break;
     case IOCTL_SERIAL_SET_HANDFLOW:
         if (lpInBuffer && nInBufferSize == sizeof(SERIAL_HANDFLOW))
             status = set_handflow(fd, (const SERIAL_HANDFLOW*)lpInBuffer);




More information about the wine-cvs mailing list