From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/unix/server.c | 2 +- dlls/ntdll/unix/signal_arm.c | 4 +++- dlls/ntdll/unix/signal_arm64.c | 4 +++- dlls/ntdll/unix/signal_i386.c | 4 +++- dlls/ntdll/unix/signal_x86_64.c | 4 +++- dlls/ntdll/unix/thread.c | 4 +++- dlls/ntdll/unix/unix_private.h | 4 ++-- include/wine/server_protocol.h | 7 +++++-- server/async.c | 1 + server/protocol.def | 5 ++++- server/timer.c | 1 + 11 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 3969c2bb898..0c99e9c2e66 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -385,7 +385,7 @@ static int wait_select_reply( void *cookie ) */ static NTSTATUS invoke_user_apc( CONTEXT *context, const struct user_apc *apc, NTSTATUS status ) { - return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2], + return call_user_apc_dispatcher( context, apc->flags, apc->args[0], apc->args[1], apc->args[2], wine_server_get_ptr( apc->func ), status ); }
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 45ca9f02c58..e429750925c 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -562,13 +562,15 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = get_syscall_frame(); ULONG sp = context ? context->Sp : frame->sp; struct apc_stack_layout *stack;
+ if (flags) FIXME( "flags %#x are not supported.\n", flags ); + sp &= ~7; stack = (struct apc_stack_layout *)sp - 1; if (context) diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 9964d0a9224..f5bd47d597a 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -747,13 +747,15 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = get_syscall_frame(); ULONG64 sp = context ? context->Sp : frame->sp; struct apc_stack_layout *stack;
+ if (flags) FIXME( "flags %#x are not supported.\n", flags ); + sp &= ~15; stack = (struct apc_stack_layout *)sp - 1; if (context) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 6eaffbc39c9..db72829bd1f 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1508,13 +1508,15 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = get_syscall_frame(); ULONG esp = context ? context->Esp : frame->esp; struct apc_stack_layout *stack = (struct apc_stack_layout *)esp - 1;
+ if (flags) FIXME( "flags %#x are not supported.\n", flags ); + if (!context) { stack->context.ContextFlags = CONTEXT_FULL; diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 93da4a6d8bb..7ebcf99658a 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1541,13 +1541,15 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = get_syscall_frame(); ULONG64 rsp = context ? context->Rsp : frame->rsp; struct apc_stack_layout *stack;
+ if (flags) FIXME( "flags %#x are not supported.\n", flags ); + rsp &= ~15; stack = (struct apc_stack_layout *)rsp - 1; if (context) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 23f9b8ad697..6c1ea2d0a00 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1730,7 +1730,6 @@ NTSTATUS WINAPI NtQueueApcThreadEx2( HANDLE handle, HANDLE reserve_handle, ULONG union apc_call call;
TRACE( "%p %p %#x %p %p %p %p.\n", handle, reserve_handle, flags, func, (void *)arg1, (void *)arg2, (void *)arg3 ); - if (flags) FIXME( "Unsupported flags %#x.\n", flags );
SERVER_START_REQ( queue_apc ) { @@ -1740,6 +1739,9 @@ NTSTATUS WINAPI NtQueueApcThreadEx2( HANDLE handle, HANDLE reserve_handle, ULONG { call.type = APC_USER; call.user.func = wine_server_client_ptr( func ); + call.user.flags = 0; + if (flags & QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC) call.user.flags |= SERVER_USER_APC_SPECIAL; + if (flags & QUEUE_USER_APC_CALLBACK_DATA_CONTEXT) call.user.flags |= SERVER_USER_APC_CALLBACK_DATA_CONTEXT; call.user.args[0] = arg1; call.user.args[1] = arg2; call.user.args[2] = arg3; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index fa38f4b87ca..1f6396bee0c 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -388,8 +388,8 @@ extern NTSTATUS wow64_wine_spawnvp( void *args );
extern void dbg_init(void);
-extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, - PNTAPCFUNC func, NTSTATUS status ); +extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, unsigned int flags, ULONG_PTR arg1, ULONG_PTR arg2, + ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ); extern NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ); extern void call_raise_user_exception_dispatcher(void);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 528dd435944..e14610d2bb5 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -491,11 +491,14 @@ enum apc_type struct user_apc { enum apc_type type; - int __pad; + unsigned int flags; client_ptr_t func; apc_param_t args[3]; };
+#define SERVER_USER_APC_SPECIAL 0x01 +#define SERVER_USER_APC_CALLBACK_DATA_CONTEXT 0x02 + union apc_call { enum apc_type type; @@ -6852,6 +6855,6 @@ union generic_reply struct set_keyboard_repeat_reply set_keyboard_repeat_reply; };
-#define SERVER_PROTOCOL_VERSION 883 +#define SERVER_PROTOCOL_VERSION 884
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/async.c b/server/async.c index 1ed241dcb65..4068f744567 100644 --- a/server/async.c +++ b/server/async.c @@ -519,6 +519,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota union apc_call data; memset( &data, 0, sizeof(data) ); data.type = APC_USER; + data.user.flags = 0; data.user.func = async->data.apc; data.user.args[0] = async->data.apc_context; data.user.args[1] = async->data.iosb; diff --git a/server/protocol.def b/server/protocol.def index 2d85c9619c7..ecc20a8e2d0 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -507,11 +507,14 @@ enum apc_type struct user_apc { enum apc_type type; /* APC_USER */ - int __pad; + unsigned int flags; /* SERVER_USER_APC_* flags */ client_ptr_t func; /* void (__stdcall *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR); */ apc_param_t args[3]; /* arguments for user function */ };
+#define SERVER_USER_APC_SPECIAL 0x01 +#define SERVER_USER_APC_CALLBACK_DATA_CONTEXT 0x02 + union apc_call { enum apc_type type; diff --git a/server/timer.c b/server/timer.c index 6357569ccba..522fc6a7113 100644 --- a/server/timer.c +++ b/server/timer.c @@ -136,6 +136,7 @@ static void timer_callback( void *private ) assert (timer->callback); memset( &data, 0, sizeof(data) ); data.type = APC_USER; + data.user.flags = 0; data.user.func = timer->callback; data.user.args[0] = timer->arg; data.user.args[1] = (unsigned int)timer->when;