From: Elizabeth Figura zfigura@codeweavers.com
The only cases this affects are Wine-internal sockopt ioctls, and ws2_32 does not read back the IOSB status for those. --- dlls/ntdll/unix/socket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 587faf51ccf..78f24a081c3 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1485,6 +1485,10 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc TRACE( "handle %p, code %#x, in_buffer %p, in_size %u, out_buffer %p, out_size %u\n", handle, code, in_buffer, in_size, out_buffer, out_size );
+ /* many of the below internal codes return success but don't completely + * fill the iosb or signal completion; such sockopts are only called + * synchronously by ws2_32 */ + switch (code) { case IOCTL_AFD_BIND: @@ -2528,7 +2532,5 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
if (needs_close) close( fd );
- if (status != STATUS_PENDING && !NT_ERROR(status)) io->Status = status; - return status; }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ntdll/unix/serial.c | 6 ++---- dlls/ntdll/unix/socket.c | 26 +++----------------------- dlls/ntdll/unix/sync.c | 9 ++++++++- dlls/ntdll/unix/unix_private.h | 3 ++- 4 files changed, 15 insertions(+), 29 deletions(-)
diff --git a/dlls/ntdll/unix/serial.c b/dlls/ntdll/unix/serial.c index cc3929c7a0b..8637dfbd447 100644 --- a/dlls/ntdll/unix/serial.c +++ b/dlls/ntdll/unix/serial.c @@ -1202,15 +1202,13 @@ static NTSTATUS wait_on( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE ap if (events) { status = STATUS_SUCCESS; - io->Status = STATUS_SUCCESS; - io->Information = sizeof(events); *out_buffer = events; - set_async_direct_result( &wait_handle, STATUS_SUCCESS, sizeof(events), FALSE ); + set_async_direct_result( &wait_handle, io, STATUS_SUCCESS, sizeof(events), FALSE ); } else { status = STATUS_PENDING; - set_async_direct_result( &wait_handle, STATUS_PENDING, 0, TRUE ); + set_async_direct_result( &wait_handle, io, STATUS_PENDING, 0, TRUE ); } }
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 78f24a081c3..b10d51f3c60 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -875,12 +875,7 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi status = try_recv( fd, async, &information ); if (status == STATUS_DEVICE_NOT_READY && (force_async || !nonblocking)) status = STATUS_PENDING; - if (!NT_ERROR(status) && status != STATUS_PENDING) - { - io->Status = status; - io->Information = information; - } - set_async_direct_result( &wait_handle, status, information, FALSE ); + set_async_direct_result( &wait_handle, io, status, information, FALSE ); }
if (status != STATUS_PENDING) @@ -1125,8 +1120,6 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
if (status == STATUS_ALERTED) { - ULONG_PTR information; - status = try_send( fd, async ); if (status == STATUS_DEVICE_NOT_READY && (force_async || !nonblocking)) status = STATUS_PENDING; @@ -1138,14 +1131,7 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi if (status == STATUS_DEVICE_NOT_READY && async->sent_len) status = STATUS_SUCCESS;
- information = async->sent_len; - if (!NT_ERROR(status) && status != STATUS_PENDING) - { - io->Status = status; - io->Information = information; - } - - set_async_direct_result( &wait_handle, status, information, FALSE ); + set_async_direct_result( &wait_handle, io, status, async->sent_len, FALSE ); }
if (status != STATUS_PENDING) @@ -1401,13 +1387,7 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, status = STATUS_PENDING;
information = async->head_cursor + async->file_cursor + async->tail_cursor; - if (!NT_ERROR(status) && status != STATUS_PENDING) - { - io->Status = status; - io->Information = information; - } - - set_async_direct_result( &wait_handle, status, information, TRUE ); + set_async_direct_result( &wait_handle, io, status, information, TRUE ); }
if (status != STATUS_PENDING) diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 4b2d7c1ccbc..326e6e7734e 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -2669,13 +2669,20 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
/* Notify direct completion of async and close the wait handle if it is no longer needed. */ -void set_async_direct_result( HANDLE *async_handle, NTSTATUS status, ULONG_PTR information, BOOL mark_pending ) +void set_async_direct_result( HANDLE *async_handle, IO_STATUS_BLOCK *io, + NTSTATUS status, ULONG_PTR information, BOOL mark_pending ) { unsigned int ret;
/* if we got STATUS_ALERTED, we must have a valid async handle */ assert( *async_handle );
+ if (!NT_ERROR(status) && status != STATUS_PENDING) + { + io->Status = status; + io->Information = information; + } + SERVER_START_REQ( set_async_direct_result ) { req->handle = wine_server_obj_handle( *async_handle ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index fcb3de83a29..c00b0e4b602 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -344,7 +344,8 @@ extern void init_files(void); extern void init_cpu_info(void); extern void file_complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information ); -extern void set_async_direct_result( HANDLE *async_handle, NTSTATUS status, ULONG_PTR information, BOOL mark_pending ); +extern void set_async_direct_result( HANDLE *async_handle, IO_STATUS_BLOCK *io, + NTSTATUS status, ULONG_PTR information, BOOL mark_pending );
extern NTSTATUS unixcall_wine_dbg_write( void *args ); extern NTSTATUS unixcall_wine_server_call( void *args );
From: Elizabeth Figura zfigura@codeweavers.com
Similar helpers are in file.c, and sync.c has nothing to do with file I/O otherwise. --- dlls/ntdll/unix/file.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/unix/sync.c | 34 ---------------------------------- 2 files changed, 31 insertions(+), 34 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index b8fb4f19e13..2ce38b34158 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -5484,6 +5484,37 @@ static void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULO SERVER_END_REQ; }
+/* notify direct completion of async and close the wait handle if it is no longer needed */ +void set_async_direct_result( HANDLE *async_handle, IO_STATUS_BLOCK *io, + NTSTATUS status, ULONG_PTR information, BOOL mark_pending ) +{ + unsigned int ret; + + /* if we got STATUS_ALERTED, we must have a valid async handle */ + assert( *async_handle ); + + if (!NT_ERROR(status) && status != STATUS_PENDING) + { + io->Status = status; + io->Information = information; + } + + SERVER_START_REQ( set_async_direct_result ) + { + req->handle = wine_server_obj_handle( *async_handle ); + req->status = status; + req->information = information; + req->mark_pending = mark_pending; + ret = wine_server_call( req ); + if (ret == STATUS_SUCCESS) + *async_handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + if (ret != STATUS_SUCCESS) + ERR( "cannot report I/O result back to server: %#x\n", ret ); +} + /* complete async file I/O, signaling completion in all ways necessary */ void file_complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information ) diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 326e6e7734e..1d66f0d974f 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -2667,40 +2667,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
#endif
-/* Notify direct completion of async and close the wait handle if it is no longer needed. - */ -void set_async_direct_result( HANDLE *async_handle, IO_STATUS_BLOCK *io, - NTSTATUS status, ULONG_PTR information, BOOL mark_pending ) -{ - unsigned int ret; - - /* if we got STATUS_ALERTED, we must have a valid async handle */ - assert( *async_handle ); - - if (!NT_ERROR(status) && status != STATUS_PENDING) - { - io->Status = status; - io->Information = information; - } - - SERVER_START_REQ( set_async_direct_result ) - { - req->handle = wine_server_obj_handle( *async_handle ); - req->status = status; - req->information = information; - req->mark_pending = mark_pending; - ret = wine_server_call( req ); - if (ret == STATUS_SUCCESS) - *async_handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; - - if (ret != STATUS_SUCCESS) - ERR( "cannot report I/O result back to server: %08x\n", ret ); - - return; -} - /*********************************************************************** * NtCreateTransaction (NTDLL.@) */