server: Add a common structure to store irp parameters.

This commit is contained in:
Alexandre Julliard 2015-05-06 11:21:40 +09:00
parent faa1db4d13
commit 311f786286
7 changed files with 116 additions and 40 deletions

View File

@ -188,7 +188,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
HANDLE manager = get_device_manager();
HANDLE irp = 0;
NTSTATUS status = STATUS_SUCCESS;
ULONG type, code;
irp_params_t irp_params;
void *in_buff;
DEVICE_OBJECT *device = NULL;
ULONG in_size = 4096, out_size = 0;
@ -215,10 +215,9 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
wine_server_set_reply( req, in_buff, in_size );
if (!(status = wine_server_call( req )))
{
type = reply->type;
code = reply->code;
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;
in_size = reply->in_size;
@ -236,13 +235,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
switch(status)
{
case STATUS_SUCCESS:
switch (type)
switch (irp_params.major)
{
case IRP_MJ_DEVICE_CONTROL:
status = process_ioctl( device, code, in_buff, in_size, out_size, irp );
status = process_ioctl( device, irp_params.ioctl.code, in_buff, in_size, out_size, irp );
break;
default:
FIXME( "unsupported request %u\n", type );
FIXME( "unsupported request %u\n", irp_params.major );
status = STATUS_NOT_SUPPORTED;
break;
}

View File

@ -631,6 +631,28 @@ typedef union
} create_thread;
} apc_result_t;
typedef union
{
unsigned int major;
struct
{
unsigned int major;
unsigned int key;
file_pos_t pos;
} read;
struct
{
unsigned int major;
unsigned int key;
file_pos_t pos;
} write;
struct
{
unsigned int major;
ioctl_code_t code;
} ioctl;
} irp_params_t;
struct rawinput_device
{
unsigned short usage_page;
@ -4834,16 +4856,15 @@ struct get_next_device_request_request
struct get_next_device_request_reply
{
struct reply_header __header;
obj_handle_t next;
unsigned int type;
client_ptr_t user_ptr;
ioctl_code_t code;
irp_params_t params;
obj_handle_t next;
process_id_t client_pid;
thread_id_t client_tid;
data_size_t in_size;
data_size_t out_size;
/* VARARG(next_data,bytes); */
char __pad_44[4];
char __pad_52[4];
};
@ -6020,6 +6041,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 473
#define SERVER_PROTOCOL_VERSION 474
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -44,9 +44,8 @@ struct irp_call
struct thread *thread; /* thread that queued the irp */
client_ptr_t user_arg; /* user arg used to identify the request */
struct async *async; /* pending async op */
unsigned int type; /* request type (IRP_MJ_*) */
unsigned int status; /* resulting status (or STATUS_PENDING) */
ioctl_code_t code; /* ioctl code */
irp_params_t params; /* irp parameters */
data_size_t result; /* size of result (input or output depending on the type) */
data_size_t in_size; /* size of input data */
void *in_data; /* input data */
@ -198,8 +197,8 @@ static void irp_call_destroy( struct object *obj )
release_object( irp->thread );
}
static struct irp_call *create_irp( struct device *device, unsigned int type, const void *in_data,
data_size_t in_size, data_size_t out_size )
static struct irp_call *create_irp( struct device *device, const irp_params_t *params,
const void *in_data, data_size_t in_size, data_size_t out_size )
{
struct irp_call *irp;
@ -213,8 +212,7 @@ static struct irp_call *create_irp( struct device *device, unsigned int type, co
{
irp->device = (struct device *)grab_object( device );
irp->async = NULL;
irp->type = type;
irp->code = 0;
irp->params = *params;
irp->status = STATUS_PENDING;
irp->result = 0;
irp->in_size = in_size;
@ -356,8 +354,13 @@ static obj_handle_t device_read( struct fd *fd, const async_data_t *async_data,
struct device *device = get_fd_user( fd );
struct irp_call *irp;
obj_handle_t handle;
irp_params_t params;
irp = create_irp( device, IRP_MJ_READ, NULL, 0, get_reply_max_size() );
params.major = IRP_MJ_READ;
params.read.key = 0;
params.read.pos = pos;
irp = create_irp( device, &params, NULL, 0, get_reply_max_size() );
if (!irp) return 0;
handle = queue_irp( device, irp, async_data, blocking );
@ -371,8 +374,13 @@ static obj_handle_t device_write( struct fd *fd, const async_data_t *async_data,
struct device *device = get_fd_user( fd );
struct irp_call *irp;
obj_handle_t handle;
irp_params_t params;
irp = create_irp( device, IRP_MJ_WRITE, get_req_data(), get_req_data_size(), 0 );
params.major = IRP_MJ_WRITE;
params.write.key = 0;
params.write.pos = pos;
irp = create_irp( device, &params, get_req_data(), get_req_data_size(), 0 );
if (!irp) return 0;
handle = queue_irp( device, irp, async_data, blocking );
@ -386,13 +394,15 @@ static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_
struct device *device = get_fd_user( fd );
struct irp_call *irp;
obj_handle_t handle;
irp_params_t params;
irp = create_irp( device, IRP_MJ_DEVICE_CONTROL, get_req_data(), get_req_data_size(),
params.major = IRP_MJ_DEVICE_CONTROL;
params.ioctl.code = code;
irp = create_irp( device, &params, get_req_data(), get_req_data_size(),
get_reply_max_size() );
if (!irp) return 0;
irp->code = code;
handle = queue_irp( device, irp, async_data, blocking );
release_object( irp );
return handle;
@ -559,8 +569,7 @@ DECL_HANDLER(get_next_device_request)
if ((ptr = list_head( &manager->requests )))
{
irp = LIST_ENTRY( ptr, struct irp_call, mgr_entry );
reply->type = irp->type;
reply->code = irp->code;
reply->params = irp->params;
reply->user_ptr = irp->device->user_ptr;
reply->client_pid = get_process_id( irp->thread->process );
reply->client_tid = get_thread_id( irp->thread );

View File

@ -647,6 +647,28 @@ typedef union
} create_thread;
} apc_result_t;
typedef union
{
unsigned int major; /* irp major function */
struct
{
unsigned int major; /* IRP_MJ_READ */
unsigned int key; /* driver key */
file_pos_t pos; /* file position */
} read;
struct
{
unsigned int major; /* IRP_MJ_WRITE */
unsigned int key; /* driver key */
file_pos_t pos; /* file position */
} write;
struct
{
unsigned int major; /* IRP_MJ_DEVICE_CONTROL */
ioctl_code_t code; /* ioctl code */
} ioctl;
} irp_params_t;
struct rawinput_device
{
unsigned short usage_page;
@ -3357,10 +3379,9 @@ enum coords_relative
obj_handle_t prev; /* handle to the previous irp */
unsigned int status; /* status of the previous irp */
@REPLY
obj_handle_t next; /* handle to the next irp */
unsigned int type; /* irp type (IRP_MJ_*) */
client_ptr_t user_ptr; /* opaque ptr for the device */
ioctl_code_t code; /* ioctl code */
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 */
thread_id_t client_tid; /* tid of thread calling irp */
data_size_t in_size; /* total needed input size */

View File

@ -657,6 +657,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(lparam_t) == 8 );
C_ASSERT( sizeof(luid_t) == 8 );
C_ASSERT( sizeof(mem_size_t) == 8 );
@ -2145,15 +2146,14 @@ 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, next) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, type) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, user_ptr) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, code) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_pid) == 28 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, client_tid) == 32 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 36 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, out_size) == 40 );
C_ASSERT( sizeof(struct get_next_device_request_reply) == 48 );
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, 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 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, in_size) == 44 );
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_reply, out_size) == 48 );
C_ASSERT( sizeof(struct get_next_device_request_reply) == 56 );
C_ASSERT( sizeof(struct make_process_system_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct make_process_system_reply, event) == 8 );
C_ASSERT( sizeof(struct make_process_system_reply) == 16 );

