From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/hook.c | 16 +++++++++++----- dlls/win32u/message.c | 2 +- dlls/win32u/win32u_private.h | 1 + dlls/win32u/winstation.c | 35 +++++++++++++++++++++++++++++++++++ server/protocol.def | 9 ++++++++- server/queue.c | 12 ++++++++++-- 6 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/dlls/win32u/hook.c b/dlls/win32u/hook.c index eca9e7d6ce9..3e2798b8c75 100644 --- a/dlls/win32u/hook.c +++ b/dlls/win32u/hook.c @@ -62,10 +62,16 @@ static const char *debugstr_hook_id( unsigned int id )
BOOL is_hooked( INT id ) { - struct user_thread_info *thread_info = get_user_thread_info(); + struct object_lock lock = OBJECT_LOCK_INIT; + const queue_shm_t *queue_shm; + BOOL ret = TRUE; + UINT status; + + while ((status = get_shared_queue( &lock, &queue_shm )) == STATUS_PENDING) + ret = queue_shm->hooks_count[id - WH_MINHOOK] > 0;
- if (!thread_info->active_hooks) return TRUE; - return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0; + if (status) return TRUE; + return ret; }
/*********************************************************************** @@ -430,7 +436,7 @@ LRESULT call_message_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, size
if (!is_hooked( id )) { - TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks ); + TRACE( "skipping hook %s\n", hook_names[id - WH_MINHOOK] ); return 0; }
@@ -569,7 +575,7 @@ void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG c
if (!is_hooked( WH_WINEVENT )) { - TRACE( "skipping hook mask %x\n", thread_info->active_hooks ); + TRACE( "skipping hook\n" ); return; }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index b7062414658..941af31701f 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2945,7 +2945,7 @@ static HANDLE get_server_queue_handle(void)
if (!(ret = thread_info->server_queue)) { - SERVER_START_REQ( get_msg_queue ) + SERVER_START_REQ( get_msg_queue_handle ) { wine_server_call( req ); ret = wine_server_ptr_handle( reply->handle ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e2e35d6c40d..cd64751e95b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -219,6 +219,7 @@ struct object_lock * on it, within the loop, or after, unless the function has returned STATUS_SUCCESS. */ extern NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **desktop_shm ); +extern NTSTATUS get_shared_queue( struct object_lock *lock, const queue_shm_t **queue_shm );
extern BOOL is_virtual_desktop(void);
diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 1676539c69c..1a1b37f6eda 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -48,6 +48,7 @@ WINE_DECLARE_DEBUG_CHANNEL(win); struct session_thread_data { const shared_object_t *shared_desktop; /* thread desktop shared session cached object */ + const shared_object_t *shared_queue; /* thread message queue shared session cached object */ };
struct session_block @@ -219,6 +220,40 @@ NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **des return STATUS_SUCCESS; }
+NTSTATUS get_shared_queue( struct object_lock *lock, const queue_shm_t **queue_shm ) +{ + struct session_thread_data *data = get_session_thread_data(); + const shared_object_t *object; + + TRACE( "lock %p, queue_shm %p\n", lock, queue_shm ); + + if (!(object = data->shared_queue)) + { + obj_locator_t locator; + + SERVER_START_REQ( get_msg_queue ) + { + wine_server_call( req ); + locator = reply->locator; + } + SERVER_END_REQ; + + data->shared_queue = find_shared_session_object( locator ); + if (!(object = data->shared_queue)) return STATUS_INVALID_HANDLE; + memset( lock, 0, sizeof(*lock) ); + } + + if (!lock->id || !shared_object_release_seqlock( object, lock->seq )) + { + shared_object_acquire_seqlock( object, &lock->seq ); + *queue_shm = &object->shm.queue; + lock->id = object->id; + return STATUS_PENDING; + } + + return STATUS_SUCCESS; +} + BOOL is_virtual_desktop(void) { HANDLE desktop = NtUserGetThreadDesktop( GetCurrentThreadId() ); diff --git a/server/protocol.def b/server/protocol.def index 12c27a8e3e1..128aab3a812 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2115,10 +2115,17 @@ struct process_info @END
+/* Get a handle for the current thread message queue */ +@REQ(get_msg_queue_handle) +@REPLY + obj_handle_t handle; /* handle to the queue */ +@END + + /* Get the message queue of the current thread */ @REQ(get_msg_queue) @REPLY - obj_handle_t handle; /* handle to the queue */ + obj_locator_t locator; /* locator for the shared session object */ @END
diff --git a/server/queue.c b/server/queue.c index 6d9c9f20a5f..f73beb3ce4c 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2902,8 +2902,8 @@ DECL_HANDLER(is_window_hung) }
-/* get the message queue of the current thread */ -DECL_HANDLER(get_msg_queue) +/* get a handle for the current thread message queue */ +DECL_HANDLER(get_msg_queue_handle) { struct msg_queue *queue = get_current_queue();
@@ -2912,6 +2912,14 @@ DECL_HANDLER(get_msg_queue) }
+/* get the message queue of the current thread */ +DECL_HANDLER(get_msg_queue) +{ + struct msg_queue *queue = get_current_queue(); + if (queue) reply->locator = get_shared_object_locator( queue->shared ); +} + + /* set the file descriptor associated to the current thread queue */ DECL_HANDLER(set_queue_fd) {