Module: wine Branch: master Commit: 5075c31ed00b09f9bc0cbea9d940557e170eb17f URL: https://gitlab.winehq.org/wine/wine/-/commit/5075c31ed00b09f9bc0cbea9d940557...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Dec 12 16:31:25 2022 +0100
win32u: Call init_window_call_params after WH_CALLWNDPROC hook in call_window_proc.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53908 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52779
---
dlls/user32/tests/msg.c | 33 +++++++++++++++++++++++++++++++++ dlls/win32u/message.c | 22 ++++++++++------------ 2 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index e36eb7125e6..50bfc9855dd 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -19417,6 +19417,38 @@ static void test_create_name(void) UnregisterClassW( L"TestCreateNameClassW", NULL ); }
+static LRESULT WINAPI changed_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == WM_USER) return 3; + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static LRESULT WINAPI call_window_proc_hook( INT code, WPARAM wparam, LPARAM lparam ) +{ + CWPSTRUCT *cwp = (CWPSTRUCT *)lparam; + + ok( cwp->message == WM_USER, "message = %u\n", cwp->message ); + SetWindowLongPtrW( cwp->hwnd, GWLP_WNDPROC, (LONG_PTR)changed_window_proc ); + return CallNextHookEx( NULL, code, wparam, lparam ); +} + +static void test_hook_changing_window_proc(void) +{ + HWND hwnd; + HHOOK hook; + LRESULT res; + + hwnd = CreateWindowExW( 0, L"static", NULL, WS_POPUP, 0,0,0,0,GetDesktopWindow(),0,0, NULL ); + hook = SetWindowsHookExW( WH_CALLWNDPROC, call_window_proc_hook, NULL, GetCurrentThreadId() ); + ok( hook != NULL, "SetWindowsHookExW failed: %lu\n", GetLastError() ); + + res = SendMessageW( hwnd, WM_USER, 1, 2 ); + ok( res == 3, "SendMessageW(WM_USER) returned %Iu\n", res ); + + UnhookWindowsHookEx( hook ); + DestroyWindow( hwnd ); +} + START_TEST(msg) { char **test_argv; @@ -19534,6 +19566,7 @@ START_TEST(msg) test_TrackPopupMenuEmpty(); test_DoubleSetCapture(); test_create_name(); + test_hook_changing_window_proc(); /* keep it the last test, under Windows it tends to break the tests * which rely on active/foreground windows being correct. */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index ff417169ad1..d1eeacba39e 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1346,6 +1346,14 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
if (!needs_unpack) size = 0; if (!is_current_thread_window( hwnd )) return 0; + + /* first the WH_CALLWNDPROC hook */ + cwp.lParam = lparam; + 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) ); + if (size && !(params = malloc( sizeof(*params) + size ))) return 0; if (!init_window_call_params( params, hwnd, msg, wparam, lparam, &result, !unicode, mapping )) { @@ -1359,25 +1367,15 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar params->ansi = FALSE; if (size) memcpy( params + 1, buffer, size ); } - - /* first the WH_CALLWNDPROC hook */ - cwp.lParam = lparam; - cwp.wParam = wparam; - cwp.message = msg; - cwp.hwnd = params->hwnd; - call_hooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, sizeof(cwp) ); - dispatch_win_proc_params( params, sizeof(*params) + size ); + if (params != &p) free( params );
/* and finally the WH_CALLWNDPROCRET hook */ cwpret.lResult = result; cwpret.lParam = lparam; cwpret.wParam = wparam; cwpret.message = msg; - cwpret.hwnd = params->hwnd; - - if (params != &p) free( params ); - + cwpret.hwnd = hwnd; call_hooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, sizeof(cwpret) ); return result; }