From 654fcc721b47525d58c93a628d462fb1273cad73 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mike_mccormack@looksmart.com.au>
Date: Sat, 16 Sep 2000 20:55:12 +0000
Subject: [PATCH] Implemented SetCommMask, SetCommTimeouts, GetCommMask,
 GetCommTimeouts.

---
 include/server.h |  36 +++++++++++++-
 misc/comm.c      | 126 +++++++++++++++++++++++++++--------------------
 server/request.h |   4 ++
 server/serial.c  |  55 +++++++++++++++++++++
 server/trace.c   |  35 +++++++++++++
 5 files changed, 202 insertions(+), 54 deletions(-)

diff --git a/include/server.h b/include/server.h
index cefb21b5310..d79c50407dc 100644
--- a/include/server.h
+++ b/include/server.h
@@ -1322,6 +1322,36 @@ struct create_serial_request
     IN  char         name[1];      /* file name */
 };
 
+struct get_serial_info_request
+{
+    REQUEST_HEADER;                /* request header */
+    IN  int          handle;       /* handle to comm port */
+    OUT unsigned int readinterval;
+    OUT unsigned int readconst;
+    OUT unsigned int readmult;
+    OUT unsigned int writeconst;
+    OUT unsigned int writemult;
+    OUT unsigned int eventmask;
+    OUT unsigned int commerror;
+};
+
+struct set_serial_info_request
+{
+    REQUEST_HEADER;                /* request header */
+    IN  int          handle;       /* handle to comm port */
+    IN  int          flags;        /* bitmask to set values (see below) */
+    IN  unsigned int readinterval;
+    IN  unsigned int readconst;
+    IN  unsigned int readmult;
+    IN  unsigned int writeconst;
+    IN  unsigned int writemult;
+    IN  unsigned int eventmask;
+    IN  unsigned int commerror;
+};
+#define SERIALINFO_SET_TIMEOUTS  0x01
+#define SERIALINFO_SET_MASK      0x02
+#define SERIALINFO_SET_ERROR     0x04
+
 /* Everything below this line is generated automatically by tools/make_requests */
 /* ### make_requests begin ### */
 
@@ -1435,6 +1465,8 @@ enum request
     REQ_WAKE_QUEUE,
     REQ_WAIT_INPUT_IDLE,
     REQ_CREATE_SERIAL,
+    REQ_GET_SERIAL_INFO,
+    REQ_SET_SERIAL_INFO,
     REQ_NB_REQUESTS
 };
 
@@ -1550,9 +1582,11 @@ union generic_request
     struct wake_queue_request wake_queue;
     struct wait_input_idle_request wait_input_idle;
     struct create_serial_request create_serial;
+    struct get_serial_info_request get_serial_info;
+    struct set_serial_info_request set_serial_info;
 };
 
-#define SERVER_PROTOCOL_VERSION 21
+#define SERVER_PROTOCOL_VERSION 22
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
diff --git a/misc/comm.c b/misc/comm.c
index 35b4ea7bdbd..69a7111a1db 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1906,26 +1906,17 @@ BOOL WINAPI SetupComm( HANDLE handle, DWORD insize, DWORD outsize)
  */
 BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask)
 {
-    int fd;
+    struct get_serial_info_request *req = get_req_buffer();
 
     TRACE("handle %d, mask %p\n", handle, evtmask);
-    if(0>(fd=COMM_GetReadFd(handle))) 
-    {
-	FIXME("no handle %d found\n",handle);
+
+    req->handle = handle;
+
+    if(server_call( REQ_GET_SERIAL_INFO ))
         return FALSE;
-    }
-    close(fd);
-    *evtmask = eventmask;
-    TRACE("%s%s%s%s%s%s%s%s%s\n",
-	  (eventmask&EV_BREAK)?"EV_BREAK":"",
-	  (eventmask&EV_CTS)?"EV_CTS":"",
-	  (eventmask&EV_DSR)?"EV_DSR":"",
-	  (eventmask&EV_ERR)?"EV_ERR":"",
-	  (eventmask&EV_RING)?"EV_RING":"",
-	  (eventmask&EV_RLSD)?"EV_RLSD":"",
-	  (eventmask&EV_RXCHAR)?"EV_RXCHAR":"",
-	  (eventmask&EV_RXFLAG)?"EV_RXFLAG":"",
-	  (eventmask&EV_TXEMPTY)?"EV_TXEMPTY":"");
+
+    if(evtmask)
+        *evtmask = req->eventmask;
 	  
     return TRUE;
 }
