Module: wine Branch: master Commit: 35ef5df76cf9d282f3df36eec24b3876039650a3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=35ef5df76cf9d282f3df36eec2...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jun 4 23:03:15 2007 +0200
kernel32: Rewrite GetOverlappedResult for the new async I/O behavior.
---
dlls/kernel32/file.c | 67 ++++++++++---------------------------------- dlls/kernel32/tests/file.c | 2 - 2 files changed, 15 insertions(+), 54 deletions(-)
diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c index be8ca63..a3d6942 100644 --- a/dlls/kernel32/file.c +++ b/dlls/kernel32/file.c @@ -539,17 +539,11 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, * * If successful (and relevant) lpTransferred will hold the number of * bytes transferred during the async operation. - * - * BUGS - * - * Currently only works for WaitCommEvent, ReadFile, WriteFile - * with communications ports. - * */ BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpTransferred, BOOL bWait) { - DWORD r = WAIT_OBJECT_0; + NTSTATUS status;
TRACE( "(%p %p %p %x)\n", hFile, lpOverlapped, lpTransferred, bWait );
@@ -558,57 +552,26 @@ BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, ERR("lpOverlapped was null\n"); return FALSE; } - if ( bWait ) + + status = lpOverlapped->Internal; + if (status == STATUS_PENDING) { - if ( lpOverlapped->hEvent ) + if (!bWait) { - do - { - TRACE( "waiting on %p\n", lpOverlapped ); - r = WaitForSingleObjectEx( lpOverlapped->hEvent, INFINITE, TRUE ); - TRACE( "wait on %p returned %d\n", lpOverlapped, r ); - } while ( r == WAIT_IO_COMPLETION ); + SetLastError( ERROR_IO_INCOMPLETE ); + return FALSE; } - else - { - /* busy loop */ - while ( ((volatile OVERLAPPED*)lpOverlapped)->Internal == STATUS_PENDING ) - Sleep( 10 ); - } - } - else if ( lpOverlapped->Internal == STATUS_PENDING ) - { - /* Wait in order to give APCs a chance to run. */ - /* This is cheating, so we must set the event again in case of success - - it may be a non-manual reset event. */ - do - { - TRACE( "waiting on %p\n", lpOverlapped ); - r = WaitForSingleObjectEx( lpOverlapped->hEvent, 0, TRUE ); - TRACE( "wait on %p returned %d\n", lpOverlapped, r ); - } while ( r == WAIT_IO_COMPLETION ); - if ( r == WAIT_OBJECT_0 && lpOverlapped->hEvent ) - NtSetEvent( lpOverlapped->hEvent, NULL ); - } - if ( r == WAIT_FAILED ) - { - WARN("wait operation failed\n"); - return FALSE; + + if (WaitForSingleObject( lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile, + INFINITE ) == WAIT_FAILED) + return FALSE; + status = lpOverlapped->Internal; } + if (lpTransferred) *lpTransferred = lpOverlapped->InternalHigh;
- switch ( lpOverlapped->Internal ) - { - case STATUS_SUCCESS: - return TRUE; - case STATUS_PENDING: - SetLastError( ERROR_IO_INCOMPLETE ); - if ( bWait ) ERR("PENDING status after waiting!\n"); - return FALSE; - default: - SetLastError( RtlNtStatusToDosError( lpOverlapped->Internal ) ); - return FALSE; - } + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; }
/*********************************************************************** diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 89cf0a2..e9f97f5 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -1768,9 +1768,7 @@ static void test_overlapped(void) ov.Internal = STATUS_PENDING; ov.InternalHigh = 0xabcd; r = GetOverlappedResult(0, &ov, &result, 0); - todo_wine { ok( GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError() ); - } ok( r == FALSE, "should return false\n"); ok( result == 0, "wrong result %u\n", result );