Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - Pass real status (not ret_status) to NTDLL_AddCompletion() in NtReadFile(). v3: - pass FALSE instead of 'status == STATUS_PENDING' to NTDLL_AddCompletion().
dlls/kernel32/tests/file.c | 4 ++-- dlls/ntdll/file.c | 17 +++++++++-------- dlls/ntdll/ntdll_misc.h | 2 +- dlls/ntdll/sync.c | 3 ++- dlls/ntdll/tests/file.c | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index dd84557238..33b17aa327 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4577,8 +4577,8 @@ static void test_WriteFileGather(void) ok(GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed, error %u.\n", GetLastError());
br = GetQueuedCompletionStatus(hiocp2, &size, &key, &povl, 1000); - todo_wine ok(br, "GetQueuedCompletionStatus failed, err %u.\n", GetLastError()); - todo_wine ok(povl == &ovl, "Wrong ovl %p.\n", povl); + ok(br, "GetQueuedCompletionStatus failed, err %u.\n", GetLastError()); + ok(povl == &ovl, "Wrong ovl %p.\n", povl);
br = GetOverlappedResult(hfile, &ovl, &tx, TRUE); ok(br, "GetOverlappedResult failed, err %u.\n", GetLastError()); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 1cf3ae2d05..ffedbeb534 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -831,7 +831,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, int result, unix_handle, needs_close; unsigned int options; struct io_timeouts timeouts; - NTSTATUS status; + NTSTATUS status, ret_status; ULONG total = 0; enum server_fd_type type; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; @@ -1013,10 +1013,11 @@ err: if (status != STATUS_PENDING && hEvent) NtResetEvent( hEvent, NULL ); }
- if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total ); - if (async_read && (options & FILE_NO_INTERMEDIATE_BUFFERING) && status == STATUS_SUCCESS) - return STATUS_PENDING; - return status; + ret_status = async_read && (options & FILE_NO_INTERMEDIATE_BUFFERING) && status == STATUS_SUCCESS + ? STATUS_PENDING : status; + + if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total, ret_status == STATUS_PENDING ); + return ret_status; }
@@ -1089,7 +1090,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap if (event) NtSetEvent( event, NULL ); if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 ); - if (send_completion) NTDLL_AddCompletion( file, cvalue, status, total ); + if (send_completion) NTDLL_AddCompletion( file, cvalue, status, total, TRUE );
return STATUS_PENDING;
@@ -1408,7 +1409,7 @@ err: if (status != STATUS_PENDING && hEvent) NtResetEvent( hEvent, NULL ); }
- if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total ); + if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total, FALSE );
return status; } @@ -1500,7 +1501,7 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap if (status != STATUS_PENDING && event) NtResetEvent( event, NULL ); }
- if (send_completion) NTDLL_AddCompletion( file, cvalue, status, total ); + if (send_completion) NTDLL_AddCompletion( file, cvalue, status, total, FALSE );
return status; } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 6a54fafc7e..084c5123c3 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -197,7 +197,7 @@ extern BYTE* CDECL __wine_user_shared_data(void);
/* completion */ extern NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, - NTSTATUS CompletionStatus, ULONG Information ) DECLSPEC_HIDDEN; + NTSTATUS CompletionStatus, ULONG Information, BOOL async) DECLSPEC_HIDDEN;
/* code pages */ extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 3293c52859..cc70fde2b3 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -1529,7 +1529,7 @@ NTSTATUS WINAPI NtQueryIoCompletion( HANDLE CompletionPort, IO_COMPLETION_INFORM }
NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, - NTSTATUS CompletionStatus, ULONG Information ) + NTSTATUS CompletionStatus, ULONG Information, BOOL async ) { NTSTATUS status;
@@ -1539,6 +1539,7 @@ NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, req->cvalue = CompletionValue; req->status = CompletionStatus; req->information = Information; + req->async = async; status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 1c1143fdab..3320ccecfa 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3579,7 +3579,7 @@ static void test_file_completion_information(void) ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE); ok(ret, "GetOverlappedResult failed, error %u.\n", GetLastError()); ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); - todo_wine ok(ret, "GetQueuedCompletionStatus failed, error %u.\n", GetLastError()); + ok(ret, "GetQueuedCompletionStatus failed, error %u.\n", GetLastError());
CloseHandle(ov.hEvent); CloseHandle(port);