win32u is mostly ready for using syscall interface (for functions not taking HDC as an argument), but using client callbacks from syscalls will affect ability to unwind exceptions in a number of cases. On Windows, depending on kernel version, there are three different behaviors:
(1) On 32-bit Windows kernels unwinding works across client callbacks. (2) On early 64-bit Windows kernels exceptions from client callbacks are filtered and ignored. (3) On recent Windows kernels exceptions from client callbacks are treated as unhandled exceptions.
(1) is tempting because that's closest to how our pre-syscall code works. I prototyped that and I think we could make it work, but it's an additional complication to syscall interface that didn't really feel worth comparing to other options.
ntdll part of this MR implements (2). I think we would ideally use (3) instead, but it's much more risky (and syscall conversion seems risky enough on its own). Microsoft incrementally transitioned from (2) to (3) with some compatibility mitigations involved.
On top of that, some user32 calls that have win32u counterpars are still unwindable, unlike win32u variants. For example, DispatchMessageW behaves identical to NtUserDispatchMessage, except that it allow unwinding through the call, which suggests that the final call to window proc is done directly by user32, without kernel->client callback. SendMessage is also sometimes unwindable, but only when doing trivial winproc calls (but things like installing hook change that).
-- v2: win32u: Get rid of no longer needed NtUserSetCallbacks. win32u: Use syscall interface for NtUserMessageCall and NtUserTrackPopupMenuEx. win32u: Use syscall interface for NtUserMsgWaitForMultipleObjectsEx. win32u/tests: Add tests for catching exceptions from timer proc. win32u: Use syscall interface for NtUserDispatchMessage. ntdll: Suppress callback exceptions in KiUserCallbackDispatcher. win32u: Avoid using client callbacks for NtUserSendMessage. win32u: Remove no longer needed NtUserDispatchMessageA. user32: Avoid using NtUserDispatchMessage in DispatchMessage.
From: Jacek Caban jacek@codeweavers.com
When possible, call window proc on PE side to allow unwinding exceptions through DispatchMessageW call. --- dlls/user32/message.c | 26 ++++++++++++++++++++++++++ dlls/user32/user_private.h | 1 + dlls/user32/winproc.c | 2 +- dlls/win32u/message.c | 9 +++++++++ include/ntuser.h | 5 +++-- 5 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index f4e9b5b404e..f72d837ac94 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -832,6 +832,22 @@ BOOL WINAPI TranslateMessage( const MSG *msg ) }
+static LRESULT dispatch_message( const MSG *msg, BOOL ansi ) +{ + struct win_proc_params params; + LRESULT retval = 0; + + if (!NtUserMessageCall( msg->hwnd, msg->message, msg->wParam, msg->lParam, + ¶ms, NtUserGetDispatchParams, ansi )) return 0; + params.result = &retval; + + SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam ); + dispatch_win_proc_params( ¶ms ); + SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam ); + return retval; +} + + /*********************************************************************** * DispatchMessageA (USER32.@) * @@ -856,6 +872,11 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageA( const MSG* msg ) __ENDTRY return retval; } + + /* whenever possible, avoid using NtUserDispatchMessage to make the call unwindable */ + if (msg->message != WM_SYSTIMER && msg->message != WM_PAINT) + return dispatch_message( msg, TRUE ); + return NtUserDispatchMessageA( msg ); }
@@ -904,6 +925,11 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageW( const MSG* msg ) return retval; } } + + /* whenever possible, avoid using NtUserDispatchMessage to make the call unwindable */ + if (msg->message != WM_SYSTIMER && msg->message != WM_PAINT) + return dispatch_message( msg, FALSE ); + return NtUserDispatchMessage( msg ); }
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 2e09605cc03..81c3c5021ab 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -89,6 +89,7 @@ extern LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UIN extern INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; extern INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; extern void winproc_init(void) DECLSPEC_HIDDEN; +extern void dispatch_win_proc_params( struct win_proc_params *params ) DECLSPEC_HIDDEN; extern void get_winproc_params( struct win_proc_params *params ) DECLSPEC_HIDDEN;
extern ATOM get_class_info( HINSTANCE instance, const WCHAR *name, WNDCLASSEXW *info, diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 098bd17fbc0..5fc134c6718 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -719,7 +719,7 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN }
-static void dispatch_win_proc_params( struct win_proc_params *params ) +void dispatch_win_proc_params( struct win_proc_params *params ) { DPI_AWARENESS_CONTEXT context = SetThreadDpiAwarenessContext( params->dpi_awareness );
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 0045c8a54c0..50bce801339 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2952,6 +2952,15 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa case NtUserClipboardWindowProc: return user_driver->pClipboardWindowProc( hwnd, msg, wparam, lparam );
+ case NtUserGetDispatchParams: + if (!hwnd) return FALSE; + if (init_window_call_params( result_info, hwnd, msg, wparam, lparam, + NULL, ansi, WMCHAR_MAP_DISPATCHMESSAGE )) + return TRUE; + if (!is_window( hwnd )) SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + else SetLastError( ERROR_MESSAGE_SYNC_ONLY ); + return FALSE; + case NtUserSpyEnter: spy_enter_message( ansi, hwnd, msg, wparam, lparam ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 8cd7833717f..b0ebfbfcf5f 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -276,8 +276,9 @@ enum NtUserSendMessageCallback = 0x02b8, /* Wine-specific exports */ NtUserClipboardWindowProc = 0x0300, - NtUserSpyEnter = 0x0301, - NtUserSpyExit = 0x0302, + NtUserGetDispatchParams = 0x3001, + NtUserSpyEnter = 0x0302, + NtUserSpyExit = 0x0303, };
/* NtUserThunkedMenuItemInfo codes */
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/message.c | 2 +- dlls/win32u/message.c | 16 ++++------------ dlls/win32u/sysparams.c | 3 --- dlls/win32u/win32u_private.h | 1 - include/ntuser.h | 6 ------ 5 files changed, 5 insertions(+), 23 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index f72d837ac94..40babb71eba 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -877,7 +877,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageA( const MSG* msg ) if (msg->message != WM_SYSTIMER && msg->message != WM_PAINT) return dispatch_message( msg, TRUE );
- return NtUserDispatchMessageA( msg ); + return NtUserDispatchMessage( msg ); }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 50bce801339..49dc3fd6d08 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2496,9 +2496,9 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r }
/********************************************************************** - * dispatch_message + * NtUserDispatchMessage (win32u.@) */ -LRESULT dispatch_message( const MSG *msg, BOOL ansi ) +LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ) { struct win_proc_params params; LRESULT retval = 0; @@ -2509,7 +2509,7 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) params.func = (WNDPROC)msg->lParam; params.result = &retval; /* FIXME */ if (!init_win_proc_params( ¶ms, msg->hwnd, msg->message, - msg->wParam, NtGetTickCount(), ansi )) + msg->wParam, NtGetTickCount(), FALSE )) return 0; __TRY { @@ -2541,7 +2541,7 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) spy_enter_message( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam );
if (init_window_call_params( ¶ms, msg->hwnd, msg->message, msg->wParam, msg->lParam, - &retval, ansi, WMCHAR_MAP_DISPATCHMESSAGE )) + &retval, FALSE, WMCHAR_MAP_DISPATCHMESSAGE )) dispatch_win_proc_params( ¶ms, sizeof(params) ); else if (!is_window( msg->hwnd )) SetLastError( ERROR_INVALID_WINDOW_HANDLE ); else SetLastError( ERROR_MESSAGE_SYNC_ONLY ); @@ -2558,14 +2558,6 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) return retval; }
-/********************************************************************** - * NtUserDispatchMessage (win32u.@) - */ -LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ) -{ - return dispatch_message( msg, FALSE ); -} - static BOOL is_message_broadcastable( UINT msg ) { return msg < WM_USER || msg >= 0xc000; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 2c1f8f4241f..e8b55616f6a 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4880,9 +4880,6 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) case NtUserCallOneParam_CreateMenu: return HandleToUlong( create_menu( arg ) );
- case NtUserCallOneParam_DispatchMessageA: - return dispatch_message( (const MSG *)arg, TRUE ); - case NtUserCallOneParam_EnableDC: return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index a0b3e8c2e9e..a7f0624fdba 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -436,7 +436,6 @@ extern void track_keyboard_menu_bar( HWND hwnd, UINT wparam, WCHAR ch ) DECLSPEC extern void track_mouse_menu_bar( HWND hwnd, INT ht, int x, int y ) DECLSPEC_HIDDEN;
/* message.c */ -extern LRESULT dispatch_message( const MSG *msg, BOOL ansi ) DECLSPEC_HIDDEN; extern BOOL kill_system_timer( HWND hwnd, UINT_PTR id ) DECLSPEC_HIDDEN; extern BOOL reply_message_result( LRESULT result, MSG *msg ) DECLSPEC_HIDDEN; extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput, diff --git a/include/ntuser.h b/include/ntuser.h index b0ebfbfcf5f..67058defb6f 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -902,7 +902,6 @@ enum NtUserCallOneParam_BeginDeferWindowPos, NtUserCallOneParam_CreateCursorIcon, NtUserCallOneParam_CreateMenu, - NtUserCallOneParam_DispatchMessageA, NtUserCallOneParam_EnableDC, NtUserCallOneParam_EnableThunkLock, NtUserCallOneParam_EnumClipboardFormats, @@ -944,11 +943,6 @@ static inline HMENU NtUserCreateMenu( BOOL is_popup ) return UlongToHandle( NtUserCallOneParam( is_popup, NtUserCallOneParam_CreateMenu )); }
-static inline LRESULT NtUserDispatchMessageA( const MSG *msg ) -{ - return NtUserCallOneParam( (UINT_PTR)msg, NtUserCallOneParam_DispatchMessageA ); -} - static inline WORD NtUserEnableDC( HDC hdc ) { return NtUserCallOneParam( HandleToUlong(hdc), NtUserCallOneParam_EnableDC );
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/message.c | 39 ++++++++++++++++++++++++++++++++++-- dlls/win32u/hook.c | 2 +- dlls/win32u/message.c | 26 +++++++++++++++++++++--- dlls/win32u/tests/win32u.c | 4 ++-- dlls/win32u/win32u_private.h | 1 + 5 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 40babb71eba..71c0f339b54 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -597,12 +597,41 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l }
+static LRESULT dispatch_send_message( struct win_proc_params *params ) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + INPUT_MESSAGE_SOURCE prev_source = thread_info->msg_source; + LRESULT retval = 0; + + static const INPUT_MESSAGE_SOURCE msg_source_unavailable = { IMDT_UNAVAILABLE, IMO_UNAVAILABLE }; + + thread_info->recursion_count++; + + params->result = &retval; + thread_info->msg_source = msg_source_unavailable; + SPY_EnterMessage( SPY_SENDMESSAGE, params->hwnd, params->msg, params->wparam, params->lparam ); + + dispatch_win_proc_params( params ); + + SPY_ExitMessage( SPY_RESULT_OK, params->hwnd, params->msg, retval, params->wparam, params->lparam ); + thread_info->msg_source = prev_source; + thread_info->recursion_count--; + return retval; +} + + /*********************************************************************** * SendMessageW (USER32.@) */ LRESULT WINAPI SendMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { - return NtUserMessageCall( hwnd, msg, wparam, lparam, NULL, NtUserSendMessage, FALSE ); + struct win_proc_params params; + LRESULT retval; + + params.hwnd = 0; + retval = NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, NtUserSendMessage, FALSE ); + if (params.hwnd) retval = dispatch_send_message( ¶ms ); + return retval; }
@@ -611,6 +640,9 @@ LRESULT WINAPI SendMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) */ LRESULT WINAPI SendMessageA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { + struct win_proc_params params; + LRESULT retval; + if (msg == WM_CHAR && !WIN_IsCurrentThread( hwnd )) { if (!map_wparam_AtoW( msg, &wparam, WMCHAR_MAP_SENDMESSAGE )) @@ -618,7 +650,10 @@ LRESULT WINAPI SendMessageA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) return NtUserMessageCall( hwnd, msg, wparam, lparam, NULL, NtUserSendMessage, FALSE ); }
- return NtUserMessageCall( hwnd, msg, wparam, lparam, NULL, NtUserSendMessage, TRUE ); + params.hwnd = 0; + retval = NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, NtUserSendMessage, TRUE ); + if (params.hwnd) retval = dispatch_send_message( ¶ms ); + return retval; }
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index a271693622a..dcf2bb9f865 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -60,7 +60,7 @@ static const char *debugstr_hook_id( unsigned int id ) return hook_names[id - WH_MINHOOK]; }
-static BOOL is_hooked( INT id ) +BOOL is_hooked( INT id ) { struct user_thread_info *thread_info = get_user_thread_info();
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 49dc3fd6d08..1b9585c4178 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -109,6 +109,7 @@ struct send_message_info SENDASYNCPROC callback; /* callback function for SendMessageCallback */ ULONG_PTR data; /* callback data */ enum wm_char_mapping wm_char; + struct win_proc_params *params; };
static const INPUT_MESSAGE_SOURCE msg_source_unavailable = { IMDT_UNAVAILABLE, IMO_UNAVAILABLE }; @@ -2374,6 +2375,7 @@ LRESULT send_internal_message_timeout( DWORD dest_pid, DWORD dest_tid, info.lparam = lparam; info.flags = flags; info.timeout = timeout; + info.params = NULL;
ret = send_inter_thread_message( &info, &result ); } @@ -2399,6 +2401,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r info.hwnd = hwnd; info.flags = 0; info.timeout = 0; + info.params = NULL;
if (input->type == INPUT_HARDWARE && rawinput->header.dwType == RIM_TYPEHID) { @@ -2635,6 +2638,16 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr, if (!(info->dest_tid = get_window_thread( info->hwnd, &dest_pid ))) return FALSE; if (is_exiting_thread( info->dest_tid )) return FALSE;
+ if (info->params && info->dest_tid == GetCurrentThreadId() && + !is_hooked( WH_CALLWNDPROC ) && !is_hooked( WH_CALLWNDPROCRET ) && + thread_info->recursion_count <= MAX_WINPROC_RECURSION) + { + /* if we're called from client side and need just a simple winproc call, + * just fill dispatch params and let user32 do the rest */ + return init_window_call_params( info->params, info->hwnd, info->msg, info->wparam, info->lparam, + NULL, ansi, info->wm_char ); + } + thread_info->msg_source = msg_source_unavailable; spy_enter_message( SPY_SENDMESSAGE, info->hwnd, info->msg, info->wparam, info->lparam );
@@ -2755,7 +2768,8 @@ BOOL kill_system_timer( HWND hwnd, UINT_PTR id ) return ret; }
-static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) +static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + struct win_proc_params *client_params, BOOL ansi ) { struct send_message_info info; DWORD_PTR res = 0; @@ -2768,6 +2782,7 @@ static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l info.flags = SMTO_NORMAL; info.timeout = 0; info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT; + info.params = client_params;
process_message( &info, &res, ansi ); return res; @@ -2787,6 +2802,7 @@ LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, info.flags = flags; info.timeout = timeout; info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT; + info.params = NULL;
return process_message( &info, res_ptr, ansi ); } @@ -2794,7 +2810,7 @@ LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, /* see SendMessageW */ LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { - return send_window_message( hwnd, msg, wparam, lparam, FALSE ); + return send_window_message( hwnd, msg, wparam, lparam, NULL, FALSE ); }
/* see SendNotifyMessageW */ @@ -2815,6 +2831,7 @@ static BOOL send_notify_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar info.lparam = lparam; info.flags = 0; info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT; + info.params = NULL;
return process_message( &info, NULL, ansi ); } @@ -2840,6 +2857,7 @@ static BOOL send_message_callback( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp info.data = params->data; info.flags = 0; info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT; + info.params = NULL;
return process_message( &info, NULL, ansi ); } @@ -2866,6 +2884,7 @@ BOOL WINAPI NtUserPostMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam info.wparam = wparam; info.lparam = lparam; info.flags = 0; + info.params = NULL;
if (is_broadcast(hwnd)) return broadcast_message( &info, NULL );
@@ -2899,6 +2918,7 @@ BOOL WINAPI NtUserPostThreadMessage( DWORD thread, UINT msg, WPARAM wparam, LPAR info.wparam = wparam; info.lparam = lparam; info.flags = 0; + info.params = NULL; return put_message_in_queue( &info, NULL ); }
@@ -2924,7 +2944,7 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa wparam, lparam, ansi );
case NtUserSendMessage: - return send_window_message( hwnd, msg, wparam, lparam, ansi ); + return send_window_message( hwnd, msg, wparam, lparam, result_info, ansi );
case NtUserSendMessageTimeout: { diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index dc1638f37ab..07179e6cdb9 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -425,10 +425,10 @@ static void test_message_call(void)
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, NtUserSendMessage, FALSE ); + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, NULL, NtUserSendMessage, FALSE ); ok( res == 3, "res = %Iu\n", res );
- res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, NtUserSendMessage, TRUE ); + res = NtUserMessageCall( hwnd, WM_USER, 1, 2, NULL, NtUserSendMessage, TRUE ); ok( res == 3, "res = %Iu\n", res );
res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)L"test", NULL, NtUserSendMessage, FALSE ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index a7f0624fdba..914a02ffd52 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -391,6 +391,7 @@ extern LRESULT handle_nc_hit_test( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; /* hook.c */ 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, BOOL unicode ) DECLSPEC_HIDDEN; +extern BOOL is_hooked( INT id ) DECLSPEC_HIDDEN; extern BOOL unhook_windows_hook( INT id, HOOKPROC proc ) DECLSPEC_HIDDEN;
/* imm.c */
From: Jacek Caban jacek@codeweavers.com
--- dlls/ntdll/signal_arm.c | 16 ++++++++++++++-- dlls/ntdll/signal_arm64.c | 16 ++++++++++++++-- dlls/ntdll/signal_i386.c | 16 ++++++++++++++-- dlls/ntdll/signal_x86_64.c | 16 ++++++++++++++-- dlls/ntdll/unix/signal_arm.c | 3 +++ dlls/ntdll/unix/signal_arm64.c | 3 +++ dlls/ntdll/unix/signal_i386.c | 3 +++ dlls/ntdll/unix/signal_x86_64.c | 3 +++ 8 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index d0229d934ce..c3674487277 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -533,9 +533,21 @@ void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1 */ void WINAPI KiUserCallbackDispatcher( ULONG id, void *args, ULONG len ) { - NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + NTSTATUS status; + + __TRY + { + NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + status = NtCallbackReturn( NULL, 0, func( args, len )); + } + __EXCEPT_ALL + { + ERR_(seh)( "ignoring exception\n" ); + status = NtCallbackReturn( 0, 0, 0 ); + } + __ENDTRY
- RtlRaiseStatus( NtCallbackReturn( NULL, 0, func( args, len ))); + RtlRaiseStatus( status ); }
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 959c3ea50dc..ee3204ebce8 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -576,9 +576,21 @@ void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg */ void WINAPI KiUserCallbackDispatcher( ULONG id, void *args, ULONG len ) { - NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + NTSTATUS status; + + __TRY + { + NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + status = NtCallbackReturn( NULL, 0, func( args, len )); + } + __EXCEPT_ALL + { + ERR_(seh)( "ignoring exception\n" ); + status = NtCallbackReturn( 0, 0, 0 ); + } + __ENDTRY
- RtlRaiseStatus( NtCallbackReturn( NULL, 0, func( args, len ))); + RtlRaiseStatus( status ); }
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index f4c935ecc94..ae065f8c37b 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -257,9 +257,21 @@ void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1 */ void WINAPI KiUserCallbackDispatcher( ULONG id, void *args, ULONG len ) { - NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + NTSTATUS status; + + __TRY + { + NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + status = NtCallbackReturn( NULL, 0, func( args, len )); + } + __EXCEPT_ALL + { + ERR_(seh)( "ignoring exception\n" ); + status = NtCallbackReturn( 0, 0, 0 ); + } + __ENDTRY
- RtlRaiseStatus( NtCallbackReturn( NULL, 0, func( args, len ))); + RtlRaiseStatus( status ); }
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 9957d0c3dfa..b1ab4933b93 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -661,9 +661,21 @@ __ASM_GLOBAL_FUNC( KiUserApcDispatcher, */ void WINAPI KiUserCallbackDispatcher( ULONG id, void *args, ULONG len ) { - NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + NTSTATUS status; + + __TRY + { + NTSTATUS (WINAPI *func)(void *, ULONG) = ((void **)NtCurrentTeb()->Peb->KernelCallbackTable)[id]; + status = NtCallbackReturn( NULL, 0, func( args, len )); + } + __EXCEPT_ALL + { + ERR_(seh)( "ignoring exception\n" ); + status = NtCallbackReturn( 0, 0, 0 ); + } + __ENDTRY
- RtlRaiseStatus( NtCallbackReturn( NULL, 0, func( args, len ))); + RtlRaiseStatus( status ); }
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 73843ba56a6..5d1478a1ff4 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -721,6 +721,7 @@ struct user_callback_frame ULONG *ret_len; __wine_jmp_buf jmpbuf; NTSTATUS status; + void *teb_frame; };
/*********************************************************************** @@ -756,6 +757,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.restore_flags = CONTEXT_INTEGER; callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; + callback_frame.teb_frame = NtCurrentTeb()->Tib.ExceptionList; arm_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 ); @@ -777,6 +779,7 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status *frame->ret_len = ret_len; frame->status = status; arm_thread_data()->syscall_frame = frame->frame.prev_frame; + NtCurrentTeb()->Tib.ExceptionList = frame->teb_frame; __wine_longjmp( &frame->jmpbuf, 1 ); }
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 10543322a8f..4e552e0f10a 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -730,6 +730,7 @@ struct user_callback_frame ULONG *ret_len; __wine_jmp_buf jmpbuf; NTSTATUS status; + void *teb_frame; };
/*********************************************************************** @@ -766,6 +767,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.restore_flags = CONTEXT_INTEGER; callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; + callback_frame.teb_frame = NtCurrentTeb()->Tib.ExceptionList; arm64_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 ); @@ -787,6 +789,7 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status *frame->ret_len = ret_len; frame->status = status; arm64_thread_data()->syscall_frame = frame->frame.prev_frame; + NtCurrentTeb()->Tib.ExceptionList = frame->teb_frame; __wine_longjmp( &frame->jmpbuf, 1 ); }
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 5ddef2701c4..2dfce706394 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1575,6 +1575,7 @@ struct user_callback_frame ULONG *ret_len; __wine_jmp_buf jmpbuf; NTSTATUS status; + void *teb_frame; };
/*********************************************************************** @@ -1614,6 +1615,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.syscall_flags = frame->syscall_flags; callback_frame.frame.syscall_table = frame->syscall_table; callback_frame.frame.prev_frame = frame; + callback_frame.teb_frame = NtCurrentTeb()->Tib.ExceptionList; x86_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 ); @@ -1635,6 +1637,7 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status *frame->ret_len = ret_len; frame->status = status; x86_thread_data()->syscall_frame = frame->frame.prev_frame; + NtCurrentTeb()->Tib.ExceptionList = frame->teb_frame; __wine_longjmp( &frame->jmpbuf, 1 ); }
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 9b7a19bce72..d6f19dbfa84 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2327,6 +2327,7 @@ struct user_callback_frame ULONG *ret_len; __wine_jmp_buf jmpbuf; NTSTATUS status; + void *teb_frame; };
/*********************************************************************** @@ -2368,6 +2369,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void callback_frame.frame.prev_frame = frame; callback_frame.frame.syscall_flags = frame->syscall_flags; callback_frame.frame.syscall_table = frame->syscall_table; + callback_frame.teb_frame = NtCurrentTeb()->Tib.ExceptionList; amd64_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 ); @@ -2389,6 +2391,7 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status *frame->ret_len = ret_len; frame->status = status; amd64_thread_data()->syscall_frame = frame->frame.prev_frame; + NtCurrentTeb()->Tib.ExceptionList = frame->teb_frame; __wine_longjmp( &frame->jmpbuf, 1 ); }
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/gdiobj.c | 1 - dlls/win32u/message.c | 10 +--------- dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 1 - dlls/win32u/wrappers.c | 6 ------ dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 10 +++++++++- 8 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index fddaf898761..e5c2c185511 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1158,7 +1158,6 @@ static struct unix_funcs unix_funcs = NtUserDestroyMenu, NtUserDestroyWindow, NtUserDisableThreadIme, - NtUserDispatchMessage, NtUserDragDetect, NtUserDrawCaptionTemp, NtUserDrawIconEx, diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 1b9585c4178..7045aedb4b1 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2514,15 +2514,7 @@ LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ) if (!init_win_proc_params( ¶ms, msg->hwnd, msg->message, msg->wParam, NtGetTickCount(), FALSE )) return 0; - __TRY - { - dispatch_win_proc_params( ¶ms, sizeof(params) ); - } - __EXCEPT - { - retval = 0; - } - __ENDTRY + dispatch_win_proc_params( ¶ms, sizeof(params) ); return retval; } if (msg->message == WM_SYSTIMER) diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index f5508f62d16..a7e18158fb5 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -117,6 +117,7 @@ static void * const syscalls[] = NtUserDeleteMenu, NtUserDestroyAcceleratorTable, NtUserDestroyInputContext, + NtUserDispatchMessage, NtUserEndMenu, NtUserFindExistingCursorIcon, NtUserFindWindowEx, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index d74685ad603..7ec96eedfcf 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -839,7 +839,7 @@ @ stub NtUserDisableProcessWindowFiltering @ stdcall NtUserDisableThreadIme(long) @ stub NtUserDiscardPointerFrameMessages -@ stdcall NtUserDispatchMessage(ptr) +@ stdcall -syscall NtUserDispatchMessage(ptr) @ stub NtUserDisplayConfigGetDeviceInfo @ stub NtUserDisplayConfigSetDeviceInfo @ stub NtUserDoSoundConnect diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 914a02ffd52..d5b3e0fdda8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -215,7 +215,6 @@ struct unix_funcs BOOL (WINAPI *pNtUserDestroyMenu)( HMENU handle ); BOOL (WINAPI *pNtUserDestroyWindow)( HWND hwnd ); BOOL (WINAPI *pNtUserDisableThreadIme)( DWORD thread_id ); - LRESULT (WINAPI *pNtUserDispatchMessage)( const MSG *msg ); BOOL (WINAPI *pNtUserDragDetect)( HWND hwnd, int x, int y ); BOOL (WINAPI *pNtUserDrawCaptionTemp)( HWND hwnd, HDC hdc, const RECT *rect, HFONT font, HICON icon, const WCHAR *str, UINT flags ); diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 609e893403b..9c2264e887e 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -855,12 +855,6 @@ BOOL WINAPI NtUserDisableThreadIme( DWORD thread_id ) return unix_funcs->pNtUserDisableThreadIme( thread_id ); }
-LRESULT WINAPI NtUserDispatchMessage( const MSG *msg ) -{ - if (!unix_funcs) return 0; - return unix_funcs->pNtUserDispatchMessage( msg ); -} - BOOL WINAPI NtUserDragDetect( HWND hwnd, int x, int y ) { if (!unix_funcs) return FALSE; diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 005037d71a5..3842eb3c1da 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -104,6 +104,7 @@ SYSCALL_ENTRY( NtUserDeleteMenu ) \ SYSCALL_ENTRY( NtUserDestroyAcceleratorTable ) \ SYSCALL_ENTRY( NtUserDestroyInputContext ) \ + SYSCALL_ENTRY( NtUserDispatchMessage ) \ SYSCALL_ENTRY( NtUserEndMenu ) \ SYSCALL_ENTRY( NtUserFindExistingCursorIcon ) \ SYSCALL_ENTRY( NtUserFindWindowEx ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 386458ccf0c..7ca1e87109d 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -78,7 +78,7 @@ typedef struct DWORD dwType; } RAWINPUTDEVICELIST32;
-static MSG *msg_32to64( MSG *msg, MSG32 *msg32 ) +static MSG *msg_32to64( MSG *msg, const MSG32 *msg32 ) { if (!msg32) return NULL;
@@ -281,6 +281,14 @@ NTSTATUS WINAPI wow64_NtUserDestroyInputContext( UINT *args ) return NtUserDestroyInputContext( handle ); }
+NTSTATUS WINAPI wow64_NtUserDispatchMessage( UINT *args ) +{ + const MSG32 *msg32 = get_ptr( &args ); + MSG msg; + + return NtUserDispatchMessage( msg_32to64( &msg, msg32 )); +} + NTSTATUS WINAPI wow64_NtUserEndMenu( UINT *args ) { return NtUserEndMenu();
From: Jacek Caban jacek@codeweavers.com
We currently depend on default behaviour of suppressing exceptions from client callbacks. If we change it to fail by default, we will need a separated filter for NtUserDispatchMessage. --- dlls/win32u/tests/win32u.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 07179e6cdb9..0985478b2f0 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -632,6 +632,50 @@ static void test_message_filter(void) ok( ret, "NtUserUnhookWindowsHook failed: %lu\n", GetLastError() ); }
+static char calls[128]; + +static void WINAPI timer_func( HWND hwnd, UINT msg, UINT_PTR id, DWORD time ) +{ + sprintf( calls + strlen( calls ), "timer%Iu,", id ); + NtUserKillTimer( hwnd, id ); + + if (!id) + { + MSG msg; + NtUserSetTimer( hwnd, 1, 1, timer_func, TIMERV_DEFAULT_COALESCING ); + while (GetMessageW( &msg, NULL, 0, 0 )) + { + TranslateMessage( &msg ); + NtUserDispatchMessage( &msg ); + if (msg.message == WM_TIMER) break; + } + } + + strcat( calls, "crash," ); + *(volatile int *)0 = 0; +} + +static void test_timer(void) +{ + HWND hwnd; + MSG msg; + + hwnd = CreateWindowExA( 0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL ); + + NtUserSetTimer( hwnd, 0, 1, timer_func, TIMERV_DEFAULT_COALESCING ); + + calls[0] = 0; + while (GetMessageW( &msg, NULL, 0, 0 )) + { + TranslateMessage( &msg ); + NtUserDispatchMessage( &msg ); + if (msg.message == WM_TIMER) break; + } + + ok( !strcmp( calls, "timer0,timer1,crash,crash," ), "calls = %s\n", calls ); + DestroyWindow( hwnd ); +} + START_TEST(win32u) { /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */ @@ -646,6 +690,7 @@ START_TEST(win32u) test_window_text(); test_menu(); test_message_filter(); + test_timer();
test_NtUserCloseWindowStation(); }
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/user_main.c | 1 - dlls/win32u/driver.c | 8 ++------ dlls/win32u/gdiobj.c | 1 - dlls/win32u/ntuser_private.h | 1 - dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 2 -- dlls/win32u/wrappers.c | 7 ------- dlls/wineandroid.drv/android.h | 2 -- dlls/wineandroid.drv/dllmain.c | 1 - dlls/wineandroid.drv/init.c | 3 --- dlls/wineandroid.drv/unixlib.h | 1 - dlls/wineandroid.drv/window.c | 4 ++-- dlls/winemac.drv/dllmain.c | 1 - dlls/winemac.drv/event.c | 8 ++++---- dlls/winemac.drv/macdrv.h | 3 --- dlls/winemac.drv/macdrv_main.c | 3 --- dlls/winemac.drv/unixlib.h | 1 - dlls/winex11.drv/dllmain.c | 1 - dlls/winex11.drv/event.c | 8 ++++---- dlls/winex11.drv/unixlib.h | 1 - dlls/winex11.drv/x11drv.h | 3 --- dlls/winex11.drv/x11drv_main.c | 9 --------- dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 21 +++++++++++++++++++++ 25 files changed, 36 insertions(+), 58 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 16ce5c6a854..7125e32b154 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -133,7 +133,6 @@ static NTSTATUS try_finally( NTSTATUS (CDECL *func)( void *), void *arg,
static const struct user_callbacks user_funcs = { - NtWaitForMultipleObjects, try_finally, };
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index baa0143be61..3d29453c2bf 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -811,12 +811,8 @@ static NTSTATUS nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE * DWORD mask, DWORD flags ) { if (!count && timeout && !timeout->QuadPart) return WAIT_TIMEOUT; - - if (!user_callbacks) - return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); - return user_callbacks->pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); }
static void nulldrv_ReleaseDC( HWND hwnd, HDC hdc ) diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index e5c2c185511..2c3d46b7a5b 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1200,7 +1200,6 @@ static struct unix_funcs unix_funcs = NtUserMapVirtualKeyEx, NtUserMessageCall, NtUserMoveWindow, - NtUserMsgWaitForMultipleObjectsEx, NtUserOpenClipboard, NtUserPeekMessage, NtUserPostMessage, diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 9c23799c6bb..69adad822a0 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -32,7 +32,6 @@ struct hardware_msg_data;
struct user_callbacks { - NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); NTSTATUS (CDECL *try_finally)( NTSTATUS (CDECL *func)( void *), void *arg, void (CALLBACK *finally_func)( BOOL )); }; diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index a7e18158fb5..f4ec0b8dc3b 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -163,6 +163,7 @@ static void * const syscalls[] = NtUserKillTimer, NtUserLockWindowUpdate, NtUserMenuItemFromPoint, + NtUserMsgWaitForMultipleObjectsEx, NtUserNotifyWinEvent, NtUserOpenDesktop, NtUserOpenInputDesktop, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 7ec96eedfcf..b56059e7fd8 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1085,7 +1085,7 @@ @ stub NtUserModifyUserStartupInfoFlags @ stub NtUserModifyWindowTouchCapability @ stdcall NtUserMoveWindow(long long long long long long) -@ stdcall NtUserMsgWaitForMultipleObjectsEx(long ptr long long long) +@ stdcall -syscall NtUserMsgWaitForMultipleObjectsEx(long ptr long long long) @ stub NtUserNavigateFocus @ stub NtUserNotifyIMEStatus @ stub NtUserNotifyProcessCreate diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d5b3e0fdda8..d811ac6e879 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -265,8 +265,6 @@ struct unix_funcs 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 ); BOOL (WINAPI *pNtUserOpenClipboard)( HWND hwnd, ULONG unk ); BOOL (WINAPI *pNtUserPeekMessage)( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags ); BOOL (WINAPI *pNtUserPostMessage)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 9c2264e887e..4c22c14ca6f 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1110,13 +1110,6 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa return unix_funcs->pNtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); }
-DWORD WINAPI NtUserMsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, - DWORD timeout, DWORD mask, DWORD flags ) -{ - if (!unix_funcs) return 0; - return unix_funcs->pNtUserMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags ); -} - BOOL WINAPI NtUserOpenClipboard( HWND hwnd, ULONG unk ) { if (!unix_funcs) return FALSE; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 57f566b3cfd..22652f11d27 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -120,8 +120,6 @@ extern NTSTATUS android_java_init( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS android_java_uninit( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS android_register_window( void *arg ) DECLSPEC_HIDDEN; extern PNTAPCFUNC register_window_callback; -extern NTSTATUS (WINAPI *pNtWaitForMultipleObjects)( ULONG,const HANDLE*,BOOLEAN, - BOOLEAN,const LARGE_INTEGER* ) DECLSPEC_HIDDEN;
extern unsigned int screen_width DECLSPEC_HIDDEN; extern unsigned int screen_height DECLSPEC_HIDDEN; diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c index 81581591770..6556a492505 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -130,7 +130,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) return FALSE;
params.register_window_callback = register_window_callback; - params.pNtWaitForMultipleObjects = NtWaitForMultipleObjects; if (__wine_unix_call( unix_handle, unix_init, ¶ms )) return FALSE;
callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index a82932bf65f..83fe224dccf 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -563,8 +563,6 @@ jobject *p_java_object = NULL; unsigned short *p_java_gdt_sel = NULL;
static NTSTATUS CDECL unix_call( enum android_funcs code, void *params ); -NTSTATUS (WINAPI *pNtWaitForMultipleObjects)( ULONG,const HANDLE*,BOOLEAN, - BOOLEAN,const LARGE_INTEGER* );
static HRESULT android_init( void *arg ) { @@ -611,7 +609,6 @@ static HRESULT android_init( void *arg ) #endif } __wine_set_user_driver( &android_drv_funcs, WINE_GDI_DRIVER_VERSION ); - pNtWaitForMultipleObjects = params->pNtWaitForMultipleObjects; params->unix_call = unix_call; return STATUS_SUCCESS; } diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h index 92d28176ee7..2b4d02648e5 100644 --- a/dlls/wineandroid.drv/unixlib.h +++ b/dlls/wineandroid.drv/unixlib.h @@ -37,7 +37,6 @@ enum android_funcs struct init_params { PNTAPCFUNC register_window_callback; - NTSTATUS (WINAPI *pNtWaitForMultipleObjects)( ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER* ); NTSTATUS (CDECL *unix_call)( enum android_funcs code, void *params ); };
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index c580a36c828..9406236a405 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1212,8 +1212,8 @@ NTSTATUS ANDROID_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles if (current_event) mask = 0; if (process_events( mask )) return count - 1; } - return pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); }
/********************************************************************** diff --git a/dlls/winemac.drv/dllmain.c b/dlls/winemac.drv/dllmain.c index 0618ec83228..567485b2f03 100644 --- a/dlls/winemac.drv/dllmain.c +++ b/dlls/winemac.drv/dllmain.c @@ -414,7 +414,6 @@ static BOOL process_attach(void) str->len = LoadStringW(macdrv_module, str->id, (WCHAR *)&str->str, 0); params.strings = strings;
- params.pNtWaitForMultipleObjects = NtWaitForMultipleObjects; if (__wine_unix_call(macdrv_handle, unix_init, ¶ms)) return FALSE;
callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index d76c6ee8edb..ef1ab23bb1d 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -525,8 +525,8 @@ NTSTATUS macdrv_MsgWaitForMultipleObjectsEx(DWORD count, const HANDLE *handles, if (!data) { if (!count && timeout && !timeout->QuadPart) return WAIT_TIMEOUT; - return pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); }
if (data->current_event && data->current_event->type != QUERY_EVENT && @@ -538,8 +538,8 @@ NTSTATUS macdrv_MsgWaitForMultipleObjectsEx(DWORD count, const HANDLE *handles, if (process_events(data->queue, event_mask)) ret = count - 1; else if (count || !timeout || timeout->QuadPart) { - ret = pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + ret = NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); if (ret == count - 1) process_events(data->queue, event_mask); } else ret = WAIT_TIMEOUT; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 72bd1cefaeb..7cb1665a8fc 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -42,9 +42,6 @@ extern BOOL allow_set_gamma DECLSPEC_HIDDEN; extern BOOL allow_software_rendering DECLSPEC_HIDDEN; extern BOOL disable_window_decorations DECLSPEC_HIDDEN;
-extern NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN, - BOOLEAN,const LARGE_INTEGER*) DECLSPEC_HIDDEN; - extern const char* debugstr_cf(CFTypeRef t) DECLSPEC_HIDDEN;
static inline CGRect cgrect_from_rect(RECT rect) diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index e1fd7b2d331..4b79c69a6f8 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -69,8 +69,6 @@ int enable_app_nap = FALSE;
CFDictionaryRef localized_strings;
-NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN, - BOOLEAN,const LARGE_INTEGER*);
/************************************************************************** * debugstr_cf @@ -461,7 +459,6 @@ static NTSTATUS macdrv_init(void *arg) init_user_driver(); macdrv_init_display_devices(FALSE);
- pNtWaitForMultipleObjects = params->pNtWaitForMultipleObjects; params->unix_call = unix_call; return STATUS_SUCCESS; } diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h index 284a3e26db9..d162732b08e 100644 --- a/dlls/winemac.drv/unixlib.h +++ b/dlls/winemac.drv/unixlib.h @@ -83,7 +83,6 @@ struct localized_string
struct init_params { - NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); struct localized_string *strings; NTSTATUS (CDECL *unix_call)(enum macdrv_funcs code, void *params); }; diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index b7c5692b32d..086a32d2f85 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -67,7 +67,6 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) void **callback_table; struct init_params params = { - NtWaitForMultipleObjects, foreign_window_proc, };
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index cbfb228ea09..ddf5cd0433b 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -483,8 +483,8 @@ NTSTATUS X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, if (!data) { if (!count && timeout && !timeout->QuadPart) return WAIT_TIMEOUT; - return pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + return NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); }
if (data->current_event) mask = 0; /* don't process nested events */ @@ -492,8 +492,8 @@ NTSTATUS X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, if (process_events( data->display, filter_event, mask )) ret = count - 1; else if (count || !timeout || timeout->QuadPart) { - ret = pNtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), - !!(flags & MWMO_ALERTABLE), timeout ); + ret = NtWaitForMultipleObjects( count, handles, !(flags & MWMO_WAITALL), + !!(flags & MWMO_ALERTABLE), timeout ); if (ret == count - 1) process_events( data->display, filter_event, mask ); } else ret = WAIT_TIMEOUT; diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index d490600226f..208c395e02b 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -50,7 +50,6 @@ struct create_desktop_params /* x11drv_init params */ struct init_params { - NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); WNDPROC foreign_window_proc; BOOL show_systray; NTSTATUS (CDECL *unix_call)( enum x11drv_funcs code, void *params ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f44b3006345..0fe29d8e322 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -446,9 +446,6 @@ extern char *process_name DECLSPEC_HIDDEN; extern Display *clipboard_display DECLSPEC_HIDDEN; extern WNDPROC client_foreign_window_proc;
-extern NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN, - BOOLEAN,const LARGE_INTEGER*) DECLSPEC_HIDDEN; - /* atoms */
enum x11drv_atoms diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 44d4763b316..9e05ebaa9a5 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -220,14 +220,6 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "text/uri-list" };
-/* We use use pointer to call NtWaitForMultipleObjects to make it go through - * syscall dispatcher. We need that because win32u bypasses syscall thunks and - * if we called NtWaitForMultipleObjects directly, it wouldn't be able to handle - * user APCs. This will be removed as soon as we may use syscall interface - * for NtUserMsgWaitForMultipleObjectsEx. */ -NTSTATUS (WINAPI *pNtWaitForMultipleObjects)( ULONG, const HANDLE *, BOOLEAN, - BOOLEAN, const LARGE_INTEGER* ); - static NTSTATUS CDECL unix_call( enum x11drv_funcs code, void *params );
/*********************************************************************** @@ -686,7 +678,6 @@ static NTSTATUS x11drv_init( void *arg ) if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" ); if (!(display = XOpenDisplay( NULL ))) return STATUS_UNSUCCESSFUL;
- pNtWaitForMultipleObjects = params->pNtWaitForMultipleObjects; client_foreign_window_proc = params->foreign_window_proc;
fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */ diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 3842eb3c1da..b5103726e50 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -150,6 +150,7 @@ SYSCALL_ENTRY( NtUserKillTimer ) \ SYSCALL_ENTRY( NtUserLockWindowUpdate ) \ SYSCALL_ENTRY( NtUserMenuItemFromPoint ) \ + SYSCALL_ENTRY( NtUserMsgWaitForMultipleObjectsEx ) \ SYSCALL_ENTRY( NtUserNotifyWinEvent ) \ SYSCALL_ENTRY( NtUserOpenDesktop ) \ SYSCALL_ENTRY( NtUserOpenInputDesktop ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 7ca1e87109d..4e6e86028ba 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -836,6 +836,27 @@ NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) return NtUserMenuItemFromPoint( hwnd, handle, x, y ); }
+NTSTATUS WINAPI wow64_NtUserMsgWaitForMultipleObjectsEx( UINT *args ) +{ + DWORD count = get_ulong( &args ); + const ULONG *handles32 = get_ptr( &args ); + DWORD timeout = get_ulong( &args ); + DWORD mask = get_ulong( &args ); + DWORD flags = get_ulong( &args ); + + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + unsigned int i; + + if (count > ARRAYSIZE(handles)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return WAIT_FAILED; + } + for (i = 0; i < count; i++) handles[i] = UlongToHandle( handles32[i] ); + + return NtUserMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags ); +} + NTSTATUS WINAPI wow64_NtUserNotifyWinEvent( UINT *args ) { DWORD event = get_ulong( &args );
From: Jacek Caban jacek@codeweavers.com
try_finally() hack is no longer needed. We don't expect exceptions from unixlib code and client callbacks' exceptions are not propagated anyway. --- dlls/win32u/gdiobj.c | 2 -- dlls/win32u/menu.c | 42 +----------------------------------- dlls/win32u/syscall.c | 2 ++ dlls/win32u/win32u.spec | 4 ++-- dlls/win32u/win32u_private.h | 4 ---- dlls/win32u/wrappers.c | 14 ------------ dlls/wow64win/syscall.h | 2 ++ dlls/wow64win/user.c | 26 ++++++++++++++++++++++ 8 files changed, 33 insertions(+), 63 deletions(-)
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 2c3d46b7a5b..30c507275fc 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1198,7 +1198,6 @@ static struct unix_funcs unix_funcs = NtUserInvalidateRgn, NtUserIsClipboardFormatAvailable, NtUserMapVirtualKeyEx, - NtUserMessageCall, NtUserMoveWindow, NtUserOpenClipboard, NtUserPeekMessage, @@ -1245,7 +1244,6 @@ static struct unix_funcs unix_funcs = NtUserSystemParametersInfoForDpi, NtUserToUnicodeEx, NtUserTrackMouseEvent, - NtUserTrackPopupMenuEx, NtUserTranslateAccelerator, NtUserTranslateMessage, NtUserUnregisterClass, diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 2530c04241c..641eb926e16 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -4053,14 +4053,7 @@ static UINT find_item_by_key( HWND owner, HMENU hmenu, WCHAR key, BOOL force_men return -1; }
-static BOOL seh_release_capture; - -static void CALLBACK finally_release_capture( BOOL __normal ) -{ - if (seh_release_capture) set_capture_window( 0, GUI_INMENUMODE, NULL ); -} - -static BOOL track_menu_impl( HMENU hmenu, UINT flags, int x, int y, HWND hwnd, const RECT *rect ) +static BOOL track_menu( HMENU hmenu, UINT flags, int x, int y, HWND hwnd, const RECT *rect ) { BOOL enter_idle_sent = FALSE; int executed_menu_id = -1; @@ -4103,8 +4096,6 @@ static BOOL track_menu_impl( HMENU hmenu, UINT flags, int x, int y, HWND hwnd, c if ((flags & TPM_POPUPMENU) && menu->nItems == 0) return FALSE;
- seh_release_capture = TRUE; - while (!exit_menu) { if (!(menu = unsafe_menu_ptr( mt.hCurrentMenu ))) break; @@ -4308,7 +4299,6 @@ static BOOL track_menu_impl( HMENU hmenu, UINT flags, int x, int y, HWND hwnd, c else mt.trackFlags &= ~TF_SKIPREMOVE; }
- seh_release_capture = FALSE; set_capture_window( 0, GUI_INMENUMODE, NULL );
/* If dropdown is still painted and the close box is clicked on @@ -4344,36 +4334,6 @@ static BOOL track_menu_impl( HMENU hmenu, UINT flags, int x, int y, HWND hwnd, c return executed_menu_id; }
-/* FIXME: this is an ugly hack to work around unixlib exceptions limitations. - * For this to work properly we need recursive exception handlers capable of - * catching exceptions from client callbacks. We probably need to actually - * run on Unix stack first, so we need a hack for now. */ -struct track_menu_params -{ - HMENU handle; - UINT flags; - int x; - int y; - HWND hwnd; - const RECT *rect; -}; - -static NTSTATUS CDECL track_menu_proc( void *arg ) -{ - struct track_menu_params *params = arg; - return track_menu_impl( params->handle, params->flags, params->x, params->y, - params->hwnd, params->rect ); -} - -static BOOL track_menu( HMENU handle, UINT flags, int x, int y, HWND hwnd, const RECT *rect ) -{ - struct track_menu_params params = - { .handle = handle, .flags = flags, .x = x, .y = y, .hwnd = hwnd, .rect = rect }; - if (!user_callbacks) - return track_menu_impl( handle, flags, x, y, hwnd, rect ); - return user_callbacks->try_finally( track_menu_proc, ¶ms, finally_release_capture ); -} - static BOOL init_tracking( HWND hwnd, HMENU handle, BOOL is_popup, UINT flags ) { struct menu *menu; diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index f4ec0b8dc3b..eeebf521bc2 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -163,6 +163,7 @@ static void * const syscalls[] = NtUserKillTimer, NtUserLockWindowUpdate, NtUserMenuItemFromPoint, + NtUserMessageCall, NtUserMsgWaitForMultipleObjectsEx, NtUserNotifyWinEvent, NtUserOpenDesktop, @@ -187,6 +188,7 @@ static void * const syscalls[] = NtUserSetWindowsHookEx, NtUserThunkedMenuInfo, NtUserThunkedMenuItemInfo, + NtUserTrackPopupMenuEx, NtUserUnhookWinEvent, NtUserUnhookWindowsHookEx, NtUserUpdateInputContext, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index b56059e7fd8..83de1ab87c8 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1079,7 +1079,7 @@ @ stdcall NtUserMapVirtualKeyEx(long long long) @ stub NtUserMarkWindowForRawMouse @ stdcall -syscall NtUserMenuItemFromPoint(long long long long) -@ stdcall NtUserMessageCall(long long long long long long long) +@ stdcall -syscall NtUserMessageCall(long long long long long long long) @ stub NtUserMinInitialize @ stub NtUserMinMaximize @ stub NtUserModifyUserStartupInfoFlags @@ -1278,7 +1278,7 @@ @ stdcall -syscall NtUserThunkedMenuItemInfo(long long long long ptr ptr) @ stdcall NtUserToUnicodeEx(long long ptr ptr long long long) @ stdcall NtUserTrackMouseEvent(ptr) -@ stdcall NtUserTrackPopupMenuEx(long long long long long ptr) +@ stdcall -syscall NtUserTrackPopupMenuEx(long long long long long ptr) @ stub NtUserTransformPoint @ stub NtUserTransformRect @ stdcall NtUserTranslateAccelerator(long long ptr) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d811ac6e879..262d46d3d7c 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -262,8 +262,6 @@ struct unix_funcs BOOL (WINAPI *pNtUserInvalidateRgn)( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); - 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 ); BOOL (WINAPI *pNtUserOpenClipboard)( HWND hwnd, ULONG unk ); BOOL (WINAPI *pNtUserPeekMessage)( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags ); @@ -320,8 +318,6 @@ struct unix_funcs INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state, WCHAR *str, int size, UINT flags, HKL layout ); BOOL (WINAPI *pNtUserTrackMouseEvent)( TRACKMOUSEEVENT *info ); - BOOL (WINAPI *pNtUserTrackPopupMenuEx)( HMENU handle, UINT flags, INT x, INT y, HWND hwnd, - TPMPARAMS *params ); INT (WINAPI *pNtUserTranslateAccelerator)( HWND hwnd, HACCEL accel, MSG *msg ); BOOL (WINAPI *pNtUserTranslateMessage)( const MSG *msg, UINT flags ); BOOL (WINAPI *pNtUserUnregisterClass)( UNICODE_STRING *name, HINSTANCE instance, diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 4c22c14ca6f..923254dcf96 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1103,13 +1103,6 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ) return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout ); }
-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 ); -} - BOOL WINAPI NtUserOpenClipboard( HWND hwnd, ULONG unk ) { if (!unix_funcs) return FALSE; @@ -1388,13 +1381,6 @@ BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ) return unix_funcs->pNtUserTrackMouseEvent( info ); }
-BOOL WINAPI NtUserTrackPopupMenuEx( HMENU handle, UINT flags, INT x, INT y, HWND hwnd, - TPMPARAMS *params ) -{ - if (!unix_funcs) return FALSE; - return unix_funcs->pNtUserTrackPopupMenuEx( handle, flags, x, y, hwnd, params ); -} - INT WINAPI NtUserTranslateAccelerator( HWND hwnd, HACCEL accel, MSG *msg ) { if (!unix_funcs) return 0; diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index b5103726e50..937abaf8b3b 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -150,6 +150,7 @@ SYSCALL_ENTRY( NtUserKillTimer ) \ SYSCALL_ENTRY( NtUserLockWindowUpdate ) \ SYSCALL_ENTRY( NtUserMenuItemFromPoint ) \ + SYSCALL_ENTRY( NtUserMessageCall ) \ SYSCALL_ENTRY( NtUserMsgWaitForMultipleObjectsEx ) \ SYSCALL_ENTRY( NtUserNotifyWinEvent ) \ SYSCALL_ENTRY( NtUserOpenDesktop ) \ @@ -174,6 +175,7 @@ SYSCALL_ENTRY( NtUserSetWindowsHookEx ) \ SYSCALL_ENTRY( NtUserThunkedMenuInfo ) \ SYSCALL_ENTRY( NtUserThunkedMenuItemInfo ) \ + SYSCALL_ENTRY( NtUserTrackPopupMenuEx ) \ SYSCALL_ENTRY( NtUserUnhookWinEvent ) \ SYSCALL_ENTRY( NtUserUnhookWindowsHookEx ) \ SYSCALL_ENTRY( NtUserUpdateInputContext ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 4e6e86028ba..be91b830e7a 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -836,6 +836,20 @@ NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args ) return NtUserMenuItemFromPoint( hwnd, handle, x, y ); }
+NTSTATUS WINAPI wow64_NtUserMessageCall( UINT *args ) +{ + HWND hwnd = get_handle( &args ); + UINT msg = get_ulong( &args ); + UINT wparam = get_ulong( &args ); + UINT lparam = get_ulong( &args ); + void *result_info = get_ptr( &args ); + UINT type = get_ulong ( &args ); + BOOL ansi = get_ulong( &args ); + + FIXME( "%p %x %x %x %p %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); + return 0; +} + NTSTATUS WINAPI wow64_NtUserMsgWaitForMultipleObjectsEx( UINT *args ) { DWORD count = get_ulong( &args ); @@ -1151,6 +1165,18 @@ NTSTATUS WINAPI wow64_NtUserThunkedMenuItemInfo( UINT *args ) unicode_str_32to64( &str, str32 )); }
+NTSTATUS WINAPI wow64_NtUserTrackPopupMenuEx( UINT *args ) +{ + HMENU handle = get_handle( &args ); + UINT flags = get_ulong( &args ); + int x = get_ulong( &args ); + int y = get_ulong( &args ); + HWND hwnd = get_handle( &args ); + TPMPARAMS *params = get_ptr( &args ); + + return NtUserTrackPopupMenuEx( handle, flags, x, y, hwnd, params ); +} + NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args ) { HWINEVENTHOOK handle = get_handle( &args );
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/user_main.c | 20 -------------------- dlls/win32u/gdiobj.c | 3 --- dlls/win32u/ntuser_private.h | 10 ---------- dlls/win32u/sysparams.c | 3 --- dlls/win32u/win32u_private.h | 2 -- dlls/win32u/window.c | 2 +- include/ntuser.h | 1 - 7 files changed, 1 insertion(+), 40 deletions(-)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 7125e32b154..d3940d4a95c 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -119,23 +119,6 @@ static void dpiaware_init(void) } }
-static NTSTATUS try_finally( NTSTATUS (CDECL *func)( void *), void *arg, - void (CALLBACK *finally_func)( BOOL )) -{ - NTSTATUS status; - __TRY - { - status = func( arg ); - } - __FINALLY( finally_func ); - return status; -} - -static const struct user_callbacks user_funcs = -{ - try_finally, -}; - static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params, ULONG size ) { HANDLE ret = CopyImage( params->hwnd, params->type, params->dx, params->dy, params->flags ); @@ -247,9 +230,6 @@ static BOOL process_attach(void) { NtCurrentTeb()->Peb->KernelCallbackTable = kernel_callback_table;
- /* FIXME: should not be needed */ - NtUserCallOneParam( (UINT_PTR)&user_funcs, NtUserSetCallbacks ); - dpiaware_init(); winproc_init(); register_desktop_class(); diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 30c507275fc..b20e3a7ddbb 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -50,8 +50,6 @@ static GDI_HANDLE_ENTRY *next_unused; static LONG debug_count; SYSTEM_BASIC_INFORMATION system_info;
-const struct user_callbacks *user_callbacks = NULL; - static inline HGDIOBJ entry_to_handle( GDI_HANDLE_ENTRY *entry ) { unsigned int idx = entry - gdi_shared->Handles; @@ -1283,7 +1281,6 @@ NTSTATUS gdi_init(void)
NTSTATUS callbacks_init( void *args ) { - user_callbacks = *(const struct user_callbacks **)args; *(const struct unix_funcs **)args = &unix_funcs; return 0; } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 69adad822a0..313382505d4 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -25,16 +25,6 @@ #include "ntuser.h" #include "wine/list.h"
-struct dce; -struct tagWND; - -struct hardware_msg_data; - -struct user_callbacks -{ - NTSTATUS (CDECL *try_finally)( NTSTATUS (CDECL *func)( void *), void *arg, - void (CALLBACK *finally_func)( BOOL )); -};
#define WM_SYSTIMER 0x0118 #define WM_POPUPSYSTEMMENU 0x0313 diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index e8b55616f6a..8bb6b46397e 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4953,9 +4953,6 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) default: user_check_not_lock(); return 0; }
- case NtUserSetCallbacks: - return (UINT_PTR)InterlockedExchangePointer( (void **)&user_callbacks, (void *)arg ); - case NtUserSpyGetVKeyName: return (UINT_PTR)debugstr_vkey_name( arg );
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 262d46d3d7c..bdc8235a831 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -32,8 +32,6 @@ #include "wine/debug.h" #include "wine/server.h"
-extern const struct user_callbacks *user_callbacks DECLSPEC_HIDDEN; - struct unix_funcs { /* win32u functions */ diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index fee1617ef10..a2ef9e72a06 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3438,7 +3438,7 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) /* child windows get WM_CHILDACTIVATE message */ if ((get_window_long( winpos->hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD) send_message( winpos->hwnd, WM_CHILDACTIVATE, 0, 0 ); - else if (user_callbacks) + else set_foreground_window( winpos->hwnd, FALSE ); }
diff --git a/include/ntuser.h b/include/ntuser.h index 67058defb6f..59916d25d6d 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -924,7 +924,6 @@ enum NtUserGetDeskPattern, NtUserGetWinProcPtr, NtUserLock, - NtUserSetCallbacks, NtUserSpyGetVKeyName, };
On Thu Jul 21 09:44:32 2022 +0000, Alexandre Julliard wrote:
This is causing a crash here:
tools/runtest -q -P wine -T . -M comctl32.dll -p dlls/comctl32/tests/comctl32_test.exe tab && touch dlls/comctl32/tests/tab.ok wine: Unhandled stack overflow at address 7B02DDF9 (thread 0120), starting debugger... 0120:err:virtual:virtual_setup_exception stack overflow 1156 bytes in thread 0120 addr 0x7bc5bb1f stack 0x840b7c (0x840000-0x841000-0xa40000) make: *** [Makefile:9298: dlls/comctl32/tests/tab.ok] Error 1
The series didn't enforce message recursion limit when calling window proc directly from user32, the new version should fix it.
BTW, it looks like tab control is also broken when theming is enabled: it has an infinite recursion and depends on win32u to break it.