Zebediah Figura : ntdll: Use the send_socket request for NtWriteFile() on a socket.
Alexandre Julliard
julliard at winehq.org
Thu Jul 14 16:59:25 CDT 2022
Module: wine
Branch: master
Commit: cb8937801d42417c2b98cba15366ccc154c1cc40
URL: https://gitlab.winehq.org/wine/wine/-/commit/cb8937801d42417c2b98cba15366ccc154c1cc40
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Sun May 29 16:51:00 2022 -0500
ntdll: Use the send_socket request for NtWriteFile() on a socket.
send_socket does some extra bookkeeping that's currently missing from the
register_async path. Instead of adding it to sock_queue_async(), let's just
centralize all send requests so that they go through send_socket.
---
dlls/ntdll/unix/file.c | 10 +++-
dlls/ntdll/unix/socket.c | 111 ++++++++++++++++++++++++++---------------
dlls/ntdll/unix/unix_private.h | 2 +
3 files changed, 81 insertions(+), 42 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index f57532f55bf..738367dbb57 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -4768,7 +4768,7 @@ static BOOL async_write_proc( void *user, ULONG_PTR *info, NTSTATUS *status )
&needs_close, &type, NULL )))
break;
- if (!fileio->count && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_SOCKET))
+ if (!fileio->count && type == FD_TYPE_MAILSLOT)
result = send( fd, fileio->buffer, 0, 0 );
else
result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already );
@@ -5498,11 +5498,17 @@ NTSTATUS WINAPI NtWriteFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, v
goto done;
}
}
+ else if (type == FD_TYPE_SOCKET)
+ {
+ status = sock_write( handle, unix_handle, event, apc, apc_user, io, buffer, length );
+ if (needs_close) close( unix_handle );
+ return status;
+ }
for (;;)
{
/* zero-length writes on sockets may not work with plain write(2) */
- if (!length && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_SOCKET))
+ if (!length && type == FD_TYPE_MAILSLOT)
result = send( unix_handle, buffer, 0, 0 );
else
result = write( unix_handle, (const char *)buffer + total, length - total );
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 6abee680ee5..ef3c8494c3d 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -895,49 +895,13 @@ static BOOL async_send_proc( void *user, ULONG_PTR *info, NTSTATUS *status )
}
static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
- IO_STATUS_BLOCK *io, int fd, const void *buffers_ptr, unsigned int count,
- const struct WS_sockaddr *addr, unsigned int addr_len, int unix_flags, int force_async )
+ IO_STATUS_BLOCK *io, int fd, struct async_send_ioctl *async, int force_async )
{
- struct async_send_ioctl *async;
+ BOOL nonblocking, alerted;
ULONG_PTR information;
HANDLE wait_handle;
- DWORD async_size;
NTSTATUS status;
- unsigned int i;
ULONG options;
- BOOL nonblocking, alerted;
-
- async_size = offsetof( struct async_send_ioctl, iov[count] );
-
- if (!(async = (struct async_send_ioctl *)alloc_fileio( async_size, async_send_proc, handle )))
- return STATUS_NO_MEMORY;
-
- async->count = count;
- if (in_wow64_call())
- {
- const struct afd_wsabuf_32 *buffers = buffers_ptr;
-
- for (i = 0; i < count; ++i)
- {
- async->iov[i].iov_base = ULongToPtr( buffers[i].buf );
- async->iov[i].iov_len = buffers[i].len;
- }
- }
- else
- {
- const WSABUF *buffers = buffers_ptr;
-
- for (i = 0; i < count; ++i)
- {
- async->iov[i].iov_base = buffers[i].buf;
- async->iov[i].iov_len = buffers[i].len;
- }
- }
- async->unix_flags = unix_flags;
- async->addr = addr;
- async->addr_len = addr_len;
- async->iov_cursor = 0;
- async->sent_len = 0;
SERVER_START_REQ( send_socket )
{
@@ -982,6 +946,72 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
return status;
}
+static NTSTATUS sock_ioctl_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
+ IO_STATUS_BLOCK *io, int fd, const void *buffers_ptr, unsigned int count,
+ const struct WS_sockaddr *addr, unsigned int addr_len, int unix_flags, int force_async )
+{
+ struct async_send_ioctl *async;
+ DWORD async_size;
+ unsigned int i;
+
+ async_size = offsetof( struct async_send_ioctl, iov[count] );
+
+ if (!(async = (struct async_send_ioctl *)alloc_fileio( async_size, async_send_proc, handle )))
+ return STATUS_NO_MEMORY;
+
+ async->count = count;
+ if (in_wow64_call())
+ {
+ const struct afd_wsabuf_32 *buffers = buffers_ptr;
+
+ for (i = 0; i < count; ++i)
+ {
+ async->iov[i].iov_base = ULongToPtr( buffers[i].buf );
+ async->iov[i].iov_len = buffers[i].len;
+ }
+ }
+ else
+ {
+ const WSABUF *buffers = buffers_ptr;
+
+ for (i = 0; i < count; ++i)
+ {
+ async->iov[i].iov_base = buffers[i].buf;
+ async->iov[i].iov_len = buffers[i].len;
+ }
+ }
+ async->unix_flags = unix_flags;
+ async->addr = addr;
+ async->addr_len = addr_len;
+ async->iov_cursor = 0;
+ async->sent_len = 0;
+
+ return sock_send( handle, event, apc, apc_user, io, fd, async, force_async );
+}
+
+
+NTSTATUS sock_write( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE apc,
+ void *apc_user, IO_STATUS_BLOCK *io, const void *buffer, ULONG length )
+{
+ static const DWORD async_size = offsetof( struct async_send_ioctl, iov[1] );
+ struct async_send_ioctl *async;
+
+ if (!(async = (struct async_send_ioctl *)alloc_fileio( async_size, async_recv_proc, handle )))
+ return STATUS_NO_MEMORY;
+
+ async->count = 1;
+ async->iov[0].iov_base = (void *)buffer;
+ async->iov[0].iov_len = length;
+ async->unix_flags = 0;
+ async->addr = NULL;
+ async->addr_len = 0;
+ async->iov_cursor = 0;
+ async->sent_len = 0;
+
+ return sock_send( handle, event, apc, apc_user, io, fd, async, 1 );
+}
+
+
static ssize_t do_send( int fd, const void *buffer, size_t len, int flags )
{
ssize_t ret;
@@ -1420,8 +1450,9 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
WARN( "ignoring MSG_PARTIAL\n" );
if (params->ws_flags & ~(WS_MSG_OOB | WS_MSG_PARTIAL))
FIXME( "unknown flags %#x\n", params->ws_flags );
- status = sock_send( handle, event, apc, apc_user, io, fd, u64_to_user_ptr( params->buffers_ptr ), params->count,
- u64_to_user_ptr( params->addr_ptr ), params->addr_len, unix_flags, params->force_async );
+ status = sock_ioctl_send( handle, event, apc, apc_user, io, fd, u64_to_user_ptr( params->buffers_ptr ),
+ params->count, u64_to_user_ptr( params->addr_ptr ), params->addr_len,
+ unix_flags, params->force_async );
if (needs_close) close( fd );
return status;
}
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 8d305bdada6..47f0f9c56a9 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -258,6 +258,8 @@ extern NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
ULONG code, void *in_buffer, ULONG in_size, void *out_buffer, ULONG out_size ) DECLSPEC_HIDDEN;
extern NTSTATUS sock_read( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
IO_STATUS_BLOCK *io, void *buffer, ULONG length ) DECLSPEC_HIDDEN;
+extern NTSTATUS sock_write( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
+ IO_STATUS_BLOCK *io, const void *buffer, ULONG length ) DECLSPEC_HIDDEN;
extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
IO_STATUS_BLOCK *io, ULONG code, void *in_buffer,
ULONG in_size, void *out_buffer, ULONG out_size ) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list