From 8bce6309ac01cdc17eb418b4024b1c08db710ccd Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 3 May 2019 15:39:27 +0200 Subject: [PATCH] server: Pass IRP output size in irp_params_t. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/ntoskrnl.exe/ntoskrnl.c | 23 ++++++++++++----------- include/wine/server_protocol.h | 8 ++++++-- server/device.c | 7 ++++--- server/protocol.def | 5 ++++- server/request.h | 13 ++++++------- server/trace.c | 5 +++-- tools/make_requests | 2 +- 7 files changed, 36 insertions(+), 27 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index b4afc1ff1db..8d6b7dace8a 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -599,7 +599,7 @@ static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp, HANDLE irp_handle ) /* process a create request for a given file */ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IRP *irp; IO_STACK_LOCATION *irpsp; @@ -645,7 +645,7 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON /* process a close request for a given file */ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IRP *irp; IO_STACK_LOCATION *irpsp; @@ -684,7 +684,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG /* process a read request for a given device */ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IRP *irp; void *out_buff; @@ -692,6 +692,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG IO_STACK_LOCATION *irpsp; DEVICE_OBJECT *device; FILE_OBJECT *file = wine_server_get_ptr( params->read.file ); + ULONG out_size = params->read.out_size; if (!file) return STATUS_INVALID_HANDLE; @@ -727,7 +728,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG /* process a write request for a given device */ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IRP *irp; LARGE_INTEGER offset; @@ -763,7 +764,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG /* process a flush request for a given device */ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IRP *irp; IO_STACK_LOCATION *irpsp; @@ -794,7 +795,7 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG /* process an ioctl request for a given device */ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { IO_STACK_LOCATION *irpsp; IRP *irp; @@ -802,6 +803,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG void *to_free = NULL; DEVICE_OBJECT *device; FILE_OBJECT *file = wine_server_get_ptr( params->ioctl.file ); + ULONG out_size = params->ioctl.out_size; if (!file) return STATUS_INVALID_HANDLE; @@ -862,7 +864,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG * object associated with kernel object is freed so that we may free it on client side * as well. */ static NTSTATUS dispatch_cleanup( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ) + HANDLE irp_handle ) { void *obj = wine_server_get_ptr( params->cleanup.obj ); TRACE( "freeing %p object\n", obj ); @@ -871,7 +873,7 @@ static NTSTATUS dispatch_cleanup( const irp_params_t *params, void *in_buff, ULO } typedef NTSTATUS (*dispatch_func)( const irp_params_t *params, void *in_buff, ULONG in_size, - ULONG out_size, HANDLE irp_handle ); + HANDLE irp_handle ); static const dispatch_func dispatch_funcs[IRP_MJ_MAXIMUM_FUNCTION + 1] = { @@ -963,7 +965,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) HANDLE irp = 0; NTSTATUS status = STATUS_SUCCESS; irp_params_t irp_params; - ULONG in_size = 4096, out_size = 0; + ULONG in_size = 4096; void *in_buff = NULL; HANDLE handles[2]; @@ -996,7 +998,6 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) irp_params = reply->params; client_tid = reply->client_tid; in_size = reply->in_size; - out_size = reply->out_size; NtCurrentTeb()->Reserved5[1] = wine_server_get_ptr( reply->client_thread ); } else @@ -1017,7 +1018,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) status = STATUS_NOT_SUPPORTED; break; } - status = dispatch_funcs[irp_params.major]( &irp_params, in_buff, in_size, out_size, irp ); + status = dispatch_funcs[irp_params.major]( &irp_params, in_buff, in_size, irp ); if (status == STATUS_SUCCESS) { irp = 0; /* status reported by IoCompleteRequest */ diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index e0b63846fa7..4236c12ae52 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -661,6 +661,8 @@ typedef union { unsigned int major; unsigned int key; + data_size_t out_size; + int __pad; client_ptr_t file; file_pos_t pos; } read; @@ -681,6 +683,8 @@ typedef union { unsigned int major; ioctl_code_t code; + data_size_t out_size; + int __pad; client_ptr_t file; } ioctl; struct @@ -5245,8 +5249,8 @@ struct get_next_device_request_reply thread_id_t client_tid; client_ptr_t client_thread; data_size_t in_size; - data_size_t out_size; /* VARARG(next_data,bytes); */ + char __pad_60[4]; }; @@ -6678,6 +6682,6 @@ union generic_reply struct resume_process_reply resume_process_reply; }; -#define SERVER_PROTOCOL_VERSION 579 +#define SERVER_PROTOCOL_VERSION 580 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/device.c b/server/device.c index 1d864e0bea0..97d316e152e 100644 --- a/server/device.c +++ b/server/device.c @@ -548,7 +548,8 @@ static void fill_irp_params( struct device_manager *manager, struct irp_call *ir params->close.file = get_kernel_object_ptr( manager, &irp->file->obj ); break; case IRP_MJ_READ: - params->read.file = get_kernel_object_ptr( manager, &irp->file->obj ); + params->read.file = get_kernel_object_ptr( manager, &irp->file->obj ); + params->read.out_size = irp->iosb->out_size; break; case IRP_MJ_WRITE: params->write.file = get_kernel_object_ptr( manager, &irp->file->obj ); @@ -557,7 +558,8 @@ static void fill_irp_params( struct device_manager *manager, struct irp_call *ir params->flush.file = get_kernel_object_ptr( manager, &irp->file->obj ); break; case IRP_MJ_DEVICE_CONTROL: - params->ioctl.file = get_kernel_object_ptr( manager, &irp->file->obj ); + params->ioctl.file = get_kernel_object_ptr( manager, &irp->file->obj ); + params->ioctl.out_size = irp->iosb->out_size; break; } } @@ -876,7 +878,6 @@ DECL_HANDLER(get_next_device_request) } iosb = irp->iosb; reply->in_size = iosb->in_size; - reply->out_size = iosb->out_size; if (iosb->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW ); else if (!irp->file || (reply->next = alloc_handle( current->process, irp, 0, 0 ))) { diff --git a/server/protocol.def b/server/protocol.def index 90f26d4937a..9a261eb6f0d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -677,6 +677,8 @@ typedef union { unsigned int major; /* IRP_MJ_READ */ unsigned int key; /* driver key */ + data_size_t out_size; /* needed output size */ + int __pad; client_ptr_t file; /* opaque ptr for the file object */ file_pos_t pos; /* file position */ } read; @@ -697,6 +699,8 @@ typedef union { unsigned int major; /* IRP_MJ_DEVICE_CONTROL */ ioctl_code_t code; /* ioctl code */ + data_size_t out_size; /* needed output size */ + int __pad; client_ptr_t file; /* opaque ptr for the file object */ } ioctl; struct @@ -3623,7 +3627,6 @@ struct handle_info thread_id_t client_tid; /* tid of thread calling irp */ client_ptr_t client_thread; /* pointer to thread object of calling irp */ data_size_t in_size; /* total needed input size */ - data_size_t out_size; /* needed output size */ VARARG(next_data,bytes); /* input data of the next irp */ @END diff --git a/server/request.h b/server/request.h index a21252c7a62..b46a1d93ba9 100644 --- a/server/request.h +++ b/server/request.h @@ -731,7 +731,7 @@ C_ASSERT( sizeof(file_pos_t) == 8 ); C_ASSERT( sizeof(hw_input_t) == 32 ); C_ASSERT( sizeof(int) == 4 ); C_ASSERT( sizeof(ioctl_code_t) == 4 ); -C_ASSERT( sizeof(irp_params_t) == 24 ); +C_ASSERT( sizeof(irp_params_t) == 32 ); C_ASSERT( sizeof(lparam_t) == 8 ); C_ASSERT( sizeof(luid_t) == 8 ); C_ASSERT( sizeof(mem_size_t) == 8 ); @@ -2290,12 +2290,11 @@ C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, prev) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, status) == 20 ); C_ASSERT( sizeof(struct get_next_device_request_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, params) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, next) == 32 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_tid) == 36 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_thread) == 40 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 48 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, out_size) == 52 ); -C_ASSERT( sizeof(struct get_next_device_request_reply) == 56 ); +C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, next) == 40 ); +C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_tid) == 44 ); +C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_thread) == 48 ); +C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 56 ); +C_ASSERT( sizeof(struct get_next_device_request_reply) == 64 ); C_ASSERT( FIELD_OFFSET(struct get_kernel_object_ptr_request, manager) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_kernel_object_ptr_request, handle) == 16 ); C_ASSERT( sizeof(struct get_kernel_object_ptr_request) == 24 ); diff --git a/server/trace.c b/server/trace.c index 5c6325a2576..cb5b9c01e07 100644 --- a/server/trace.c +++ b/server/trace.c @@ -331,7 +331,8 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data ) fputc( '}', stderr ); break; case IRP_MJ_READ: - fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key ); + fprintf( stderr, "%s{major=READ,key=%08x,out_size=%u", prefix, data->read.key, + data->read.out_size ); dump_uint64( ",pos=", &data->read.pos ); dump_uint64( ",file=", &data->read.file ); fputc( '}', stderr ); @@ -350,6 +351,7 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data ) case IRP_MJ_DEVICE_CONTROL: fprintf( stderr, "%s{major=DEVICE_CONTROL", prefix ); dump_ioctl_code( ",code=", &data->ioctl.code ); + fprintf( stderr, ",out_size=%u", data->ioctl.out_size ); dump_uint64( ",file=", &data->ioctl.file ); fputc( '}', stderr ); break; @@ -4288,7 +4290,6 @@ static void dump_get_next_device_request_reply( const struct get_next_device_req fprintf( stderr, ", client_tid=%04x", req->client_tid ); dump_uint64( ", client_thread=", &req->client_thread ); fprintf( stderr, ", in_size=%u", req->in_size ); - fprintf( stderr, ", out_size=%u", req->out_size ); dump_varargs_bytes( ", next_data=", cur_size ); } diff --git a/tools/make_requests b/tools/make_requests index 367f2456538..405e1301cd1 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -48,7 +48,7 @@ my %formats = "apc_call_t" => [ 40, 8, "&dump_apc_call" ], "apc_result_t" => [ 40, 8, "&dump_apc_result" ], "async_data_t" => [ 40, 8, "&dump_async_data" ], - "irp_params_t" => [ 24, 8, "&dump_irp_params" ], + "irp_params_t" => [ 32, 8, "&dump_irp_params" ], "luid_t" => [ 8, 4, "&dump_luid" ], "ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ], "cpu_type_t" => [ 4, 4, "&dump_cpu_type" ],