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