@@ -1935,26 +1926,17 @@ BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask)
  */
 BOOL WINAPI SetCommMask(HANDLE handle,DWORD evtmask)
 {
-    int fd;
+    struct set_serial_info_request *req = get_req_buffer();
 
     TRACE("handle %d, mask %lx\n", handle, evtmask);
-    TRACE("%s%s%s%s%s%s%s%s%s\n",
-	  (evtmask&EV_BREAK)?"EV_BREAK":"",
-	  (evtmask&EV_CTS)?"EV_CTS":"",
-	  (evtmask&EV_DSR)?"EV_DSR":"",
-	  (evtmask&EV_ERR)?"EV_ERR":"",
-	  (evtmask&EV_RING)?"EV_RING":"",
-	  (evtmask&EV_RLSD)?"EV_RLSD":"",
-	  (evtmask&EV_RXCHAR)?"EV_RXCHAR":"",
-	  (evtmask&EV_RXFLAG)?"EV_RXFLAG":"",
-	  (evtmask&EV_TXEMPTY)?"EV_TXEMPTY":"");
 	  
-    if(0>(fd=COMM_GetWriteFd(handle))) {
-	FIXME("no handle %d found\n",handle);
+    req->handle    = handle;
+    req->flags     = SERIALINFO_SET_MASK;
+    req->eventmask = evtmask;
+
+    if(server_call( REQ_SET_SERIAL_INFO ))
         return FALSE;
-    }
-    close(fd);
-    eventmask = evtmask;
+
     return TRUE;
 }
 
@@ -2461,41 +2443,78 @@ BOOL WINAPI TransmitCommChar(HANDLE hComm,CHAR chTransmit)
 /*****************************************************************************
  *	GetCommTimeouts		(KERNEL32.160)
  */
-BOOL WINAPI GetCommTimeouts(HANDLE hcom,LPCOMMTIMEOUTS lptimeouts)
+BOOL WINAPI GetCommTimeouts(HANDLE hComm,LPCOMMTIMEOUTS lptimeouts)
 {
-	FIXME("(%x,%p):stub.\n",hcom,lptimeouts);
+    struct get_serial_info_request *req = get_req_buffer();
+
+    TRACE("(%x,%p)\n",hComm,lptimeouts);
+
+    if(!lptimeouts)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    req->handle = hComm;
+
+    if(server_call( REQ_GET_SERIAL_INFO ))
+        return FALSE;
+
+    lptimeouts->ReadIntervalTimeout         = req->readinterval;
+    lptimeouts->ReadTotalTimeoutMultiplier  = req->readmult;
+    lptimeouts->ReadTotalTimeoutConstant    = req->readconst;
+    lptimeouts->WriteTotalTimeoutMultiplier = req->writemult;
+    lptimeouts->WriteTotalTimeoutConstant   = req->writeconst;
+
 	return TRUE;
 }
 
 /*****************************************************************************
  *	SetCommTimeouts		(KERNEL32.453)
+ *
+ * Sets the timeouts used when reading and writing data to/from COMM ports.
+ *
+ * ReadIntervalTimeout 
+ *     - converted and passes to linux kernel as c_cc[VTIME]
+ * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
+ *     - used in ReadFile to calculate GetOverlappedResult's timeout
+ * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
+ *     - used in WriteFile to calculate GetOverlappedResult's timeout
  */
