Commit b0d3b5b6 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Return STATUS_PENDING from NtReadFile() for async read in case of EOF.

Fixes crashes in "Planet Zoo" during character or game save. Signed-off-by: 's avatarPaul Gofman <pgofman@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 18590bb2
...@@ -1018,13 +1018,13 @@ done: ...@@ -1018,13 +1018,13 @@ done:
err: err:
if (needs_close) close( unix_handle ); if (needs_close) close( unix_handle );
if (status == STATUS_SUCCESS || (status == STATUS_END_OF_FILE && !async_read)) if (status == STATUS_SUCCESS || (status == STATUS_END_OF_FILE && (!async_read || type == FD_TYPE_FILE)))
{ {
io_status->u.Status = status; io_status->u.Status = status;
io_status->Information = total; io_status->Information = total;
TRACE("= SUCCESS (%u)\n", total); TRACE("= SUCCESS (%u)\n", total);
if (hEvent) NtSetEvent( hEvent, NULL ); if (hEvent) NtSetEvent( hEvent, NULL );
if (apc && !status) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, if (apc && (!status || async_read)) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc,
(ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 ); (ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 );
} }
else else
...@@ -1033,7 +1033,7 @@ err: ...@@ -1033,7 +1033,7 @@ err:
if (status != STATUS_PENDING && hEvent) NtResetEvent( hEvent, NULL ); if (status != STATUS_PENDING && hEvent) NtResetEvent( hEvent, NULL );
} }
ret_status = async_read && type == FD_TYPE_FILE && status == STATUS_SUCCESS ret_status = async_read && type == FD_TYPE_FILE && (status == STATUS_SUCCESS || status == STATUS_END_OF_FILE)
? STATUS_PENDING : status; ? STATUS_PENDING : status;
if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total, ret_status == STATUS_PENDING ); if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total, ret_status == STATUS_PENDING );
......
...@@ -652,7 +652,8 @@ static void read_file_test(void) ...@@ -652,7 +652,8 @@ static void read_file_test(void)
iosb.Information = 0xdeadbeef; iosb.Information = 0xdeadbeef;
offset.QuadPart = strlen(text) + 2; offset.QuadPart = strlen(text) + 2;
status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL ); status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL );
ok(status == STATUS_PENDING || status == STATUS_END_OF_FILE /* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status); ok(status == STATUS_PENDING || broken(status == STATUS_END_OF_FILE) /* before Vista */,
"expected STATUS_PENDING, got %#x\n", status);
if (status == STATUS_PENDING) /* vista */ if (status == STATUS_PENDING) /* vista */
{ {
WaitForSingleObject( event, 1000 ); WaitForSingleObject( event, 1000 );
...@@ -4540,7 +4541,8 @@ static void test_read_write(void) ...@@ -4540,7 +4541,8 @@ static void test_read_write(void)
ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
ok(!ret, "ReadFile should fail\n"); ok(!ret, "ReadFile should fail\n");
ret = GetLastError(); ret = GetLastError();
ok(ret == ERROR_IO_PENDING || ret == ERROR_HANDLE_EOF /* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret); ok(ret == ERROR_IO_PENDING || broken(ret == ERROR_HANDLE_EOF) /* before Vista */,
"expected ERROR_IO_PENDING, got %d\n", ret);
ok(bytes == 0, "bytes %u\n", bytes); ok(bytes == 0, "bytes %u\n", bytes);
off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment