OSDN Git Service

Share the hook state among 32bit and 64bit processes.
authorKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Fri, 27 Jan 2012 14:53:57 +0000 (23:53 +0900)
committerKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Mon, 20 Feb 2012 04:25:23 +0000 (13:25 +0900)
Rewrite the IPC stuff.

xkeymacs/mainfrm.cpp
xkeymacs/mainfrm.h
xkeymacs/profile.cpp
xkeymacs/xkeymacs.cpp
xkeymacs/xkeymacs.h
xkeymacs/xkeymacs64.cpp
xkeymacsdll/ipc.h
xkeymacsdll/xkeymacsdll.cpp
xkeymacsdll/xkeymacsdll.h

index c4b8c39..35db6a4 100644 (file)
@@ -22,7 +22,6 @@ HICON CMainFrame::m_hIcon[MAX_ICON_TYPE][MAX_STATUS];
 DWORD CMainFrame::m_dwOldMessage[MAX_ICON_TYPE];\r
 NOTIFYICONDATA CMainFrame::m_stNtfyIcon[MAX_ICON_TYPE];\r
 NOTIFYICONDATA CMainFrame::m_stOldNtfyIcon[MAX_ICON_TYPE];\r
-bool CMainFrame::m_bPollIconMessage;\r
 \r
 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)\r
 \r
@@ -157,47 +156,62 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
 \r
 void CMainFrame::StartPollThread()\r
 {\r
-       m_bPollIconMessage = TRUE;\r
-       m_hThread = CreateThread(NULL, 0, PollIconMessage, this, 0, NULL);\r
+       m_hThread = CreateThread(NULL, 0, PollMessage, this, 0, NULL);\r
 }\r
 \r
 void CMainFrame::TerminatePollThread()\r
 {\r
-       m_bPollIconMessage = FALSE;\r
-       IconMsg nul = {MAIN_ICON,};\r
-       if (CXkeymacsDll::SendIconMessage(&nul, 1))\r
-               WaitForSingleObject(m_hThread, 5000);\r
+       DWORD ack, read;\r
+       IPC32Message msg;\r
+       msg.Type = IPC32_TERMINATE;\r
+       CallNamedPipe(XKEYMACS32_PIPE, &msg, sizeof(msg.Type), &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);\r
        CloseHandle(m_hThread);\r
 }\r
 \r
