This patch sequence fixes Wolfenstein II, Bug 43935.
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/kernel32/tests/file.c | 28 ++++++++++++++++++++--------
dlls/ntdll/file.c | 4 +++-
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index 0b8cef23f8..44fbf7a4b1 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -4353,7 +4353,8 @@ static void test_WriteFileGather(void)
FILE_SEGMENT_ELEMENT fse[2];
OVERLAPPED ovl, *povl = NULL;
SYSTEM_INFO si;
- LPVOID buf = NULL;
+ BOOL br;
+ char *wbuf = NULL, *rbuf1;
ret = GetTempPathA( MAX_PATH, temp_path );
ok( ret != 0, "GetTempPathA error %d\n", GetLastError() );
@@ -4371,12 +4372,16 @@ static void test_WriteFileGather(void)
ok( hiocp2 != 0, "CreateIoCompletionPort failed err %u\n", GetLastError() );
GetSystemInfo( &si );
- buf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
- ok( buf != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
+ wbuf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
+ ok( wbuf != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
+
+ rbuf1 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
+ ok( rbuf1 != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
memset( &ovl, 0, sizeof(ovl) );
memset( fse, 0, sizeof(fse) );
- fse[0].Buffer = buf;
+ memset( wbuf, 0x42, si.dwPageSize );
+ fse[0].Buffer = wbuf;
if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl ))
ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %u\n", GetLastError() );
@@ -4384,20 +4389,27 @@ static void test_WriteFileGather(void)
ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
ok( povl == &ovl, "wrong ovl %p\n", povl );
+ /* read exact size */
memset( &ovl, 0, sizeof(ovl) );
memset( fse, 0, sizeof(fse) );
- fse[0].Buffer = buf;
- if (!ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ))
- ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() );
+ fse[0].Buffer = rbuf1;
+ memset( rbuf1, 0, si.dwPageSize );
+ br = ReadFileScatter( hfile, fse, si.dwPageSize, 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" );
+
CloseHandle( hfile );
CloseHandle( hiocp1 );
CloseHandle( hiocp2 );
- VirtualFree( buf, 0, MEM_RELEASE );
+ VirtualFree( wbuf, 0, MEM_RELEASE );
+ VirtualFree( rbuf1, 0, MEM_RELEASE );
DeleteFileA( filename );
}
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index ca2afa0e89..bdfc383d7e 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1090,7 +1090,9 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
if (needs_close) close( unix_handle );
if (status == STATUS_SUCCESS)
{
- io_status->u.Status = status;
+ /* report status asynchronously */
+ status = STATUS_PENDING;
+ io_status->u.Status = STATUS_SUCCESS;
io_status->Information = total;
TRACE("= SUCCESS (%u)\n", total);
if (event) NtSetEvent( event, NULL );
--
2.15.0