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
This commit is contained in:
parent
28cd4fae3b
commit
b53e016925
|
@ -1180,39 +1180,34 @@ BOOL WINAPI TransmitCommChar(HANDLE hComm, CHAR chTransmit)
|
|||
*
|
||||
* 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;
|
||||
SERIAL_TIMEOUTS st;
|
||||
|
||||
TRACE("(%p,%p)\n",hComm,lptimeouts);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -368,6 +368,25 @@ static NTSTATUS get_status(int fd, SERIAL_STATUS* ss)
|
|||
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, const SERIAL_CHARS* sc)
|
|||
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 hDevice,
|
|||
{
|
||||
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 hDevice,
|
|||
|
||||
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 hDevice,
|
|||
}
|
||||
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 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
|||
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 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue