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 */