Module: wine Branch: master Commit: 7cc06fb9999adfb79baea9348d5132e2b42d483d URL: https://gitlab.winehq.org/wine/wine/-/commit/7cc06fb9999adfb79baea9348d5132e...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Jul 19 16:22:32 2023 +0200
win32u: Pack messages in WH_CALLWNDPROC hooks.
---
dlls/user32/hook.c | 12 ++++++++++++ dlls/win32u/hook.c | 26 ++++++++++++++++++++------ dlls/win32u/message.c | 6 ++++-- dlls/win32u/win32u_private.h | 2 ++ dlls/wow64win/user.c | 9 +++++++++ 5 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 1465712adb2..1ae49587688 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -483,6 +483,18 @@ BOOL WINAPI User32CallWindowsHook( struct win_hook_params *params, ULONG size ) ret_size = sizeof(*cbtc.lpcs); } break; + case WH_CALLWNDPROC: + if (ret_size > sizeof(CWPSTRUCT)) + { + CWPSTRUCT *cwp = (CWPSTRUCT *)params->lparam; + size_t offset = (lparam_offset + sizeof(*cwp) + 15) & ~15; + void *buffer = (char *)params + offset; + + unpack_message( cwp->hwnd, cwp->message, &cwp->wParam, &cwp->lParam, + &buffer, size - offset, !params->prev_unicode ); + ret_size = 0; + break; + } } } if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index b880c8d37e0..27b109ce545 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -195,7 +195,8 @@ static UINT get_ll_hook_timeout(void) * Call hook either in current thread or send message to the destination * thread. */ -static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, size_t lparam_size ) +static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, size_t lparam_size, + size_t message_size, BOOL ansi ) { DWORD_PTR ret = 0;
@@ -230,7 +231,7 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz else if (info->proc) { struct user_thread_info *thread_info = get_user_thread_info(); - size_t size, lparam_offset = 0, message_offset = 0, message_size = 0; + size_t size, lparam_offset = 0, message_offset = 0; size_t lparam_ret_size = lparam_size; HHOOK prev = thread_info->hook; BOOL prev_unicode = thread_info->hook_unicode; @@ -287,6 +288,13 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz WM_CREATE, lp, FALSE ); } break; + case WH_CALLWNDPROC: + { + CWPSTRUCT *cwp = (CWPSTRUCT *)((char *)params + lparam_offset); + pack_user_message( (char *)params + message_offset, message_size, + cwp->message, cwp->lParam, ansi ); + } + break; } }
@@ -357,7 +365,7 @@ LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARA info.wparam = wparam; info.lparam = lparam; info.prev_unicode = thread_info->hook_unicode; - return call_hook( &info, module, 0 ); + return call_hook( &info, module, 0, 0, FALSE ); }
LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) @@ -390,10 +398,11 @@ LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) info.wparam = wparam; info.lparam = lparam; info.prev_unicode = TRUE; /* assume Unicode for this function */ - return call_hook( &info, module, 0 ); + return call_hook( &info, module, 0, 0, FALSE ); }
-LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size ) +LRESULT call_message_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size, + size_t message_size, BOOL ansi ) { struct user_thread_info *thread_info = get_user_thread_info(); struct win_hook_params info; @@ -434,7 +443,7 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lpara info.code = code; info.wparam = wparam; info.lparam = lparam; - ret = call_hook( &info, module, lparam_size ); + ret = call_hook( &info, module, lparam_size, message_size, ansi );
SERVER_START_REQ( finish_hook_chain ) { @@ -445,6 +454,11 @@ LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lpara return ret; }
+LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size ) +{ + return call_message_hooks( id, code, wparam, lparam, lparam_size, 0, FALSE ); +} + /*********************************************************************** * NtUserSetWinEventHook (win32u.@) */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index fe048e0ee38..5aec4c5eb95 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1530,7 +1530,8 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwp.wParam = wparam; cwp.message = msg; cwp.hwnd = hwnd = get_full_window_handle( hwnd ); - call_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, sizeof(cwp) ); + call_message_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, sizeof(cwp), + packed_size, ansi );
if (size && !(params = malloc( sizeof(*params) + size ))) return 0; if (!init_window_call_params( params, hwnd, msg, wparam, lparam, !unicode, mapping )) @@ -1557,7 +1558,8 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar cwpret.wParam = wparam; cwpret.message = msg; cwpret.hwnd = hwnd; - call_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, sizeof(cwpret) ); + call_message_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, sizeof(cwpret), + packed_size, ansi ); return result; }
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 8d6fb34776d..b27ba7fab14 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -75,6 +75,8 @@ extern LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size_t lparam_size ) DECLSPEC_HIDDEN; +extern LRESULT call_message_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, + size_t lparam_size, size_t message_size, BOOL ansi ) DECLSPEC_HIDDEN; extern BOOL is_hooked( INT id ) DECLSPEC_HIDDEN; extern BOOL unhook_windows_hook( INT id, HOOKPROC proc ) DECLSPEC_HIDDEN;
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 1fad0f566fd..94df46cbb90 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -744,6 +744,15 @@ static UINT hook_lparam_64to32( int id, int code, const void *lp, size_t size, v cwp32.message = cwp->message; cwp32.hwnd = HandleToUlong( cwp->hwnd ); memcpy( lp32, &cwp32, sizeof(cwp32) ); + if (size > sizeof(*cwp)) + { + const size_t offset64 = (sizeof(*cwp) + 15) & ~15; + const size_t offset32 = (sizeof(cwp32) + 15) & ~15; + size = packed_message_64to32( cwp32.message, + (const char *)lp + offset64, + (char *)lp32 + offset32, size - offset64 ); + return offset32 + size; + } return sizeof(cwp32); }