ntdll: Add a helper function to get the iosb pointer to pass to the server.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-08-05 17:42:57 +02:00
parent 460755a007
commit 156c34ea03
3 changed files with 36 additions and 28 deletions

View File

@ -4811,7 +4811,7 @@ static NTSTATUS server_read_file( HANDLE handle, HANDLE event, PIO_APC_ROUTINE a
SERVER_START_REQ( read ) SERVER_START_REQ( read )
{ {
req->async = server_async( handle, &async->io, event, apc, apc_context, io ); req->async = server_async( handle, &async->io, event, apc, apc_context, iosb_client_ptr(io) );
req->pos = offset ? offset->QuadPart : 0; req->pos = offset ? offset->QuadPart : 0;
wine_server_set_reply( req, buffer, size ); wine_server_set_reply( req, buffer, size );
status = virtual_locked_server_call( req ); status = virtual_locked_server_call( req );
@ -4849,7 +4849,7 @@ static NTSTATUS server_write_file( HANDLE handle, HANDLE event, PIO_APC_ROUTINE
SERVER_START_REQ( write ) SERVER_START_REQ( write )
{ {
req->async = server_async( handle, &async->io, event, apc, apc_context, io ); req->async = server_async( handle, &async->io, event, apc, apc_context, iosb_client_ptr(io) );
req->pos = offset ? offset->QuadPart : 0; req->pos = offset ? offset->QuadPart : 0;
wine_server_add_data( req, buffer, size ); wine_server_add_data( req, buffer, size );
status = wine_server_call( req ); status = wine_server_call( req );
@ -4889,7 +4889,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
SERVER_START_REQ( ioctl ) SERVER_START_REQ( ioctl )
{ {
req->code = code; req->code = code;
req->async = server_async( handle, &async->io, event, apc, apc_context, io ); req->async = server_async( handle, &async->io, event, apc, apc_context, iosb_client_ptr(io) );
wine_server_add_data( req, in_buffer, in_size ); wine_server_add_data( req, in_buffer, in_size );
if ((code & 3) != METHOD_BUFFERED) wine_server_add_data( req, out_buffer, out_size ); if ((code & 3) != METHOD_BUFFERED) wine_server_add_data( req, out_buffer, out_size );
wine_server_set_reply( req, out_buffer, out_size ); wine_server_set_reply( req, out_buffer, out_size );
@ -5048,7 +5048,7 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL
/* register an async I/O for a file read; helper for NtReadFile */ /* register an async I/O for a file read; helper for NtReadFile */
static NTSTATUS register_async_file_read( HANDLE handle, HANDLE event, static NTSTATUS register_async_file_read( HANDLE handle, HANDLE event,
PIO_APC_ROUTINE apc, void *apc_user, PIO_APC_ROUTINE apc, void *apc_user,
IO_STATUS_BLOCK *iosb, void *buffer, client_ptr_t iosb, void *buffer,
ULONG already, ULONG length, BOOL avail_mode ) ULONG already, ULONG length, BOOL avail_mode )
{ {
struct async_fileio_read *fileio; struct async_fileio_read *fileio;
@ -5116,6 +5116,7 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
struct io_timeouts timeouts; struct io_timeouts timeouts;
NTSTATUS status, ret_status; NTSTATUS status, ret_status;
ULONG total = 0; ULONG total = 0;
client_ptr_t iosb_ptr = iosb_client_ptr(io);
enum server_fd_type type; enum server_fd_type type;
ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
BOOL send_completion = FALSE, async_read, timeout_init_done = FALSE; BOOL send_completion = FALSE, async_read, timeout_init_done = FALSE;
@ -5179,7 +5180,7 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
if ((status = get_io_timeouts( handle, type, length, TRUE, &timeouts ))) goto err; if ((status = get_io_timeouts( handle, type, length, TRUE, &timeouts ))) goto err;
if (timeouts.interval) if (timeouts.interval)
{ {
status = register_async_file_read( handle, event, apc, apc_user, io, status = register_async_file_read( handle, event, apc, apc_user, iosb_ptr,
buffer, total, length, FALSE ); buffer, total, length, FALSE );
goto err; goto err;
} }
@ -5235,7 +5236,7 @@ NTSTATUS WINAPI NtReadFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, vo
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
goto done; goto done;
} }
status = register_async_file_read( handle, event, apc, apc_user, io, status = register_async_file_read( handle, event, apc, apc_user, iosb_ptr,
buffer, total, length, avail_mode ); buffer, total, length, avail_mode );
goto err; goto err;
} }
@ -5284,7 +5285,7 @@ err:
TRACE("= SUCCESS (%u)\n", total); TRACE("= SUCCESS (%u)\n", total);
if (event) NtSetEvent( event, NULL ); if (event) NtSetEvent( event, NULL );
if (apc && (!status || async_read)) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, if (apc && (!status || async_read)) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc,
(ULONG_PTR)apc_user, (ULONG_PTR)io, 0 ); (ULONG_PTR)apc_user, iosb_ptr, 0 );
} }
else else
{ {
@ -5311,6 +5312,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
unsigned int options; unsigned int options;
NTSTATUS status; NTSTATUS status;
ULONG pos = 0, total = 0; ULONG pos = 0, total = 0;
client_ptr_t iosb_ptr = iosb_client_ptr(io);
enum server_fd_type type; enum server_fd_type type;
ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
BOOL send_completion = FALSE; BOOL send_completion = FALSE;
@ -5364,8 +5366,7 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
io->Information = total; io->Information = total;
TRACE("= 0x%08x (%u)\n", status, total); TRACE("= 0x%08x (%u)\n", status, total);
if (event) NtSetEvent( event, NULL ); if (event) NtSetEvent( event, NULL );
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
(ULONG_PTR)apc_user, (ULONG_PTR)io, 0 );
if (send_completion) add_completion( file, cvalue, status, total, TRUE ); if (send_completion) add_completion( file, cvalue, status, total, TRUE );
return STATUS_PENDING; return STATUS_PENDING;
@ -5390,6 +5391,7 @@ NTSTATUS WINAPI NtWriteFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, v
struct io_timeouts timeouts; struct io_timeouts timeouts;
NTSTATUS status, ret_status; NTSTATUS status, ret_status;
ULONG total = 0; ULONG total = 0;
client_ptr_t iosb_ptr = iosb_client_ptr(io);
enum server_fd_type type; enum server_fd_type type;
ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
BOOL send_completion = FALSE, async_write, append_write = FALSE, timeout_init_done = FALSE; BOOL send_completion = FALSE, async_write, append_write = FALSE, timeout_init_done = FALSE;
@ -5532,7 +5534,7 @@ NTSTATUS WINAPI NtWriteFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, v
{ {
req->type = ASYNC_TYPE_WRITE; req->type = ASYNC_TYPE_WRITE;
req->count = length; req->count = length;
req->async = server_async( handle, &fileio->io, event, apc, apc_user, io ); req->async = server_async( handle, &fileio->io, event, apc, apc_user, iosb_ptr );
status = wine_server_call( req ); status = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
@ -5587,8 +5589,7 @@ err:
io->Information = total; io->Information = total;
TRACE("= SUCCESS (%u)\n", total); TRACE("= SUCCESS (%u)\n", total);
if (event) NtSetEvent( event, NULL ); if (event) NtSetEvent( event, NULL );
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
(ULONG_PTR)apc_user, (ULONG_PTR)io, 0 );
} }
else else
{ {
@ -5613,6 +5614,7 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
unsigned int options; unsigned int options;
NTSTATUS status; NTSTATUS status;
ULONG pos = 0, total = 0; ULONG pos = 0, total = 0;
client_ptr_t iosb_ptr = iosb_client_ptr(io);
enum server_fd_type type; enum server_fd_type type;
ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
BOOL send_completion = FALSE; BOOL send_completion = FALSE;
@ -5677,8 +5679,7 @@ NTSTATUS WINAPI NtWriteFileGather( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
io->Information = total; io->Information = total;
TRACE("= SUCCESS (%u)\n", total); TRACE("= SUCCESS (%u)\n", total);
if (event) NtSetEvent( event, NULL ); if (event) NtSetEvent( event, NULL );
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
(ULONG_PTR)apc_user, (ULONG_PTR)io, 0 );
} }
else else
{ {
@ -5894,7 +5895,7 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE handle, IO_STATUS_BLOCK *io )
SERVER_START_REQ( flush ) SERVER_START_REQ( flush )
{ {
req->async = server_async( handle, &async->io, NULL, NULL, NULL, io ); req->async = server_async( handle, &async->io, NULL, NULL, NULL, iosb_client_ptr(io) );
ret = wine_server_call( req ); ret = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->event ); wait_handle = wine_server_ptr_handle( reply->event );
if (wait_handle && ret != STATUS_PENDING) if (wait_handle && ret != STATUS_PENDING)
@ -6168,7 +6169,7 @@ NTSTATUS WINAPI NtNotifyChangeDirectoryFile( HANDLE handle, HANDLE event, PIO_AP
req->filter = filter; req->filter = filter;
req->want_data = (buffer != NULL); req->want_data = (buffer != NULL);
req->subtree = subtree; req->subtree = subtree;
req->async = server_async( handle, &fileio->io, event, apc, apc_context, iosb ); req->async = server_async( handle, &fileio->io, event, apc, apc_context, iosb_client_ptr(iosb) );
status = wine_server_call( req ); status = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
@ -6390,13 +6391,13 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
{ {
int fd, needs_close; int fd, needs_close;
struct stat st; struct stat st;
NTSTATUS status;
io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ); status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL );
if (io->u.Status == STATUS_BAD_DEVICE_TYPE) if (status == STATUS_BAD_DEVICE_TYPE)
{ {
struct async_irp *async; struct async_irp *async;
HANDLE wait_handle; HANDLE wait_handle;
NTSTATUS status;
if (!(async = (struct async_irp *)alloc_fileio( sizeof(*async), irp_completion, handle ))) if (!(async = (struct async_irp *)alloc_fileio( sizeof(*async), irp_completion, handle )))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -6405,7 +6406,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
SERVER_START_REQ( get_volume_info ) SERVER_START_REQ( get_volume_info )
{ {
req->async = server_async( handle, &async->io, NULL, NULL, NULL, io ); req->async = server_async( handle, &async->io, NULL, NULL, NULL, iosb_client_ptr(io) );
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->info_class = info_class; req->info_class = info_class;
wine_server_set_reply( req, buffer, length ); wine_server_set_reply( req, buffer, length );
@ -6422,7 +6423,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
if (wait_handle) status = wait_async( wait_handle, FALSE ); if (wait_handle) status = wait_async( wait_handle, FALSE );
return status; return status;
} }
else if (io->u.Status) return io->u.Status; else if (status) return io->u.Status = status;
io->u.Status = STATUS_NOT_IMPLEMENTED; io->u.Status = STATUS_NOT_IMPLEMENTED;
io->Information = 0; io->Information = 0;

View File

@ -638,7 +638,7 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
{ {
req->status = status; req->status = status;
req->total = information; req->total = information;
req->async = server_async( handle, &async->io, event, apc, apc_user, io ); req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
req->oob = !!(unix_flags & MSG_OOB); req->oob = !!(unix_flags & MSG_OOB);
status = wine_server_call( req ); status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait ); wait_handle = wine_server_ptr_handle( reply->wait );
@ -781,7 +781,7 @@ static NTSTATUS sock_poll( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
SERVER_START_REQ( poll_socket ) SERVER_START_REQ( poll_socket )
{ {
req->async = server_async( handle, &async->io, event, apc, apc_user, io ); req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
req->timeout = params->timeout; req->timeout = params->timeout;
wine_server_add_data( req, input, params->count * sizeof(*input) ); wine_server_add_data( req, input, params->count * sizeof(*input) );
wine_server_set_reply( req, async->sockets, params->count * sizeof(async->sockets[0]) ); wine_server_set_reply( req, async->sockets, params->count * sizeof(async->sockets[0]) );
@ -944,7 +944,7 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
{ {
req->status = status; req->status = status;
req->total = async->sent_len; req->total = async->sent_len;
req->async = server_async( handle, &async->io, event, apc, apc_user, io ); req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
status = wine_server_call( req ); status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait ); wait_handle = wine_server_ptr_handle( reply->wait );
options = reply->options; options = reply->options;
@ -1124,7 +1124,7 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
{ {
req->status = STATUS_PENDING; req->status = STATUS_PENDING;
req->total = 0; req->total = 0;
req->async = server_async( handle, &async->io, event, apc, apc_user, io ); req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
status = wine_server_call( req ); status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait ); wait_handle = wine_server_ptr_handle( reply->wait );
options = reply->options; options = reply->options;
@ -1144,10 +1144,12 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
static void complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user, static void complete_async( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information ) IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR information )
{ {
ULONG_PTR iosb_ptr = iosb_client_ptr(io);
io->Status = status; io->Status = status;
io->Information = information; io->Information = information;
if (event) NtSetEvent( event, NULL ); if (event) NtSetEvent( event, NULL );
if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, (ULONG_PTR)io, 0 ); if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, (ULONG_PTR)apc_user, iosb_ptr, 0 );
if (apc_user) add_completion( handle, (ULONG_PTR)apc_user, status, information, FALSE ); if (apc_user) add_completion( handle, (ULONG_PTR)apc_user, status, information, FALSE );
} }

View File

@ -337,12 +337,12 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
} }
static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event, static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
PIO_APC_ROUTINE apc, void *apc_context, IO_STATUS_BLOCK *io ) PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
{ {
async_data_t async; async_data_t async;
async.handle = wine_server_obj_handle( handle ); async.handle = wine_server_obj_handle( handle );
async.user = wine_server_client_ptr( user ); async.user = wine_server_client_ptr( user );
async.iosb = wine_server_client_ptr( io ); async.iosb = iosb;
async.event = wine_server_obj_handle( event ); async.event = wine_server_obj_handle( event );
async.apc = wine_server_client_ptr( apc ); async.apc = wine_server_client_ptr( apc );
async.apc_context = wine_server_client_ptr( apc_context ); async.apc_context = wine_server_client_ptr( apc_context );
@ -354,6 +354,11 @@ static inline NTSTATUS wait_async( HANDLE handle, BOOL alertable )
return NtWaitForSingleObject( handle, alertable, NULL ); return NtWaitForSingleObject( handle, alertable, NULL );
} }
static inline client_ptr_t iosb_client_ptr( IO_STATUS_BLOCK *io )
{
return wine_server_client_ptr( io );
}
#ifdef _WIN64 #ifdef _WIN64
typedef TEB32 WOW_TEB; typedef TEB32 WOW_TEB;
static inline TEB64 *NtCurrentTeb64(void) { return NULL; } static inline TEB64 *NtCurrentTeb64(void) { return NULL; }