Eric Pouech : ntdll/kernel32: GetCommState & IOCTL_GET_BAUD_RATE

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


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

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

ntdll/kernel32: GetCommState & IOCTL_GET_BAUD_RATE

- implemented SERIAL_GET_BAUD_RATE ioctl
- made use of it in kernel.GetCommState

---

 dlls/kernel/comm.c  |  133 ++++++++++-----------------------------------------
 dlls/ntdll/serial.c |   67 +++++++++++++++++++++++++-
 2 files changed, 93 insertions(+), 107 deletions(-)

diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c
index c6ac9f7..8fd765b 100644
--- a/dlls/kernel/comm.c
+++ b/dlls/kernel/comm.c
@@ -1063,6 +1063,10 @@ BOOL WINAPI SetCommState( HANDLE handle,
  *
  *  Fills in a device control block with information from a communications device.
  *
+ * PARAMS
+ *      handle          [in]    The communications device
+ *      lpdcb           [out]   The device control block
+ *
  * RETURNS
  *
  *  True on success, false if the communication device handle is bad etc
@@ -1071,16 +1075,31 @@ BOOL WINAPI SetCommState( HANDLE handle,
  *
  *  XonChar and XoffChar are not set.
  */
-BOOL WINAPI GetCommState(
-    HANDLE handle, /* [in] The communications device. */
-    LPDCB  lpdcb)  /* [out] The device control block. */
+BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
 {
      struct termios port;
-     int fd,speed;
+     int fd;
      int stat = DTR_CONTROL_ENABLE | RTS_CONTROL_ENABLE;
 
-     TRACE("handle %p, ptr %p\n", handle, lpdcb);
+    SERIAL_BAUD_RATE    sbr;
+
+    TRACE("handle %p, ptr %p\n", handle, lpdcb);
+
+    if (!lpdcb)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    lpdcb->DCBlength = sizeof(*lpdcb);
+    
+    if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE,
+                         NULL, 0, &sbr, sizeof(sbr), NULL, NULL))
+        return FALSE;
+    /* yes, they seem no never be (re)set on NT */
+    lpdcb->fBinary = 1;
+    lpdcb->fParity = 0;
 
+    lpdcb->BaudRate = sbr.BaudRate;
      fd = get_comm_fd( handle, FILE_READ_DATA );
      if (fd < 0) return FALSE;
      if (tcgetattr(fd, &port) == -1) {
@@ -1099,85 +1118,6 @@ #ifdef TIOCMGET
      }
 #endif
      release_comm_fd( handle, fd );
-#ifndef __EMX__
-#ifdef CBAUD
-     speed= (port.c_cflag & CBAUD);
-#else
-     speed= (cfgetospeed(&port));
-#endif
-     switch (speed) {
-		case B0:
-			lpdcb->BaudRate = 0;
-			break;
-		case B50:
-			lpdcb->BaudRate = 50;
-			break;
-		case B75:
-			lpdcb->BaudRate = 75;
-			break;
-		case B110:
-			lpdcb->BaudRate = 110;
-			break;
-		case B134:
-			lpdcb->BaudRate = 134;
-			break;
-		case B150:
-			lpdcb->BaudRate = 150;
-			break;
-		case B200:
-			lpdcb->BaudRate = 200;
-			break;
-		case B300:
-			lpdcb->BaudRate = 300;
-			break;
-		case B600:
-			lpdcb->BaudRate = 600;
-			break;
-		case B1200:
-			lpdcb->BaudRate = 1200;
-			break;
-		case B1800:
-			lpdcb->BaudRate = 1800;
-			break;
-		case B2400:
-			lpdcb->BaudRate = 2400;
-			break;
-		case B4800:
-			lpdcb->BaudRate = 4800;
-			break;
-		case B9600:
-			lpdcb->BaudRate = 9600;
-			break;
-		case B19200:
-			lpdcb->BaudRate = 19200;
-			break;
-		case B38400:
-			lpdcb->BaudRate = 38400;
-			break;
-#ifdef B57600
-		case B57600:
-			lpdcb->BaudRate = 57600;
-			break;
-#endif
-#ifdef B115200
-		case B115200:
-			lpdcb->BaudRate = 115200;
-			break;
-#endif
-#ifdef B230400
-                case B230400:
-			lpdcb->BaudRate = 230400;
-			break;
-#endif
-#ifdef B460800
-                case B460800:
-			lpdcb->BaudRate = 460800;
-			break;
-#endif
-	        default:
-		        ERR("unknown speed %x\n", speed);
-	}
-#endif
 	switch (port.c_cflag & CSIZE) {
 		case CS5:
 			lpdcb->ByteSize = 5;
@@ -1233,7 +1173,6 @@ #endif
             lpdcb->StopBits = ONESTOPBIT;
 
 	lpdcb->fNull = 0;
-	lpdcb->fBinary = 1;
 
 	/* termios does not support DTR/DSR flow control */
 	lpdcb->fOutxDsrFlow = 0;
@@ -1274,28 +1213,10 @@ #endif
 	lpdcb->XonLim = 10;
 	lpdcb->XoffLim = 10;
 
-        TRACE("OK\n");
-
-	TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
-	      lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
-	      (lpdcb->StopBits == ONESTOPBIT)?1:
-	      (lpdcb->StopBits == TWOSTOPBITS)?2:0);
-	TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
-	      (lpdcb->fOutX)?"IXOFF":"~IXOFF");
-         TRACE("fOutxCtsFlow %d fRtsControl %d\n", lpdcb->fOutxCtsFlow,
-                 lpdcb->fRtsControl);
-         TRACE("fOutxDsrFlow %d fDtrControl%d\n", lpdcb->fOutxDsrFlow,
-                 lpdcb->fDtrControl);
-#ifdef CRTSCTS
-	if (	lpdcb->fOutxCtsFlow 			||
-		lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
-		)
-	  TRACE("CRTSCTS\n");
-        else
+    TRACE("OK\n");
+    dump_dcb(lpdcb);
 
