OSDN Git Service

forgot to "git add" modified files, so re-commit:
authorU-i7\gimy <gimy@users.sourceforge.jp>
Sat, 13 Jun 2009 13:15:17 +0000 (22:15 +0900)
committerU-i7\gimy <gimy@users.sourceforge.jp>
Sat, 13 Jun 2009 13:15:17 +0000 (22:15 +0900)
many changes as follow:

* key input substitution in user mode instead of driver(NO_DRIVER macro)
  - no access to mayud driver
  - hook key input by WH_KEYBOARD_LL
  - generate key event by SendInput() API
  - use mailslot to avoid stall on WM_COPYDATA notify(USE_MAILSLOT macro)
  - ignore !PM_REMOVE message to avoid duplicate message in mayu.dll
  - workaround on {104,109}.mayu for E0-RShift problem

* support 64bit(MAYU64 macro)
  - change API such as GetWindowLong() -> GetWindowLongPtr()
  - change type such as LONG -> LONG_PTR
  - cast HWND to DWORD to share it between 32bit and 64bit
  - add yamyd which install hook to 32bit process on 64bit system
  - use X64 macro in *.mak
  - devide obj out directory for 32bit and 64bit
  - overload load_ARGUMENT() for WPARAM/LPARAM on 64bit
  - not assume INVALID_HANDLE_VALUE=0xffffffff
  - disable notifyCommand()(tentative)

* execute without install
  - not build installer
  - use yamy.ini file instead of registry(USE_INI macro)

* logging
  - add HOOK_RPT*() macro for hook debug
  - suppress HOOK_RPT*() output in specific process such as debugger
  - dump log to file(LOG_TO_FILE macro:disable by default)
  - add "Check" to menu which log key press state in system

* bug fix
  - fix crash on Engine::setFocus()
  - fix assert fail on processing empty list in KeyIterator::KeyIterator()
  - link debug runtime on debug build

* etc
  - move out most part of initialization for mayu.dll from DllMain
  - remove explicit tregex::use_except to follow update of boost::regex
  - change default compiler to VC++9
  - LOGNAME -> USENAME
  - -GX -> -EHsc
  - remove -k from nmake options
  - broadcast WM_NULL to detach mayu.dll on mayu.exe exit

33 files changed:
104.mayu
109.mayu
dlgeditsetting.cpp
dlgeditsetting.h
dlginvestigate.cpp
dlginvestigate.h
dlglog.cpp
dlglog.h
dlgsetting.cpp
dlgsetting.h
dlgversion.cpp
dlgversion.h
engine.cpp [changed mode: 0644->0755]
engine.h [changed mode: 0644->0755]
function.cpp [changed mode: 0644->0755]
hook.cpp [changed mode: 0644->0755]
hook.h [changed mode: 0644->0755]
keyboard.cpp [changed mode: 0644->0755]
keymap.cpp
layoutmanager.cpp
mayu-common.mak [changed mode: 0644->0755]
mayu-vc.mak [changed mode: 0644->0755]
mayu.cpp [changed mode: 0644->0755]
mayu.rc
mayurc.h
registry.cpp [changed mode: 0644->0755]
registry.h [changed mode: 0644->0755]
setting.cpp
setting.h
stringtool.h
vc.mak
windowstool.cpp [changed mode: 0644->0755]
windowstool.h

index a4b8bdf..ae37146 100644 (file)
--- a/104.mayu
+++ b/104.mayu
@@ -83,6 +83,7 @@ def key FullStop Period                       =    0x34 # .>
 def key Solidus Slash                  =    0x35 # /?
 def key NumSolidus NumSlash            = E0-0x35 # Numpad /
 def key RightShift RShift              =    0x36
+def key E0RightShift E0RShift          = E0-0x36
 def key NumAsterisk NumMultiply                =    0x37 # Numpad *
 def key PrintScreen Snapshot           = E0-0x37
 def key LeftAlt LAlt LMenu             =    0x38
@@ -157,6 +158,8 @@ def mod Shift       = LShift RShift
 def mod Alt    = LAlt RAlt
 def mod Control        = LControl RControl
 def mod Windows        = LWindows RWindows
+mod shift += E0RShift
+key *E0RShift = *RShift
 
 
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index f8b37f8..cbb16bc 100644 (file)
--- a/109.mayu
+++ b/109.mayu
@@ -69,6 +69,7 @@ def key Comma                         =    0x33 # ,<
 def key FullStop Period                        =    0x34 # .>
 def key Solidus Slash                  =    0x35 # /?
 def key RightShift RShift              =    0x36
+def key E0RightShift E0RShift          = E0-0x36
 def key NumAsterisk NumMultiply                =    0x37 # \83e\83\93\83L\81[ *
 def key LeftAlt LAlt LMenu             =    0x38
 def key Space                          =    0x39
@@ -210,6 +211,8 @@ def mod Shift       = LShift RShift
 def mod Alt    = LAlt RAlt
 def mod Control        = LControl RControl
 def mod Windows        = LWindows RWindows
