📄 install.cpp
字号:
static char *install_id =
"@(#)Copyright (C) H.Shirouzu 2005-2006 install.cpp Ver1.33";
/* ========================================================================
Project Name : Installer for FastCopy
Module Name : Installer Application Class
Create : 2005-02-02(Wed)
Update : 2006-02-26(Sun)
Copyright : H.Shirouzu
Reference :
======================================================================== */
#include "../tlib.h"
#include "instrc.h"
#include "install.h"
char *SetupFiles [] = { FASTCOPY_EXE, INSTALL_EXE, README_TXT, HELP_CHM, CURRENT_SHEXTDLL, NULL };
/*
WinMain
*/
int WINAPI WinMain(HINSTANCE hI, HINSTANCE, LPSTR cmdLine, int nCmdShow)
{
return TInstApp(hI, cmdLine, nCmdShow).Run();
}
/*
僀儞僗僩乕儖傾僾儕働乕僔儑儞僋儔僗
*/
TInstApp::TInstApp(HINSTANCE _hI, LPSTR _cmdLine, int _nCmdShow) : TApp(_hI, _cmdLine, _nCmdShow)
{
}
TInstApp::~TInstApp()
{
}
void TInstApp::InitWindow(void)
{
TDlg *maindlg = new TInstDlg(cmdLine);
mainWnd = maindlg;
maindlg->Create();
}
/*
儊僀儞僟僀傾儘僌僋儔僗
*/
TInstDlg::TInstDlg(char *cmdLine) : TDlg(INSTALL_DIALOG), staticText(this)
{
cfg.mode = strcmp(cmdLine, "/r") ? SETUP_MODE : UNINSTALL_MODE;
cfg.programLink = TRUE;
cfg.desktopLink = TRUE;
}
TInstDlg::~TInstDlg()
{
}
/*
儊僀儞僟僀傾儘僌梡 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)::LoadIcon(TApp::GetInstance(), (LPCSTR)SETUP_ICON));
MoveWindow((cx - xsize)/2, (cy - ysize)/2, xsize, ysize, TRUE);
Show();
// 僾儘僷僥傿僔乕僩偺惗惉
staticText.CreateByWnd(GetDlgItem(INSTALL_STATIC));
propertySheet = new TInstSheet(&staticText, &cfg);
// 尰嵼僨傿儗僋僩儕愝掕
char buf[MAX_PATH], setupDir[MAX_PATH];
TRegistry reg(HKEY_LOCAL_MACHINE);
// 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();
}
SetDlgItemText(FILE_EDIT, setupDir);
CheckDlgButton(cfg.mode == SETUP_MODE ? SETUP_RADIO : UNINSTALL_RADIO, 1);
ChangeMode();
return TRUE;
}
/*
儊僀儞僟僀傾儘僌梡 WM_COMMAND 張棟儖乕僠儞
*/
BOOL TInstDlg::EvCommand(WORD wNotifyCode, WORD wID, LPARAM hwndCtl)
{
switch (wID) {
case IDOK:
propertySheet->GetData();
if (cfg.mode == UNINSTALL_MODE)
UnInstall();
else
Install();
return TRUE;
case IDCANCEL:
::PostQuitMessage(0);
return TRUE;
case FILE_BUTTON:
BrowseDirDlg(this, FILE_EDIT, "Select Install Directory");
return TRUE;
case SETUP_RADIO:
case UNINSTALL_RADIO:
if (wNotifyCode == BN_CLICKED)
ChangeMode();
return TRUE;
}
return FALSE;
}
void TInstDlg::ChangeMode(void)
{
cfg.mode = IsDlgButtonChecked(SETUP_RADIO) ? SETUP_MODE : UNINSTALL_MODE;
::EnableWindow(GetDlgItem(FILE_EDIT), cfg.mode == SETUP_MODE);
propertySheet->Paste();
}
BOOL IsSameFile(char *src, char *dst)
{
WIN32_FIND_DATA src_dat, dst_dat;
HANDLE hFind;
if ((hFind = ::FindFirstFile(src, &src_dat)) == INVALID_HANDLE_VALUE)
return FALSE;
::FindClose(hFind);
if ((hFind = ::FindFirstFile(dst, &dst_dat)) == INVALID_HANDLE_VALUE)
return FALSE;
::FindClose(hFind);
if (src_dat.nFileSizeLow != dst_dat.nFileSizeLow || src_dat.nFileSizeHigh != dst_dat.nFileSizeHigh)
return FALSE;
return (*(_int64 *)&dst_dat.ftLastWriteTime == *(_int64 *)&src_dat.ftLastWriteTime) ||
// src 偐 dst 偺僞僀儉僗僞儞僾偺嵟彫扨埵偑 1 昩埲忋乮FAT or SAMBA 摍偺壜擻惈乯偱偐偮...
// 僞僀儉僗僞儞僾偺嵎偑 2 昩埲撪側傜丄摨堦僞僀儉僗僞儞僾偲傒側偡
((*(_int64 *)&src_dat.ftLastWriteTime % 10000000) == 0 || (*(_int64 *)&dst_dat.ftLastWriteTime % 10000000) == 0) &&
*(_int64 *)&dst_dat.ftLastWriteTime + 20000000 >= *(_int64 *)&src_dat.ftLastWriteTime &&
*(_int64 *)&dst_dat.ftLastWriteTime - 20000000 <= *(_int64 *)&src_dat.ftLastWriteTime;
}
BOOL MiniCopy(char *src, char *dst)
{
HANDLE hSrc, hDst, hMap;
BOOL ret = FALSE;
DWORD srcSize, dstSize;
void *view;
FILETIME ct, la, ft;
if ((hSrc = ::CreateFile(src, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
return FALSE;
srcSize = ::GetFileSize(hSrc, 0);
if ((hDst = ::CreateFile(dst, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
if ((hMap = ::CreateFileMapping(hSrc, 0, PAGE_READONLY, 0, 0, 0)) != NULL) {
if ((view = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) {
if (::WriteFile(hDst, view, srcSize, &dstSize, 0) && srcSize == dstSize) {
if (::GetFileTime(hSrc, &ct, &la, &ft))
::SetFileTime(hDst, &ct, &la, &ft);
ret = TRUE;
}
::UnmapViewOfFile(view);
}
::CloseHandle(hMap);
}
::CloseHandle(hDst);
}
::CloseHandle(hSrc);
return ret;
}
BOOL DelayCopy(char *src, char *dst)
{
char tmp_file[MAX_PATH];
BOOL ret = FALSE;
wsprintf(tmp_file, "%s.new", dst);
if (MiniCopy(src, tmp_file) == FALSE)
return FALSE;
if (IsWinNT()) {
ret = ::MoveFileEx(tmp_file, dst, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
}
else {
char win_ini[MAX_PATH], short_tmp[MAX_PATH], short_dst[MAX_PATH];
::GetShortPathName(tmp_file, short_tmp, sizeof(short_tmp));
::GetShortPathName(dst, short_dst, sizeof(short_dst));
::GetWindowsDirectory(win_ini, sizeof(win_ini));
strcat(win_ini, "\\WININIT.INI");
// WritePrivateProfileString("Rename", "NUL", short_dst, win_ini); 昁梫側偝偦
ret = WritePrivateProfileString("Rename", short_dst, short_tmp, win_ini);
}
return ret;
}
BOOL TInstDlg::Install(void)
{
char buf[MAX_PATH], setupDir[MAX_PATH], setupPath[MAX_PATH], curDir[MAX_PATH];
BOOL is_delay_copy = FALSE;
// 僀儞僗僩乕儖僷僗愝掕
GetDlgItemText(FILE_EDIT, setupDir, sizeof(setupDir));
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) == 0 && DelayCopy(buf, installPath)) {
is_delay_copy = TRUE;
continue;
}
return MessageBox(installPath, GetLoadStr(IDS_NOTCREATEFILE)), FALSE;
}
}
// 僗僞乕僩儊僯儏乕仌僨僗僋僩僢僾偵搊榐
TRegistry reg(HKEY_CURRENT_USER);
if (reg.OpenKey(REGSTR_SHELLFOLDERS)) {
char *regStr[] = { REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL };
BOOL execFlg[] = { cfg.programLink, cfg.desktopLink, NULL };
for (int cnt=0; regStr[cnt]; cnt++) {
if (reg.GetStr(regStr[cnt], buf, sizeof(buf))) {
if (cnt != 0 || RemoveSameLink(buf, buf) == FALSE)
::wsprintf(buf + strlen(buf), "\\%s", FASTCOPY_SHORTCUT);
if (execFlg[cnt])
SymLink(setupPath, buf);
else
DeleteLink(buf);
}
}
reg.CloseKey();
}
// 僔僃儖奼挘忣曬偺 update
::GetModuleFileName(NULL, curDir, sizeof(curDir));
GetParentDir(curDir, curDir);
MakePath(buf, setupDir, CURRENT_SHEXTDLL);
HMODULE hShellExtDll = TLoadLibrary(buf);
if (hShellExtDll) {
BOOL (WINAPI *UpdateDllProc)(void) = (BOOL (WINAPI *)(void))GetProcAddress(hShellExtDll, "UpdateDll");
if (UpdateDllProc)
UpdateDllProc();
::FreeLibrary(hShellExtDll);
// 媽僶乕僕儑儞 dll 偺嶍彍
char *oldDlls[] = { SHELLEXT1_DLL, SHELLEXT2_DLL, SHELLEXT3_DLL, SHELLEXT4_DLL, NULL };
for (int i=0; oldDlls[i]; i++) {
MakePath(buf, setupDir, oldDlls[i]);
if (::GetFileAttributes(buf) != 0xffffffff) {
if (::DeleteFile(buf) == FALSE)
::MoveFileEx(buf, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
}
}
#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 (MessageBox(GetLoadStr(is_delay_copy ? IDS_DELAYSETUPCOMPLETE : IDS_SETUPCOMPLETE), INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) == IDOK) {
::SetCurrentDirectory(setupDir);
::WinExec(setupPath, SW_SHOW);
}
::PostQuitMessage(0);
return TRUE;
}
BOOL TInstDlg::UnInstall(void)
{
char buf[MAX_PATH];
if (MessageBox(GetLoadStr(IDS_START), UNINSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK)
return FALSE;
// 僗僞乕僩儊僯儏乕仌僨僗僋僩僢僾偐傜嶍彍
TRegistry reg(HKEY_CURRENT_USER);
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);
DeleteLink(buf);
}
}
reg.CloseKey();
}
// 儗僕僗僩儕偐傜傾僾儕働乕僔儑儞忣曬傪嶍彍
char setupDir[MAX_PATH] = "";
::GetModuleFileName(NULL, setupDir, sizeof(setupDir));
GetParentDir(setupDir, setupDir);
BOOL is_shext = FALSE;
MakePath(buf, setupDir, CURRENT_SHEXTDLL);
HMODULE hShellExtDll = TLoadLibrary(buf);
if (hShellExtDll) {
BOOL (WINAPI *IsRegisterDllProc)(void) = (BOOL (WINAPI *)(void))GetProcAddress(hShellExtDll, "IsRegistServer");
HRESULT (WINAPI *UnRegisterDllProc)(void) = (HRESULT (WINAPI *)(void))GetProcAddress(hShellExtDll, "DllUnregisterServer");
if (IsRegisterDllProc && UnRegisterDllProc && (is_shext = IsRegisterDllProc())) {
UnRegisterDllProc();
}
::FreeLibrary(hShellExtDll);
}
// 儗僕僗僩儕偐傜傾儞僀儞僗僩乕儖忣曬傪嶍彍
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));
// 僀儞僗僩乕儖僨傿儗僋僩儕傪奐偔
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -