WinService.cpp 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808
  1. #include "stdafx.h"
  2. #include "WinService.h"
  3. #include <psapi.h>
  4. #include <tlhelp32.h>
  5. #pragma comment ( lib, "psapi.lib" )
  6. #include <Aclapi.h>
  7. #include <strsafe.h>
  8. #include <shlwapi.h>
  9. namespace WinService
  10. {
  11. SCVariant g_scVariant;
  12. int InitWinSock()
  13. {
  14. WORD wVersionRequested;
  15. WSADATA wsaData;
  16. int nErrCode;
  17. wVersionRequested = MAKEWORD(2, 2);
  18. nErrCode = WSAStartup(wVersionRequested, &wsaData);
  19. if (0 != nErrCode)
  20. return -1;
  21. return 0;
  22. }
  23. /************************************************************************/
  24. /* 函数:[7/20/2017 IT];
  25. /* 描述:初始化服务名称和描述名称;
  26. /* 参数:;
  27. /* [IN] :;
  28. /* [OUT] :;
  29. /* [IN/OUT] :;
  30. /* 返回:void;
  31. /* 注意:;
  32. /* 示例:;
  33. /*
  34. /* 修改:;
  35. /* 日期:;
  36. /* 内容:;
  37. /************************************************************************/
  38. void InitServiceName(IN LPCTSTR lpServiceName, IN LPCTSTR lpServiceDescription)
  39. {
  40. if (lpServiceName == NULL || lpServiceName[0] == '\0')
  41. {
  42. TCHAR szModuleFileName[MAX_PATH] = { 0 };
  43. TCHAR szExeName[MAX_PATH] = { 0 };
  44. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  45. TCHAR szDir[_MAX_DIR] = { 0 };
  46. TCHAR szFna[_MAX_DIR] = { 0 };
  47. TCHAR szExt[_MAX_DIR] = { 0 };
  48. ::GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName) / sizeof(TCHAR));
  49. _tsplitpath_s(szModuleFileName, szDrive, szDir, szFna, szExt);
  50. // 用程序名来当服务名称;
  51. _stprintf_s(g_scVariant.scName, _T("%s"), szFna);
  52. }
  53. else
  54. {
  55. _stprintf_s(g_scVariant.scName, _T("%s"), lpServiceName);
  56. }
  57. if (lpServiceDescription == NULL || lpServiceDescription[0] == '\0')
  58. _stprintf_s(g_scVariant.scDescription, _T("%s"), g_scVariant.scName);
  59. else
  60. _stprintf_s(g_scVariant.scDescription, _T("%s"), lpServiceDescription);
  61. }
  62. /************************************************************************/
  63. /* 函数:[7/20/2017 IT];
  64. /* 描述:;
  65. /* 参数:;
  66. /* [IN] :;
  67. /* [OUT] :;
  68. /* [IN/OUT] :;
  69. /* 返回:void;
  70. /* 注意:;
  71. /* 示例:;
  72. /*
  73. /* 修改:;
  74. /* 日期:;
  75. /* 内容:;
  76. /************************************************************************/
  77. BOOL IsInstalled()
  78. {
  79. BOOL bResult = FALSE;
  80. // 打开服务控制管理器;
  81. SC_HANDLE schSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  82. if (schSCM != NULL)
  83. {// 打开服务;
  84. SC_HANDLE schSvc = ::OpenService(schSCM, g_scVariant.scName, SERVICE_QUERY_CONFIG);
  85. if (schSvc != NULL)
  86. {
  87. bResult = TRUE;
  88. ::CloseServiceHandle(schSvc);
  89. }
  90. ::CloseServiceHandle(schSCM);
  91. }
  92. return bResult;
  93. }
  94. /************************************************************************/
  95. /* 函数:[7/20/2017 IT];
  96. /* 描述:;
  97. /* 参数:;
  98. /* [IN] :;
  99. /* [OUT] :;
  100. /* [IN/OUT] :;
  101. /* 返回:void;
  102. /* 注意:;
  103. /* 示例:;
  104. /*
  105. /* 修改:;
  106. /* 日期:;
  107. /* 内容:;
  108. /************************************************************************/
  109. BOOL Install()
  110. {
  111. // 获取服务程序的绝对路径;
  112. TCHAR szFilePath[MAX_PATH];
  113. if (0 == ::GetModuleFileName(NULL, szFilePath, MAX_PATH))
  114. {
  115. _tprintf_s(_T("Cannot Install Service (%d)\n"), GetLastError());
  116. return FALSE;
  117. }
  118. // 打开服务控制管理器,获取SCM数据库句柄;
  119. SC_HANDLE schSCM = ::OpenSCManager(
  120. NULL, // 本地计算机;
  121. NULL, // ServicesActive database;
  122. SC_MANAGER_ALL_ACCESS // 所有权限;
  123. );
  124. if (schSCM == NULL)
  125. {
  126. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  127. return FALSE;
  128. }
  129. // 创建服务;
  130. SC_HANDLE schSvc = ::CreateService(
  131. schSCM, // SCM数据库;
  132. g_scVariant.scName, // 服务名称;
  133. g_scVariant.scDescription, // 服务描述;
  134. SERVICE_ALL_ACCESS, // 需要的访问权限;
  135. SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // 服务类型;
  136. SERVICE_AUTO_START, //SERVICE_DEMAND_START, // 启动类型;
  137. SERVICE_ERROR_NORMAL, // 错误控制类型;
  138. szFilePath, // 服务程序路径;
  139. NULL, // 无加载顺序组;
  140. NULL, // 无标签标识;
  141. _T(""), // 无依赖;
  142. NULL, // 本地系统账号;
  143. NULL // 无密码(no password);
  144. );
  145. if (schSvc == NULL)
  146. {
  147. _tprintf_s(_T("CreateService failed (%d)\n"), GetLastError());
  148. CloseServiceHandle(schSvc);
  149. return FALSE;
  150. }
  151. // 设置服务的描述;
  152. SERVICE_DESCRIPTION ServiceDesc;
  153. ServiceDesc.lpDescription = g_scVariant.scDescription;
  154. ::ChangeServiceConfig2(schSvc, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc);
  155. // 释放资源;
  156. ::CloseServiceHandle(schSvc);
  157. ::CloseServiceHandle(schSCM);
  158. return TRUE;
  159. }
  160. /************************************************************************/
  161. /* 函数:[7/20/2017 IT];
  162. /* 描述:;
  163. /* 参数:;
  164. /* [IN] :;
  165. /* [OUT] :;
  166. /* [IN/OUT] :;
  167. /* 返回:void;
  168. /* 注意:;
  169. /* 示例:;
  170. /*
  171. /* 修改:;
  172. /* 日期:;
  173. /* 内容:;
  174. /************************************************************************/
  175. BOOL Uninstall()
  176. {
  177. if (!IsInstalled()) return TRUE;
  178. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  179. if (hSCM == NULL) return FALSE;
  180. SC_HANDLE hService = ::OpenService(hSCM, g_scVariant.scName, SERVICE_STOP | DELETE);
  181. if (hService == NULL)
  182. {
  183. ::CloseServiceHandle(hSCM);
  184. return FALSE;
  185. }
  186. SERVICE_STATUS scStatus;
  187. ::ControlService(hService, SERVICE_CONTROL_STOP, &scStatus);
  188. // 删除服务;
  189. BOOL bDelete = ::DeleteService(hService);
  190. ::CloseServiceHandle(hService);
  191. ::CloseServiceHandle(hSCM);
  192. if (bDelete)
  193. {
  194. //LOG4C((LOG_NOTICE,"服务成功卸载"));
  195. return TRUE;
  196. }
  197. //LOG4C((LOG_NOTICE,"服务卸载失败"));
  198. LogEvent(_T("Service could not be deleted"));
  199. return FALSE;
  200. }
  201. /************************************************************************/
  202. /* 函数:ServiceMain[4/23/2016 home];
  203. /* 描述:服务入口函数;
  204. /* 参数:;
  205. /* 返回:void;
  206. /* 注意:;
  207. /* 示例:;
  208. /*
  209. /* 修改:;
  210. /* 日期:;
  211. /* 内容:;
  212. /************************************************************************/
  213. void WINAPI ServiceMain()
  214. {
  215. // 注册服务的控制函数;
  216. g_scVariant.scStatusHandle = RegisterServiceCtrlHandler(g_scVariant.scName, SvcCtrlHandler);
  217. if (g_scVariant.scStatusHandle == NULL)
  218. {
  219. SvcReportEvent(_T("Handler not installed"));
  220. return;
  221. }
  222. // 在这里设置服务状态;
  223. g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  224. g_scVariant.scStatus.dwServiceSpecificExitCode = 0;
  225. // 注册成功后向SCM报告服务状态信息,因为服务还没初始化完成;
  226. // 所以当前服务状态为SERVICE_START_PENDING ;
  227. ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000); // 处理第一个事件大约需要3秒钟;
  228. //////////////////////////////////////////////////////////////////////////
  229. // 开始初始化服务;
  230. g_scVariant.hscEvent = ::CreateEvent(NULL, TRUE, FALSE, _T("CtrlService::g_hCtrlSvc"));
  231. if (g_scVariant.hscEvent == NULL)
  232. {
  233. // 向SCM报告服务已停止;
  234. ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 0);
  235. return;
  236. }
  237. // 向SCM报告服务正在运行;
  238. ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
  239. // 开启工作者;
  240. if (g_scVariant.lpStartWorkCallBack)
  241. g_scVariant.lpStartWorkCallBack();
  242. // 线程中的处理函数运行结束后返回ServiceMain(),
  243. // ServiceMain()调用WaitForSingleObject,
  244. // 因为服务被停止之前ServiceMain()不会结束
  245. WaitForSingleObject(g_scVariant.hscEvent, INFINITE); // INFINITE表示无限等待,等待SCM的信号;
  246. CloseHandle(g_scVariant.hscEvent);
  247. // 结束工作者;
  248. if (g_scVariant.lpEndofWorkCallBack)
  249. g_scVariant.lpEndofWorkCallBack();
  250. SvcReportEvent(_T("Service stopped"));
  251. // 向SCM报告服务已停止工作;
  252. ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
  253. }
  254. /************************************************************************/
  255. /* 函数:SvcCtrlHandler[4/23/2016 home];
  256. /* 描述:每当有控制码发送给服务时被SCM调用;
  257. /* 参数:;
  258. /* [IN] dwControlCode:发送给服务的控制码;
  259. /* [OUT] :;
  260. /* [IN/OUT] :;
  261. /* 返回:void;
  262. /* 注意:;
  263. /* 示例:;
  264. /*
  265. /* 修改:;
  266. /* 日期:;
  267. /* 内容:;
  268. /************************************************************************/
  269. void WINAPI SvcCtrlHandler(IN DWORD dwControlCode)
  270. {
  271. BOOL bsucc = FALSE;
  272. switch (dwControlCode)
  273. {
  274. case SERVICE_CONTROL_SHUTDOWN: // 关掉服务;
  275. case SERVICE_CONTROL_STOP: // 停止服务;
  276. bsucc = ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 0);
  277. if (bsucc)
  278. {
  279. if (g_scVariant.lpEndofWorkCallBack)
  280. g_scVariant.lpEndofWorkCallBack();
  281. KillService();
  282. }
  283. break;
  284. case SERVICE_CONTROL_PAUSE:
  285. // 暂停服务;
  286. break;
  287. case SERVICE_CONTROL_CONTINUE:
  288. // 恢复被暂停的服务;
  289. break;
  290. case SERVICE_CONTROL_INTERROGATE:
  291. break;
  292. default:
  293. SvcReportEvent(_T("Bad service request"));
  294. }
  295. }
  296. /************************************************************************/
  297. /* 函数:ReportSvcStatus[4/22/2016 home];
  298. /* 描述:设置当前服务状态,并将其报告给SCM;
  299. /* 参数:;
  300. /* [IN] dwCurrentState:服务当前状态(详情见 SERVICE_STATUS);
  301. /* [IN] dwWin32ExitCode:系统返回服务的错误码;
  302. /* [IN] dwServiceSpecificExitCode:用户自定义的服务错误码;
  303. /* [OUT] dwCheckPoint:;
  304. /* [IN/OUT] dwWaitHint:挂起操作的估计用时;
  305. /* 返回:void;
  306. /* 注意:;
  307. /* 示例:;
  308. /*
  309. /* 修改:;
  310. /* 日期:;
  311. /* 内容:;
  312. /************************************************************************/
  313. BOOL ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
  314. {
  315. BOOL bSuccess;
  316. // 填充SERVICE_STATUS结构体,以便用于设置服务状态;
  317. g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; // 表示我们的服务是独占一个进程的服务 ;
  318. g_scVariant.scStatus.dwCurrentState = dwCurrentState; // 当前服务状态;
  319. g_scVariant.scStatus.dwWaitHint = dwWaitHint;
  320. if (dwCurrentState == SERVICE_START_PENDING)
  321. {
  322. g_scVariant.scStatus.dwControlsAccepted = 0; // 不接受任何控制通知;
  323. }
  324. else
  325. {
  326. // 通知 SCM 服务接受哪个控制通知:这里允许停止、关机、暂停继续;
  327. g_scVariant.scStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; //|SERVICE_ACCEPT_PAUSE_CONTINUE;
  328. }
  329. if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED))
  330. g_scVariant.scStatus.dwCheckPoint = 0;
  331. else
  332. g_scVariant.scStatus.dwCheckPoint = dwCheckPoint++;
  333. // dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。
  334. // 初始化服务时并不退出,因此值为 0;
  335. if (dwServiceSpecificExitCode == 0)
  336. {
  337. g_scVariant.scStatus.dwWin32ExitCode = dwWin32ExitCode;
  338. }
  339. else
  340. {
  341. g_scVariant.scStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; //用户自定义错误代码;
  342. }
  343. g_scVariant.scStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
  344. //设置好nServiceStatus后,向SCM报告服务状态,非0表示成功,0表示失败;
  345. bSuccess = SetServiceStatus(g_scVariant.scStatusHandle, &g_scVariant.scStatus);
  346. if (!bSuccess)
  347. {
  348. SvcReportEvent(_T("Set Service Status failed (%d) "), GetLastError());
  349. KillService();
  350. return FALSE;
  351. }
  352. else
  353. return TRUE;
  354. }
  355. // 结束服务;
  356. void KillService()
  357. {
  358. if (g_scVariant.hscEvent)
  359. SetEvent(g_scVariant.hscEvent); //如果操作成功,则返回非零值,否则为0。设置事件的状态为有标记,释放任意等待线程。如果事件是手工的,此事件将保持有标记直到调用ResetEvent。这种情况下将释放多个线程,如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。如果没有线程在等待,则此事件将保持有标记,直到一个线程被释放。
  360. //ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0,0,0);
  361. }
  362. /************************************************************************/
  363. /* 函数:[4/23/2016 home];
  364. /* 描述:;
  365. /* 参数:;
  366. /* [IN] :;
  367. /* [OUT] :;
  368. /* [IN/OUT] :;
  369. /* 返回:void;
  370. /* 注意:;
  371. /* 示例:;
  372. /*
  373. /* 修改:;
  374. /* 日期:;
  375. /* 内容:;
  376. /************************************************************************/
  377. void SvcReportEvent(IN LPCTSTR pFormat, ...)
  378. {
  379. TCHAR szReport[MAX_PATH] = { 0 };
  380. HANDLE hEventSource;
  381. LPCTSTR lpszStrings[2];
  382. va_list pArg = NULL;
  383. va_start(pArg, pFormat);
  384. StringCchVPrintf(szReport, MAX_PATH, pFormat, pArg);
  385. va_end(pArg);
  386. hEventSource = RegisterEventSource(NULL, g_scVariant.scName);
  387. if (hEventSource != NULL)
  388. {
  389. lpszStrings[0] = g_scVariant.scName;
  390. lpszStrings[1] = szReport;
  391. ReportEvent(
  392. hEventSource, // 事件日志句柄;
  393. EVENTLOG_INFORMATION_TYPE, // 事件类型;
  394. 0, // 事件类别;
  395. 0/*SVC_ERROR*/, // 事件标识;
  396. NULL, // 无安全标识;
  397. 2, // lpszStrings数组大小;
  398. 0, // 无二进制数据;
  399. lpszStrings, // 字符串数组;
  400. NULL // 无二进制数据;
  401. );
  402. DeregisterEventSource(hEventSource);
  403. }
  404. }
  405. /************************************************************************/
  406. /* 函数:StartSvc[4/23/2016 home];
  407. /* 描述:启动服务;
  408. /* 参数:;
  409. /* [IN] lpSvcName:要打开的服务名称;
  410. /* 返回:void;
  411. /* 注意:;
  412. /* 示例:;
  413. /*
  414. /* 修改:;
  415. /* 日期:;
  416. /* 内容:;
  417. /************************************************************************/
  418. void StartSvc(IN LPCTSTR lpSvcName)
  419. {
  420. TCHAR szSvcName[MAX_PATH] = { 0 };
  421. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  422. _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName);
  423. else
  424. _stprintf_s(szSvcName, _T("%s"), lpSvcName);
  425. SC_HANDLE schSCM;
  426. SC_HANDLE schService;
  427. SERVICE_STATUS_PROCESS ssStatus;
  428. DWORD dwOldCheckPoint;
  429. DWORD dwStartTickCount;
  430. DWORD dwWaitTime;
  431. DWORD dwBytesNeeded;
  432. // 打开服务管理器;
  433. schSCM = OpenSCManager(
  434. NULL, // NULL表示要地计算机;
  435. NULL, // NULl表示服务活动数据库;
  436. SC_MANAGER_ALL_ACCESS); // 全部管理权限;
  437. if (NULL == schSCM)
  438. {
  439. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  440. return;
  441. }
  442. // 获取服务句柄;
  443. schService = OpenService(
  444. schSCM, // SCM数据库;
  445. szSvcName, // 服务名称;
  446. SERVICE_ALL_ACCESS); // 全部权限;
  447. if (schService == NULL)
  448. {
  449. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  450. CloseServiceHandle(schSCM);
  451. return;
  452. }
  453. // 启动服务前,检查服务状态以防服务不是停止的状态;
  454. if (!QueryServiceStatusEx(
  455. schService, // 服务句柄;
  456. SC_STATUS_PROCESS_INFO, // 要查询的服务状态类型;
  457. (LPBYTE)&ssStatus, // 服务状态对象地址;
  458. sizeof(SERVICE_STATUS_PROCESS), // 结构体大小;
  459. &dwBytesNeeded)) // size needed if buffer is too small
  460. {
  461. _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
  462. CloseServiceHandle(schService);
  463. CloseServiceHandle(schSCM);
  464. return;
  465. }
  466. // Check if the service is already running. It would be possible
  467. // to stop the service here, but for simplicity this example just returns.
  468. // 如果服务已经在运行,检查;可以在这里停止服务,简单起见,这里只返回;
  469. if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
  470. {
  471. _tprintf_s(_T("Cannot start the service because it is already running\n"));
  472. CloseServiceHandle(schService);
  473. CloseServiceHandle(schSCM);
  474. return;
  475. }
  476. // Save the tick count and initial checkpoint.
  477. // 保持计数值并初始化检查点;
  478. dwStartTickCount = GetTickCount();
  479. dwOldCheckPoint = ssStatus.dwCheckPoint;
  480. // Wait for the service to stop before attempting to start it.
  481. // 在尝试启动服务前,等待服务停止;
  482. while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
  483. {
  484. // Do not wait longer than the wait hint. A good interval is
  485. // one-tenth of the wait hint but not less than 1 second
  486. // and not more than 10 seconds.
  487. dwWaitTime = ssStatus.dwWaitHint / 10;
  488. if (dwWaitTime < 1000)
  489. dwWaitTime = 1000;
  490. else if (dwWaitTime > 10000)
  491. dwWaitTime = 10000;
  492. Sleep(dwWaitTime);
  493. // Check the status until the service is no longer stop pending.
  494. // 检测状态直到服务不再停止等待;
  495. if (!QueryServiceStatusEx(
  496. schService, // handle to service
  497. SC_STATUS_PROCESS_INFO, // information level
  498. (LPBYTE)&ssStatus, // address of structure
  499. sizeof(SERVICE_STATUS_PROCESS), // size of structure
  500. &dwBytesNeeded)) // size needed if buffer is too small
  501. {
  502. _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
  503. CloseServiceHandle(schService);
  504. CloseServiceHandle(schSCM);
  505. return;
  506. }
  507. if (ssStatus.dwCheckPoint > dwOldCheckPoint)
  508. {
  509. // Continue to wait and check.
  510. // 继续等待并检测;
  511. dwStartTickCount = GetTickCount();
  512. dwOldCheckPoint = ssStatus.dwCheckPoint;
  513. }
  514. else
  515. {
  516. if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
  517. {
  518. _tprintf_s(_T("Timeout waiting for service to stop\n"));
  519. CloseServiceHandle(schService);
  520. CloseServiceHandle(schSCM);
  521. return;
  522. }
  523. }
  524. }
  525. // Attempt to start the service.
  526. // 尝试启动服务;
  527. if (!StartService(
  528. schService, // handle to service
  529. 0, // number of arguments
  530. NULL)) // no arguments
  531. {
  532. _tprintf_s(_T("StartService failed (%d)\n"), GetLastError());
  533. CloseServiceHandle(schService);
  534. CloseServiceHandle(schSCM);
  535. return;
  536. }
  537. else printf("Service start pending...\n");
  538. // Check the status until the service is no longer start pending.
  539. // 检测服务状态直到服务不再启动挂起操作;
  540. if (!QueryServiceStatusEx(
  541. schService, // handle to service
  542. SC_STATUS_PROCESS_INFO, // info level
  543. (LPBYTE)&ssStatus, // address of structure
  544. sizeof(SERVICE_STATUS_PROCESS), // size of structure
  545. &dwBytesNeeded)) // if buffer too small
  546. {
  547. _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
  548. CloseServiceHandle(schService);
  549. CloseServiceHandle(schSCM);
  550. return;
  551. }
  552. // Save the tick count and initial checkpoint.
  553. dwStartTickCount = GetTickCount();
  554. dwOldCheckPoint = ssStatus.dwCheckPoint;
  555. while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
  556. {
  557. // Do not wait longer than the wait hint. A good interval is
  558. // one-tenth the wait hint, but no less than 1 second and no
  559. // more than 10 seconds.
  560. dwWaitTime = ssStatus.dwWaitHint / 10;
  561. if (dwWaitTime < 1000)
  562. dwWaitTime = 1000;
  563. else if (dwWaitTime > 10000)
  564. dwWaitTime = 10000;
  565. Sleep(dwWaitTime);
  566. // Check the status again.
  567. if (!QueryServiceStatusEx(
  568. schService, // handle to service
  569. SC_STATUS_PROCESS_INFO, // info level
  570. (LPBYTE)&ssStatus, // address of structure
  571. sizeof(SERVICE_STATUS_PROCESS), // size of structure
  572. &dwBytesNeeded)) // if buffer too small
  573. {
  574. _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
  575. break;
  576. }
  577. if (ssStatus.dwCheckPoint > dwOldCheckPoint)
  578. {
  579. // Continue to wait and check.
  580. dwStartTickCount = GetTickCount();
  581. dwOldCheckPoint = ssStatus.dwCheckPoint;
  582. }
  583. else
  584. {
  585. if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
  586. {
  587. // No progress made within the wait hint.
  588. break;
  589. }
  590. }
  591. }
  592. // Determine whether the service is running.
  593. if (ssStatus.dwCurrentState == SERVICE_RUNNING)
  594. {
  595. _tprintf_s(_T("Service started successfully.\n"));
  596. }
  597. else
  598. {
  599. _tprintf_s(_T("Service not started. \n"));
  600. _tprintf_s(_T(" Current State: %d\n"), ssStatus.dwCurrentState);
  601. _tprintf_s(_T(" Exit Code: %d\n"), ssStatus.dwWin32ExitCode);
  602. _tprintf_s(_T(" Check Point: %d\n"), ssStatus.dwCheckPoint);
  603. _tprintf_s(_T(" Wait Hint: %d\n"), ssStatus.dwWaitHint);
  604. }
  605. CloseServiceHandle(schService);
  606. CloseServiceHandle(schSCM);
  607. }
  608. /************************************************************************/
  609. /* 函数:UpdateSvcDacl[4/23/2016 home];
  610. /* 描述:;
  611. /* 参数:;
  612. /* [IN] :;
  613. /* [OUT] :;
  614. /* [IN/OUT] :;
  615. /* 返回:void;
  616. /* 注意:;
  617. /* 示例:;
  618. /*
  619. /* 修改:;
  620. /* 日期:;
  621. /* 内容:;
  622. /************************************************************************/
  623. void UpdateSvcDacl(IN LPCTSTR lpSvcName)
  624. {
  625. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  626. return;
  627. EXPLICIT_ACCESS ea;
  628. SECURITY_DESCRIPTOR sd;
  629. PSECURITY_DESCRIPTOR psd = NULL;
  630. PACL pacl = NULL;
  631. PACL pNewAcl = NULL;
  632. BOOL bDaclPresent = FALSE;
  633. BOOL bDaclDefaulted = FALSE;
  634. DWORD dwError = 0;
  635. DWORD dwSize = 0;
  636. DWORD dwBytesNeeded = 0;
  637. SC_HANDLE schSCManager;
  638. SC_HANDLE schService;
  639. // 获取SCM数据库的句柄值;
  640. schSCManager = OpenSCManager(
  641. NULL, // local computer
  642. NULL, // ServicesActive database
  643. SC_MANAGER_ALL_ACCESS); // full access rights
  644. if (NULL == schSCManager)
  645. {
  646. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  647. return;
  648. }
  649. // Get a handle to the service
  650. schService = OpenService(
  651. schSCManager, // SCManager database
  652. lpSvcName, // name of service
  653. READ_CONTROL | WRITE_DAC); // access
  654. if (schService == NULL)
  655. {
  656. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  657. CloseServiceHandle(schSCManager);
  658. return;
  659. }
  660. // Get the current security descriptor.
  661. // 获取当前服务的安全描述符;
  662. if (!QueryServiceObjectSecurity(schService,
  663. DACL_SECURITY_INFORMATION,
  664. &psd, // using NULL does not work on all versions
  665. 0,
  666. &dwBytesNeeded))
  667. {
  668. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  669. {
  670. dwSize = dwBytesNeeded;
  671. psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
  672. if (psd == NULL)
  673. {
  674. // Note: HeapAlloc does not support GetLastError.
  675. _tprintf_s(_T("HeapAlloc failed\n"));
  676. goto dacl_cleanup;
  677. }
  678. if (!QueryServiceObjectSecurity(schService,
  679. DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
  680. {
  681. _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
  682. goto dacl_cleanup;
  683. }
  684. }
  685. else
  686. {
  687. _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
  688. goto dacl_cleanup;
  689. }
  690. }
  691. // Get the DACL.
  692. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
  693. &bDaclDefaulted))
  694. {
  695. _tprintf_s(_T("GetSecurityDescriptorDacl failed(%d)\n"), GetLastError());
  696. goto dacl_cleanup;
  697. }
  698. // Build the ACE.
  699. BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
  700. SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
  701. SET_ACCESS, NO_INHERITANCE);
  702. dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
  703. if (dwError != ERROR_SUCCESS)
  704. {
  705. printf("SetEntriesInAcl failed(%d)\n", dwError);
  706. goto dacl_cleanup;
  707. }
  708. // Initialize a new security descriptor.
  709. if (!InitializeSecurityDescriptor(&sd,
  710. SECURITY_DESCRIPTOR_REVISION))
  711. {
  712. printf("InitializeSecurityDescriptor failed(%d)\n", GetLastError());
  713. goto dacl_cleanup;
  714. }
  715. // Set the new DACL in the security descriptor.
  716. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
  717. {
  718. printf("SetSecurityDescriptorDacl failed(%d)\n", GetLastError());
  719. goto dacl_cleanup;
  720. }
  721. // Set the new DACL for the service object.
  722. if (!SetServiceObjectSecurity(schService,
  723. DACL_SECURITY_INFORMATION, &sd))
  724. {
  725. printf("SetServiceObjectSecurity failed(%d)\n", GetLastError());
  726. goto dacl_cleanup;
  727. }
  728. else printf("Service DACL updated successfully\n");
  729. dacl_cleanup:
  730. CloseServiceHandle(schSCManager);
  731. CloseServiceHandle(schService);
  732. if (NULL != pNewAcl)
  733. LocalFree((HLOCAL)pNewAcl);
  734. if (NULL != psd)
  735. HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
  736. }
  737. void StopSvc(IN LPCTSTR lpSvcName)
  738. {
  739. TCHAR szSvcName[MAX_PATH] = { 0 };
  740. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  741. _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName);
  742. else
  743. _stprintf_s(szSvcName, _T("%s"), lpSvcName);
  744. SERVICE_STATUS_PROCESS ssp;
  745. DWORD dwStartTime = GetTickCount();
  746. DWORD dwBytesNeeded;
  747. DWORD dwTimeout = 30000; // 30-second time-out
  748. DWORD dwWaitTime;
  749. SC_HANDLE schSCManager;
  750. SC_HANDLE schService;
  751. // Get a handle to the SCM database.
  752. schSCManager = OpenSCManager(
  753. NULL, // local computer
  754. NULL, // ServicesActive database
  755. SC_MANAGER_ALL_ACCESS); // full access rights
  756. if (NULL == schSCManager)
  757. {
  758. printf("OpenSCManager failed (%d)\n", GetLastError());
  759. return;
  760. }
  761. // Get a handle to the service.
  762. schService = OpenService(
  763. schSCManager, // SCM database
  764. szSvcName, // name of service
  765. SERVICE_STOP |
  766. SERVICE_QUERY_STATUS |
  767. SERVICE_ENUMERATE_DEPENDENTS);
  768. if (schService == NULL)
  769. {
  770. printf("OpenService failed (%d)\n", GetLastError());
  771. CloseServiceHandle(schSCManager);
  772. return;
  773. }
  774. // Make sure the service is not already stopped.
  775. if (!QueryServiceStatusEx(
  776. schService,
  777. SC_STATUS_PROCESS_INFO,
  778. (LPBYTE)&ssp,
  779. sizeof(SERVICE_STATUS_PROCESS),
  780. &dwBytesNeeded))
  781. {
  782. printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
  783. goto stop_cleanup;
  784. }
  785. if (ssp.dwCurrentState == SERVICE_STOPPED)
  786. {
  787. printf("Service is already stopped.\n");
  788. goto stop_cleanup;
  789. }
  790. // If a stop is pending, wait for it.
  791. while (ssp.dwCurrentState == SERVICE_STOP_PENDING)
  792. {
  793. printf("Service stop pending...\n");
  794. // Do not wait longer than the wait hint. A good interval is
  795. // one-tenth of the wait hint but not less than 1 second
  796. // and not more than 10 seconds.
  797. dwWaitTime = ssp.dwWaitHint / 10;
  798. if (dwWaitTime < 1000)
  799. dwWaitTime = 1000;
  800. else if (dwWaitTime > 10000)
  801. dwWaitTime = 10000;
  802. Sleep(dwWaitTime);
  803. if (!QueryServiceStatusEx(
  804. schService,
  805. SC_STATUS_PROCESS_INFO,
  806. (LPBYTE)&ssp,
  807. sizeof(SERVICE_STATUS_PROCESS),
  808. &dwBytesNeeded))
  809. {
  810. printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
  811. goto stop_cleanup;
  812. }
  813. if (ssp.dwCurrentState == SERVICE_STOPPED)
  814. {
  815. printf("Service stopped successfully.\n");
  816. goto stop_cleanup;
  817. }
  818. if (GetTickCount() - dwStartTime > dwTimeout)
  819. {
  820. printf("Service stop timed out.\n");
  821. goto stop_cleanup;
  822. }
  823. }
  824. // If the service is running, dependencies must be stopped first.
  825. StopDependentServices();
  826. // Send a stop code to the service.
  827. if (!ControlService(
  828. schService,
  829. SERVICE_CONTROL_STOP,
  830. (LPSERVICE_STATUS)&ssp))
  831. {
  832. printf("ControlService failed (%d)\n", GetLastError());
  833. goto stop_cleanup;
  834. }
  835. // Wait for the service to stop.
  836. while (ssp.dwCurrentState != SERVICE_STOPPED)
  837. {
  838. Sleep(ssp.dwWaitHint);
  839. if (!QueryServiceStatusEx(
  840. schService,
  841. SC_STATUS_PROCESS_INFO,
  842. (LPBYTE)&ssp,
  843. sizeof(SERVICE_STATUS_PROCESS),
  844. &dwBytesNeeded))
  845. {
  846. printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
  847. goto stop_cleanup;
  848. }
  849. if (ssp.dwCurrentState == SERVICE_STOPPED)
  850. break;
  851. if (GetTickCount() - dwStartTime > dwTimeout)
  852. {
  853. printf("Wait timed out\n");
  854. goto stop_cleanup;
  855. }
  856. }
  857. printf("Service stopped successfully\n");
  858. stop_cleanup:
  859. CloseServiceHandle(schService);
  860. CloseServiceHandle(schSCManager);
  861. }
  862. BOOL StopDependentServices()
  863. {
  864. DWORD i;
  865. DWORD dwBytesNeeded;
  866. DWORD dwCount;
  867. LPENUM_SERVICE_STATUS lpDependencies = NULL;
  868. ENUM_SERVICE_STATUS ess;
  869. SC_HANDLE hDepService;
  870. SERVICE_STATUS_PROCESS ssp;
  871. DWORD dwStartTime = GetTickCount();
  872. DWORD dwTimeout = 30000; // 30-second time-out
  873. SC_HANDLE schSCManager = NULL;
  874. SC_HANDLE schService = NULL;
  875. // Pass a zero-length buffer to get the required buffer size.
  876. if (EnumDependentServices(schService, SERVICE_ACTIVE,
  877. lpDependencies, 0, &dwBytesNeeded, &dwCount))
  878. {
  879. // If the Enum call succeeds, then there are no dependent
  880. // services, so do nothing.
  881. return TRUE;
  882. }
  883. else
  884. {
  885. if (GetLastError() != ERROR_MORE_DATA)
  886. return FALSE; // Unexpected error
  887. // Allocate a buffer for the dependencies.
  888. lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(
  889. GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded);
  890. if (!lpDependencies)
  891. return FALSE;
  892. __try {
  893. // Enumerate the dependencies.
  894. if (!EnumDependentServices(schService, SERVICE_ACTIVE,
  895. lpDependencies, dwBytesNeeded, &dwBytesNeeded,
  896. &dwCount))
  897. return FALSE;
  898. for (i = 0; i < dwCount; i++)
  899. {
  900. ess = *(lpDependencies + i);
  901. // Open the service.
  902. hDepService = OpenService(schSCManager,
  903. ess.lpServiceName,
  904. SERVICE_STOP | SERVICE_QUERY_STATUS);
  905. if (!hDepService)
  906. return FALSE;
  907. __try {
  908. // Send a stop code.
  909. if (!ControlService(hDepService,
  910. SERVICE_CONTROL_STOP,
  911. (LPSERVICE_STATUS)&ssp))
  912. return FALSE;
  913. // Wait for the service to stop.
  914. while (ssp.dwCurrentState != SERVICE_STOPPED)
  915. {
  916. Sleep(ssp.dwWaitHint);
  917. if (!QueryServiceStatusEx(
  918. hDepService,
  919. SC_STATUS_PROCESS_INFO,
  920. (LPBYTE)&ssp,
  921. sizeof(SERVICE_STATUS_PROCESS),
  922. &dwBytesNeeded))
  923. return FALSE;
  924. if (ssp.dwCurrentState == SERVICE_STOPPED)
  925. break;
  926. if (GetTickCount() - dwStartTime > dwTimeout)
  927. return FALSE;
  928. }
  929. }
  930. __finally
  931. {
  932. // Always release the service handle.
  933. CloseServiceHandle(hDepService);
  934. }
  935. }
  936. }
  937. __finally
  938. {
  939. // Always free the enumeration buffer.
  940. HeapFree(GetProcessHeap(), 0, lpDependencies);
  941. }
  942. }
  943. return TRUE;
  944. }
  945. /************************************************************************/
  946. /* 函数:[4/23/2016 home];
  947. /* 描述:;
  948. /* 参数:;
  949. /* [IN] :;
  950. /* [OUT] :;
  951. /* [IN/OUT] :;
  952. /* 返回:void;
  953. /* 注意:;
  954. /* 示例:;
  955. /*
  956. /* 修改:;
  957. /* 日期:;
  958. /* 内容:;
  959. /************************************************************************/
  960. void DoQuerySvc(IN LPCTSTR lpSvcName)
  961. {
  962. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  963. {
  964. _tprintf_s(_T("要查询的服务名称无效\n"));
  965. return;
  966. }
  967. SC_HANDLE hSCM;
  968. SC_HANDLE hSvc;
  969. LPQUERY_SERVICE_CONFIG lpsc;
  970. LPSERVICE_DESCRIPTION lpsd;
  971. DWORD dwBytesNeeded, cbBfuSize, dwError;
  972. // 获取SCM句柄;
  973. hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  974. if (hSCM == NULL)
  975. {
  976. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  977. return;
  978. }
  979. // 获取服务句柄;
  980. hSvc = OpenService(
  981. hSCM,
  982. lpSvcName,
  983. SERVICE_QUERY_CONFIG // 需要查询设置的权限;
  984. );
  985. if (hSvc == NULL)
  986. {
  987. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  988. CloseServiceHandle(hSCM);
  989. return;
  990. }
  991. // 获取服务设置信息;
  992. if (!QueryServiceConfig(hSvc, NULL, 0, &dwBytesNeeded))
  993. {
  994. dwError = GetLastError();
  995. if (ERROR_INSUFFICIENT_BUFFER == dwError)
  996. {
  997. cbBfuSize = dwBytesNeeded;
  998. lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBfuSize);
  999. }
  1000. else
  1001. {
  1002. _tprintf_s(_T("QueryServiceConfig failed (%d)\n"), dwError);
  1003. goto cleanup;
  1004. }
  1005. }
  1006. if (!QueryServiceConfig(hSvc, lpsc, cbBfuSize, &dwBytesNeeded))
  1007. {
  1008. _tprintf_s(_T("QuerySericeConfig failed (%d)\n"), GetLastError());
  1009. goto cleanup;
  1010. }
  1011. if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded))
  1012. {
  1013. dwError = GetLastError();
  1014. if (ERROR_INSUFFICIENT_BUFFER == dwError)
  1015. {
  1016. cbBfuSize = dwBytesNeeded;
  1017. lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBfuSize);
  1018. }
  1019. else
  1020. {
  1021. _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
  1022. goto cleanup;
  1023. }
  1024. }
  1025. if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpsd, cbBfuSize, &dwBytesNeeded))
  1026. {
  1027. _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
  1028. goto cleanup;
  1029. }
  1030. //////////////////////////////////////////////////////////////////////////
  1031. // 查询成功,组织要返回的东西;
  1032. _tprintf(TEXT("%s configuration: \n"), g_scVariant.scName);
  1033. _tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType);
  1034. _tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType);
  1035. _tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl);
  1036. _tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName);
  1037. _tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName);
  1038. if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
  1039. _tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription);
  1040. if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
  1041. _tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup);
  1042. if (lpsc->dwTagId != 0)
  1043. _tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId);
  1044. if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
  1045. _tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies);
  1046. // 释放资源;
  1047. LocalFree(lpsc);
  1048. LocalFree(lpsd);
  1049. cleanup:
  1050. CloseServiceHandle(hSvc);
  1051. CloseServiceHandle(hSCM);
  1052. }
  1053. /************************************************************************/
  1054. /* 函数:[4/23/2016 home];
  1055. /* 描述:;
  1056. /* 参数:;
  1057. /* [IN] :;
  1058. /* [OUT] :;
  1059. /* [IN/OUT] :;
  1060. /* 返回:void;
  1061. /* 注意:;
  1062. /* 示例:;
  1063. /*
  1064. /* 修改:;
  1065. /* 日期:;
  1066. /* 内容:;
  1067. /************************************************************************/
  1068. void DoDisableSvc(IN LPCTSTR lpSvcName)
  1069. {
  1070. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  1071. {
  1072. _tprintf_s(_T("要禁用的服务名称无效\n"));
  1073. return;
  1074. }
  1075. SC_HANDLE schSCM;
  1076. SC_HANDLE schSvc;
  1077. // 打开SCM;
  1078. schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  1079. if (schSCM == NULL)
  1080. {
  1081. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  1082. return;
  1083. }
  1084. // 获取服务句柄;
  1085. schSvc = OpenService(schSCM, lpSvcName, SERVICE_CHANGE_CONFIG);
  1086. if (schSvc == NULL)
  1087. {
  1088. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  1089. CloseServiceHandle(schSCM);
  1090. return;
  1091. }
  1092. if (!ChangeServiceConfig(
  1093. schSvc,
  1094. SERVICE_NO_CHANGE, // service type: no change
  1095. SERVICE_DISABLED, // service start type
  1096. SERVICE_NO_CHANGE, // error control: no change
  1097. NULL, // binary path: no change
  1098. NULL, // load order group: no change
  1099. NULL, // tag ID: no change
  1100. NULL, // dependencies: no change
  1101. NULL, // account name: no change
  1102. NULL, // password: no change
  1103. NULL)) // display name: no change
  1104. {
  1105. _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
  1106. }
  1107. CloseServiceHandle(schSvc);
  1108. CloseServiceHandle(schSCM);
  1109. }
  1110. /************************************************************************/
  1111. /* 函数:[4/23/2016 home];
  1112. /* 描述:;
  1113. /* 参数:;
  1114. /* [IN] :;
  1115. /* [OUT] :;
  1116. /* [IN/OUT] :;
  1117. /* 返回:void;
  1118. /* 注意:;
  1119. /* 示例:;
  1120. /*
  1121. /* 修改:;
  1122. /* 日期:;
  1123. /* 内容:;
  1124. /************************************************************************/
  1125. void DoEnableSvc(IN LPCTSTR lpSvcName)
  1126. {
  1127. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  1128. {
  1129. _tprintf_s(_T("要启用的服务名称无效\n"));
  1130. return;
  1131. }
  1132. SC_HANDLE schSCM;
  1133. SC_HANDLE schSvc;
  1134. // Get a handle to the SCM database.
  1135. // 获取SCM数据库句柄;
  1136. schSCM = OpenSCManager(
  1137. NULL, // local computer
  1138. NULL, // ServicesActive database
  1139. SC_MANAGER_ALL_ACCESS); // full access rights
  1140. if (NULL == schSCM)
  1141. {
  1142. printf("OpenSCManager failed (%d)\n", GetLastError());
  1143. return;
  1144. }
  1145. // Get a handle to the service.
  1146. // 获取服务句柄值;
  1147. schSvc = OpenService(
  1148. schSCM, // SCM database
  1149. lpSvcName, // name of service
  1150. SERVICE_CHANGE_CONFIG); // need change config access
  1151. if (schSvc == NULL)
  1152. {
  1153. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  1154. CloseServiceHandle(schSCM);
  1155. return;
  1156. }
  1157. // Change the service start type.
  1158. // 改变服务启动类型;
  1159. if (!ChangeServiceConfig(
  1160. schSvc, // 服务句柄;
  1161. SERVICE_NO_CHANGE, // service type: no change
  1162. SERVICE_DEMAND_START, // service start type
  1163. SERVICE_NO_CHANGE, // error control: no change
  1164. NULL, // binary path: no change
  1165. NULL, // load order group: no change
  1166. NULL, // tag ID: no change
  1167. NULL, // dependencies: no change
  1168. NULL, // account name: no change
  1169. NULL, // password: no change
  1170. NULL)) // display name: no change
  1171. {
  1172. _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
  1173. }
  1174. else
  1175. {
  1176. _tprintf_s(_T("Service enabled successfully.\n"));
  1177. }
  1178. CloseServiceHandle(schSvc);
  1179. CloseServiceHandle(schSCM);
  1180. }
  1181. /************************************************************************/
  1182. /* 函数:[4/23/2016 home];
  1183. /* 描述:;
  1184. /* 参数:;
  1185. /* [IN] :;
  1186. /* [OUT] :;
  1187. /* [IN/OUT] :;
  1188. /* 返回:void;
  1189. /* 注意:;
  1190. /* 示例:;
  1191. /*
  1192. /* 修改:;
  1193. /* 日期:;
  1194. /* 内容:;
  1195. /************************************************************************/
  1196. void DoUpdateSvcDesc(IN LPCTSTR lpSvcName)
  1197. {
  1198. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  1199. {
  1200. _tprintf_s(_T("要更新描述的服务名称无效\n"));
  1201. return;
  1202. }
  1203. SC_HANDLE schSCM;
  1204. SC_HANDLE schSvc;
  1205. SERVICE_DESCRIPTION sd;
  1206. LPTSTR szDesc = TEXT("This is a test description");
  1207. // Get a handle to the SCM database.
  1208. // 获取SCM数据库句柄;
  1209. schSCM = OpenSCManager(
  1210. NULL, // NULL表示本地计算机;
  1211. NULL, // NULL表示:ServicesActive database
  1212. SC_MANAGER_ALL_ACCESS); // full access rights
  1213. if (NULL == schSCM)
  1214. {
  1215. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  1216. return;
  1217. }
  1218. // Get a handle to the service.
  1219. // 获取服务句柄值;
  1220. schSvc = OpenService(
  1221. schSCM, // SCM 数据库句柄;
  1222. lpSvcName, // 服务名称;
  1223. SERVICE_CHANGE_CONFIG); // need change config access
  1224. if (schSvc == NULL)
  1225. {
  1226. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  1227. CloseServiceHandle(schSCM);
  1228. return;
  1229. }
  1230. // Change the service description.
  1231. // 改变服务描述;
  1232. sd.lpDescription = szDesc;
  1233. if (!ChangeServiceConfig2(
  1234. schSvc, // 服务句柄;
  1235. SERVICE_CONFIG_DESCRIPTION, // 要改变的类型: description;
  1236. &sd)) // 新描述;
  1237. {
  1238. _tprintf_s(_T("ChangeServiceConfig2 failed\n"));
  1239. }
  1240. else
  1241. {
  1242. _tprintf_s(_T("Service description updated successfully.\n"));
  1243. }
  1244. CloseServiceHandle(schSvc);
  1245. CloseServiceHandle(schSCM);
  1246. }
  1247. /************************************************************************/
  1248. /* 函数:[4/23/2016 home];
  1249. /* 描述:;
  1250. /* 参数:;
  1251. /* [IN] :;
  1252. /* [OUT] :;
  1253. /* [IN/OUT] :;
  1254. /* 返回:void;
  1255. /* 注意:;
  1256. /* 示例:;
  1257. /*
  1258. /* 修改:;
  1259. /* 日期:;
  1260. /* 内容:;
  1261. /************************************************************************/
  1262. void DoDeleteSvc(IN LPCTSTR lpSvcName)
  1263. {
  1264. if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
  1265. {
  1266. _tprintf_s(_T("要删除的服务名称无效\n"));
  1267. return;
  1268. }
  1269. SC_HANDLE schSCM;
  1270. SC_HANDLE schSvc;
  1271. SERVICE_STATUS ssStatus;
  1272. // 打开服务管理器;
  1273. schSCM = OpenSCManager(
  1274. NULL, // NULL表示本地计算机;
  1275. NULL, // NULL表示ServicesActive database
  1276. SC_MANAGER_ALL_ACCESS); // full access rights
  1277. if (NULL == schSCM)
  1278. {
  1279. _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
  1280. return;
  1281. }
  1282. // 打开服务;
  1283. schSvc = OpenService(
  1284. schSCM, // SCM database
  1285. lpSvcName, // name of service
  1286. SERVICE_STOP | DELETE // need delete access
  1287. );
  1288. if (schSvc == NULL)
  1289. {
  1290. _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
  1291. CloseServiceHandle(schSCM);
  1292. return;
  1293. }
  1294. // 删除服务关,需要先停止服务;
  1295. if (!::ControlService(schSvc, SERVICE_CONTROL_STOP, &ssStatus))
  1296. {
  1297. _tprintf_s(_T("删除服务前停止服务失败 (%d)\n"), GetLastError());
  1298. }
  1299. // 删除服务;
  1300. if (!DeleteService(schSvc))
  1301. {
  1302. _tprintf_s(_T("DeleteService failed (%d)\n"), GetLastError());
  1303. SvcReportEvent(_T("Service could not be deleted"));
  1304. }
  1305. else
  1306. {
  1307. _tprintf_s(_T("Service deleted successfully\n"));
  1308. }
  1309. CloseServiceHandle(schSvc);
  1310. CloseServiceHandle(schSCM);
  1311. }
  1312. /************************************************************************/
  1313. /* 函数:SetCallBack[5/5/2016 Home];
  1314. /* 描述:设置回调函数;
  1315. /* 参数:;
  1316. /* [IN] lpStartWorkCallBack:工作开始回调指针;
  1317. /* [IN] lpEndofWorkCallBack:工作结束回调指针;
  1318. /* 返回:void;
  1319. /* 注意:;
  1320. /* 示例:;
  1321. /*
  1322. /* 修改:;
  1323. /* 日期:;
  1324. /* 内容:;
  1325. /************************************************************************/
  1326. void SetCallBack(IN LPVOID lpStartWorkCallBack, IN LPVOID lpEndofWorkCallBack)
  1327. {
  1328. if (g_scVariant.lpStartWorkCallBack == NULL)
  1329. g_scVariant.lpStartWorkCallBack = (WorkEndofCallback)lpStartWorkCallBack;
  1330. if (g_scVariant.lpEndofWorkCallBack == NULL)
  1331. g_scVariant.lpEndofWorkCallBack = (WorkEndofCallback)lpEndofWorkCallBack;
  1332. }
  1333. /************************************************************************/
  1334. /* 函数:StartProcess[5/6/2016 IT];
  1335. /* 描述:在服务进程里,调用外部EXE;
  1336. /* 参数:;
  1337. /* [IN] :;
  1338. /* [OUT] :;
  1339. /* [IN/OUT] :;
  1340. /* 返回:void;
  1341. /* 注意:;
  1342. /* 示例:;
  1343. /*
  1344. /* 修改:;
  1345. /* 日期:;
  1346. /* 内容:;
  1347. /************************************************************************/
  1348. BOOL StartProcess(IN LPCTSTR lpExePath)
  1349. {
  1350. #if 0
  1351. if (!lpExePath || !PathFileExists(lpExePath))
  1352. {
  1353. return FALSE;
  1354. }
  1355. HANDLE hToken;
  1356. if (!GetTokenByName(hToken, _T("EXPLORER.EXE")))
  1357. {
  1358. return FALSE;
  1359. }
  1360. STARTUPINFO si;
  1361. PROCESS_INFORMATION pi;
  1362. ZeroMemory(&si, sizeof(STARTUPINFO));
  1363. si.cb = sizeof(STARTUPINFO);
  1364. si.lpDesktop = TEXT("winsta0\\default");
  1365. BOOL bResult = CreateProcessAsUser(hToken, lpExePath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
  1366. DWORD dwError = GetLastError();// 返回740错误,表示服务必须在Admin账号下运行才能创建成功;
  1367. //CreateProcessWithTokenW(hToken, )
  1368. CloseHandle(hToken);
  1369. if (bResult)
  1370. {
  1371. // WriteLogAlways(_T("C:\\serverlog.txt"),_T("CreateProcessAsUser ok"));
  1372. }
  1373. else
  1374. {
  1375. //WriteLogAlways(_T("C:\\servererrlog.txt"),_T("CreateProcessAsUser failed"));
  1376. }
  1377. #else
  1378. HANDLE hPtoken = NULL;
  1379. GetExplorerToken(&hPtoken);
  1380. //if(!GetTokenByName(hPtoken,_T("EXPLORER.EXE")))
  1381. //{
  1382. // return FALSE;
  1383. //}
  1384. PROCESS_INFORMATION pi;
  1385. STARTUPINFOW si = { sizeof(STARTUPINFO), NULL, L"", NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_USESHOWWINDOW, 0, 0, NULL, 0, 0, 0 };
  1386. si.wShowWindow = SW_SHOW;
  1387. si.lpDesktop = NULL;
  1388. ZeroMemory(&pi, sizeof(pi));
  1389. static HMODULE advapi32_dll = LoadLibraryW(L"advapi32.dll");
  1390. if (!advapi32_dll)
  1391. return FALSE;
  1392. /*static F_CreateProcessWithTokenW f_CreateProcessWithTokenW = (F_CreateProcessWithTokenW)(
  1393. GetProcAddress(advapi32_dll,"CreateProcessWithTokenW"));
  1394. if (f_CreateProcessWithTokenW == NULL)
  1395. return ;
  1396. */
  1397. BOOL bResult = CreateProcessWithTokenW(hPtoken, LOGON_WITH_PROFILE, NULL, (LPWSTR)lpExePath, NULL, NULL, NULL, &si, &pi);
  1398. DWORD dwError = GetLastError();
  1399. Sleep(1000);
  1400. CloseHandle(pi.hProcess);
  1401. CloseHandle(pi.hThread);
  1402. #endif
  1403. return bResult;
  1404. }
  1405. /************************************************************************/
  1406. /* 函数:[5/6/2016 IT];
  1407. /* 描述:;
  1408. /* 参数:;
  1409. /* [IN] :;
  1410. /* [OUT] :;
  1411. /* [IN/OUT] :;
  1412. /* 返回:void;
  1413. /* 注意:;
  1414. /* 示例:;
  1415. /*
  1416. /* 修改:;
  1417. /* 日期:;
  1418. /* 内容:;
  1419. /************************************************************************/
  1420. BOOL GetTokenByName(IN HANDLE &hToken, IN LPCTSTR lpName)
  1421. {
  1422. if (!lpName)
  1423. {
  1424. return FALSE;
  1425. }
  1426. BOOL bRet = FALSE;
  1427. HANDLE hProcessSnap = NULL;
  1428. PROCESSENTRY32 pe32 = { 0 };
  1429. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1430. if (hProcessSnap == INVALID_HANDLE_VALUE)
  1431. return FALSE;
  1432. pe32.dwSize = sizeof(PROCESSENTRY32);
  1433. if (Process32First(hProcessSnap, &pe32))
  1434. {
  1435. do
  1436. {
  1437. CString exefile = pe32.szExeFile;
  1438. CString paraname = lpName;
  1439. if (!exefile.CompareNoCase(lpName))
  1440. {
  1441. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
  1442. bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
  1443. CloseHandle(hProcessSnap);
  1444. return bRet;
  1445. }
  1446. } while (Process32Next(hProcessSnap, &pe32));
  1447. bRet = TRUE;
  1448. }
  1449. else
  1450. bRet = FALSE;
  1451. CloseHandle(hProcessSnap);
  1452. return bRet;
  1453. }
  1454. /************************************************************************/
  1455. /* 函数:[5/6/2016 IT];
  1456. /* 描述:;
  1457. /* 参数:;
  1458. /* [IN] :;
  1459. /* [OUT] :;
  1460. /* [IN/OUT] :;
  1461. /* 返回:void;
  1462. /* 注意:;
  1463. /* 示例:;
  1464. /*
  1465. /* 修改:;
  1466. /* 日期:;
  1467. /* 内容:;
  1468. /************************************************************************/
  1469. // Jeff.Hacker. WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理;
  1470. BOOL GetDebugPriv()
  1471. {
  1472. // 返回的访问令牌指针;
  1473. HANDLE hToken;
  1474. // 接收所返回的制定特权名称的信息;
  1475. LUID sedebugnameValue;
  1476. // 新特权信息的指针(结构体);
  1477. TOKEN_PRIVILEGES tkp;
  1478. DWORD dwCurProcId = GetCurrentProcessId();
  1479. // 要修改访问权限的进程句柄;
  1480. HANDLE hCurProc;
  1481. hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
  1482. if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  1483. {
  1484. //ShowSystemErrorInfo(_T("升级包OpenProcessToken失败."),GetLastError());
  1485. return FALSE;
  1486. }
  1487. if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
  1488. {
  1489. //ShowSystemErrorInfo(_T("升级包LookupPrivilegeValue失败."),GetLastError());
  1490. CloseHandle(hToken);
  1491. return FALSE;
  1492. }
  1493. tkp.PrivilegeCount = 1;
  1494. tkp.Privileges[0].Luid = sedebugnameValue;
  1495. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1496. if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
  1497. {
  1498. //ShowSystemErrorInfo(_T("升级包AdjustTokenPrivileges失败."),GetLastError());
  1499. CloseHandle(hToken);
  1500. return FALSE;
  1501. }
  1502. CloseHandle(hCurProc);
  1503. CloseHandle(hToken);
  1504. return TRUE;
  1505. }
  1506. DWORD GetExplorerToken(OUT HANDLE* phExplorerToken)
  1507. {
  1508. DWORD dwStatus = ERROR_FILE_NOT_FOUND;
  1509. BOOL bRet = FALSE;
  1510. HANDLE hProcess = NULL;
  1511. HANDLE hProcessSnap = NULL;
  1512. TCHAR szExplorerPath[MAX_PATH] = { 0 };
  1513. TCHAR FileName[MAX_PATH] = { 0 };
  1514. PROCESSENTRY32 pe32 = { 0 };
  1515. __try
  1516. {
  1517. GetWindowsDirectory(szExplorerPath, MAX_PATH);
  1518. _tcscat_s(szExplorerPath, MAX_PATH, _T("\\Explorer.EXE"));
  1519. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1520. if (hProcessSnap == INVALID_HANDLE_VALUE)
  1521. {
  1522. dwStatus = GetLastError();
  1523. __leave;
  1524. }
  1525. pe32.dwSize = sizeof(PROCESSENTRY32);
  1526. if (!Process32First(hProcessSnap, &pe32))
  1527. {
  1528. dwStatus = GetLastError();
  1529. __leave;
  1530. }
  1531. int ii = 0;
  1532. do
  1533. {
  1534. hProcess = OpenProcess(PROCESS_ALL_ACCESS/*PROCESS_QUERY_INFORMATION*/, FALSE, pe32.th32ProcessID);
  1535. if (NULL != hProcess)
  1536. {
  1537. ii++;
  1538. //if ( GetModuleFileNameEx(hProcess , NULL , FileName , MAX_PATH) )
  1539. //{
  1540. if (_tcsicmp(pe32.szExeFile, _T("Explorer.EXE")) == 0)
  1541. {
  1542. HANDLE hToken;
  1543. if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken))
  1544. {
  1545. HANDLE hNewToken = NULL;
  1546. DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);
  1547. *phExplorerToken = hNewToken;
  1548. dwStatus = 0;
  1549. CloseHandle(hToken);
  1550. }
  1551. break;
  1552. }
  1553. //}
  1554. CloseHandle(hProcess);
  1555. hProcess = NULL;
  1556. }
  1557. } while (Process32Next(hProcessSnap, &pe32));
  1558. }
  1559. __finally
  1560. {
  1561. if (NULL != hProcess)
  1562. {
  1563. CloseHandle(hProcess);
  1564. }
  1565. if (NULL != hProcessSnap)
  1566. {
  1567. CloseHandle(hProcessSnap);
  1568. }
  1569. }
  1570. return dwStatus;
  1571. }
  1572. // 打进服务事件日志里;
  1573. void LogEvent(IN LPCTSTR pFormat, ...)
  1574. {
  1575. TCHAR chMsg[MAX_PATH];
  1576. HANDLE hEventLog;
  1577. LPTSTR lpszStrings[1];
  1578. va_list pArg;
  1579. va_start(pArg, pFormat);
  1580. StringCchVPrintf(chMsg, MAX_PATH, pFormat, pArg);
  1581. va_end(pArg);
  1582. lpszStrings[0] = chMsg;
  1583. hEventLog = RegisterEventSource(NULL, g_scVariant.scName);
  1584. if (hEventLog != NULL)
  1585. {
  1586. ReportEvent(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);
  1587. if (hEventLog)
  1588. DeregisterEventSource(hEventLog);
  1589. }
  1590. }
  1591. };