-DWORD WINAPI CMainFrame::PollIconMessage(LPVOID)\r
+bool SendAck(HANDLE pipe)\r
 {\r
-       HANDLE hPipe = CreateNamedPipe(ICON_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,\r
-                                                                       sizeof(DWORD), sizeof(IconMsg) * MAX_ICON_TYPE, 0, NULL);\r
-       if (hPipe == INVALID_HANDLE_VALUE)\r
+       DWORD written, ack = 0;\r
+       return WriteFile(pipe, &ack, sizeof(DWORD), &written, NULL) && written == sizeof(DWORD) &&\r
+                       FlushFileBuffers(pipe) && DisconnectNamedPipe(pipe);\r
+}\r
+\r
+DWORD WINAPI CMainFrame::PollMessage(LPVOID)\r
+{\r
+       HANDLE pipe = CreateNamedPipe(XKEYMACS32_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,\r
+                                                                       sizeof(DWORD), sizeof(IPC32Message), 0, NULL);\r
+       if (pipe == INVALID_HANDLE_VALUE)\r
                return 1;\r
        for (; ;) {\r
-               if (ConnectNamedPipe(hPipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))\r
+               if (ConnectNamedPipe(pipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))\r
                        break;\r
-               IconMsg msg[MAX_ICON_TYPE];\r
+               IPC32Message msg;\r
                DWORD read;\r
-               if (!ReadFile(hPipe, msg, sizeof(msg), &read, NULL))\r
+               if (!ReadFile(pipe, &msg, sizeof(msg), &read, NULL))\r
                        break;\r
-               DWORD written, ack = 0;\r
-               // return ack ASAP to release hooks from blocking state.\r
-               if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD) ||\r
-                               !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))\r
-                       break;\r
-               if (!m_bPollIconMessage)\r
-                       break;\r
-               for (DWORD i = 0; i < read / sizeof(IconMsg); ++i) {\r
-                       m_stNtfyIcon[msg[i].nType].hIcon = m_hIcon[msg[i].nType][msg[i].nState];\r
-                       if (msg[i].nType == MX_ICON && msg[i].szTip[0] != 0)\r
-                               memcpy(m_stNtfyIcon[MX_ICON].szTip, msg[i].szTip, 128);\r
-                       DoShell_NotifyIcon(msg[i].nType, NIM_MODIFY);\r
+               switch (msg.Type) {\r
+               case IPC32_TERMINATE:\r
+                       SendAck(pipe);\r
+                       goto exit;\r
+               case IPC32_HOOKSTATE:\r
+                       CXkeymacsDll::SetHookStateDirect(msg.Enable);\r
+                       static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(msg.Enable ? IPC64_ENABLE : IPC64_DISABLE);\r
+                       if (!SendAck(pipe))\r
+                               goto exit;\r
+                       continue;\r
+               case IPC32_ICON:\r
+                       // return ack ASAP to release hooks from blocking state.\r
+                       if (!SendAck(pipe))\r
+                               goto exit;\r
+                       for (DWORD i = 0; i < (read - offsetof(IPC32Message, IconState)) / sizeof(IconState); ++i) {\r
+                               m_stNtfyIcon[msg.IconState[i].Type].hIcon = m_hIcon[msg.IconState[i].Type][msg.IconState[i].State];\r
+                               if (msg.IconState[i].Type == MX_ICON && msg.IconState[i].Tip[0] != 0)\r
+                                       memcpy(m_stNtfyIcon[MX_ICON].szTip, msg.IconState[i].Tip, 128);\r
+                               DoShell_NotifyIcon(msg.IconState[i].Type, NIM_MODIFY);\r
+                       }\r
                }\r
        }\r
-       CloseHandle(hPipe);\r
+exit:\r
+       CloseHandle(pipe);\r
        return 0;\r
 }\r
 \r
@@ -471,7 +485,7 @@ void CMainFrame::OnQuit()
 \r
        CXkeymacsDll::ReleaseHooks();\r
        TerminatePollThread();\r
-       static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPCMessage(XKEYMACS_EXIT);\r
+       static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(IPC64_EXIT);\r
        DeleteAllShell_NotifyIcon();\r
 \r
        PostQuitMessage(0);\r
@@ -522,9 +536,7 @@ void CMainFrame::OnReset()
        TerminatePollThread();\r
        CXkeymacsDll::ResetHooks();\r
        StartPollThread();\r
-       CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
-       if (!pApp->SendIPCMessage(XKEYMACS_RESET))\r
-               pApp->Start64bitProcess(); // try to restart 64bit app\r
+       static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPC64Message(IPC64_RESET);\r
 }\r
 \r
 void CMainFrame::OnHelpFinder() \r
index c8fc1d1..99ad635 100644 (file)
@@ -101,11 +101,10 @@ private:
        static void DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage);\r
        static void DeleteAllShell_NotifyIcon();\r
        static void AddAllShell_NotifyIcon();\r
-       static bool m_bPollIconMessage;\r
        HANDLE m_hThread;\r
        void StartPollThread();\r
        void TerminatePollThread();\r
-       static DWORD WINAPI PollIconMessage(LPVOID lpParam);\r
+       static DWORD WINAPI PollMessage(LPVOID lpParam);\r
 public:\r
        void EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable);\r
 };\r
index f56ca32..4b8221a 100644 (file)
@@ -281,7 +281,7 @@ void CProfile::SetDllData()
                return;\r
        if (!CXkeymacsDll::SaveConfig())\r
                return;\r
