1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
5 #define APSTUDIO_INVOKED
\r
8 #include "compiler_specific_func.h"
\r
9 #include "dlginvestigate.h"
\r
11 #include "dlgsetting.h"
\r
12 #include "dlgversion.h"
\r
14 #include "errormessage.h"
\r
16 #include "function.h"
\r
19 #include "mayuipc.h"
\r
21 #include "msgstream.h"
\r
22 #include "multithread.h"
\r
23 #include "registry.h"
\r
24 #include "setting.h"
\r
26 #include "windowstool.h"
\r
27 #include "fixscancodemap.h"
\r
28 #include "vk2tchar.h"
\r
29 #include <process.h>
\r
31 #include <commctrl.h>
\r
32 #include <wtsapi32.h>
\r
37 #define ID_MENUITEM_reloadBegin _APS_NEXT_COMMAND_VALUE
\r
40 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
47 HWND m_hwndTaskTray; /// tasktray window
\r
48 HWND m_hwndLog; /// log dialog
\r
49 HWND m_hwndInvestigate; /// investigate dialog
\r
50 HWND m_hwndVersion; /// version dialog
\r
52 UINT m_WM_TaskbarRestart; /** window message sent when
\r
54 UINT m_WM_MayuIPC; /** IPC message sent from
\r
55 other applications */
\r
56 NOTIFYICONDATA m_ni; /// taskbar icon data
\r
57 HICON m_tasktrayIcon[2]; /// taskbar icon
\r
58 bool m_canUseTasktrayBaloon; ///
\r
60 tomsgstream m_log; /** log stream (output to log
\r
63 tofstream m_logFile;
\r
64 #endif // LOG_TO_FILE
\r
66 HMENU m_hMenuTaskTray; /// tasktray menu
\r
68 HANDLE m_hMutexYamyd;
\r
70 PROCESS_INFORMATION m_pi;
\r
73 HANDLE m_hNotifyMailslot; /// mailslot to receive notify
\r
74 HANDLE m_hNotifyEvent; /// event on receive notify
\r
75 OVERLAPPED m_olNotify; ///
\r
76 BYTE m_notifyBuf[NOTIFY_MESSAGE_SIZE];
\r
77 static const DWORD SESSION_LOCKED = 1<<0;
\r
78 static const DWORD SESSION_DISCONNECTED = 1<<1;
\r
79 static const DWORD SESSION_END_QUERIED = 1<<2;
\r
80 DWORD m_sessionState;
\r
81 int m_escapeNlsKeys;
\r
82 FixScancodeMap m_fixScancodeMap;
\r
84 Setting *m_setting; /// current setting
\r
85 bool m_isSettingDialogOpened; /// is setting dialog opened ?
\r
87 Engine m_engine; /// engine
\r
89 bool m_usingSN; /// using WTSRegisterSessionNotification() ?
\r
90 time_t m_startTime; /// mayu started at ...
\r
93 WM_APP_taskTrayNotify = WM_APP + 101, ///
\r
94 WM_APP_msgStreamNotify = WM_APP + 102, ///
\r
95 WM_APP_escapeNLSKeysFailed = WM_APP + 121, ///
\r
96 ID_TaskTrayIcon = 1, ///
\r
100 YAMY_TIMER_ESCAPE_NLS_KEYS = 0, ///
\r
104 static VOID CALLBACK mailslotProc(DWORD i_code, DWORD i_len, LPOVERLAPPED i_ol) {
\r
107 if (i_code == ERROR_SUCCESS) {
\r
108 pThis = reinterpret_cast<Mayu*>(CONTAINING_RECORD(i_ol, Mayu, m_olNotify));
\r
109 pThis->mailslotHandler(i_code, i_len);
\r
114 BOOL mailslotHandler(DWORD i_code, DWORD i_len) {
\r
120 cd.dwData = reinterpret_cast<Notify *>(m_notifyBuf)->m_type;
\r
122 cd.lpData = m_notifyBuf;
\r
123 notifyHandler(&cd);
\r
126 memset(m_notifyBuf, 0, sizeof(m_notifyBuf));
\r
127 result = ReadFileEx(m_hNotifyMailslot, m_notifyBuf, sizeof(m_notifyBuf),
\r
128 &m_olNotify, Mayu::mailslotProc);
\r
132 /// register class for tasktray
\r
133 ATOM Register_tasktray() {
\r
136 wc.lpfnWndProc = tasktray_wndProc;
\r
138 wc.cbWndExtra = sizeof(Mayu *);
\r
139 wc.hInstance = g_hInst;
\r
142 wc.hbrBackground = NULL;
\r
143 wc.lpszMenuName = NULL;
\r
144 wc.lpszClassName = _T("mayuTasktray");
\r
145 return RegisterClass(&wc);
\r
149 BOOL notifyHandler(COPYDATASTRUCT *cd) {
\r
150 switch (cd->dwData) {
\r
151 case Notify::Type_setFocus:
\r
152 case Notify::Type_name: {
\r
153 NotifySetFocus *n = (NotifySetFocus *)cd->lpData;
\r
154 n->m_className[NUMBER_OF(n->m_className) - 1] = _T('\0');
\r
155 n->m_titleName[NUMBER_OF(n->m_titleName) - 1] = _T('\0');
\r
157 if (n->m_type == Notify::Type_setFocus)
\r
158 m_engine.setFocus(reinterpret_cast<HWND>(n->m_hwnd), n->m_threadId,
\r
159 n->m_className, n->m_titleName, false);
\r
162 Acquire a(&m_log, 1);
\r
163 m_log << _T("HWND:\t") << std::hex
\r
165 << std::dec << std::endl;
\r
166 m_log << _T("THREADID:") << static_cast<int>(n->m_threadId)
\r
169 Acquire a(&m_log, (n->m_type == Notify::Type_name) ? 0 : 1);
\r
170 m_log << _T("CLASS:\t") << n->m_className << std::endl;
\r
171 m_log << _T("TITLE:\t") << n->m_titleName << std::endl;
\r
174 HWND hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), &isMDI);
\r
177 getChildWindowRect(hwnd, &rc);
\r
178 m_log << _T("MDI Window Position/Size: (")
\r
179 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
180 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
182 hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), NULL);
\r
185 GetWindowRect(hwnd, &rc);
\r
186 m_log << _T("Toplevel Window Position/Size: (")
\r
187 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
188 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
191 SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
\r
192 m_log << _T("Desktop Window Position/Size: (")
\r
193 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
194 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
197 m_log << std::endl;
\r
201 case Notify::Type_lockState: {
\r
202 NotifyLockState *n = (NotifyLockState *)cd->lpData;
\r
203 m_engine.setLockState(n->m_isNumLockToggled,
\r
204 n->m_isCapsLockToggled,
\r
205 n->m_isScrollLockToggled,
\r
206 n->m_isKanaLockToggled,
\r
207 n->m_isImeLockToggled,
\r
208 n->m_isImeCompToggled);
\r
210 Acquire a(&m_log, 0);
\r
211 if (n->m_isKanaLockToggled) {
\r
212 m_log << _T("Notify::Type_lockState Kana on : ");
\r
214 m_log << _T("Notify::Type_lockState Kana off : ");
\r
216 m_log << n->m_debugParam << ", "
\r
217 << g_hookData->m_correctKanaLockHandling << std::endl;
\r
222 case Notify::Type_sync: {
\r
223 m_engine.syncNotify();
\r
227 case Notify::Type_threadAttach: {
\r
228 NotifyThreadAttach *n = (NotifyThreadAttach *)cd->lpData;
\r
229 m_engine.threadAttachNotify(n->m_threadId);
\r
233 case Notify::Type_threadDetach: {
\r
234 NotifyThreadDetach *n = (NotifyThreadDetach *)cd->lpData;
\r
235 m_engine.threadDetachNotify(n->m_threadId);
\r
239 case Notify::Type_command64: {
\r
240 NotifyCommand64 *n = (NotifyCommand64 *)cd->lpData;
\r
241 m_engine.commandNotify(n->m_hwnd, n->m_message,
\r
242 n->m_wParam, n->m_lParam);
\r
246 case Notify::Type_command32: {
\r
247 NotifyCommand32 *n = (NotifyCommand32 *)cd->lpData;
\r
248 m_engine.commandNotify(n->m_hwnd, n->m_message,
\r
249 n->m_wParam, n->m_lParam);
\r
253 case Notify::Type_show: {
\r
254 NotifyShow *n = (NotifyShow *)cd->lpData;
\r
255 switch (n->m_show) {
\r
256 case NotifyShow::Show_Maximized:
\r
257 m_engine.setShow(true, false, n->m_isMDI);
\r
259 case NotifyShow::Show_Minimized:
\r
260 m_engine.setShow(false, true, n->m_isMDI);
\r
262 case NotifyShow::Show_Normal:
\r
264 m_engine.setShow(false, false, n->m_isMDI);
\r
270 case Notify::Type_log: {
\r
271 Acquire a(&m_log, 1);
\r
272 NotifyLog *n = (NotifyLog *)cd->lpData;
\r
273 m_log << _T("hook log: ") << n->m_msg << std::endl;
\r
280 /// window procedure for tasktray
\r
281 static LRESULT CALLBACK
\r
282 tasktray_wndProc(HWND i_hwnd, UINT i_message,
\r
283 WPARAM i_wParam, LPARAM i_lParam) {
\r
285 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLongPtr(i_hwnd, 0));
\r
287 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLong(i_hwnd, 0));
\r
291 switch (i_message) {
\r
293 This = reinterpret_cast<Mayu *>(
\r
294 reinterpret_cast<CREATESTRUCT *>(i_lParam)->lpCreateParams);
\r
295 This->m_fixScancodeMap.init(i_hwnd, WM_APP_escapeNLSKeysFailed);
\r
296 if (This->m_escapeNlsKeys) {
\r
297 This->m_fixScancodeMap.escape(true);
\r
300 SetWindowLongPtr(i_hwnd, 0, (LONG_PTR)This);
\r
302 SetWindowLong(i_hwnd, 0, (long)This);
\r
307 switch (i_message) {
\r
308 case WM_COPYDATA: {
\r
309 COPYDATASTRUCT *cd;
\r
310 cd = reinterpret_cast<COPYDATASTRUCT *>(i_lParam);
\r
311 return This->notifyHandler(cd);
\r
313 case WM_QUERYENDSESSION:
\r
314 if (!This->m_sessionState) {
\r
315 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
316 This->m_fixScancodeMap.escape(false);
\r
319 This->m_sessionState |= Mayu::SESSION_END_QUERIED;
\r
320 This->m_engine.prepairQuit();
\r
321 PostQuitMessage(0);
\r
324 #ifndef WM_WTSSESSION_CHANGE // WinUser.h
\r
325 # define WM_WTSSESSION_CHANGE 0x02B1
\r
327 case WM_WTSSESSION_CHANGE: {
\r
328 const char *m = "";
\r
329 switch (i_wParam) {
\r
330 #ifndef WTS_CONSOLE_CONNECT // WinUser.h
\r
331 # define WTS_CONSOLE_CONNECT 0x1
\r
332 # define WTS_CONSOLE_DISCONNECT 0x2
\r
333 # define WTS_REMOTE_CONNECT 0x3
\r
334 # define WTS_REMOTE_DISCONNECT 0x4
\r
335 # define WTS_SESSION_LOGON 0x5
\r
336 # define WTS_SESSION_LOGOFF 0x6
\r
337 # define WTS_SESSION_LOCK 0x7
\r
338 # define WTS_SESSION_UNLOCK 0x8
\r
341 restore NLS keys when any bits of m_sessionState is on
\r
343 escape NLS keys when all bits of m_sessionState cleared
\r
345 case WTS_CONSOLE_CONNECT:
\r
346 This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;
\r
347 if (!This->m_sessionState) {
\r
348 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
349 This->m_fixScancodeMap.escape(true);
\r
352 m = "WTS_CONSOLE_CONNECT";
\r
354 case WTS_CONSOLE_DISCONNECT:
\r
355 if (!This->m_sessionState) {
\r
356 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
357 This->m_fixScancodeMap.escape(false);
\r
360 This->m_sessionState |= Mayu::SESSION_DISCONNECTED;
\r
361 m = "WTS_CONSOLE_DISCONNECT";
\r
363 case WTS_REMOTE_CONNECT:
\r
364 This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;
\r
365 if (!This->m_sessionState) {
\r
366 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
367 This->m_fixScancodeMap.escape(true);
\r
370 m = "WTS_REMOTE_CONNECT";
\r
372 case WTS_REMOTE_DISCONNECT:
\r
373 if (!This->m_sessionState) {
\r
374 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
375 This->m_fixScancodeMap.escape(false);
\r
378 This->m_sessionState |= Mayu::SESSION_DISCONNECTED;
\r
379 m = "WTS_REMOTE_DISCONNECT";
\r
381 case WTS_SESSION_LOGON:
\r
382 m = "WTS_SESSION_LOGON";
\r
384 case WTS_SESSION_LOGOFF:
\r
385 m = "WTS_SESSION_LOGOFF";
\r
387 case WTS_SESSION_LOCK: {
\r
388 if (!This->m_sessionState) {
\r
389 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
390 This->m_fixScancodeMap.escape(false);
\r
393 This->m_sessionState |= Mayu::SESSION_LOCKED;
\r
394 m = "WTS_SESSION_LOCK";
\r
397 case WTS_SESSION_UNLOCK: {
\r
398 This->m_sessionState &= ~Mayu::SESSION_LOCKED;
\r
399 if (!This->m_sessionState) {
\r
400 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
401 This->m_fixScancodeMap.escape(true);
\r
404 m = "WTS_SESSION_UNLOCK";
\r
407 //case WTS_SESSION_REMOTE_CONTROL: m = "WTS_SESSION_REMOTE_CONTROL"; break;
\r
409 This->m_log << _T("WM_WTSESSION_CHANGE(")
\r
410 << i_wParam << ", " << i_lParam << "): "
\r
414 case WM_APP_msgStreamNotify: {
\r
415 tomsgstream::StreamBuf *log =
\r
416 reinterpret_cast<tomsgstream::StreamBuf *>(i_lParam);
\r
417 const tstring &str = log->acquireString();
\r
419 This->m_logFile << str << std::flush;
\r
420 #endif // LOG_TO_FILE
\r
421 editInsertTextAtLast(GetDlgItem(This->m_hwndLog, IDC_EDIT_log),
\r
423 log->releaseString();
\r
427 case WM_APP_taskTrayNotify: {
\r
428 if (i_wParam == ID_TaskTrayIcon)
\r
429 switch (i_lParam) {
\r
430 case WM_RBUTTONUP: {
\r
432 CHECK_TRUE( GetCursorPos(&p) );
\r
433 SetForegroundWindow(i_hwnd);
\r
434 HMENU hMenuSub = GetSubMenu(This->m_hMenuTaskTray, 0);
\r
435 if (This->m_engine.getIsEnabled())
\r
436 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
437 MF_UNCHECKED | MF_BYCOMMAND);
\r
439 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
440 MF_CHECKED | MF_BYCOMMAND);
\r
441 CHECK_TRUE( SetMenuDefaultItem(hMenuSub,
\r
442 ID_MENUITEM_investigate, FALSE) );
\r
444 // create reload menu
\r
445 HMENU hMenuSubSub = GetSubMenu(hMenuSub, 1);
\r
446 Registry reg(MAYU_REGISTRY_ROOT);
\r
448 reg.read(_T(".mayuIndex"), &mayuIndex, 0);
\r
449 while (DeleteMenu(hMenuSubSub, 0, MF_BYPOSITION))
\r
451 tregex getName(_T("^([^;]*);"));
\r
452 for (int index = 0; ; index ++) {
\r
454 _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
\r
456 if (!reg.read(buf, &dot_mayu))
\r
459 if (boost::regex_search(dot_mayu, what, getName)) {
\r
461 std::memset(&mii, 0, sizeof(mii));
\r
462 mii.cbSize = sizeof(mii);
\r
463 mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
\r
464 mii.fType = MFT_STRING;
\r
466 MFS_ENABLED | ((mayuIndex == index) ? MFS_CHECKED : 0);
\r
467 mii.wID = ID_MENUITEM_reloadBegin + index;
\r
468 tstringi name(what.str(1));
\r
469 mii.dwTypeData = const_cast<_TCHAR *>(name.c_str());
\r
470 mii.cch = name.size();
\r
472 InsertMenuItem(hMenuSubSub, index, TRUE, &mii);
\r
477 TrackPopupMenu(hMenuSub, TPM_LEFTALIGN,
\r
478 p.x, p.y, 0, i_hwnd, NULL);
\r
479 // TrackPopupMenu may fail (ERROR_POPUP_ALREADY_ACTIVE)
\r
483 case WM_LBUTTONDBLCLK:
\r
484 SendMessage(i_hwnd, WM_COMMAND,
\r
485 MAKELONG(ID_MENUITEM_investigate, 0), 0);
\r
491 case WM_APP_escapeNLSKeysFailed:
\r
495 This->m_log << _T("escape NLS keys done code=") << i_wParam << std::endl;
\r
496 switch (i_wParam) {
\r
498 case YAMY_ERROR_RETRY_INJECTION_SUCCESS:
\r
499 // escape NLS keys success
\r
501 case YAMY_ERROR_TIMEOUT_INJECTION:
\r
502 ret = This->errorDialogWithCode(IDS_escapeNlsKeysRetry, i_wParam, MB_RETRYCANCEL | MB_ICONSTOP);
\r
503 if (ret == IDRETRY) {
\r
504 This->m_fixScancodeMap.escape(true);
\r
508 This->errorDialogWithCode(IDS_escapeNlsKeysFailed, i_wParam, MB_OK);
\r
512 This->m_log << _T("restore NLS keys done with code=") << i_wParam << std::endl;
\r
518 int notify_code = HIWORD(i_wParam);
\r
519 int id = LOWORD(i_wParam);
\r
520 if (notify_code == 0) // menu
\r
523 if (ID_MENUITEM_reloadBegin <= id) {
\r
524 Registry reg(MAYU_REGISTRY_ROOT);
\r
525 reg.write(_T(".mayuIndex"), id - ID_MENUITEM_reloadBegin);
\r
529 case ID_MENUITEM_reload:
\r
532 case ID_MENUITEM_investigate: {
\r
533 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
534 ShowWindow(This->m_hwndInvestigate, SW_SHOW);
\r
537 GetWindowRect(This->m_hwndInvestigate, &rc1);
\r
538 GetWindowRect(This->m_hwndLog, &rc2);
\r
540 MoveWindow(This->m_hwndLog, rc1.left, rc1.bottom,
\r
541 rcWidth(&rc1), rcHeight(&rc2), TRUE);
\r
543 SetForegroundWindow(This->m_hwndLog);
\r
544 SetForegroundWindow(This->m_hwndInvestigate);
\r
547 case ID_MENUITEM_setting:
\r
548 if (!This->m_isSettingDialogOpened) {
\r
549 This->m_isSettingDialogOpened = true;
\r
550 if (DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_setting),
\r
551 NULL, dlgSetting_dlgProc))
\r
553 This->m_isSettingDialogOpened = false;
\r
556 case ID_MENUITEM_log:
\r
557 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
558 SetForegroundWindow(This->m_hwndLog);
\r
560 case ID_MENUITEM_check: {
\r
563 ret = GetKeyboardState(keys);
\r
565 This->m_log << _T("Check Keystate Failed(%d)")
\r
566 << GetLastError() << std::endl;
\r
568 This->m_log << _T("Check Keystate: ") << std::endl;
\r
569 for (int i = 0; i < 0xff; i++) {
\r
571 asyncKey = GetAsyncKeyState(i);
\r
572 This->m_log << std::hex;
\r
573 if (asyncKey & 0x8000) {
\r
574 This->m_log << _T(" ") << VK2TCHAR[i]
\r
575 << _T("(0x") << i << _T("): pressed!")
\r
578 if (i == 0x14 || // VK_CAPTITAL
\r
579 i == 0x15 || // VK_KANA
\r
580 i == 0x19 || // VK_KANJI
\r
581 i == 0x90 || // VK_NUMLOCK
\r
582 i == 0x91 // VK_SCROLL
\r
585 This->m_log << _T(" ") << VK2TCHAR[i]
\r
586 << _T("(0x") << i << _T("): locked!")
\r
590 This->m_log << std::dec;
\r
592 This->m_log << std::endl;
\r
596 case ID_MENUITEM_version:
\r
597 ShowWindow(This->m_hwndVersion, SW_SHOW);
\r
598 SetForegroundWindow(This->m_hwndVersion);
\r
600 case ID_MENUITEM_help: {
\r
601 _TCHAR buf[GANA_MAX_PATH];
\r
602 CHECK_TRUE( GetModuleFileName(g_hInst, buf, NUMBER_OF(buf)) );
\r
603 tstringi helpFilename = pathRemoveFileSpec(buf);
\r
604 helpFilename += _T("\\");
\r
605 helpFilename += loadString(IDS_helpFilename);
\r
606 ShellExecute(NULL, _T("open"), helpFilename.c_str(),
\r
607 NULL, NULL, SW_SHOWNORMAL);
\r
610 case ID_MENUITEM_disable:
\r
611 This->m_engine.enable(!This->m_engine.getIsEnabled());
\r
612 if (This->m_engine.getIsEnabled()) {
\r
613 This->m_fixScancodeMap.escape(true);
\r
615 This->m_fixScancodeMap.escape(false);
\r
617 This->showTasktrayIcon();
\r
619 case ID_MENUITEM_quit:
\r
620 This->m_engine.prepairQuit();
\r
621 PostQuitMessage(0);
\r
627 case WM_APP_engineNotify: {
\r
628 switch (i_wParam) {
\r
629 case EngineNotify_shellExecute:
\r
630 This->m_engine.shellExecute();
\r
632 case EngineNotify_loadSetting:
\r
635 case EngineNotify_helpMessage:
\r
636 This->showHelpMessage(false);
\r
638 This->showHelpMessage(true);
\r
640 case EngineNotify_showDlg: {
\r
641 // show investigate/log window
\r
642 int sw = (i_lParam & ~MayuDialogType_mask);
\r
644 switch (static_cast<MayuDialogType>(
\r
645 i_lParam & MayuDialogType_mask)) {
\r
646 case MayuDialogType_investigate:
\r
647 hwnd = This->m_hwndInvestigate;
\r
649 case MayuDialogType_log:
\r
650 hwnd = This->m_hwndLog;
\r
654 ShowWindow(hwnd, sw);
\r
656 case SW_SHOWNORMAL:
\r
657 case SW_SHOWMAXIMIZED:
\r
660 case SW_SHOWDEFAULT:
\r
661 SetForegroundWindow(hwnd);
\r
667 case EngineNotify_setForegroundWindow:
\r
668 // FIXME: completely useless. why ?
\r
669 setForegroundWindow(reinterpret_cast<HWND>(i_lParam));
\r
671 Acquire a(&This->m_log, 1);
\r
672 This->m_log << _T("setForegroundWindow(0x")
\r
673 << std::hex << i_lParam << std::dec << _T(")")
\r
677 case EngineNotify_clearLog:
\r
678 SendMessage(This->m_hwndLog, WM_COMMAND,
\r
679 MAKELONG(IDC_BUTTON_clearLog, 0), 0);
\r
687 case WM_APP_dlglogNotify: {
\r
688 switch (i_wParam) {
\r
689 case DlgLogNotify_logCleared:
\r
690 This->showBanner(true);
\r
699 if (This->m_usingSN) {
\r
700 wtsUnRegisterSessionNotification(i_hwnd);
\r
701 This->m_usingSN = false;
\r
703 if (!This->m_sessionState) {
\r
704 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
705 This->m_fixScancodeMap.escape(false);
\r
711 if (i_message == This->m_WM_TaskbarRestart) {
\r
712 if (This->showTasktrayIcon(true)) {
\r
713 Acquire a(&This->m_log, 0);
\r
714 This->m_log << _T("Tasktray icon is updated.") << std::endl;
\r
716 Acquire a(&This->m_log, 1);
\r
717 This->m_log << _T("Tasktray icon already exists.") << std::endl;
\r
720 } else if (i_message == This->m_WM_MayuIPC) {
\r
721 switch (static_cast<MayuIPCCommand>(i_wParam)) {
\r
722 case MayuIPCCommand_Enable:
\r
723 This->m_engine.enable(!!i_lParam);
\r
724 if (This->m_engine.getIsEnabled()) {
\r
725 This->m_fixScancodeMap.escape(true);
\r
727 This->m_fixScancodeMap.escape(false);
\r
729 This->showTasktrayIcon();
\r
731 Acquire a(&This->m_log, 1);
\r
732 This->m_log << _T("Enabled by another application.")
\r
735 Acquire a(&This->m_log, 1);
\r
736 This->m_log << _T("Disabled by another application.")
\r
743 return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
\r
748 Setting *newSetting = new Setting;
\r
751 for (int i = 1; i < __argc; ++ i) {
\r
752 if (__targv[i][0] == _T('-') && __targv[i][1] == _T('D'))
\r
753 newSetting->m_symbols.insert(__targv[i] + 2);
\r
756 if (!SettingLoader(&m_log, &m_log).load(newSetting)) {
\r
757 ShowWindow(m_hwndLog, SW_SHOW);
\r
758 SetForegroundWindow(m_hwndLog);
\r
760 Acquire a(&m_log, 0);
\r
761 m_log << _T("error: failed to load.") << std::endl;
\r
764 m_log << _T("successfully loaded.") << std::endl;
\r
765 while (!m_engine.setSetting(newSetting))
\r
768 m_setting = newSetting;
\r
771 // show message (a baloon from the task tray icon)
\r
772 void showHelpMessage(bool i_doesShow = true) {
\r
773 if (m_canUseTasktrayBaloon) {
\r
775 tstring helpMessage, helpTitle;
\r
776 m_engine.getHelpMessages(&helpMessage, &helpTitle);
\r
777 tcslcpy(m_ni.szInfo, helpMessage.c_str(), NUMBER_OF(m_ni.szInfo));
\r
778 tcslcpy(m_ni.szInfoTitle, helpTitle.c_str(),
\r
779 NUMBER_OF(m_ni.szInfoTitle));
\r
780 m_ni.dwInfoFlags = NIIF_INFO;
\r
782 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
783 CHECK_TRUE( Shell_NotifyIcon(NIM_MODIFY, &m_ni) );
\r
787 // change the task tray icon
\r
788 bool showTasktrayIcon(bool i_doesAdd = false) {
\r
789 m_ni.hIcon = m_tasktrayIcon[m_engine.getIsEnabled() ? 1 : 0];
\r
790 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
792 // http://support.microsoft.com/kb/418138/JA/
\r
794 for (; !Shell_NotifyIcon(NIM_ADD, &m_ni) && 0 < guard; -- guard) {
\r
795 if (Shell_NotifyIcon(NIM_MODIFY, &m_ni)) {
\r
798 Sleep(1000); // 1sec
\r
802 return !!Shell_NotifyIcon(NIM_MODIFY, &m_ni);
\r
806 void showBanner(bool i_isCleared) {
\r
810 _TCHAR starttimebuf[1024];
\r
811 _TCHAR timebuf[1024];
\r
813 #ifdef __BORLANDC__
\r
814 #pragma message("\t\t****\tAfter std::ostream() is called, ")
\r
815 #pragma message("\t\t****\tstrftime(... \"%%#c\" ...) fails.")
\r
816 #pragma message("\t\t****\tWhy ? Bug of Borland C++ 5.5.1 ? ")
\r
817 #pragma message("\t\t****\t - nayuta")
\r
818 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
820 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
821 localtime(&m_startTime));
\r
823 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%#c"), localtime(&now));
\r
824 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%#c"),
\r
825 localtime(&m_startTime));
\r
828 Acquire a(&m_log, 0);
\r
829 m_log << _T("------------------------------------------------------------") << std::endl;
\r
830 m_log << loadString(IDS_mayu) << _T(" ") _T(VERSION);
\r
832 m_log << _T(" (DEBUG)");
\r
835 m_log << _T(" (UNICODE)");
\r
837 m_log << std::endl;
\r
838 m_log << _T(" built by ")
\r
839 << _T(LOGNAME) << _T("@") << toLower(_T(COMPUTERNAME))
\r
840 << _T(" (") << _T(__DATE__) << _T(" ")
\r
841 << _T(__TIME__) << _T(", ")
\r
842 << getCompilerVersionString() << _T(")") << std::endl;
\r
843 _TCHAR modulebuf[1024];
\r
844 CHECK_TRUE( GetModuleFileName(g_hInst, modulebuf,
\r
845 NUMBER_OF(modulebuf)) );
\r
846 m_log << _T("started at ") << starttimebuf << std::endl;
\r
847 m_log << modulebuf << std::endl;
\r
848 m_log << _T("------------------------------------------------------------") << std::endl;
\r
851 m_log << _T("log was cleared at ") << timebuf << std::endl;
\r
853 m_log << _T("log begins at ") << timebuf << std::endl;
\r
857 int errorDialogWithCode(UINT ids, int code, UINT style = MB_OK | MB_ICONSTOP)
\r
859 _TCHAR title[1024];
\r
862 _sntprintf_s(title, NUMBER_OF(title), _TRUNCATE, loadString(IDS_mayu).c_str());
\r
863 _sntprintf_s(text, NUMBER_OF(text), _TRUNCATE, loadString(ids).c_str(), code);
\r
864 return MessageBox((HWND)NULL, text, title, style);
\r
867 int enableToWriteByUser(HANDLE hdl)
\r
869 TCHAR userName[GANA_MAX_ATOM_LENGTH];
\r
870 DWORD userNameSize = NUMBER_OF(userName);
\r
872 SID_NAME_USE sidType;
\r
875 TCHAR *pDomain = NULL;
\r
876 DWORD domainSize = 0;
\r
878 PSECURITY_DESCRIPTOR pSd;
\r
880 ACL_SIZE_INFORMATION aclInfo;
\r
886 DWORD newAceIndex = 0;
\r
891 ret = GetUserName(userName, &userNameSize);
\r
892 if (ret == FALSE) {
\r
893 err = YAMY_ERROR_ON_GET_USERNAME;
\r
897 // get buffer size for pSid (and pDomain)
\r
898 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
899 if (ret != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
\r
900 // above call should fail by ERROR_INSUFFICIENT_BUFFER
\r
901 err = YAMY_ERROR_ON_GET_LOGONUSERNAME;
\r
905 pSid = reinterpret_cast<PSID>(LocalAlloc(LPTR, sidSize));
\r
906 pDomain = reinterpret_cast<TCHAR*>(LocalAlloc(LPTR, domainSize * sizeof(TCHAR)));
\r
907 if (pSid == NULL || pDomain == NULL) {
\r
908 err = YAMY_ERROR_NO_MEMORY;
\r
912 // get SID (and Domain) for logoned user
\r
913 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
914 if (ret == FALSE) {
\r
915 // LookupAccountName() should success in this time
\r
916 err = YAMY_ERROR_ON_GET_LOGONUSERNAME;
\r
920 // get DACL for hdl
\r
921 ret = GetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOrigDacl, NULL, &pSd);
\r
922 if (ret != ERROR_SUCCESS) {
\r
923 err = YAMY_ERROR_ON_GET_SECURITYINFO;
\r
927 // get size for original DACL
\r
928 ret = GetAclInformation(pOrigDacl, &aclInfo, sizeof(aclInfo), AclSizeInformation);
\r
929 if (ret == FALSE) {
\r
930 err = YAMY_ERROR_ON_GET_DACL;
\r
934 // compute size for new DACL
\r
935 newDaclSize = aclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pSid) - sizeof(DWORD);
\r
937 // allocate memory for new DACL
\r
938 pNewDacl = reinterpret_cast<PACL>(LocalAlloc(LPTR, newDaclSize));
\r
939 if (pNewDacl == NULL) {
\r
940 err = YAMY_ERROR_NO_MEMORY;
\r
944 // initialize new DACL
\r
945 ret = InitializeAcl(pNewDacl, newDaclSize, ACL_REVISION);
\r
946 if (ret == FALSE) {
\r
947 err = YAMY_ERROR_ON_INITIALIZE_ACL;
\r
951 // copy original DACL to new DACL
\r
952 for (aceIndex = 0; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
955 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
956 if (ret == FALSE) {
\r
957 err = YAMY_ERROR_ON_GET_ACE;
\r
961 if ((reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->Header.AceFlags & INHERITED_ACE) {
\r
965 if (EqualSid(pSid, &(reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->SidStart) != FALSE) {
\r
969 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
970 if (ret == FALSE) {
\r
971 err = YAMY_ERROR_ON_ADD_ACE;
\r
978 ret = AddAccessAllowedAce(pNewDacl, ACL_REVISION, GENERIC_ALL, pSid);
\r
979 if (ret == FALSE) {
\r
980 err = YAMY_ERROR_ON_ADD_ALLOWED_ACE;
\r
984 // copy the rest of inherited ACEs
\r
985 for (; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
988 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
989 if (ret == FALSE) {
\r
990 err = YAMY_ERROR_ON_GET_ACE;
\r
994 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
995 if (ret == FALSE) {
\r
996 err = YAMY_ERROR_ON_ADD_ACE;
\r
1001 ret = SetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);
\r
1002 if (ret != ERROR_SUCCESS) {
\r
1003 err = YAMY_ERROR_ON_SET_SECURITYINFO;
\r
1009 LocalFree(pDomain);
\r
1010 LocalFree(pNewDacl);
\r
1017 Mayu(HANDLE i_mutex)
\r
1018 : m_hwndTaskTray(NULL),
\r
1021 m_WM_TaskbarRestart(RegisterWindowMessage(_T("TaskbarCreated"))),
\r
1022 m_WM_MayuIPC(RegisterWindowMessage(WM_MayuIPC_NAME)),
\r
1023 m_canUseTasktrayBaloon(
\r
1024 PACKVERSION(5, 0) <= getDllVersion(_T("shlwapi.dll"))),
\r
1025 m_log(WM_APP_msgStreamNotify),
\r
1027 m_isSettingDialogOpened(false),
\r
1028 m_sessionState(0),
\r
1030 Registry reg(MAYU_REGISTRY_ROOT);
\r
1031 reg.read(_T("escapeNLSKeys"), &m_escapeNlsKeys, 0);
\r
1032 m_hNotifyMailslot = CreateMailslot(NOTIFY_MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, (SECURITY_ATTRIBUTES *)NULL);
\r
1033 ASSERT(m_hNotifyMailslot != INVALID_HANDLE_VALUE);
\r
1035 if (checkWindowsVersion(6, 0) != FALSE) { // enableToWriteByUser() is available only Vista or later
\r
1036 err = enableToWriteByUser(m_hNotifyMailslot);
\r
1038 errorDialogWithCode(IDS_cannotPermitStandardUser, err);
\r
1042 m_hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
\r
1043 ASSERT(m_hNotifyEvent);
\r
1044 m_olNotify.Offset = 0;
\r
1045 m_olNotify.OffsetHigh = 0;
\r
1046 m_olNotify.hEvent = m_hNotifyEvent;
\r
1047 time(&m_startTime);
\r
1049 CHECK_TRUE( Register_focus() );
\r
1050 CHECK_TRUE( Register_target() );
\r
1051 CHECK_TRUE( Register_tasktray() );
\r
1055 HomeDirectories pathes;
\r
1056 getHomeDirectories(&pathes);
\r
1057 for (HomeDirectories::iterator i = pathes.begin(); i != pathes.end(); ++ i)
\r
1058 if (SetCurrentDirectory(i->c_str()))
\r
1062 // create windows, dialogs
\r
1063 tstringi title = loadString(IDS_mayu);
\r
1064 m_hwndTaskTray = CreateWindow(_T("mayuTasktray"), title.c_str(),
\r
1065 WS_OVERLAPPEDWINDOW,
\r
1066 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1067 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1068 NULL, NULL, g_hInst, this);
\r
1069 CHECK_TRUE( m_hwndTaskTray );
\r
1071 // set window handle of tasktray to hooks
\r
1072 CHECK_FALSE( installMessageHook(reinterpret_cast<DWORD>(m_hwndTaskTray)) );
\r
1073 m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray,
\r
1074 NOTIFY_FOR_THIS_SESSION);
\r
1077 dld.m_log = &m_log;
\r
1078 dld.m_hwndTaskTray = m_hwndTaskTray;
\r
1080 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_log), NULL,
\r
1081 dlgLog_dlgProc, (LPARAM)&dld);
\r
1082 CHECK_TRUE( m_hwndLog );
\r
1084 DlgInvestigateData did;
\r
1085 did.m_engine = &m_engine;
\r
1086 did.m_hwndLog = m_hwndLog;
\r
1087 m_hwndInvestigate =
\r
1088 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_investigate), NULL,
\r
1089 dlgInvestigate_dlgProc, (LPARAM)&did);
\r
1090 CHECK_TRUE( m_hwndInvestigate );
\r
1093 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_version),
\r
1094 NULL, dlgVersion_dlgProc,
\r
1096 CHECK_TRUE( m_hwndVersion );
\r
1099 #ifdef LOG_TO_FILE
\r
1101 _TCHAR exePath[GANA_MAX_PATH];
\r
1102 _TCHAR exeDrive[GANA_MAX_PATH];
\r
1103 _TCHAR exeDir[GANA_MAX_PATH];
\r
1104 GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
\r
1105 _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
\r
1108 path += _T("mayu.log");
\r
1109 m_logFile.open(path.c_str(), std::ios::app);
\r
1110 m_logFile.imbue(std::locale("japanese"));
\r
1111 #endif // LOG_TO_FILE
\r
1112 SendMessage(GetDlgItem(m_hwndLog, IDC_EDIT_log), EM_SETLIMITTEXT, 0, 0);
\r
1113 m_log.attach(m_hwndTaskTray);
\r
1115 // start keyboard handler thread
\r
1116 m_engine.setAssociatedWndow(m_hwndTaskTray);
\r
1119 // show tasktray icon
\r
1120 m_tasktrayIcon[0] = loadSmallIcon(IDI_ICON_mayu_disabled);
\r
1121 m_tasktrayIcon[1] = loadSmallIcon(IDI_ICON_mayu);
\r
1122 std::memset(&m_ni, 0, sizeof(m_ni));
\r
1123 m_ni.uID = ID_TaskTrayIcon;
\r
1124 m_ni.hWnd = m_hwndTaskTray;
\r
1125 m_ni.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
\r
1126 m_ni.hIcon = m_tasktrayIcon[1];
\r
1127 m_ni.uCallbackMessage = WM_APP_taskTrayNotify;
\r
1128 tstring tip = loadString(IDS_mayu);
\r
1129 tcslcpy(m_ni.szTip, tip.c_str(), NUMBER_OF(m_ni.szTip));
\r
1130 if (m_canUseTasktrayBaloon) {
\r
1131 m_ni.cbSize = NOTIFYICONDATA_V3_SIZE;
\r
1132 m_ni.uFlags |= NIF_INFO;
\r
1134 m_ni.cbSize = NOTIFYICONDATA_V1_SIZE;
\r
1135 showTasktrayIcon(true);
\r
1138 m_hMenuTaskTray = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU_tasktray));
\r
1139 ASSERT(m_hMenuTaskTray);
\r
1141 // set initial lock state
\r
1142 notifyLockState();
\r
1145 ZeroMemory(&m_pi,sizeof(m_pi));
\r
1146 ZeroMemory(&m_si,sizeof(m_si));
\r
1147 m_si.cb=sizeof(m_si);
\r
1149 // create mutex to block yamyd
\r
1150 m_hMutexYamyd = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE, MUTEX_YAMYD_BLOCKER);
\r
1152 tstring yamydPath;
\r
1153 _TCHAR exePath[GANA_MAX_PATH];
\r
1154 _TCHAR exeDrive[GANA_MAX_PATH];
\r
1155 _TCHAR exeDir[GANA_MAX_PATH];
\r
1157 GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
\r
1158 _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
\r
1159 yamydPath = exeDrive;
\r
1160 yamydPath += exeDir;
\r
1161 yamydPath += _T("yamyd32");
\r
1163 BOOL result = CreateProcess(yamydPath.c_str(), NULL, NULL, NULL, FALSE,
\r
1164 NORMAL_PRIORITY_CLASS, 0, NULL, &m_si, &m_pi);
\r
1165 if (result == FALSE) {
\r
1168 TCHAR title[1024];
\r
1170 m_pi.hProcess = NULL;
\r
1171 LoadString(GetModuleHandle(NULL), IDS_cannotInvoke,
\r
1172 text, sizeof(text)/sizeof(text[0]));
\r
1173 LoadString(GetModuleHandle(NULL), IDS_mayu,
\r
1174 title, sizeof(title)/sizeof(title[0]));
\r
1175 _stprintf_s(buf, sizeof(buf)/sizeof(buf[0]),
\r
1176 text, _T("yamyd32"), GetLastError());
\r
1177 MessageBox((HWND)NULL, buf, title, MB_OK | MB_ICONSTOP);
\r
1179 CloseHandle(m_pi.hThread);
\r
1186 // stop notify from mayu.dll
\r
1187 g_hookData->m_hwndTaskTray = NULL;
\r
1188 CHECK_FALSE( uninstallMessageHook() );
\r
1191 ReleaseMutex(m_hMutexYamyd);
\r
1192 if (m_pi.hProcess) {
\r
1193 WaitForSingleObject(m_pi.hProcess, 5000);
\r
1194 CloseHandle(m_pi.hProcess);
\r
1196 CloseHandle(m_hMutexYamyd);
\r
1199 CancelIo(m_hNotifyMailslot);
\r
1201 CloseHandle(m_hNotifyMailslot);
\r
1202 CloseHandle(m_hNotifyEvent);
\r
1203 ReleaseMutex(m_mutex);
\r
1204 WaitForSingleObject(m_mutex, INFINITE);
\r
1205 // first, detach log from edit control to avoid deadlock
\r
1207 #ifdef LOG_TO_FILE
\r
1208 m_logFile.close();
\r
1209 #endif // LOG_TO_FILE
\r
1211 // destroy windows
\r
1212 CHECK_TRUE( DestroyWindow(m_hwndVersion) );
\r
1213 CHECK_TRUE( DestroyWindow(m_hwndInvestigate) );
\r
1214 CHECK_TRUE( DestroyWindow(m_hwndLog) );
\r
1215 CHECK_TRUE( DestroyWindow(m_hwndTaskTray) );
\r
1218 DestroyMenu(m_hMenuTaskTray);
\r
1220 // delete tasktray icon
\r
1221 CHECK_TRUE( Shell_NotifyIcon(NIM_DELETE, &m_ni) );
\r
1222 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[1]) );
\r
1223 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[0]) );
\r
1225 // stop keyboard handler thread
\r
1228 if (!(m_sessionState & SESSION_END_QUERIED)) {
\r
1230 SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, 0, 3000, &result);
\r
1233 // remove setting;
\r
1238 WPARAM messageLoop() {
\r
1239 showBanner(false);
\r
1242 mailslotHandler(0, 0);
\r
1244 HANDLE handles[] = { m_hNotifyEvent };
\r
1246 switch (ret = MsgWaitForMultipleObjectsEx(NUMBER_OF(handles), &handles[0],
\r
1247 INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE)) {
\r
1248 case WAIT_OBJECT_0: // m_hNotifyEvent
\r
1251 case WAIT_OBJECT_0 + NUMBER_OF(handles): {
\r
1253 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
\r
1254 if (msg.message == WM_QUIT) {
\r
1255 return msg.wParam;
\r
1257 if (IsDialogMessage(m_hwndLog, &msg))
\r
1259 if (IsDialogMessage(m_hwndInvestigate, &msg))
\r
1261 if (IsDialogMessage(m_hwndVersion, &msg))
\r
1263 TranslateMessage(&msg);
\r
1264 DispatchMessage(&msg);
\r
1270 case WAIT_IO_COMPLETION:
\r
1282 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
1286 /// convert registry
\r
1287 void convertRegistry()
\r
1289 Registry reg(MAYU_REGISTRY_ROOT);
\r
1290 tstringi dot_mayu;
\r
1291 bool doesAdd = false;
\r
1293 if (reg.read(_T(".mayu"), &dot_mayu)) {
\r
1294 reg.write(_T(".mayu0"), _T(";") + dot_mayu + _T(";"));
\r
1295 reg.remove(_T(".mayu"));
\r
1298 } else if (!reg.read(_T(".mayu0"), &dot_mayu)) {
\r
1299 reg.write(_T(".mayu0"), loadString(IDS_readFromHomeDirectory) + _T(";;"));
\r
1304 Registry commonreg(HKEY_LOCAL_MACHINE, _T("Software\\GANAware\\mayu"));
\r
1305 tstringi dir, layout;
\r
1306 if (commonreg.read(_T("dir"), &dir) &&
\r
1307 commonreg.read(_T("layout"), &layout)) {
\r
1308 tstringi tmp = _T(";") + dir + _T("\\dot.mayu");
\r
1309 if (layout == _T("109")) {
\r
1310 reg.write(_T(".mayu1"), loadString(IDS_109Emacs) + tmp
\r
1311 + _T(";-DUSE109") _T(";-DUSEdefault"));
\r
1312 reg.write(_T(".mayu2"), loadString(IDS_104on109Emacs) + tmp
\r
1313 + _T(";-DUSE109") _T(";-DUSEdefault") _T(";-DUSE104on109"));
\r
1314 reg.write(_T(".mayu3"), loadString(IDS_109) + tmp
\r
1315 + _T(";-DUSE109"));
\r
1316 reg.write(_T(".mayu4"), loadString(IDS_104on109) + tmp
\r
1317 + _T(";-DUSE109") _T(";-DUSE104on109"));
\r
1319 reg.write(_T(".mayu1"), loadString(IDS_104Emacs) + tmp
\r
1320 + _T(";-DUSE104") _T(";-DUSEdefault"));
\r
1321 reg.write(_T(".mayu2"), loadString(IDS_109on104Emacs) + tmp
\r
1322 + _T(";-DUSE104") _T(";-DUSEdefault") _T(";-DUSE109on104"));
\r
1323 reg.write(_T(".mayu3"), loadString(IDS_104) + tmp
\r
1324 + _T(";-DUSE104"));
\r
1325 reg.write(_T(".mayu4"), loadString(IDS_109on104) + tmp
\r
1326 + _T(";-DUSE104") _T(";-DUSE109on104"));
\r
1328 reg.write(_T(".mayuIndex"), index);
\r
1335 int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
\r
1336 LPTSTR /* i_lpszCmdLine */, int /* i_nCmdShow */)
\r
1338 g_hInst = i_hInstance;
\r
1341 CHECK_TRUE( _tsetlocale(LC_ALL, _T("")) );
\r
1343 // common controls
\r
1344 #if defined(_WIN95)
\r
1345 InitCommonControls();
\r
1347 INITCOMMONCONTROLSEX icc;
\r
1348 icc.dwSize = sizeof(icc);
\r
1349 icc.dwICC = ICC_LISTVIEW_CLASSES;
\r
1350 CHECK_TRUE( InitCommonControlsEx(&icc) );
\r
1353 // convert old registry to new registry
\r
1355 convertRegistry();
\r
1356 #endif // !USE_INI
\r
1358 // is another mayu running ?
\r
1359 HANDLE mutex = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE,
\r
1360 MUTEX_MAYU_EXCLUSIVE_RUNNING);
\r
1361 if (GetLastError() == ERROR_ALREADY_EXISTS) {
\r
1362 // another mayu already running
\r
1363 tstring text = loadString(IDS_mayuAlreadyExists);
\r
1364 tstring title = loadString(IDS_mayu);
\r
1366 UINT WM_TaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));
\r
1367 PostMessage(reinterpret_cast<HWND>(g_hookData->m_hwndTaskTray),
\r
1368 WM_TaskbarRestart, 0, 0);
\r
1370 MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
\r
1375 Mayu(mutex).messageLoop();
\r
1376 } catch (ErrorMessage &i_e) {
\r
1377 tstring title = loadString(IDS_mayu);
\r
1378 MessageBox((HWND)NULL, i_e.getMessage().c_str(), title.c_str(),
\r
1379 MB_OK | MB_ICONSTOP);
\r
1382 CHECK_TRUE( CloseHandle(mutex) );
\r