Module: wine Branch: master Commit: 2c8b60af43fb8fee3b8485eb7b3374e494dfd6f4 URL: https://gitlab.winehq.org/wine/wine/-/commit/2c8b60af43fb8fee3b8485eb7b3374e...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jan 18 15:16:13 2024 +0100
user32: Return result through NtCallbackReturn for the window hook callback.
---
dlls/user32/hook.c | 14 ++++++++++++-- dlls/user32/user_private.h | 2 +- dlls/win32u/hook.c | 11 ++++++++--- dlls/wow64win/user.c | 20 +++++++++++--------- 4 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 024bb5b7116..4f5b8d13973 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -62,6 +62,8 @@ * WH_MOUSE_LL Implemented but should use SendMessage instead */
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "user_private.h" #include "wine/asm.h" #include "wine/debug.h" @@ -452,8 +454,9 @@ BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params, return TRUE; }
-BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) +NTSTATUS WINAPI User32CallWindowsHook( void *args, ULONG size ) { + struct win_hook_params *params = args; HOOKPROC proc = params->proc; HMODULE free_module = 0; void *ret_ptr = NULL; @@ -514,7 +517,14 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) params->prev_unicode, params->next_unicode );
if (free_module) FreeLibrary( free_module ); - return NtCallbackReturn( ret_ptr, ret_size, ret ); + + if (ret_size) + { + LRESULT *result_ptr = (LRESULT *)ret_ptr - 1; + *result_ptr = ret; + return NtCallbackReturn( result_ptr, sizeof(*result_ptr) + ret_size, STATUS_SUCCESS ); + } + return NtCallbackReturn( &ret, sizeof(ret), STATUS_SUCCESS ); }
/*********************************************************************** diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 9022e44b7d2..40d67ac468d 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -85,7 +85,7 @@ NTSTATUS WINAPI User32CallEnumDisplayMonitor( void *args, ULONG size ); BOOL WINAPI User32CallSendAsyncCallback( const struct send_async_params *params, ULONG size ); BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params, ULONG size ); BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ); -BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ); +NTSTATUS WINAPI User32CallWindowsHook( void *args, ULONG size ); BOOL WINAPI User32InitBuiltinClasses( const struct win_hook_params *params, ULONG size );
/* message spy definitions */ diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index 378eda40abb..fab2b960fa5 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -330,9 +330,14 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz thread_info->hook = params->handle; thread_info->hook_unicode = params->next_unicode; thread_info->hook_call_depth++; - ret = KeUserModeCallback( NtUserCallWindowsHook, params, size, &ret_ptr, &ret_len ); - if (ret_len && ret_len == lparam_ret_size) - memcpy( (void *)params->lparam, ret_ptr, ret_len ); + if (!KeUserModeCallback( NtUserCallWindowsHook, params, size, &ret_ptr, &ret_len ) && + ret_len >= sizeof(ret)) + { + LRESULT *result_ptr = ret_ptr; + ret = *result_ptr; + if (ret_len == sizeof(ret) + lparam_ret_size) + memcpy( (void *)params->lparam, result_ptr + 1, ret_len - sizeof(ret) ); + } thread_info->hook = prev; thread_info->hook_unicode = prev_unicode; thread_info->hook_call_depth--; diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index d1f8a04e959..2dd811578f5 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -1113,8 +1113,9 @@ static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) struct win_hook_params32 params32; UINT module_len, size32, offset; void *ret_ptr; - ULONG ret_len; - NTSTATUS ret; + LRESULT *result_ptr = arg; + ULONG ret_len, ret_size = 0; + NTSTATUS status;
module_len = wcslen( params->module ); size32 = FIELD_OFFSET( struct win_hook_params32, module[module_len + 1] ); @@ -1142,22 +1143,23 @@ static NTSTATUS WINAPI wow64_NtUserCallWindowsHook( void *arg, ULONG size ) size - offset, (char *)arg + size32 ); }
- ret = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, size32, &ret_ptr, &ret_len ); + status = Wow64KiUserCallbackDispatcher( NtUserCallWindowsHook, arg, size32, &ret_ptr, &ret_len ); + if (status || ret_len < sizeof(LONG)) return status;
switch (params32.id) { case WH_SYSMSGFILTER: case WH_MSGFILTER: case WH_GETMESSAGE: - if (ret_len == sizeof(MSG32)) + if (ret_len == sizeof(MSG32) + sizeof(LONG)) { - MSG msg; - msg_32to64( &msg, ret_ptr ); - return NtCallbackReturn( &msg, sizeof(msg), ret ); + msg_32to64( (MSG *)(result_ptr + 1), (MSG32 *)((LONG *)ret_ptr + 1) ); + ret_size = sizeof(MSG); } + break; } - - return ret; + *result_ptr = *(LONG *)ret_ptr; + return NtCallbackReturn( result_ptr, sizeof(*result_ptr) + ret_size, status ); }
static NTSTATUS WINAPI wow64_NtUserCopyImage( void *arg, ULONG size )