-       pApp->SendIPCMessage(XKEYMACS_RELOAD);\r
+       pApp->SendIPC64Message(IPC64_RELOAD);\r
 }\r
 \r
 void CProfile::SaveKeyBind(LPCTSTR appName, int comID, int type, int key)\r
index 3ca0fd7..578a39f 100644 (file)
@@ -114,15 +114,14 @@ BOOL CXkeymacsApp::Start64bitProcess()
        return TRUE;\r
 }\r
 \r
-BOOL CXkeymacsApp::SendIPCMessage(DWORD msg)\r
+void CXkeymacsApp::SendIPC64Message(DWORD msg)\r
 {\r
        if (!m_bIsWow64)\r
-               return TRUE;\r
+               return;\r
        DWORD ack, read;\r
        for (int i = 0; i < 10; Sleep(100), ++i)\r
-               if (CallNamedPipe(IPC_PIPE, &msg, sizeof(msg), &ack, sizeof(DWORD), &read, NMPWAIT_WAIT_FOREVER))\r
-                       return TRUE;\r
-       return FALSE;\r
+               if (CallNamedPipe(XKEYMACS64_PIPE, &msg, sizeof(msg), &ack, sizeof(DWORD), &read, NMPWAIT_WAIT_FOREVER))\r
+                       return;;\r
 }\r
 \r
 int CXkeymacsApp::ExitInstance() \r
index 0a98aed..1c702f3 100644 (file)
@@ -38,7 +38,7 @@ public:
                //    DO NOT EDIT what you see in these blocks of generated code !\r
        //}}AFX_MSG\r
        BOOL IsWow64();\r
-       BOOL SendIPCMessage(DWORD msg);\r
+       void SendIPC64Message(DWORD msg);\r
        BOOL Start64bitProcess();\r
        DECLARE_MESSAGE_MAP()\r
 private:\r
index a8558f7..b5ff41a 100644 (file)
@@ -39,7 +39,7 @@ BOOL CXkeymacsApp::InitInstance()
 \r
 UINT PollIPCMessage(LPVOID param)\r
 {\r
-       HANDLE hPipe = CreateNamedPipe(IPC_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 512, 512, 0, NULL);\r
+       HANDLE hPipe = CreateNamedPipe(XKEYMACS64_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 512, 512, 0, NULL);\r
        if (hPipe == INVALID_HANDLE_VALUE)\r
                return 1;\r
        for (; ;) {\r
@@ -49,22 +49,28 @@ UINT PollIPCMessage(LPVOID param)
                DWORD read;\r
                if (!ReadFile(hPipe, &msg, sizeof(msg), &read, NULL) || read != sizeof(msg)) \r
                        break;\r
-               DWORD written, nul = 0;\r
-               if (!WriteFile(hPipe, &nul, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD)\r
-                               || !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))\r
-                       break;\r
                switch (msg)\r
                {\r
-               case XKEYMACS_EXIT:\r
+               case IPC64_EXIT:\r
                        goto exit;\r
                        break;\r
-               case XKEYMACS_RELOAD:\r
+               case IPC64_RELOAD:\r
                        CXkeymacsDll::LoadConfig();\r
                        break;\r
-               case XKEYMACS_RESET:\r
+               case IPC64_RESET:\r
                        CXkeymacsDll::ResetHooks();\r
                        break;\r
+               case IPC64_DISABLE:\r
+                       CXkeymacsDll::SetHookStateDirect(false);\r
+                       break;\r
+               case IPC64_ENABLE:\r
+                       CXkeymacsDll::SetHookStateDirect(true);\r
+                       break;\r
                }\r
+               DWORD written, ack = 0;\r
+               if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD)\r
+                               || !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))\r
+                       break;\r
        }\r
 exit:\r
        CloseHandle(hPipe);\r
index 206eba4..0c6fff2 100644 (file)
@@ -7,12 +7,6 @@
 \r
 #include "defs.h"\r
 \r
