[PATCH v4 2/3] ntdll: Don't return an error when reading past EOF in NtReadFileScatter
Andrew Eikum
aeikum at codeweavers.com
Wed Dec 6 15:07:54 CST 2017
Signed-off-by: Andrew Eikum <aeikum at 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 );
--
2.15.1
More information about the wine-devel
mailing list