Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- dlls/kernel32/tests/file.c | 34 +++++++++++++++++++++++++++++++++- dlls/ntdll/file.c | 8 +++----- 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 4980e02d7d..94feee6372 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4353,7 +4353,7 @@ static void test_WriteFileGather(void) FILE_SEGMENT_ELEMENT fse[2]; OVERLAPPED ovl, *povl = NULL; SYSTEM_INFO si; - LPVOID wbuf = NULL, rbuf1; + LPVOID wbuf = NULL, rbuf1, rbuf2; BOOL br;
evt = CreateEventW( NULL, TRUE, FALSE, NULL ); @@ -4380,6 +4380,9 @@ static void test_WriteFileGather(void) rbuf1 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE ); ok( rbuf1 != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
+ rbuf2 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE ); + ok( rbuf2 != NULL, "VirtualAlloc failed err %u\n", GetLastError() ); + memset( &ovl, 0, sizeof(ovl) ); ovl.hEvent = evt; memset( fse, 0, sizeof(fse) ); @@ -4461,6 +4464,34 @@ static void test_WriteFileGather(void)
ResetEvent( evt );
+ /* read past EOF */ + memset( &ovl, 0, sizeof(ovl) ); + ovl.hEvent = evt; + memset( fse, 0, sizeof(fse) ); + fse[0].Buffer = rbuf1; + fse[1].Buffer = rbuf2; + memset( rbuf1, 0, si.dwPageSize ); + memset( rbuf2, 0x17, si.dwPageSize ); + SetLastError( 0xdeadbeef ); + br = ReadFileScatter( hfile, fse, si.dwPageSize * 2, NULL, &ovl ); + ok( br == FALSE, "ReadFileScatter should be asynchronous\n" ); + ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() ); + + ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); + ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError() ); + ok( povl == &ovl, "wrong ovl %p\n", povl ); + + tx = 0; + br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); + ok( br == TRUE, "GetOverlappedResult failed: %u\n", GetLastError() ); + ok( tx == si.dwPageSize, "got unexpected bytes transferred: %u\n", tx ); + + ok( memcmp( rbuf1, wbuf, si.dwPageSize ) == 0, + "data was not read into buffer\n" ); + memset( rbuf1, 0x17, si.dwPageSize ); + ok( memcmp( rbuf2, rbuf1, si.dwPageSize ) == 0, + "data should not have been read into buffer\n" ); + CloseHandle( hfile ); CloseHandle( hiocp1 ); CloseHandle( hiocp2 ); @@ -4481,6 +4512,7 @@ static void test_WriteFileGather(void)
VirtualFree( wbuf, 0, MEM_RELEASE ); VirtualFree( rbuf1, 0, MEM_RELEASE ); + VirtualFree( rbuf2, 0, MEM_RELEASE ); CloseHandle( evt ); DeleteFileA( filename ); } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 9df15ffe1d..3d4a94923b 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1070,11 +1070,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap status = FILE_GetNtStatus(); break; } - if (!result) - { - status = STATUS_END_OF_FILE; - break; - } + if (!result) break; total += result; length -= result; if ((pos += result) == page_size) @@ -1084,6 +1080,8 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap } }
+ if (total == 0) status = STATUS_END_OF_FILE; + send_completion = cvalue != 0;
if (needs_close) close( unix_handle );