Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ntdll/unix/socket.c | 27 +++++++++++++++++++++------ dlls/ws2_32/socket.c | 4 ++-- include/wine/afd.h | 11 +++++++++-- 3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 6b4b4a9b3f8..9b40dd30f25 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1003,7 +1003,7 @@ 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 WSABUF *buffers, unsigned int count, + 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; @@ -1019,10 +1019,25 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi return STATUS_NO_MEMORY;
async->count = count; - for (i = 0; i < count; ++i) + if (in_wow64_call()) { - async->iov[i].iov_base = buffers[i].buf; - async->iov[i].iov_len = buffers[i].len; + 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; @@ -1463,8 +1478,8 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc 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, params->buffers, params->count, - params->addr, params->addr_len, unix_flags, params->force_async ); + 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 ); break; }
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 33df823b213..e95a9669656 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -992,12 +992,12 @@ static int WS2_sendto( SOCKET s, WSABUF *buffers, DWORD buffer_count, DWORD *ret apc = socket_apc; }
- params.addr = addr; + params.addr_ptr = u64_from_user_ptr( addr ); params.addr_len = addr_len; params.ws_flags = flags; params.force_async = !!overlapped; params.count = buffer_count; - params.buffers = buffers; + params.buffers_ptr = u64_from_user_ptr( buffers );
status = NtDeviceIoControlFile( (HANDLE)s, event, apc, cvalue, piosb, IOCTL_AFD_WINE_SENDMSG, ¶ms, sizeof(params), NULL, 0 ); diff --git a/include/wine/afd.h b/include/wine/afd.h index 7db429c2b79..ee67e255dd0 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -256,6 +256,12 @@ C_ASSERT( sizeof(struct afd_get_events_params) == 56 ); #define IOCTL_AFD_WINE_GET_IP_RECVTOS WINE_AFD_IOC(295) #define IOCTL_AFD_WINE_SET_IP_RECVTOS WINE_AFD_IOC(296)
+struct afd_iovec +{ + ULONGLONG ptr; + ULONG len; +}; + struct afd_create_params { int family, type, protocol; @@ -293,13 +299,14 @@ C_ASSERT( sizeof(struct afd_recvmsg_params) == 48 );
struct afd_sendmsg_params { - const struct WS(sockaddr) *addr; + ULONGLONG addr_ptr; /* const struct WS(sockaddr) */ unsigned int addr_len; unsigned int ws_flags; int force_async; unsigned int count; - const WSABUF *buffers; + ULONGLONG buffers_ptr; /* const WSABUF[] */ }; +C_ASSERT( sizeof(struct afd_sendmsg_params) == 32 );
struct afd_transmit_params {