/* メインダイアログ用 WM_INITDIALOG 処理ルーチン */ BOOL TInstDlg::EvCreate(LPARAM lParam) { GetWindowRect(&rect); int cx = ::GetSystemMetrics(SM_CXFULLSCREEN), cy = ::GetSystemMetrics(SM_CYFULLSCREEN); int xsize = rect.right - rect.left, ysize = rect.bottom - rect.top; ::SetClassLong(hWnd, GCL_HICON, (LONG_PTR)::LoadIcon(TApp::GetInstance(), (LPCSTR)SETUP_ICON)); MoveWindow((cx - xsize)/2, (cy - ysize)/2, xsize, ysize, TRUE); Show(); // プロパティシートの生成 staticText.AttachWnd(GetDlgItem(INSTALL_STATIC)); propertySheet = new TInstSheet(this, &cfg); // 現在ディレクトリ設定 char buf[MAX_PATH], setupDir[MAX_PATH]; TRegistry reg(HKEY_LOCAL_MACHINE, BY_MBCS); // タイトル設定 if (IsWinVista() && TIsUserAnAdmin()) { GetWindowText(buf, sizeof(buf)); strcat(buf, " (Admin)"); SetWindowText(buf); } // Program Filesのパス取り出し if (reg.OpenKey(REGSTR_PATH_SETUP)) { if (reg.GetStr(REGSTR_PROGRAMFILES, buf, sizeof(buf))) MakePath(setupDir, buf, FASTCOPY); reg.CloseKey(); } // 既にセットアップされている場合は、セットアップディレクトリを読み出す if (reg.OpenKey(REGSTR_PATH_UNINSTALL)) { if (reg.OpenKey(FASTCOPY)) { if (reg.GetStr(REGSTR_VAL_UNINSTALLER_COMMANDLINE, setupDir, sizeof(setupDir))) { GetParentDir(setupDir, setupDir); } reg.CloseKey(); } reg.CloseKey(); } if (!cfg.startMenu || !cfg.deskTop) { GetShortcutPath(&cfg); } SetDlgItemText(FILE_EDIT, cfg.setupDir ? toA(cfg.setupDir) : setupDir); CheckDlgButton(cfg.mode == SETUP_MODE ? SETUP_RADIO : UNINSTALL_RADIO, 1); ChangeMode(); if (cfg.runImme) PostMessage(WM_COMMAND, MAKEWORD(IDOK, 0), 0); return TRUE; }
BOOL ConvertVirtualStoreConf(void *execDirV, void *userDirV, void *virtualDirV) { #define FASTCOPY_INI_W L"FastCopy.ini" WCHAR buf[MAX_PATH]; WCHAR org_ini[MAX_PATH], usr_ini[MAX_PATH], vs_ini[MAX_PATH]; BOOL is_admin = TIsUserAnAdmin(); BOOL is_exists; MakePathV(usr_ini, userDirV, FASTCOPY_INI_W); MakePathV(org_ini, execDirV, FASTCOPY_INI_W); #ifdef _WIN64 ConvertToX86Dir(org_ini); #endif is_exists = GetFileAttributesV(usr_ini) != 0xffffffff; if (!is_exists) { CreateDirectoryV(userDirV, NULL); } if (virtualDirV && GetChar(virtualDirV, 0)) { MakePathV(vs_ini, virtualDirV, FASTCOPY_INI_W); if (GetFileAttributesV(vs_ini) != 0xffffffff) { if (!is_exists) { is_exists = ::CopyFileW(vs_ini, usr_ini, TRUE); } MakePathV(buf, userDirV, L"to_OldDir(VirtualStore).lnk"); SymLinkV(virtualDirV, buf); sprintfV(buf, L"%s.obsolete", vs_ini); MoveFileW(vs_ini, buf); if (GetFileAttributesV(vs_ini) != 0xffffffff) { DeleteFileV(vs_ini); } } } if ((is_admin || !is_exists) && GetFileAttributesV(org_ini) != 0xffffffff) { if (!is_exists) { is_exists = ::CopyFileW(org_ini, usr_ini, TRUE); } if (is_admin) { sprintfV(buf, L"%s.obsolete", org_ini); MoveFileW(org_ini, buf); if (GetFileAttributesV(org_ini) != 0xffffffff) { DeleteFileV(org_ini); } } } MakePathV(buf, userDirV, L"to_ExeDir.lnk"); // if (GetFileAttributesV(buf) == 0xffffffff) { SymLinkV(execDirV, buf); // } return TRUE; }
/* メインダイアログクラス */ TInstDlg::TInstDlg(char *cmdLine) : TDlg(INSTALL_DIALOG), staticText(this) { cfg.mode = strcmp(cmdLine, "/r") ? SETUP_MODE : UNINSTALL_MODE; cfg.programLink = TRUE; cfg.desktopLink = TRUE; cfg.hOrgWnd = NULL; cfg.runImme = FALSE; cfg.appData = NULL; cfg.setupDir = NULL; cfg.startMenu = NULL; cfg.deskTop = NULL; cfg.virtualDir= NULL; if (IS_WINNT_V && TIsUserAnAdmin()) { WCHAR *p = wcsstr((WCHAR *)GetCommandLineV(), L"/runas="); if (p) { if (p && (p = wcstok(p+7, L","))) cfg.hOrgWnd = (HWND)wcstoul(p, 0, 16); if (p && (p = wcstok(NULL, L","))) cfg.mode = (InstMode)wcstoul(p, 0, 10); if (p && (p = wcstok(NULL, L","))) cfg.runImme = wcstoul(p, 0, 10); if (p && (p = wcstok(NULL, L","))) cfg.programLink = wcstoul(p, 0, 10); if (p && (p = wcstok(NULL, L","))) cfg.desktopLink = wcstoul(p, 0, 10); if (p && (p = wcstok(NULL, L"\""))) cfg.startMenu = p; if (p) p = wcstok(NULL, L"\""); if (p && (p = wcstok(NULL, L"\""))) cfg.deskTop = p; if (p) p = wcstok(NULL, L"\""); if (p && (p = wcstok(NULL, L"\""))) cfg.setupDir = p; if (p) p = wcstok(NULL, L"\""); if (p && (p = wcstok(NULL, L"\""))) cfg.appData = p; if (p) p = wcstok(NULL, L"\""); if (p && (p = wcstok(NULL, L"\""))) cfg.virtualDir= p; if (p) { ::PostMessage(cfg.hOrgWnd, WM_CLOSE, 0, 0); } else { cfg.runImme = FALSE; ::PostQuitMessage(0); } } } }
BOOL TUninstDlg::UnInstall(void) { // 現在、起動中の ipmsg を終了 int st = TerminateIPMsg(); if (st == 1) return FALSE; if (st == 2) { if (!IsWinVista() || TIsUserAnAdmin() || !TIsEnableUAC()) { MessageBox(GetLoadStr(IDS_CANTTERMINATE), UNINSTALL_STR); return FALSE; } if (MessageBox(GetLoadStr(IDS_REQUIREADMIN_TERM), "", MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; return RunAsAdmin(hWnd); } if (!runasWnd && MessageBox(GetLoadStr(IDS_START), UNINSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; // 公開鍵削除 if (IsDlgButtonChecked(DELPUBKEY_CHECK)) { BOOL need_admin = FALSE; char contName[MAX_PATH_U8], userName[MAX_PATH_U8]; DWORD size = sizeof(userName); ::GetUserName(userName, &size); ::wsprintf(contName, "ipmsg.rsa2048.%s", userName); if (!DeleteKeySet(MS_ENHANCED_PROV, contName, CRYPT_MACHINE_KEYSET) || !DeleteKeySet(MS_ENHANCED_PROV, contName, 0)) need_admin = TRUE; ::wsprintf(contName, "ipmsg.rsa1024.%s", userName); if (!DeleteKeySet(MS_ENHANCED_PROV, contName, CRYPT_MACHINE_KEYSET) || !DeleteKeySet(MS_ENHANCED_PROV, contName, 0)) need_admin = TRUE; ::wsprintf(contName, "ipmsg.rsa512.%s", userName); if (!DeleteKeySet(MS_DEF_PROV, contName, CRYPT_MACHINE_KEYSET) || !DeleteKeySet(MS_DEF_PROV, contName, 0)) need_admin = TRUE; if (need_admin) { if (IsWinVista() && !TIsUserAnAdmin() && TIsEnableUAC()) { if (MessageBox(GetLoadStr(IDS_REQUIREADMIN_PUBKEY), "", MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; return RunAsAdmin(hWnd); } } } // スタートアップ&デスクトップから削除 TRegistry reg(HKEY_CURRENT_USER); if (reg.OpenKey(REGSTR_SHELLFOLDERS)) { char buf[MAX_PATH_U8]; char *regStr[] = { REGSTR_STARTUP, REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL }; for (int i=0; regStr[i]; i++) { if (reg.GetStr(regStr[i], buf, sizeof(buf))) { if (i == 0) RemoveSameLink(buf); ::wsprintf(buf + strlen(buf), "\\%s", IPMSG_SHORTCUT_NAME); DeleteLink(buf); } } reg.CloseKey(); } // レジストリからユーザー設定情報を削除 if (reg.ChangeApp(HSTOOLS_STR)) reg.DeleteChildTree(GetLoadStr(IDS_REGIPMSG)); // レジストリからアプリケーション情報を削除 char setupDir[MAX_PATH_U8]; // セットアップディレクトリ情報を保存 GetDlgItemTextU8(RESETUP_EDIT, setupDir, sizeof(setupDir)); reg.ChangeTopKey(HKEY_LOCAL_MACHINE); if (reg.OpenKey(REGSTR_PATH_APPPATHS)) { if (reg.OpenKey(IPMSG_EXENAME)) { reg.GetStr(REGSTR_PATH, setupDir, sizeof(setupDir)); reg.CloseKey(); } reg.DeleteKey(IPMSG_EXENAME); reg.CloseKey(); } // レジストリからアンインストール情報を削除 if (reg.OpenKey(REGSTR_PATH_UNINSTALL)) { reg.DeleteKey(IPMSG_NAME); reg.CloseKey(); } // 終了メッセージ MessageBox(GetLoadStr(IDS_UNINSTCOMPLETE)); // インストールディレクトリを開く if (GetDriveTypeEx(setupDir) != DRIVE_REMOTE) ShellExecuteU8(NULL, NULL, setupDir, 0, 0, SW_SHOW); ::PostQuitMessage(0); return TRUE; }
BOOL TInstDlg::UnInstall(void) { char buf[MAX_PATH]; char setupDir[MAX_PATH] = ""; ::GetModuleFileName(NULL, setupDir, sizeof(setupDir)); GetParentDir(setupDir, setupDir); BOOL is_shext = FALSE; is_shext = ShellExtFunc(setupDir, CHECK_SHELLEXT); if (is_shext && IsWinVista() && !TIsUserAnAdmin()) { RunAsAdmin(TRUE); return TRUE; } if (MessageBox(GetLoadStr(IDS_START), UNINSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; // スタートメニュー&デスクトップから削除 TRegistry reg(HKEY_CURRENT_USER, BY_MBCS); if (reg.OpenKey(REGSTR_SHELLFOLDERS)) { char *regStr[] = { REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL }; for (int cnt=0; regStr[cnt] != NULL; cnt++) { if (reg.GetStr(regStr[cnt], buf, sizeof(buf))) { if (cnt == 0) RemoveSameLink(buf); ::wsprintf(buf + strlen(buf), "\\%s", FASTCOPY_SHORTCUT); if (IS_WINNT_V) { Wstr w_buf(buf, BY_MBCS); DeleteLinkV(w_buf.Buf()); } else { DeleteLinkV(buf); } } } reg.CloseKey(); } ShellExtFunc(setupDir, UNREGISTER_SHELLEXT); #ifdef _WIN64 if (IS_WINNT_V) { #else if (IS_WINNT_V && TIsWow64()) { #endif SHELLEXECUTEINFO sei = { sizeof(sei) }; char arg[1024]; sprintf(arg, "\"%s\\%s\",%s", setupDir, CURRENT_SHEXTDLL_EX, "DllUnregisterServer"); sei.lpFile = "rundll32.exe"; sei.lpParameters = arg; ShellExecuteEx(&sei); } // レジストリからアンインストール情報を削除 if (reg.OpenKey(REGSTR_PATH_UNINSTALL)) { if (reg.OpenKey(FASTCOPY)) { if (reg.GetStr(REGSTR_VAL_UNINSTALLER_COMMANDLINE, setupDir, sizeof(setupDir))) GetParentDir(setupDir, setupDir); reg.CloseKey(); } reg.DeleteKey(FASTCOPY); reg.CloseKey(); } // 終了メッセージ MessageBox(is_shext ? GetLoadStr(IDS_UNINSTSHEXTFIN) : GetLoadStr(IDS_UNINSTFIN)); // インストールディレクトリを開く if (GetFileAttributes(setupDir) != 0xffffffff) { ::ShellExecute(NULL, NULL, setupDir, 0, 0, SW_SHOW); } // AppDataディレクトリを開く if (IsWinVista()) { WCHAR wbuf[MAX_PATH] = L"", upath[MAX_PATH] = L""; WCHAR fastcopy_dir[MAX_PATH] = L"", *fastcopy_dirname = NULL; Wstr w_setup(setupDir); if (TIsVirtualizedDirV(w_setup.Buf())) { if (TSHGetSpecialFolderPathV(NULL, wbuf, CSIDL_APPDATA, FALSE)) { GetFullPathNameW(w_setup.Buf(), MAX_PATH, fastcopy_dir, &fastcopy_dirname); MakePathV(upath, wbuf, fastcopy_dirname); if (GetFileAttributesV(upath) != 0xffffffff) { ::ShellExecuteW(NULL, NULL, upath, 0, 0, SW_SHOW); } } } } ::PostQuitMessage(0); return TRUE; } BOOL ReadLink(char *src, char *dest, char *arg=NULL) { IShellLink *shellLink; // 実際は IShellLinkA or IShellLinkW IPersistFile *persistFile; WCHAR wbuf[MAX_PATH]; BOOL ret = FALSE; if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&shellLink))) { if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { AtoW(src, wbuf, MAX_PATH); if (SUCCEEDED(persistFile->Load(wbuf, STGM_READ))) { if (SUCCEEDED(shellLink->GetPath(dest, MAX_PATH, NULL, 0))) { if (arg) { shellLink->GetArguments(arg, MAX_PATH); } ret = TRUE; } } persistFile->Release(); } shellLink->Release(); } return ret; }
BOOL TInstDlg::Install(void) { char buf[MAX_PATH], setupDir[MAX_PATH], setupPath[MAX_PATH]; BOOL is_delay_copy = FALSE; int len; // インストールパス設定 len = GetDlgItemText(FILE_EDIT, setupDir, sizeof(setupDir)); if (GetChar(setupDir, len-1) == '\\') SetChar(setupDir, len-1, 0); Wstr w_setup(setupDir); if (IsWinVista() && TIsVirtualizedDirV(w_setup.Buf())) { if (!TIsUserAnAdmin()) { return RunAsAdmin(TRUE); } else if (cfg.runImme && cfg.setupDir && lstrcmpiV(w_setup.Buf(), cfg.setupDir)) { return MessageBox(GetLoadStr(IDS_ADMINCHANGE)), FALSE; } } CreateDirectory(setupDir, NULL); DWORD attr = GetFileAttributes(setupDir); if (attr == 0xffffffff || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) return MessageBox(GetLoadStr(IDS_NOTCREATEDIR)), FALSE; MakePath(setupPath, setupDir, FASTCOPY_EXE); if (MessageBox(GetLoadStr(IDS_START), INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; // ファイルコピー if (cfg.mode == SETUP_MODE) { char installPath[MAX_PATH], orgDir[MAX_PATH]; ::GetModuleFileName(NULL, orgDir, sizeof(orgDir)); GetParentDir(orgDir, orgDir); for (int cnt=0; SetupFiles[cnt] != NULL; cnt++) { MakePath(buf, orgDir, SetupFiles[cnt]); MakePath(installPath, setupDir, SetupFiles[cnt]); if (MiniCopy(buf, installPath) || IsSameFile(buf, installPath)) continue; if ((strcmp(SetupFiles[cnt], CURRENT_SHEXTDLL_EX) == 0 || strcmp(SetupFiles[cnt], CURRENT_SHEXTDLL) == 0) && DelayCopy(buf, installPath)) { is_delay_copy = TRUE; continue; } return MessageBox(installPath, GetLoadStr(IDS_NOTCREATEFILE)), FALSE; } } // スタートメニュー&デスクトップに登録 char *linkPath[] = { toA(cfg.startMenu, TRUE), toA(cfg.deskTop, TRUE), NULL }; BOOL execFlg[] = { cfg.programLink, cfg.desktopLink, NULL }; for (int cnt=0; linkPath[cnt]; cnt++) { strcpy(buf, linkPath[cnt]); if (cnt != 0 || RemoveSameLink(linkPath[cnt], buf) == FALSE) { ::wsprintf(buf + strlen(buf), "\\%s", FASTCOPY_SHORTCUT); } if (execFlg[cnt]) { if (IS_WINNT_V) { Wstr w_setup(setupPath, BY_MBCS); Wstr w_buf(buf, BY_MBCS); SymLinkV(w_setup.Buf(), w_buf.Buf()); } else { SymLinkV(setupPath, buf); } } else { if (IS_WINNT_V) { Wstr w_buf(buf, BY_MBCS); DeleteLinkV(w_buf.Buf()); } else { DeleteLinkV(buf); } } } #if 0 // レジストリにアンインストール情報を登録 if (reg.OpenKey(REGSTR_PATH_UNINSTALL)) { if (reg.CreateKey(FASTCOPY)) { MakePath(buf, setupDir, INSTALL_EXE); strcat(buf, " /r"); reg.SetStr(REGSTR_VAL_UNINSTALLER_DISPLAYNAME, FASTCOPY); reg.SetStr(REGSTR_VAL_UNINSTALLER_COMMANDLINE, buf); reg.CloseKey(); } reg.CloseKey(); } #endif if (IsWinVista() && TIsVirtualizedDirV(w_setup.Buf())) { WCHAR wbuf[MAX_PATH] = L"", old_path[MAX_PATH] = L"", usr_path[MAX_PATH] = L""; WCHAR fastcopy_dir[MAX_PATH], *fastcopy_dirname = NULL; GetFullPathNameW(w_setup.Buf(), MAX_PATH, fastcopy_dir, &fastcopy_dirname); if (cfg.appData) { strcpyV(usr_path, cfg.appData); } else { TSHGetSpecialFolderPathV(NULL, wbuf, CSIDL_APPDATA, FALSE); MakePathV(usr_path, wbuf, fastcopy_dirname); } ConvertVirtualStoreConf(w_setup.Buf(), usr_path, cfg.virtualDir); } // コピーしたアプリケーションを起動 const char *msg = GetLoadStr(is_delay_copy ? IDS_DELAYSETUPCOMPLETE : IDS_SETUPCOMPLETE); int flg = MB_OKCANCEL|MB_ICONINFORMATION; if (IsWin7()) { msg = Fmt("%s%s", msg, GetLoadStr(IDS_COMPLETE_WIN7)); } TLaunchDlg dlg(msg, this); UINT id; if ((id = dlg.Exec()) == IDOK || id == LAUNCH_BUTTON) { char *arg = (id == LAUNCH_BUTTON) ? "/install" : ""; ShellExecute(NULL, "open", setupPath, arg, setupDir, SW_SHOW); } ::PostQuitMessage(0); return TRUE; }