From: Jacek Caban jacek@codeweavers.com
A/W conversion is not used in those cases anyway, so just use a single implementation.
Signed-off-by: Jacek Caban jacek@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 );