From f7541123b595d86d78c97e1b73a681dad4cb53ee Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 13 Jun 2014 21:49:49 +0200 Subject: [PATCH] Add patch to avoid race-condition when unloading modules while hook is active. --- ...e-condition-when-unloading-module-wh.patch | 124 ++++++++++++++++++ .../46fb5f97-34cb-4b6b-ae10-7511db90ba1d.def | 4 + patches/patch-list.patch | 3 +- 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 patches/98-Miscellaneous/0005-user32-Avoid-race-condition-when-unloading-module-wh.patch create mode 100644 patches/98-Miscellaneous/46fb5f97-34cb-4b6b-ae10-7511db90ba1d.def diff --git a/patches/98-Miscellaneous/0005-user32-Avoid-race-condition-when-unloading-module-wh.patch b/patches/98-Miscellaneous/0005-user32-Avoid-race-condition-when-unloading-module-wh.patch new file mode 100644 index 00000000..9cf0907b --- /dev/null +++ b/patches/98-Miscellaneous/0005-user32-Avoid-race-condition-when-unloading-module-wh.patch @@ -0,0 +1,124 @@ +From 038eae36c2d25095acafa702e27522cdb286d2a7 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 13 Jun 2014 20:35:41 +0200 +Subject: user32: Avoid race-condition when unloading module while hook is + still active. + +--- + dlls/user32/hook.c | 16 ++++++++++++---- + dlls/user32/message.c | 5 ++++- + dlls/user32/user_private.h | 2 +- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c +index 633704b..2f6b42c 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 be5d995..3167a2f 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 2bb869a..adf3f7d 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; +-- +1.7.9.5 + diff --git a/patches/98-Miscellaneous/46fb5f97-34cb-4b6b-ae10-7511db90ba1d.def b/patches/98-Miscellaneous/46fb5f97-34cb-4b6b-ae10-7511db90ba1d.def new file mode 100644 index 00000000..313220b4 --- /dev/null +++ b/patches/98-Miscellaneous/46fb5f97-34cb-4b6b-ae10-7511db90ba1d.def @@ -0,0 +1,4 @@ +Revision: 1 +Author: Sebastian Lackner +Title: Avoid race-condition when unloading modules while hook is still active. + diff --git a/patches/patch-list.patch b/patches/patch-list.patch index 03c00fda..e3394885 100644 --- a/patches/patch-list.patch +++ b/patches/patch-list.patch @@ -6,7 +6,7 @@ diff --git a/libs/wine/config.c b/libs/wine/config.c index a273502..5fa0cd5 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c -@@ -478,6 +478,42 @@ const char *wine_get_version(void) +@@ -478,6 +478,43 @@ const char *wine_get_version(void) return PACKAGE_VERSION; } @@ -33,6 +33,7 @@ index a273502..5fa0cd5 100644 + { "255473fa-4e0a-4f51-952b-4deecc1a2181:1", "Michael Müller", "Indicate direct rendering through OpenGL extension." }, + { "59bd38b7-bbdc-4cfd-9ccd-1c72c4ed84c0:1", "Sebastian Lackner", "Implement X11DRV_FLUSH_GDI_DISPLAY ExtEscape command." }, + { "325645ba-d39d-4de4-9c94-3fe694eedaab:1", "Sebastian Lackner", "kernel32: Silence repeated CompareStringEx FIXME." }, ++ { "46fb5f97-34cb-4b6b-ae10-7511db90ba1d:1", "Sebastian Lackner", "Avoid race-condition when unloading modules while hook is still active." }, + { "acff3012-0f75-4710-9941-08b5ce4c61f3:2", "Erich E. Hoover", "wined3d: Silence repeated resource_check_usage FIXME." }, + { "c7263660-be78-439b-979f-e745a8d87120:1", "Sebastian Lackner", "wined3d: Silence repeated wined3d_swapchain_present FIXME." }, + { "eec5dea8-879d-417b-9f97-364deaae6576:1", "Sebastian Lackner", "Add tests for IVMRMonitorConfig." },