-struct IconMsg {\r
-       ICON_TYPE nType;\r
-       int nState;\r
-       TCHAR szTip[128];\r
-};\r
-\r
 struct AppConfig {\r
        TCHAR AppName[CLASS_NAME_LENGTH];\r
        TCHAR WindowText[WINDOW_TEXT_LENGTH];\r
@@ -33,8 +27,23 @@ struct Config {
        bool Is106Keyboard;\r
 };\r
 \r
-enum XKEYMACS_IPC { XKEYMACS_EXIT, XKEYMACS_RELOAD, XKEYMACS_RESET };\r
+enum XKEYMACS_IPC32 { IPC32_TERMINATE, IPC32_ICON, IPC32_HOOKSTATE };\r
+enum XKEYMACS_IPC64 { IPC64_EXIT, IPC64_RELOAD, IPC64_RESET, IPC64_DISABLE, IPC64_ENABLE };\r
+\r
+struct IconState {\r
+       ICON_TYPE Type;\r
+       int State;\r
+       TCHAR Tip[128];\r
+};\r
+\r
+struct IPC32Message {\r
+       XKEYMACS_IPC32 Type;\r
+       union {\r
+               bool Enable;\r
+               IconState IconState[MAX_ICON_TYPE];\r
+       };\r
+};\r
 \r
-#define ICON_PIPE _T("\\\\.\\pipe\\XKEYMACS_ICON")\r
-#define IPC_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC")\r
+#define XKEYMACS32_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC32")\r
+#define XKEYMACS64_PIPE _T("\\\\.\\pipe\\XKEYMACS_IPC64")\r
 #endif\r
index e1e969c..72a8a67 100644 (file)
@@ -206,6 +206,11 @@ void CXkeymacsDll::ReleaseKeyboardHook()
                unhook(*phHook);\r
 }\r
 \r
