Signed-off-by: Andrew Eikum aeikum@codeweavers.com ---
v3: Always SetLastError before checking GLE return.
dlls/kernel32/tests/file.c | 28 +++++++++++++++++++++++++++- dlls/ntdll/file.c | 8 +++----- 2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index a8d229c887..28d11a4fd3 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;
ret = GetTempPathA( MAX_PATH, temp_path ); @@ -4378,6 +4378,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) ); memset( fse, 0, sizeof(fse) ); memset( wbuf, 0x42, si.dwPageSize ); @@ -4435,11 +4438,34 @@ static void test_WriteFileGather(void) ok( povl == NULL, "wrong ovl %p\n", povl ); }
+ /* read past EOF */ + memset( &ovl, 0, sizeof(ovl) ); + 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 ); + + 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 ); VirtualFree( wbuf, 0, MEM_RELEASE ); VirtualFree( rbuf1, 0, MEM_RELEASE ); + VirtualFree( rbuf2, 0, MEM_RELEASE ); DeleteFileA( filename ); }
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 12b1d0f6c5..6c3b571638 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;
error: