Module: wine Branch: master Commit: fcf7d2a140c2d4f41bdb3aa5f967ccfe1c728646 URL: https://source.winehq.org/git/wine.git/?a=commit;h=fcf7d2a140c2d4f41bdb3aa5f...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Feb 16 12:30:44 2022 +0100
win32u: Move NtUserSetWindowsHookEx implementation from user32.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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 );