?? install.cpp
字號:
static char *install_id =
"@(#)Copyright (C) H.Shirouzu 1998-2002 install.cpp Ver2.00";
/* ========================================================================
Project Name : Installer for IPMSG32
Module Name : Installer Application Class
Create : 1998-06-14(Sun)
Update : 2002-11-03(Sun)
Copyright : H.Shirouzu
Reference :
======================================================================== */
#include "../tlib.h"
#include "instrc.h"
#include "install.h"
char *SetupFiles [] = { INSTALL_EXENAME, README_NAME, OPENLAB_NAME, NULL };
/*
WinMain
*/
int WINAPI WinMain(HINSTANCE hI, HINSTANCE, LPSTR cmdLine, int nCmdShow)
{
TInstApp app(hI, cmdLine, nCmdShow);
return app.Run();
}
/*
僀儞僗僩乕儖傾僾儕働乕僔儑儞僋儔僗
*/
TInstApp::TInstApp(HINSTANCE _hI, LPSTR _cmdLine, int _nCmdShow) : TApp(_hI, _cmdLine, _nCmdShow)
{
}
TInstApp::~TInstApp()
{
}
void TInstApp::InitWindow(void)
{
InitCommonControls();
TDlg *maindlg = new TInstDlg(cmdLine);
mainWnd = maindlg;
maindlg->Create();
}
/*
儊僀儞僟僀傾儘僌僋儔僗
*/
TInstDlg::TInstDlg(char *cmdLine) : TDlg(INSTALL_DIALOG), staticText(this)
{
cfg.mode = SETUP_MODE;
cfg.portNo = IPMSG_DEFAULT_PORT;
cfg.startupLink = TRUE;
cfg.programLink = TRUE;
cfg.desktopLink = TRUE;
cfg.delPubkey = TRUE;
if (cmdLine)
{
for (char *tok = strtok(cmdLine, " \t\n"); tok; tok = strtok(NULL, " \t\n"))
{
if (strcmp(tok, UNINSTALL_CMDLINE) == 0)
cfg.mode = UNINSTALL_MODE;
else if (*tok >= '0' && *tok <= '9' && atoi(tok) > 0)
cfg.portNo = atoi(tok);
}
}
}
TInstDlg::~TInstDlg()
{
}
/*
儊僀儞僟僀傾儘僌梡 WM_INITDIALOG 張棟儖乕僠儞
*/
BOOL TInstDlg::EvCreate(LPARAM lParam)
{
if (IsNewShell() != TRUE)
{
MessageBox(NOTNEWSHELL_MSGSTR);
::PostQuitMessage(0);
return TRUE;
}
if (cfg.portNo != IPMSG_DEFAULT_PORT)
{
char buf[100];
::GetWindowText(hWnd, buf, sizeof(buf));
::wsprintf(buf + strlen(buf), " (PortNo = %d)", cfg.portNo);
SetWindowText(buf);
}
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::hI, (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], resetupDir[MAX_PATH];
::GetModuleFileName(NULL, resetupDir, sizeof(resetupDir));
GetParentDir(resetupDir, resetupDir);
SetDlgItemText(RESETUP_EDIT, resetupDir);
// Program Files偺僷僗庢傝弌偟
TRegistry reg(HKEY_LOCAL_MACHINE);
if (reg.OpenKey(REGSTR_PATH_SETUP) == TRUE)
{
if (reg.GetStr(REGSTR_PROGRAMFILES, buf, sizeof(buf)) == TRUE)
MakePath(setupDir, buf, IPMSG_STR);
reg.CloseKey();
}
// 婛偵僙僢僩傾僢僾偝傟偰偄傞応崌偼丄僙僢僩傾僢僾僨傿儗僋僩儕傪撉傒弌偡
if (reg.OpenKey(REGSTR_PATH_APPPATHS) == TRUE)
{
if (reg.OpenKey(IPMSG_EXENAME) == TRUE)
{
reg.GetStr(REGSTR_PATH, setupDir, sizeof(setupDir));
reg.CloseKey();
}
reg.CloseKey();
}
SetDlgItemText(FILE_EDIT, setupDir);
if (cfg.mode != UNINSTALL_MODE && (strcmp(setupDir, resetupDir) == 0 || GetDriveTypeEx(resetupDir) == DRIVE_REMOTE))
cfg.mode = RESETUP_MODE;
::SendMessage(GetDlgItem(cfg.mode == SETUP_MODE ? SETUP_RADIO : cfg.mode == RESETUP_MODE ? RESETUP_RADIO : UNINSTALL_RADIO), BM_SETCHECK, 1, 0);
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 RESETUP_RADIO:
case UNINSTALL_RADIO:
if (wNotifyCode == BN_CLICKED)
ChangeMode();
return TRUE;
}
return FALSE;
}
void TInstDlg::ChangeMode(void)
{
cfg.mode = SendDlgItemMessage(SETUP_RADIO, BM_GETCHECK, 0, 0) ? SETUP_MODE : SendDlgItemMessage(RESETUP_RADIO, BM_GETCHECK, 0, 0) ? RESETUP_MODE : UNINSTALL_MODE;
::EnableWindow(GetDlgItem(FILE_EDIT), cfg.mode == SETUP_MODE);
::EnableWindow(GetDlgItem(RESETUP_EDIT), cfg.mode == RESETUP_MODE);
propertySheet->Paste();
}
BOOL TInstDlg::Install(void)
{
char buf[MAX_PATH], setupDir[MAX_PATH], setupPath[MAX_PATH];
// 尰嵼丄婲摦拞偺 ipmsg 傪廔椆
if (TerminateIPMsg() != TRUE)
return FALSE;
// 僀儞僗僩乕儖僷僗愝掕
GetDlgItemText(cfg.mode == SETUP_MODE ? FILE_EDIT : RESETUP_EDIT, setupDir, sizeof(setupDir));
CreateDirectory(setupDir, NULL);
DWORD attr = GetFileAttributes(setupDir);
if (attr == 0xffffffff || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
return MessageBox(NOTCREATEDIR_MSGSTR), FALSE;
MakePath(setupPath, setupDir, IPMSG_EXENAME);
if (MessageBox(START_MSGSTR, INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK)
return FALSE;
// 僼傽僀儖僐僺乕
if (cfg.mode == SETUP_MODE)
{
char installPath[MAX_PATH], orgDir[MAX_PATH];
WIN32_FIND_DATA data;
HANDLE fh;
BOOL copy = TRUE;
GetDlgItemText(RESETUP_EDIT, orgDir, sizeof(orgDir));
MakePath(buf, orgDir, IPMSG_EXENAME);
if ((fh = ::FindFirstFile(buf, &data)) != INVALID_HANDLE_VALUE)
{
if (data.nFileSizeLow < MAX_WRAPPER_IPMSGSIZE)
MakePath(buf, orgDir, RESOLVE_WRAPPER_IPMSG);
::FindClose(fh);
}
if ((fh = ::FindFirstFile(setupPath, &data)) != INVALID_HANDLE_VALUE)
{
if (data.nFileSizeLow < MAX_WRAPPER_IPMSGSIZE)
copy = FALSE;
::FindClose(fh);
}
if (copy && ::CopyFile(buf, setupPath, FALSE) == FALSE)
return MessageBox(setupPath, NOTCREATEFILE_MSGSTR), FALSE;
for (int cnt=0; SetupFiles[cnt] != NULL; cnt++)
{
MakePath(buf, orgDir, SetupFiles[cnt]);
MakePath(installPath, setupDir, SetupFiles[cnt]);
if (::CopyFile(buf, installPath, FALSE) == FALSE)
return MessageBox(installPath, NOTCREATEFILE_MSGSTR), FALSE;
}
}
// 僗僞乕僩傾僢僾仌僨僗僋僩僢僾偵搊榐
TRegistry reg(HKEY_CURRENT_USER);
if (reg.OpenKey(REGSTR_SHELLFOLDERS) == TRUE)
{
char *regStr[] = { REGSTR_STARTUP, REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL };
BOOL execFlg[] = { cfg.startupLink, cfg.programLink, cfg.desktopLink };
for (int cnt=0; regStr[cnt] != NULL; cnt++)
{
if (reg.GetStr(regStr[cnt], buf, sizeof(buf)) == TRUE)
{
if (cnt != 0 || RemoveSameLink(buf, buf) != TRUE)
::wsprintf(buf + strlen(buf), "\\%s", IPMSG_SHORTCUT_NAME);
if (execFlg[cnt])
SymLink(setupPath, buf);
else
DeleteLink(buf);
}
}
reg.CloseKey();
}
// 儗僕僗僩儕偵傾僾儕働乕僔儑儞忣曬傪搊榐
reg.ChangeTopKey(HKEY_LOCAL_MACHINE);
if (reg.OpenKey(REGSTR_PATH_APPPATHS) == TRUE)
{
if (reg.CreateKey(IPMSG_EXENAME) == TRUE)
{
reg.SetStr(NULL, setupPath);
reg.SetStr(REGSTR_PATH, setupDir);
reg.CloseKey();
}
reg.CloseKey();
}
// 儗僕僗僩儕偵傾儞僀儞僗僩乕儖忣曬傪搊榐
if (reg.OpenKey(REGSTR_PATH_UNINSTALL) == TRUE)
{
if (reg.CreateKey(IPMSG_NAME) == TRUE)
{
MakePath(buf, setupDir, INSTALL_EXENAME);
strcat(buf, " /r");
reg.SetStr(REGSTR_VAL_UNINSTALLER_DISPLAYNAME, IPMSG_FULLNAME);
reg.SetStr(REGSTR_VAL_UNINSTALLER_COMMANDLINE, buf);
reg.CloseKey();
}
reg.CloseKey();
}
// 僐僺乕偟偨傾僾儕働乕僔儑儞傪婲摦
if (MessageBox(SETUPCOMPLETE_MSGSTR, INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) == IDOK)
{
::SetCurrentDirectory(setupDir);
::WinExec(setupPath, SW_SHOW);
}
if (cfg.mode == SETUP_MODE)
::ShellExecute(NULL, NULL, setupDir, 0, 0, SW_SHOW);
::PostQuitMessage(0);
return TRUE;
}
BOOL TInstDlg::UnInstall(void)
{
// 尰嵼丄婲摦拞偺 ipmsg 傪廔椆
if (TerminateIPMsg() != TRUE)
return FALSE;
if (MessageBox(START_MSGSTR, UNINSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK)
return FALSE;
// 僗僞乕僩傾僢僾仌僨僗僋僩僢僾偐傜嶍彍
TRegistry reg(HKEY_CURRENT_USER);
if (reg.OpenKey(REGSTR_SHELLFOLDERS) == TRUE)
{
char buf[MAX_PATH];
char *regStr[] = { REGSTR_STARTUP, REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL };
for (int cnt=0; regStr[cnt] != NULL; cnt++)
{
if (reg.GetStr(regStr[cnt], buf, sizeof(buf)) == TRUE)
{
if (cnt == 0)
RemoveSameLink(buf);
::wsprintf(buf + strlen(buf), "\\%s", IPMSG_SHORTCUT_NAME);
DeleteLink(buf);
}
}
reg.CloseKey();
}
// 儗僕僗僩儕偐傜儐乕僓乕愝掕忣曬傪嶍彍
if (reg.ChangeApp(HSTOOLS_STR) == TRUE)
reg.DeleteChildTree(REGSTR_IPMSG);
// 儗僕僗僩儕偐傜傾僾儕働乕僔儑儞忣曬傪嶍彍
char setupDir[MAX_PATH]; // 僙僢僩傾僢僾僨傿儗僋僩儕忣曬傪曐懚
GetDlgItemText(RESETUP_EDIT, setupDir, sizeof(setupDir));
reg.ChangeTopKey(HKEY_LOCAL_MACHINE);
if (reg.OpenKey(REGSTR_PATH_APPPATHS) == TRUE)
{
if (reg.OpenKey(IPMSG_EXENAME) == TRUE)
{
reg.GetStr(REGSTR_PATH, setupDir, sizeof(setupDir));
reg.CloseKey();
}
reg.DeleteKey(IPMSG_EXENAME);
reg.CloseKey();
}
// 儗僕僗僩儕偐傜傾儞僀儞僗僩乕儖忣曬傪嶍彍
if (reg.OpenKey(REGSTR_PATH_UNINSTALL) == TRUE)
{
reg.DeleteKey(IPMSG_NAME);
reg.CloseKey();
}
// 廔椆儊僢僙乕僕
MessageBox(UNINSTCOMPLETE_MSGSTR);
// 僀儞僗僩乕儖僨傿儗僋僩儕傪奐偔
if (GetDriveTypeEx(setupDir) != DRIVE_REMOTE)
::ShellExecute(NULL, NULL, setupDir, 0, 0, SW_SHOW);
// 岞奐尞偺嶍彍
#ifndef MS_DEF_PROV
typedef unsigned long HCRYPTPROV;
#define MS_DEF_PROV "Microsoft Base Cryptographic Provider v1.0"
#define MS_ENHANCED_PROV "Microsoft Enhanced Cryptographic Provider v1.0"
#define CRYPT_DELETEKEYSET 0x00000010
#define CRYPT_MACHINE_KEYSET 0x00000020
#define PROV_RSA_FULL 1
#endif
BOOL (WINAPI *pCryptAcquireContext)(HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
HINSTANCE advdll;
if (cfg.delPubkey && (advdll = ::LoadLibrary("advapi32.dll")) && (pCryptAcquireContext = (BOOL (WINAPI *)(HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD))::GetProcAddress(advdll, "CryptAcquireContextA")))
{
HCRYPTPROV csp = NULL;
char contName[MAX_PATH], userName[MAX_PATH];
DWORD size = sizeof(userName);
::GetUserName(userName, &size);
::wsprintf(contName, "ipmsg.rsa1024.%s", userName);
pCryptAcquireContext(&csp, contName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
pCryptAcquireContext(&csp, contName, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
::wsprintf(contName, "ipmsg.rsa512.%s", userName);
pCryptAcquireContext(&csp, contName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET|CRYPT_MACHINE_KEYSET);
pCryptAcquireContext(&csp, contName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
}
::PostQuitMessage(0);
return TRUE;
}
/*
摨偠撪梕傪帩偮僔儑乕僩僇僢僩傪嶍彍乮僗僞乕僩傾僢僾傊偺廳暋搊榐傛偗乯
*/
BOOL TInstDlg::RemoveSameLink(const char *dir, char *remove_path)
{
char path[MAX_PATH], dest[MAX_PATH], arg[MAX_PATH];
HANDLE fh;
WIN32_FIND_DATA data;
BOOL ret = FALSE;
::wsprintf(path, "%s\\*.*", dir);
if ((fh = ::FindFirstFile(path, &data)) == INVALID_HANDLE_VALUE)
return FALSE;
do {
::wsprintf(path, "%s\\%s", dir, data.cFileName);
if (ReadLink(path, dest, arg) == TRUE && *arg == 0)
{
int dest_len = strlen(dest), ipmsg_len = strlen(IPMSG_EXENAME);
if (dest_len > ipmsg_len && strncmpi(dest + dest_len - ipmsg_len, IPMSG_EXENAME, ipmsg_len) == 0) {
ret = ::DeleteFile(path);
if (remove_path != NULL)
strcpy(remove_path, path);
}
}
} while (::FindNextFile(fh, &data) == TRUE);
::FindClose(fh);
return ret;
}
/*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -