From 64ba011dba87ebbda3503935f1620cd7d89f7308 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 10 Apr 2007 17:27:50 +0200 Subject: [PATCH] ntdll: Determine the async read avail_mode flag from the client side. --- dlls/ntdll/file.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 078e4fe4941..8158a144877 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -465,6 +465,40 @@ static inline int get_next_io_timeout( struct io_timeouts *timeouts, ULONG alrea } +/* retrieve the avail_mode flag for async reads */ +static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL *avail_mode ) +{ + NTSTATUS status = STATUS_SUCCESS; + + switch(type) + { + case FD_TYPE_SERIAL: + { + /* GetCommTimeouts */ + SERIAL_TIMEOUTS st; + IO_STATUS_BLOCK io; + + status = NtDeviceIoControlFile( handle, NULL, NULL, NULL, &io, + IOCTL_SERIAL_GET_TIMEOUTS, NULL, 0, &st, sizeof(st) ); + if (status) break; + *avail_mode = (!st.ReadTotalTimeoutMultiplier && + !st.ReadTotalTimeoutConstant && + st.ReadIntervalTimeout == MAXDWORD); + } + break; + case FD_TYPE_MAILSLOT: + case FD_TYPE_SOCKET: + case FD_TYPE_PIPE: + *avail_mode = TRUE; + break; + default: + *avail_mode = FALSE; + break; + } + return status; +} + + /****************************************************************************** * NtReadFile [NTDLL.@] * ZwReadFile [NTDLL.@] @@ -553,8 +587,11 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, if (flags & FD_FLAG_OVERLAPPED) { async_fileio_read *fileio; + BOOL avail_mode; - if (total && (flags & FD_FLAG_AVAILABLE)) + if ((status = get_io_avail_mode( hFile, type, &avail_mode ))) + goto done; + if (total && avail_mode) { status = STATUS_SUCCESS; goto done; @@ -569,7 +606,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, fileio->already = total; fileio->count = length; fileio->buffer = buffer; - fileio->avail_mode = (flags & FD_FLAG_AVAILABLE); + fileio->avail_mode = avail_mode; SERVER_START_REQ( register_async ) {