user32: Avoid using NtUserDispatchMessage in DispatchMessage.

When possible, call window proc on PE side to allow unwinding exceptions through DispatchMessageW call.
This commit is contained in:
Jacek Caban 2022-07-19 18:33:42 +02:00 committed by Alexandre Julliard
parent e382997c8b
commit 26a4fb74ee
5 changed files with 40 additions and 3 deletions

View file

@ -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,
&params, NtUserGetDispatchParams, ansi )) return 0;
params.result = &retval;
SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam );
dispatch_win_proc_params( &params );
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 );
}

View file

@ -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,

View file

@ -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 );

View file

@ -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;

View file

@ -276,8 +276,9 @@ enum
NtUserSendMessageCallback = 0x02b8,
/* Wine-specific exports */
NtUserClipboardWindowProc = 0x0300,
NtUserSpyEnter = 0x0301,
NtUserSpyExit = 0x0302,
NtUserGetDispatchParams = 0x3001,
NtUserSpyEnter = 0x0302,
NtUserSpyExit = 0x0303,
};
/* NtUserThunkedMenuItemInfo codes */