ntdll/kernel32: EscapeCommFunction & associated IOCTLs
- implemented ntdll's serial IOCTL: CLR_DTR, CLR_RTS, SET_DTR, SET_RTS, SET_XOFF, SET_XON, RESET_DEVICE - implemented kernel32.EscapeCommFunction on top of them
This commit is contained in:
parent
fcdc293bb0
commit
5f9e9836cf
|
@ -146,19 +146,6 @@ static int COMM_GetEInfo(int fd, serial_irq_info *irq_info)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
|
|
||||||
{
|
|
||||||
#ifdef TIOCMGET
|
|
||||||
unsigned int mstat, okay;
|
|
||||||
okay = ioctl(fd, TIOCMGET, &mstat);
|
|
||||||
if (okay) return okay;
|
|
||||||
if (andy) mstat &= andy;
|
|
||||||
mstat |= orrie;
|
|
||||||
return ioctl(fd, TIOCMSET, &mstat);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* COMM_Parse* (Internal)
|
* COMM_Parse* (Internal)
|
||||||
|
@ -699,111 +686,38 @@ BOOL WINAPI ClearCommBreak(HANDLE handle)
|
||||||
*
|
*
|
||||||
* Directs a communication device to perform an extended function.
|
* Directs a communication device to perform an extended function.
|
||||||
*
|
*
|
||||||
|
* PARAMS
|
||||||
|
*
|
||||||
|
* handle [in] The communication device to perform the extended function
|
||||||
|
* nFunction [in] The extended function to be performed
|
||||||
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
*
|
*
|
||||||
* True or requested data on successful completion of the command,
|
* True or requested data on successful completion of the command,
|
||||||
* false if the device is not present cannot execute the command
|
* false if the device is not present cannot execute the command
|
||||||
* or the command failed.
|
* or the command failed.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI EscapeCommFunction(
|
BOOL WINAPI EscapeCommFunction(HANDLE handle, UINT func)
|
||||||
HANDLE handle, /* [in] The communication device to perform the extended function. */
|
|
||||||
UINT nFunction) /* [in] The extended function to be performed. */
|
|
||||||
{
|
{
|
||||||
int fd,direct=FALSE,result=FALSE;
|
DWORD ioc;
|
||||||
struct termios port;
|
|
||||||
|
|
||||||
TRACE("handle %p, function=%d\n", handle, nFunction);
|
switch (func)
|
||||||
fd = get_comm_fd( handle, FILE_READ_DATA );
|
{
|
||||||
if(fd<0) return FALSE;
|
case CLRDTR: ioc = IOCTL_SERIAL_CLR_DTR; break;
|
||||||
|
case CLRRTS: ioc = IOCTL_SERIAL_CLR_RTS; break;
|
||||||
if (tcgetattr(fd,&port) == -1) {
|
case SETDTR: ioc = IOCTL_SERIAL_SET_DTR; break;
|
||||||
release_comm_fd( handle, fd );
|
case SETRTS: ioc = IOCTL_SERIAL_SET_RTS; break;
|
||||||
return FALSE;
|
case SETXOFF: ioc = IOCTL_SERIAL_SET_XOFF; break;
|
||||||
}
|
case SETXON: ioc = IOCTL_SERIAL_SET_XON; break;
|
||||||
|
case SETBREAK: ioc = IOCTL_SERIAL_SET_BREAK_ON; break;
|
||||||
switch (nFunction) {
|
case CLRBREAK: ioc = IOCTL_SERIAL_SET_BREAK_OFF; break;
|
||||||
case RESETDEV:
|
case RESETDEV: ioc = IOCTL_SERIAL_RESET_DEVICE; break;
|
||||||
TRACE("\n");
|
default:
|
||||||
break;
|
ERR("Unknown function code (%u)\n", func);
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
case CLRDTR:
|
return FALSE;
|
||||||
TRACE("CLRDTR\n");
|
}
|
||||||
#ifdef TIOCM_DTR
|
return DeviceIoControl(handle, ioc, NULL, 0, NULL, 0, NULL, NULL);
|
||||||
direct=TRUE;
|
|
||||||
result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case CLRRTS:
|
|
||||||
TRACE("CLRRTS\n");
|
|
||||||
#ifdef TIOCM_RTS
|
|
||||||
direct=TRUE;
|
|
||||||
result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SETDTR:
|
|
||||||
TRACE("SETDTR\n");
|
|
||||||
#ifdef TIOCM_DTR
|
|
||||||
direct=TRUE;
|
|
||||||
result= COMM_WhackModem(fd, 0, TIOCM_DTR);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SETRTS:
|
|
||||||
TRACE("SETRTS\n");
|
|
||||||
#ifdef TIOCM_RTS
|
|
||||||
direct=TRUE;
|
|
||||||
result= COMM_WhackModem(fd, 0, TIOCM_RTS);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case SETXOFF:
|
|
||||||
TRACE("SETXOFF\n");
|
|
||||||
port.c_iflag |= IXOFF;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SETXON:
|
|
||||||
TRACE("SETXON\n");
|
|
||||||
port.c_iflag |= IXON;
|
|
||||||
break;
|
|
||||||
case SETBREAK:
|
|
||||||
TRACE("setbreak\n");
|
|
||||||
#ifdef TIOCSBRK
|
|
||||||
direct=TRUE;
|
|
||||||
result = ioctl(fd,TIOCSBRK,0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case CLRBREAK:
|
|
||||||
TRACE("clrbreak\n");
|
|
||||||
#ifdef TIOCSBRK
|
|
||||||
direct=TRUE;
|
|
||||||
result = ioctl(fd,TIOCCBRK,0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
WARN("(handle=%p,nFunction=%d): Unknown function\n",
|
|
||||||
handle, nFunction);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!direct)
|
|
||||||
if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
|
|
||||||
release_comm_fd( handle, fd );
|
|
||||||
return FALSE;
|
|
||||||
} else
|
|
||||||
result= TRUE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (result == -1)
|
|
||||||
{
|
|
||||||
result= FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = TRUE;
|
|
||||||
}
|
|
||||||
release_comm_fd( handle, fd );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
|
@ -823,6 +823,44 @@ static NTSTATUS set_wait_mask(HANDLE hDevice, DWORD mask)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS set_XOff(int fd)
|
||||||
|
{
|
||||||
|
struct termios port;
|
||||||
|
|
||||||
|
if (tcgetattr(fd,&port) == -1)
|
||||||
|
{
|
||||||
|
FIXME("tcgetattr on fd %d failed (%s)!\n", fd, strerror(errno));
|
||||||
|
return FILE_GetNtStatus();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
port.c_iflag |= IXOFF;
|
||||||
|
if (tcsetattr(fd, TCSADRAIN, &port) == -1)
|
||||||
|
{
|
||||||
|
FIXME("tcsetattr on fd %d failed (%s)!\n", fd, strerror(errno));
|
||||||
|
return FILE_GetNtStatus();
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS set_XOn(int fd)
|
||||||
|
{
|
||||||
|
struct termios port;
|
||||||
|
|
||||||
|
if (tcgetattr(fd,&port) == -1)
|
||||||
|
{
|
||||||
|
FIXME("tcgetattr on fd %d failed (%s)!\n", fd, strerror(errno));
|
||||||
|
return FILE_GetNtStatus();
|
||||||
|
}
|
||||||
|
port.c_iflag |= IXON;
|
||||||
|
if (tcsetattr(fd, TCSADRAIN, &port) == -1)
|
||||||
|
{
|
||||||
|
FIXME("tcsetattr on fd %d failed (%s)!\n", fd, strerror(errno));
|
||||||
|
return FILE_GetNtStatus();
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS xmit_immediate(HANDLE hDevice, int fd, char* ptr)
|
static NTSTATUS xmit_immediate(HANDLE hDevice, int fd, char* ptr)
|
||||||
{
|
{
|
||||||
/* FIXME: not perfect as it should bypass the in-queue */
|
/* FIXME: not perfect as it should bypass the in-queue */
|
||||||
|
@ -861,6 +899,20 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
||||||
|
|
||||||
switch (dwIoControlCode)
|
switch (dwIoControlCode)
|
||||||
{
|
{
|
||||||
|
case IOCTL_SERIAL_CLR_DTR:
|
||||||
|
#ifdef TIOCM_DTR
|
||||||
|
if (whack_modem(fd, ~TIOCM_DTR, 0) == -1) status = FILE_GetNtStatus();
|
||||||
|
#else
|
||||||
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case IOCTL_SERIAL_CLR_RTS:
|
||||||
|
#ifdef TIOCM_RTS
|
||||||
|
if (whack_modem(fd, ~TIOCM_RTS, 0) == -1) status = FILE_GetNtStatus();
|
||||||
|
#else
|
||||||
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case IOCTL_SERIAL_GET_BAUD_RATE:
|
case IOCTL_SERIAL_GET_BAUD_RATE:
|
||||||
if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_BAUD_RATE))
|
if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_BAUD_RATE))
|
||||||
{
|
{
|
||||||
|
@ -943,6 +995,9 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
||||||
else
|
else
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
break;
|
||||||
|
case IOCTL_SERIAL_RESET_DEVICE:
|
||||||
|
FIXME("Unsupported\n");
|
||||||
|
break;
|
||||||
case IOCTL_SERIAL_SET_BAUD_RATE:
|
case IOCTL_SERIAL_SET_BAUD_RATE:
|
||||||
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_BAUD_RATE))
|
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_BAUD_RATE))
|
||||||
status = set_baud_rate(fd, (const SERIAL_BAUD_RATE*)lpInBuffer);
|
status = set_baud_rate(fd, (const SERIAL_BAUD_RATE*)lpInBuffer);
|
||||||
|
@ -979,6 +1034,13 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
||||||
else
|
else
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
break;
|
||||||
|
case IOCTL_SERIAL_SET_DTR:
|
||||||
|
#ifdef TIOCM_DTR
|
||||||
|
if (whack_modem(fd, 0, TIOCM_DTR) == -1) status = FILE_GetNtStatus();
|
||||||
|
#else
|
||||||
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case IOCTL_SERIAL_SET_HANDFLOW:
|
case IOCTL_SERIAL_SET_HANDFLOW:
|
||||||
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_HANDFLOW))
|
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_HANDFLOW))
|
||||||
status = set_handflow(fd, (const SERIAL_HANDFLOW*)lpInBuffer);
|
status = set_handflow(fd, (const SERIAL_HANDFLOW*)lpInBuffer);
|
||||||
|
@ -997,6 +1059,13 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
||||||
else
|
else
|
||||||
status = STATUS_INVALID_PARAMETER;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
break;
|
||||||
|
case IOCTL_SERIAL_SET_RTS:
|
||||||
|
#ifdef TIOCM_RTS
|
||||||
|
if (whack_modem(fd, 0, TIOCM_RTS) == -1) status = FILE_GetNtStatus();
|
||||||
|
#else
|
||||||
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case IOCTL_SERIAL_SET_TIMEOUTS:
|
case IOCTL_SERIAL_SET_TIMEOUTS:
|
||||||
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_TIMEOUTS))
|
if (lpInBuffer && nInBufferSize == sizeof(SERIAL_TIMEOUTS))
|
||||||
status = set_timeouts(hDevice, fd, (const SERIAL_TIMEOUTS*)lpInBuffer);
|
status = set_timeouts(hDevice, fd, (const SERIAL_TIMEOUTS*)lpInBuffer);
|
||||||
|
@ -1010,6 +1079,12 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice,
|
||||||
}
|
}
|
||||||
else status = STATUS_INVALID_PARAMETER;
|
else status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
break;
|
||||||
|
case IOCTL_SERIAL_SET_XOFF:
|
||||||
|
status = set_XOff(fd);
|
||||||
|
break;
|
||||||
|
case IOCTL_SERIAL_SET_XON:
|
||||||
|
status = set_XOn(fd);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unsupported IOCTL %lx (type=%lx access=%lx func=%lx meth=%lx)\n",
|
FIXME("Unsupported IOCTL %lx (type=%lx access=%lx func=%lx meth=%lx)\n",
|
||||||
dwIoControlCode, dwIoControlCode >> 16, (dwIoControlCode >> 14) & 3,
|
dwIoControlCode, dwIoControlCode >> 16, (dwIoControlCode >> 14) & 3,
|
||||||
|
|
Loading…
Reference in New Issue