diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 633704be4d5a41b963f232d9fabee87e6bf01d70..2f6b42cd3270b7f6f843ce77b3494ca3918b6d7a 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -359,11 +359,13 @@ static LRESULT call_hook_proc( HOOKPROC proc, INT id, INT code, WPARAM wparam, L * * Retrieve the hook procedure real value for a module-relative proc */ -void *get_hook_proc( void *proc, const WCHAR *module ) +void *get_hook_proc( void *proc, const WCHAR *module, HMODULE *free_module ) { HMODULE mod; - if (!(mod = GetModuleHandleW(module))) + GetModuleHandleExW( 0, module, &mod ); + *free_module = mod; + if (!mod) { TRACE( "loading %s\n", debugstr_w(module) ); /* FIXME: the library will never be freed */ @@ -411,12 +413,13 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA } else if (info->proc) { + HMODULE free_module = 0; TRACE( "calling hook %p %s code %x wp %lx lp %lx module %s\n", info->proc, hook_names[info->id-WH_MINHOOK], code, wparam, lparam, debugstr_w(info->module) ); if (!info->module[0] || - (info->proc = get_hook_proc( info->proc, info->module )) != NULL) + (info->proc = get_hook_proc( info->proc, info->module, &free_module )) != NULL) { struct user_thread_info *thread_info = get_user_thread_info(); HHOOK prev = thread_info->hook; @@ -428,6 +431,8 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA info->prev_unicode, info->next_unicode ); thread_info->hook = prev; thread_info->hook_unicode = prev_unicode; + + if (free_module) FreeLibrary(free_module); } } @@ -897,10 +902,11 @@ void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id WINEVENTPROC proc = info.proc; if (proc) { + HMODULE free_module = 0; TRACE( "calling WH_WINEVENT hook %p event %x hwnd %p %x %x module %s\n", proc, event, hwnd, object_id, child_id, debugstr_w(info.module) ); - if (!info.module[0] || (proc = get_hook_proc( proc, info.module )) != NULL) + if (!info.module[0] || (proc = get_hook_proc( proc, info.module, &free_module )) != NULL) { if (TRACE_ON(relay)) DPRINTF( "%04x:Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n", @@ -914,6 +920,8 @@ void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id DPRINTF( "%04x:Ret winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n", GetCurrentThreadId(), proc, info.handle, event, hwnd, object_id, child_id, GetCurrentThreadId(), GetCurrentTime()); + + if (free_module) FreeLibrary(free_module); } } else diff --git a/dlls/user32/message.c b/dlls/user32/message.c index be5d995b0ba41c9a6123670e0feebeff962bd929..3167a2f16aa544072fb8d5d41c321d051b6d7478 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -2815,6 +2815,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags if (size >= sizeof(msg_data->winevent)) { WINEVENTPROC hook_proc; + HMODULE free_module = 0; hook_proc = wine_server_get_ptr( msg_data->winevent.hook_proc ); size -= sizeof(msg_data->winevent); @@ -2825,7 +2826,7 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags size = min( size, (MAX_PATH - 1) * sizeof(WCHAR) ); memcpy( module, &msg_data->winevent + 1, size ); module[size / sizeof(WCHAR)] = 0; - if (!(hook_proc = get_hook_proc( hook_proc, module ))) + if (!(hook_proc = get_hook_proc( hook_proc, module, &free_module ))) { ERR( "invalid winevent hook module name %s\n", debugstr_w(module) ); continue; @@ -2847,6 +2848,8 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags GetCurrentThreadId(), hook_proc, msg_data->winevent.hook, info.msg.message, info.msg.hwnd, info.msg.wParam, info.msg.lParam, msg_data->winevent.tid, info.msg.time); + + if (free_module) FreeLibrary(free_module); } continue; case MSG_HOOK_LL: diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 2bb869aabff5b32cc0b66e2af8c9d3ca6ca05b14..adf3f7d1569134fe30dafcbdccfc2f1ffa92ae4c 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -225,7 +225,7 @@ extern void move_window_bits( HWND hwnd, struct window_surface *old_surface, struct window_surface *new_surface, const RECT *visible_rect, const RECT *old_visible_rect, const RECT *client_rect, const RECT *valid_rects ) DECLSPEC_HIDDEN; -extern void *get_hook_proc( void *proc, const WCHAR *module ) DECLSPEC_HIDDEN; +extern void *get_hook_proc( void *proc, const WCHAR *module, HMODULE *free_module ) DECLSPEC_HIDDEN; extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN; extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern DWORD get_input_codepage( void ) DECLSPEC_HIDDEN;