server: Add request to retrieve the next pending ioctl call for a device manager.

This commit is contained in:
Alexandre Julliard 2007-05-08 20:40:26 +02:00
parent 61e08b346b
commit 78b75108cd
5 changed files with 115 additions and 1 deletions

View File

@ -4014,6 +4014,27 @@ struct delete_device_reply
};
struct get_next_device_request_request
{
struct request_header __header;
obj_handle_t manager;
obj_handle_t prev;
unsigned int status;
/* VARARG(prev_data,bytes); */
};
struct get_next_device_request_reply
{
struct reply_header __header;
obj_handle_t next;
ioctl_code_t code;
void* user_ptr;
data_size_t in_size;
data_size_t out_size;
/* VARARG(next_data,bytes); */
};
enum request
{
REQ_new_process,
@ -4233,6 +4254,7 @@ enum request
REQ_create_device_manager,
REQ_create_device,
REQ_delete_device,
REQ_get_next_device_request,
REQ_NB_REQUESTS
};
@ -4457,6 +4479,7 @@ union generic_request
struct create_device_manager_request create_device_manager_request;
struct create_device_request create_device_request;
struct delete_device_request delete_device_request;
struct get_next_device_request_request get_next_device_request_request;
};
union generic_reply
{
@ -4679,8 +4702,9 @@ union generic_reply
struct create_device_manager_reply create_device_manager_reply;
struct create_device_reply create_device_reply;
struct delete_device_reply delete_device_reply;
struct get_next_device_request_reply get_next_device_request_reply;
};
#define SERVER_PROTOCOL_VERSION 301
#define SERVER_PROTOCOL_VERSION 302
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -442,3 +442,49 @@ DECL_HANDLER(delete_device)
release_object( device );
}
}
/* retrieve the next pending device ioctl request */
DECL_HANDLER(get_next_device_request)
{
struct ioctl_call *ioctl;
struct device_manager *manager;
struct list *ptr;
if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
0, &device_manager_ops )))
return;
if (req->prev)
{
if ((ioctl = (struct ioctl_call *)get_handle_obj( current->process, req->prev,
0, &ioctl_call_ops )))
{
set_ioctl_result( ioctl, req->status, get_req_data(), get_req_data_size() );
close_handle( current->process, req->prev ); /* avoid an extra round-trip for close */
release_object( ioctl );
}
clear_error();
}
if ((ptr = list_head( &manager->requests )))
{
ioctl = LIST_ENTRY( ptr, struct ioctl_call, mgr_entry );
reply->code = ioctl->code;
reply->user_ptr = ioctl->device->user_ptr;
reply->in_size = ioctl->in_size;
reply->out_size = ioctl->out_size;
if (ioctl->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
else if ((reply->next = alloc_handle( current->process, ioctl, 0, 0 )))
{
set_reply_data_ptr( ioctl->in_data, ioctl->in_size );
ioctl->in_data = NULL;
ioctl->in_size = 0;
list_remove( &ioctl->mgr_entry );
list_init( &ioctl->mgr_entry );
}
}
else set_error( STATUS_PENDING );
release_object( manager );
}

View File

@ -2882,3 +2882,19 @@ enum message_type
@REQ(delete_device)
obj_handle_t handle; /* handle to the device */
@END
/* Retrieve the next pending device ioctl request */
@REQ(get_next_device_request)
obj_handle_t manager; /* handle to the device manager */
obj_handle_t prev; /* handle to the previous ioctl */
unsigned int status; /* status of the previous ioctl */
VARARG(prev_data,bytes); /* output data of the previous ioctl */
@REPLY
obj_handle_t next; /* handle to the next ioctl */
ioctl_code_t code; /* ioctl code */
void* user_ptr; /* opaque ptr for the device */
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 ioctl */
@END

View File

@ -327,6 +327,7 @@ DECL_HANDLER(allocate_locally_unique_id);
DECL_HANDLER(create_device_manager);
DECL_HANDLER(create_device);
DECL_HANDLER(delete_device);
DECL_HANDLER(get_next_device_request);
#ifdef WANT_REQUEST_HANDLERS
@ -550,6 +551,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_device_manager,
(req_handler)req_create_device,
(req_handler)req_delete_device,
(req_handler)req_get_next_device_request,
};
#endif /* WANT_REQUEST_HANDLERS */

View File

@ -3492,6 +3492,28 @@ static void dump_delete_device_request( const struct delete_device_request *req
fprintf( stderr, " handle=%p", req->handle );
}
static void dump_get_next_device_request_request( const struct get_next_device_request_request *req )
{
fprintf( stderr, " manager=%p,", req->manager );
fprintf( stderr, " prev=%p,", req->prev );
fprintf( stderr, " status=%08x,", req->status );
fprintf( stderr, " prev_data=" );
dump_varargs_bytes( cur_size );
}
static void dump_get_next_device_request_reply( const struct get_next_device_request_reply *req )
{
fprintf( stderr, " next=%p,", req->next );
fprintf( stderr, " code=" );
dump_ioctl_code( &req->code );
fprintf( stderr, "," );
fprintf( stderr, " user_ptr=%p,", req->user_ptr );
fprintf( stderr, " in_size=%u,", req->in_size );
fprintf( stderr, " out_size=%u,", req->out_size );
fprintf( stderr, " next_data=" );
dump_varargs_bytes( cur_size );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@ -3710,6 +3732,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_device_manager_request,
(dump_func)dump_create_device_request,
(dump_func)dump_delete_device_request,
(dump_func)dump_get_next_device_request_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@ -3930,6 +3953,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_device_manager_reply,
(dump_func)dump_create_device_reply,
(dump_func)0,
(dump_func)dump_get_next_device_request_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@ -4150,6 +4174,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_device_manager",
"create_device",
"delete_device",
"get_next_device_request",
};
static const struct
@ -4181,6 +4206,7 @@ static const struct
{ "ERROR_CLIPBOARD_NOT_OPEN", 0xc0010000 | ERROR_CLIPBOARD_NOT_OPEN },
{ "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX },
{ "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE },
{ "FILE_DELETED", STATUS_FILE_DELETED },
{ "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY },
{ "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT },
{ "GENERIC_NOT_MAPPED", STATUS_GENERIC_NOT_MAPPED },