-BOOL WINAPI SetCommTimeouts(HANDLE hcom,LPCOMMTIMEOUTS lptimeouts) {
-	/* struct DosDeviceStruct *ptr; */
-	struct termios	tios;
+BOOL WINAPI SetCommTimeouts(
+    HANDLE hComm,              /* [I] handle of COMM device */
+    LPCOMMTIMEOUTS lptimeouts /* [I] pointer to COMMTIMEOUTS structure */
+) {
+    struct set_serial_info_request *req = get_req_buffer();
 	int	fd;
+    struct termios tios;
 
-	FIXME("(%x,%p):stub.\n",hcom,lptimeouts);
-	/* 
-	if ((ptr = GetDeviceStruct(hcom)) == NULL) {
-		FIXME("no handle for cid = %0x!.\n",hcom);
-		return FALSE;
-	}
-	 */
+    TRACE("(%x,%p)\n",hComm,lptimeouts);
 
-	fd = COMM_GetWriteFd(hcom);
-	if (fd < 0) {
-		FIXME("no fd for cid = %0x!.\n",hcom);
+    if(!lptimeouts)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
 		return FALSE;
 	}
 
+    req->handle       = hComm;
+    req->flags        = SERIALINFO_SET_TIMEOUTS;
 
-	FIXME("ReadIntervalTimeout %ld\n",lptimeouts->ReadIntervalTimeout);
-	FIXME("ReadTotalTimeoutMultiplier %ld\n",lptimeouts->ReadTotalTimeoutMultiplier);
-	FIXME("ReadTotalTimeoutConstant %ld\n",lptimeouts->ReadTotalTimeoutConstant);
-	FIXME("WriteTotalTimeoutMultiplier %ld\n",lptimeouts->WriteTotalTimeoutMultiplier);
-	FIXME("WriteTotalTimeoutConstant %ld\n",lptimeouts->WriteTotalTimeoutConstant);
+    req->readinterval = lptimeouts->ReadIntervalTimeout ;
+    req->readmult     = lptimeouts->ReadTotalTimeoutMultiplier ;
+    req->readconst    = lptimeouts->ReadTotalTimeoutConstant ;
+    req->writemult    = lptimeouts->WriteTotalTimeoutMultiplier ;
+    req->writeconst   = lptimeouts->WriteTotalTimeoutConstant ;
 
+    if(server_call( REQ_SET_SERIAL_INFO ))
+        return FALSE;
+
+    /* FIXME: move this stuff to the server */
+    fd = COMM_GetWriteFd(hComm);
+    if (fd < 0) {
+       FIXME("no fd for handle = %0x!.\n",hComm);
+       return FALSE;
+    }
 
 	if (-1==tcgetattr(fd,&tios)) {
 		FIXME("tcgetattr on fd %d failed!\n",fd);
@@ -2507,6 +2526,7 @@ BOOL WINAPI SetCommTimeouts(HANDLE hcom,LPCOMMTIMEOUTS lptimeouts) {
 		FIXME("tcsetattr on fd %d failed!\n",fd);
 		return FALSE;
 	}
+    close(fd);
 	return TRUE;
 }
 
diff --git a/server/request.h b/server/request.h
index d66c230b4ab..975330ce466 100644
--- a/server/request.h
+++ b/server/request.h
@@ -202,6 +202,8 @@ DECL_HANDLER(get_msg_queue);
 DECL_HANDLER(wake_queue);
 DECL_HANDLER(wait_input_idle);
 DECL_HANDLER(create_serial);
+DECL_HANDLER(get_serial_info);
+DECL_HANDLER(set_serial_info);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -316,6 +318,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_wake_queue,
     (req_handler)req_wait_input_idle,
     (req_handler)req_create_serial,
+    (req_handler)req_get_serial_info,
+    (req_handler)req_set_serial_info,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/serial.c b/server/serial.c
index e5b60667fb5..64a9956ef9c 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -196,3 +196,58 @@ DECL_HANDLER(create_serial)
     }
 }
 
