OSDN Git Service

invoke yamy{64,32} and yamyd32 from same directory of yamy.exe instead of current...
[yamy/yamy.git] / mayu.cpp
index 3b93438..f83f19e 100644 (file)
--- a/mayu.cpp
+++ b/mayu.cpp
@@ -64,8 +64,11 @@ class Mayu
 #endif // LOG_TO_FILE\r
 \r
        HMENU m_hMenuTaskTray;                  /// tasktray menu\r
+#ifdef _WIN64\r
+       HANDLE m_hMutexYamyd;\r
        STARTUPINFO m_si;\r
        PROCESS_INFORMATION m_pi;\r
+#endif // _WIN64\r
        HANDLE m_mutex;\r
 #ifdef USE_MAILSLOT\r
        HANDLE m_hNotifyMailslot;                       /// mailslot to receive notify\r
@@ -73,7 +76,10 @@ class Mayu
        OVERLAPPED m_olNotify;                  ///\r
        BYTE m_notifyBuf[NOTIFY_MESSAGE_SIZE];\r
 #endif // USE_MAILSLOT\r
-       bool m_isConsoleConnected;\r
+       static const DWORD SESSION_LOCKED = 1<<0;\r
+       static const DWORD SESSION_DISCONNECTED = 1<<1;\r
+       static const DWORD SESSION_END_QUERIED = 1<<2;\r
+       DWORD m_sessionState;\r
        int m_escapeNlsKeys;\r
        FixScancodeMap m_fixScancodeMap;\r
 \r
@@ -296,6 +302,12 @@ private:
                                return This->notifyHandler(cd);\r
                        }\r
                        case WM_QUERYENDSESSION:\r
+                               if (!This->m_sessionState) {\r
+                                       if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                               This->m_fixScancodeMap.escape(false);\r
+                                       }\r
+                               }\r
+                               This->m_sessionState |= Mayu::SESSION_END_QUERIED;\r
                                This->m_engine.prepairQuit();\r
                                PostQuitMessage(0);\r
                                return TRUE;\r
@@ -316,22 +328,14 @@ private:
 #  define WTS_SESSION_LOCK                   0x7\r
 #  define WTS_SESSION_UNLOCK                 0x8\r
 #endif\r
-/*\r
-       order of WTS_* messages:\r
-       <case1>screen lock -> screen unlock\r
-       <case2>change of user -> logon by same user\r
-               (1)WTS_SESSION_LOCK                     ... restore Scancode Map\r
-               (2)WTS_SESSION_UNLOCK           ... re-fix Scancode Map\r
-\r
-       <case3>change of user -> logon by another user -> change of user -> logon by previous user\r
-               (1)WTS_SESSION_LOCK                     ... restore Scancode Map\r
-               (2)WTS_CONSOLE_CONNECT          ... mark disconnection(m_isConsoleConnected=false)\r
-               (3)WTS_SESSION_UNLOCK           ... (re-fix Scancode Map is not effective here!)\r
-               (4)WTS_CONSOLE_DISCONNECT       ... re-fix Scancode Map\r
-*/\r
+                               /*\r
+                                       restore NLS keys when any bits of m_sessionState is on\r
+                                       and\r
+                                       escape NLS keys when all bits of m_sessionState cleared\r
+                               */\r
                                case WTS_CONSOLE_CONNECT:\r
-                                       if (This->m_isConsoleConnected == false) {\r
-                                               This->m_isConsoleConnected = true;\r
+                                       This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;\r
+                                       if (!This->m_sessionState) {\r
                                                if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
                                                        This->m_fixScancodeMap.escape(true);\r
                                                }\r
@@ -339,13 +343,30 @@ private:
                                        m = "WTS_CONSOLE_CONNECT";\r
                                        break;\r
                                case WTS_CONSOLE_DISCONNECT:\r
-                                       This->m_isConsoleConnected = false;\r
+                                       if (!This->m_sessionState) {\r
+                                               if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                                       This->m_fixScancodeMap.escape(false);\r
+                                               }\r
+                                       }\r
+                                       This->m_sessionState |= Mayu::SESSION_DISCONNECTED;\r
                                        m = "WTS_CONSOLE_DISCONNECT";\r
                                        break;\r
                                case WTS_REMOTE_CONNECT:\r
+                                       This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;\r
+                                       if (!This->m_sessionState) {\r
+                                               if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                                       This->m_fixScancodeMap.escape(true);\r
+                                               }\r
+                                       }\r
                                        m = "WTS_REMOTE_CONNECT";\r
                                        break;\r
                                case WTS_REMOTE_DISCONNECT:\r
+                                       if (!This->m_sessionState) {\r
+                                               if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                                       This->m_fixScancodeMap.escape(false);\r
+                                               }\r
+                                       }\r
+                                       This->m_sessionState |= Mayu::SESSION_DISCONNECTED;\r
                                        m = "WTS_REMOTE_DISCONNECT";\r
                                        break;\r
                                case WTS_SESSION_LOGON:\r
@@ -355,14 +376,18 @@ private:
                                        m = "WTS_SESSION_LOGOFF";\r
                                        break;\r
                                case WTS_SESSION_LOCK: {\r
-                                       if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
-                                               This->m_fixScancodeMap.escape(false);\r
+                                       if (!This->m_sessionState) {\r
+                                               if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                                       This->m_fixScancodeMap.escape(false);\r
+                                               }\r
                                        }\r
