Jacek Caban : win32u: Move NtUserSetWindowsHookEx implementation from user32.
Alexandre Julliard
julliard at winehq.org
Wed Feb 16 15:30:25 CST 2022
Module: wine
Branch: master
Commit: fcf7d2a140c2d4f41bdb3aa5f967ccfe1c728646
URL: https://source.winehq.org/git/wine.git/?a=commit;h=fcf7d2a140c2d4f41bdb3aa5f967ccfe1c728646
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Feb 16 12:30:44 2022 +0100
win32u: Move NtUserSetWindowsHookEx implementation from user32.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/user32/hook.c | 69 +++++++--------------------------------
dlls/win32u/hook.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
dlls/win32u/syscall.c | 1 +
dlls/win32u/win32u.spec | 2 +-
dlls/wow64win/syscall.h | 1 +
dlls/wow64win/user.c | 16 ++++++++++
include/ntuser.h | 2 ++
7 files changed, 118 insertions(+), 58 deletions(-)
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 3adfba43691..71ddb6860dc 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -140,73 +140,28 @@ static UINT get_ll_hook_timeout(void)
*
* Implementation of SetWindowsHookExA and SetWindowsHookExW.
*/
-static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode )
+static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL ansi )
{
- HHOOK handle = 0;
WCHAR module[MAX_PATH];
- DWORD len;
+ UNICODE_STRING str;
- if (!proc)
+ if (!inst)
{
- SetLastError( ERROR_INVALID_FILTER_PROC );
- return 0;
+ RtlInitUnicodeString( &str, NULL );
}
-
- if (tid) /* thread-local hook */
+ else
{
- if (id == WH_JOURNALRECORD ||
- id == WH_JOURNALPLAYBACK ||
- id == WH_KEYBOARD_LL ||
- id == WH_MOUSE_LL ||
- id == WH_SYSMSGFILTER)
+ size_t len = GetModuleFileNameW( inst, module, ARRAYSIZE(module) );
+ if (!len || len >= ARRAYSIZE(module))
{
- /* these can only be global */
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
+ str.Buffer = module;
+ str.MaximumLength = str.Length = len * sizeof(WCHAR);
}
- else /* system-global hook */
- {
- if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
- else if (!inst)
- {
- SetLastError( ERROR_HOOK_NEEDS_HMOD );
- return 0;
- }
- }
-
- if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH))
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
-
- SERVER_START_REQ( set_hook )
- {
- req->id = id;
- req->pid = 0;
- req->tid = tid;
- req->event_min = EVENT_MIN;
- req->event_max = EVENT_MAX;
- req->flags = WINEVENT_INCONTEXT;
- req->unicode = unicode;
- if (inst) /* make proc relative to the module base */
- {
- req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
- wine_server_add_data( req, module, lstrlenW(module) * sizeof(WCHAR) );
- }
- else req->proc = wine_server_client_ptr( proc );
-
- if (!wine_server_call_err( req ))
- {
- handle = wine_server_ptr_handle( reply->handle );
- get_user_thread_info()->active_hooks = reply->active_hooks;
- }
- }
- SERVER_END_REQ;
- TRACE( "%s %p %x -> %p\n", hook_names[id-WH_MINHOOK], proc, tid, handle );
- return handle;
+ return NtUserSetWindowsHookEx( inst, &str, tid, id, proc, ansi );
}
#ifdef __i386__
@@ -548,7 +503,7 @@ HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
*/
HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
- return set_windows_hook( id, proc, inst, tid, FALSE );
+ return set_windows_hook( id, proc, inst, tid, TRUE );
}
/***********************************************************************
@@ -556,7 +511,7 @@ HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid
*/
HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
- return set_windows_hook( id, proc, inst, tid, TRUE );
+ return set_windows_hook( id, proc, inst, tid, FALSE );
}
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c
index 748ff3e9031..c91ccf41f6f 100644
--- a/dlls/win32u/hook.c
+++ b/dlls/win32u/hook.c
@@ -32,6 +32,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(hook);
#define WH_WINEVENT (WH_MAXHOOK+1)
+static const char * const hook_names[WH_WINEVENT - WH_MINHOOK + 1] =
+{
+ "WH_MSGFILTER",
+ "WH_JOURNALRECORD",
+ "WH_JOURNALPLAYBACK",
+ "WH_KEYBOARD",
+ "WH_GETMESSAGE",
+ "WH_CALLWNDPROC",
+ "WH_CBT",
+ "WH_SYSMSGFILTER",
+ "WH_MOUSE",
+ "WH_HARDWARE",
+ "WH_DEBUG",
+ "WH_SHELL",
+ "WH_FOREGROUNDIDLE",
+ "WH_CALLWNDPROCRET",
+ "WH_KEYBOARD_LL",
+ "WH_MOUSE_LL",
+ "WH_WINEVENT"
+};
static BOOL is_hooked( INT id )
{
@@ -41,6 +61,71 @@ static BOOL is_hooked( INT id )
return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0;
}
+/***********************************************************************
+ * NtUserSetWindowsHookEx (win32u.@)
+ */
+HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, DWORD tid, INT id,
+ HOOKPROC proc, BOOL ansi )
+{
+ HHOOK handle = 0;
+
+ if (!proc)
+ {
+ SetLastError( ERROR_INVALID_FILTER_PROC );
+ return 0;
+ }
+
+ if (tid) /* thread-local hook */
+ {
+ if (id == WH_JOURNALRECORD ||
+ id == WH_JOURNALPLAYBACK ||
+ id == WH_KEYBOARD_LL ||
+ id == WH_MOUSE_LL ||
+ id == WH_SYSMSGFILTER)
+ {
+ /* these can only be global */
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+ }
+ else /* system-global hook */
+ {
+ if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
+ else if (!inst)
+ {
+ SetLastError( ERROR_HOOK_NEEDS_HMOD );
+ return 0;
+ }
+ }
+
+ SERVER_START_REQ( set_hook )
+ {
+ req->id = id;
+ req->pid = 0;
+ req->tid = tid;
+ req->event_min = EVENT_MIN;
+ req->event_max = EVENT_MAX;
+ req->flags = WINEVENT_INCONTEXT;
+ req->unicode = !ansi;
+ if (inst) /* make proc relative to the module base */
+ {
+ req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
+ wine_server_add_data( req, module->Buffer, module->Length );
+ }
+ else req->proc = wine_server_client_ptr( proc );
+
+ if (!wine_server_call_err( req ))
+ {
+ handle = wine_server_ptr_handle( reply->handle );
+ get_user_thread_info()->active_hooks = reply->active_hooks;
+ }
+ }
+ SERVER_END_REQ;
+
+ TRACE( "%s %p %x -> %p\n", hook_names[id - WH_MINHOOK], proc, tid, handle );
+ return handle;
+}
+
/***********************************************************************
* NtUserSetWinEventHook (win32u.@)
*/
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 3034a0377ff..9258b6b6377 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -141,6 +141,7 @@ static void * const syscalls[] =
NtUserSetProp,
NtUserSetThreadDesktop,
NtUserSetWinEventHook,
+ NtUserSetWindowsHookEx,
NtUserUnhookWinEvent,
};
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 5ddbf53af77..0088d21eda5 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -1256,7 +1256,7 @@
@ stub NtUserSetWindowStationUser
@ stub NtUserSetWindowWord
@ stub NtUserSetWindowsHookAW
-@ stub NtUserSetWindowsHookEx
+@ stdcall -syscall NtUserSetWindowsHookEx(ptr ptr long long ptr long)
@ stub NtUserShowCaret
@ stdcall NtUserShowCursor(long)
@ stub NtUserShowScrollBar
diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h
index 50b442ecaea..6c70d95f263 100644
--- a/dlls/wow64win/syscall.h
+++ b/dlls/wow64win/syscall.h
@@ -128,6 +128,7 @@
SYSCALL_ENTRY( NtUserSetProp ) \
SYSCALL_ENTRY( NtUserSetThreadDesktop ) \
SYSCALL_ENTRY( NtUserSetWinEventHook ) \
+ SYSCALL_ENTRY( NtUserSetWindowsHookEx ) \
SYSCALL_ENTRY( NtUserUnhookWinEvent )
#endif /* __WOW64WIN_SYSCALL_H */
diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c
index 7a97cbed7f2..b78ae290049 100644
--- a/dlls/wow64win/user.c
+++ b/dlls/wow64win/user.c
@@ -392,3 +392,19 @@ NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args )
return NtUserUnhookWinEvent( handle );
}
+
+NTSTATUS WINAPI wow64_NtUserSetWindowsHookEx( UINT *args )
+{
+ HINSTANCE inst = get_handle( &args );
+ UNICODE_STRING32 *module32 = get_ptr( &args );
+ DWORD tid = get_ulong( &args );
+ INT id = get_ulong( &args );
+ HOOKPROC proc = get_ptr( &args );
+ BOOL ansi = get_ulong( &args );
+ UNICODE_STRING module;
+ HHOOK ret;
+
+ ret = NtUserSetWindowsHookEx( inst, unicode_str_32to64( &module, module32 ),
+ tid, id, proc, ansi );
+ return HandleToUlong( ret );
+}
diff --git a/include/ntuser.h b/include/ntuser.h
index 6f166f70d05..a591363f77e 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -193,6 +193,8 @@ BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle );
BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle );
BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values );
BOOL WINAPI NtUserSetThreadDesktop( HDESK handle );
+HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, DWORD tid, INT id,
+ HOOKPROC proc, BOOL ansi );
HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HMODULE inst,
UNICODE_STRING *module, WINEVENTPROC proc,
DWORD pid, DWORD tid, DWORD flags );
More information about the wine-cvs
mailing list