| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- #include "StdAfx.h"
- #include "GuardMain.h"
- #include <ProfInfo.h>
- #include <io.h>
- #include <tlhelp32.h>
- #include "Config.h"
- SINGLETON_IMPLEMENT(CGuardMain)
- CGuardMain::CGuardMain(void) : m_hFileConfig(NULL), m_hMapFileConfig(NULL), m_pThreadWatch(NULL), m_pThreadTimer(NULL), m_pProcessInfo(NULL)
- {
- }
- CGuardMain::~CGuardMain(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __runWithOs
- **【函数功能】 随系统启动
- **【参数】
- **【返回值】
- ****************************************************************/
- void CGuardMain::__runWithOs( void )
- {
- //获得当前应用程序路径
- TCHAR path[MAX_PATH] = { 0 };
- if( !GetModuleFileName( NULL, path, MAX_PATH ) )
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法获取系统路径"));
- return;
- }
- CRegKey key;
- if (key.Open(HKEY_LOCAL_MACHINE, REG_STARTUP_PATH, KEY_WRITE | KEY_READ) != ERROR_SUCCESS)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法打开系统接口"));
- return;
- }
- CString Path2Write;
- Path2Write.Format(_T("\"%s\""), path);
- if(key.SetStringValue(REG_STARTUP_ITEM, Path2Write, REG_SZ) != ERROR_SUCCESS)
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法建立启动项"));
- }
- /*****************************************************************
- **【函数名称】 __loadConfigInfo
- **【函数功能】 加载配置信息
- **【参数】
- **【返回值】 BOOL
- ****************************************************************/
- bool CGuardMain::__loadConfigInfo( void )
- {
- // 加载配置文件
- if(_access(FILE_PATH, 0) == -1)
- CreateDirectoryA(FILE_PATH, NULL);
- m_hFileConfig = CreateFile(FILE_NAME,
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if(m_hFileConfig == NULL)
- return false;
- // 打开内存映射文件
- m_hMapFileConfig = CreateFileMapping(m_hFileConfig, NULL, PAGE_READWRITE, 0, sizeof(ProcessInfo)*WATCH_MAX_COUNT, VIEW_NAME);
- if(m_hMapFileConfig == NULL)
- {
- CloseHandle(m_hFileConfig);
- m_hFileConfig = NULL;
- return false;
- }
- // 映射文件对象到进程地址空间
- LPVOID hViewFile = MapViewOfFile(m_hMapFileConfig, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(ProcessInfo)*WATCH_MAX_COUNT);
- if(hViewFile == NULL)
- {
- CloseHandle(m_hMapFileConfig);
- m_hMapFileConfig = NULL;
- CloseHandle(m_hFileConfig);
- m_hFileConfig = NULL;
- return false;
- }
- // 保存内存指针
- if(m_hFileConfig != NULL)
- {
- CloseHandle(m_hFileConfig);
- m_hFileConfig = NULL;
- }
- if(m_hMapFileConfig != NULL)
- {
- CloseHandle(m_hMapFileConfig);
- m_hMapFileConfig = NULL;
- }
- m_pProcessInfo = (ProcessInfo*)hViewFile;
- return true;
- }
- /*****************************************************************
- **【函数名称】 __onWatch
- **【函数功能】 处理监控函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CGuardMain::__onWatch( void )
- {
- for(int i = 0; i < WATCH_MAX_COUNT; i++)
- {
- // 屏蔽路径为空的项
- if(strcmp(m_pProcessInfo[i].m_szName, _T("")) == 0 ||
- strcmp(m_pProcessInfo[i].m_szPath, _T("")) == 0)
- continue;
- // 从系统中查找进程
- DWORD dwProcessId = 0;
- if(!__searchProcess(m_pProcessInfo[i].m_szName, dwProcessId))
- {
- // 搜索不到进程,启动进程
- if(m_pProcessInfo[i].m_nErrorCount >= 2)
- {
- m_pProcessInfo[i].m_nErrorCount = 0;
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: %s监控失败, 将启动该进程, path = %s"),
- m_pProcessInfo[i].m_szName, m_pProcessInfo[i].m_szPath);
- __runProcess(m_pProcessInfo[i]);
- }
- else
- {
- m_pProcessInfo[i].m_nErrorCount++;
- }
- }
- else
- {
- if(m_pProcessInfo[i].m_bUseActiveFlag)
- {
- // 进程存在,判断进程是否假死
- if(m_pProcessInfo[i].m_bActiveFlag)
- {
- m_pProcessInfo[i].m_nErrorCount = 0;
- m_pProcessInfo[i].m_bActiveFlag = FALSE;
- }
- else
- {
- if(m_pProcessInfo[i].m_nErrorCount >= 2)
- {
- m_pProcessInfo[i].m_nErrorCount = 0;
- // 杀死进程
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 检测不到%s心跳, 将关闭该进程"),
- m_pProcessInfo[i].m_szName);
- __killProcess(dwProcessId);
- }
- else
- {
- m_pProcessInfo[i].m_nErrorCount++;
- }
- }
- }
- else
- {
- // 不启用心跳通讯,检测到进程存在
- m_pProcessInfo[i].m_nErrorCount = 0;
- }
- } // end if
- } // end for
- }
- /*****************************************************************
- **【函数名称】 __onTimer
- **【函数功能】 处理定时器函数
- **【参数】
- **【返回值】
- ****************************************************************/
- void CGuardMain::__onTimer( void )
- {
- CTime TimeCurr = CTime::GetCurrentTime();
- CString strTime = TimeCurr.Format(_T("%H"));
- for(int i = 0; i < WATCH_MAX_COUNT; i++)
- {
- if(strcmp(m_pProcessInfo[i].m_szName, _T("")) == 0) continue;
- // 定时器时长增加
- m_pProcessInfo[i].m_nRunTimer++;
- // 运行超过指定时长,并且当前为01:00,重启该进程
- if(m_pProcessInfo[i].m_nOnTimerReStart != 0 && m_pProcessInfo[i].m_nRunTimer >= m_pProcessInfo[i].m_nOnTimerReStart
- && strTime == CConfig::processRestartOclock())
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: %s已运行%d小时, 达到定时重启时限(%d小时), 将重新启动"), m_pProcessInfo[i].m_szName,
- m_pProcessInfo[i].m_nRunTimer, m_pProcessInfo[i].m_nOnTimerReStart);
- // 重启进程
- DWORD dwProcessId = 0;
- if(__searchProcess(m_pProcessInfo[i].m_szName, dwProcessId))
- {
- // 杀死进程
- __killProcess(dwProcessId);
- }
- // 重启进程
- __runProcess(m_pProcessInfo[i]);
- }
- } // endfor
- }
- /*****************************************************************
- **【函数名称】 __getLastError
- **【函数功能】 获取错误信息
- **【参数】
- **【返回值】
- ****************************************************************/
- CString CGuardMain::__getLastError( void )
- {
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- CString strErrMsg = _T("");
- strErrMsg.Format("%s", (LPCTSTR)lpMsgBuf);
- LocalFree(lpMsgBuf);
- return strErrMsg;
- }
- /*****************************************************************
- **【函数名称】 __getTokenByName
- **【函数功能】 得到登录用户名和口令
- **【参数】 HANDLE 标识符句柄
- lpName 进程名称
- **【返回值】
- ****************************************************************/
- bool CGuardMain::__getTokenByName(HANDLE &hToken, CString strName)
- {
- if(strName.IsEmpty())
- return false;
- HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if(hProcessSnap == INVALID_HANDLE_VALUE)
- return false;
-
- BOOL bRet = FALSE;
- PROCESSENTRY32 pe32 = {0};
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if(Process32First(hProcessSnap, &pe32))
- {
- do
- {
- if(strName.CompareNoCase(pe32.szExeFile) == 0)
- {
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
- bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
- CloseHandle(hProcessSnap);
- return bRet != FALSE;
- }
- }
- while(Process32Next(hProcessSnap, &pe32));
- }
-
- CloseHandle(hProcessSnap);
- return false;
- }
- /*****************************************************************
- **【函数名称】 __searchProcess
- **【函数功能】 搜索进程
- **【参数】 lpProcessName 进程名称
- dwProcessId 返回的进程ID
- **【返回值】
- ****************************************************************/
- bool CGuardMain::__searchProcess(LPCTSTR lpProcessName, DWORD& dwProcessId)
- {
- HANDLE hSnapshot;
- hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if(hSnapshot == INVALID_HANDLE_VALUE)
- return false;
- bool bRet = false;
- PROCESSENTRY32 lppe;
- lppe.dwSize = sizeof(PROCESSENTRY32);
- if(Process32First(hSnapshot, &lppe))
- {
- do
- {
- if(strcmp(lppe.szExeFile, lpProcessName) == 0)
- {
- dwProcessId = lppe.th32ProcessID;
- bRet = true;
- break;
- }
- }
- while(Process32Next(hSnapshot, &lppe)); // 查找下一个进程
- }
-
- CloseHandle(hSnapshot);
- return bRet;
- }
- /*****************************************************************
- **【函数名称】 __killProcess
- **【函数功能】 杀死进程
- **【参数】 dwProcessId 进程ID
- **【返回值】
- ****************************************************************/
- void CGuardMain::__killProcess(DWORD dwProcessId)
- {
- DWORD xCode;
- HANDLE hProc = OpenProcess(PROCESS_TERMINATE, false, dwProcessId);
- if(hProc && !GetExitCodeProcess(hProc, &xCode))
- {
- // 结束进程
- TerminateProcess(hProc, xCode);
- CloseHandle(hProc);
- Sleep(3);
- }
- }
- /*****************************************************************
- **【函数名称】 __runProcess
- **【函数功能】 运行指定进程并前台显示
- **【参数】 ProInfo 进程信息
- **【返回值】
- ****************************************************************/
- void CGuardMain::__runProcess(ProcessInfo& ProInfo)
- {
- // 获取应用程序目录,设置子进程的当前目录
- CString strDircet = ProInfo.m_szPath;
- int nIndex = strDircet.ReverseFind('\\');
- if(-1 == nIndex)
- {
- nIndex = strDircet.ReverseFind('/');
- }
- strDircet = strDircet.Left(nIndex+1);
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- ZeroMemory(&pi, sizeof(pi));
- BOOL bRet = CreateProcess(ProInfo.m_szPath, // No module name (use command line)
- NULL, // Command line
- NULL, // Process handle not inheritable
- NULL, // Thread handle not inheritable
- FALSE, // Set handle inheritance to FALSE
- 0, // No creation flags
- NULL, // Use parent's environment block
- strDircet, // Use parent's starting directory
- &si, // Pointer to STARTUPINFO structure
- &pi); // Pointer to PROCESS_INFORMATION structure
- // 运行时长清零
- if(bRet)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: 进程%s启动成功, Path = %s"), ProInfo.m_szName, ProInfo.m_szPath);
- ProInfo.m_nRunTimer = 0;
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- Sleep(5000);
- }
- else
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 进程%s启动失败, Path = %s, Cause = %s"),
- ProInfo.m_szName, ProInfo.m_szPath, __getLastError());
- }
- }
- /*****************************************************************
- **【函数名称】 __runProcess
- **【函数功能】 运行指定进程并前台显示
- **【参数】 ProInfo 进程信息
- **【返回值】
- ****************************************************************/
- void CGuardMain::__runProcessByService(ProcessInfo& ProInfo)
- {
- // 获取登录用户信息
- HANDLE hToken = NULL;
- if(!__getTokenByName(hToken, _T("EXPLORER.EXE")))
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 启动进程%s时获取用户令牌失败, Cause = %s"), __getLastError());
- return;
- }
- typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE)(HANDLE hToken, LPPROFILEINFO lpProfileInfo);
- HMODULE hLib = LoadLibrary(_T("userenv.dll"));
- LPFNLOADUSERPROFILE LoadUserProfile = NULL;
- #ifdef UNICODE
- LoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hLib, _T("LoadUserProfileW"));
- #else
- LoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hLib, _T("LoadUserProfileA"));
- #endif
- if(LoadUserProfile == NULL) return;
- PROFILEINFO profile = {0};
- profile.dwSize = sizeof(PROFILEINFO);
- profile.lpUserName = "administrator";
- if(LoadUserProfile(hToken, &profile) == NULL)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 启动进程%s时加载用户配置文件失败, Cause = %s"), __getLastError());
- return;
- }
- PROCESS_INFORMATION pi; // 进程信息
- STARTUPINFO lp = {0}; // 新进程窗口信息
- lp.cb = sizeof(lp);
- lp.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
- lp.wShowWindow = SW_HIDE;
- // 启动新进程
- BOOL bRet = CreateProcessAsUser(hToken,
- ProInfo.m_szPath,
- NULL,
- NULL,
- NULL,
- FALSE,
- NORMAL_PRIORITY_CLASS,
- NULL,
- NULL,
- &lp,
- &pi);
- CloseHandle(hToken);
- }
- /*****************************************************************
- **【函数名称】 __watchThreadFun
- **【函数功能】 监控线程类
- **【参数】
- **【返回值】
- ****************************************************************/
- UINT CGuardMain::__watchThreadFun(LPVOID Param)
- {
- CGuardMain* pGuard = (CGuardMain*)Param;
- ASSERT(pGuard != NULL);
- while(TRUE)
- {
- Sleep(WATCH_TIMER_SERVICE);
- pGuard->__onWatch();
- }
- return 0;
- }
- /*****************************************************************
- **【函数名称】 __timerThreadFun
- **【函数功能】 定时器线程函数
- **【参数】
- **【返回值】
- ****************************************************************/
- UINT CGuardMain::__timerThreadFun(LPVOID Param)
- {
- CGuardMain* pGuard = (CGuardMain*)Param;
- ASSERT(pGuard != NULL);
- while(TRUE)
- {
- // 每个小时观察一次
- Sleep(1000 * 3600);
- pGuard->__onTimer();
- }
- return 0;
- }
- /*****************************************************************
- **【函数名称】 init
- **【函数功能】 初始化监控控制类
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CGuardMain::init( void )
- {
- //__runWithOs();
- // 加载配置信息
- if(!__loadConfigInfo())
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 读取映射文件失败, Cause = %s"), __getLastError());
- return false;
- }
- // 创建监控线程
- m_pThreadWatch = AfxBeginThread(__watchThreadFun, this, 0, 0, CREATE_SUSPENDED, NULL);
- if(m_pThreadWatch == NULL)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 启动守护监控线程失败"));
- return false;
- }
- // 创建定时器线程
- m_pThreadTimer = AfxBeginThread(__timerThreadFun, this, 0, 0, CREATE_SUSPENDED, NULL);
- if(m_pThreadTimer == NULL)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 启动定时守护线程失败"));
- return false;
- }
- // 启动监控服务
- startWatchServer();
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: 守护功能启动成功"));
- return TRUE;
- }
- /*****************************************************************
- **【函数名称】 startWatch
- **【函数功能】 开始监控
- **【参数】
- **【返回值】
- ****************************************************************/
- void CGuardMain::startWatchServer()
- {
- if(m_pThreadWatch != NULL) m_pThreadWatch->ResumeThread();
- if(m_pThreadTimer != NULL) m_pThreadTimer->ResumeThread();
- }
- /*****************************************************************
- **【函数名称】 stopWatch
- **【函数功能】 停止监控
- **【参数】
- **【返回值】
- ****************************************************************/
- void CGuardMain::stopWatchServer()
- {
- if(m_pThreadWatch != NULL) m_pThreadWatch->SuspendThread();
- if(m_pThreadTimer != NULL) m_pThreadTimer->SuspendThread();
- }
|