+                                       This->m_sessionState |= Mayu::SESSION_LOCKED;\r
                                        m = "WTS_SESSION_LOCK";\r
                                        break;\r
                           }\r
                                case WTS_SESSION_UNLOCK: {\r
-                                       if (This->m_isConsoleConnected == true) {\r
+                                       This->m_sessionState &= ~Mayu::SESSION_LOCKED;\r
+                                       if (!This->m_sessionState) {\r
                                                if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
                                                        This->m_fixScancodeMap.escape(true);\r
                                                }\r
@@ -457,7 +482,7 @@ private:
                        case WM_APP_escapeNLSKeysFailed:\r
                                if (i_lParam) {\r
                                        This->m_log << _T("escape NLS keys done code=") << i_wParam << std::endl;\r
-                                       if (i_wParam) {\r
+                                       if (i_wParam != YAMY_SUCCESS && i_wParam != YAMY_ERROR_RETRY_INJECTION_SUCCESS) {\r
                                                int ret = This->errorDialogWithCode(IDS_escapeNlsKeysFailed, i_wParam, MB_RETRYCANCEL | MB_ICONSTOP);\r
                                                if (ret == IDRETRY) {\r
                                                        This->m_fixScancodeMap.escape(true);\r
@@ -655,8 +680,10 @@ private:
                                        wtsUnRegisterSessionNotification(i_hwnd);\r
                                        This->m_usingSN = false;\r
                                }\r
-                               if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
-                                       This->m_fixScancodeMap.escape(false);\r
+                               if (!This->m_sessionState) {\r
+                                       if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {\r
+                                               This->m_fixScancodeMap.escape(false);\r
+                                       }\r
                                }\r
                                return 0;\r
 \r
@@ -674,6 +701,11 @@ private:
                                        switch (static_cast<MayuIPCCommand>(i_wParam)) {\r
                                        case MayuIPCCommand_Enable:\r
                                                This->m_engine.enable(!!i_lParam);\r
+                                               if (This->m_engine.getIsEnabled()) {\r
+                                                       This->m_fixScancodeMap.escape(true);\r
+                                               } else {\r
+                                                       This->m_fixScancodeMap.escape(false);\r
+                                               }\r
                                                This->showTasktrayIcon();\r
                                                if (i_lParam) {\r
                                                        Acquire a(&This->m_log, 1);\r
@@ -973,7 +1005,7 @@ public:
                        m_log(WM_APP_msgStreamNotify),\r
                        m_setting(NULL),\r
                        m_isSettingDialogOpened(false),\r
-                       m_isConsoleConnected(true),\r
+                       m_sessionState(0),\r
                        m_engine(m_log) {\r
                Registry reg(MAYU_REGISTRY_ROOT);\r
                reg.read(_T("escapeNLSKeys"), &m_escapeNlsKeys, 0);\r
@@ -1094,19 +1126,33 @@ public:
                // set initial lock state\r
                notifyLockState();\r
 \r
-               BOOL result;\r
-\r
+#ifdef _WIN64\r
                ZeroMemory(&m_pi,sizeof(m_pi));\r
                ZeroMemory(&m_si,sizeof(m_si));\r
                m_si.cb=sizeof(m_si);\r
-#ifdef _WIN64\r
-               result = CreateProcess(_T("yamyd32"), _T("yamyd32"), NULL, NULL, FALSE,\r
+\r
+               // create mutex to block yamyd\r
+               m_hMutexYamyd = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE, MUTEX_YAMYD_BLOCKER);\r
+\r
+               tstring yamydPath;\r
+               _TCHAR exePath[GANA_MAX_PATH];\r
+               _TCHAR exeDrive[GANA_MAX_PATH];\r
+               _TCHAR exeDir[GANA_MAX_PATH];\r
+\r
+               GetModuleFileName(NULL, exePath, GANA_MAX_PATH);\r
+               _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);\r
+               yamydPath = exeDrive;\r
+               yamydPath += exeDir;\r
+               yamydPath += _T("yamyd32");\r
+\r
+               BOOL result = CreateProcess(yamydPath.c_str(), NULL, NULL, NULL, FALSE,\r
                                                           NORMAL_PRIORITY_CLASS, 0, NULL, &m_si, &m_pi);\r
                if (result == FALSE) {\r
                        TCHAR buf[1024];\r
                        TCHAR text[1024];\r
                        TCHAR title[1024];\r
 \r
+                       m_pi.hProcess = NULL;\r
                        LoadString(GetModuleHandle(NULL), IDS_cannotInvoke,\r
                                           text, sizeof(text)/sizeof(text[0]));\r
                        LoadString(GetModuleHandle(NULL), IDS_mayu,\r
@@ -1116,7 +1162,6 @@ public:
                        MessageBox((HWND)NULL, buf, title, MB_OK | MB_ICONSTOP);\r
                } else {\r
                        CloseHandle(m_pi.hThread);\r
-                       CloseHandle(m_pi.hProcess);\r
                }\r
 #endif // _WIN64\r
        }\r
@@ -1140,7 +1185,19 @@ public:
                // stop notify from mayu.dll\r
                g_hookData->m_hwndTaskTray = NULL;\r
                CHECK_FALSE( uninstallMessageHook() );\r
-               PostMessage(HWND_BROADCAST, WM_NULL, 0, 0);\r
+\r
+#ifdef _WIN64\r
+               ReleaseMutex(m_hMutexYamyd);\r
+               if (m_pi.hProcess) {\r
+                       WaitForSingleObject(m_pi.hProcess, 5000);\r
+                       CloseHandle(m_pi.hProcess);\r
+               }\r
+               CloseHandle(m_hMutexYamyd);\r
+#endif // _WIN64\r
+               if (!(m_sessionState & SESSION_END_QUERIED)) {\r
+                       DWORD_PTR result;\r
+                       SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 3000, &result);\r
+               }\r
 \r
                // destroy windows\r
                CHECK_TRUE( DestroyWindow(m_hwndVersion) );\r