server: Pass the device client pointer as part of the IRP parameters.

This commit is contained in:
Alexandre Julliard 2015-07-08 17:50:00 +09:00
parent 47a11ec626
commit d087ea6798
7 changed files with 66 additions and 37 deletions

View File

@ -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:

View File

@ -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 */

View File

@ -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, &params, 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, &params, 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, &params, 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, &params, 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;

View File

@ -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 */

View File

@ -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 );

View File

@ -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 );

View File

@ -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" ],