From 2287c9ec18ff9a7361111f6a1590ea0db8d46f72 Mon Sep 17 00:00:00 2001 From: "U-i7\\gimy" Date: Wed, 15 Jul 2009 22:37:49 +0900 Subject: [PATCH] separate WH_KEYBOARD_LL and WH_MOUSE_LL handlers as thread, expect to fix ticket #17576 and #17767 --- engine.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ engine.h | 28 +++++++++++++++++++++++++ hook.cpp | 70 +++++++++++++++++++++++++++++++++++++++++--------------------- hook.h | 6 ++++-- mayu.cpp | 4 ++-- yamyd.cpp | 4 ++-- 6 files changed, 138 insertions(+), 30 deletions(-) diff --git a/engine.cpp b/engine.cpp index 4c74873..8f12c16 100644 --- a/engine.cpp +++ b/engine.cpp @@ -975,6 +975,8 @@ Engine::Engine(tomsgstream &i_log) m_didMayuStartDevice(false), m_threadEvent(NULL), m_mayudVersion(_T("unknown")), + m_keyboardHandler(installKeyboardHook), + m_mouseHandler(installMouseHook), m_readEvent(NULL), m_interruptThreadEvent(NULL), m_sts4mayu(NULL), @@ -1082,6 +1084,8 @@ void Engine::close() { // start keyboard handler thread void Engine::start() { + m_keyboardHandler.start(this); + m_mouseHandler.start(this); CHECK_TRUE( m_threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ); CHECK_TRUE( m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ); @@ -1133,6 +1137,8 @@ void Engine::stop() { CHECK_TRUE( CloseHandle(m_interruptThreadEvent) ); m_interruptThreadEvent = NULL; } + m_mouseHandler.stop(); + m_keyboardHandler.stop(); } bool Engine::pause() { @@ -1557,3 +1563,53 @@ void Engine::commandNotify( << _T("wID = ") << LOWORD(i_wParam) << _T(", ") << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl; } + +unsigned int WINAPI Engine::InputHandler::run(void *i_this) +{ + reinterpret_cast(i_this)->run(); + _endthreadex(0); + return 0; +} + +Engine::InputHandler::InputHandler(INSTALL_HOOK i_installHook) : m_installHook(i_installHook) +{ + CHECK_TRUE(m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL)); + CHECK_TRUE(m_hThread = (HANDLE)_beginthreadex(NULL, 0, run, this, CREATE_SUSPENDED, &m_threadId)); +} + +Engine::InputHandler::~InputHandler() +{ + CloseHandle(m_hEvent); +} + +void Engine::InputHandler::run() +{ + MSG msg; + + CHECK_FALSE(m_installHook(Engine::keyboardDetour, m_engine, true)); + PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + SetEvent(m_hEvent); + + while (GetMessage(&msg, NULL, 0, 0)) { + // nothing to do... + } + + CHECK_FALSE(m_installHook(Engine::keyboardDetour, m_engine, false)); + + return; +} + +int Engine::InputHandler::start(Engine *i_engine) +{ + m_engine = i_engine; + ResumeThread(m_hThread); + WaitForSingleObject(m_hEvent, INFINITE); + return 0; +} + +int Engine::InputHandler::stop() +{ + PostThreadMessage(m_threadId, WM_QUIT, 0, 0); + WaitForSingleObject(m_hThread, INFINITE); + return 0; +} diff --git a/engine.h b/engine.h index 636bd61..69a5b2a 100644 --- a/engine.h +++ b/engine.h @@ -8,6 +8,7 @@ # include "multithread.h" # include "setting.h" # include "msgstream.h" +# include "hook.h" # include # include @@ -143,6 +144,31 @@ private: InterruptThreadReason_Resume, }; + /// + class InputHandler { + public: + typedef int (*INSTALL_HOOK)(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install); + + static unsigned int WINAPI run(void *i_this); + + InputHandler(INSTALL_HOOK i_installHook); + + ~InputHandler(); + + void run(); + + int start(Engine *i_engine); + + int stop(); + + private: + unsigned m_threadId; + HANDLE m_hThread; + HANDLE m_hEvent; + INSTALL_HOOK m_installHook; + Engine *m_engine; + }; + private: CriticalSection m_cs; /// criticalSection @@ -163,6 +189,8 @@ private: #ifdef NO_DRIVER std::deque m_kidq; CriticalSection m_cskidq; + InputHandler m_keyboardHandler; + InputHandler m_mouseHandler; #endif // NO_DRIVER HANDLE m_readEvent; /** reading from mayu device has been completed */ diff --git a/hook.cpp b/hook.cpp index c1b3197..6bbd655 100644 --- a/hook.cpp +++ b/hook.cpp @@ -826,8 +826,8 @@ through: #endif // NO_DRIVER -/// install hooks -DllExport int installHooks(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine) +/// install message hook +DllExport int installMessageHook() { if (!g.m_isInitialized) initialize(); @@ -838,25 +838,12 @@ DllExport int installHooks(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine) g.m_hInstDLL, 0); s_hookDataArch->m_hHookCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)callWndProc, g.m_hInstDLL, 0); - g_hookData->m_mouseHookType = MouseHookType_None; - if (i_engine != NULL) { -#ifdef NO_DRIVER - g.m_keyboardDetour = i_keyboardDetour; - g.m_engine = i_engine; - g.m_hHookKeyboardProc = - SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, - g.m_hInstDLL, 0); -#endif // NO_DRIVER - g.m_hHookMouseProc = - SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)lowLevelMouseProc, - g.m_hInstDLL, 0); - } return 0; } -/// uninstall hooks -DllExport int uninstallHooks() +/// uninstall message hook +DllExport int uninstallMessageHook() { if (s_hookDataArch->m_hHookGetMessage) UnhookWindowsHookEx(s_hookDataArch->m_hHookGetMessage); @@ -864,14 +851,49 @@ DllExport int uninstallHooks() if (s_hookDataArch->m_hHookCallWndProc) UnhookWindowsHookEx(s_hookDataArch->m_hHookCallWndProc); s_hookDataArch->m_hHookCallWndProc = NULL; - if (g.m_hHookMouseProc) - UnhookWindowsHookEx(g.m_hHookMouseProc); - g.m_hHookMouseProc = NULL; + g.m_hwndTaskTray = 0; + return 0; +} + + +/// install keyboard hook +DllExport int installKeyboardHook(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install) +{ #ifdef NO_DRIVER - if (g.m_hHookKeyboardProc) - UnhookWindowsHookEx(g.m_hHookKeyboardProc); - g.m_hHookKeyboardProc = NULL; + if (i_install) { + if (!g.m_isInitialized) + initialize(); + + g.m_keyboardDetour = i_keyboardDetour; + g.m_engine = i_engine; + g.m_hHookKeyboardProc = + SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, + g.m_hInstDLL, 0); + } else { + if (g.m_hHookKeyboardProc) + UnhookWindowsHookEx(g.m_hHookKeyboardProc); + g.m_hHookKeyboardProc = NULL; + } #endif // NO_DRIVER - g.m_hwndTaskTray = 0; + return 0; +} + + +/// install mouse hook +DllExport int installMouseHook(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install) +{ + if (i_install) { + if (!g.m_isInitialized) + initialize(); + + g_hookData->m_mouseHookType = MouseHookType_None; + g.m_hHookMouseProc = + SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)lowLevelMouseProc, + g.m_hInstDLL, 0); + } else { + if (g.m_hHookMouseProc) + UnhookWindowsHookEx(g.m_hHookMouseProc); + g.m_hHookMouseProc = NULL; + } return 0; } diff --git a/hook.h b/hook.h index 28d7e6e..d7f236b 100644 --- a/hook.h +++ b/hook.h @@ -144,8 +144,10 @@ public: # ifndef _HOOK_CPP extern DllImport HookData *g_hookData; -extern DllImport int installHooks(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine); -extern DllImport int uninstallHooks(); +extern DllImport int installMessageHook(); +extern DllImport int uninstallMessageHook(); +extern DllImport int installKeyboardHook(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install); +extern DllImport int installMouseHook(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install); extern DllImport bool notify(void *data, size_t sizeof_data); extern DllImport void notifyLockState(); # endif // !_HOOK_CPP diff --git a/mayu.cpp b/mayu.cpp index 42a35ea..2ef63cb 100644 --- a/mayu.cpp +++ b/mayu.cpp @@ -789,7 +789,7 @@ public: #ifndef USE_MAILSLOT g_hookData->m_hwndTaskTray = reinterpret_cast(m_hwndTaskTray); #endif // !USE_MAILSLOT - CHECK_FALSE( installHooks(Engine::keyboardDetour, &m_engine) ); + CHECK_FALSE( installMessageHook() ); m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray, NOTIFY_FOR_THIS_SESSION); @@ -900,7 +900,7 @@ public: // stop notify from mayu.dll g_hookData->m_hwndTaskTray = NULL; - CHECK_FALSE( uninstallHooks() ); + CHECK_FALSE( uninstallMessageHook() ); PostMessage(HWND_BROADCAST, WM_NULL, 0, 0); // destroy windows diff --git a/yamyd.cpp b/yamyd.cpp index 395d006..b70dab0 100644 --- a/yamyd.cpp +++ b/yamyd.cpp @@ -10,13 +10,13 @@ int WINAPI _tWinMain(HINSTANCE /* i_hInstance */, HINSTANCE /* i_hPrevInstance * { HANDLE mutex = OpenMutex(SYNCHRONIZE, FALSE, MUTEX_MAYU_EXCLUSIVE_RUNNING); if (mutex != NULL) { - CHECK_FALSE( installHooks(NULL, NULL) ); + CHECK_FALSE( installMessageHook() ); // wait for master process exit WaitForSingleObject(mutex, INFINITE); ReleaseMutex(mutex); - CHECK_FALSE( uninstallHooks() ); + CHECK_FALSE( uninstallMessageHook() ); SendMessage(HWND_BROADCAST, WM_NULL, 0, 0); } -- 2.11.0