From 4659f98314ca7b97f17bcafe0eae965b94eaeb5b Mon Sep 17 00:00:00 2001 From: Vitaliy Margolen Date: Mon, 14 May 2007 19:56:48 -0600 Subject: [PATCH] dinput: Prevent race between destroying the hook window and unloading the dll. --- dlls/dinput/dinput_main.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 789e6e7cb58..402855e5217 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -753,6 +753,7 @@ static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wPar static HWND hook_thread_hwnd; static LONG hook_thread_refcount; +static HANDLE hook_thread; static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0}; @@ -776,6 +777,7 @@ static DWORD WINAPI hook_thread_proc(void *param) } else ERR("Error creating message window\n"); + UnregisterClassW(classW, DINPUT_instance); return 0; } @@ -791,39 +793,36 @@ static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0 static BOOL create_hook_thread(void) { LONG ref; - static ATOM class_atom; EnterCriticalSection(&dinput_hook_crit); - if (!class_atom) + ref = ++hook_thread_refcount; + TRACE("Refcount %d\n", ref); + if (ref == 1) { + DWORD tid; + HANDLE event; + + /* Create window class */ WNDCLASSEXW wcex; memset(&wcex, 0, sizeof(wcex)); wcex.cbSize = sizeof(wcex); wcex.lpfnWndProc = dinput_hook_WndProc; wcex.lpszClassName = classW; - wcex.hInstance = GetModuleHandleW(0); - if (!(class_atom = RegisterClassExW(&wcex))) ERR("Error registering window class\n"); - } - - ref = ++hook_thread_refcount; - TRACE("Refcount %d\n", ref); - if (ref == 1) - { - DWORD tid; - HANDLE thread, event; + wcex.hInstance = DINPUT_instance; + if (!RegisterClassExW(&wcex)) + ERR("Error registering window class\n"); event = CreateEventW(NULL, FALSE, FALSE, NULL); - thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid); - if (event && thread) + hook_thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid); + if (event && hook_thread) { HANDLE handles[2]; handles[0] = event; - handles[1] = thread; + handles[1] = hook_thread; WaitForMultipleObjects(2, handles, FALSE, INFINITE); } CloseHandle(event); - CloseHandle(thread); } LeaveCriticalSection(&dinput_hook_crit); @@ -842,6 +841,9 @@ static void release_hook_thread(void) HWND hwnd = hook_thread_hwnd; hook_thread_hwnd = 0; SendMessageW(hwnd, WM_USER+0x10, 0, 0); + /* wait for hook thread to exit */ + WaitForSingleObject(hook_thread, INFINITE); + CloseHandle(hook_thread); } LeaveCriticalSection(&dinput_hook_crit); } -- 2.11.4.GIT