+mod shift += E0RShift
+key *E0RShift = *RShift
 
 
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 81628b5..2ee8647 100644 (file)
@@ -151,7 +151,11 @@ public:
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgEditSetting_dlgProc(HWND i_hwnd, UINT i_message,
+#else
 BOOL CALLBACK dlgEditSetting_dlgProc(HWND i_hwnd, UINT i_message,
+#endif
                                     WPARAM i_wParam, LPARAM i_lParam)
 {
   DlgEditSetting *wc;
index fa61db7..77cf7ad 100644 (file)
@@ -9,7 +9,11 @@
 
 
 /// dialog procedure of "Edit Setting" dialog box
+#ifdef MAYU64
+INT_PTR CALLBACK dlgEditSetting_dlgProc(
+#else
 BOOL CALLBACK dlgEditSetting_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
 
 /// parameters for "Edit Setting" dialog box
index 8865b04..27fed65 100644 (file)
@@ -152,7 +152,11 @@ public:
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgInvestigate_dlgProc(HWND i_hwnd, UINT i_message,
+#else
 BOOL CALLBACK dlgInvestigate_dlgProc(HWND i_hwnd, UINT i_message,
+#endif
                                     WPARAM i_wParam, LPARAM i_lParam)
 {
   DlgInvestigate *wc;
index 31ccf28..3b04e4d 100644 (file)
@@ -9,7 +9,11 @@
 
 
 /// dialog procedure of "Investigate" dialog box
+#ifdef MAYU64
+INT_PTR CALLBACK dlgInvestigate_dlgProc(
+#else
 BOOL CALLBACK dlgInvestigate_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
 
 class Engine;
index 50641c5..f24e428 100644 (file)
@@ -161,7 +161,11 @@ public:
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgLog_dlgProc(HWND i_hwnd, UINT i_message,
+#else
 BOOL CALLBACK dlgLog_dlgProc(HWND i_hwnd, UINT i_message,
+#endif
                             WPARAM i_wParam, LPARAM i_lParam)
 {
   DlgLog *wc;
index b449957..305eb85 100644 (file)
--- a/dlglog.h
+++ b/dlglog.h
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgLog_dlgProc(
+#else
 BOOL CALLBACK dlgLog_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
 
 enum
index 0b59ec6..5d4a418 100644 (file)
@@ -341,7 +341,11 @@ public:
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgSetting_dlgProc(
+#else
 BOOL CALLBACK dlgSetting_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
 {
   DlgSetting *wc;
index 0f3d0d4..89fa988 100644 (file)
@@ -9,7 +9,11 @@
 
 
 ///
+#ifdef MAYU64
+INT_PTR CALLBACK dlgSetting_dlgProc(
+#else
 BOOL CALLBACK dlgSetting_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
 
 
index 41cf77a..cd42e32 100644 (file)
@@ -109,7 +109,11 @@ public:
 
 
 //
+#ifdef MAYU64
+INT_PTR CALLBACK dlgVersion_dlgProc(
+#else
 BOOL CALLBACK dlgVersion_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
 {
   DlgVersion *wc;
index 98d76f2..9f3cd9b 100644 (file)
@@ -9,7 +9,11 @@
 
 
 ///
+#ifdef MAYU64
+INT_PTR CALLBACK dlgVersion_dlgProc(
+#else
 BOOL CALLBACK dlgVersion_dlgProc(
+#endif
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
 
 
old mode 100644 (file)
new mode 100755 (executable)
index b92efc0..92afe98
@@ -313,10 +313,14 @@ void Engine::generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign)
        kid.Flags = sc[i].m_flags;
        if (!i_doPress)
          kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;
-       DWORD len;
 #if defined(_WINNT)
+#ifdef NO_DRIVER
+       injectInput(&kid, NULL);
+#else // !NO_DRIVER
+       DWORD len;
        WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
        CHECK_TRUE( GetOverlappedResult(m_device, &m_ol, &len, TRUE) );
+#endif // !NO_DRIVER
 #elif defined(_WIN95)
        DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
 #else
@@ -657,6 +661,30 @@ void Engine::beginGeneratingKeyboardEvents(
 }
 
 
+#ifdef NO_DRIVER
+unsigned int Engine::injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw)
+{
+  INPUT kid;
+  kid.type = INPUT_KEYBOARD;
+  kid.ki.wVk = 0;
+  kid.ki.wScan = i_kid->MakeCode;
+  kid.ki.dwFlags = KEYEVENTF_SCANCODE;
+  kid.ki.time = i_kidRaw ? i_kidRaw->time : 0;
+  kid.ki.dwExtraInfo = i_kidRaw ? i_kidRaw->dwExtraInfo : 0;
+  if (i_kid->Flags & KEYBOARD_INPUT_DATA::BREAK)
+  {
+    kid.ki.dwFlags |= KEYEVENTF_KEYUP;
+  }
+  if (i_kid->Flags & KEYBOARD_INPUT_DATA::E0)
+  {
+    kid.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
+  }
+  SendInput(1, &kid, sizeof(kid));
+  return 1;
+}
+#endif // NO_DRIVER
+
+
 // pop all pressed key on win32
 void Engine::keyboardResetOnWin32()
 {
@@ -669,6 +697,52 @@ void Engine::keyboardResetOnWin32()
 }
 
 
+#ifdef NO_DRIVER
+unsigned int WINAPI Engine::keyboardDetour(Engine *i_this, KBDLLHOOKSTRUCT *i_kid)
+{
+  return i_this->keyboardDetour(i_kid);
+}
+
+unsigned int Engine::keyboardDetour(KBDLLHOOKSTRUCT *i_kid)
+{
+#if 0
+  Acquire a(&m_log, 1);
+  m_log << std::hex
+       << _T("keyboardDetour: vkCode=") << i_kid->vkCode
+       << _T(" scanCode=") << i_kid->scanCode
+       << _T(" flags=") << i_kid->flags << std::endl;
+#endif
+  if (i_kid->flags & LLKHF_INJECTED)
+  {
+    return 0;
+  }
+  else
+  {
+    Key key;
+    KEYBOARD_INPUT_DATA kid;
+
+    kid.UnitId = 0;
+    kid.MakeCode = i_kid->scanCode;
+    kid.Flags = 0;
+    if (i_kid->flags & LLKHF_UP)
+    {
+      kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;
+    }
+    if (i_kid->flags & LLKHF_EXTENDED)
+    {
+         kid.Flags |= KEYBOARD_INPUT_DATA::E0;
+    }
+    kid.Reserved = 0;
+    kid.ExtraInformation = 0;
+
+    Acquire a(&m_cskidq);
+    m_kidq.push_back(kid);
+    SetEvent(m_readEvent);
+    return 1;
+  }
+}
+#endif // NO_DRIVER
+
 // keyboard handler thread
 unsigned int WINAPI Engine::keyboardHandler(void *i_this)
 {
@@ -687,16 +761,23 @@ void Engine::keyboardHandler()
   {
     KEYBOARD_INPUT_DATA kid;
     
+#ifndef NO_DRIVER
     DWORD len;
+#endif // !NO_DRIVER
 #if defined(_WINNT)
     {
       Acquire a(&m_log, 1);
       m_log << _T("begin ReadFile();") << std::endl;
     }
+#ifdef NO_DRIVER
+    if (1)
+    {
+#else // !NO_DRIVER
     if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol))
     {
       if (GetLastError() != ERROR_IO_PENDING)
        continue;
+#endif // !NO_DRIVER
       
       HANDLE handles[] = { m_readEvent, m_interruptThreadEvent };
     rewait:
@@ -704,8 +785,24 @@ void Engine::keyboardHandler()
                                     FALSE, INFINITE, QS_POSTMESSAGE))
       {
        case WAIT_OBJECT_0:                     // m_readEvent
+#ifdef NO_DRIVER
+       {
+         Acquire a(&m_cskidq);
+         if (m_kidq.empty())
+         {
+           goto rewait;
+         }
+         kid = m_kidq.front();
+         m_kidq.pop_front();
+         if (!m_kidq.empty())
+         {
+           SetEvent(m_readEvent);
+         }
+       }
+#else // !NO_DRIVER
          if (!GetOverlappedResult(m_device, &m_ol, &len, FALSE))
            continue;
+#endif // !NO_DRIVER
          break;
          
        case WAIT_OBJECT_0 + 1:                 // m_interruptThreadEvent
@@ -807,8 +904,12 @@ void Engine::keyboardHandler()
       else
       {
 #if defined(_WINNT)
+#ifdef NO_DRIVER
+       injectInput(&kid, NULL);
+#else // !NO_DRIVER
        WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
        GetOverlappedResult(m_device, &m_ol, &len, TRUE);
+#endif // !NO_DRIVER
 #elif defined(_WIN95)
        DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
 #else
@@ -825,8 +926,10 @@ void Engine::keyboardHandler()
        !m_currentKeymap)
     {
 #if defined(_WINNT)
+#ifndef NO_DRIVER
       WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
       GetOverlappedResult(m_device, &m_ol, &len, TRUE);
+#endif // !NO_DRIVER
 #elif defined(_WIN95)
       DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
 #else
@@ -1022,10 +1125,13 @@ Engine::Engine(tomsgstream &i_log)
   for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i)
     m_currentLock.release(static_cast<Modifier::Type>(i));
 
+#ifndef NO_DRIVER
   if (!open()) {
       throw ErrorMessage() << loadString(IDS_driverNotInstalled);
   }
+#endif // !NO_DRIVER
   
+#ifndef NO_DRIVER
   {
     TCHAR versionBuf[256];
     DWORD length = 0;
@@ -1036,6 +1142,7 @@ Engine::Engine(tomsgstream &i_log)
        && length < sizeof(versionBuf))                 // fail safe
        m_mayudVersion = tstring(versionBuf, length / 2);
   }
+#endif // !NO_DRIVER
   // create event for sync
   CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) );
 #if defined(_WINNT)
@@ -1054,9 +1161,11 @@ bool Engine::open()
 {
   // open mayu m_device
 #if defined(_WINNT)
+#ifndef NO_DRIVER
   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
                        0, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+#endif // !NO_DRIVER
 #elif defined(_WIN95)
   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, 0,
                        0, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
@@ -1069,6 +1178,7 @@ bool Engine::open()
   }
 
 #if defined(_WINNT)
+#ifndef NO_DRIVER
   // start mayud
   SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
   if (hscm)
@@ -1087,6 +1197,7 @@ bool Engine::open()
   m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
                        0, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+#endif // !NO_DRIVER
 #endif // _WINNT
   return (m_device != INVALID_HANDLE_VALUE);
 }
@@ -1096,7 +1207,9 @@ bool Engine::open()
 void Engine::close()
 {
   if (m_device != INVALID_HANDLE_VALUE) {
+#ifndef NO_DRIVER
     CHECK_TRUE( CloseHandle(m_device) );
+#endif // !NO_DRIVER
   }
   m_device = INVALID_HANDLE_VALUE;
 }
@@ -1180,7 +1293,9 @@ bool Engine::pause()
       m_interruptThreadReason = InterruptThreadReason_Pause;
       SetEvent(m_interruptThreadEvent);
     } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
+#ifndef NO_DRIVER
     close();
+#endif // !NO_DRIVER
   }
 #endif // _WINNT
   return true;
@@ -1191,9 +1306,11 @@ bool Engine::resume()
 {
 #if defined(_WINNT)
   if (m_device == INVALID_HANDLE_VALUE) {
+#ifndef NO_DRIVER
     if (!open()) {
       return false;                            // FIXME
     }
+#endif // !NO_DRIVER
     do {
       m_interruptThreadReason = InterruptThreadReason_Resume;
       SetEvent(m_interruptThreadEvent);
@@ -1221,11 +1338,16 @@ Engine::~Engine()
   CHECK_TRUE( CloseHandle(m_eSync) );
   
   // close m_device
+#ifndef NO_DRIVER
   close();
+#endif // !NO_DRIVER
 #if defined(_WINNT)
   // destroy named pipe for &SetImeString
-  DisconnectNamedPipe(m_hookPipe);
-  CHECK_TRUE( CloseHandle(m_hookPipe) );
+  if (m_hookPipe && m_hookPipe != INVALID_HANDLE_VALUE)
+  {
+    DisconnectNamedPipe(m_hookPipe);
+    CHECK_TRUE( CloseHandle(m_hookPipe) );
+  }
 #endif // _WINNT
 }
 
@@ -1361,7 +1483,11 @@ void Engine::checkShow(HWND i_hwnd)
   bool isMDIMinimized = false;
   while (i_hwnd)
   {
+#ifdef MAYU64
+    LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
+#else
     LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+#endif
     if (exStyle & WS_EX_MDICHILD)
     {
       WINDOWPLACEMENT placement;
@@ -1383,7 +1509,11 @@ void Engine::checkShow(HWND i_hwnd)
       }
     }
 
+#ifdef MAYU64
+    LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
+#else
     LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+#endif
     if ((style & WS_CHILD) == 0)
     {
       WINDOWPLACEMENT placement;
@@ -1426,16 +1556,19 @@ bool Engine::setFocus(HWND i_hwndFocus, DWORD i_threadId,
   if (!m_detachedThreadIds.empty())
   {
     DetachedThreadIds::iterator i;
+    bool retry;
     do
     {
+      retry = false;
       for (i = m_detachedThreadIds.begin();
           i != m_detachedThreadIds.end(); ++ i)
        if (*i == i_threadId)
        {
          m_detachedThreadIds.erase(i);
+         retry = true;
          break;
        }
-    } while (i != m_detachedThreadIds.end());
+    } while (retry);
   }
   
   FocusOfThread *fot;
@@ -1594,7 +1727,11 @@ void Engine::commandNotify(
       HWND h = hf;
       while (h)
       {
+#ifdef MAYU64
+       LONG_PTR style = GetWindowLongPtr(h, GWL_STYLE);
+#else
        LONG style = GetWindowLong(h, GWL_STYLE);
+#endif
        if ((style & WS_CHILD) == 0)
          break;
        h = GetParent(h);
old mode 100644 (file)
new mode 100755 (executable)
index 0bcddca..0f992fa
--- a/engine.h
+++ b/engine.h
@@ -9,6 +9,7 @@
 #  include "setting.h"
 #  include "msgstream.h"
 #  include <set>
+#  include <queue>
 
 
 enum
@@ -163,6 +164,10 @@ private:
   unsigned m_threadId;
   tstring m_mayudVersion;                      /// version of mayud.sys
 #if defined(_WINNT)
+#ifdef NO_DRIVER
+  std::deque<KEYBOARD_INPUT_DATA> m_kidq;
+  CriticalSection m_cskidq;
+#endif // NO_DRIVER
   HANDLE m_readEvent;                          /** reading from mayu device
                                                     has been completed */
   HANDLE m_interruptThreadEvent;               /// interrupt thread event
@@ -234,6 +239,17 @@ public:
   tomsgstream &m_log;                          /** log stream (output to log
                                                     dialog's edit) */
   
+public:
+#ifdef NO_DRIVER
+  /// keyboard handler thread
+  static unsigned int WINAPI keyboardDetour(Engine *i_this, KBDLLHOOKSTRUCT *i_kid);
+private:
+  ///
+  unsigned int keyboardDetour(KBDLLHOOKSTRUCT *i_kid);
+  ///
+  unsigned int injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw);
+#endif // NO_DRIVER
+  
 private:
   /// keyboard handler thread
   static unsigned int WINAPI keyboardHandler(void *i_this);
old mode 100644 (file)
new mode 100755 (executable)
index 16f7294..24dd0fe
@@ -989,7 +989,11 @@ void Engine::funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
   {
     while (hwnd)
     {
+#ifdef MAYU64
+      LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
+#else
       LONG style = GetWindowLong(hwnd, GWL_STYLE);
+#endif
       if ((style & WS_CHILD) == 0)
        break;
       hwnd = GetParent(hwnd);
@@ -1636,7 +1640,11 @@ void Engine::funcWindowToggleTopMost(FunctionParam *i_param)
     return;
   SetWindowPos(
     hwnd,
+#ifdef MAYU64
+    (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
+#else
     (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
+#endif
     HWND_NOTOPMOST : HWND_TOPMOST,
     0, 0, 0, 0,
     SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
@@ -1707,8 +1715,13 @@ void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
     for (WindowsWithAlpha::iterator i = m_windowsWithAlpha.begin(); 
         i != m_windowsWithAlpha.end(); ++ i)
     {
+#ifdef MAYU64
+      SetWindowLongPtr(*i, GWL_EXSTYLE,
+                   GetWindowLongPtr(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+#else
       SetWindowLong(*i, GWL_EXSTYLE,
                    GetWindowLong(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+#endif
       RedrawWindow(*i, NULL, NULL,
                   RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
     }
@@ -1716,7 +1729,11 @@ void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
   }
   else
   {
+#ifdef MAYU64
+    LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+#else
     LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+#endif
     if (exStyle & WS_EX_LAYERED)       // remove alpha
     {
       WindowsWithAlpha::iterator
@@ -1727,11 +1744,19 @@ void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
     
       m_windowsWithAlpha.erase(i);
     
+#ifdef MAYU64
+      SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
+#else    
       SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
+#endif
     }
     else       // add alpha
     {
+#ifdef MAYU64
+      SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
+#else
       SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
+#endif
       i_alpha %= 101;
       if (!setLayeredWindowAttributes(hwnd, 0,
                                      (BYTE)(255 * i_alpha / 100), LWA_ALPHA))
@@ -2140,7 +2165,11 @@ void Engine::funcDirectSSTP(FunctionParam *i_param,
       cd.cbData = request.size();
       cd.lpData = (void *)request.c_str();
 #endif
+#ifdef MAYU64
+      DWORD_PTR result;
+#else
       DWORD result;
+#endif
       SendMessageTimeout(i->second.m_hwnd, WM_COPYDATA,
                         reinterpret_cast<WPARAM>(m_hwndAssocWindow),
                         reinterpret_cast<LPARAM>(&cd),
@@ -2324,7 +2353,7 @@ void Engine::funcMouseHook(FunctionParam *i_param,
        target = i_param->m_hwnd;
 
       g_hookData->m_hwndMouseHookTarget =
-       getToplevelWindow(target, &isMDI);
+       reinterpret_cast<DWORD>(getToplevelWindow(target, &isMDI));
       break;
     default:
       g_hookData->m_hwndMouseHookTarget = NULL;
old mode 100644 (file)
new mode 100755 (executable)
index 6bda39d..5e55bc9
--- a/hook.cpp
+++ b/hook.cpp
 
 ///
 #define HOOK_DATA_NAME _T("{08D6E55C-5103-4e00-8209-A1C4AB13BBEF}") _T(VERSION)
+#ifdef _WIN64
+#define HOOK_DATA_NAME_ARCH _T("{290C0D51-8AEE-403d-9172-E43D46270996}") _T(VERSION)
+#else // !_WIN64
+#define HOOK_DATA_NAME_ARCH _T("{716A5DEB-CB02-4438-ABC8-D00E48673E45}") _T(VERSION)
+#endif // !_WIN64
 
 // Some applications use different values for below messages
 // when double click of title bar.
 #define SC_MINIMIZE2 (SC_MINIMIZE + 2)
 #define SC_RESTORE2 (SC_RESTORE + 2)
 
+// Debug Macros
+#ifdef NDEBUG
+#define HOOK_RPT0(msg)
+#define HOOK_RPT1(msg, arg1)
+#define HOOK_RPT2(msg, arg1, arg2)
+#else
+#define HOOK_RPT0(msg) if (g.m_isLogging) { _RPT0(_CRT_WARN, msg); }
+#define HOOK_RPT1(msg, arg1) if (g.m_isLogging) { _RPT1(_CRT_WARN, msg, arg1); }
+#define HOOK_RPT2(msg, arg1, arg2) if (g.m_isLogging) { _RPT2(_CRT_WARN, msg, arg1, arg2); }
+#endif
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Global Variables
 
 
 DllExport HookData *g_hookData;                        ///
 
+///
+class HookDataArch
+{
+public:
+  HHOOK m_hHookGetMessage;                     ///
+  HHOOK m_hHookCallWndProc;                    ///
+};
+
+static HookDataArch *s_hookDataArch;
+
 struct Globals
 {
   HANDLE m_hHookData;                          ///
+  HANDLE m_hHookDataArch;                      ///
   HWND m_hwndFocus;                            /// 
   HINSTANCE m_hInstDLL;                                ///
   bool m_isInMenu;                             ///
   UINT m_WM_MAYU_MESSAGE;                      ///
   bool m_isImeLock;                            ///
   bool m_isImeCompositioning;                  ///
+  HHOOK m_hHookMouseProc;                      ///
+#ifdef NO_DRIVER
+  HHOOK m_hHookKeyboardProc;                   ///
+  KEYBOARD_DETOUR m_keyboardDetour;
+  Engine *m_engine;
+#endif // NO_DRIVER
+  DWORD m_hwndTaskTray;                                ///
+  HANDLE m_hMailslot;
+  bool m_isInitialized;
+#ifndef NDEBUG
+  bool m_isLogging;
+  _TCHAR m_moduleName[GANA_MAX_PATH];
+#endif // !NDEBUG
 };
 
 static Globals g;
@@ -52,11 +92,48 @@ static void notifyShow(NotifyShow::Show i_show, bool i_isMDI);
 static void notifyLog(_TCHAR *i_msg);
 static bool mapHookData();
 static void unmapHookData();
+static bool initialize();
 
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Functions
 
+bool initialize()
+{
+#ifndef NDEBUG
+  _TCHAR path[GANA_MAX_PATH];
+  GetModuleFileName(NULL, path, GANA_MAX_PATH);
+  _tsplitpath_s(path, NULL, 0, NULL, 0, g.m_moduleName, GANA_MAX_PATH, NULL, 0);
+  if (_tcsncmp(g.m_moduleName, _T("Dbgview"), sizeof(_T("Dbgview"))/sizeof(_TCHAR)) != 0 &&
+      _tcsncmp(g.m_moduleName, _T("windbg"), sizeof(_T("windbg"))/sizeof(_TCHAR)) != 0)
+  {
+       g.m_isLogging = true;
+  }
+#endif // !NDEBUG
+#ifdef USE_MAILSLOT
+  g.m_hMailslot =
+         CreateFile(NOTIFY_MAILSLOT_NAME, GENERIC_WRITE,
+                    FILE_SHARE_READ | FILE_SHARE_WRITE,
+                    (SECURITY_ATTRIBUTES *)NULL, OPEN_EXISTING,
+                    FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
+  if (g.m_hMailslot == INVALID_HANDLE_VALUE)
+  {
+    HOOK_RPT2("MAYU: %S create mailslot failed(0x%08x)\r\n", g.m_moduleName, GetLastError());
+  }
+  else
+  {
+    HOOK_RPT1("MAYU: %S create mailslot successed\r\n", g.m_moduleName);
+  }
+#endif //USE_MAILSLOT
+  if (!mapHookData())
+    return false;
+  _tsetlocale(LC_ALL, _T(""));
+  g.m_WM_MAYU_MESSAGE =
+    RegisterWindowMessage(addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+  g.m_hwndTaskTray = g_hookData->m_hwndTaskTray;
+  g.m_isInitialized = true;
+  return true;
+}
 
 /// EntryPoint
 BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
@@ -66,12 +143,11 @@ BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
   {
     case DLL_PROCESS_ATTACH:
     {
-      if (!mapHookData())
-       return FALSE;
+#ifndef NDEBUG
+      g.m_isLogging = false;
+#endif // !NDEBUG
+      g.m_isInitialized = false;
       g.m_hInstDLL = i_hInstDLL;
-      _tsetlocale(LC_ALL, _T(""));
-      g.m_WM_MAYU_MESSAGE = RegisterWindowMessage(
-       addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
       break;
     }
     case DLL_THREAD_ATTACH:
@@ -79,6 +155,13 @@ BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
     case DLL_PROCESS_DETACH:
       notifyThreadDetach();
       unmapHookData();
+#ifdef USE_MAILSLOT
+      if (g.m_hMailslot != INVALID_HANDLE_VALUE)
+      {
+       CloseHandle(g.m_hMailslot);
+       g.m_hMailslot = INVALID_HANDLE_VALUE;
+      }
+#endif //USE_MAILSLOT
       break;
     case DLL_THREAD_DETACH:
       notifyThreadDetach();
@@ -93,11 +176,14 @@ BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
 /// map hook data
 static bool mapHookData()
 {
-  g.m_hHookData = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE,
+  g.m_hHookData = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
                                    0, sizeof(HookData),
                                    addSessionId(HOOK_DATA_NAME).c_str());
   if (!g.m_hHookData)
+  {
+    unmapHookData();
     return false;
+  }
   
   g_hookData =
     (HookData *)MapViewOfFile(g.m_hHookData, FILE_MAP_READ | FILE_MAP_WRITE,
@@ -107,6 +193,25 @@ static bool mapHookData()
     unmapHookData();
     return false;
   }
+
+  g.m_hHookDataArch = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+                                   0, sizeof(HookDataArch),
+                                   addSessionId(HOOK_DATA_NAME_ARCH).c_str());
+  if (!g.m_hHookDataArch)
+  {
+    unmapHookData();
+    return false;
+  }
+  
+  s_hookDataArch =
+    (HookDataArch *)MapViewOfFile(g.m_hHookDataArch, FILE_MAP_READ | FILE_MAP_WRITE,
+                             0, 0, sizeof(HookDataArch));
+  if (!s_hookDataArch)
+  {
+    unmapHookData();
+    return false;
+  }
+
   return true;
 }
 
@@ -115,12 +220,17 @@ static bool mapHookData()
 static void unmapHookData()
 {
   if (g_hookData)
-    if (!UnmapViewOfFile(g_hookData))
-      return;
+    UnmapViewOfFile(g_hookData);
   g_hookData = NULL;
   if (g.m_hHookData)
     CloseHandle(g.m_hHookData);
   g.m_hHookData = NULL;
+  if (s_hookDataArch)
+    UnmapViewOfFile(s_hookDataArch);
+  s_hookDataArch = NULL;
+  if (g.m_hHookDataArch)
+    CloseHandle(g.m_hHookDataArch);
+  g.m_hHookDataArch = NULL;
 }
 
 
@@ -128,17 +238,43 @@ static void unmapHookData()
 DllExport bool notify(void *i_data, size_t i_dataSize)
 {
   COPYDATASTRUCT cd;
+#ifdef MAYU64
+  DWORD_PTR result;
+#else  // MAYU64
   DWORD result;
+#endif // MAYU64
 
+#ifdef USE_MAILSLOT
+  DWORD len;
+  if (g.m_hMailslot != INVALID_HANDLE_VALUE)
+  {
+    BOOL ret;
+    ret = WriteFile(g.m_hMailslot, i_data, i_dataSize, &len, NULL);
+#ifndef NDEBUG
+    if (ret == 0)
+    {
+      HOOK_RPT2("MAYU: %S WriteFile to mailslot failed(0x%08x)\r\n", g.m_moduleName, GetLastError());
+    }
+    else
+    {
+      HOOK_RPT1("MAYU: %S WriteFile to mailslot successed\r\n", g.m_moduleName);
+    }
+#endif // !NDEBUG
+  }
+#else // !USE_MAILSLOT
   cd.dwData = reinterpret_cast<Notify *>(i_data)->m_type;
   cd.cbData = i_dataSize;
   cd.lpData = i_data;
-  if (g_hookData->m_hwndTaskTray == NULL)
+  if (g.m_hwndTaskTray == 0)
     return false;
-  if (!SendMessageTimeout(g_hookData->m_hwndTaskTray, WM_COPYDATA,
-                         NULL, reinterpret_cast<LPARAM>(&cd),
+  if (!SendMessageTimeout(reinterpret_cast<HWND>(g.m_hwndTaskTray),
+                         WM_COPYDATA, NULL, reinterpret_cast<LPARAM>(&cd),
                          SMTO_ABORTIFHUNG | SMTO_NORMAL, 5000, &result))
+  {
+    _RPT0(_CRT_WARN, "MAYU: SendMessageTimeout() timeouted\r\n");
     return false;
+  }
+#endif // !USE_MAILSLOT
   return true;
 }
 
@@ -207,13 +343,21 @@ static void updateShow(HWND i_hwnd, NotifyShow::Show i_show)
   if (!i_hwnd)
     return;
 
+#ifdef MAYU64
+  LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
+#else
   LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+#endif
   if (!(style & WS_MAXIMIZEBOX) && !(style & WS_MAXIMIZEBOX))
     return; // ignore window that has neither maximize or minimize button
 
   if (style & WS_CHILD)
   {
+#ifdef MAYU64
+    LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
+#else
     LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+#endif
     if (exStyle & WS_EX_MDICHILD)
     {
       isMDI = true;
@@ -236,7 +380,7 @@ static void notifyName(HWND i_hwnd, Notify::Type i_type = Notify::Type_name)
   NotifySetFocus *nfc = new NotifySetFocus;
   nfc->m_type = i_type;
   nfc->m_threadId = GetCurrentThreadId();
-  nfc->m_hwnd = i_hwnd;
+  nfc->m_hwnd = reinterpret_cast<DWORD>(i_hwnd);
   tcslcpy(nfc->m_className, className.c_str(), NUMBER_OF(nfc->m_className));
   tcslcpy(nfc->m_titleName, titleName.c_str(), NUMBER_OF(nfc->m_titleName));
 
@@ -280,6 +424,7 @@ static void notifyThreadDetach()
 static void notifyCommand(
   HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
 {
+#ifndef _WIN64
   if (g_hookData->m_doesNotifyCommand)
   {
     NotifyCommand ntc;
@@ -290,6 +435,7 @@ static void notifyCommand(
     ntc.m_lParam = i_lParam;
     notify(&ntc, sizeof(ntc));
   }
+#endif
 }
 
 
@@ -327,7 +473,11 @@ static void funcRecenter(HWND i_hwnd)
   else
     return;    // this function only works for Edit control
 
+#ifdef MAYU64
+  LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
+#else
   LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+#endif
   if (!(style & ES_MULTILINE))
     return;    // this function only works for multi line Edit control
 
@@ -427,11 +577,17 @@ DllExport void notifyLockState()
 /// hook of GetMessage
 LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
 {
+  if (!g.m_isInitialized)
+    initialize();
+
   if (!g_hookData)
     return 0;
   
   MSG &msg = (*(MSG *)i_lParam);
 
+  if (i_wParam != PM_REMOVE)
+    goto finally;
+
   switch (msg.message)
   {
     case WM_COMMAND:
@@ -498,7 +654,8 @@ LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
       }
       break;
   }
-  return CallNextHookEx(g_hookData->m_hHookGetMessage,
+ finally:
+  return CallNextHookEx(s_hookDataArch->m_hHookGetMessage,
                        i_nCode, i_wParam, i_lParam);
 }
 
@@ -506,6 +663,9 @@ LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
 /// hook of SendMessage
 LRESULT CALLBACK callWndProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
 {
+  if (!g.m_isInitialized)
+    initialize();
+
   if (!g_hookData)
     return 0;
   
@@ -615,7 +775,7 @@ LRESULT CALLBACK callWndProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
        break;
     }
   }
-  return CallNextHookEx(g_hookData->m_hHookCallWndProc, i_nCode,
+  return CallNextHookEx(s_hookDataArch->m_hHookCallWndProc, i_nCode,
                        i_wParam, i_lParam);
 }
 
@@ -625,7 +785,10 @@ static LRESULT CALLBACK lowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lPara
   MSLLHOOKSTRUCT *pMsll = (MSLLHOOKSTRUCT*)lParam;
   LONG dx = pMsll->pt.x - g_hookData->m_mousePos.x;
   LONG dy = pMsll->pt.y - g_hookData->m_mousePos.y;
-  HWND target = g_hookData->m_hwndMouseHookTarget;
+  HWND target = reinterpret_cast<HWND>(g_hookData->m_hwndMouseHookTarget);
+
+  if (!g.m_isInitialized)
+    initialize();
 
   if (!g_hookData || nCode < 0 || wParam != WM_MOUSEMOVE)
     goto through;
@@ -677,24 +840,64 @@ static LRESULT CALLBACK lowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lPara
   }
     
  through:
-  return CallNextHookEx(g_hookData->m_hHookMouseProc,
+  return CallNextHookEx(g.m_hHookMouseProc,
+                       nCode, wParam, lParam);
+}
+
+
+#ifdef NO_DRIVER
+static LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+  KBDLLHOOKSTRUCT *pKbll = (KBDLLHOOKSTRUCT*)lParam;
+
+  if (!g.m_isInitialized)
+    initialize();
+
+  if (!g_hookData || nCode < 0)
+    goto through;
+
+  if (g.m_keyboardDetour && g.m_engine)
+  {
+    unsigned int result;
+    result = g.m_keyboardDetour(g.m_engine, pKbll);
+    if (result)
+    {
+      return 1;
+    }
+  }
+ through:
+  return CallNextHookEx(g.m_hHookKeyboardProc,
                        nCode, wParam, lParam);
 }
+#endif // NO_DRIVER
 
 
 /// install hooks
-DllExport int installHooks()
+DllExport int installHooks(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine)
 {
-  g_hookData->m_hwndTaskTray = NULL;
-  g_hookData->m_hHookGetMessage =
+  if (!g.m_isInitialized)
+    initialize();
+
+  g.m_hwndTaskTray = g_hookData->m_hwndTaskTray;
+  s_hookDataArch->m_hHookGetMessage =
     SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)getMessageProc,
                     g.m_hInstDLL, 0);
-  g_hookData->m_hHookCallWndProc =
+  s_hookDataArch->m_hHookCallWndProc =
     SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)callWndProc, g.m_hInstDLL, 0);
   g_hookData->m_mouseHookType = MouseHookType_None;
-  g_hookData->m_hHookMouseProc =
-    SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)lowLevelMouseProc,
-                    g.m_hInstDLL, 0);
+  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;
 }
 
@@ -702,14 +905,20 @@ DllExport int installHooks()
 /// uninstall hooks
 DllExport int uninstallHooks()
 {
-  if (g_hookData->m_hHookGetMessage)
-    UnhookWindowsHookEx(g_hookData->m_hHookGetMessage);
-  g_hookData->m_hHookGetMessage = NULL;
-  if (g_hookData->m_hHookCallWndProc)
-    UnhookWindowsHookEx(g_hookData->m_hHookCallWndProc);
-  g_hookData->m_hHookCallWndProc = NULL;
-  if (g_hookData->m_hHookMouseProc)
-    UnhookWindowsHookEx(g_hookData->m_hHookMouseProc);
-  g_hookData->m_hHookMouseProc = NULL;
+  if (s_hookDataArch->m_hHookGetMessage)
+    UnhookWindowsHookEx(s_hookDataArch->m_hHookGetMessage);
+  s_hookDataArch->m_hHookGetMessage = NULL;
+  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;
+#ifdef NO_DRIVER
+  if (g.m_hHookKeyboardProc)
+    UnhookWindowsHookEx(g.m_hHookKeyboardProc);
+  g.m_hHookKeyboardProc = NULL;
+#endif // NO_DRIVER
+  g.m_hwndTaskTray = 0;
   return 0;
 }
diff --git a/hook.h b/hook.h
old mode 100644 (file)
new mode 100755 (executable)
index 984b66e..fcddd01
--- a/hook.h
+++ b/hook.h
@@ -7,11 +7,19 @@
 
 #  include "misc.h"
 #  include <tchar.h>
+#ifdef NO_DRIVER
+#  include <windows.h>
+#endif // NO_DRIVER
 
 ///
 #  define HOOK_PIPE_NAME \
  _T("\\\\.\\pipe\\GANAware\\mayu\\{4B22D464-7A4E-494b-982A-C2B2BBAAF9F3}") _T(VERSION)
 ///
+#ifdef USE_MAILSLOT
+#  define NOTIFY_MAILSLOT_NAME \
+_T("\\\\.\\mailslot\\GANAware\\mayu\\{330F7914-EB5B-49be-ACCE-D2B8DF585B32}") _T(VERSION)
+///
+#endif // USE_MAILSLOT
 #  define WM_MAYU_MESSAGE_NAME _T("GANAware\\mayu\\WM_MAYU_MESSAGE")
 
 ///
@@ -48,7 +56,7 @@ struct Notify
 struct NotifySetFocus : public Notify
 {
   DWORD m_threadId;                            ///
-  HWND m_hwnd;                                 ///
+  DWORD m_hwnd;                                ///
   _TCHAR m_className[GANA_MAX_PATH];           ///
   _TCHAR m_titleName[GANA_MAX_PATH];           ///
 };
@@ -119,21 +127,23 @@ enum MouseHookType
   MouseHookType_WindowMove = 1 << 1,           /// window move
 };
 
+#ifdef NO_DRIVER
+class Engine;
+typedef unsigned int (WINAPI *KEYBOARD_DETOUR)(Engine *i_engine, KBDLLHOOKSTRUCT *i_kid);
+#endif // NO_DRIVER
+
 ///
 class HookData
 {
 public:
-  HHOOK m_hHookGetMessage;                     ///
-  HHOOK m_hHookCallWndProc;                    ///
-  HHOOK m_hHookMouseProc;                      ///
   USHORT m_syncKey;                            ///
   bool m_syncKeyIsExtended;                    ///
   bool m_doesNotifyCommand;                    ///
-  HWND m_hwndTaskTray;                         ///
+  DWORD m_hwndTaskTray;                                ///
   bool m_correctKanaLockHandling;              /// does use KL- ?
   MouseHookType m_mouseHookType;               ///
   int m_mouseHookParam;                        ///
-  HWND m_hwndMouseHookTarget;          ///
+  DWORD m_hwndMouseHookTarget;         ///
   POINT m_mousePos;                            ///
 };
 
@@ -146,7 +156,7 @@ public:
 
 #  ifndef _HOOK_CPP
 extern DllImport HookData *g_hookData;
-extern DllImport int installHooks();
+extern DllImport int installHooks(KEYBOARD_DETOUR i_keyboardDetour, Engine *i_engine);
 extern DllImport int uninstallHooks();
 extern DllImport bool notify(void *data, size_t sizeof_data);
 extern DllImport void notifyLockState();
old mode 100644 (file)
new mode 100755 (executable)
index 931f5a7..98eb6d6
@@ -240,7 +240,15 @@ Keyboard::KeyIterator::KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize)
     m_i((*m_hashedKeys).begin())
 {
   if ((*m_hashedKeys).empty())
-    next();
+  {
+    do
+    {
+      -- m_hashedKeysSize;
+      ++ m_hashedKeys;
+    } while (0 < m_hashedKeysSize && (*m_hashedKeys).empty());
+    if (0 < m_hashedKeysSize)
+      m_i = (*m_hashedKeys).begin();
+  }
 }
 
 
index b692da8..47d7a29 100644 (file)
@@ -228,8 +228,7 @@ Keymap::Keymap(Type i_type,
     try
     {
       tregex::flag_type f = (tregex::normal | 
-                            tregex::icase |
-                            tregex::use_except);
+                            tregex::icase);
       if (!i_windowClass.empty())
        m_windowClass.assign(i_windowClass, f);
       if (!i_windowTitle.empty())
index bea2737..eddd48f 100644 (file)
@@ -58,7 +58,11 @@ bool LayoutManager::addItem(HWND i_hwnd, Origin i_originLeft,
   if (!i_hwnd)\r
     return false;\r
   item.m_hwnd = i_hwnd;\r
+#ifdef MAYU64\r
+  if (!(GetWindowLongPtr(i_hwnd, GWL_STYLE) & WS_CHILD))\r
+#else\r
   if (!(GetWindowLong(i_hwnd, GWL_STYLE) & WS_CHILD))\r
+#endif\r
     return false;\r
   item.m_hwndParent = GetParent(i_hwnd);\r
   if (!item.m_hwndParent)\r
@@ -197,7 +201,11 @@ BOOL LayoutManager::wmNcHitTest(int i_x, int i_y)
   if (rc.right - GetSystemMetrics(SM_CXHTHUMB) <= p.x &&\r
       rc.bottom - GetSystemMetrics(SM_CYVTHUMB) <= p.y)\r
   {\r
+#ifdef MAYU64\r
+    SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, HTBOTTOMRIGHT);\r
+#else\r
     SetWindowLong(m_hwnd, DWL_MSGRESULT, HTBOTTOMRIGHT);\r
+#endif\r
     return TRUE;\r
   }\r
   return FALSE;\r
old mode 100644 (file)
new mode 100755 (executable)
index a57fefa..aeb12b2
@@ -27,11 +27,14 @@ DISTRIB_OS  = 9x
 
 COMMON_DEFINES = -DSTRICT -D_WIN32_IE=0x0500 $(OS_SPECIFIC_DEFINES)
 BOOST_DIR      = ../boost_$(BOOST_VER)_0
+!ifdef X64
+BOOST_DIR      = $(BOOST_DIR)_x64
+!endif
 
 
 # mayu.exe     ###############################################################
 
-TARGET_1       = $(OUT_DIR)\mayu.exe
+TARGET_1       = $(OUT_DIR_EXE)\mayu$(X64).exe
 OBJS_1         =                                       \
                $(OUT_DIR)\compiler_specific_func.obj   \
                $(OUT_DIR)\dlgeditsetting.obj           \
@@ -83,13 +86,13 @@ LIBS_1              =                       \
                shell32.lib             \
                comctl32.lib            \
                wtsapi32.lib            \
-               $(OUT_DIR)\mayu.lib     \
+               $(OUT_DIR_EXE)\mayu$(X64).lib   \
 
-EXTRADEP_1     = $(OUT_DIR)\mayu.lib
+EXTRADEP_1     = $(OUT_DIR_EXE)\mayu$(X64).lib
 
 # mayu.dll     ###############################################################
 
-TARGET_2       = $(OUT_DIR)\mayu.dll
+TARGET_2       = $(OUT_DIR_EXE)\mayu$(X64).dll
 OBJS_2         = $(OUT_DIR)\hook.obj $(OUT_DIR)\stringtool.obj
 SRCS_2         = hook.cpp stringtool.cpp
 LIBS_2         = $(guixlibsmt) imm32.lib
@@ -97,9 +100,19 @@ LIBS_2              = $(guixlibsmt) imm32.lib
 
 # mayu.lib     ###############################################################
 
-TARGET_3       = $(OUT_DIR)\mayu.lib
-DLL_3          = $(OUT_DIR)\mayu.dll
+TARGET_3       = $(OUT_DIR_EXE)\mayu$(X64).lib
+DLL_3          = $(OUT_DIR_EXE)\mayu$(X64).dll
+
+
+# yamyd                ###############################################################
 
+TARGET_4       = $(OUT_DIR_EXE)\yamyd$(X64)
+OBJS_4         = $(OUT_DIR)\yamyd.obj
+
+SRCS_4         = yamyd.cpp
+LIBS_4         = user32.lib $(OUT_DIR_EXE)\mayu$(X64).lib
+
+EXTRADEP_4     = $(OUT_DIR_EXE)\mayu$(X64).lib
 
 # distribution ###############################################################
 
@@ -153,6 +166,7 @@ DISTRIB_DRIVER      = d_win9x\mayud.vxd
 DISTRIB                =                       \
                $(TARGET_1)             \
                $(TARGET_2)             \
+               $(TARGET_4)             \
                s\$(OUT_DIR)\setup.exe  \
                $(DISTRIB_SETTINGS)     \
                $(DISTRIB_MANUAL)       \
@@ -174,19 +188,22 @@ GENIEXPRESS       = perl tools/geniexpress
 
 # rules                ###############################################################
 
-all:           boost $(OUT_DIR) $(TARGET_1) $(TARGET_2) $(TARGET_3)
+all:           boost $(OUT_DIR) $(OUT_DIR_EXE) $(TARGET_1) $(TARGET_2) $(TARGET_3) $(TARGET_4)
 
 $(OUT_DIR):
                if not exist "$(OUT_DIR)\\" $(MKDIR) $(OUT_DIR)
 
+$(OUT_DIR_EXE):
+               if not exist "$(OUT_DIR_EXE)\\" $(MKDIR) $(OUT_DIR_EXE)
+
 functions.h:   engine.h tools/makefunc
                $(MAKEFUNC) < engine.h > functions.h
 
 clean::
-               -$(RM) $(TARGET_1) $(TARGET_2) $(TARGET_3)
+               -$(RM) $(TARGET_1) $(TARGET_2) $(TARGET_3) $(TARGET_4)
                -$(RM) $(OUT_DIR)\*.obj
-               -$(RM) $(OUT_DIR)\*.res $(OUT_DIR)\*.exp
-               -$(RM) mayu.aps mayu.opt $(OUT_DIR)\*.pdb
+               -$(RM) $(OUT_DIR)\*.res $(OUT_DIR_EXE)\*.exp
+               -$(RM) mayu.aps mayu.opt $(OUT_DIR_EXE)\*.pdb
                -$(RM) *~ $(CLEAN)
                -$(RMDIR) $(OUT_DIR)
 
old mode 100644 (file)
new mode 100755 (executable)
index 65f3f6b..139d542
@@ -8,13 +8,13 @@
 ###############################################################################
 
 !if "$(BOOST_VER)" == ""
-BOOST_VER      = 1_32
+BOOST_VER      = 1_38
 !endif
 INCLUDES       = -I$(BOOST_DIR)        # why here ?
 DEPENDIGNORE   = --ignore=$(BOOST_DIR)
 
 !if "$(MAYU_VC)" == ""
-MAYU_VC        = vc6
+MAYU_VC        = vc9
 !endif
 
 !if ( "$(MAYU_VC)" == "vct" )
@@ -27,19 +27,24 @@ MAYU_REGEX_VC       = $(MAYU_VC)
 !include <mayu-common.mak>
 
 DEFINES                = $(COMMON_DEFINES) -DVERSION=""""$(VERSION)"""" \
-               -DLOGNAME=""""$(LOGNAME)"""" \
-               -DCOMPUTERNAME=""""$(COMPUTERNAME)""""
+               -DLOGNAME=""""$(USERNAME)"""" \
+               -DCOMPUTERNAME=""""$(COMPUTERNAME)"""" -D_CRT_SECURE_NO_WARNINGS -DMAYU64 -DNO_DRIVER -DUSE_MAILSLOT -DUSE_INI
 # INCLUDES     = -I$(BOOST_DIR)        # make -f mayu-vc.mak depend fails ...
 
 LDFLAGS_1      =                                               \
                $(guilflags)                                    \
                /PDB:$(TARGET_1).pdb                            \
-               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC) \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC)0        \
 
 LDFLAGS_2      =                                               \
                $(dlllflags)                                    \
                /PDB:$(TARGET_2).pdb                            \
-               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC) \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC)0        \
+
+LDFLAGS_4      =                                               \
+               $(guilflags)                                    \
+               /PDB:$(TARGET_4).pdb                            \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC)0        \
 
 $(TARGET_1):   $(OBJS_1) $(RES_1) $(EXTRADEP_1)
        $(link) -out:$@ $(ldebug) $(LDFLAGS_1) $(OBJS_1) $(LIBS_1) $(RES_1)
@@ -49,6 +54,9 @@ $(TARGET_2):  $(OBJS_2) $(RES_2) $(EXTRADEP_2)
 
 $(TARGET_3):   $(DLL_3)
 
+$(TARGET_4):   $(OBJS_4) $(EXTRADEP_4)
+       $(link) -out:$@ $(ldebug) $(LDFLAGS_4) $(OBJS_4) $(LIBS_4)
+
 REGEXPP_XCFLAGS        = $(REGEXPP_XCFLAGS) XCFLAGS=-D_WCTYPE_INLINE_DEFINED
 
 clean::
@@ -56,22 +64,22 @@ clean::
 
 boost:
                cd $(BOOST_DIR)/libs/regex/build/
-               $(MAKE) -f $(MAYU_REGEX_VC).mak $(REGEXPP_XCFLAGS) main_dir libboost_regex-$(MAYU_REGEX_VC)-mt-s-$(BOOST_VER)_dir ./$(MAYU_REGEX_VC)/libboost_regex-$(MAYU_REGEX_VC)-mt-s-$(BOOST_VER).lib
-               cd ../../../../mayu
+               $(MAKE) -f $(MAYU_REGEX_VC).mak $(REGEXPP_XCFLAGS) main_dir libboost_regex-$(MAYU_REGEX_VC)0-mt-s-$(BOOST_VER)_dir ./$(MAYU_REGEX_VC)0/libboost_regex-$(MAYU_REGEX_VC)0-mt-s-$(BOOST_VER).lib libboost_regex-$(MAYU_REGEX_VC)0-mt-sgd-$(BOOST_VER)_dir ./$(MAYU_REGEX_VC)0/libboost_regex-$(MAYU_REGEX_VC)0-mt-sgd-$(BOOST_VER).lib
+               cd ../../../../yamy
 
 distclean::    clean
                cd $(BOOST_DIR)/libs/regex/build/
                -$(MAKE) -k -f $(MAYU_REGEX_VC).mak clean
-               cd ../../../../mayu
+               cd ../../../../yamy
 
 batch:
 !if "$(MAYU_VC)" != "vct"
-               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT
+               -$(MAKE) -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT
 !endif
-               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1
-               cd s
-               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) batch
-               cd ..
+               -$(MAKE) -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1
+#              cd s
+#              -$(MAKE) -f setup-vc.mak MAYU_VC=$(MAYU_VC) batch
+#              cd ..
 
 batch_clean:
                -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1 clean
old mode 100644 (file)
new mode 100755 (executable)
index 36cc3d3..8be884b
--- a/mayu.cpp
+++ b/mayu.cpp
@@ -24,6 +24,7 @@
 #include "setting.h"
 #include "target.h"
 #include "windowstool.h"
+#include "vk2tchar.h"
 #include <process.h>
 #include <time.h>
 #include <commctrl.h>
@@ -56,8 +57,20 @@ class Mayu
 
   tomsgstream m_log;                           /** log stream (output to log
                                                    dialog's edit) */
+#ifdef LOG_TO_FILE
+  tofstream m_logFile;
+#endif // LOG_TO_FILE
 
   HMENU m_hMenuTaskTray;                       /// tasktray menu
+  STARTUPINFO m_si;
+  PROCESS_INFORMATION m_pi;
+  HANDLE m_mutex;
+#ifdef USE_MAILSLOT
+  HANDLE m_hNotifyMailslot;                    /// mailslot to receive notify
+  HANDLE m_hNotifyEvent;                       /// event on receive notify
+  OVERLAPPED m_olNotify;                       /// 
+  BYTE m_notifyBuf[NOTIFY_MESSAGE_SIZE];
+#endif // USE_MAILSLOT
   
   Setting *m_setting;                          /// current setting
   bool m_isSettingDialogOpened;                        /// is setting dialog opened ?
@@ -75,6 +88,37 @@ class Mayu
   };
 
 private:
+#ifdef USE_MAILSLOT
+  static VOID CALLBACK mailslotProc(DWORD i_code, DWORD i_len, LPOVERLAPPED i_ol)
+  {
+    Mayu *pThis;
+
+    pThis = reinterpret_cast<Mayu*>(CONTAINING_RECORD(i_ol, Mayu, m_olNotify));
+    pThis->mailslotHandler(i_code, i_len);
+    return;
+  }
+
+  BOOL mailslotHandler(DWORD i_code, DWORD i_len)
+  {
+    BOOL result;
+
+    if (i_len)
+    {
+      COPYDATASTRUCT cd;
+
+      cd.dwData = reinterpret_cast<Notify *>(m_notifyBuf)->m_type;
+      cd.cbData = i_len;
+      cd.lpData = m_notifyBuf;
+      notifyHandler(&cd);
+    }
+
+    memset(m_notifyBuf, 0, sizeof(m_notifyBuf));
+    result = ReadFileEx(m_hNotifyMailslot, m_notifyBuf, sizeof(m_notifyBuf),
+                       &m_olNotify, Mayu::mailslotProc);
+    return result;
+  }
+#endif // USE_MAILSLOT
+
   /// register class for tasktray
   ATOM Register_tasktray()
   {
@@ -105,13 +149,13 @@ private:
          n->m_titleName[NUMBER_OF(n->m_titleName) - 1] = _T('\0');
          
          if (n->m_type == Notify::Type_setFocus)
-           m_engine.setFocus(n->m_hwnd, n->m_threadId,
+           m_engine.setFocus(reinterpret_cast<HWND>(n->m_hwnd), n->m_threadId,
                              n->m_className, n->m_titleName, false);
 
          {
            Acquire a(&m_log, 1);
            m_log << _T("HWND:\t") << std::hex
-                 << reinterpret_cast<int>(n->m_hwnd)
+                 << n->m_hwnd
                  << std::dec << std::endl;
            m_log << _T("THREADID:") << static_cast<int>(n->m_threadId)
                  << std::endl;
@@ -121,7 +165,7 @@ private:
          m_log << _T("TITLE:\t") << n->m_titleName << std::endl;
          
          bool isMDI = true;
-         HWND hwnd = getToplevelWindow(n->m_hwnd, &isMDI);
+         HWND hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), &isMDI);
          RECT rc;
          if (isMDI)
          {
@@ -130,7 +174,7 @@ private:
                  << rc.left << _T(", ") << rc.top << _T(") / (")
                  << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
                  << std::endl;
-           hwnd = getToplevelWindow(n->m_hwnd, NULL);
+           hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), NULL);
          }
          
          GetWindowRect(hwnd, &rc);
@@ -227,7 +271,11 @@ private:
   tasktray_wndProc(HWND i_hwnd, UINT i_message,
                   WPARAM i_wParam, LPARAM i_lParam)
   {
+#ifdef MAYU64
+    Mayu *This = reinterpret_cast<Mayu *>(GetWindowLongPtr(i_hwnd, 0));
+#else
     Mayu *This = reinterpret_cast<Mayu *>(GetWindowLong(i_hwnd, 0));
+#endif
 
     if (!This)
       switch (i_message)
@@ -235,7 +283,11 @@ private:
        case WM_CREATE:
          This = reinterpret_cast<Mayu *>(
            reinterpret_cast<CREATESTRUCT *>(i_lParam)->lpCreateParams);
+#ifdef MAYU64
+         SetWindowLongPtr(i_hwnd, 0, (LONG_PTR)This);
+#else
          SetWindowLong(i_hwnd, 0, (long)This);
+#endif
          return 0;
       }
     else
@@ -299,6 +351,9 @@ private:
          tomsgstream::StreamBuf *log =
            reinterpret_cast<tomsgstream::StreamBuf *>(i_lParam);
          const tstring &str = log->acquireString();
+#ifdef LOG_TO_FILE
+         This->m_logFile << str << std::flush;
+#endif // LOG_TO_FILE
          editInsertTextAtLast(GetDlgItem(This->m_hwndLog, IDC_EDIT_log),
                               str, 65000);
          log->releaseString();
@@ -422,6 +477,50 @@ private:
                ShowWindow(This->m_hwndLog, SW_SHOW);
                SetForegroundWindow(This->m_hwndLog);
                break;
+             case ID_MENUITEM_check:
+             {
+               BOOL ret;
+               BYTE keys[256];
+               ret = GetKeyboardState(keys);
+               if (ret == 0)
+               {
+                 This->m_log << _T("Check Keystate Failed(%d)")
+                             << GetLastError() << std::endl;
+               }
+               else
+               {
+                 This->m_log << _T("Check Keystate: ") << std::endl;
+                 for (int i = 0; i < 0xff; i++)
+                 {
+                   USHORT asyncKey;
+                   asyncKey = GetAsyncKeyState(i);
+                   This->m_log << std::hex;
+                   if (asyncKey & 0x8000)
+                   {
+                     This->m_log << _T("  ") << VK2TCHAR[i]
+                                 << _T("(0x") << i << _T("): pressed!")
+                                 << std::endl;
+                   }
+                   if (i == 0x14 || // VK_CAPTITAL
+                       i == 0x15 || // VK_KANA
+                       i == 0x19 || // VK_KANJI
+                       i == 0x90 || // VK_NUMLOCK
+                       i == 0x91    // VK_SCROLL
+                       )
+                   {
+                     if (keys[i] & 1)
+                     {
+                       This->m_log << _T("  ") << VK2TCHAR[i]
+                                   << _T("(0x") << i << _T("): locked!")
+                                   << std::endl;
+                     }
+                   }
+                   This->m_log << std::dec;
+                 }
+                 This->m_log << std::endl;
+               }
+               break;
+             }
              case ID_MENUITEM_version:
                ShowWindow(This->m_hwndVersion, SW_SHOW);
                SetForegroundWindow(This->m_hwndVersion);
@@ -699,8 +798,9 @@ private:
 
 public:
   ///
-  Mayu()
+  Mayu(HANDLE i_mutex)
     : m_hwndTaskTray(NULL),
+      m_mutex(i_mutex),
       m_hwndLog(NULL),
       m_WM_TaskbarRestart(RegisterWindowMessage(_T("TaskbarCreated"))),
       m_WM_MayuIPC(RegisterWindowMessage(WM_MayuIPC_NAME)),
@@ -711,6 +811,15 @@ public:
       m_isSettingDialogOpened(false),
       m_engine(m_log)
   {
+#ifdef USE_MAILSLOT
+       m_hNotifyMailslot = CreateMailslot(NOTIFY_MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, (SECURITY_ATTRIBUTES *)NULL);
+       ASSERT(m_hNotifyMailslot != INVALID_HANDLE_VALUE);
+       m_hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+       ASSERT(m_hNotifyEvent);
+       m_olNotify.Offset = 0;
+       m_olNotify.OffsetHigh = 0;
+       m_olNotify.hEvent = m_hNotifyEvent;
+#endif // USE_MAILSLOT
     time(&m_startTime);
 
     CHECK_TRUE( Register_focus() );
@@ -736,7 +845,10 @@ public:
     CHECK_TRUE( m_hwndTaskTray );
     
     // set window handle of tasktray to hooks
-    g_hookData->m_hwndTaskTray = m_hwndTaskTray;
+#ifndef USE_MAILSLOT
+    g_hookData->m_hwndTaskTray = reinterpret_cast<DWORD>(m_hwndTaskTray);
+#endif // !USE_MAILSLOT
+    CHECK_FALSE( installHooks(Engine::keyboardDetour, &m_engine) );
     m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray,
                                               NOTIFY_FOR_THIS_SESSION);
 
@@ -763,6 +875,19 @@ public:
     CHECK_TRUE( m_hwndVersion );
 
     // attach log
+#ifdef LOG_TO_FILE
+    tstring path;
+    _TCHAR exePath[GANA_MAX_PATH];
+    _TCHAR exeDrive[GANA_MAX_PATH];
+    _TCHAR exeDir[GANA_MAX_PATH];
+    GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
+    _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
+    path = exeDrive;
+    path += exeDir;
+    path += _T("mayu.log");
+    m_logFile.open(path.c_str(), std::ios::app);
+    m_logFile.imbue(std::locale("japanese"));
+#endif // LOG_TO_FILE
     SendMessage(GetDlgItem(m_hwndLog, IDC_EDIT_log), EM_SETLIMITTEXT, 0, 0);
     m_log.attach(m_hwndTaskTray);
 
@@ -796,16 +921,32 @@ public:
     
     // set initial lock state
     notifyLockState();
+
+    BOOL result;
+
+    ZeroMemory(&m_pi,sizeof(m_pi));
+    ZeroMemory(&m_si,sizeof(m_si));
+    m_si.cb=sizeof(m_si);
+#ifdef _WIN64
+    result = CreateProcess(_T("yamyd"), _T("yamyd"), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, 0, NULL, &m_si, &m_pi);
+#endif // _WIN64
   }
 
   ///
   ~Mayu()
   {
+    ReleaseMutex(m_mutex);
+    WaitForSingleObject(m_mutex, INFINITE);
     // first, detach log from edit control to avoid deadlock
     m_log.detach();
+#ifdef LOG_TO_FILE
+    m_logFile.close();
+#endif // LOG_TO_FILE
    
     // stop notify from mayu.dll
     g_hookData->m_hwndTaskTray = NULL;
+    CHECK_FALSE( uninstallHooks() );
+       SendMessage(HWND_BROADCAST, WM_NULL, 0, 0);
     
     // destroy windows
     CHECK_TRUE( DestroyWindow(m_hwndVersion) );
@@ -826,6 +967,11 @@ public:
     
     // remove setting;
     delete m_setting;
+    
+#ifdef USE_MAILSLOT
+    CloseHandle(m_hNotifyEvent);
+    CloseHandle(m_hNotifyMailslot);
+#endif // USE_MAILSLOT
   }
 
   /// message loop
@@ -834,6 +980,49 @@ public:
     showBanner(false);
     load();
     
+#ifdef USE_MAILSLOT
+    mailslotHandler(0, 0);
+    while (1)
+    {
+      HANDLE handles[] = { m_hNotifyEvent };
+      DWORD ret;
+      switch (ret = MsgWaitForMultipleObjectsEx(NUMBER_OF(handles), &handles[0],
+                                                                                               INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE))
+      {
+       case WAIT_OBJECT_0:                     // m_hNotifyEvent
+         break;
+         
+        case WAIT_OBJECT_0 + NUMBER_OF(handles):
+       {
+         MSG msg;
+         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0)
+         {
+           if (msg.message == WM_QUIT)
+           {
+             return msg.wParam;
+           }
+           if (IsDialogMessage(m_hwndLog, &msg))
+             break;
+           if (IsDialogMessage(m_hwndInvestigate, &msg))
+             break;
+           if (IsDialogMessage(m_hwndVersion, &msg))
+             break;
+           TranslateMessage(&msg);
+           DispatchMessage(&msg);
+           break;
+         }
+         break;
+       }
+       
+        case WAIT_IO_COMPLETION:
+         break;
+       
+        case 0x102:
+        default:
+         break;
+      }
+    }
+#else // !USE_MAILSLOT
     MSG msg;
     while (0 < GetMessage(&msg, NULL, 0, 0))
     {
@@ -847,6 +1036,7 @@ public:
       DispatchMessage(&msg);
     }
     return msg.wParam;
+#endif // !USE_MAILSLOT
   }  
 };
 
@@ -931,12 +1121,13 @@ int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
 #endif
 
   // convert old registry to new registry
+#ifndef USE_INI
   convertRegistry();
+#endif // !USE_INI
   
   // is another mayu running ?
-  HANDLE mutex = CreateMutex(
-      (SECURITY_ATTRIBUTES *)NULL, TRUE,
-      addSessionId(MUTEX_MAYU_EXCLUSIVE_RUNNING).c_str());
+  HANDLE mutex = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE,
+                            MUTEX_MAYU_EXCLUSIVE_RUNNING);
   if (GetLastError() == ERROR_ALREADY_EXISTS)
   {
     // another mayu already running
@@ -944,7 +1135,8 @@ int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
     tstring title = loadString(IDS_mayu);
     if (g_hookData) {
        UINT WM_TaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));
-       PostMessage(g_hookData->m_hwndTaskTray, WM_TaskbarRestart, 0, 0);
+       PostMessage(reinterpret_cast<HWND>(g_hookData->m_hwndTaskTray),
+                   WM_TaskbarRestart, 0, 0);
     }
     MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
     return 1;
@@ -961,10 +1153,9 @@ int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
     return 1;
   }
   
-  CHECK_FALSE( installHooks() );
   try
   {
-    Mayu().messageLoop();
+    Mayu(mutex).messageLoop();
   }
   catch (ErrorMessage &i_e)
   {
@@ -972,7 +1163,6 @@ int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
     MessageBox((HWND)NULL, i_e.getMessage().c_str(), title.c_str(),
               MB_OK | MB_ICONSTOP);
   }
-  CHECK_FALSE( uninstallHooks() );
   
   CHECK_TRUE( CloseHandle(mutex) );
   return 0;
diff --git a/mayu.rc b/mayu.rc
index edade0d..229a98e 100644 (file)
--- a/mayu.rc
+++ b/mayu.rc
@@ -190,6 +190,7 @@ BEGIN
         MENUITEM SEPARATOR\r
         MENUITEM "\92²\8d¸(&I)...",                 ID_MENUITEM_investigate\r
         MENUITEM "\83\8d\83O(&L)...",                 ID_MENUITEM_log\r
+        MENUITEM "\83`\83F\83b\83N(&C)...",             ID_MENUITEM_check\r
         MENUITEM "\83o\81[\83W\83\87\83\93(&V)...",           ID_MENUITEM_version\r
         MENUITEM "\83w\83\8b\83v(&H)...",               ID_MENUITEM_help\r
         MENUITEM SEPARATOR\r
@@ -440,6 +441,7 @@ BEGIN
         MENUITEM SEPARATOR\r
         MENUITEM "&Investigation...",           ID_MENUITEM_investigate\r
         MENUITEM "&Log...",                     ID_MENUITEM_log\r
+        MENUITEM "&Check...",                   ID_MENUITEM_check\r
         MENUITEM "&Version...",                 ID_MENUITEM_version\r
         MENUITEM "&Help...",                    ID_MENUITEM_help\r
         MENUITEM SEPARATOR\r
index d3f4ed8..2783b10 100644 (file)
--- a/mayurc.h
+++ b/mayurc.h
@@ -73,6 +73,7 @@
 #define ID_MENUITEM_help                40006\r
 #define ID_MENUITEM_disable             40007\r
 #define ID_MENUITEM_log                 40008\r
+#define ID_MENUITEM_check               40009\r
 #define IDC_STATIC                      -1\r
 \r
 // Next default values for new objects\r
old mode 100644 (file)
new mode 100755 (executable)
index d2f8d40..e7a38fc
 bool Registry::remove(HKEY i_root, const tstring &i_path,
                      const tstring &i_name)
 {
+#ifdef USE_INI
+  return false;
+  if (i_name.empty())
+    return false;
+  return WritePrivateProfileString(_T("yamy"), i_name.c_str(), NULL, i_path.c_str()) == TRUE;
+#else // !USE_INI
   if (i_name.empty())
     return RegDeleteKey(i_root, i_path.c_str()) == ERROR_SUCCESS;
   HKEY hkey;
@@ -21,18 +27,23 @@ bool Registry::remove(HKEY i_root, const tstring &i_path,
   LONG r = RegDeleteValue(hkey, i_name.c_str());
   RegCloseKey(hkey);
   return r == ERROR_SUCCESS;
+#endif // !USE_INI
 }
 
 
 // does exist the key ?
 bool Registry::doesExist(HKEY i_root, const tstring &i_path)
 {
+#ifdef USE_INI
+  return true;
+#else // !USE_INI
   HKEY hkey;
   if (ERROR_SUCCESS !=
       RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
     return false;
   RegCloseKey(hkey);
   return true;
+#endif // !USE_INI
 }
 
 
@@ -40,6 +51,11 @@ bool Registry::doesExist(HKEY i_root, const tstring &i_path)
 bool Registry::read(HKEY i_root, const tstring &i_path,
                    const tstring &i_name, int *o_value, int i_defaultValue)
 {
+#ifdef USE_INI
+  *o_value =
+    GetPrivateProfileInt(_T("yamy"), i_name.c_str(), i_defaultValue, i_path.c_str());
+  return true;
+#else // !USE_INI
   HKEY hkey;
   if (ERROR_SUCCESS ==
       RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
@@ -54,6 +70,7 @@ bool Registry::read(HKEY i_root, const tstring &i_path,
   }
   *o_value = i_defaultValue;
   return false;
+#endif // !USE_INI
 }
 
 
@@ -61,6 +78,15 @@ bool Registry::read(HKEY i_root, const tstring &i_path,
 bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
                     int i_value)
 {
+#ifdef USE_INI
+  DWORD ret;
+  _TCHAR buf[GANA_MAX_PATH];
+
+  _stprintf(buf, _T("%d"), i_value);
+  ret =  WritePrivateProfileString(_T("yamy"), i_name.c_str(),
+                                  buf, i_path.c_str());
+  return ret != 0;
+#else // !USE_INI
   HKEY hkey;
   DWORD disposition;
   if (ERROR_SUCCESS !=
@@ -72,6 +98,7 @@ bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
                         (BYTE *)&i_value, sizeof(i_value));
   RegCloseKey(hkey);
   return r == ERROR_SUCCESS;
+#endif // !USE_INI
 }
 
 
@@ -79,6 +106,20 @@ bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
 bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
                    tstring *o_value, const tstring &i_defaultValue)
 {
+#ifdef USE_INI
+  _TCHAR buf[GANA_MAX_PATH];
+  DWORD len;
+  len = GetPrivateProfileString(_T("yamy"), i_name.c_str(), _T(""),
+                               buf, sizeof(buf) / sizeof(buf[0]), i_path.c_str());
+  if (len > 0)
+  {
+    *o_value = buf;
+    return true;
+  }
+  if (!i_defaultValue.empty())
+    *o_value = i_defaultValue;
+  return false;
+#else // !USE_INI
   HKEY hkey;
   if (ERROR_SUCCESS ==
       RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
@@ -107,6 +148,7 @@ bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
   if (!i_defaultValue.empty())
     *o_value = i_defaultValue;
   return false;
+#endif // !USE_INI
 }
 
 
@@ -114,6 +156,13 @@ bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
 bool Registry::write(HKEY i_root, const tstring &i_path,
                     const tstring &i_name, const tstring &i_value)
 {
+#ifdef USE_INI
+  DWORD ret;
+
+  ret =  WritePrivateProfileString(_T("yamy"), i_name.c_str(),
+                                  i_value.c_str(), i_path.c_str());
+  return ret != 0;
+#else // !USE_INI
   HKEY hkey;
   DWORD disposition;
   if (ERROR_SUCCESS !=
@@ -126,9 +175,11 @@ bool Registry::write(HKEY i_root, const tstring &i_path,
                (i_value.size() + 1) * sizeof(tstring::value_type));
   RegCloseKey(hkey);
   return true;
+#endif // !USE_INI
 }
 
 
+#ifndef USE_INI
 // read list of string
 bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
                    tstrings *o_value, const tstrings &i_defaultValue)
@@ -239,6 +290,7 @@ bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
   RegCloseKey(hkey);
   return true;
 }
+#endif //!USE_INI
 
 
 //
old mode 100644 (file)
new mode 100755 (executable)
index 8a7a1c5..531c62d
@@ -20,14 +20,25 @@ public:
   
 public:
   ///
-  Registry() : m_root(NULL) { }
+  Registry() : m_root(NULL) { setRoot(NULL, _T("")); }
   ///
   Registry(HKEY i_root, const tstring &i_path)
-    : m_root(i_root), m_path(i_path) { }
+    : m_root(i_root), m_path(i_path) { setRoot(i_root, i_path); }
   
   /// set registry root and path
   void setRoot(HKEY i_root, const tstring &i_path)
-  { m_root = i_root; m_path = i_path; }
+  {
+    m_root = i_root;
+    m_path = i_path;
+    _TCHAR exePath[GANA_MAX_PATH];
+    _TCHAR exeDrive[GANA_MAX_PATH];
+    _TCHAR exeDir[GANA_MAX_PATH];
+    GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
+    _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
+    m_path = exeDrive;
+    m_path += exeDir;
+    m_path += _T("yamy.ini");
+  }
   
   /// remvoe
   bool remove(const tstring &i_name = _T("")) const
@@ -52,6 +63,7 @@ public:
   bool write(const tstring &i_name, const tstring &i_value) const
   { return write(m_root, m_path, i_name, i_value); }
 
+#ifndef USE_INI
   /// read list of tstring
   bool read(const tstring &i_name, tstrings *o_value, 
            const tstrings &i_defaultValue = tstrings()) const
@@ -70,6 +82,7 @@ public:
   bool write(const tstring &i_name, const BYTE *i_value,
             DWORD i_valueSize) const
   { return write(m_root, m_path, i_name, i_value, i_valueSize); }
+#endif //!USE_INI
 
 public:
   /// remove
@@ -93,6 +106,7 @@ public:
   static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
                    const tstring &i_value);
   
+#ifndef USE_INI
   /// read list of tstring
   static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
                   tstrings *o_value, const tstrings &i_defaultValue = tstrings());
@@ -108,6 +122,7 @@ public:
   /// write binary data
   static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
                    const BYTE *i_value, DWORD i_valueSize);
+#endif //!USE_INI
   /// read LOGFONT
   static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
                   LOGFONT *o_value, const tstring &i_defaultStringValue);
index 6d36976..80d89c4 100644 (file)
@@ -77,6 +77,7 @@ static bool getFilenameFromRegistry(
 void getHomeDirectories(HomeDirectories *o_pathes)
 {
   tstringi filename;
+#ifndef USE_INI
   if (getFilenameFromRegistry(NULL, &filename, NULL) &&
       !filename.empty())
   {
@@ -103,6 +104,9 @@ void getHomeDirectories(HomeDirectories *o_pathes)
   DWORD len = GetCurrentDirectory(NUMBER_OF(buf), buf);
   if (0 < len && len < NUMBER_OF(buf))
     o_pathes->push_back(buf);
+#else //USE_INI
+  _TCHAR buf[GANA_MAX_PATH];
+#endif //USE_INI
 
   if (GetModuleFileName(GetModuleHandle(NULL), buf, NUMBER_OF(buf)))
     o_pathes->push_back(pathRemoveFileSpec(buf));
@@ -694,6 +698,20 @@ void SettingLoader::load_ARGUMENT(long *o_arg)
 
 
 // &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(unsigned __int64 *o_arg)
+{
+  *o_arg = getToken()->getNumber();
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(__int64 *o_arg)
+{
+  *o_arg = getToken()->getNumber();
+}
+
+
+// &lt;ARGUMENT&gt;
 void SettingLoader::load_ARGUMENT(tstringq *o_arg)
 {
   *o_arg = getToken()->getString();
index a157fac..bc7d7af 100644 (file)
--- a/setting.h
+++ b/setting.h
@@ -130,6 +130,8 @@ private:
   void load_ARGUMENT(int *o_arg);              /// &lt;ARGUMENT&gt;
   void load_ARGUMENT(unsigned int *o_arg);     /// &lt;ARGUMENT&gt;
   void load_ARGUMENT(long *o_arg);             /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(unsigned __int64 *o_arg); /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(__int64 *o_arg);          /// &lt;ARGUMENT&gt;
   void load_ARGUMENT(tstringq *o_arg);         /// &lt;ARGUMENT&gt;
   void load_ARGUMENT(std::list<tstringq> *o_arg); /// &lt;ARGUMENT&gt;
   void load_ARGUMENT(tregex *o_arg);           /// &lt;ARGUMENT&gt;
index 250e023..882e23f 100644 (file)
@@ -10,6 +10,8 @@
 #  include <cctype>
 #  include <string>
 #  include <iosfwd>
+#  include <fstream>
+#  include <locale>
 #  include <boost/regex.hpp>
 #  include <stdio.h>                           // for snprintf
 
@@ -26,6 +28,8 @@ typedef std::basic_streambuf<_TCHAR> tstreambuf;
 typedef std::basic_stringstream<_TCHAR> tstringstream;
 /// ifstream for generic international text
 typedef std::basic_ifstream<_TCHAR> tifstream;
+/// ofstream for generic international text
+typedef std::basic_ofstream<_TCHAR> tofstream;
 /// basic_regex for generic international text
 typedef boost::basic_regex<_TCHAR> tregex;
 /// match_results for generic international text
diff --git a/vc.mak b/vc.mak
index b3fde55..f280d7b 100644 (file)
--- a/vc.mak
+++ b/vc.mak
@@ -17,10 +17,15 @@ TARGETOS    = WINNT
 !if "$(TARGETOS)" == "WINNT"
 APPVER         = 5.0
 !ifdef nodebug
-OUT_DIR                = out$(MAYU_VC)_winnt
+OUT_DIR_EXE    = out$(MAYU_VC)_winnt
 !else  # nodebug
-OUT_DIR                = out$(MAYU_VC)_winnt_debug
+OUT_DIR_EXE    = out$(MAYU_VC)_winnt_debug
 !endif # nodebug
+!ifdef X64
+OUT_DIR                = $(OUT_DIR_EXE)_x64
+!else
+OUT_DIR                = $(OUT_DIR_EXE)_x86
+!endif
 !endif # TARGETOS
 
 !if "$(TARGETOS)" == "WIN95"
@@ -41,23 +46,28 @@ OUT_DIR             = out$(MAYU_VC)_win9x_debug
 #NMAKE_WINVER  = 0x0500        # trick for WS_EX_LAYERED
 
 !ifdef nodebug
-DEBUG_FLAG     = $(cdebug)
-!else  # nodebug
 DEBUG_FLAG     =
+!else  # nodebug
+DEBUG_FLAG     = $(cdebug)
 !endif # nodebug
 
 {}.cpp{$(OUT_DIR)}.obj:
-       $(cc) -GX $(cflags) $(cvarsmt) $(DEFINES) $(INCLUDES) \
+       $(cc) -EHsc $(cflags) $(cvarsmt) $(DEFINES) $(INCLUDES) \
                $(DEBUG_FLAG) -Fo$@ $(*B).cpp
 {}.rc{$(OUT_DIR)}.res:
        $(rc) $(rcflags) $(rcvars) /fo$@ $(*B).rc
 
+!ifdef nodebug
 conxlibsmt     = $(conlibsmt) libcpmt.lib libcmt.lib
 guixlibsmt     = $(guilibsmt) libcpmt.lib libcmt.lib
+!else  # nodebug
+conxlibsmt     = $(conlibsmt) libcpmtd.lib libcmtd.lib
+guixlibsmt     = $(guilibsmt) libcpmtd.lib libcmtd.lib
+!endif # nodebug
 
 DEPENDFLAGS    = --cpp=vc --ignore='$(INCLUDE)' -p"$$(OUT_DIR)\\"      \
                --path-delimiter=dos --newline=unix                     \
-               $(DEPENDIGNORE) -GX $(cflags) $(cvarsmt)        \
+               $(DEPENDIGNORE) -EHsc $(cflags) $(cvarsmt)      \
                $(DEFINES) $(INCLUDES) $(DEBUG_FLAG)
 
 CLEAN          = $(OUT_DIR)\*.pdb
old mode 100644 (file)
new mode 100755 (executable)
index c96e4c7..1fe5915
@@ -129,12 +129,20 @@ HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)
 {
   while (i_hwnd)
   {
+#ifdef MAYU64
+    LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
+#else
     LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+#endif
     if ((style & WS_CHILD) == 0)
       break;
     if (io_isMDI && *io_isMDI)
     {
+#ifdef MAYU64
+      LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
+#else
       LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+#endif
       if (exStyle & WS_EX_MDICHILD)
        return i_hwnd;
     }
index f622c60..bb06975 100644 (file)
@@ -76,13 +76,21 @@ extern bool setForegroundWindow(HWND i_hwnd);
 /// get/set GWL_USERDATA
 template <class T> inline T getUserData(HWND i_hwnd, T *i_wc)
 {
+#ifdef MAYU64
+  return (*i_wc = reinterpret_cast<T>(GetWindowLongPtr(i_hwnd, GWLP_USERDATA)));
+#else
   return (*i_wc = reinterpret_cast<T>(GetWindowLong(i_hwnd, GWL_USERDATA)));
+#endif
 }
 
 ///
 template <class T> inline T setUserData(HWND i_hwnd, T i_wc)
 {
+#ifdef MAYU64
+  SetWindowLongPtr(i_hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(i_wc));
+#else
   SetWindowLong(i_hwnd, GWL_USERDATA, reinterpret_cast<long>(i_wc));
+#endif
   return i_wc;
 }