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; }
HWND ShowHelpV(HWND hOwner, void *help_dir, void *help_file, void *section) { #if defined(ENABLE_HTML_HELP) static HWND (WINAPI *pHtmlHelpV)(HWND, void *, UINT, DWORD_PTR) = NULL; if (pHtmlHelpV == NULL) { DWORD cookie=0; HMODULE hHtmlHelp = TLoadLibrary("hhctrl.ocx"); if (hHtmlHelp) pHtmlHelpV = (HWND (WINAPI *)(HWND, void *, UINT, DWORD_PTR)) ::GetProcAddress(hHtmlHelp, IS_WINNT_V ? "HtmlHelpW" : "HtmlHelpA"); if (pHtmlHelpV) pHtmlHelpV(NULL, NULL, HH_INITIALIZE, (DWORD)&cookie); } if (pHtmlHelpV) { WCHAR path[MAX_PATH]; MakePathV(path, help_dir, help_file); if (section) strcpyV(MakeAddr(path, strlenV(path)), section); return pHtmlHelpV(hOwner, path, HH_DISPLAY_TOC, 0); } #endif return NULL; }
BOOL TInstDlg::RunAsAdmin(BOOL is_imme) { SHELLEXECUTEINFOW sei = {0}; WCHAR buf[MAX_PATH * 2]; WCHAR exe_path[MAX_PATH]; WCHAR setup_path[MAX_PATH]; WCHAR app_data[MAX_PATH]; WCHAR virtual_store[MAX_PATH]; WCHAR fastcopy_dir[MAX_PATH]; WCHAR *fastcopy_dirname = NULL; int len; ::GetModuleFileNameW(NULL, exe_path, sizeof(exe_path)); if (!(len = GetDlgItemTextV(FILE_EDIT, setup_path, MAX_PATH))) return FALSE; if (GetChar(setup_path, len-1) == '\\') SetChar(setup_path, len-1, 0); if (!GetFullPathNameW(setup_path, MAX_PATH, fastcopy_dir, &fastcopy_dirname)) return FALSE; if (!TSHGetSpecialFolderPathV(NULL, buf, CSIDL_APPDATA, FALSE)) return FALSE; MakePathV(app_data, buf, fastcopy_dirname); strcpyV(buf, fastcopy_dir); #ifdef _WIN64 ConvertToX86Dir(buf); #endif if (!TMakeVirtualStorePathV(buf, virtual_store)) return FALSE; sprintfV(buf, L"/runas=%p,%d,%d,%d,%d,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"", hWnd, cfg.mode, is_imme, cfg.programLink, cfg.desktopLink, cfg.startMenu, cfg.deskTop, setup_path, app_data, virtual_store); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpVerb = L"runas"; sei.lpFile = exe_path; sei.lpDirectory = NULL; sei.nShow = SW_NORMAL; sei.lpParameters = buf; EnableWindow(FALSE); BOOL ret = ::ShellExecuteExW(&sei); EnableWindow(TRUE); return ret; }
BOOL ConvertToX86Dir(void *target) { WCHAR buf[MAX_PATH]; WCHAR buf86[MAX_PATH]; int len; if (!TSHGetSpecialFolderPathV(NULL, buf, CSIDL_PROGRAM_FILES, FALSE)) return FALSE; len = strlenV(buf); SetChar(buf, len++, '\\'); SetChar(buf, len, 0); if (strnicmpV(buf, target, len)) return FALSE; if (!TSHGetSpecialFolderPathV(NULL, buf86, CSIDL_PROGRAM_FILESX86, FALSE)) return FALSE; MakePathV(buf, buf86, MakeAddr(target, len)); strcpyV(target, buf); return TRUE; }
BOOL NetPlaceConvertV(void *src, void *dst) { IShellLink *shellLink; // VC4 には IShellLink ANSI 版しか定義がないための暫定処置 IPersistFile *persistFile; // (実際は NT系では IShellLinkW を呼び出し) WCHAR wSrcBuf[MAX_PATH], wDstBuf[MAX_PATH]; WCHAR *wSrc = IS_WINNT_V ? (WCHAR *)src : wSrcBuf; WCHAR *wDst = IS_WINNT_V ? wDstBuf : (WCHAR *)dst; BOOL ret = FALSE; DWORD attr, attr_mask = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY; if (SHGetPathFromIDListV == NULL) // NT4.0 系は無視 return FALSE; if ((attr = GetFileAttributesV(src)) == 0xffffffff || (attr & attr_mask) != attr_mask) return FALSE; // ディレクトリかつronly でないものは関係ない if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkV, (void **)&shellLink))) { if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (!IS_WINNT_V) AtoW((char *)src, wSrc, MAX_PATH); if (SUCCEEDED(persistFile->Load(wSrc, STGM_READ))) { if (SUCCEEDED(shellLink->GetPath((char *)wDst, MAX_PATH, 0, SLGP_UNCPRIORITY))) { if (!IS_WINNT_V) WtoA(wDst, (char *)wDstBuf, MAX_PATH); MakePathV(dst, wDstBuf, EMPTY_STR_V); ret = TRUE; } } persistFile->Release(); } shellLink->Release(); } return ret; }
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; }