+void CXkeymacsDll::SetHookStateDirect(bool enable)\r
+{\r
+       m_bHook = enable;\r
+}\r
+\r
 void CXkeymacsDll::ToggleHookState()\r
 {\r
        SetHookState(!m_bHook);\r
@@ -213,7 +218,12 @@ void CXkeymacsDll::ToggleHookState()
 \r
 void CXkeymacsDll::SetHookState(bool enable)\r
 {\r
-       m_bHook = enable;\r
+       DWORD ack, read;\r
+       IPC32Message msg;\r
+       msg.Type = IPC32_HOOKSTATE;\r
+       msg.Enable = enable;\r
+       CallNamedPipe(XKEYMACS32_PIPE, &msg, offsetof(IPC32Message, Enable) + sizeof(bool), &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);\r
+\r
        ShowHookState();\r
 }\r
 \r
@@ -224,25 +234,23 @@ bool CXkeymacsDll::GetHookState()
 \r
 void CXkeymacsDll::ShowHookState()\r
 {\r
-       IconMsg msg = {MAIN_ICON,};\r
+       IconState main = { MAIN_ICON, STATUS_ENABLE };\r
        if (m_bHook) {\r
                if (CCommands::IsTemporarilyDisableXKeymacs()) {\r
-                       msg.nState = STATUS_DISABLE_TMP;\r
+                       main.State = STATUS_DISABLE_TMP;\r
                        m_hCurrentCursor = m_hCursor[STATUS_DISABLE_TMP];\r
                } else {\r
-                       msg.nState = STATUS_ENABLE;\r
+                       main.State = STATUS_ENABLE;\r
                        m_hCurrentCursor = m_hCursor[STATUS_ENABLE];\r
                }\r
-       } else {\r
-               msg.nState = STATUS_DISABLE_WOCQ;\r
-       }\r
-       if (m_CurrentConfig->SettingStyle == SETTING_DISABLE\r
-        || (!_tcsicmp(m_CurrentConfig->AppName, _T("Default"))\r
-         && CUtils::IsDefaultIgnoreApplication())) {\r
-               msg.nState = STATUS_DISABLE;\r
+       } else\r
+               main.State = STATUS_DISABLE_WOCQ;\r
+       if (m_CurrentConfig->SettingStyle == SETTING_DISABLE ||\r
+                       (!_tcsicmp(m_CurrentConfig->AppName, _T("Default")) && CUtils::IsDefaultIgnoreApplication())) {\r
+               main.State = STATUS_DISABLE;\r
                m_hCurrentCursor = m_hCursor[STATUS_DISABLE];\r
        }\r
-       SendIconMessage(&msg, 1);\r
+       SendIconMessage(&main, 1);\r
        DoSetCursor();\r
 }\r
 \r
@@ -364,7 +372,7 @@ void CXkeymacsDll::InitKeyboardProc()
        m_CmdID = m_CurrentConfig->CmdID;\r
        m_FuncID = m_CurrentConfig->FuncID;\r
 \r
-       IconMsg msg[3] = {\r
+       IconState msg[3] = {\r
                {CX_ICON, OFF_ICON, ""},\r
                {MX_ICON, OFF_ICON, ""},\r
                {META_ICON, OFF_ICON, ""}\r
@@ -743,7 +751,7 @@ void CXkeymacsDll::InvokeM_x(LPCTSTR szPath)
 \r
 void CXkeymacsDll::SetModifierIcons()\r
 {\r
-       IconMsg msg[6] = {\r
+       IconState icons[6] = {\r
                {MX_ICON, CCommands::bM_x(), ""},\r
                {CX_ICON, CCommands::bC_x(), ""},\r
                {META_ICON, CCommands::bM_(), ""},\r
@@ -751,8 +759,8 @@ void CXkeymacsDll::SetModifierIcons()
                {CTRL_ICON, IsControl(), ""},\r
                {ALT_ICON, IsDown(VK_MENU, FALSE), ""}\r
        };\r
-       _tcscpy_s(msg[0].szTip, m_M_xTip);\r
-       SendIconMessage(msg, 6);\r
+       _tcscpy_s(icons[0].Tip, m_M_xTip);\r
+       SendIconMessage(icons, 6);\r
 }\r
 \r
 void CXkeymacsDll::SetM_xTip(LPCTSTR szPath)\r
@@ -762,10 +770,13 @@ void CXkeymacsDll::SetM_xTip(LPCTSTR szPath)
                _stprintf_s(m_M_xTip, "M-x %s", szPath);\r
 }\r
 \r
-BOOL CXkeymacsDll::SendIconMessage(IconMsg *pMsg, DWORD num)\r
+void CXkeymacsDll::SendIconMessage(IconState *state, int num)\r
 {\r
        DWORD ack, read;\r
-       return CallNamedPipe(ICON_PIPE, pMsg, sizeof(IconMsg) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT) && read == sizeof(DWORD);\r
+       IPC32Message msg;\r
+       msg.Type = IPC32_ICON;\r
+       memcpy(msg.IconState, state, num * sizeof(IconState));\r
+       CallNamedPipe(XKEYMACS32_PIPE, &msg, offsetof(IPC32Message, IconState) + sizeof(IconState) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);\r
 }\r
 \r
 void CXkeymacsDll::Kdu(BYTE bVk, DWORD n, BOOL bOriginal)\r
index 4e50603..9317e09 100644 (file)
@@ -28,11 +28,12 @@ public:
        static void ResetHooks();\r
        static void ReleaseHooks();\r
        static void ReleaseKeyboardHook();\r
+       static void SetHookStateDirect(bool enable);\r
        static void ToggleHookState();\r
        static bool GetHookState();\r
        static void ShowHookState();\r
        static void SetM_xTip(LPCTSTR szPath);\r
-       static BOOL SendIconMessage(IconMsg *pMsg, DWORD num);\r
+       static void SendIconMessage(IconState *state, int num);\r
        static BOOL IsDown(BYTE bVk, BOOL bPhysicalKey = TRUE);\r
        static void Kdu(BYTE bVk, DWORD n = 1, BOOL bOriginal = TRUE);\r
        static void DepressKey(BYTE bVk, BOOL bOriginal = TRUE);\r