[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