+DECL_HANDLER(get_serial_info)
+{
+    struct serial *serial;
+
+    if ((serial = get_serial_obj( current->process, req->handle, 0 )))
+    {
+        /* timeouts */
+        req->readinterval = serial->readinterval;
+        req->readconst    = serial->readconst;
+        req->readmult     = serial->readmult;
+        req->writeconst   = serial->writeconst;
+        req->writemult    = serial->writemult;
+
+        /* event mask */
+        req->eventmask    = serial->eventmask;
+
+        /* comm port error status */
+        req->commerror    = serial->commerror;
+
+        release_object( serial );
+    }
+}
+
+DECL_HANDLER(set_serial_info)
+{
+    struct serial *serial;
+
+    if ((serial = get_serial_obj( current->process, req->handle, 0 )))
+    {
+        /* timeouts */
+        if(req->flags & SERIALINFO_SET_TIMEOUTS)
+        {
+            serial->readinterval = req->readinterval;
+            serial->readconst    = req->readconst;
+            serial->readmult     = req->readmult;
+            serial->writeconst   = req->writeconst;
+            serial->writemult    = req->writemult;
+        }
+
+        /* event mask */
+        if(req->flags & SERIALINFO_SET_MASK)
+        {
+            serial->eventmask = req->eventmask;
+        }
+
+        /* comm port error status */
+        if(req->flags & SERIALINFO_SET_ERROR)
+        {
+            serial->commerror = req->commerror;
+        }
+
+        release_object( serial );
+    }
+}
+
diff --git a/server/trace.c b/server/trace.c
index 07c1a6dcf49..786c8b42715 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1431,6 +1431,35 @@ static void dump_create_serial_reply( const struct create_serial_request *req )
     fprintf( stderr, " handle=%d", req->handle );
 }
 
+static void dump_get_serial_info_request( const struct get_serial_info_request *req )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_get_serial_info_reply( const struct get_serial_info_request *req )
+{
+    fprintf( stderr, " readinterval=%08x,", req->readinterval );
+    fprintf( stderr, " readconst=%08x,", req->readconst );
+    fprintf( stderr, " readmult=%08x,", req->readmult );
+    fprintf( stderr, " writeconst=%08x,", req->writeconst );
+    fprintf( stderr, " writemult=%08x,", req->writemult );
+    fprintf( stderr, " eventmask=%08x,", req->eventmask );
+    fprintf( stderr, " commerror=%08x", req->commerror );
+}
+
+static void dump_set_serial_info_request( const struct set_serial_info_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " flags=%d,", req->flags );
+    fprintf( stderr, " readinterval=%08x,", req->readinterval );
+    fprintf( stderr, " readconst=%08x,", req->readconst );
+    fprintf( stderr, " readmult=%08x,", req->readmult );
+    fprintf( stderr, " writeconst=%08x,", req->writeconst );
+    fprintf( stderr, " writemult=%08x,", req->writemult );
+    fprintf( stderr, " eventmask=%08x,", req->eventmask );
+    fprintf( stderr, " commerror=%08x", req->commerror );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_wait_process_request,
@@ -1540,6 +1569,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_wake_queue_request,
     (dump_func)dump_wait_input_idle_request,
     (dump_func)dump_create_serial_request,
+    (dump_func)dump_get_serial_info_request,
+    (dump_func)dump_set_serial_info_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -1651,6 +1682,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)0,
     (dump_func)dump_wait_input_idle_reply,
     (dump_func)dump_create_serial_reply,
+    (dump_func)dump_get_serial_info_reply,
+    (dump_func)0,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -1762,6 +1795,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "wake_queue",
     "wait_input_idle",
     "create_serial",
+    "get_serial_info",
+    "set_serial_info",
 };
 
 /* ### make_requests end ### */
-- 
GitLab