[PATCH v2 6/9] win32u: Move NtUserCallMsgFilter implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Thu May 5 08:42:41 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

A/W conversion is not used in those cases anyway, so just use a single implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/user32/dialog.c       |  2 +-
 dlls/user32/hook.c         | 20 ----------------
 dlls/user32/menu.c         |  2 +-
 dlls/user32/nonclient.c    |  6 ++---
 dlls/user32/scroll.c       |  2 +-
 dlls/user32/user32.spec    |  6 ++---
 dlls/user32/winpos.c       |  4 ++--
 dlls/win32u/hook.c         | 11 +++++++++
 dlls/win32u/syscall.c      |  1 +
 dlls/win32u/tests/win32u.c | 45 +++++++++++++++++++++++++++++++++++
 dlls/win32u/win32u.spec    |  2 +-
 dlls/wow64win/syscall.h    |  1 +
 dlls/wow64win/user.c       | 48 ++++++++++++++++++++++++++++++++++++++
 include/ntuser.h           |  1 +
 14 files changed, 119 insertions(+), 32 deletions(-)

diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index ea9fae4200a..95967269daf 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -1164,7 +1164,7 @@ BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg )
     if (!IsWindow( hwndDlg ))
         return FALSE;
 
-    if (CallMsgFilterW( msg, MSGF_DIALOGBOX )) return TRUE;
+    if (NtUserCallMsgFilter( msg, MSGF_DIALOGBOX )) return TRUE;
 
     hwndDlg = WIN_GetFullHandle( hwndDlg );
     if (is_desktop_window(hwndDlg)) return FALSE;
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 76033f0dee1..c0ebe05684f 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -383,26 +383,6 @@ BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
 }
 
 
-/***********************************************************************
- *		CallMsgFilterA (USER32.@)
- */
-BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
-{
-    if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, FALSE )) return TRUE;
-    return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, FALSE );
-}
-
-
-/***********************************************************************
- *		CallMsgFilterW (USER32.@)
- */
-BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
-{
-    if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE;
-    return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE );
-}
-
-
 /***********************************************************************
  *           SetWinEventHook                            [USER32.@]
  *
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 64e5d35ba39..afe3c50154e 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -2974,7 +2974,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
         {
             if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
             {
-                if (!CallMsgFilterW( &msg, MSGF_MENU )) break;
+                if (!NtUserCallMsgFilter( &msg, MSGF_MENU )) break;
                 /* remove the message from the queue */
                 PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
             }
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index 003ecb7e5e5..85d1a14a195 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -1249,7 +1249,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
         BOOL oldstate = pressed;
 
         if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
-        if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
+        if (NtUserCallMsgFilter( &msg, MSGF_MAX )) continue;
 
         if(msg.message == WM_LBUTTONUP)
             break;
@@ -1314,7 +1314,7 @@ static void NC_TrackCloseButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
         BOOL oldstate = pressed;
 
         if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
-        if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
+        if (NtUserCallMsgFilter( &msg, MSGF_MAX )) continue;
 
         if(msg.message == WM_LBUTTONUP)
             break;
