kernel32: Rewrite GetOverlappedResult for the new async I/O behavior.
This commit is contained in:
parent
7c6bc78b90
commit
35ef5df76c
@ -539,17 +539,11 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
|
|||||||
*
|
*
|
||||||
* If successful (and relevant) lpTransferred will hold the number of
|
* If successful (and relevant) lpTransferred will hold the number of
|
||||||
* bytes transferred during the async operation.
|
* bytes transferred during the async operation.
|
||||||
*
|
|
||||||
* BUGS
|
|
||||||
*
|
|
||||||
* Currently only works for WaitCommEvent, ReadFile, WriteFile
|
|
||||||
* with communications ports.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
|
BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
|
||||||
LPDWORD lpTransferred, BOOL bWait)
|
LPDWORD lpTransferred, BOOL bWait)
|
||||||
{
|
{
|
||||||
DWORD r = WAIT_OBJECT_0;
|
NTSTATUS status;
|
||||||
|
|
||||||
TRACE( "(%p %p %p %x)\n", hFile, lpOverlapped, lpTransferred, bWait );
|
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");
|
ERR("lpOverlapped was null\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( bWait )
|
|
||||||
|
status = lpOverlapped->Internal;
|
||||||
|
if (status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
if ( lpOverlapped->hEvent )
|
if (!bWait)
|
||||||
{
|
{
|
||||||
do
|
SetLastError( ERROR_IO_INCOMPLETE );
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WaitForSingleObject( lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile,
|
||||||
|
INFINITE ) == WAIT_FAILED)
|
||||||
|
return FALSE;
|
||||||
|
status = lpOverlapped->Internal;
|
||||||
|
}
|
||||||
|
|
||||||
if (lpTransferred) *lpTransferred = lpOverlapped->InternalHigh;
|
if (lpTransferred) *lpTransferred = lpOverlapped->InternalHigh;
|
||||||
|
|
||||||
switch ( lpOverlapped->Internal )
|
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||||
{
|
return !status;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1768,9 +1768,7 @@ static void test_overlapped(void)
|
|||||||
ov.Internal = STATUS_PENDING;
|
ov.Internal = STATUS_PENDING;
|
||||||
ov.InternalHigh = 0xabcd;
|
ov.InternalHigh = 0xabcd;
|
||||||
r = GetOverlappedResult(0, &ov, &result, 0);
|
r = GetOverlappedResult(0, &ov, &result, 0);
|
||||||
todo_wine {
|
|
||||||
ok( GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError() );
|
ok( GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError() );
|
||||||
}
|
|
||||||
ok( r == FALSE, "should return false\n");
|
ok( r == FALSE, "should return false\n");
|
||||||
ok( result == 0, "wrong result %u\n", result );
|
ok( result == 0, "wrong result %u\n", result );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user