From 4a40b2eefb5b141894a0cd5dfd99b664887801bb Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 11 Jul 2005 18:05:50 +0000 Subject: [PATCH] Store the global hooks table in the desktop object. --- server/hook.c | 87 +++++++++++++++++++++------------------------ server/request.c | 1 - server/user.h | 2 +- server/winstation.c | 6 ++-- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/server/hook.c b/server/hook.c index 0830450bce3..eb40d140cec 100644 --- a/server/hook.c +++ b/server/hook.c @@ -44,6 +44,7 @@ struct hook struct process *process; /* process the hook is set to */ struct thread *thread; /* thread the hook is set to */ struct thread *owner; /* owner of the out of context hook */ + struct hook_table *table; /* hook table that contains this hook */ int index; /* hook table index */ int event_min; int event_max; @@ -84,8 +85,6 @@ static const struct object_ops hook_table_ops = }; -static struct hook_table *global_hooks; - /* create a new hook table */ static struct hook_table *alloc_hook_table(void) { @@ -103,16 +102,27 @@ static struct hook_table *alloc_hook_table(void) return table; } +static struct hook_table *get_global_hooks( struct thread *thread ) +{ + struct hook_table *table; + struct desktop *desktop = get_thread_desktop( thread, 0 ); + + if (!desktop) return NULL; + table = desktop->global_hooks; + release_object( desktop ); + return table; +} + /* create a new hook and add it to the specified table */ -static struct hook *add_hook( struct thread *thread, int index, int global ) +static struct hook *add_hook( struct desktop *desktop, struct thread *thread, int index, int global ) { struct hook *hook; - struct hook_table *table = global ? global_hooks : get_queue_hooks(thread); + struct hook_table *table = global ? desktop->global_hooks : get_queue_hooks(thread); if (!table) { if (!(table = alloc_hook_table())) return NULL; - if (global) global_hooks = table; + if (global) desktop->global_hooks = table; else set_queue_hooks( thread, table ); } if (!(hook = mem_alloc( sizeof(*hook) ))) return NULL; @@ -123,6 +133,7 @@ static struct hook *add_hook( struct thread *thread, int index, int global ) return NULL; } hook->thread = thread ? (struct thread *)grab_object( thread ) : NULL; + hook->table = table; hook->index = index; list_add_head( &table->hooks[index], &hook->chain ); if (thread) thread->desktop_users++; @@ -163,15 +174,6 @@ static struct hook *find_hook( struct thread *thread, int index, void *proc ) return NULL; } -/* get the hook table that a given hook belongs to */ -inline static struct hook_table *get_table( struct hook *hook ) -{ - if (!hook->thread) return global_hooks; - if (hook->index + WH_MINHOOK == WH_KEYBOARD_LL) return global_hooks; - if (hook->index + WH_MINHOOK == WH_MOUSE_LL) return global_hooks; - return get_queue_hooks(hook->thread); -} - /* get the first hook in the chain */ inline static struct hook *get_first_hook( struct hook_table *table, int index ) { @@ -220,10 +222,10 @@ inline static struct hook *get_first_valid_hook( struct hook_table *table, int i } /* find the next hook in the chain, skipping the deleted ones */ -static struct hook *get_next_hook( struct hook *hook, int event, user_handle_t win, - int object_id, int child_id ) +static struct hook *get_next_hook( struct thread *thread, struct hook *hook, int event, + user_handle_t win, int object_id, int child_id ) { - struct hook_table *table = get_table( hook ); + struct hook_table *global_hooks, *table = hook->table; int index = hook->index; while ((hook = HOOK_ENTRY( list_next( &table->hooks[index], &hook->chain ) ))) @@ -242,6 +244,7 @@ static struct hook *get_next_hook( struct hook *hook, int event, user_handle_t w } } } + global_hooks = get_global_hooks( thread ); if (global_hooks && table != global_hooks) /* now search through the global table */ { hook = get_first_valid_hook( global_hooks, index, event, win, object_id, child_id ); @@ -251,9 +254,8 @@ static struct hook *get_next_hook( struct hook *hook, int event, user_handle_t w static void hook_table_dump( struct object *obj, int verbose ) { - struct hook_table *table = (struct hook_table *)obj; - if (table == global_hooks) fprintf( stderr, "Global hook table\n" ); - else fprintf( stderr, "Hook table\n" ); + /* struct hook_table *table = (struct hook_table *)obj; */ + fprintf( stderr, "Hook table\n" ); } static void hook_table_destroy( struct object *obj ) @@ -268,17 +270,10 @@ static void hook_table_destroy( struct object *obj ) } } -/* free the global hooks table */ -void close_global_hooks(void) -{ - if (global_hooks) release_object( global_hooks ); -} - /* remove a hook, freeing it if the chain is not in use */ static void remove_hook( struct hook *hook ) { - struct hook_table *table = get_table( hook ); - if (table->counts[hook->index]) + if (hook->table->counts[hook->index]) hook->proc = NULL; /* chain is in use, just mark it and return */ else free_hook( hook ); @@ -307,6 +302,7 @@ static void release_hook_chain( struct hook_table *table, int index ) /* remove all global hooks owned by a given thread */ void remove_thread_hooks( struct thread *thread ) { + struct hook_table *global_hooks = get_global_hooks( thread ); int index; if (!global_hooks) return; @@ -341,6 +337,7 @@ static int is_hook_active( struct hook_table *table, int index ) unsigned int get_active_hooks(void) { struct hook_table *table = get_queue_hooks( current ); + struct hook_table *global_hooks = get_global_hooks( current ); unsigned int ret = 1 << 31; /* set high bit to indicate that the bitmap is valid */ int id; @@ -358,6 +355,7 @@ DECL_HANDLER(set_hook) { struct process *process = NULL; struct thread *thread = NULL; + struct desktop *desktop; struct hook *hook; WCHAR *module; int global; @@ -369,21 +367,17 @@ DECL_HANDLER(set_hook) return; } - if (req->pid && !(process = get_process_from_id( req->pid ))) return; + if (!(desktop = get_thread_desktop( current, DESKTOP_HOOKCONTROL ))) return; + + if (req->pid && !(process = get_process_from_id( req->pid ))) goto done; if (req->tid) { - if (!(thread = get_thread_from_id( req->tid ))) - { - if (process) release_object( process ); - return; - } + if (!(thread = get_thread_from_id( req->tid ))) goto done; if (process && process != thread->process) { - release_object( process ); - release_object( thread ); set_error( STATUS_INVALID_PARAMETER ); - return; + goto done; } } @@ -399,14 +393,10 @@ DECL_HANDLER(set_hook) /* out of context hooks do not need a module handle */ if (!module_size && (req->flags & WINEVENT_INCONTEXT)) { - if (process) release_object( process ); - if (thread) release_object( thread ); set_error( STATUS_INVALID_PARAMETER ); - return; + goto done; } - - if (!(module = memdup( get_req_data(), module_size ))) return; - thread = NULL; + if (!(module = memdup( get_req_data(), module_size ))) goto done; global = 1; } else @@ -415,7 +405,7 @@ DECL_HANDLER(set_hook) global = 0; } - if ((hook = add_hook( thread, req->id - WH_MINHOOK, global ))) + if ((hook = add_hook( desktop, thread, req->id - WH_MINHOOK, global ))) { hook->owner = (struct thread *)grab_object( current ); hook->process = process ? (struct process *)grab_object( process ) : NULL; @@ -431,8 +421,10 @@ DECL_HANDLER(set_hook) } else if (module) free( module ); +done: if (process) release_object( process ); if (thread) release_object( thread ); + release_object( desktop ); } @@ -485,8 +477,8 @@ DECL_HANDLER(start_hook_chain) req->window, req->object_id, req->child_id ))) { /* try global table */ - if (!(table = global_hooks) || - !(hook = get_first_valid_hook( global_hooks, req->id - WH_MINHOOK, req->event, + if (!(table = get_global_hooks( current )) || + !(hook = get_first_valid_hook( table, req->id - WH_MINHOOK, req->event, req->window, req->object_id, req->child_id ))) return; /* no hook set */ } @@ -513,6 +505,7 @@ DECL_HANDLER(start_hook_chain) DECL_HANDLER(finish_hook_chain) { struct hook_table *table = get_queue_hooks( current ); + struct hook_table *global_hooks = get_global_hooks( current ); int index = req->id - WH_MINHOOK; if (req->id < WH_MINHOOK || req->id > WH_WINEVENT) @@ -536,7 +529,7 @@ DECL_HANDLER(get_next_hook) set_error( STATUS_INVALID_HANDLE ); return; } - if ((next = get_next_hook( hook, req->event, req->window, req->object_id, req->child_id ))) + if ((next = get_next_hook( current, hook, req->event, req->window, req->object_id, req->child_id ))) { reply->next = next->handle; reply->id = next->index + WH_MINHOOK; diff --git a/server/request.c b/server/request.c index 8e3f79bf0bf..7c0a2a55dc5 100644 --- a/server/request.c +++ b/server/request.c @@ -795,7 +795,6 @@ static void close_socket_timeout( void *arg ) /* shut down everything properly */ release_object( master_socket ); close_signals(); - close_global_hooks(); close_global_handles(); close_registry(); dump_objects(); /* dump any remaining objects */ diff --git a/server/user.h b/server/user.h index d8c4b7c81bd..84d3d04443a 100644 --- a/server/user.h +++ b/server/user.h @@ -57,6 +57,7 @@ struct desktop struct winstation *winstation; /* winstation this desktop belongs to */ struct list entry; /* entry in winstation list of desktops */ struct window *top_window; /* desktop window for this desktop */ + struct hook_table *global_hooks; /* table of global hooks on this desktop */ }; /* user handles functions */ @@ -74,7 +75,6 @@ extern void cleanup_clipboard_thread( struct thread *thread ); /* hook functions */ -extern void close_global_hooks(void); extern void remove_thread_hooks( struct thread *thread ); extern unsigned int get_active_hooks(void); diff --git a/server/winstation.c b/server/winstation.c index 31f5e03ce23..a51315113a9 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -189,6 +189,7 @@ static struct desktop *create_desktop( const WCHAR *name, size_t len, unsigned i desktop->flags = flags; desktop->winstation = (struct winstation *)grab_object( winstation ); desktop->top_window = NULL; + desktop->global_hooks = NULL; list_add_tail( &winstation->desktops, &desktop->entry ); } } @@ -200,8 +201,8 @@ static void desktop_dump( struct object *obj, int verbose ) { struct desktop *desktop = (struct desktop *)obj; - fprintf( stderr, "Desktop flags=%x winstation=%p top_win=%p", - desktop->flags, desktop->winstation, desktop->top_window ); + fprintf( stderr, "Desktop flags=%x winstation=%p top_win=%p hooks=%p ", + desktop->flags, desktop->winstation, desktop->top_window, desktop->global_hooks ); dump_object_name( &desktop->obj ); fputc( '\n', stderr ); } @@ -222,6 +223,7 @@ static void desktop_destroy( struct object *obj ) struct desktop *desktop = (struct desktop *)obj; if (desktop->top_window) destroy_window( desktop->top_window ); + if (desktop->global_hooks) release_object( desktop->global_hooks ); list_remove( &desktop->entry ); release_object( desktop->winstation ); }