dinput: Prevent race between destroying the hook window and unloading the dll.
This commit is contained in:
parent
1af94dbf3b
commit
4659f98314
@ -753,6 +753,7 @@ static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wPar
|
|||||||
|
|
||||||
static HWND hook_thread_hwnd;
|
static HWND hook_thread_hwnd;
|
||||||
static LONG hook_thread_refcount;
|
static LONG hook_thread_refcount;
|
||||||
|
static HANDLE hook_thread;
|
||||||
|
|
||||||
static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0};
|
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");
|
else ERR("Error creating message window\n");
|
||||||
|
|
||||||
|
UnregisterClassW(classW, DINPUT_instance);
|
||||||
return 0;
|
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)
|
static BOOL create_hook_thread(void)
|
||||||
{
|
{
|
||||||
LONG ref;
|
LONG ref;
|
||||||
static ATOM class_atom;
|
|
||||||
|
|
||||||
EnterCriticalSection(&dinput_hook_crit);
|
EnterCriticalSection(&dinput_hook_crit);
|
||||||
|
|
||||||
if (!class_atom)
|
|
||||||
{
|
|
||||||
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;
|
ref = ++hook_thread_refcount;
|
||||||
TRACE("Refcount %d\n", ref);
|
TRACE("Refcount %d\n", ref);
|
||||||
if (ref == 1)
|
if (ref == 1)
|
||||||
{
|
{
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
HANDLE thread, event;
|
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 = DINPUT_instance;
|
||||||
|
if (!RegisterClassExW(&wcex))
|
||||||
|
ERR("Error registering window class\n");
|
||||||
|
|
||||||
event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid);
|
hook_thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid);
|
||||||
if (event && thread)
|
if (event && hook_thread)
|
||||||
{
|
{
|
||||||
HANDLE handles[2];
|
HANDLE handles[2];
|
||||||
handles[0] = event;
|
handles[0] = event;
|
||||||
handles[1] = thread;
|
handles[1] = hook_thread;
|
||||||
WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||||
}
|
}
|
||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
CloseHandle(thread);
|
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&dinput_hook_crit);
|
LeaveCriticalSection(&dinput_hook_crit);
|
||||||
|
|
||||||
@ -842,6 +841,9 @@ static void release_hook_thread(void)
|
|||||||
HWND hwnd = hook_thread_hwnd;
|
HWND hwnd = hook_thread_hwnd;
|
||||||
hook_thread_hwnd = 0;
|
hook_thread_hwnd = 0;
|
||||||
SendMessageW(hwnd, WM_USER+0x10, 0, 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);
|
LeaveCriticalSection(&dinput_hook_crit);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user