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,
+                            &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 );
 }
 
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