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
74 HANDLE m_hNotifyMailslot; /// mailslot to receive notify
\r
75 HANDLE m_hNotifyEvent; /// event on receive notify
\r
76 OVERLAPPED m_olNotify; ///
\r
77 BYTE m_notifyBuf[NOTIFY_MESSAGE_SIZE];
\r
78 #endif // USE_MAILSLOT
\r
79 static const DWORD SESSION_LOCKED = 1<<0;
\r
80 static const DWORD SESSION_DISCONNECTED = 1<<1;
\r
81 static const DWORD SESSION_END_QUERIED = 1<<2;
\r
82 DWORD m_sessionState;
\r
83 int m_escapeNlsKeys;
\r
84 FixScancodeMap m_fixScancodeMap;
\r
86 Setting *m_setting; /// current setting
\r
87 bool m_isSettingDialogOpened; /// is setting dialog opened ?
\r
89 Engine m_engine; /// engine
\r
91 bool m_usingSN; /// using WTSRegisterSessionNotification() ?
\r
92 time_t m_startTime; /// mayu started at ...
\r
95 WM_APP_taskTrayNotify = WM_APP + 101, ///
\r
96 WM_APP_msgStreamNotify = WM_APP + 102, ///
\r
97 WM_APP_escapeNLSKeysFailed = WM_APP + 121, ///
\r
98 ID_TaskTrayIcon = 1, ///
\r
102 YAMY_TIMER_ESCAPE_NLS_KEYS = 0, ///
\r
106 #ifdef USE_MAILSLOT
\r
107 static VOID CALLBACK mailslotProc(DWORD i_code, DWORD i_len, LPOVERLAPPED i_ol) {
\r
110 if (i_code == ERROR_SUCCESS) {
\r
111 pThis = reinterpret_cast<Mayu*>(CONTAINING_RECORD(i_ol, Mayu, m_olNotify));
\r
112 pThis->mailslotHandler(i_code, i_len);
\r
117 BOOL mailslotHandler(DWORD i_code, DWORD i_len) {
\r
123 cd.dwData = reinterpret_cast<Notify *>(m_notifyBuf)->m_type;
\r
125 cd.lpData = m_notifyBuf;
\r
126 notifyHandler(&cd);
\r
129 memset(m_notifyBuf, 0, sizeof(m_notifyBuf));
\r
130 result = ReadFileEx(m_hNotifyMailslot, m_notifyBuf, sizeof(m_notifyBuf),
\r
131 &m_olNotify, Mayu::mailslotProc);
\r
134 #endif // USE_MAILSLOT
\r
136 /// register class for tasktray
\r
137 ATOM Register_tasktray() {
\r
140 wc.lpfnWndProc = tasktray_wndProc;
\r
142 wc.cbWndExtra = sizeof(Mayu *);
\r
143 wc.hInstance = g_hInst;
\r
146 wc.hbrBackground = NULL;
\r
147 wc.lpszMenuName = NULL;
\r
148 wc.lpszClassName = _T("mayuTasktray");
\r
149 return RegisterClass(&wc);
\r
153 BOOL notifyHandler(COPYDATASTRUCT *cd) {
\r
154 switch (cd->dwData) {
\r
155 case Notify::Type_setFocus:
\r
156 case Notify::Type_name: {
\r
157 NotifySetFocus *n = (NotifySetFocus *)cd->lpData;
\r
158 n->m_className[NUMBER_OF(n->m_className) - 1] = _T('\0');
\r
159 n->m_titleName[NUMBER_OF(n->m_titleName) - 1] = _T('\0');
\r
161 if (n->m_type == Notify::Type_setFocus)
\r
162 m_engine.setFocus(reinterpret_cast<HWND>(n->m_hwnd), n->m_threadId,
\r
163 n->m_className, n->m_titleName, false);
\r
166 Acquire a(&m_log, 1);
\r
167 m_log << _T("HWND:\t") << std::hex
\r
169 << std::dec << std::endl;
\r
170 m_log << _T("THREADID:") << static_cast<int>(n->m_threadId)
\r
173 Acquire a(&m_log, (n->m_type == Notify::Type_name) ? 0 : 1);
\r
174 m_log << _T("CLASS:\t") << n->m_className << std::endl;
\r
175 m_log << _T("TITLE:\t") << n->m_titleName << std::endl;
\r
178 HWND hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), &isMDI);
\r
181 getChildWindowRect(hwnd, &rc);
\r
182 m_log << _T("MDI Window Position/Size: (")
\r
183 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
184 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
186 hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), NULL);
\r
189 GetWindowRect(hwnd, &rc);
\r
190 m_log << _T("Toplevel Window Position/Size: (")
\r
191 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
192 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
195 SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
\r
196 m_log << _T("Desktop Window Position/Size: (")
\r
197 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
198 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
201 m_log << std::endl;
\r
205 case Notify::Type_lockState: {
\r
206 NotifyLockState *n = (NotifyLockState *)cd->lpData;
\r
207 m_engine.setLockState(n->m_isNumLockToggled,
\r
208 n->m_isCapsLockToggled,
\r
209 n->m_isScrollLockToggled,
\r
210 n->m_isKanaLockToggled,
\r
211 n->m_isImeLockToggled,
\r
212 n->m_isImeCompToggled);
\r
214 Acquire a(&m_log, 0);
\r
215 if (n->m_isKanaLockToggled) {
\r
216 m_log << _T("Notify::Type_lockState Kana on : ");
\r
218 m_log << _T("Notify::Type_lockState Kana off : ");
\r
220 m_log << n->m_debugParam << ", "
\r
221 << g_hookData->m_correctKanaLockHandling << std::endl;
\r
226 case Notify::Type_sync: {
\r
227 m_engine.syncNotify();
\r
231 case Notify::Type_threadDetach: {
\r
232 NotifyThreadDetach *n = (NotifyThreadDetach *)cd->lpData;
\r
233 m_engine.threadDetachNotify(n->m_threadId);
\r
237 case Notify::Type_command: {
\r
238 NotifyCommand *n = (NotifyCommand *)cd->lpData;
\r
239 m_engine.commandNotify(n->m_hwnd, n->m_message,
\r
240 n->m_wParam, n->m_lParam);
\r
244 case Notify::Type_show: {
\r
245 NotifyShow *n = (NotifyShow *)cd->lpData;
\r
246 switch (n->m_show) {
\r
247 case NotifyShow::Show_Maximized:
\r
248 m_engine.setShow(true, false, n->m_isMDI);
\r
250 case NotifyShow::Show_Minimized:
\r
251 m_engine.setShow(false, true, n->m_isMDI);
\r
253 case NotifyShow::Show_Normal:
\r
255 m_engine.setShow(false, false, n->m_isMDI);
\r
261 case Notify::Type_log: {
\r
262 Acquire a(&m_log, 1);
\r
263 NotifyLog *n = (NotifyLog *)cd->lpData;
\r
264 m_log << _T("hook log: ") << n->m_msg << std::endl;
\r
271 /// window procedure for tasktray
\r
272 static LRESULT CALLBACK
\r
273 tasktray_wndProc(HWND i_hwnd, UINT i_message,
\r
274 WPARAM i_wParam, LPARAM i_lParam) {
\r
276 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLongPtr(i_hwnd, 0));
\r
278 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLong(i_hwnd, 0));
\r
282 switch (i_message) {
\r
284 This = reinterpret_cast<Mayu *>(
\r
285 reinterpret_cast<CREATESTRUCT *>(i_lParam)->lpCreateParams);
\r
286 This->m_fixScancodeMap.init(i_hwnd, WM_APP_escapeNLSKeysFailed);
\r
287 if (This->m_escapeNlsKeys) {
\r
288 This->m_fixScancodeMap.escape(true);
\r
291 SetWindowLongPtr(i_hwnd, 0, (LONG_PTR)This);
\r
293 SetWindowLong(i_hwnd, 0, (long)This);
\r
298 switch (i_message) {
\r
299 case WM_COPYDATA: {
\r
300 COPYDATASTRUCT *cd;
\r
301 cd = reinterpret_cast<COPYDATASTRUCT *>(i_lParam);
\r
302 return This->notifyHandler(cd);
\r
304 case WM_QUERYENDSESSION:
\r
305 if (!This->m_sessionState) {
\r
306 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
307 This->m_fixScancodeMap.escape(false);
\r
310 This->m_sessionState |= Mayu::SESSION_END_QUERIED;
\r
311 This->m_engine.prepairQuit();
\r
312 PostQuitMessage(0);
\r
315 #ifndef WM_WTSSESSION_CHANGE // WinUser.h
\r
316 # define WM_WTSSESSION_CHANGE 0x02B1
\r
318 case WM_WTSSESSION_CHANGE: {
\r
319 const char *m = "";
\r
320 switch (i_wParam) {
\r
321 #ifndef WTS_CONSOLE_CONNECT // WinUser.h
\r
322 # define WTS_CONSOLE_CONNECT 0x1
\r
323 # define WTS_CONSOLE_DISCONNECT 0x2
\r
324 # define WTS_REMOTE_CONNECT 0x3
\r
325 # define WTS_REMOTE_DISCONNECT 0x4
\r
326 # define WTS_SESSION_LOGON 0x5
\r
327 # define WTS_SESSION_LOGOFF 0x6
\r
328 # define WTS_SESSION_LOCK 0x7
\r
329 # define WTS_SESSION_UNLOCK 0x8
\r
332 restore NLS keys when any bits of m_sessionState is on
\r
334 escape NLS keys when all bits of m_sessionState cleared
\r
336 case WTS_CONSOLE_CONNECT:
\r
337 This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;
\r
338 if (!This->m_sessionState) {
\r
339 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
340 This->m_fixScancodeMap.escape(true);
\r
343 m = "WTS_CONSOLE_CONNECT";
\r
345 case WTS_CONSOLE_DISCONNECT:
\r
346 if (!This->m_sessionState) {
\r
347 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
348 This->m_fixScancodeMap.escape(false);
\r
351 This->m_sessionState |= Mayu::SESSION_DISCONNECTED;
\r
352 m = "WTS_CONSOLE_DISCONNECT";
\r
354 case WTS_REMOTE_CONNECT:
\r
355 This->m_sessionState &= ~Mayu::SESSION_DISCONNECTED;
\r
356 if (!This->m_sessionState) {
\r
357 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
358 This->m_fixScancodeMap.escape(true);
\r
361 m = "WTS_REMOTE_CONNECT";
\r
363 case WTS_REMOTE_DISCONNECT:
\r
364 if (!This->m_sessionState) {
\r
365 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
366 This->m_fixScancodeMap.escape(false);
\r
369 This->m_sessionState |= Mayu::SESSION_DISCONNECTED;
\r
370 m = "WTS_REMOTE_DISCONNECT";
\r
372 case WTS_SESSION_LOGON:
\r
373 m = "WTS_SESSION_LOGON";
\r
375 case WTS_SESSION_LOGOFF:
\r
376 m = "WTS_SESSION_LOGOFF";
\r
378 case WTS_SESSION_LOCK: {
\r
379 if (!This->m_sessionState) {
\r
380 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
381 This->m_fixScancodeMap.escape(false);
\r
384 This->m_sessionState |= Mayu::SESSION_LOCKED;
\r
385 m = "WTS_SESSION_LOCK";
\r
388 case WTS_SESSION_UNLOCK: {
\r
389 This->m_sessionState &= ~Mayu::SESSION_LOCKED;
\r
390 if (!This->m_sessionState) {
\r
391 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
392 This->m_fixScancodeMap.escape(true);
\r
395 m = "WTS_SESSION_UNLOCK";
\r
398 //case WTS_SESSION_REMOTE_CONTROL: m = "WTS_SESSION_REMOTE_CONTROL"; break;
\r
400 This->m_log << _T("WM_WTSESSION_CHANGE(")
\r
401 << i_wParam << ", " << i_lParam << "): "
\r
405 case WM_APP_msgStreamNotify: {
\r
406 tomsgstream::StreamBuf *log =
\r
407 reinterpret_cast<tomsgstream::StreamBuf *>(i_lParam);
\r
408 const tstring &str = log->acquireString();
\r
410 This->m_logFile << str << std::flush;
\r
411 #endif // LOG_TO_FILE
\r
412 editInsertTextAtLast(GetDlgItem(This->m_hwndLog, IDC_EDIT_log),
\r
414 log->releaseString();
\r
418 case WM_APP_taskTrayNotify: {
\r
419 if (i_wParam == ID_TaskTrayIcon)
\r
420 switch (i_lParam) {
\r
421 case WM_RBUTTONUP: {
\r
423 CHECK_TRUE( GetCursorPos(&p) );
\r
424 SetForegroundWindow(i_hwnd);
\r
425 HMENU hMenuSub = GetSubMenu(This->m_hMenuTaskTray, 0);
\r
426 if (This->m_engine.getIsEnabled())
\r
427 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
428 MF_UNCHECKED | MF_BYCOMMAND);
\r
430 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
431 MF_CHECKED | MF_BYCOMMAND);
\r
432 CHECK_TRUE( SetMenuDefaultItem(hMenuSub,
\r
433 ID_MENUITEM_investigate, FALSE) );
\r
435 // create reload menu
\r
436 HMENU hMenuSubSub = GetSubMenu(hMenuSub, 1);
\r
437 Registry reg(MAYU_REGISTRY_ROOT);
\r
439 reg.read(_T(".mayuIndex"), &mayuIndex, 0);
\r
440 while (DeleteMenu(hMenuSubSub, 0, MF_BYPOSITION))
\r
442 tregex getName(_T("^([^;]*);"));
\r
443 for (int index = 0; ; index ++) {
\r
445 _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
\r
447 if (!reg.read(buf, &dot_mayu))
\r
450 if (boost::regex_search(dot_mayu, what, getName)) {
\r
452 std::memset(&mii, 0, sizeof(mii));
\r
453 mii.cbSize = sizeof(mii);
\r
454 mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
\r
455 mii.fType = MFT_STRING;
\r
457 MFS_ENABLED | ((mayuIndex == index) ? MFS_CHECKED : 0);
\r
458 mii.wID = ID_MENUITEM_reloadBegin + index;
\r
459 tstringi name(what.str(1));
\r
460 mii.dwTypeData = const_cast<_TCHAR *>(name.c_str());
\r
461 mii.cch = name.size();
\r
463 InsertMenuItem(hMenuSubSub, index, TRUE, &mii);
\r
468 TrackPopupMenu(hMenuSub, TPM_LEFTALIGN,
\r
469 p.x, p.y, 0, i_hwnd, NULL);
\r
470 // TrackPopupMenu may fail (ERROR_POPUP_ALREADY_ACTIVE)
\r
474 case WM_LBUTTONDBLCLK:
\r
475 SendMessage(i_hwnd, WM_COMMAND,
\r
476 MAKELONG(ID_MENUITEM_investigate, 0), 0);
\r
482 case WM_APP_escapeNLSKeysFailed:
\r
486 This->m_log << _T("escape NLS keys done code=") << i_wParam << std::endl;
\r
487 switch (i_wParam) {
\r
489 case YAMY_ERROR_RETRY_INJECTION_SUCCESS:
\r
490 // escape NLS keys success
\r
492 case YAMY_ERROR_TIMEOUT_INJECTION:
\r
493 ret = This->errorDialogWithCode(IDS_escapeNlsKeysRetry, i_wParam, MB_RETRYCANCEL | MB_ICONSTOP);
\r
494 if (ret == IDRETRY) {
\r
495 This->m_fixScancodeMap.escape(true);
\r
499 This->errorDialogWithCode(IDS_escapeNlsKeysFailed, i_wParam, MB_OK);
\r
503 This->m_log << _T("restore NLS keys done with code=") << i_wParam << std::endl;
\r
509 int notify_code = HIWORD(i_wParam);
\r
510 int id = LOWORD(i_wParam);
\r
511 if (notify_code == 0) // menu
\r
514 if (ID_MENUITEM_reloadBegin <= id) {
\r
515 Registry reg(MAYU_REGISTRY_ROOT);
\r
516 reg.write(_T(".mayuIndex"), id - ID_MENUITEM_reloadBegin);
\r
520 case ID_MENUITEM_reload:
\r
523 case ID_MENUITEM_investigate: {
\r
524 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
525 ShowWindow(This->m_hwndInvestigate, SW_SHOW);
\r
528 GetWindowRect(This->m_hwndInvestigate, &rc1);
\r
529 GetWindowRect(This->m_hwndLog, &rc2);
\r
531 MoveWindow(This->m_hwndLog, rc1.left, rc1.bottom,
\r
532 rcWidth(&rc1), rcHeight(&rc2), TRUE);
\r
534 SetForegroundWindow(This->m_hwndLog);
\r
535 SetForegroundWindow(This->m_hwndInvestigate);
\r
538 case ID_MENUITEM_setting:
\r
539 if (!This->m_isSettingDialogOpened) {
\r
540 This->m_isSettingDialogOpened = true;
\r
541 if (DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_setting),
\r
542 NULL, dlgSetting_dlgProc))
\r
544 This->m_isSettingDialogOpened = false;
\r
547 case ID_MENUITEM_log:
\r
548 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
549 SetForegroundWindow(This->m_hwndLog);
\r
551 case ID_MENUITEM_check: {
\r
554 ret = GetKeyboardState(keys);
\r
556 This->m_log << _T("Check Keystate Failed(%d)")
\r
557 << GetLastError() << std::endl;
\r
559 This->m_log << _T("Check Keystate: ") << std::endl;
\r
560 for (int i = 0; i < 0xff; i++) {
\r
562 asyncKey = GetAsyncKeyState(i);
\r
563 This->m_log << std::hex;
\r
564 if (asyncKey & 0x8000) {
\r
565 This->m_log << _T(" ") << VK2TCHAR[i]
\r
566 << _T("(0x") << i << _T("): pressed!")
\r
569 if (i == 0x14 || // VK_CAPTITAL
\r
570 i == 0x15 || // VK_KANA
\r
571 i == 0x19 || // VK_KANJI
\r
572 i == 0x90 || // VK_NUMLOCK
\r
573 i == 0x91 // VK_SCROLL
\r
576 This->m_log << _T(" ") << VK2TCHAR[i]
\r
577 << _T("(0x") << i << _T("): locked!")
\r
581 This->m_log << std::dec;
\r
583 This->m_log << std::endl;
\r
587 case ID_MENUITEM_version:
\r
588 ShowWindow(This->m_hwndVersion, SW_SHOW);
\r
589 SetForegroundWindow(This->m_hwndVersion);
\r
591 case ID_MENUITEM_help: {
\r
592 _TCHAR buf[GANA_MAX_PATH];
\r
593 CHECK_TRUE( GetModuleFileName(g_hInst, buf, NUMBER_OF(buf)) );
\r
594 tstringi helpFilename = pathRemoveFileSpec(buf);
\r
595 helpFilename += _T("\\");
\r
596 helpFilename += loadString(IDS_helpFilename);
\r
597 ShellExecute(NULL, _T("open"), helpFilename.c_str(),
\r
598 NULL, NULL, SW_SHOWNORMAL);
\r
601 case ID_MENUITEM_disable:
\r
602 This->m_engine.enable(!This->m_engine.getIsEnabled());
\r
603 if (This->m_engine.getIsEnabled()) {
\r
604 This->m_fixScancodeMap.escape(true);
\r
606 This->m_fixScancodeMap.escape(false);
\r
608 This->showTasktrayIcon();
\r
610 case ID_MENUITEM_quit:
\r
611 This->m_engine.prepairQuit();
\r
612 PostQuitMessage(0);
\r
618 case WM_APP_engineNotify: {
\r
619 switch (i_wParam) {
\r
620 case EngineNotify_shellExecute:
\r
621 This->m_engine.shellExecute();
\r
623 case EngineNotify_loadSetting:
\r
626 case EngineNotify_helpMessage:
\r
627 This->showHelpMessage(false);
\r
629 This->showHelpMessage(true);
\r
631 case EngineNotify_showDlg: {
\r
632 // show investigate/log window
\r
633 int sw = (i_lParam & ~MayuDialogType_mask);
\r
635 switch (static_cast<MayuDialogType>(
\r
636 i_lParam & MayuDialogType_mask)) {
\r
637 case MayuDialogType_investigate:
\r
638 hwnd = This->m_hwndInvestigate;
\r
640 case MayuDialogType_log:
\r
641 hwnd = This->m_hwndLog;
\r
645 ShowWindow(hwnd, sw);
\r
647 case SW_SHOWNORMAL:
\r
648 case SW_SHOWMAXIMIZED:
\r
651 case SW_SHOWDEFAULT:
\r
652 SetForegroundWindow(hwnd);
\r
658 case EngineNotify_setForegroundWindow:
\r
659 // FIXME: completely useless. why ?
\r
660 setForegroundWindow(reinterpret_cast<HWND>(i_lParam));
\r
662 Acquire a(&This->m_log, 1);
\r
663 This->m_log << _T("setForegroundWindow(0x")
\r
664 << std::hex << i_lParam << std::dec << _T(")")
\r
668 case EngineNotify_clearLog:
\r
669 SendMessage(This->m_hwndLog, WM_COMMAND,
\r
670 MAKELONG(IDC_BUTTON_clearLog, 0), 0);
\r
678 case WM_APP_dlglogNotify: {
\r
679 switch (i_wParam) {
\r
680 case DlgLogNotify_logCleared:
\r
681 This->showBanner(true);
\r
690 if (This->m_usingSN) {
\r
691 wtsUnRegisterSessionNotification(i_hwnd);
\r
692 This->m_usingSN = false;
\r
694 if (!This->m_sessionState) {
\r
695 if (This->m_escapeNlsKeys && This->m_engine.getIsEnabled()) {
\r
696 This->m_fixScancodeMap.escape(false);
\r
702 if (i_message == This->m_WM_TaskbarRestart) {
\r
703 if (This->showTasktrayIcon(true)) {
\r
704 Acquire a(&This->m_log, 0);
\r
705 This->m_log << _T("Tasktray icon is updated.") << std::endl;
\r
707 Acquire a(&This->m_log, 1);
\r
708 This->m_log << _T("Tasktray icon already exists.") << std::endl;
\r
711 } else if (i_message == This->m_WM_MayuIPC) {
\r
712 switch (static_cast<MayuIPCCommand>(i_wParam)) {
\r
713 case MayuIPCCommand_Enable:
\r
714 This->m_engine.enable(!!i_lParam);
\r
715 if (This->m_engine.getIsEnabled()) {
\r
716 This->m_fixScancodeMap.escape(true);
\r
718 This->m_fixScancodeMap.escape(false);
\r
720 This->showTasktrayIcon();
\r
722 Acquire a(&This->m_log, 1);
\r
723 This->m_log << _T("Enabled by another application.")
\r
726 Acquire a(&This->m_log, 1);
\r
727 This->m_log << _T("Disabled by another application.")
\r
734 return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
\r
739 Setting *newSetting = new Setting;
\r
742 for (int i = 1; i < __argc; ++ i) {
\r
743 if (__targv[i][0] == _T('-') && __targv[i][1] == _T('D'))
\r
744 newSetting->m_symbols.insert(__targv[i] + 2);
\r
747 if (!SettingLoader(&m_log, &m_log).load(newSetting)) {
\r
748 ShowWindow(m_hwndLog, SW_SHOW);
\r
749 SetForegroundWindow(m_hwndLog);
\r
751 Acquire a(&m_log, 0);
\r
752 m_log << _T("error: failed to load.") << std::endl;
\r
755 m_log << _T("successfully loaded.") << std::endl;
\r
756 while (!m_engine.setSetting(newSetting))
\r
759 m_setting = newSetting;
\r
762 // show message (a baloon from the task tray icon)
\r
763 void showHelpMessage(bool i_doesShow = true) {
\r
764 if (m_canUseTasktrayBaloon) {
\r
766 tstring helpMessage, helpTitle;
\r
767 m_engine.getHelpMessages(&helpMessage, &helpTitle);
\r
768 tcslcpy(m_ni.szInfo, helpMessage.c_str(), NUMBER_OF(m_ni.szInfo));
\r
769 tcslcpy(m_ni.szInfoTitle, helpTitle.c_str(),
\r
770 NUMBER_OF(m_ni.szInfoTitle));
\r
771 m_ni.dwInfoFlags = NIIF_INFO;
\r
773 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
774 CHECK_TRUE( Shell_NotifyIcon(NIM_MODIFY, &m_ni) );
\r
778 // change the task tray icon
\r
779 bool showTasktrayIcon(bool i_doesAdd = false) {
\r
780 m_ni.hIcon = m_tasktrayIcon[m_engine.getIsEnabled() ? 1 : 0];
\r
781 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
783 // http://support.microsoft.com/kb/418138/JA/
\r
785 for (; !Shell_NotifyIcon(NIM_ADD, &m_ni) && 0 < guard; -- guard) {
\r
786 if (Shell_NotifyIcon(NIM_MODIFY, &m_ni)) {
\r
789 Sleep(1000); // 1sec
\r
793 return !!Shell_NotifyIcon(NIM_MODIFY, &m_ni);
\r
797 void showBanner(bool i_isCleared) {
\r
801 _TCHAR starttimebuf[1024];
\r
802 _TCHAR timebuf[1024];
\r
804 #ifdef __BORLANDC__
\r
805 #pragma message("\t\t****\tAfter std::ostream() is called, ")
\r
806 #pragma message("\t\t****\tstrftime(... \"%%#c\" ...) fails.")
\r
807 #pragma message("\t\t****\tWhy ? Bug of Borland C++ 5.5.1 ? ")
\r
808 #pragma message("\t\t****\t - nayuta")
\r
809 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
811 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
812 localtime(&m_startTime));
\r
814 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%#c"), localtime(&now));
\r
815 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%#c"),
\r
816 localtime(&m_startTime));
\r
819 Acquire a(&m_log, 0);
\r
820 m_log << _T("------------------------------------------------------------") << std::endl;
\r
821 m_log << loadString(IDS_mayu) << _T(" ") _T(VERSION);
\r
823 m_log << _T(" (DEBUG)");
\r
826 m_log << _T(" (UNICODE)");
\r
828 m_log << std::endl;
\r
829 m_log << _T(" built by ")
\r
830 << _T(LOGNAME) << _T("@") << toLower(_T(COMPUTERNAME))
\r
831 << _T(" (") << _T(__DATE__) << _T(" ")
\r
832 << _T(__TIME__) << _T(", ")
\r
833 << getCompilerVersionString() << _T(")") << std::endl;
\r
834 _TCHAR modulebuf[1024];
\r
835 CHECK_TRUE( GetModuleFileName(g_hInst, modulebuf,
\r
836 NUMBER_OF(modulebuf)) );
\r
837 m_log << _T("started at ") << starttimebuf << std::endl;
\r
838 m_log << modulebuf << std::endl;
\r
839 m_log << _T("------------------------------------------------------------") << std::endl;
\r
842 m_log << _T("log was cleared at ") << timebuf << std::endl;
\r
844 m_log << _T("log begins at ") << timebuf << std::endl;
\r
848 int errorDialogWithCode(UINT ids, int code, UINT style = MB_OK | MB_ICONSTOP)
\r
850 _TCHAR title[1024];
\r
853 _sntprintf_s(title, NUMBER_OF(title), _TRUNCATE, loadString(IDS_mayu).c_str());
\r
854 _sntprintf_s(text, NUMBER_OF(text), _TRUNCATE, loadString(ids).c_str(), code);
\r
855 return MessageBox((HWND)NULL, text, title, style);
\r
858 int enableToWriteByUser(HANDLE hdl)
\r
860 TCHAR userName[GANA_MAX_ATOM_LENGTH];
\r
861 DWORD userNameSize = NUMBER_OF(userName);
\r
863 SID_NAME_USE sidType;
\r
866 TCHAR *pDomain = NULL;
\r
867 DWORD domainSize = 0;
\r
869 PSECURITY_DESCRIPTOR pSd;
\r
871 ACL_SIZE_INFORMATION aclInfo;
\r
877 DWORD newAceIndex = 0;
\r
882 ret = GetUserName(userName, &userNameSize);
\r
883 if (ret == FALSE) {
\r
884 err = YAMY_ERROR_ON_GET_USERNAME;
\r
888 // get buffer size for pSid (and pDomain)
\r
889 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
890 if (ret != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
\r
891 // above call should fail by ERROR_INSUFFICIENT_BUFFER
\r
892 err = YAMY_ERROR_ON_GET_LOGONUSERNAME;
\r
896 pSid = reinterpret_cast<PSID>(LocalAlloc(LPTR, sidSize));
\r
897 pDomain = reinterpret_cast<TCHAR*>(LocalAlloc(LPTR, domainSize * sizeof(TCHAR)));
\r
898 if (pSid == NULL || pDomain == NULL) {
\r
899 err = YAMY_ERROR_NO_MEMORY;
\r
903 // get SID (and Domain) for logoned user
\r
904 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
905 if (ret == FALSE) {
\r
906 // LookupAccountName() should success in this time
\r
907 err = YAMY_ERROR_ON_GET_LOGONUSERNAME;
\r
911 // get DACL for hdl
\r
912 ret = GetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOrigDacl, NULL, &pSd);
\r
913 if (ret != ERROR_SUCCESS) {
\r
914 err = YAMY_ERROR_ON_GET_SECURITYINFO;
\r
918 // get size for original DACL
\r
919 ret = GetAclInformation(pOrigDacl, &aclInfo, sizeof(aclInfo), AclSizeInformation);
\r
920 if (ret == FALSE) {
\r
921 err = YAMY_ERROR_ON_GET_DACL;
\r
925 // compute size for new DACL
\r
926 newDaclSize = aclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pSid) - sizeof(DWORD);
\r
928 // allocate memory for new DACL
\r
929 pNewDacl = reinterpret_cast<PACL>(LocalAlloc(LPTR, newDaclSize));
\r
930 if (pNewDacl == NULL) {
\r
931 err = YAMY_ERROR_NO_MEMORY;
\r
935 // initialize new DACL
\r
936 ret = InitializeAcl(pNewDacl, newDaclSize, ACL_REVISION);
\r
937 if (ret == FALSE) {
\r
938 err = YAMY_ERROR_ON_INITIALIZE_ACL;
\r
942 // copy original DACL to new DACL
\r
943 for (aceIndex = 0; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
946 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
947 if (ret == FALSE) {
\r
948 err = YAMY_ERROR_ON_GET_ACE;
\r
952 if ((reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->Header.AceFlags & INHERITED_ACE) {
\r
956 if (EqualSid(pSid, &(reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->SidStart) != FALSE) {
\r
960 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
961 if (ret == FALSE) {
\r
962 err = YAMY_ERROR_ON_ADD_ACE;
\r
969 ret = AddAccessAllowedAce(pNewDacl, ACL_REVISION, GENERIC_ALL, pSid);
\r
970 if (ret == FALSE) {
\r
971 err = YAMY_ERROR_ON_ADD_ALLOWED_ACE;
\r
975 // copy the rest of inherited ACEs
\r
976 for (; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
979 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
980 if (ret == FALSE) {
\r
981 err = YAMY_ERROR_ON_GET_ACE;
\r
985 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
986 if (ret == FALSE) {
\r
987 err = YAMY_ERROR_ON_ADD_ACE;
\r
992 ret = SetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);
\r
993 if (ret != ERROR_SUCCESS) {
\r
994 err = YAMY_ERROR_ON_SET_SECURITYINFO;
\r
1000 LocalFree(pDomain);
\r
1001 LocalFree(pNewDacl);
\r
1008 Mayu(HANDLE i_mutex)
\r
1009 : m_hwndTaskTray(NULL),
\r
1012 m_WM_TaskbarRestart(RegisterWindowMessage(_T("TaskbarCreated"))),
\r
1013 m_WM_MayuIPC(RegisterWindowMessage(WM_MayuIPC_NAME)),
\r
1014 m_canUseTasktrayBaloon(
\r
1015 PACKVERSION(5, 0) <= getDllVersion(_T("shlwapi.dll"))),
\r
1016 m_log(WM_APP_msgStreamNotify),
\r
1018 m_isSettingDialogOpened(false),
\r
1019 m_sessionState(0),
\r
1021 Registry reg(MAYU_REGISTRY_ROOT);
\r
1022 reg.read(_T("escapeNLSKeys"), &m_escapeNlsKeys, 0);
\r
1023 #ifdef USE_MAILSLOT
\r
1024 m_hNotifyMailslot = CreateMailslot(NOTIFY_MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, (SECURITY_ATTRIBUTES *)NULL);
\r
1025 ASSERT(m_hNotifyMailslot != INVALID_HANDLE_VALUE);
\r
1027 if (checkWindowsVersion(6, 0) != FALSE) { // enableToWriteByUser() is available only Vista or later
\r
1028 err = enableToWriteByUser(m_hNotifyMailslot);
\r
1030 errorDialogWithCode(IDS_cannotPermitStandardUser, err);
\r
1034 m_hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
\r
1035 ASSERT(m_hNotifyEvent);
\r
1036 m_olNotify.Offset = 0;
\r
1037 m_olNotify.OffsetHigh = 0;
\r
1038 m_olNotify.hEvent = m_hNotifyEvent;
\r
1039 #endif // USE_MAILSLOT
\r
1040 time(&m_startTime);
\r
1042 CHECK_TRUE( Register_focus() );
\r
1043 CHECK_TRUE( Register_target() );
\r
1044 CHECK_TRUE( Register_tasktray() );
\r
1048 HomeDirectories pathes;
\r
1049 getHomeDirectories(&pathes);
\r
1050 for (HomeDirectories::iterator i = pathes.begin(); i != pathes.end(); ++ i)
\r
1051 if (SetCurrentDirectory(i->c_str()))
\r
1055 // create windows, dialogs
\r
1056 tstringi title = loadString(IDS_mayu);
\r
1057 m_hwndTaskTray = CreateWindow(_T("mayuTasktray"), title.c_str(),
\r
1058 WS_OVERLAPPEDWINDOW,
\r
1059 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1060 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1061 NULL, NULL, g_hInst, this);
\r
1062 CHECK_TRUE( m_hwndTaskTray );
\r
1064 // set window handle of tasktray to hooks
\r
1065 #ifndef USE_MAILSLOT
\r
1066 g_hookData->m_hwndTaskTray = reinterpret_cast<DWORD>(m_hwndTaskTray);
\r
1067 #endif // !USE_MAILSLOT
\r
1068 CHECK_FALSE( installMessageHook() );
\r
1069 m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray,
\r
1070 NOTIFY_FOR_THIS_SESSION);
\r
1073 dld.m_log = &m_log;
\r
1074 dld.m_hwndTaskTray = m_hwndTaskTray;
\r
1076 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_log), NULL,
\r
1077 dlgLog_dlgProc, (LPARAM)&dld);
\r
1078 CHECK_TRUE( m_hwndLog );
\r
1080 DlgInvestigateData did;
\r
1081 did.m_engine = &m_engine;
\r
1082 did.m_hwndLog = m_hwndLog;
\r
1083 m_hwndInvestigate =
\r
1084 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_investigate), NULL,
\r
1085 dlgInvestigate_dlgProc, (LPARAM)&did);
\r
1086 CHECK_TRUE( m_hwndInvestigate );
\r
1089 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_version),
\r
1090 NULL, dlgVersion_dlgProc,
\r
1091 (LPARAM)m_engine.getMayudVersion().c_str());
\r
1092 CHECK_TRUE( m_hwndVersion );
\r
1095 #ifdef LOG_TO_FILE
\r
1097 _TCHAR exePath[GANA_MAX_PATH];
\r
1098 _TCHAR exeDrive[GANA_MAX_PATH];
\r
1099 _TCHAR exeDir[GANA_MAX_PATH];
\r
1100 GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
\r
1101 _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
\r
1104 path += _T("mayu.log");
\r
1105 m_logFile.open(path.c_str(), std::ios::app);
\r
1106 m_logFile.imbue(std::locale("japanese"));
\r
1107 #endif // LOG_TO_FILE
\r
1108 SendMessage(GetDlgItem(m_hwndLog, IDC_EDIT_log), EM_SETLIMITTEXT, 0, 0);
\r
1109 m_log.attach(m_hwndTaskTray);
\r
1111 // start keyboard handler thread
\r
1112 m_engine.setAssociatedWndow(m_hwndTaskTray);
\r
1115 // show tasktray icon
\r
1116 m_tasktrayIcon[0] = loadSmallIcon(IDI_ICON_mayu_disabled);
\r
1117 m_tasktrayIcon[1] = loadSmallIcon(IDI_ICON_mayu);
\r
1118 std::memset(&m_ni, 0, sizeof(m_ni));
\r
1119 m_ni.uID = ID_TaskTrayIcon;
\r
1120 m_ni.hWnd = m_hwndTaskTray;
\r
1121 m_ni.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
\r
1122 m_ni.hIcon = m_tasktrayIcon[1];
\r
1123 m_ni.uCallbackMessage = WM_APP_taskTrayNotify;
\r
1124 tstring tip = loadString(IDS_mayu);
\r
1125 tcslcpy(m_ni.szTip, tip.c_str(), NUMBER_OF(m_ni.szTip));
\r
1126 if (m_canUseTasktrayBaloon) {
\r
1127 m_ni.cbSize = NOTIFYICONDATA_V3_SIZE;
\r
1128 m_ni.uFlags |= NIF_INFO;
\r
1130 m_ni.cbSize = NOTIFYICONDATA_V1_SIZE;
\r
1131 showTasktrayIcon(true);
\r
1134 m_hMenuTaskTray = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU_tasktray));
\r
1135 ASSERT(m_hMenuTaskTray);
\r
1137 // set initial lock state
\r
1138 notifyLockState();
\r
1141 ZeroMemory(&m_pi,sizeof(m_pi));
\r
1142 ZeroMemory(&m_si,sizeof(m_si));
\r
1143 m_si.cb=sizeof(m_si);
\r
1145 // create mutex to block yamyd
\r
1146 m_hMutexYamyd = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE, MUTEX_YAMYD_BLOCKER);
\r
1148 tstring yamydPath;
\r
1149 _TCHAR exePath[GANA_MAX_PATH];
\r
1150 _TCHAR exeDrive[GANA_MAX_PATH];
\r
1151 _TCHAR exeDir[GANA_MAX_PATH];
\r
1153 GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
\r
1154 _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
\r
1155 yamydPath = exeDrive;
\r
1156 yamydPath += exeDir;
\r
1157 yamydPath += _T("yamyd32");
\r
1159 BOOL result = CreateProcess(yamydPath.c_str(), NULL, NULL, NULL, FALSE,
\r
1160 NORMAL_PRIORITY_CLASS, 0, NULL, &m_si, &m_pi);
\r
1161 if (result == FALSE) {
\r
1164 TCHAR title[1024];
\r
1166 m_pi.hProcess = NULL;
\r
1167 LoadString(GetModuleHandle(NULL), IDS_cannotInvoke,
\r
1168 text, sizeof(text)/sizeof(text[0]));
\r
1169 LoadString(GetModuleHandle(NULL), IDS_mayu,
\r
1170 title, sizeof(title)/sizeof(title[0]));
\r
1171 _stprintf_s(buf, sizeof(buf)/sizeof(buf[0]),
\r
1172 text, _T("yamyd32"), GetLastError());
\r
1173 MessageBox((HWND)NULL, buf, title, MB_OK | MB_ICONSTOP);
\r
1175 CloseHandle(m_pi.hThread);
\r
1182 #ifdef USE_MAILSLOT
\r
1183 CancelIo(m_hNotifyMailslot);
\r
1185 CloseHandle(m_hNotifyMailslot);
\r
1186 CloseHandle(m_hNotifyEvent);
\r
1187 #endif // USE_MAILSLOT
\r
1188 ReleaseMutex(m_mutex);
\r
1189 WaitForSingleObject(m_mutex, INFINITE);
\r
1190 // first, detach log from edit control to avoid deadlock
\r
1192 #ifdef LOG_TO_FILE
\r
1193 m_logFile.close();
\r
1194 #endif // LOG_TO_FILE
\r
1196 // stop notify from mayu.dll
\r
1197 g_hookData->m_hwndTaskTray = NULL;
\r
1198 CHECK_FALSE( uninstallMessageHook() );
\r
1201 ReleaseMutex(m_hMutexYamyd);
\r
1202 if (m_pi.hProcess) {
\r
1203 WaitForSingleObject(m_pi.hProcess, 5000);
\r
1204 CloseHandle(m_pi.hProcess);
\r
1206 CloseHandle(m_hMutexYamyd);
\r
1208 if (!(m_sessionState & SESSION_END_QUERIED)) {
\r
1210 SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 3000, &result);
\r
1213 // destroy windows
\r
1214 CHECK_TRUE( DestroyWindow(m_hwndVersion) );
\r
1215 CHECK_TRUE( DestroyWindow(m_hwndInvestigate) );
\r
1216 CHECK_TRUE( DestroyWindow(m_hwndLog) );
\r
1217 CHECK_TRUE( DestroyWindow(m_hwndTaskTray) );
\r
1220 DestroyMenu(m_hMenuTaskTray);
\r
1222 // delete tasktray icon
\r
1223 CHECK_TRUE( Shell_NotifyIcon(NIM_DELETE, &m_ni) );
\r
1224 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[1]) );
\r
1225 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[0]) );
\r
1227 // stop keyboard handler thread
\r
1230 // remove setting;
\r
1235 WPARAM messageLoop() {
\r
1236 showBanner(false);
\r
1239 #ifdef USE_MAILSLOT
\r
1240 mailslotHandler(0, 0);
\r
1242 HANDLE handles[] = { m_hNotifyEvent };
\r
1244 switch (ret = MsgWaitForMultipleObjectsEx(NUMBER_OF(handles), &handles[0],
\r
1245 INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE)) {
\r
1246 case WAIT_OBJECT_0: // m_hNotifyEvent
\r
1249 case WAIT_OBJECT_0 + NUMBER_OF(handles): {
\r
1251 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
\r
1252 if (msg.message == WM_QUIT) {
\r
1253 return msg.wParam;
\r
1255 if (IsDialogMessage(m_hwndLog, &msg))
\r
1257 if (IsDialogMessage(m_hwndInvestigate, &msg))
\r
1259 if (IsDialogMessage(m_hwndVersion, &msg))
\r
1261 TranslateMessage(&msg);
\r
1262 DispatchMessage(&msg);
\r
1268 case WAIT_IO_COMPLETION:
\r
1276 #else // !USE_MAILSLOT
\r
1278 while (0 < GetMessage(&msg, NULL, 0, 0)) {
\r
1279 if (IsDialogMessage(m_hwndLog, &msg))
\r
1281 if (IsDialogMessage(m_hwndInvestigate, &msg))
\r
1283 if (IsDialogMessage(m_hwndVersion, &msg))
\r
1285 TranslateMessage(&msg);
\r
1286 DispatchMessage(&msg);
\r
1288 return msg.wParam;
\r
1289 #endif // !USE_MAILSLOT
\r
1294 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
1298 /// convert registry
\r
1299 void convertRegistry()
\r
1301 Registry reg(MAYU_REGISTRY_ROOT);
\r
1302 tstringi dot_mayu;
\r
1303 bool doesAdd = false;
\r
1305 if (reg.read(_T(".mayu"), &dot_mayu)) {
\r
1306 reg.write(_T(".mayu0"), _T(";") + dot_mayu + _T(";"));
\r
1307 reg.remove(_T(".mayu"));
\r
1310 } else if (!reg.read(_T(".mayu0"), &dot_mayu)) {
\r
1311 reg.write(_T(".mayu0"), loadString(IDS_readFromHomeDirectory) + _T(";;"));
\r
1316 Registry commonreg(HKEY_LOCAL_MACHINE, _T("Software\\GANAware\\mayu"));
\r
1317 tstringi dir, layout;
\r
1318 if (commonreg.read(_T("dir"), &dir) &&
\r
1319 commonreg.read(_T("layout"), &layout)) {
\r
1320 tstringi tmp = _T(";") + dir + _T("\\dot.mayu");
\r
1321 if (layout == _T("109")) {
\r
1322 reg.write(_T(".mayu1"), loadString(IDS_109Emacs) + tmp
\r
1323 + _T(";-DUSE109") _T(";-DUSEdefault"));
\r
1324 reg.write(_T(".mayu2"), loadString(IDS_104on109Emacs) + tmp
\r
1325 + _T(";-DUSE109") _T(";-DUSEdefault") _T(";-DUSE104on109"));
\r
1326 reg.write(_T(".mayu3"), loadString(IDS_109) + tmp
\r
1327 + _T(";-DUSE109"));
\r
1328 reg.write(_T(".mayu4"), loadString(IDS_104on109) + tmp
\r
1329 + _T(";-DUSE109") _T(";-DUSE104on109"));
\r
1331 reg.write(_T(".mayu1"), loadString(IDS_104Emacs) + tmp
\r
1332 + _T(";-DUSE104") _T(";-DUSEdefault"));
\r
1333 reg.write(_T(".mayu2"), loadString(IDS_109on104Emacs) + tmp
\r
1334 + _T(";-DUSE104") _T(";-DUSEdefault") _T(";-DUSE109on104"));
\r
1335 reg.write(_T(".mayu3"), loadString(IDS_104) + tmp
\r
1336 + _T(";-DUSE104"));
\r
1337 reg.write(_T(".mayu4"), loadString(IDS_109on104) + tmp
\r
1338 + _T(";-DUSE104") _T(";-DUSE109on104"));
\r
1340 reg.write(_T(".mayuIndex"), index);
\r
1347 int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
\r
1348 LPTSTR /* i_lpszCmdLine */, int /* i_nCmdShow */)
\r
1350 g_hInst = i_hInstance;
\r
1353 CHECK_TRUE( _tsetlocale(LC_ALL, _T("")) );
\r
1355 // common controls
\r
1356 #if defined(_WIN95)
\r
1357 InitCommonControls();
\r
1359 INITCOMMONCONTROLSEX icc;
\r
1360 icc.dwSize = sizeof(icc);
\r
1361 icc.dwICC = ICC_LISTVIEW_CLASSES;
\r
1362 CHECK_TRUE( InitCommonControlsEx(&icc) );
\r
1365 // convert old registry to new registry
\r
1367 convertRegistry();
\r
1368 #endif // !USE_INI
\r
1370 // is another mayu running ?
\r
1371 HANDLE mutex = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE,
\r
1372 MUTEX_MAYU_EXCLUSIVE_RUNNING);
\r
1373 if (GetLastError() == ERROR_ALREADY_EXISTS) {
\r
1374 // another mayu already running
\r
1375 tstring text = loadString(IDS_mayuAlreadyExists);
\r
1376 tstring title = loadString(IDS_mayu);
\r
1378 UINT WM_TaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));
\r
1379 PostMessage(reinterpret_cast<HWND>(g_hookData->m_hwndTaskTray),
\r
1380 WM_TaskbarRestart, 0, 0);
\r
1382 MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
\r
1387 Mayu(mutex).messageLoop();
\r
1388 } catch (ErrorMessage &i_e) {
\r
1389 tstring title = loadString(IDS_mayu);
\r
1390 MessageBox((HWND)NULL, i_e.getMessage().c_str(), title.c_str(),
\r
1391 MB_OK | MB_ICONSTOP);
\r
1394 CHECK_TRUE( CloseHandle(mutex) );
\r