diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c index de959de7336..41ae7909699 100644 --- a/dlls/kernel/comm.c +++ b/dlls/kernel/comm.c @@ -848,37 +848,19 @@ BOOL WINAPI EscapeCommFunction( * Terminates pending operations and/or discards buffers on a * communication resource. * + * PARAMS + * + * handle [in] The communication resource to be purged + * flags [in] Flags for clear pending/buffer on input/output + * * RETURNS * * True on success and false if the communications handle is bad. */ -BOOL WINAPI PurgeComm( - HANDLE handle, /* [in] The communication resource to be purged. */ - DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */ +BOOL WINAPI PurgeComm(HANDLE handle, DWORD flags) { - int fd; - - TRACE("handle %p, flags %lx\n", handle, flags); - - fd = get_comm_fd( handle, FILE_READ_DATA ); - if(fd<0) return FALSE; - - /* - ** not exactly sure how these are different - ** Perhaps if we had our own internal queues, one flushes them - ** and the other flushes the kernel's buffers. - */ - if(flags&PURGE_TXABORT) - tcflush(fd,TCOFLUSH); - if(flags&PURGE_RXABORT) - tcflush(fd,TCIFLUSH); - if(flags&PURGE_TXCLEAR) - tcflush(fd,TCOFLUSH); - if(flags&PURGE_RXCLEAR) - tcflush(fd,TCIFLUSH); - release_comm_fd( handle, fd ); - - return 1; + return DeviceIoControl(handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags), + NULL, 0, NULL, NULL); } /***************************************************************************** diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c index 0b15f6e1908..ecf025c719a 100644 --- a/dlls/ntdll/serial.c +++ b/dlls/ntdll/serial.c @@ -129,6 +129,20 @@ static const char* iocode2str(DWORD ioc) } } +static NTSTATUS purge(int fd, DWORD flags) +{ + /* + ** not exactly sure how these are different + ** Perhaps if we had our own internal queues, one flushes them + ** and the other flushes the kernel's buffers. + */ + if (flags & PURGE_TXABORT) tcflush(fd, TCOFLUSH); + if (flags & PURGE_RXABORT) tcflush(fd, TCIFLUSH); + if (flags & PURGE_TXCLEAR) tcflush(fd, TCOFLUSH); + if (flags & PURGE_RXCLEAR) tcflush(fd, TCIFLUSH); + return STATUS_SUCCESS; +} + /****************************************************************** * COMM_DeviceIoControl * @@ -156,6 +170,12 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDevice, switch (dwIoControlCode) { + case IOCTL_SERIAL_PURGE: + if (lpInBuffer && nInBufferSize == sizeof(DWORD)) + status = purge(fd, *(DWORD*)lpInBuffer); + else + status = STATUS_INVALID_PARAMETER; + break; case IOCTL_SERIAL_SET_BREAK_OFF: #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */ if (ioctl(fd, TIOCCBRK, 0) == -1)