View File

@ -38,6 +38,7 @@
#include "winternl.h"
#include "winuser.h"
#include "winioctl.h"
#include "ddk/wdm.h"
#include "file.h"
#include "request.h"
#include "unicode.h"
@ -308,6 +309,31 @@ static void dump_async_data( const char *prefix, const async_data_t *data )
fputc( '}', stderr );
}
static void dump_irp_params( const char *prefix, const irp_params_t *data )
{
switch (data->major)
{
case IRP_MJ_READ:
fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key );
dump_uint64( ",pos=", &data->read.pos );
fputc( '}', stderr );
break;
case IRP_MJ_WRITE:
fprintf( stderr, "%s{major=WRITE,key=%08x", prefix, data->write.key );
dump_uint64( ",pos=", &data->write.pos );
fputc( '}', stderr );
break;
case IRP_MJ_DEVICE_CONTROL:
fprintf( stderr, "%s{major=DEVICE_CONTROL", prefix );
dump_ioctl_code( ",code=", &data->ioctl.code );
fputc( '}', stderr );
break;
default:
fprintf( stderr, "%s{major=%u}", prefix, data->major );
break;
}
}
static void dump_hw_input( const char *prefix, const hw_input_t *input )
{
switch (input->type)
@ -3951,10 +3977,9 @@ 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 )
{
fprintf( stderr, " next=%04x", req->next );
fprintf( stderr, ", type=%08x", req->type );
dump_uint64( ", user_ptr=", &req->user_ptr );
dump_ioctl_code( ", code=", &req->code );
dump_uint64( " user_ptr=", &req->user_ptr );
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 );
fprintf( stderr, ", in_size=%u", req->in_size );

View File

@ -48,6 +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" ],
"luid_t" => [ 8, 4, "&dump_luid" ],
"ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ],
"cpu_type_t" => [ 4, 4, "&dump_cpu_type" ],