From 177eb908c9433bd1b45c243d3b13e996711c1cd3 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 4 Apr 2022 16:57:23 +0200 Subject: [PATCH] win32u: Return LRESULT from NtUserMessageCall. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/user32/user_main.c | 3 +- dlls/user32/winproc.c | 4 +- dlls/win32u/message.c | 20 +++----- dlls/win32u/tests/win32u.c | 97 ++++++++++++++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 4 +- dlls/win32u/window.c | 8 ++- dlls/win32u/wrappers.c | 4 +- include/ntuser.h | 29 ++++++++--- 8 files changed, 138 insertions(+), 31 deletions(-) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 13bb8f37e00..72566f0fa03 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -377,5 +377,6 @@ void SPY_EnterMessage( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar void SPY_ExitMessage( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam ) { - if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, lreturn, FNID_SPYEXIT, flag ); + if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, (void *)lreturn, + FNID_SPYEXIT, flag ); } diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 2d3e9a25d84..51c89111202 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -1332,7 +1332,7 @@ LRESULT WINAPI CallWindowProcA( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam params.func = func; params.result = &result; - if (!NtUserMessageCall( hwnd, msg, wParam, lParam, (ULONG_PTR)¶ms, FNID_CALLWNDPROC, TRUE )) + if (!NtUserMessageCall( hwnd, msg, wParam, lParam, ¶ms, FNID_CALLWNDPROC, TRUE )) return 0; dispatch_win_proc_params( ¶ms ); return result; @@ -1351,7 +1351,7 @@ LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam params.func = func; params.result = &result; - if (!NtUserMessageCall( hwnd, msg, wParam, lParam, (ULONG_PTR)¶ms, FNID_CALLWNDPROC, FALSE )) + if (!NtUserMessageCall( hwnd, msg, wParam, lParam, ¶ms, FNID_CALLWNDPROC, FALSE )) return 0; dispatch_win_proc_params( ¶ms ); return result; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 1d4074c7a11..0f84ad055e7 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2133,23 +2133,19 @@ BOOL kill_system_timer( HWND hwnd, UINT_PTR id ) return ret; } -static BOOL send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - LRESULT *result, BOOL ansi ) +static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { /* FIXME: move implementation from user32 */ if (!user_callbacks) return FALSE; - *result = ansi + return ansi ? user_callbacks->pSendMessageA( hwnd, msg, wparam, lparam ) : user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam ); - return TRUE; } /* see SendMessageW */ LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { - LRESULT result = 0; - send_window_message( hwnd, msg, wparam, lparam, &result, FALSE ); - return result; + return send_window_message( hwnd, msg, wparam, lparam, FALSE ); } /* see SendNotifyMessageW */ @@ -2166,8 +2162,8 @@ LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) return user_callbacks->pPostMessageW( hwnd, msg, wparam, lparam ); } -BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - ULONG_PTR result_info, DWORD type, BOOL ansi ) +LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ) { switch (type) { @@ -2175,17 +2171,17 @@ BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam return init_win_proc_params( (struct win_proc_params *)result_info, hwnd, msg, wparam, lparam, ansi ); case FNID_SENDMESSAGE: - return send_window_message( hwnd, msg, wparam, lparam, (LRESULT *)result_info, ansi ); + return send_window_message( hwnd, msg, wparam, lparam, ansi ); case FNID_SENDNOTIFYMESSAGE: return send_notify_message( hwnd, msg, wparam, lparam, ansi ); case FNID_SPYENTER: spy_enter_message( ansi, hwnd, msg, wparam, lparam ); return 0; case FNID_SPYEXIT: - spy_exit_message( ansi, hwnd, msg, result_info, wparam, lparam ); + spy_exit_message( ansi, hwnd, msg, (LPARAM)result_info, wparam, lparam ); return 0; default: - FIXME( "%p %x %lx %lx %lx %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); + FIXME( "%p %x %lx %lx %p %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); } return 0; } diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 40ea1e58687..33b50ef53b1 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -381,6 +381,102 @@ static void test_cursoricon(void) ok(ret, "Destroy icon failed, error %lu.\n", GetLastError()); } +static LRESULT WINAPI test_message_call_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + switch (msg) + { + case WM_SETTEXT: + ok( !wcscmp( (const WCHAR *)lparam, L"test" ), + "lparam = %s\n", wine_dbgstr_w( (const WCHAR *)lparam )); + return 6; + case WM_USER: + ok( wparam == 1, "wparam = %Iu\n", wparam ); + ok( lparam == 2, "lparam = %Iu\n", lparam ); + return 3; + case WM_USER + 1: + return lparam; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static void WINAPI test_message_callback( HWND hwnd, UINT msg, ULONG_PTR data, LRESULT result ) +{ + ok( msg == WM_USER, "msg = %u\n", msg ); + ok( data == 10, "data = %Iu\n", data ); + ok( result == 3, "result = %Iu\n", result ); +} + +static void test_message_call(void) +{ + const LPARAM large_lparam = (LPARAM)(3 + ((ULONGLONG)1 << 60)); + struct send_message_callback_params callback_params = { + .callback = test_message_callback, + .data = 10, + }; + struct send_message_timeout_params smp; + WNDCLASSW cls = { 0 }; + LRESULT res; + HWND hwnd; + + cls.lpfnWndProc = test_message_call_proc; + cls.lpszClassName = L"TestClass"; + RegisterClassW( &cls ); + + hwnd = CreateWindowExW( 0, L"TestClass", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL ); + + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, FNID_SENDMESSAGE, FALSE ); + ok( res == 3, "res = %Iu\n", res ); + + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, FNID_SENDMESSAGE, TRUE ); + ok( res == 3, "res = %Iu\n", res ); + + res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)L"test", NULL, FNID_SENDMESSAGE, FALSE ); + ok( res == 6, "res = %Iu\n", res ); + + res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)"test", NULL, FNID_SENDMESSAGE, TRUE ); + ok( res == 6, "res = %Iu\n", res ); + + SetLastError( 0xdeadbeef ); + res = NtUserMessageCall( UlongToHandle(0xdeadbeef), WM_USER, 1, 2, 0, FNID_SENDMESSAGE, TRUE ); + ok( !res, "res = %Iu\n", res ); + ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "GetLastError() = %lu\n", GetLastError()); + + res = NtUserMessageCall( hwnd, WM_USER + 1, 0, large_lparam, 0, FNID_SENDMESSAGE, FALSE ); + ok( res == large_lparam, "res = %Iu\n", res ); + + smp.flags = 0; + smp.timeout = 10; + smp.result = 0xdeadbeef; + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, &smp, FNID_SENDMESSAGEWTOOPTION, FALSE ); + todo_wine + ok( res == 3, "res = %Iu\n", res ); + todo_wine + ok( smp.result == 1, "smp.result = %Iu\n", smp.result ); + + smp.flags = 0; + smp.timeout = 10; + smp.result = 0xdeadbeef; + res = NtUserMessageCall( hwnd, WM_USER + 1, 0, large_lparam, + &smp, FNID_SENDMESSAGEWTOOPTION, FALSE ); + todo_wine + ok( res == large_lparam, "res = %Iu\n", res ); + todo_wine + ok( smp.result == 1, "smp.result = %Iu\n", smp.result ); + + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, + FNID_SENDNOTIFYMESSAGE, FALSE ); + ok( res == 1, "res = %Iu\n", res ); + + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, &callback_params, + FNID_SENDMESSAGECALLBACK, FALSE ); + todo_wine + ok( res == 1, "res = %Iu\n", res ); + + DestroyWindow( hwnd ); + UnregisterClassW( L"TestClass", NULL ); +} + START_TEST(win32u) { /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */ @@ -391,6 +487,7 @@ START_TEST(win32u) test_class(); test_NtUserBuildHwndList(); test_cursoricon(); + test_message_call(); test_NtUserCloseWindowStation(); } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 9b88c473864..350372b0ed7 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -236,8 +236,8 @@ struct unix_funcs BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); - BOOL (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - ULONG_PTR result_info, DWORD type, BOOL ansi ); + LRESULT (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ); BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ); DWORD (WINAPI *pNtUserMsgWaitForMultipleObjectsEx)( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 59761b8185c..09f3fc01e58 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4667,7 +4667,6 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, DPI_AWARENESS_CONTEXT context; HWND hwnd, owner = 0; INT sw = SW_SHOW; - LRESULT result; RECT rect; WND *win; @@ -4846,8 +4845,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs.x, cs.y, cs.cx, cs.cy, wine_dbgstr_rect(&rect) ); *client_cs = cs; - if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result, - FNID_SENDMESSAGE, ansi ) || !result) + if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, NULL, FNID_SENDMESSAGE, ansi )) { WARN( "%p: aborted by WM_NCCREATE\n", hwnd ); goto failed; @@ -4879,8 +4877,8 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, else goto failed; /* send WM_CREATE */ - if (!NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result, - FNID_SENDMESSAGE, ansi ) || result == -1) goto failed; + if (NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, 0, FNID_SENDMESSAGE, ansi ) == -1) + goto failed; cs = *client_cs; /* call the driver */ diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 8e53a3adc8c..4f7c6191df8 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -957,8 +957,8 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ) return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout ); } -BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - ULONG_PTR result_info, DWORD type, BOOL ansi ) +LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ) { if (!unix_funcs) return 0; return unix_funcs->pNtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); diff --git a/include/ntuser.h b/include/ntuser.h index b6672124c88..4515a9ce0f1 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -239,12 +239,27 @@ enum /* NtUserMessageCall codes */ enum { - FNID_CALLWNDPROC = 0x02ab, - FNID_SENDMESSAGE = 0x02b1, - FNID_SENDNOTIFYMESSAGE = 0x02b7, + FNID_CALLWNDPROC = 0x02ab, + FNID_SENDMESSAGE = 0x02b1, + FNID_SENDMESSAGEWTOOPTION = 0x02b3, + FNID_SENDNOTIFYMESSAGE = 0x02b7, + FNID_SENDMESSAGECALLBACK = 0x02b8, /* Wine-specific exports */ - FNID_SPYENTER = 0x0300, - FNID_SPYEXIT = 0x0301, + FNID_SPYENTER = 0x0300, + FNID_SPYEXIT = 0x0301, +}; + +struct send_message_timeout_params +{ + UINT flags; + UINT timeout; + DWORD_PTR result; +}; + +struct send_message_callback_params +{ + SENDASYNCPROC callback; + ULONG_PTR data; }; /* color index used to retrieve system 55aa brush */ @@ -582,8 +597,8 @@ INT WINAPI NtUserInternalGetWindowText( HWND hwnd, WCHAR *text, INT count ); BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format ); BOOL WINAPI NtUserKillTimer( HWND hwnd, UINT_PTR id ); UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ); -BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, - ULONG_PTR result_info, DWORD type, BOOL ansi ); +LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + void *result_info, DWORD type, BOOL ansi ); BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ); DWORD WINAPI NtUserMsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags );