user: Pass hook handle to the destination thread.

Vitaliy Margolen wine-patch at kievinfo.com
Wed Oct 4 22:27:09 CDT 2006


ChangeLog:
Pass hook handle to the destination thread.
Call server to get hook information for inter-thread hooks.

Changes since last tries:
- Fixed message unpacking for inter-process messages (tested works).
- Use lparam to pass internal structure

 dlls/user/hook.c         |   41 +++++++++++++++++++++++++++++++++++++----
 dlls/user/message.c      |   31 ++++++++++++++++++++++++-------
 dlls/user/user_private.h |    7 +++++++
 server/hook.c            |   29 +++++++++++++++++++++++++++++
 server/protocol.def      |   13 +++++++++++++
 5 files changed, 110 insertions(+), 11 deletions(-)

-------------- next part --------------
4db02177725a6a5d43055c7d8e95616447e3f45c
diff --git a/dlls/user/hook.c b/dlls/user/hook.c
index 4ba1d82..bf348dd 100644
--- a/dlls/user/hook.c
+++ b/dlls/user/hook.c
@@ -329,18 +329,24 @@ static LRESULT call_hook( struct hook_in
 
     if (info->tid)
     {
+        struct hook_extra_info h_extra;
+        h_extra.handle = info->handle;
+        h_extra.lparam = lparam;
+
         TRACE( "calling hook in thread %04x %s code %x wp %x lp %lx\n",
                info->tid, hook_names[info->id-WH_MINHOOK], code, wparam, lparam );
 
         switch(info->id)
         {
         case WH_KEYBOARD_LL:
-            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_KEYBOARD_LL_HOOK, wparam, lparam,
-                                            SMTO_ABORTIFHUNG, get_ll_hook_timeout(), &ret );
+            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_KEYBOARD_LL_HOOK,
+                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
+                                            get_ll_hook_timeout(), &ret );
             break;
         case WH_MOUSE_LL:
-            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_MOUSE_LL_HOOK, wparam, lparam,
-                                            SMTO_ABORTIFHUNG, get_ll_hook_timeout(), &ret );
+            MSG_SendInternalMessageTimeout( info->pid, info->tid, WM_WINE_MOUSE_LL_HOOK,
+                                            wparam, (LPARAM)&h_extra, SMTO_ABORTIFHUNG,
+                                            get_ll_hook_timeout(), &ret );
             break;
         default:
             ERR("Unknown hook id %d\n", info->id);
@@ -547,6 +553,33 @@ LRESULT WINAPI CallNextHookEx( HHOOK hho
 }
 
 
+LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
+{
+    struct hook_info info;
+
+    ZeroMemory( &info, sizeof(info) - sizeof(info.module) );
+
+    SERVER_START_REQ( get_hook_info )
+    {
+        req->handle = hhook;
+        wine_server_set_reply( req, info.module, sizeof(info.module)-sizeof(WCHAR) );
+        if (!wine_server_call_err( req ))
+        {
+            info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
+            info.handle       = hhook;
+            info.id           = reply->id;
+            info.pid          = reply->pid;
+            info.tid          = reply->tid;
+            info.proc         = reply->proc;
+            info.prev_unicode = reply->unicode;
+            info.next_unicode = reply->unicode;
+        }
+    }
+    SERVER_END_REQ;
+
+    return call_hook( &info, code, wparam, lparam );
+}
+
 /***********************************************************************
  *		CallMsgFilterA (USER32.@)
  */
diff --git a/dlls/user/message.c b/dlls/user/message.c
index ccef67b..b92951c 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -612,11 +612,19 @@ static size_t pack_message( HWND hwnd, U
         push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) );
         return 0;
     case WM_WINE_KEYBOARD_LL_HOOK:
-        push_data( data, (KBDLLHOOKSTRUCT *)lparam, sizeof(KBDLLHOOKSTRUCT) );
+    {
+        struct hook_extra_info *h_extra = (struct hook_extra_info *)lparam;
+        push_data( data, h_extra, sizeof(*h_extra) );
+        push_data( data, (LPVOID)h_extra->lparam, sizeof(KBDLLHOOKSTRUCT) );
         return 0;
+    }
     case WM_WINE_MOUSE_LL_HOOK:
-        push_data( data, (MSLLHOOKSTRUCT *)lparam, sizeof(MSLLHOOKSTRUCT) );
+    {
+        struct hook_extra_info *h_extra = (struct hook_extra_info *)lparam;
+        push_data( data, h_extra, sizeof(*h_extra) );
+        push_data( data, (LPVOID)h_extra->lparam, sizeof(MSLLHOOKSTRUCT) );
         return 0;
+    }
     case WM_NCPAINT:
         if (wparam <= 1) return 0;
         FIXME( "WM_NCPAINT hdc packing not supported yet\n" );
@@ -876,11 +884,17 @@ static BOOL unpack_message( HWND hwnd, U
         minsize = sizeof(DEV_BROADCAST_HDR);
         break;
     case WM_WINE_KEYBOARD_LL_HOOK:
-        minsize = sizeof(KBDLLHOOKSTRUCT);
-        break;
     case WM_WINE_MOUSE_LL_HOOK:
-        minsize = sizeof(MSLLHOOKSTRUCT);
+    {
+        struct hook_extra_info *h_extra = (struct hook_extra_info *)*buffer;
+
+        minsize = sizeof(struct hook_extra_info) +
+                  (message == WM_WINE_KEYBOARD_LL_HOOK ? sizeof(KBDLLHOOKSTRUCT)
+                                                       : sizeof(MSLLHOOKSTRUCT));
+        if (size < minsize) return FALSE;
+        h_extra->lparam = (LPARAM)(h_extra + 1);
         break;
+    }
     case WM_NCPAINT:
         if (*wparam <= 1) return TRUE;
         FIXME( "WM_NCPAINT hdc unpacking not supported\n" );
@@ -1189,9 +1203,12 @@ static LRESULT handle_internal_message( 
         if (hwnd == GetDesktopWindow()) return 0;
         return (LRESULT)SetActiveWindow( (HWND)wparam );
     case WM_WINE_KEYBOARD_LL_HOOK:
-        return HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, wparam, lparam, TRUE );
     case WM_WINE_MOUSE_LL_HOOK:
-        return HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, wparam, lparam, TRUE );
+    {
+        struct hook_extra_info *h_extra = (struct hook_extra_info *)lparam;
+
+        return call_current_hook( h_extra->handle, HC_ACTION, wparam, h_extra->lparam );
+    }
     default:
         if (msg >= WM_WINE_FIRST_DRIVER_MSG && msg <= WM_WINE_LAST_DRIVER_MSG)
             return USER_Driver->pWindowMessage( hwnd, msg, wparam, lparam );
diff --git a/dlls/user/user_private.h b/dlls/user/user_private.h
index 00e9b45..39a1d15 100644
--- a/dlls/user/user_private.h
+++ b/dlls/user/user_private.h
@@ -182,6 +182,12 @@ struct user_thread_info
                                                           /* 30-7c Available for more data */
 };
 
+struct hook_extra_info
+{
+    HHOOK handle;
+    LPARAM lparam;
+};
+
 static inline struct user_thread_info *get_user_thread_info(void)
 {
     return (struct user_thread_info *)NtCurrentTeb()->Win32ClientInfo;
@@ -200,6 +206,7 @@ extern HBRUSH SYSCOLOR_55AABrush;
 extern BOOL CLIPBOARD_ReleaseOwner(void);
 extern BOOL FOCUS_MouseActivate( HWND hwnd );
 extern BOOL HOOK_IsHooked( INT id );
+extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
 extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid,
                                                UINT msg, WPARAM wparam, LPARAM lparam,
                                                UINT flags, UINT timeout, PDWORD_PTR res_ptr );
diff --git a/server/hook.c b/server/hook.c
index b2cb0b8..21ae119 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -567,3 +567,32 @@ DECL_HANDLER(get_next_hook)
         reply->proc = next->proc;
     }
 }
+
+
+/* get the hook's information */
+DECL_HANDLER(get_hook_info)
+{
+    struct hook *hook;
+
+    if (!(hook = get_user_object( req->handle, USER_HOOK ))) return;
+    if (hook->thread && (hook->thread != current))
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+    reply->id      = hook->index + WH_MINHOOK;
+    reply->unicode = hook->unicode;
+    if (hook->module) set_reply_data( hook->module, hook->module_size );
+
+    if (run_hook_in_owner_thread( hook ))
+    {
+        reply->pid = get_process_id( hook->owner->process );
+        reply->tid = get_thread_id( hook->owner );
+    }
+    else
+    {
+        reply->pid = 0;
+        reply->tid = 0;
+    }
+    reply->proc = hook->proc;
+}
diff --git a/server/protocol.def b/server/protocol.def
index caddcc2..a45e609 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2388,6 +2388,19 @@ #define SET_CARET_STATE      0x04  /* se
 @END
 
 
+/* Get the hook's information */
+ at REQ(get_hook_info)
+    user_handle_t  handle;         /* handle to the current hook */
+ at REPLY
+    int            id;             /* id of the next hook */
+    process_id_t   pid;            /* process id for low-level keyboard/mouse hooks */
+    thread_id_t    tid;            /* thread id for low-level keyboard/mouse hooks */
+    void*          proc;           /* next hook procedure */
+    int            unicode;        /* is hook unicode hook? */
+    VARARG(module,unicode_str);    /* module name */
+ at END
+
+
 /* Create a window class */
 @REQ(create_class)
     int            local;          /* is it a local class? */



More information about the wine-patches mailing list