From d087ea6798d9dca4d974a21bb9acb70ae7dac4eb Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 8 Jul 2015 17:50:00 +0900 Subject: [PATCH] server: Pass the device client pointer as part of the IRP parameters. --- dlls/ntoskrnl.exe/ntoskrnl.c | 41 ++++++++++++++++++++++++----------------- include/wine/server_protocol.h | 12 ++++++++++-- server/device.c | 23 +++++++++++++---------- server/protocol.def | 10 +++++++++- server/request.h | 5 ++--- server/trace.c | 10 +++++++--- tools/make_requests | 2 +- 7 files changed, 66 insertions(+), 37 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 35454a5b632..53739c62c72 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -152,13 +152,16 @@ static NTSTATUS dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) } /* process a read request for a given device */ -static NTSTATUS dispatch_read( DEVICE_OBJECT *device, const irp_params_t *params, - void *in_buff, ULONG in_size, ULONG out_size, HANDLE irp_handle ) +static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG in_size, + ULONG out_size, HANDLE irp_handle ) { IRP *irp; void *out_buff; LARGE_INTEGER offset; IO_STACK_LOCATION *irpsp; + DEVICE_OBJECT *device = wine_server_get_ptr( params->read.device ); + + if (!device->DriverObject->MajorFunction[IRP_MJ_READ]) return STATUS_NOT_SUPPORTED; TRACE( "device %p size %u\n", device, out_size ); @@ -181,12 +184,15 @@ static NTSTATUS dispatch_read( DEVICE_OBJECT *device, const irp_params_t *params } /* process a write request for a given device */ -static NTSTATUS dispatch_write( DEVICE_OBJECT *device, const irp_params_t *params, - void *in_buff, ULONG in_size, ULONG out_size, HANDLE irp_handle ) +static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG in_size, + ULONG out_size, HANDLE irp_handle ) { IRP *irp; LARGE_INTEGER offset; IO_STACK_LOCATION *irpsp; + DEVICE_OBJECT *device = wine_server_get_ptr( params->write.device ); + + if (!device->DriverObject->MajorFunction[IRP_MJ_WRITE]) return STATUS_NOT_SUPPORTED; TRACE( "device %p size %u\n", device, in_size ); @@ -204,10 +210,13 @@ static NTSTATUS dispatch_write( DEVICE_OBJECT *device, const irp_params_t *param } /* process a flush request for a given device */ -static NTSTATUS dispatch_flush( DEVICE_OBJECT *device, const irp_params_t *params, - void *in_buff, ULONG in_size, ULONG out_size, HANDLE irp_handle ) +static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG in_size, + ULONG out_size, HANDLE irp_handle ) { IRP *irp; + DEVICE_OBJECT *device = wine_server_get_ptr( params->flush.device ); + + if (!device->DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]) return STATUS_NOT_SUPPORTED; TRACE( "device %p\n", device ); @@ -220,11 +229,14 @@ static NTSTATUS dispatch_flush( DEVICE_OBJECT *device, const irp_params_t *param } /* process an ioctl request for a given device */ -static NTSTATUS dispatch_ioctl( DEVICE_OBJECT *device, const irp_params_t *params, - void *in_buff, ULONG in_size, ULONG out_size, HANDLE irp_handle ) +static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG in_size, + ULONG out_size, HANDLE irp_handle ) { IRP *irp; void *out_buff = NULL; + DEVICE_OBJECT *device = wine_server_get_ptr( params->ioctl.device ); + + if (!device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]) return STATUS_NOT_SUPPORTED; TRACE( "ioctl %x device %p in_size %u out_size %u\n", params->ioctl.code, device, in_size, out_size ); @@ -251,8 +263,8 @@ static NTSTATUS dispatch_ioctl( DEVICE_OBJECT *device, const irp_params_t *param return dispatch_irp( device, irp ); } -typedef NTSTATUS (*dispatch_func)( DEVICE_OBJECT *device, const irp_params_t *params, - void *in_buff, ULONG in_size, ULONG out_size, HANDLE irp_handle ); +typedef NTSTATUS (*dispatch_func)( const irp_params_t *params, void *in_buff, ULONG in_size, + ULONG out_size, HANDLE irp_handle ); static const dispatch_func dispatch_funcs[IRP_MJ_MAXIMUM_FUNCTION + 1] = { @@ -297,7 +309,6 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) NTSTATUS status = STATUS_SUCCESS; irp_params_t irp_params; void *in_buff; - DEVICE_OBJECT *device = NULL; ULONG in_size = 4096, out_size = 0; HANDLE handles[2]; @@ -323,7 +334,6 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) if (!(status = wine_server_call( req ))) { irp = wine_server_ptr_handle( reply->next ); - device = wine_server_get_ptr( reply->user_ptr ); irp_params = reply->params; client_tid = reply->client_tid; client_pid = reply->client_pid; @@ -342,16 +352,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) switch(status) { case STATUS_SUCCESS: - if (irp_params.major > IRP_MJ_MAXIMUM_FUNCTION || - !dispatch_funcs[irp_params.major] || - !device->DriverObject->MajorFunction[irp_params.major]) + if (irp_params.major > IRP_MJ_MAXIMUM_FUNCTION || !dispatch_funcs[irp_params.major]) { WARN( "unsupported request %u\n", irp_params.major ); status = STATUS_NOT_SUPPORTED; break; } - status = dispatch_funcs[irp_params.major]( device, &irp_params, - in_buff, in_size, out_size, irp ); + status = dispatch_funcs[irp_params.major]( &irp_params, in_buff, in_size, out_size, irp ); if (status == STATUS_SUCCESS) irp = 0; /* status reported by IoCompleteRequest */ break; case STATUS_BUFFER_OVERFLOW: diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index febaee54a2f..860b66f2e24 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -638,18 +638,27 @@ typedef union { unsigned int major; unsigned int key; + client_ptr_t device; file_pos_t pos; } read; struct { unsigned int major; unsigned int key; + client_ptr_t device; file_pos_t pos; } write; struct { unsigned int major; + int __pad; + client_ptr_t device; + } flush; + struct + { + unsigned int major; ioctl_code_t code; + client_ptr_t device; } ioctl; } irp_params_t; @@ -4882,7 +4891,6 @@ struct get_next_device_request_request struct get_next_device_request_reply { struct reply_header __header; - client_ptr_t user_ptr; irp_params_t params; obj_handle_t next; process_id_t client_pid; @@ -6073,6 +6081,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 476 +#define SERVER_PROTOCOL_VERSION 477 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/device.c b/server/device.c index da99c329640..5dd3ae6a0c4 100644 --- a/server/device.c +++ b/server/device.c @@ -446,9 +446,10 @@ static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_d obj_handle_t handle; irp_params_t params; - params.major = IRP_MJ_READ; - params.read.key = 0; - params.read.pos = pos; + params.read.major = IRP_MJ_READ; + params.read.key = 0; + params.read.pos = pos; + params.read.device = file->device->user_ptr; irp = create_irp( file, ¶ms, NULL, 0, get_reply_max_size() ); if (!irp) return 0; @@ -466,9 +467,10 @@ static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_ obj_handle_t handle; irp_params_t params; - params.major = IRP_MJ_WRITE; - params.write.key = 0; - params.write.pos = pos; + params.write.major = IRP_MJ_WRITE; + params.write.key = 0; + params.write.pos = pos; + params.write.device = file->device->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), 0 ); if (!irp) return 0; @@ -485,7 +487,8 @@ static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_ obj_handle_t handle; irp_params_t params; - params.major = IRP_MJ_FLUSH_BUFFERS; + params.flush.major = IRP_MJ_FLUSH_BUFFERS; + params.flush.device = file->device->user_ptr; irp = create_irp( file, ¶ms, NULL, 0, 0 ); if (!irp) return 0; @@ -503,8 +506,9 @@ static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const a obj_handle_t handle; irp_params_t params; - params.major = IRP_MJ_DEVICE_CONTROL; - params.ioctl.code = code; + params.ioctl.major = IRP_MJ_DEVICE_CONTROL; + params.ioctl.code = code; + params.ioctl.device = file->device->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), get_reply_max_size() ); @@ -698,7 +702,6 @@ DECL_HANDLER(get_next_device_request) { irp = LIST_ENTRY( ptr, struct irp_call, mgr_entry ); reply->params = irp->params; - reply->user_ptr = irp->file->device->user_ptr; reply->client_pid = get_process_id( irp->thread->process ); reply->client_tid = get_thread_id( irp->thread ); reply->in_size = irp->in_size; diff --git a/server/protocol.def b/server/protocol.def index 9e5e416341e..ab03f59656e 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -654,18 +654,27 @@ typedef union { unsigned int major; /* IRP_MJ_READ */ unsigned int key; /* driver key */ + client_ptr_t device; /* opaque ptr for the device */ file_pos_t pos; /* file position */ } read; struct { unsigned int major; /* IRP_MJ_WRITE */ unsigned int key; /* driver key */ + client_ptr_t device; /* opaque ptr for the device */ file_pos_t pos; /* file position */ } write; struct { + unsigned int major; /* IRP_MJ_FLUSH_BUFFERS */ + int __pad; + client_ptr_t device; /* opaque ptr for the device */ + } flush; + struct + { unsigned int major; /* IRP_MJ_DEVICE_CONTROL */ ioctl_code_t code; /* ioctl code */ + client_ptr_t device; /* opaque ptr for the device */ } ioctl; } irp_params_t; @@ -3392,7 +3401,6 @@ enum coords_relative obj_handle_t prev; /* handle to the previous irp */ unsigned int status; /* status of the previous irp */ @REPLY - client_ptr_t user_ptr; /* opaque ptr for the device */ irp_params_t params; /* irp parameters */ obj_handle_t next; /* handle to the next irp */ process_id_t client_pid; /* pid of process calling irp */ diff --git a/server/request.h b/server/request.h index 1dfd10ec73a..845547fa2b7 100644 --- a/server/request.h +++ b/server/request.h @@ -661,7 +661,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) == 16 ); +C_ASSERT( sizeof(irp_params_t) == 24 ); C_ASSERT( sizeof(lparam_t) == 8 ); C_ASSERT( sizeof(luid_t) == 8 ); C_ASSERT( sizeof(mem_size_t) == 8 ); @@ -2155,8 +2155,7 @@ C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, manager) == 12 ); 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, user_ptr) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, params) == 16 ); +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_pid) == 36 ); C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_tid) == 40 ); diff --git a/server/trace.c b/server/trace.c index 73abd1ba266..88575854ddf 100644 --- a/server/trace.c +++ b/server/trace.c @@ -319,19 +319,24 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data ) case IRP_MJ_READ: fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key ); dump_uint64( ",pos=", &data->read.pos ); + dump_uint64( ",device=", &data->read.device ); fputc( '}', stderr ); break; case IRP_MJ_WRITE: fprintf( stderr, "%s{major=WRITE,key=%08x", prefix, data->write.key ); dump_uint64( ",pos=", &data->write.pos ); + dump_uint64( ",device=", &data->write.device ); fputc( '}', stderr ); break; case IRP_MJ_FLUSH_BUFFERS: - fprintf( stderr, "%s{major=FLUSH_BUFFERS}", prefix ); + fprintf( stderr, "%s{major=FLUSH_BUFFERS", prefix ); + dump_uint64( ",device=", &data->flush.device ); + fputc( '}', stderr ); break; case IRP_MJ_DEVICE_CONTROL: fprintf( stderr, "%s{major=DEVICE_CONTROL", prefix ); dump_ioctl_code( ",code=", &data->ioctl.code ); + dump_uint64( ",device=", &data->ioctl.device ); fputc( '}', stderr ); break; default: @@ -3998,8 +4003,7 @@ static void dump_get_next_device_request_request( const struct get_next_device_r static void dump_get_next_device_request_reply( const struct get_next_device_request_reply *req ) { - dump_uint64( " user_ptr=", &req->user_ptr ); - dump_irp_params( ", params=", &req->params ); + dump_irp_params( " params=", &req->params ); fprintf( stderr, ", next=%04x", req->next ); fprintf( stderr, ", client_pid=%04x", req->client_pid ); fprintf( stderr, ", client_tid=%04x", req->client_tid ); diff --git a/tools/make_requests b/tools/make_requests index 871abec77c6..bceef7025d4 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" => [ 16, 8, "&dump_irp_params" ], + "irp_params_t" => [ 24, 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" ], -- 2.11.4.GIT