Module: wine Branch: refs/heads/master Commit: b53e016925301e6086bca3fd665074b0ea01d090 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=b53e016925301e6086bca3fd...
Author: Eric Pouech eric.pouech@wanadoo.fr Date: Sun May 7 14:10:58 2006 +0200
ntdll/kernel32: [SG]etCommTimeout, SERIAL_[GS]ET_TIMEOUT
- implemented ntdll's COMM IOCTL GET_TIMEOUTS, SET_TIMEOUTS - implemented kernel32.GetCommTimeout and SetCommTimeout on top of them
---
dlls/kernel/comm.c | 114 +++++++++++++++------------------------------------ dlls/ntdll/serial.c | 87 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 84 deletions(-)
diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c index 7d8e6da..f12043d 100644 --- a/dlls/kernel/comm.c +++ b/dlls/kernel/comm.c @@ -1180,39 +1180,34 @@ BOOL WINAPI TransmitCommChar(HANDLE hCom * * Obtains the request timeout values for the communications device. * + * PARAMS + * hComm [in] The communications device + * lptimeouts [out] The struct of request timeouts + * * RETURNS * * True on success, false if communications device handle is bad * or the target structure is null. */ -BOOL WINAPI GetCommTimeouts( - HANDLE hComm, /* [in] The communications device. */ - LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */ +BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) { - BOOL ret; - - TRACE("(%p,%p)\n",hComm,lptimeouts); + SERIAL_TIMEOUTS st;
- if(!lptimeouts) + TRACE("(%p, %p)\n", hComm, lptimeouts); + if (!lptimeouts) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - SERVER_START_REQ( get_serial_info ) - { - req->handle = hComm; - if ((ret = !wine_server_call_err( req ))) - { - lptimeouts->ReadIntervalTimeout = reply->readinterval; - lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult; - lptimeouts->ReadTotalTimeoutConstant = reply->readconst; - lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult; - lptimeouts->WriteTotalTimeoutConstant = reply->writeconst; - } - } - SERVER_END_REQ; - return ret; + if (!DeviceIoControl(hComm, IOCTL_SERIAL_GET_TIMEOUTS, + NULL, 0, &st, sizeof(st), NULL, NULL)) + return FALSE; + lptimeouts->ReadIntervalTimeout = st.ReadIntervalTimeout; + lptimeouts->ReadTotalTimeoutMultiplier = st.ReadTotalTimeoutMultiplier; + lptimeouts->ReadTotalTimeoutConstant = st.ReadTotalTimeoutConstant; + lptimeouts->WriteTotalTimeoutMultiplier = st.WriteTotalTimeoutMultiplier; + lptimeouts->WriteTotalTimeoutConstant = st.WriteTotalTimeoutConstant; + return TRUE; }
/***************************************************************************** @@ -1220,6 +1215,10 @@ BOOL WINAPI GetCommTimeouts( * * Sets the timeouts used when reading and writing data to/from COMM ports. * + * PARAMS + * hComm [in] handle of COMM device + * lptimeouts [in] pointer to COMMTIMEOUTS structure + * * ReadIntervalTimeout * - converted and passes to linux kernel as c_cc[VTIME] * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant @@ -1231,72 +1230,25 @@ BOOL WINAPI GetCommTimeouts( * * True if the timeouts were set, false otherwise. */ -BOOL WINAPI SetCommTimeouts( - HANDLE hComm, /* [in] handle of COMM device */ - LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */ +BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) { - BOOL ret; - int fd; - struct termios tios; + SERIAL_TIMEOUTS st;
- TRACE("(%p,%p)\n",hComm,lptimeouts); + TRACE("(%p, %p)\n", hComm, lptimeouts);
- if(!lptimeouts) + if (lptimeouts == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - SERVER_START_REQ( set_serial_info ) - { - req->handle = hComm; - req->flags = SERIALINFO_SET_TIMEOUTS; - req->readinterval = lptimeouts->ReadIntervalTimeout ; - req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ; - req->readconst = lptimeouts->ReadTotalTimeoutConstant ; - req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ; - req->writeconst = lptimeouts->WriteTotalTimeoutConstant ; - ret = !wine_server_call_err( req ); - } - SERVER_END_REQ; - if (!ret) return FALSE; - - /* FIXME: move this stuff to the server */ - fd = get_comm_fd( hComm, FILE_READ_DATA ); - if (fd < 0) return FALSE; - - if (-1==tcgetattr(fd,&tios)) { - FIXME("tcgetattr on fd %d failed!\n",fd); - release_comm_fd( hComm, fd ); - return FALSE; - } - - /* VTIME is in 1/10 seconds */ - { - unsigned int ux_timeout; - - if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */ - { - ux_timeout = 0; - } - else - { - ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100; - if(ux_timeout == 0) - { - ux_timeout = 1; /* must be at least some timeout */ - } - } - tios.c_cc[VTIME] = ux_timeout; - } - - if (-1==tcsetattr(fd,0,&tios)) { - FIXME("tcsetattr on fd %d failed!\n",fd); - release_comm_fd( hComm, fd ); - return FALSE; - } - release_comm_fd( hComm, fd ); - return TRUE; + st.ReadIntervalTimeout = lptimeouts->ReadIntervalTimeout; + st.ReadTotalTimeoutMultiplier = lptimeouts->ReadTotalTimeoutMultiplier; + st.ReadTotalTimeoutConstant = lptimeouts->ReadTotalTimeoutConstant; + st.WriteTotalTimeoutMultiplier = lptimeouts->WriteTotalTimeoutMultiplier; + st.WriteTotalTimeoutConstant = lptimeouts->WriteTotalTimeoutConstant; + + return DeviceIoControl(hComm, IOCTL_SERIAL_SET_TIMEOUTS, + &st, sizeof(st), NULL, 0, NULL, NULL); }
/*********************************************************************** diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c index 9b56c6b..1b45a10 100644 --- a/dlls/ntdll/serial.c +++ b/dlls/ntdll/serial.c @@ -368,6 +368,25 @@ #endif return status; }
+static NTSTATUS get_timeouts(HANDLE handle, SERIAL_TIMEOUTS* st) +{ + NTSTATUS status; + SERVER_START_REQ( get_serial_info ) + { + req->handle = handle; + if (!(status = wine_server_call( req ))) + { + st->ReadIntervalTimeout = reply->readinterval; + st->ReadTotalTimeoutMultiplier = reply->readmult; + st->ReadTotalTimeoutConstant = reply->readconst; + st->WriteTotalTimeoutMultiplier = reply->writemult; + st->WriteTotalTimeoutConstant = reply->writeconst; + } + } + SERVER_END_REQ; + return status; +} + static NTSTATUS get_wait_mask(HANDLE hDevice, DWORD* mask) { NTSTATUS status; @@ -738,6 +757,51 @@ static NTSTATUS set_special_chars(int fd return STATUS_SUCCESS; }
+static NTSTATUS set_timeouts(HANDLE handle, int fd, const SERIAL_TIMEOUTS* st) +{ + NTSTATUS status; + struct termios port; + unsigned int ux_timeout; + + SERVER_START_REQ( set_serial_info ) + { + req->handle = handle; + req->flags = SERIALINFO_SET_TIMEOUTS; + req->readinterval = st->ReadIntervalTimeout ; + req->readmult = st->ReadTotalTimeoutMultiplier ; + req->readconst = st->ReadTotalTimeoutConstant ; + req->writemult = st->WriteTotalTimeoutMultiplier ; + req->writeconst = st->WriteTotalTimeoutConstant ; + status = wine_server_call( req ); + } + SERVER_END_REQ; + if (status) return status; + + if (tcgetattr(fd, &port) == -1) + { + FIXME("tcgetattr on fd %d failed (%s)!\n", fd, strerror(errno)); + return FILE_GetNtStatus(); + } + + /* VTIME is in 1/10 seconds */ + if (st->ReadIntervalTimeout == 0) /* 0 means no timeout */ + ux_timeout = 0; + else + { + ux_timeout = (st->ReadIntervalTimeout + 99) / 100; + if (ux_timeout == 0) + ux_timeout = 1; /* must be at least some timeout */ + } + port.c_cc[VTIME] = ux_timeout; + + if (tcsetattr(fd, 0, &port) == -1) + { + FIXME("tcsetattr on fd %d failed (%s)!\n", fd, strerror(errno)); + return FILE_GetNtStatus(); + } + return STATUS_SUCCESS; +} + static NTSTATUS set_wait_mask(HANDLE hDevice, DWORD mask) { NTSTATUS status; @@ -777,7 +841,7 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDe { DWORD sz = 0, access = FILE_READ_DATA; NTSTATUS status = STATUS_SUCCESS; - int fd; + int fd = -1;
TRACE("%p %s %p %ld %p %ld %p\n", hDevice, iocode2str(dwIoControlCode), lpInBuffer, nInBufferSize, @@ -785,7 +849,9 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDe
piosb->Information = 0;
- if ((status = wine_server_handle_to_fd( hDevice, access, &fd, NULL ))) goto error; + if (dwIoControlCode != IOCTL_SERIAL_GET_TIMEOUTS) + if ((status = wine_server_handle_to_fd( hDevice, access, &fd, NULL ))) + goto error;
switch (dwIoControlCode) { @@ -841,6 +907,15 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDe } else status = STATUS_INVALID_PARAMETER; break; + case IOCTL_SERIAL_GET_TIMEOUTS: + if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_TIMEOUTS)) + { + if (!(status = get_timeouts(hDevice, (SERIAL_TIMEOUTS*)lpInBuffer))) + sz = sizeof(SERIAL_TIMEOUTS); + } + else + status = STATUS_INVALID_PARAMETER; + break; case IOCTL_SERIAL_GET_WAIT_MASK: if (lpOutBuffer && nOutBufferSize == sizeof(DWORD)) { @@ -910,6 +985,12 @@ #endif else status = STATUS_INVALID_PARAMETER; break; + case IOCTL_SERIAL_SET_TIMEOUTS: + if (lpInBuffer && nInBufferSize == sizeof(SERIAL_TIMEOUTS)) + status = set_timeouts(hDevice, fd, (const SERIAL_TIMEOUTS*)lpInBuffer); + else + status = STATUS_INVALID_PARAMETER; + break; case IOCTL_SERIAL_SET_WAIT_MASK: if (lpInBuffer && nInBufferSize == sizeof(DWORD)) { @@ -925,7 +1006,7 @@ #endif status = STATUS_INVALID_PARAMETER; break; } - wine_server_release_fd( hDevice, fd ); + if (fd != -1) wine_server_release_fd( hDevice, fd ); error: piosb->u.Status = status; piosb->Information = sz;