中间件标准版5.1git,去除基础模块

GuardMain.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. #include "StdAfx.h"
  2. #include "GuardMain.h"
  3. #include <ProfInfo.h>
  4. #include <io.h>
  5. #include <tlhelp32.h>
  6. #include "Config.h"
  7. SINGLETON_IMPLEMENT(CGuardMain)
  8. CGuardMain::CGuardMain(void) : m_hFileConfig(NULL), m_hMapFileConfig(NULL), m_pThreadWatch(NULL), m_pThreadTimer(NULL), m_pProcessInfo(NULL)
  9. {
  10. }
  11. CGuardMain::~CGuardMain(void)
  12. {
  13. }
  14. /*****************************************************************
  15. **【函数名称】 __runWithOs
  16. **【函数功能】 随系统启动
  17. **【参数】
  18. **【返回值】
  19. ****************************************************************/
  20. void CGuardMain::__runWithOs( void )
  21. {
  22. //获得当前应用程序路径
  23. TCHAR path[MAX_PATH] = { 0 };
  24. if( !GetModuleFileName( NULL, path, MAX_PATH ) )
  25. {
  26. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法获取系统路径"));
  27. return;
  28. }
  29. CRegKey key;
  30. if (key.Open(HKEY_LOCAL_MACHINE, REG_STARTUP_PATH, KEY_WRITE | KEY_READ) != ERROR_SUCCESS)
  31. {
  32. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法打开系统接口"));
  33. return;
  34. }
  35. CString Path2Write;
  36. Path2Write.Format(_T("\"%s\""), path);
  37. if(key.SetStringValue(REG_STARTUP_ITEM, Path2Write, REG_SZ) != ERROR_SUCCESS)
  38. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 设置随系统启动失败, 无法建立启动项"));
  39. }
  40. /*****************************************************************
  41. **【函数名称】 __loadConfigInfo
  42. **【函数功能】 加载配置信息
  43. **【参数】
  44. **【返回值】 BOOL
  45. ****************************************************************/
  46. bool CGuardMain::__loadConfigInfo( void )
  47. {
  48. // 加载配置文件
  49. if(_access(FILE_PATH, 0) == -1)
  50. CreateDirectoryA(FILE_PATH, NULL);
  51. m_hFileConfig = CreateFile(FILE_NAME,
  52. GENERIC_READ|GENERIC_WRITE,
  53. FILE_SHARE_READ|FILE_SHARE_WRITE,
  54. NULL,
  55. OPEN_ALWAYS,
  56. FILE_ATTRIBUTE_NORMAL,
  57. NULL);
  58. if(m_hFileConfig == NULL)
  59. return false;
  60. // 打开内存映射文件
  61. m_hMapFileConfig = CreateFileMapping(m_hFileConfig, NULL, PAGE_READWRITE, 0, sizeof(ProcessInfo)*WATCH_MAX_COUNT, VIEW_NAME);
  62. if(m_hMapFileConfig == NULL)
  63. {
  64. CloseHandle(m_hFileConfig);
  65. m_hFileConfig = NULL;
  66. return false;
  67. }
  68. // 映射文件对象到进程地址空间
  69. LPVOID hViewFile = MapViewOfFile(m_hMapFileConfig, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(ProcessInfo)*WATCH_MAX_COUNT);
  70. if(hViewFile == NULL)
  71. {
  72. CloseHandle(m_hMapFileConfig);
  73. m_hMapFileConfig = NULL;
  74. CloseHandle(m_hFileConfig);
  75. m_hFileConfig = NULL;
  76. return false;
  77. }
  78. // 保存内存指针
  79. if(m_hFileConfig != NULL)
  80. {
  81. CloseHandle(m_hFileConfig);
  82. m_hFileConfig = NULL;
  83. }
  84. if(m_hMapFileConfig != NULL)
  85. {
  86. CloseHandle(m_hMapFileConfig);
  87. m_hMapFileConfig = NULL;
  88. }
  89. m_pProcessInfo = (ProcessInfo*)hViewFile;
  90. return true;
  91. }
  92. /*****************************************************************
  93. **【函数名称】 __onWatch
  94. **【函数功能】 处理监控函数
  95. **【参数】
  96. **【返回值】
  97. ****************************************************************/
  98. void CGuardMain::__onWatch( void )
  99. {
  100. for(int i = 0; i < WATCH_MAX_COUNT; i++)
  101. {
  102. // 屏蔽路径为空的项
  103. if(strcmp(m_pProcessInfo[i].m_szName, _T("")) == 0 ||
  104. strcmp(m_pProcessInfo[i].m_szPath, _T("")) == 0)
  105. continue;
  106. // 从系统中查找进程
  107. DWORD dwProcessId = 0;
  108. if(!__searchProcess(m_pProcessInfo[i].m_szName, dwProcessId))
  109. {
  110. // 搜索不到进程,启动进程
  111. if(m_pProcessInfo[i].m_nErrorCount >= 2)
  112. {
  113. m_pProcessInfo[i].m_nErrorCount = 0;
  114. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: %s监控失败, 将启动该进程, path = %s"),
  115. m_pProcessInfo[i].m_szName, m_pProcessInfo[i].m_szPath);
  116. __runProcess(m_pProcessInfo[i]);
  117. }
  118. else
  119. {
  120. m_pProcessInfo[i].m_nErrorCount++;
  121. }
  122. }
  123. else
  124. {
  125. if(m_pProcessInfo[i].m_bUseActiveFlag)
  126. {
  127. // 进程存在,判断进程是否假死
  128. if(m_pProcessInfo[i].m_bActiveFlag)
  129. {
  130. m_pProcessInfo[i].m_nErrorCount = 0;
  131. m_pProcessInfo[i].m_bActiveFlag = FALSE;
  132. }
  133. else
  134. {
  135. if(m_pProcessInfo[i].m_nErrorCount >= 2)
  136. {
  137. m_pProcessInfo[i].m_nErrorCount = 0;
  138. // 杀死进程
  139. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 检测不到%s心跳, 将关闭该进程"),
  140. m_pProcessInfo[i].m_szName);
  141. __killProcess(dwProcessId);
  142. }
  143. else
  144. {
  145. m_pProcessInfo[i].m_nErrorCount++;
  146. }
  147. }
  148. }
  149. else
  150. {
  151. // 不启用心跳通讯,检测到进程存在
  152. m_pProcessInfo[i].m_nErrorCount = 0;
  153. }
  154. } // end if
  155. } // end for
  156. }
  157. /*****************************************************************
  158. **【函数名称】 __onTimer
  159. **【函数功能】 处理定时器函数
  160. **【参数】
  161. **【返回值】
  162. ****************************************************************/
  163. void CGuardMain::__onTimer( void )
  164. {
  165. CTime TimeCurr = CTime::GetCurrentTime();
  166. CString strTime = TimeCurr.Format(_T("%H"));
  167. for(int i = 0; i < WATCH_MAX_COUNT; i++)
  168. {
  169. if(strcmp(m_pProcessInfo[i].m_szName, _T("")) == 0) continue;
  170. // 定时器时长增加
  171. m_pProcessInfo[i].m_nRunTimer++;
  172. // 运行超过指定时长,并且当前为01:00,重启该进程
  173. if(m_pProcessInfo[i].m_nOnTimerReStart != 0 && m_pProcessInfo[i].m_nRunTimer >= m_pProcessInfo[i].m_nOnTimerReStart
  174. && strTime == CConfig::processRestartOclock())
  175. {
  176. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: %s已运行%d小时, 达到定时重启时限(%d小时), 将重新启动"), m_pProcessInfo[i].m_szName,
  177. m_pProcessInfo[i].m_nRunTimer, m_pProcessInfo[i].m_nOnTimerReStart);
  178. // 重启进程
  179. DWORD dwProcessId = 0;
  180. if(__searchProcess(m_pProcessInfo[i].m_szName, dwProcessId))
  181. {
  182. // 杀死进程
  183. __killProcess(dwProcessId);
  184. }
  185. // 重启进程
  186. __runProcess(m_pProcessInfo[i]);
  187. }
  188. } // endfor
  189. }
  190. /*****************************************************************
  191. **【函数名称】 __getLastError
  192. **【函数功能】 获取错误信息
  193. **【参数】
  194. **【返回值】
  195. ****************************************************************/
  196. CString CGuardMain::__getLastError( void )
  197. {
  198. LPVOID lpMsgBuf;
  199. FormatMessage(
  200. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  201. FORMAT_MESSAGE_FROM_SYSTEM |
  202. FORMAT_MESSAGE_IGNORE_INSERTS,
  203. NULL,
  204. GetLastError(),
  205. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  206. (LPTSTR) &lpMsgBuf,
  207. 0,
  208. NULL
  209. );
  210. CString strErrMsg = _T("");
  211. strErrMsg.Format("%s", (LPCTSTR)lpMsgBuf);
  212. LocalFree(lpMsgBuf);
  213. return strErrMsg;
  214. }
  215. /*****************************************************************
  216. **【函数名称】 __getTokenByName
  217. **【函数功能】 得到登录用户名和口令
  218. **【参数】 HANDLE 标识符句柄
  219. lpName 进程名称
  220. **【返回值】
  221. ****************************************************************/
  222. bool CGuardMain::__getTokenByName(HANDLE &hToken, CString strName)
  223. {
  224. if(strName.IsEmpty())
  225. return false;
  226. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  227. if(hProcessSnap == INVALID_HANDLE_VALUE)
  228. return false;
  229. BOOL bRet = FALSE;
  230. PROCESSENTRY32 pe32 = {0};
  231. pe32.dwSize = sizeof(PROCESSENTRY32);
  232. if(Process32First(hProcessSnap, &pe32))
  233. {
  234. do
  235. {
  236. if(strName.CompareNoCase(pe32.szExeFile) == 0)
  237. {
  238. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
  239. bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
  240. CloseHandle(hProcessSnap);
  241. return bRet != FALSE;
  242. }
  243. }
  244. while(Process32Next(hProcessSnap, &pe32));
  245. }
  246. CloseHandle(hProcessSnap);
  247. return false;
  248. }
  249. /*****************************************************************
  250. **【函数名称】 __searchProcess
  251. **【函数功能】 搜索进程
  252. **【参数】 lpProcessName 进程名称
  253. dwProcessId 返回的进程ID
  254. **【返回值】
  255. ****************************************************************/
  256. bool CGuardMain::__searchProcess(LPCTSTR lpProcessName, DWORD& dwProcessId)
  257. {
  258. HANDLE hSnapshot;
  259. hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  260. if(hSnapshot == INVALID_HANDLE_VALUE)
  261. return false;
  262. bool bRet = false;
  263. PROCESSENTRY32 lppe;
  264. lppe.dwSize = sizeof(PROCESSENTRY32);
  265. if(Process32First(hSnapshot, &lppe))
  266. {
  267. do
  268. {
  269. if(strcmp(lppe.szExeFile, lpProcessName) == 0)
  270. {
  271. dwProcessId = lppe.th32ProcessID;
  272. bRet = true;
  273. break;
  274. }
  275. }
  276. while(Process32Next(hSnapshot, &lppe)); // 查找下一个进程
  277. }
  278. CloseHandle(hSnapshot);
  279. return bRet;
  280. }
  281. /*****************************************************************
  282. **【函数名称】 __killProcess
  283. **【函数功能】 杀死进程
  284. **【参数】 dwProcessId 进程ID
  285. **【返回值】
  286. ****************************************************************/
  287. void CGuardMain::__killProcess(DWORD dwProcessId)
  288. {
  289. DWORD xCode;
  290. HANDLE hProc = OpenProcess(PROCESS_TERMINATE, false, dwProcessId);
  291. if(hProc && !GetExitCodeProcess(hProc, &xCode))
  292. {
  293. // 结束进程
  294. TerminateProcess(hProc, xCode);
  295. CloseHandle(hProc);
  296. Sleep(3);
  297. }
  298. }
  299. /*****************************************************************
  300. **【函数名称】 __runProcess
  301. **【函数功能】 运行指定进程并前台显示
  302. **【参数】 ProInfo 进程信息
  303. **【返回值】
  304. ****************************************************************/
  305. void CGuardMain::__runProcess(ProcessInfo& ProInfo)
  306. {
  307. // 获取应用程序目录,设置子进程的当前目录
  308. CString strDircet = ProInfo.m_szPath;
  309. int nIndex = strDircet.ReverseFind('\\');
  310. if(-1 == nIndex)
  311. {
  312. nIndex = strDircet.ReverseFind('/');
  313. }
  314. strDircet = strDircet.Left(nIndex+1);
  315. STARTUPINFO si;
  316. PROCESS_INFORMATION pi;
  317. ZeroMemory(&si, sizeof(si));
  318. si.cb = sizeof(si);
  319. ZeroMemory(&pi, sizeof(pi));
  320. BOOL bRet = CreateProcess(ProInfo.m_szPath, // No module name (use command line)
  321. NULL, // Command line
  322. NULL, // Process handle not inheritable
  323. NULL, // Thread handle not inheritable
  324. FALSE, // Set handle inheritance to FALSE
  325. 0, // No creation flags
  326. NULL, // Use parent's environment block
  327. strDircet, // Use parent's starting directory
  328. &si, // Pointer to STARTUPINFO structure
  329. &pi); // Pointer to PROCESS_INFORMATION structure
  330. // 运行时长清零
  331. if(bRet)
  332. {
  333. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: 进程%s启动成功, Path = %s"), ProInfo.m_szName, ProInfo.m_szPath);
  334. ProInfo.m_nRunTimer = 0;
  335. CloseHandle( pi.hProcess );
  336. CloseHandle( pi.hThread );
  337. Sleep(5000);
  338. }
  339. else
  340. {
  341. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 进程%s启动失败, Path = %s, Cause = %s"),
  342. ProInfo.m_szName, ProInfo.m_szPath, __getLastError());
  343. }
  344. }
  345. /*****************************************************************
  346. **【函数名称】 __runProcess
  347. **【函数功能】 运行指定进程并前台显示
  348. **【参数】 ProInfo 进程信息
  349. **【返回值】
  350. ****************************************************************/
  351. void CGuardMain::__runProcessByService(ProcessInfo& ProInfo)
  352. {
  353. // 获取登录用户信息
  354. HANDLE hToken = NULL;
  355. if(!__getTokenByName(hToken, _T("EXPLORER.EXE")))
  356. {
  357. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 启动进程%s时获取用户令牌失败, Cause = %s"), __getLastError());
  358. return;
  359. }
  360. typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE)(HANDLE hToken, LPPROFILEINFO lpProfileInfo);
  361. HMODULE hLib = LoadLibrary(_T("userenv.dll"));
  362. LPFNLOADUSERPROFILE LoadUserProfile = NULL;
  363. #ifdef UNICODE
  364. LoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hLib, _T("LoadUserProfileW"));
  365. #else
  366. LoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hLib, _T("LoadUserProfileA"));
  367. #endif
  368. if(LoadUserProfile == NULL) return;
  369. PROFILEINFO profile = {0};
  370. profile.dwSize = sizeof(PROFILEINFO);
  371. profile.lpUserName = "administrator";
  372. if(LoadUserProfile(hToken, &profile) == NULL)
  373. {
  374. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Guard}: 启动进程%s时加载用户配置文件失败, Cause = %s"), __getLastError());
  375. return;
  376. }
  377. PROCESS_INFORMATION pi; // 进程信息
  378. STARTUPINFO lp = {0}; // 新进程窗口信息
  379. lp.cb = sizeof(lp);
  380. lp.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
  381. lp.wShowWindow = SW_HIDE;
  382. // 启动新进程
  383. BOOL bRet = CreateProcessAsUser(hToken,
  384. ProInfo.m_szPath,
  385. NULL,
  386. NULL,
  387. NULL,
  388. FALSE,
  389. NORMAL_PRIORITY_CLASS,
  390. NULL,
  391. NULL,
  392. &lp,
  393. &pi);
  394. CloseHandle(hToken);
  395. }
  396. /*****************************************************************
  397. **【函数名称】 __watchThreadFun
  398. **【函数功能】 监控线程类
  399. **【参数】
  400. **【返回值】
  401. ****************************************************************/
  402. UINT CGuardMain::__watchThreadFun(LPVOID Param)
  403. {
  404. CGuardMain* pGuard = (CGuardMain*)Param;
  405. ASSERT(pGuard != NULL);
  406. while(TRUE)
  407. {
  408. Sleep(WATCH_TIMER_SERVICE);
  409. pGuard->__onWatch();
  410. }
  411. return 0;
  412. }
  413. /*****************************************************************
  414. **【函数名称】 __timerThreadFun
  415. **【函数功能】 定时器线程函数
  416. **【参数】
  417. **【返回值】
  418. ****************************************************************/
  419. UINT CGuardMain::__timerThreadFun(LPVOID Param)
  420. {
  421. CGuardMain* pGuard = (CGuardMain*)Param;
  422. ASSERT(pGuard != NULL);
  423. while(TRUE)
  424. {
  425. // 每个小时观察一次
  426. Sleep(1000 * 3600);
  427. pGuard->__onTimer();
  428. }
  429. return 0;
  430. }
  431. /*****************************************************************
  432. **【函数名称】 init
  433. **【函数功能】 初始化监控控制类
  434. **【参数】
  435. **【返回值】
  436. ****************************************************************/
  437. bool CGuardMain::init( void )
  438. {
  439. //__runWithOs();
  440. // 加载配置信息
  441. if(!__loadConfigInfo())
  442. {
  443. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 读取映射文件失败, Cause = %s"), __getLastError());
  444. return false;
  445. }
  446. // 创建监控线程
  447. m_pThreadWatch = AfxBeginThread(__watchThreadFun, this, 0, 0, CREATE_SUSPENDED, NULL);
  448. if(m_pThreadWatch == NULL)
  449. {
  450. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 启动守护监控线程失败"));
  451. return false;
  452. }
  453. // 创建定时器线程
  454. m_pThreadTimer = AfxBeginThread(__timerThreadFun, this, 0, 0, CREATE_SUSPENDED, NULL);
  455. if(m_pThreadTimer == NULL)
  456. {
  457. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Guard}: 启动定时守护线程失败"));
  458. return false;
  459. }
  460. // 启动监控服务
  461. startWatchServer();
  462. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Guard}: 守护功能启动成功"));
  463. return TRUE;
  464. }
  465. /*****************************************************************
  466. **【函数名称】 startWatch
  467. **【函数功能】 开始监控
  468. **【参数】
  469. **【返回值】
  470. ****************************************************************/
  471. void CGuardMain::startWatchServer()
  472. {
  473. if(m_pThreadWatch != NULL) m_pThreadWatch->ResumeThread();
  474. if(m_pThreadTimer != NULL) m_pThreadTimer->ResumeThread();
  475. }
  476. /*****************************************************************
  477. **【函数名称】 stopWatch
  478. **【函数功能】 停止监控
  479. **【参数】
  480. **【返回值】
  481. ****************************************************************/
  482. void CGuardMain::stopWatchServer()
  483. {
  484. if(m_pThreadWatch != NULL) m_pThreadWatch->SuspendThread();
  485. if(m_pThreadTimer != NULL) m_pThreadTimer->SuspendThread();
  486. }