server: Added mechanism for returning results of APC calls.
Defined APC_VIRTUAL_ALLOC and APC_VIRTUAL_FREE requests.
This commit is contained in:
parent
46d7fa4852
commit
fb40dc4099
|
@ -662,14 +662,18 @@ static BOOL call_apcs( BOOL alertable )
|
|||
BOOL user_apc = FALSE;
|
||||
NTSTATUS ret;
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
HANDLE handle = 0;
|
||||
|
||||
memset( &result, 0, sizeof(result) );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SERVER_START_REQ( get_apc )
|
||||
{
|
||||
req->alertable = alertable;
|
||||
req->prev = handle;
|
||||
req->result = result;
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
handle = reply->handle;
|
||||
|
@ -680,6 +684,8 @@ static BOOL call_apcs( BOOL alertable )
|
|||
|
||||
if (ret) return user_apc; /* no more APCs */
|
||||
|
||||
memset( &result, 0, sizeof(result) );
|
||||
|
||||
switch (call.type)
|
||||
{
|
||||
case APC_USER:
|
||||
|
|
|
@ -209,7 +209,15 @@ struct token_groups
|
|||
|
||||
};
|
||||
|
||||
enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC_IO };
|
||||
enum apc_type
|
||||
{
|
||||
APC_NONE,
|
||||
APC_USER,
|
||||
APC_TIMER,
|
||||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
|
@ -235,8 +243,43 @@ typedef union
|
|||
void *sb;
|
||||
unsigned int status;
|
||||
} async_io;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned int zero_bits;
|
||||
unsigned int op_type;
|
||||
unsigned int prot;
|
||||
} virtual_alloc;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned int op_type;
|
||||
} virtual_free;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
unsigned int status;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
} virtual_alloc;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
unsigned int status;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
} virtual_free;
|
||||
} apc_result_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -554,6 +597,7 @@ struct get_apc_request
|
|||
struct request_header __header;
|
||||
int alertable;
|
||||
obj_handle_t prev;
|
||||
apc_result_t result;
|
||||
};
|
||||
struct get_apc_reply
|
||||
{
|
||||
|
@ -564,6 +608,19 @@ struct get_apc_reply
|
|||
|
||||
|
||||
|
||||
struct get_apc_result_request
|
||||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
};
|
||||
struct get_apc_result_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
apc_result_t result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct close_handle_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -3803,6 +3860,7 @@ enum request
|
|||
REQ_unload_dll,
|
||||
REQ_queue_apc,
|
||||
REQ_get_apc,
|
||||
REQ_get_apc_result,
|
||||
REQ_close_handle,
|
||||
REQ_set_handle_info,
|
||||
REQ_dup_handle,
|
||||
|
@ -4023,6 +4081,7 @@ union generic_request
|
|||
struct unload_dll_request unload_dll_request;
|
||||
struct queue_apc_request queue_apc_request;
|
||||
struct get_apc_request get_apc_request;
|
||||
struct get_apc_result_request get_apc_result_request;
|
||||
struct close_handle_request close_handle_request;
|
||||
struct set_handle_info_request set_handle_info_request;
|
||||
struct dup_handle_request dup_handle_request;
|
||||
|
@ -4241,6 +4300,7 @@ union generic_reply
|
|||
struct unload_dll_reply unload_dll_reply;
|
||||
struct queue_apc_reply queue_apc_reply;
|
||||
struct get_apc_reply get_apc_reply;
|
||||
struct get_apc_result_reply get_apc_result_reply;
|
||||
struct close_handle_reply close_handle_reply;
|
||||
struct set_handle_info_reply set_handle_info_reply;
|
||||
struct dup_handle_reply dup_handle_reply;
|
||||
|
@ -4437,6 +4497,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 264
|
||||
#define SERVER_PROTOCOL_VERSION 265
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -225,7 +225,15 @@ struct token_groups
|
|||
/* VARARGS(sids,SID); */
|
||||
};
|
||||
|
||||
enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC_IO };
|
||||
enum apc_type
|
||||
{
|
||||
APC_NONE,
|
||||
APC_USER,
|
||||
APC_TIMER,
|
||||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
|
@ -251,8 +259,43 @@ typedef union
|
|||
void *sb; /* status block */
|
||||
unsigned int status; /* I/O status */
|
||||
} async_io;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_ALLOC */
|
||||
void *addr; /* requested address */
|
||||
unsigned long size; /* allocation size */
|
||||
unsigned int zero_bits; /* allocation alignment */
|
||||
unsigned int op_type; /* type of operation */
|
||||
unsigned int prot; /* memory protection flags */
|
||||
} virtual_alloc;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_FREE */
|
||||
void *addr; /* requested address */
|
||||
unsigned long size; /* allocation size */
|
||||
unsigned int op_type; /* type of operation */
|
||||
} virtual_free;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_ALLOC */
|
||||
unsigned int status; /* status returned by call */
|
||||
void *addr; /* resulting address */
|
||||
unsigned long size; /* resulting size */
|
||||
} virtual_alloc;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_FREE */
|
||||
unsigned int status; /* status returned by call */
|
||||
void *addr; /* resulting address */
|
||||
unsigned long size; /* resulting size */
|
||||
} virtual_free;
|
||||
} apc_result_t;
|
||||
|
||||
/****************************************************************/
|
||||
/* Request declarations */
|
||||
|
||||
|
@ -472,12 +515,21 @@ typedef union
|
|||
@REQ(get_apc)
|
||||
int alertable; /* is thread alertable? */
|
||||
obj_handle_t prev; /* handle to previous APC */
|
||||
apc_result_t result; /* result of previous APC */
|
||||
@REPLY
|
||||
obj_handle_t handle; /* handle to APC */
|
||||
apc_call_t call; /* call arguments */
|
||||
@END
|
||||
|
||||
|
||||
/* Get the result of an APC call */
|
||||
@REQ(get_apc_result)
|
||||
obj_handle_t handle; /* handle to the APC */
|
||||
@REPLY
|
||||
apc_result_t result; /* result of the APC */
|
||||
@END
|
||||
|
||||
|
||||
/* Close a handle for the current process */
|
||||
@REQ(close_handle)
|
||||
obj_handle_t handle; /* handle to close */
|
||||
|
|
|
@ -129,6 +129,7 @@ DECL_HANDLER(load_dll);
|
|||
DECL_HANDLER(unload_dll);
|
||||
DECL_HANDLER(queue_apc);
|
||||
DECL_HANDLER(get_apc);
|
||||
DECL_HANDLER(get_apc_result);
|
||||
DECL_HANDLER(close_handle);
|
||||
DECL_HANDLER(set_handle_info);
|
||||
DECL_HANDLER(dup_handle);
|
||||
|
@ -348,6 +349,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_unload_dll,
|
||||
(req_handler)req_queue_apc,
|
||||
(req_handler)req_get_apc,
|
||||
(req_handler)req_get_apc_result,
|
||||
(req_handler)req_close_handle,
|
||||
(req_handler)req_set_handle_info,
|
||||
(req_handler)req_dup_handle,
|
||||
|
|
|
@ -72,7 +72,8 @@ struct thread_apc
|
|||
struct list entry; /* queue linked list */
|
||||
struct object *owner; /* object that queued this apc */
|
||||
int executed; /* has it been executed by the client? */
|
||||
apc_call_t call;
|
||||
apc_call_t call; /* call arguments */
|
||||
apc_result_t result; /* call results once executed */
|
||||
};
|
||||
|
||||
static void dump_thread_apc( struct object *obj, int verbose );
|
||||
|
@ -1105,6 +1106,7 @@ DECL_HANDLER(get_apc)
|
|||
{
|
||||
if (!(apc = (struct thread_apc *)get_handle_obj( current->process, req->prev,
|
||||
0, &thread_apc_ops ))) return;
|
||||
apc->result = req->result;
|
||||
apc->executed = 1;
|
||||
wake_up( &apc->obj, 0 );
|
||||
close_handle( current->process, req->prev );
|
||||
|
@ -1135,6 +1137,23 @@ DECL_HANDLER(get_apc)
|
|||
release_object( apc );
|
||||
}
|
||||
|
||||
/* Get the result of an APC call */
|
||||
DECL_HANDLER(get_apc_result)
|
||||
{
|
||||
struct thread_apc *apc;
|
||||
|
||||
if (!(apc = (struct thread_apc *)get_handle_obj( current->process, req->handle,
|
||||
0, &thread_apc_ops ))) return;
|
||||
if (!apc->executed) set_error( STATUS_PENDING );
|
||||
else
|
||||
{
|
||||
reply->result = apc->result;
|
||||
/* close the handle directly to avoid an extra round-trip */
|
||||
close_handle( current->process, req->handle );
|
||||
}
|
||||
release_object( apc );
|
||||
}
|
||||
|
||||
/* retrieve the current context of a thread */
|
||||
DECL_HANDLER(get_thread_context)
|
||||
{
|
||||
|
|
|
@ -119,6 +119,17 @@ static void dump_apc_call( const apc_call_t *call )
|
|||
fprintf( stderr, "APC_ASYNC_IO,user=%p,sb=%p,status=%s",
|
||||
call->async_io.user, call->async_io.sb, get_status_name(call->async_io.status) );
|
||||
break;
|
||||
case APC_VIRTUAL_ALLOC:
|
||||
fprintf( stderr, "APC_VIRTUAL_ALLOC,addr=%p,size=%lu,zero_bits=%u,op_type=%x,prot=%x",
|
||||
call->virtual_alloc.addr, call->virtual_alloc.size,
|
||||
call->virtual_alloc.zero_bits, call->virtual_alloc.op_type,
|
||||
call->virtual_alloc.prot );
|
||||
break;
|
||||
case APC_VIRTUAL_FREE:
|
||||
fprintf( stderr, "APC_VIRTUAL_FREE,addr=%p,size=%lu,op_type=%x",
|
||||
call->virtual_free.addr, call->virtual_free.size,
|
||||
call->virtual_free.op_type );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", call->type );
|
||||
break;
|
||||
|
@ -126,6 +137,30 @@ static void dump_apc_call( const apc_call_t *call )
|
|||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_apc_result( const apc_result_t *result )
|
||||
{
|
||||
fputc( '{', stderr );
|
||||
switch(result->type)
|
||||
{
|
||||
case APC_NONE:
|
||||
break;
|
||||
case APC_VIRTUAL_ALLOC:
|
||||
fprintf( stderr, "APC_VIRTUAL_ALLOC,status=%s,addr=%p,size=%lu",
|
||||
get_status_name( result->virtual_alloc.status ),
|
||||
result->virtual_alloc.addr, result->virtual_alloc.size );
|
||||
break;
|
||||
case APC_VIRTUAL_FREE:
|
||||
fprintf( stderr, "APC_VIRTUAL_FREE,status=%s,addr=%p,size=%lu",
|
||||
get_status_name( result->virtual_free.status ),
|
||||
result->virtual_free.addr, result->virtual_free.size );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", result->type );
|
||||
break;
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_context( const CONTEXT *context )
|
||||
{
|
||||
#ifdef __i386__
|
||||
|
@ -882,7 +917,9 @@ static void dump_queue_apc_request( const struct queue_apc_request *req )
|
|||
static void dump_get_apc_request( const struct get_apc_request *req )
|
||||
{
|
||||
fprintf( stderr, " alertable=%d,", req->alertable );
|
||||
fprintf( stderr, " prev=%p", req->prev );
|
||||
fprintf( stderr, " prev=%p,", req->prev );
|
||||
fprintf( stderr, " result=" );
|
||||
dump_apc_result( &req->result );
|
||||
}
|
||||
|
||||
static void dump_get_apc_reply( const struct get_apc_reply *req )
|
||||
|
@ -892,6 +929,17 @@ static void dump_get_apc_reply( const struct get_apc_reply *req )
|
|||
dump_apc_call( &req->call );
|
||||
}
|
||||
|
||||
static void dump_get_apc_result_request( const struct get_apc_result_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_get_apc_result_reply( const struct get_apc_result_reply *req )
|
||||
{
|
||||
fprintf( stderr, " result=" );
|
||||
dump_apc_result( &req->result );
|
||||
}
|
||||
|
||||
static void dump_close_handle_request( const struct close_handle_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
|
@ -3310,6 +3358,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_unload_dll_request,
|
||||
(dump_func)dump_queue_apc_request,
|
||||
(dump_func)dump_get_apc_request,
|
||||
(dump_func)dump_get_apc_result_request,
|
||||
(dump_func)dump_close_handle_request,
|
||||
(dump_func)dump_set_handle_info_request,
|
||||
(dump_func)dump_dup_handle_request,
|
||||
|
@ -3526,6 +3575,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_get_apc_reply,
|
||||
(dump_func)dump_get_apc_result_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_set_handle_info_reply,
|
||||
(dump_func)dump_dup_handle_reply,
|
||||
|
@ -3742,6 +3792,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"unload_dll",
|
||||
"queue_apc",
|
||||
"get_apc",
|
||||
"get_apc_result",
|
||||
"close_handle",
|
||||
"set_handle_info",
|
||||
"dup_handle",
|
||||
|
|
|
@ -43,6 +43,7 @@ my %formats =
|
|||
"rectangle_t" => "&dump_rectangle",
|
||||
"char_info_t" => "&dump_char_info",
|
||||
"apc_call_t" => "&dump_apc_call",
|
||||
"apc_result_t" => "&dump_apc_result",
|
||||
);
|
||||
|
||||
my @requests = ();
|
||||
|
|
Loading…
Reference in New Issue