-	  TRACE("~CRTSCTS\n");
-#endif
-	return TRUE;
+    return TRUE;
 }
 
 /*****************************************************************************
diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c
index 351b7e4..c86dc66 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -129,6 +129,62 @@ #undef X
     }
 }
 
+static NTSTATUS get_baud_rate(int fd, SERIAL_BAUD_RATE* sbr)
+{
+    struct termios port;
+    int speed;
+    
+    if (tcgetattr(fd, &port) == -1)
+    {
+        ERR("tcgetattr error '%s'\n", strerror(errno));
+        return FILE_GetNtStatus();
+    }
+#ifndef __EMX__
+#ifdef CBAUD
+    speed = port.c_cflag & CBAUD;
+#else
+    speed = cfgetospeed(&port);
+#endif
+    switch (speed)
+    {
+    case B0:            sbr->BaudRate = 0;      break;
+    case B50:           sbr->BaudRate = 50;	break;
+    case B75:		sbr->BaudRate = 75;	break;
+    case B110:		sbr->BaudRate = 110;	break;
+    case B134:		sbr->BaudRate = 134;	break;
+    case B150:		sbr->BaudRate = 150;	break;
+    case B200:		sbr->BaudRate = 200;	break;
+    case B300:		sbr->BaudRate = 300;	break;
+    case B600:		sbr->BaudRate = 600;	break;
+    case B1200:		sbr->BaudRate = 1200;	break;
+    case B1800:		sbr->BaudRate = 1800;	break;
+    case B2400:		sbr->BaudRate = 2400;	break;
+    case B4800:		sbr->BaudRate = 4800;	break;
+    case B9600:		sbr->BaudRate = 9600;	break;
+    case B19200:	sbr->BaudRate = 19200;	break;
+    case B38400:	sbr->BaudRate = 38400;	break;
+#ifdef B57600
+    case B57600:	sbr->BaudRate = 57600;	break;
+#endif
+#ifdef B115200
+    case B115200:	sbr->BaudRate = 115200;	break;
+#endif
+#ifdef B230400
+    case B230400:	sbr->BaudRate = 230400;	break;
+#endif
+#ifdef B460800
+    case B460800:	sbr->BaudRate = 460800;	break;
+#endif
+    default:
+        ERR("unknown speed %x\n", speed);
+        return STATUS_INVALID_PARAMETER;
+    }
+#else
+    return STATUS_INVALID_PARAMETER;
+#endif
+    return STATUS_SUCCESS;
+}
+
 static NTSTATUS get_modem_status(int fd, DWORD* lpModemStat)
 {
     NTSTATUS    status = STATUS_SUCCESS;
@@ -619,7 +675,16 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDe
 
     switch (dwIoControlCode)
     {
-    case IOCTL_SERIAL_GET_COMMSTATUS:
+    case IOCTL_SERIAL_GET_BAUD_RATE:
+        if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_BAUD_RATE))
+        {
+            if (!(status = get_baud_rate(fd, (SERIAL_BAUD_RATE*)lpOutBuffer)))
+                sz = sizeof(SERIAL_BAUD_RATE);
+        }
+        else
+            status = STATUS_INVALID_PARAMETER;
+        break;
+     case IOCTL_SERIAL_GET_COMMSTATUS:
         if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_STATUS))
         {
             if (!(status = get_status(fd, (SERIAL_STATUS*)lpOutBuffer)))




More information about the wine-cvs mailing list