From e3049f11fad715c65d8b62fcdaed660e39ffde5d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 6 Jun 2023 15:55:51 +0200 Subject: [PATCH] server: Send the APC call data as vararg in the queue_apc request. To make it possible to support a larger structure. --- dlls/ntdll/unix/server.c | 2 +- dlls/ntdll/unix/thread.c | 13 +++++++------ include/wine/server_protocol.h | 4 ++-- server/protocol.def | 2 +- server/request.h | 3 +-- server/thread.c | 8 ++++++-- server/trace.c | 14 +++++++++++++- 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 227784448d3..fe57b622f94 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -819,7 +819,7 @@ unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, a SERVER_START_REQ( queue_apc ) { req->handle = wine_server_obj_handle( process ); - req->call = *call; + wine_server_add_data( req, call, sizeof(*call) ); if (!(ret = wine_server_call( req ))) { handle = wine_server_ptr_handle( reply->handle ); diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 3e2be2feaff..6eabfb9a834 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1680,19 +1680,20 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1 ULONG_PTR arg2, ULONG_PTR arg3 ) { unsigned int ret; + apc_call_t call; SERVER_START_REQ( queue_apc ) { req->handle = wine_server_obj_handle( handle ); if (func) { - req->call.type = APC_USER; - req->call.user.func = wine_server_client_ptr( func ); - req->call.user.args[0] = arg1; - req->call.user.args[1] = arg2; - req->call.user.args[2] = arg3; + call.type = APC_USER; + call.user.func = wine_server_client_ptr( func ); + call.user.args[0] = arg1; + call.user.args[1] = arg2; + call.user.args[2] = arg3; + wine_server_add_data( req, &call, sizeof(call) ); } - else req->call.type = APC_NONE; /* wake up only */ ret = wine_server_call( req ); } SERVER_END_REQ; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 881b6022086..340512a054e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1236,7 +1236,7 @@ struct queue_apc_request { struct request_header __header; obj_handle_t handle; - apc_call_t call; + /* VARARG(call,apc_call); */ }; struct queue_apc_reply { @@ -6413,7 +6413,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 772 +#define SERVER_PROTOCOL_VERSION 773 /* ### protocol_version end ### */ diff --git a/server/protocol.def b/server/protocol.def index 49fe8012606..7995f481e19 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1133,7 +1133,7 @@ typedef struct /* Queue an APC for a thread or process */ @REQ(queue_apc) obj_handle_t handle; /* thread or process handle */ - apc_call_t call; /* call arguments */ + VARARG(call,apc_call); /* call arguments */ @REPLY obj_handle_t handle; /* APC handle */ int self; /* run APC in caller itself? */ diff --git a/server/request.h b/server/request.h index 07a5546d008..b13381d3fe1 100644 --- a/server/request.h +++ b/server/request.h @@ -861,8 +861,7 @@ C_ASSERT( sizeof(struct resume_thread_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct resume_thread_reply, count) == 8 ); C_ASSERT( sizeof(struct resume_thread_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct queue_apc_request, handle) == 12 ); -C_ASSERT( FIELD_OFFSET(struct queue_apc_request, call) == 16 ); -C_ASSERT( sizeof(struct queue_apc_request) == 64 ); +C_ASSERT( sizeof(struct queue_apc_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct queue_apc_reply, handle) == 8 ); C_ASSERT( FIELD_OFFSET(struct queue_apc_reply, self) == 12 ); C_ASSERT( sizeof(struct queue_apc_reply) == 16 ); diff --git a/server/thread.c b/server/thread.c index 9e29cf617f5..5299f6c042d 100644 --- a/server/thread.c +++ b/server/thread.c @@ -514,7 +514,8 @@ static struct thread_apc *create_apc( struct object *owner, const apc_call_t *ca if ((apc = alloc_object( &thread_apc_ops ))) { - apc->call = *call_data; + if (call_data) apc->call = *call_data; + else apc->call.type = APC_NONE; apc->caller = NULL; apc->owner = owner; apc->executed = 0; @@ -1701,8 +1702,11 @@ DECL_HANDLER(queue_apc) struct thread *thread = NULL; struct process *process = NULL; struct thread_apc *apc; + const apc_call_t *call = get_req_data(); - if (!(apc = create_apc( NULL, &req->call ))) return; + if (get_req_data_size() < sizeof(*call)) call = NULL; + + if (!(apc = create_apc( NULL, call ))) return; switch (apc->call.type) { diff --git a/server/trace.c b/server/trace.c index 2950edac3e5..7cd6f8938d3 100644 --- a/server/trace.c +++ b/server/trace.c @@ -540,6 +540,18 @@ static void dump_varargs_ushorts( const char *prefix, data_size_t size ) remove_data( size ); } +static void dump_varargs_apc_call( const char *prefix, data_size_t size ) +{ + const apc_call_t *call = cur_data; + + if (size >= sizeof(*call)) + { + dump_apc_call( prefix, call ); + size = sizeof(*call); + } + remove_data( size ); +} + static void dump_varargs_apc_result( const char *prefix, data_size_t size ) { const apc_result_t *result = cur_data; @@ -1640,7 +1652,7 @@ static void dump_resume_thread_reply( const struct resume_thread_reply *req ) static void dump_queue_apc_request( const struct queue_apc_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); - dump_apc_call( ", call=", &req->call ); + dump_varargs_apc_call( ", call=", cur_size ); } static void dump_queue_apc_reply( const struct queue_apc_reply *req ) -- 2.11.4.GIT