@@ -1464,7 +1464,7 @@ LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
         for (;;)
         {
             if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
-            if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
+            if (NtUserCallMsgFilter( &msg, MSGF_MAX )) continue;
             if (msg.message == WM_RBUTTONUP)
             {
                 hittest = NC_HandleNCHitTest( hwnd, msg.pt );
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index efe115246f2..1909d4082ce 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -1110,7 +1110,7 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
     do
     {
         if (!GetMessageW( &msg, 0, 0, 0 )) break;
-        if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
+        if (NtUserCallMsgFilter( &msg, MSGF_SCROLLBAR )) continue;
         if (msg.message == WM_LBUTTONUP ||
             msg.message == WM_MOUSEMOVE ||
             msg.message == WM_MOUSELEAVE ||
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 1ae27b2482f..555023de110 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -25,9 +25,9 @@
 # @ stub BuildReasonArray
 @ stdcall CalcChildScroll(long long)
 @ stdcall CalcMenuBar(long long long long ptr) CalcMenuBar
-@ stdcall CallMsgFilter(ptr long) CallMsgFilterA
-@ stdcall CallMsgFilterA(ptr long)
-@ stdcall CallMsgFilterW(ptr long)
+@ stdcall CallMsgFilter(ptr long) NtUserCallMsgFilter
+@ stdcall CallMsgFilterA(ptr long) NtUserCallMsgFilter
+@ stdcall CallMsgFilterW(ptr long) NtUserCallMsgFilter
 @ stdcall CallNextHookEx(long long long long) NtUserCallNextHookEx
 @ stdcall CallWindowProcA(ptr long long long long)
 @ stdcall CallWindowProcW(ptr long long long long)
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 63c08e5d795..cdcd03484cd 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -786,7 +786,7 @@ static LONG start_size_move( HWND hwnd, WPARAM wParam, POINT *capturePoint, LONG
         while(!hittest)
         {
             if (!GetMessageW( &msg, 0, 0, 0 )) return 0;
-            if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
+            if (NtUserCallMsgFilter( &msg, MSGF_SIZE )) continue;
 
             switch(msg.message)
             {
@@ -952,7 +952,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
         int dx = 0, dy = 0;
 
         if (!GetMessageW( &msg, 0, 0, 0 )) break;
-        if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
+        if (NtUserCallMsgFilter( &msg, MSGF_SIZE )) continue;
 
         /* Exit on button-up, Return, or Esc */
         if ((msg.message == WM_LBUTTONUP) ||
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c
index eb08e3d0d0c..a271693622a 100644
--- a/dlls/win32u/hook.c
+++ b/dlls/win32u/hook.c
@@ -172,6 +172,17 @@ BOOL unhook_windows_hook( INT id, HOOKPROC proc )
     return !status;
 }
 
+/***********************************************************************
+ *           NtUserCallMsgFilter (win32u.@)
+ */
+BOOL WINAPI NtUserCallMsgFilter( MSG *msg, INT code )
+{
+    /* FIXME: We should use NtCallbackReturn instead of passing (potentially kernel) pointer
+     * like that, but we need to consequently use syscall thunks first for that to work. */
+    if (call_hooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE;
+    return call_hooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE );
+}
+
 static UINT get_ll_hook_timeout(void)
 {
     /* FIXME: should retrieve LowLevelHooksTimeout in HKEY_CURRENT_USER\Control Panel\Desktop */
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 488056ef439..f306ea12d4a 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -106,6 +106,7 @@ static void * const syscalls[] =
     NtUserAddClipboardFormatListener,
     NtUserAttachThreadInput,
     NtUserBuildHwndList,
+    NtUserCallMsgFilter,
     NtUserCheckMenuItem,
     NtUserChildWindowFromPointEx,
     NtUserCloseDesktop,
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c
index 03c143cc143..11820859358 100644
--- a/dlls/win32u/tests/win32u.c
+++ b/dlls/win32u/tests/win32u.c
@@ -579,6 +579,50 @@ static void test_menu(void)
     ok( ret, "NtUserDestroyMenu failed: %lu\n", GetLastError() );
 }
 
+static MSG *msg_ptr;
+
+static LRESULT WINAPI hook_proc( INT code, WPARAM wparam, LPARAM lparam )
+{
+    msg_ptr = (MSG *)lparam;
+    ok( code == 100, "code = %d\n", code );
+    ok( msg_ptr->time == 1, "time = %lx\n", msg_ptr->time );
+    ok( msg_ptr->wParam == 10, "wParam = %Ix\n", msg_ptr->wParam );
+    ok( msg_ptr->lParam == 20, "lParam = %Ix\n", msg_ptr->lParam );
+    msg_ptr->time = 3;
+    msg_ptr->wParam = 1;
+    msg_ptr->lParam = 2;
+    return CallNextHookEx( NULL, code, wparam, lparam );
+}
+
+static void test_message_filter(void)
+{
+    HHOOK hook;
+    MSG msg;
+    BOOL ret;
+
+    hook = SetWindowsHookExW( WH_MSGFILTER, hook_proc, NULL, GetCurrentThreadId() );
+    ok( hook != NULL, "SetWindowsHookExW failed\n");
+
+    memset( &msg, 0, sizeof(msg) );
+    msg.time = 1;
+    msg.wParam = 10;
+    msg.lParam = 20;
+    ret = NtUserCallMsgFilter( &msg, 100 );
+    ok( !ret, "CallMsgFilterW returned: %x\n", ret );
+    todo_wine
+    ok( msg_ptr != &msg, "our ptr was passed directly to hook\n" );
+
+    if (sizeof(void *) == 8) /* on some Windows versions, msg is not modified on wow64 */
+    {
+        ok( msg.time == 3, "time = %lx\n", msg.time );
+        ok( msg.wParam == 1, "wParam = %Ix\n", msg.wParam );
+        ok( msg.lParam == 2, "lParam = %Ix\n", msg.lParam );
+    }
+
+    ret = NtUserUnhookWindowsHookEx( hook );
+    ok( ret, "NtUserUnhookWindowsHook failed: %lu\n", GetLastError() );
+}
+
 START_TEST(win32u)
 {
     /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */
@@ -592,6 +636,7 @@ START_TEST(win32u)
     test_message_call();
     test_window_text();
     test_menu();
+    test_message_filter();
 
     test_NtUserCloseWindowStation();
 }
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index d6a51c1d3b9..a915f89e578 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -776,7 +776,7 @@
 @ stub NtUserCallHwndParamLock
 @ stub NtUserCallHwndParamLockSafe
 @ stub NtUserCallHwndSafe
-@ stub NtUserCallMsgFilter
+@ stdcall -syscall NtUserCallMsgFilter(ptr long)
 @ stdcall NtUserCallNextHookEx(long long long long)
 @ stdcall NtUserCallNoParam(long)
 @ stdcall NtUserCallOneParam(long long)
diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h
index 27ba163408b..2eb3ac55ff1 100644
--- a/dlls/wow64win/syscall.h
+++ b/dlls/wow64win/syscall.h
@@ -93,6 +93,7 @@
     SYSCALL_ENTRY( NtUserAddClipboardFormatListener ) \
     SYSCALL_ENTRY( NtUserAttachThreadInput ) \
     SYSCALL_ENTRY( NtUserBuildHwndList ) \
+    SYSCALL_ENTRY( NtUserCallMsgFilter ) \
     SYSCALL_ENTRY( NtUserCheckMenuItem ) \
     SYSCALL_ENTRY( NtUserChildWindowFromPointEx ) \
     SYSCALL_ENTRY( NtUserCloseDesktop ) \
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index d90c4ec2f99..e828dae5247 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -46,6 +46,42 @@ typedef struct
     UINT32  hbmpItem;
 } MENUITEMINFOW32;
 
+typedef struct
+{
+    UINT32  hwnd;
+    UINT    message;
+    UINT32  wParam;
+    UINT32  lParam;
+    DWORD   time;
+    POINT   pt;
+} MSG32;
+
+static MSG *msg_32to64( MSG *msg, MSG32 *msg32 )
+{
+    if (!msg32) return NULL;
+
+    msg->hwnd    = UlongToHandle( msg32->hwnd );
+    msg->message = msg32->message;
+    msg->wParam  = msg32->wParam;
+    msg->lParam  = msg32->lParam;
+    msg->time    = msg32->time;
+    msg->pt      = msg32->pt;
+    return msg;
+}
+
+static MSG32 *msg_64to32( MSG *msg, MSG32 *msg32 )
+{
+    if (!msg32) return NULL;
+
+    msg32->hwnd    = HandleToUlong( msg->hwnd );
+    msg32->message = msg->message;
+    msg32->wParam  = msg->wParam;
+    msg32->lParam  = msg->lParam;
+    msg32->time    = msg->time;
+    msg32->pt      = msg->pt;
+    return msg32;
+}
+
 NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args )
 {
     FIXME( "\n" );
@@ -555,6 +591,18 @@ NTSTATUS WINAPI wow64_NtUserUnhookWindowsHookEx( UINT *args )
     return NtUserUnhookWindowsHookEx( handle );
 }
 
+NTSTATUS WINAPI wow64_NtUserCallMsgFilter( UINT *args )
+{
+    MSG32 *msg32 = get_ptr( &args );
+    INT code = get_ulong( &args );
+    MSG msg;
+    BOOL ret;
+
+    ret = NtUserCallMsgFilter( msg_32to64( &msg, msg32 ), code );
+    msg_64to32( &msg, msg32 );
+    return ret;
+}
+
 NTSTATUS WINAPI wow64_NtUserGetForegroundWindow( UINT *args )
 {
     return HandleToUlong( NtUserGetForegroundWindow() );
diff --git a/include/ntuser.h b/include/ntuser.h
index fdc43cac8ed..bc44ac76d4e 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -462,6 +462,7 @@ NTSTATUS WINAPI NtUserBuildHwndList( HDESK desktop, ULONG unk2, ULONG unk3, ULON
 ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code );
 ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code );
 LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
+BOOL    WINAPI NtUserCallMsgFilter( MSG *msg, INT code );
 ULONG_PTR WINAPI NtUserCallNoParam( ULONG code );
 ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code );
 ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code );
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/39



More information about the wine-devel mailing list