Jacek Caban : user32: Avoid using NtUserDispatchMessage in DispatchMessage.
Alexandre Julliard
julliard at winehq.org
Thu Jul 21 17:04:07 CDT 2022
Module: wine
Branch: master
Commit: 26a4fb74ee9966252724627969a35637fb5e8f70
URL: https://gitlab.winehq.org/wine/wine/-/commit/26a4fb74ee9966252724627969a35637fb5e8f70
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Jul 19 18:33:42 2022 +0200
user32: Avoid using NtUserDispatchMessage in DispatchMessage.
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 */
More information about the wine-cvs
mailing list