Commit cb893780 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

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.
parent 9783e2e1
......@@ -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 );
......
......@@ -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;
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment