1 ///////////////////////////////////////////////////////////////////////////////
\r
6 #include "../registry.h"
\r
7 #include "../stringtool.h"
\r
8 #include "../windowstool.h"
\r
10 #include "setuprc.h"
\r
11 #include "installer.h"
\r
13 #include <windowsx.h>
\r
17 using namespace Installer;
\r
20 ///////////////////////////////////////////////////////////////////////////////
\r
24 #define DIR_REGISTRY_ROOT \
\r
25 HKEY_LOCAL_MACHINE, \
\r
26 _T("Software\\GANAware\\mayu")
\r
29 ///////////////////////////////////////////////////////////////////////////////
\r
36 u_int32 g_flags = SetupFile::Normal;
\r
39 using namespace SetupFile;
\r
40 const SetupFile::Data g_setupFiles[] = {
\r
42 #define SN(i_kind, i_os, i_from, i_destination) \
\r
43 { i_kind, i_os, Normal|Flag_Usb, _T(i_from), i_destination, _T(i_from) }
\r
45 #define DN(i_kind, i_os, i_from, i_destination, i_to) \
\r
46 { i_kind, i_os, Normal|Flag_Usb, _T(i_from), i_destination, _T(i_to) }
\r
49 SN(Dll , ALL, "mayu.dll" , ToDest),
\r
50 SN(File, ALL, "mayu.exe" , ToDest),
\r
51 SN(File, ALL, "setup.exe" , ToDest),
\r
55 SN(File, NT , "mayud.sys" , ToDest),
\r
56 SN(File, NT , "mayudnt4.sys" , ToDest),
\r
57 SN(File, W2k, "mayudrsc.sys" , ToDest),
\r
58 SN(File, W2k, "mayud.sys" , ToDriver),
\r
59 DN(File, NT4, "mayudnt4.sys" , ToDriver, "mayud.sys"),
\r
60 SN(File, W2k, "mayudrsc.sys" , ToDriver),
\r
61 #elif defined(_WIN95)
\r
62 SN(File, W9x, "mayud.vxd" , ToDest),
\r
68 SN(File, ALL, "104.mayu" , ToDest),
\r
69 SN(File, ALL, "104on109.mayu" , ToDest),
\r
70 SN(File, ALL, "109.mayu" , ToDest),
\r
71 SN(File, ALL, "109on104.mayu" , ToDest),
\r
72 SN(File, ALL, "default.mayu" , ToDest),
\r
73 SN(File, ALL, "dot.mayu" , ToDest),
\r
74 SN(File, ALL, "emacsedit.mayu" , ToDest),
\r
77 SN(Dir , ALL, "doc" , ToDest), // mkdir
\r
78 DN(File, ALL, "banner-ja.gif" , ToDest, "doc\\banner-ja.gif" ),
\r
79 DN(File, ALL, "edit-setting-ja.png", ToDest, "doc\\edit-setting-ja.png"),
\r
80 DN(File, ALL, "investigate-ja.png" , ToDest, "doc\\investigate-ja.png" ),
\r
81 DN(File, ALL, "log-ja.png" , ToDest, "doc\\log-ja.png" ),
\r
82 DN(File, ALL, "menu-ja.png" , ToDest, "doc\\menu-ja.png" ),
\r
83 DN(File, ALL, "pause-ja.png" , ToDest, "doc\\pause-ja.png" ),
\r
84 DN(File, ALL, "setting-ja.png" , ToDest, "doc\\setting-ja.png" ),
\r
85 DN(File, ALL, "target.png" , ToDest, "doc\\target.png" ),
\r
86 DN(File, ALL, "version-ja.png" , ToDest, "doc\\version-ja.png" ),
\r
87 DN(File, ALL, "CONTENTS-ja.html" , ToDest, "doc\\CONTENTS-ja.html" ),
\r
88 DN(File, ALL, "CUSTOMIZE-ja.html" , ToDest, "doc\\CUSTOMIZE-ja.html" ),
\r
89 DN(File, ALL, "MANUAL-ja.html" , ToDest, "doc\\MANUAL-ja.html" ),
\r
90 DN(File, ALL, "README-ja.html" , ToDest, "doc\\README-ja.html" ),
\r
91 DN(File, ALL, "README.css" , ToDest, "doc\\README.css" ),
\r
92 DN(File, ALL, "syntax.txt" , ToDest, "doc\\syntax.txt" ),
\r
94 SN(File, ALL, "mayu-mode.el" , ToDest),
\r
96 SN(Dir , ALL, "contrib" , ToDest), // mkdir
\r
97 DN(File, ALL, "mayu-settings.txt" , ToDest, "contrib\\mayu-settings.txt"),
\r
98 DN(File, ALL, "dvorak.mayu" , ToDest, "contrib\\dvorak.mayu" ),
\r
99 DN(File, ALL, "DVORAKon109.mayu" , ToDest, "contrib\\DVORAKon109.mayu" ),
\r
100 DN(File, ALL, "keitai.mayu" , ToDest, "contrib\\keitai.mayu" ),
\r
101 DN(File, ALL, "ax.mayu" , ToDest, "contrib\\ax.mayu" ),
\r
102 DN(File, ALL, "98x1.mayu" , ToDest, "contrib\\98x1.mayu" ),
\r
103 DN(File, ALL, "109onAX.mayu" , ToDest, "contrib\\109onAX.mayu" ),
\r
105 SN(Dir , ALL, "Plugins" , ToDest), // mkdir
\r
109 enum KeyboardKind {
\r
115 static const StringResource g_strres[] = {
\r
116 #include "strres.h"
\r
120 bool g_wasExecutedBySFX = false; // Was setup executed by cab32 SFX ?
\r
121 Resource *g_resource; // resource information
\r
122 tstringi g_destDir; // destination directory
\r
125 ///////////////////////////////////////////////////////////////////////////////
\r
130 int message(int i_id, int i_flag, HWND i_hwnd = NULL)
\r
132 return MessageBox(i_hwnd, g_resource->loadString(i_id),
\r
133 g_resource->loadString(IDS_mayuSetup), i_flag);
\r
137 // driver service error
\r
138 void driverServiceError(DWORD i_err)
\r
141 case ERROR_ACCESS_DENIED:
\r
142 message(IDS_notAdministrator, MB_OK | MB_ICONSTOP);
\r
144 case ERROR_SERVICE_MARKED_FOR_DELETE:
\r
145 message(IDS_alreadyUninstalled, MB_OK | MB_ICONSTOP);
\r
149 int err = int(i_err);
\r
154 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
\r
155 NULL, i_err, 0, (LPTSTR)&errmsg, 0, NULL)) {
\r
157 _sntprintf(buf, NUMBER_OF(buf), _T("%s: %d: %s\n"),
\r
158 g_resource->loadString(IDS_error),
\r
161 MessageBox(NULL, buf, g_resource->loadString(IDS_mayuSetup),
\r
162 MB_OK | MB_ICONSTOP);
\r
164 message(IDS_error, MB_OK | MB_ICONSTOP);
\r
171 ///////////////////////////////////////////////////////////////////////////////
\r
179 bool m_doRegisterToStartMenu; // if register to the start menu
\r
180 bool m_doRegisterToStartUp; // if register to the start up
\r
185 Registry reg(DIR_REGISTRY_ROOT);
\r
186 CHECK_TRUE( reg.write(_T("dir"), g_destDir) );
\r
187 tstringi srcDir = getModuleDirectory();
\r
189 if (!installFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir,
\r
191 removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
\r
192 if (g_wasExecutedBySFX)
\r
193 removeSrcFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir);
\r
196 if (g_wasExecutedBySFX)
\r
197 removeSrcFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir);
\r
199 #if defined(_WINNT)
\r
201 createDriverService(_T("mayud"),
\r
202 g_resource->loadString(IDS_mayud),
\r
203 getDriverDirectory() + _T("\\mayud.sys"),
\r
204 _T("+Keyboard Class\0"),
\r
205 g_flags & Flag_Usb ? true : false);
\r
207 if (err != ERROR_SUCCESS) {
\r
208 driverServiceError(err);
\r
209 removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
\r
213 if (g_flags == Flag_Usb)
\r
214 CHECK_TRUE( reg.write(_T("isUsbDriver"), DWORD(1)) );
\r
218 if (m_doRegisterToStartMenu) {
\r
219 tstringi shortcut = getStartMenuName(loadString(IDS_shortcutName));
\r
220 if (!shortcut.empty())
\r
221 createLink((g_destDir + _T("\\mayu.exe")).c_str(), shortcut.c_str(),
\r
222 g_resource->loadString(IDS_shortcutName),
\r
223 g_destDir.c_str());
\r
225 if (m_doRegisterToStartUp) {
\r
226 tstringi shortcut = getStartUpName(loadString(IDS_shortcutName));
\r
227 if (!shortcut.empty())
\r
228 createLink((g_destDir + _T("\\mayu.exe")).c_str(), shortcut.c_str(),
\r
229 g_resource->loadString(IDS_shortcutName),
\r
230 g_destDir.c_str());
\r
234 reg.write(_T("layout"),
\r
235 (g_keyboardKind == KEYBOARD_KIND_109) ? _T("109") : _T("104"));
\r
238 createFileExtension(_T(".mayu"), _T("text/plain"),
\r
239 _T("mayu file"), g_resource->loadString(IDS_mayuFile),
\r
240 g_destDir + _T("\\mayu.exe,1"),
\r
241 g_resource->loadString(IDS_mayuShellOpen));
\r
244 createUninstallInformation(_T("mayu"), g_resource->loadString(IDS_mayu),
\r
245 g_destDir + _T("\\setup.exe -u"));
\r
247 if (g_flags == Flag_Usb) {
\r
248 if (message(IDS_copyFinishUsb, MB_YESNO | MB_ICONQUESTION, m_hwnd)
\r
252 // Get a token for this process.
\r
253 if (!OpenProcessToken(GetCurrentProcess(),
\r
254 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
\r
255 message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
\r
258 // Get the LUID for the shutdown privilege.
\r
259 TOKEN_PRIVILEGES tkp;
\r
260 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
\r
261 tkp.PrivilegeCount = 1; // one privilege to set
\r
262 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
\r
263 // Get the shutdown privilege for this process.
\r
264 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
\r
265 (PTOKEN_PRIVILEGES)NULL, 0);
\r
266 // Cannot test the return value of AdjustTokenPrivileges.
\r
267 if (GetLastError() != ERROR_SUCCESS) {
\r
268 message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
\r
271 // Shut down the system and force all applications to close.
\r
272 if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0)) {
\r
273 message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
\r
278 if (message(IDS_copyFinish, MB_YESNO | MB_ICONQUESTION, m_hwnd)
\r
280 ExitWindows(0, 0); // logoff
\r
287 BOOL wmInitDialog(HWND /* focus */, LPARAM /* lParam */) {
\r
288 setSmallIcon(m_hwnd, IDI_ICON_mayu);
\r
289 setBigIcon(m_hwnd, IDI_ICON_mayu);
\r
290 Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_path), g_destDir.c_str());
\r
291 HWND hwndCombo = GetDlgItem(m_hwnd, IDC_COMBO_keyboard);
\r
293 if (checkOs(SetupFile::W2k))
\r
296 ComboBox_AddString(hwndCombo,
\r
297 g_resource->loadString(IDS_keyboard109usb));
\r
298 ComboBox_AddString(hwndCombo,
\r
299 g_resource->loadString(IDS_keyboard104usb));
\r
302 ComboBox_AddString(hwndCombo, g_resource->loadString(IDS_keyboard109));
\r
303 ComboBox_AddString(hwndCombo, g_resource->loadString(IDS_keyboard104));
\r
305 ComboBox_SetCurSel(hwndCombo,
\r
306 (g_keyboardKind == KEYBOARD_KIND_109) ? 0 : 1);
\r
308 for (int i = IDS_note01; i <= IDS_note13; ++ i) {
\r
309 note += g_resource->loadString(i);
\r
311 Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_note), note.c_str());
\r
317 EndDialog(m_hwnd, 0);
\r
322 BOOL wmCommand(int /* notify_code */, int i_id, HWND /* hwnd_control */) {
\r
324 case IDC_BUTTON_browse: {
\r
325 _TCHAR folder[GANA_MAX_PATH];
\r
328 ZeroMemory(&bi, sizeof(bi));
\r
329 bi.hwndOwner = m_hwnd;
\r
330 bi.pidlRoot = NULL;
\r
331 bi.pszDisplayName = folder;
\r
332 bi.lpszTitle = g_resource->loadString(IDS_selectDir);
\r
333 ITEMIDLIST *browse = SHBrowseForFolder(&bi);
\r
334 if (browse != NULL) {
\r
335 if (SHGetPathFromIDList(browse, folder)) {
\r
336 if (createDirectories(folder))
\r
337 Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_path), folder);
\r
339 IMalloc *imalloc = NULL;
\r
340 if (SHGetMalloc(&imalloc) == NOERROR)
\r
341 imalloc->Free((void *)browse);
\r
347 _TCHAR buf[GANA_MAX_PATH];
\r
348 Edit_GetText(GetDlgItem(m_hwnd, IDC_EDIT_path), buf, NUMBER_OF(buf));
\r
350 g_destDir = normalizePath(buf);
\r
351 m_doRegisterToStartMenu =
\r
352 (IsDlgButtonChecked(m_hwnd, IDC_CHECK_registerStartMenu) ==
\r
354 m_doRegisterToStartUp =
\r
355 (IsDlgButtonChecked(m_hwnd, IDC_CHECK_registerStartUp) ==
\r
359 ComboBox_GetCurSel(GetDlgItem(m_hwnd, IDC_COMBO_keyboard));
\r
360 g_flags = SetupFile::Normal;
\r
362 if (checkOs(SetupFile::W2k))
\r
367 g_keyboardKind = KEYBOARD_KIND_109;
\r
368 g_flags = Flag_Usb;
\r
371 g_keyboardKind = KEYBOARD_KIND_104;
\r
372 g_flags = Flag_Usb;
\r
376 g_keyboardKind = KEYBOARD_KIND_109;
\r
379 g_keyboardKind = KEYBOARD_KIND_104;
\r
388 g_keyboardKind = KEYBOARD_KIND_109;
\r
391 g_keyboardKind = KEYBOARD_KIND_104;
\r
398 if (g_flags == Flag_Usb)
\r
399 if (message(IDS_usbWarning, MB_OKCANCEL | MB_ICONWARNING, m_hwnd)
\r
404 if (createDirectories(g_destDir.c_str()))
\r
405 EndDialog(m_hwnd, install());
\r
407 message(IDS_invalidDirectory, MB_OK | MB_ICONSTOP, m_hwnd);
\r
409 message(IDS_mayuEmpty, MB_OK, m_hwnd);
\r
414 CHECK_TRUE( EndDialog(m_hwnd, 0) );
\r
422 DlgMain(HWND i_hwnd)
\r
424 m_doRegisterToStartMenu(false),
\r
425 m_doRegisterToStartUp(false) {
\r
428 static BOOL CALLBACK dlgProc(HWND i_hwnd, UINT i_message,
\r
429 WPARAM i_wParam, LPARAM i_lParam) {
\r
431 getUserData(i_hwnd, &wc);
\r
433 switch (i_message) {
\r
434 case WM_INITDIALOG:
\r
435 wc = setUserData(i_hwnd, new DlgMain(i_hwnd));
\r
436 return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
\r
439 switch (i_message) {
\r
441 return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
\r
442 reinterpret_cast<HWND>(i_lParam));
\r
444 return wc->wmClose();
\r
455 // (in this function, we cannot use any resource, so we use strres[])
\r
458 if (IDYES != message(IDS_removeOk, MB_YESNO | MB_ICONQUESTION))
\r
461 #if defined(_WINNT)
\r
462 DWORD err = removeDriverService(_T("mayud"));
\r
463 if (err != ERROR_SUCCESS) {
\r
464 driverServiceError(err);
\r
469 DeleteFile(getStartMenuName(
\r
470 g_resource->loadString(IDS_shortcutName)).c_str());
\r
471 DeleteFile(getStartUpName(
\r
472 g_resource->loadString(IDS_shortcutName)).c_str());
\r
474 removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
\r
475 removeFileExtension(_T(".mayu"), _T("mayu file"));
\r
476 removeUninstallInformation(_T("mayu"));
\r
478 Registry::remove(DIR_REGISTRY_ROOT);
\r
479 Registry::remove(HKEY_CURRENT_USER, _T("Software\\GANAware\\mayu"));
\r
481 message(IDS_removeFinish, MB_OK | MB_ICONINFORMATION);
\r
486 int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* hPrevInstance */,
\r
487 LPTSTR /* lpszCmdLine */, int /* nCmdShow */)
\r
489 CoInitialize(NULL);
\r
491 g_hInst = i_hInstance;
\r
492 Resource resource(g_strres);
\r
493 g_resource = &resource;
\r
497 #if defined(_WINNT)
\r
498 !checkOs(SetupFile::NT)
\r
499 #elif defined(_WIN95)
\r
500 !checkOs(SetupFile::W9x)
\r
505 message(IDS_invalidOS, MB_OK | MB_ICONSTOP);
\r
511 (resource.getLocale() == LOCALE_Japanese_Japan_932) ?
\r
512 KEYBOARD_KIND_109 : KEYBOARD_KIND_104;
\r
515 tstringi programFiles; // "Program Files" directory
\r
516 Registry::read(HKEY_LOCAL_MACHINE,
\r
517 _T("Software\\Microsoft\\Windows\\CurrentVersion"),
\r
518 _T("ProgramFilesDir"), &programFiles);
\r
519 Registry::read(DIR_REGISTRY_ROOT, _T("dir"), &g_destDir,
\r
520 programFiles + _T("\\mayu"));
\r
524 if (__argc == 2 && _tcsicmp(__targv[1], _T("-u")) == 0)
\r
525 retval = uninstallStep1(_T("-u"));
\r
527 HANDLE mutexPrevVer = CreateMutex(
\r
528 (SECURITY_ATTRIBUTES *)NULL, TRUE,
\r
529 MUTEX_MAYU_EXCLUSIVE_RUNNING);
\r
530 if (GetLastError() == ERROR_ALREADY_EXISTS) { // mayu is running
\r
531 message(IDS_mayuRunning, MB_OK | MB_ICONSTOP);
\r
533 // is mayu running ?
\r
534 HANDLE mutex = CreateMutex(
\r
535 (SECURITY_ATTRIBUTES *)NULL, TRUE,
\r
536 addSessionId(MUTEX_MAYU_EXCLUSIVE_RUNNING).c_str());
\r
537 if (GetLastError() == ERROR_ALREADY_EXISTS) { // mayu is running
\r
538 message(IDS_mayuRunning, MB_OK | MB_ICONSTOP);
\r
539 } else if (__argc == 3 && _tcsicmp(__targv[1], _T("-u")) == 0) {
\r
540 uninstallStep2(__targv[2]);
\r
541 retval = uninstall();
\r
542 } else if (__argc == 2 && _tcsicmp(__targv[1], _T("-s")) == 0) {
\r
543 g_wasExecutedBySFX = true;
\r
544 retval = DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_main), NULL,
\r
546 } else if (__argc == 1) {
\r
547 retval = DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_main), NULL,
\r
550 CloseHandle(mutex);
\r
552 CloseHandle(mutexPrevVer);
\r