Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43071 Signed-off-by: Paul Gofman gofmanp@gmail.com --- After running grep for ReadFile over the source tree and sorting out ReadFile() calls with explicit NULL for overlapped structure or NtReadFile() calls with NULL offset, the following remains:
dlls/user.exe16/comm.c: Calls ReadFileEx() in comm_waitread() on a device file, doesn't check any status and relies on completion routine.
dlls/winemac.drv/clipboard.c: Calls ReadFile() on pipe, handles possible outputs.
dlls/quartz/filesource.c: Calls ReadFile() in FileAsyncReader_Request() to queue read request, does not record the difference between sync or async result. Leaves FileAsyncReader_WaitForNext() to deal with waits and calling GetOverlappedResult(). I did not unwind the whole logic behind waits and condition for calling GetOverlappedResult(), but since GetOverlappedResult() is the only way it uses to get the actual read status and number of bytes read, I suppose it has no reason to suffer from async return status. Actually the sync result looks a bit more problematic in theory: GetOverlappedResult() after sync result would hang on Windows (while does not hang under Wine as file handles are always signalled).
dlls/quartz/filesource.c: sync_read(): Calls ReadFile() on pipe and GetOverlappedResult() in case of sync return or ERROR_IO_PENDING.
programs/services/rpc.c: Calls ReadFile() on pipe for overlapped read in process_send_command(), processes async result.
dlls/ntdll/file.c | 2 +- dlls/ntdll/tests/file.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 7ecde56669..e8775a3c64 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1013,7 +1013,7 @@ err: if (status != STATUS_PENDING && hEvent) NtResetEvent( hEvent, NULL ); }
- ret_status = async_read && (options & FILE_NO_INTERMEDIATE_BUFFERING) && status == STATUS_SUCCESS + ret_status = async_read && type == FD_TYPE_FILE && status == STATUS_SUCCESS ? STATUS_PENDING : status;
if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total, ret_status == STATUS_PENDING ); diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 5058439953..d107c2ed2b 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -635,7 +635,7 @@ static void read_file_test(void) offset.QuadPart = 0; ResetEvent( event ); status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL ); - todo_wine ok(status == STATUS_PENDING + ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */, "wrong status %x.\n", status); if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); @@ -4450,7 +4450,7 @@ static void test_read_write(void) bytes = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(hfile, buf, 0, &bytes, &ovl); - todo_wine ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, + ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, "Unexpected result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); ret = GetLastError(); ok(bytes == 0, "bytes %u\n", bytes); @@ -4479,7 +4479,7 @@ static void test_read_write(void) bytes = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(hfile, NULL, 0, &bytes, &ovl); - todo_wine ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, + ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, "Unexpected result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); ret = GetLastError(); ok(bytes == 0, "bytes %u\n", bytes); @@ -4524,7 +4524,7 @@ static void test_read_write(void) iob.Information = -1; offset.QuadPart = sizeof(contents); status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL); - todo_wine ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */, + ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */, "expected STATUS_PENDING, got %#x.\n", status); if (status == STATUS_PENDING) { @@ -4550,7 +4550,7 @@ static void test_read_write(void) bytes = 0; SetLastError(0xdeadbeef); ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); - todo_wine ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, + ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, "Unexpected result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); if (!ret) ok(bytes == 0, "bytes %u\n", bytes); @@ -4598,7 +4598,7 @@ static void test_read_write(void) iob.Information = -1; offset.QuadPart = 0; status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); - todo_wine ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */, + ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */, "expected STATUS_PENDING, got %#x.\n", status); if (status == STATUS_PENDING) { @@ -4658,7 +4658,7 @@ static void test_read_write(void) bytes = 0; SetLastError(0xdeadbeef); ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); - todo_wine ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, + ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */, "Unexpected result %#x, GetLastError() %u.\n", ret, GetLastError()); if (!ret) {