12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808 |
- #include "stdafx.h"
- #include "WinService.h"
- #include <psapi.h>
- #include <tlhelp32.h>
- #pragma comment ( lib, "psapi.lib" )
- #include <Aclapi.h>
- #include <strsafe.h>
- #include <shlwapi.h>
- namespace WinService
- {
- SCVariant g_scVariant;
- int InitWinSock()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int nErrCode;
- wVersionRequested = MAKEWORD(2, 2);
- nErrCode = WSAStartup(wVersionRequested, &wsaData);
- if (0 != nErrCode)
- return -1;
- return 0;
- }
- /************************************************************************/
- /* 函数:[7/20/2017 IT];
- /* 描述:初始化服务名称和描述名称;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void InitServiceName(IN LPCTSTR lpServiceName, IN LPCTSTR lpServiceDescription)
- {
- if (lpServiceName == NULL || lpServiceName[0] == '\0')
- {
- TCHAR szModuleFileName[MAX_PATH] = { 0 };
- TCHAR szExeName[MAX_PATH] = { 0 };
- TCHAR szDrive[_MAX_DRIVE] = { 0 };
- TCHAR szDir[_MAX_DIR] = { 0 };
- TCHAR szFna[_MAX_DIR] = { 0 };
- TCHAR szExt[_MAX_DIR] = { 0 };
- ::GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName) / sizeof(TCHAR));
- _tsplitpath_s(szModuleFileName, szDrive, szDir, szFna, szExt);
- // 用程序名来当服务名称;
- _stprintf_s(g_scVariant.scName, _T("%s"), szFna);
- }
- else
- {
- _stprintf_s(g_scVariant.scName, _T("%s"), lpServiceName);
- }
- if (lpServiceDescription == NULL || lpServiceDescription[0] == '\0')
- _stprintf_s(g_scVariant.scDescription, _T("%s"), g_scVariant.scName);
- else
- _stprintf_s(g_scVariant.scDescription, _T("%s"), lpServiceDescription);
- }
- /************************************************************************/
- /* 函数:[7/20/2017 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL IsInstalled()
- {
- BOOL bResult = FALSE;
- // 打开服务控制管理器;
- SC_HANDLE schSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (schSCM != NULL)
- {// 打开服务;
- SC_HANDLE schSvc = ::OpenService(schSCM, g_scVariant.scName, SERVICE_QUERY_CONFIG);
- if (schSvc != NULL)
- {
- bResult = TRUE;
- ::CloseServiceHandle(schSvc);
- }
- ::CloseServiceHandle(schSCM);
- }
- return bResult;
- }
- /************************************************************************/
- /* 函数:[7/20/2017 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL Install()
- {
- // 获取服务程序的绝对路径;
- TCHAR szFilePath[MAX_PATH];
- if (0 == ::GetModuleFileName(NULL, szFilePath, MAX_PATH))
- {
- _tprintf_s(_T("Cannot Install Service (%d)\n"), GetLastError());
- return FALSE;
- }
- // 打开服务控制管理器,获取SCM数据库句柄;
- SC_HANDLE schSCM = ::OpenSCManager(
- NULL, // 本地计算机;
- NULL, // ServicesActive database;
- SC_MANAGER_ALL_ACCESS // 所有权限;
- );
- if (schSCM == NULL)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return FALSE;
- }
- // 创建服务;
- SC_HANDLE schSvc = ::CreateService(
- schSCM, // SCM数据库;
- g_scVariant.scName, // 服务名称;
- g_scVariant.scDescription, // 服务描述;
- SERVICE_ALL_ACCESS, // 需要的访问权限;
- SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // 服务类型;
- SERVICE_AUTO_START, //SERVICE_DEMAND_START, // 启动类型;
- SERVICE_ERROR_NORMAL, // 错误控制类型;
- szFilePath, // 服务程序路径;
- NULL, // 无加载顺序组;
- NULL, // 无标签标识;
- _T(""), // 无依赖;
- NULL, // 本地系统账号;
- NULL // 无密码(no password);
- );
- if (schSvc == NULL)
- {
- _tprintf_s(_T("CreateService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSvc);
- return FALSE;
- }
- // 设置服务的描述;
- SERVICE_DESCRIPTION ServiceDesc;
- ServiceDesc.lpDescription = g_scVariant.scDescription;
- ::ChangeServiceConfig2(schSvc, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc);
- // 释放资源;
- ::CloseServiceHandle(schSvc);
- ::CloseServiceHandle(schSCM);
- return TRUE;
- }
- /************************************************************************/
- /* 函数:[7/20/2017 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL Uninstall()
- {
- if (!IsInstalled()) return TRUE;
- SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (hSCM == NULL) return FALSE;
- SC_HANDLE hService = ::OpenService(hSCM, g_scVariant.scName, SERVICE_STOP | DELETE);
- if (hService == NULL)
- {
- ::CloseServiceHandle(hSCM);
- return FALSE;
- }
- SERVICE_STATUS scStatus;
- ::ControlService(hService, SERVICE_CONTROL_STOP, &scStatus);
- // 删除服务;
- BOOL bDelete = ::DeleteService(hService);
- ::CloseServiceHandle(hService);
- ::CloseServiceHandle(hSCM);
- if (bDelete)
- {
- //LOG4C((LOG_NOTICE,"服务成功卸载"));
- return TRUE;
- }
- //LOG4C((LOG_NOTICE,"服务卸载失败"));
- LogEvent(_T("Service could not be deleted"));
- return FALSE;
- }
- /************************************************************************/
- /* 函数:ServiceMain[4/23/2016 home];
- /* 描述:服务入口函数;
- /* 参数:;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void WINAPI ServiceMain()
- {
- // 注册服务的控制函数;
- g_scVariant.scStatusHandle = RegisterServiceCtrlHandler(g_scVariant.scName, SvcCtrlHandler);
- if (g_scVariant.scStatusHandle == NULL)
- {
- SvcReportEvent(_T("Handler not installed"));
- return;
- }
- // 在这里设置服务状态;
- g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- g_scVariant.scStatus.dwServiceSpecificExitCode = 0;
- // 注册成功后向SCM报告服务状态信息,因为服务还没初始化完成;
- // 所以当前服务状态为SERVICE_START_PENDING ;
- ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000); // 处理第一个事件大约需要3秒钟;
- //////////////////////////////////////////////////////////////////////////
- // 开始初始化服务;
- g_scVariant.hscEvent = ::CreateEvent(NULL, TRUE, FALSE, _T("CtrlService::g_hCtrlSvc"));
- if (g_scVariant.hscEvent == NULL)
- {
- // 向SCM报告服务已停止;
- ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 0);
- return;
- }
- // 向SCM报告服务正在运行;
- ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
- // 开启工作者;
- if (g_scVariant.lpStartWorkCallBack)
- g_scVariant.lpStartWorkCallBack();
- // 线程中的处理函数运行结束后返回ServiceMain(),
- // ServiceMain()调用WaitForSingleObject,
- // 因为服务被停止之前ServiceMain()不会结束
- WaitForSingleObject(g_scVariant.hscEvent, INFINITE); // INFINITE表示无限等待,等待SCM的信号;
- CloseHandle(g_scVariant.hscEvent);
- // 结束工作者;
- if (g_scVariant.lpEndofWorkCallBack)
- g_scVariant.lpEndofWorkCallBack();
- SvcReportEvent(_T("Service stopped"));
- // 向SCM报告服务已停止工作;
- ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
- }
- /************************************************************************/
- /* 函数:SvcCtrlHandler[4/23/2016 home];
- /* 描述:每当有控制码发送给服务时被SCM调用;
- /* 参数:;
- /* [IN] dwControlCode:发送给服务的控制码;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void WINAPI SvcCtrlHandler(IN DWORD dwControlCode)
- {
- BOOL bsucc = FALSE;
- switch (dwControlCode)
- {
- case SERVICE_CONTROL_SHUTDOWN: // 关掉服务;
- case SERVICE_CONTROL_STOP: // 停止服务;
- bsucc = ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 0);
- if (bsucc)
- {
- if (g_scVariant.lpEndofWorkCallBack)
- g_scVariant.lpEndofWorkCallBack();
- KillService();
- }
- break;
- case SERVICE_CONTROL_PAUSE:
- // 暂停服务;
- break;
- case SERVICE_CONTROL_CONTINUE:
- // 恢复被暂停的服务;
- break;
- case SERVICE_CONTROL_INTERROGATE:
- break;
- default:
- SvcReportEvent(_T("Bad service request"));
- }
- }
- /************************************************************************/
- /* 函数:ReportSvcStatus[4/22/2016 home];
- /* 描述:设置当前服务状态,并将其报告给SCM;
- /* 参数:;
- /* [IN] dwCurrentState:服务当前状态(详情见 SERVICE_STATUS);
- /* [IN] dwWin32ExitCode:系统返回服务的错误码;
- /* [IN] dwServiceSpecificExitCode:用户自定义的服务错误码;
- /* [OUT] dwCheckPoint:;
- /* [IN/OUT] dwWaitHint:挂起操作的估计用时;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
- {
- BOOL bSuccess;
- // 填充SERVICE_STATUS结构体,以便用于设置服务状态;
- g_scVariant.scStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; // 表示我们的服务是独占一个进程的服务 ;
- g_scVariant.scStatus.dwCurrentState = dwCurrentState; // 当前服务状态;
- g_scVariant.scStatus.dwWaitHint = dwWaitHint;
- if (dwCurrentState == SERVICE_START_PENDING)
- {
- g_scVariant.scStatus.dwControlsAccepted = 0; // 不接受任何控制通知;
- }
- else
- {
- // 通知 SCM 服务接受哪个控制通知:这里允许停止、关机、暂停继续;
- g_scVariant.scStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; //|SERVICE_ACCEPT_PAUSE_CONTINUE;
- }
- if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED))
- g_scVariant.scStatus.dwCheckPoint = 0;
- else
- g_scVariant.scStatus.dwCheckPoint = dwCheckPoint++;
- // dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。
- // 初始化服务时并不退出,因此值为 0;
- if (dwServiceSpecificExitCode == 0)
- {
- g_scVariant.scStatus.dwWin32ExitCode = dwWin32ExitCode;
- }
- else
- {
- g_scVariant.scStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; //用户自定义错误代码;
- }
- g_scVariant.scStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
- //设置好nServiceStatus后,向SCM报告服务状态,非0表示成功,0表示失败;
- bSuccess = SetServiceStatus(g_scVariant.scStatusHandle, &g_scVariant.scStatus);
- if (!bSuccess)
- {
- SvcReportEvent(_T("Set Service Status failed (%d) "), GetLastError());
- KillService();
- return FALSE;
- }
- else
- return TRUE;
- }
- // 结束服务;
- void KillService()
- {
- if (g_scVariant.hscEvent)
- SetEvent(g_scVariant.hscEvent); //如果操作成功,则返回非零值,否则为0。设置事件的状态为有标记,释放任意等待线程。如果事件是手工的,此事件将保持有标记直到调用ResetEvent。这种情况下将释放多个线程,如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。如果没有线程在等待,则此事件将保持有标记,直到一个线程被释放。
- //ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0,0,0);
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void SvcReportEvent(IN LPCTSTR pFormat, ...)
- {
- TCHAR szReport[MAX_PATH] = { 0 };
- HANDLE hEventSource;
- LPCTSTR lpszStrings[2];
- va_list pArg = NULL;
- va_start(pArg, pFormat);
- StringCchVPrintf(szReport, MAX_PATH, pFormat, pArg);
- va_end(pArg);
- hEventSource = RegisterEventSource(NULL, g_scVariant.scName);
- if (hEventSource != NULL)
- {
- lpszStrings[0] = g_scVariant.scName;
- lpszStrings[1] = szReport;
- ReportEvent(
- hEventSource, // 事件日志句柄;
- EVENTLOG_INFORMATION_TYPE, // 事件类型;
- 0, // 事件类别;
- 0/*SVC_ERROR*/, // 事件标识;
- NULL, // 无安全标识;
- 2, // lpszStrings数组大小;
- 0, // 无二进制数据;
- lpszStrings, // 字符串数组;
- NULL // 无二进制数据;
- );
- DeregisterEventSource(hEventSource);
- }
- }
- /************************************************************************/
- /* 函数:StartSvc[4/23/2016 home];
- /* 描述:启动服务;
- /* 参数:;
- /* [IN] lpSvcName:要打开的服务名称;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void StartSvc(IN LPCTSTR lpSvcName)
- {
- TCHAR szSvcName[MAX_PATH] = { 0 };
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName);
- else
- _stprintf_s(szSvcName, _T("%s"), lpSvcName);
- SC_HANDLE schSCM;
- SC_HANDLE schService;
- SERVICE_STATUS_PROCESS ssStatus;
- DWORD dwOldCheckPoint;
- DWORD dwStartTickCount;
- DWORD dwWaitTime;
- DWORD dwBytesNeeded;
- // 打开服务管理器;
- schSCM = OpenSCManager(
- NULL, // NULL表示要地计算机;
- NULL, // NULl表示服务活动数据库;
- SC_MANAGER_ALL_ACCESS); // 全部管理权限;
- if (NULL == schSCM)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // 获取服务句柄;
- schService = OpenService(
- schSCM, // SCM数据库;
- szSvcName, // 服务名称;
- SERVICE_ALL_ACCESS); // 全部权限;
- if (schService == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCM);
- return;
- }
- // 启动服务前,检查服务状态以防服务不是停止的状态;
- if (!QueryServiceStatusEx(
- schService, // 服务句柄;
- SC_STATUS_PROCESS_INFO, // 要查询的服务状态类型;
- (LPBYTE)&ssStatus, // 服务状态对象地址;
- sizeof(SERVICE_STATUS_PROCESS), // 结构体大小;
- &dwBytesNeeded)) // size needed if buffer is too small
- {
- _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- // Check if the service is already running. It would be possible
- // to stop the service here, but for simplicity this example just returns.
- // 如果服务已经在运行,检查;可以在这里停止服务,简单起见,这里只返回;
- if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
- {
- _tprintf_s(_T("Cannot start the service because it is already running\n"));
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- // Save the tick count and initial checkpoint.
- // 保持计数值并初始化检查点;
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- // Wait for the service to stop before attempting to start it.
- // 在尝试启动服务前,等待服务停止;
- while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
- {
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- dwWaitTime = ssStatus.dwWaitHint / 10;
- if (dwWaitTime < 1000)
- dwWaitTime = 1000;
- else if (dwWaitTime > 10000)
- dwWaitTime = 10000;
- Sleep(dwWaitTime);
- // Check the status until the service is no longer stop pending.
- // 检测状态直到服务不再停止等待;
- if (!QueryServiceStatusEx(
- schService, // handle to service
- SC_STATUS_PROCESS_INFO, // information level
- (LPBYTE)&ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded)) // size needed if buffer is too small
- {
- _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- if (ssStatus.dwCheckPoint > dwOldCheckPoint)
- {
- // Continue to wait and check.
- // 继续等待并检测;
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- }
- else
- {
- if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
- {
- _tprintf_s(_T("Timeout waiting for service to stop\n"));
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- }
- }
- // Attempt to start the service.
- // 尝试启动服务;
- if (!StartService(
- schService, // handle to service
- 0, // number of arguments
- NULL)) // no arguments
- {
- _tprintf_s(_T("StartService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- else printf("Service start pending...\n");
- // Check the status until the service is no longer start pending.
- // 检测服务状态直到服务不再启动挂起操作;
- if (!QueryServiceStatusEx(
- schService, // handle to service
- SC_STATUS_PROCESS_INFO, // info level
- (LPBYTE)&ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded)) // if buffer too small
- {
- _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- return;
- }
- // Save the tick count and initial checkpoint.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
- {
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth the wait hint, but no less than 1 second and no
- // more than 10 seconds.
- dwWaitTime = ssStatus.dwWaitHint / 10;
- if (dwWaitTime < 1000)
- dwWaitTime = 1000;
- else if (dwWaitTime > 10000)
- dwWaitTime = 10000;
- Sleep(dwWaitTime);
- // Check the status again.
- if (!QueryServiceStatusEx(
- schService, // handle to service
- SC_STATUS_PROCESS_INFO, // info level
- (LPBYTE)&ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded)) // if buffer too small
- {
- _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
- break;
- }
- if (ssStatus.dwCheckPoint > dwOldCheckPoint)
- {
- // Continue to wait and check.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- }
- else
- {
- if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
- {
- // No progress made within the wait hint.
- break;
- }
- }
- }
- // Determine whether the service is running.
- if (ssStatus.dwCurrentState == SERVICE_RUNNING)
- {
- _tprintf_s(_T("Service started successfully.\n"));
- }
- else
- {
- _tprintf_s(_T("Service not started. \n"));
- _tprintf_s(_T(" Current State: %d\n"), ssStatus.dwCurrentState);
- _tprintf_s(_T(" Exit Code: %d\n"), ssStatus.dwWin32ExitCode);
- _tprintf_s(_T(" Check Point: %d\n"), ssStatus.dwCheckPoint);
- _tprintf_s(_T(" Wait Hint: %d\n"), ssStatus.dwWaitHint);
- }
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCM);
- }
- /************************************************************************/
- /* 函数:UpdateSvcDacl[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void UpdateSvcDacl(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- return;
- EXPLICIT_ACCESS ea;
- SECURITY_DESCRIPTOR sd;
- PSECURITY_DESCRIPTOR psd = NULL;
- PACL pacl = NULL;
- PACL pNewAcl = NULL;
- BOOL bDaclPresent = FALSE;
- BOOL bDaclDefaulted = FALSE;
- DWORD dwError = 0;
- DWORD dwSize = 0;
- DWORD dwBytesNeeded = 0;
- SC_HANDLE schSCManager;
- SC_HANDLE schService;
- // 获取SCM数据库的句柄值;
- schSCManager = OpenSCManager(
- NULL, // local computer
- NULL, // ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
- if (NULL == schSCManager)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // Get a handle to the service
- schService = OpenService(
- schSCManager, // SCManager database
- lpSvcName, // name of service
- READ_CONTROL | WRITE_DAC); // access
- if (schService == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCManager);
- return;
- }
- // Get the current security descriptor.
- // 获取当前服务的安全描述符;
- if (!QueryServiceObjectSecurity(schService,
- DACL_SECURITY_INFORMATION,
- &psd, // using NULL does not work on all versions
- 0,
- &dwBytesNeeded))
- {
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- dwSize = dwBytesNeeded;
- psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
- if (psd == NULL)
- {
- // Note: HeapAlloc does not support GetLastError.
- _tprintf_s(_T("HeapAlloc failed\n"));
- goto dacl_cleanup;
- }
- if (!QueryServiceObjectSecurity(schService,
- DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
- {
- _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
- goto dacl_cleanup;
- }
- }
- else
- {
- _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
- goto dacl_cleanup;
- }
- }
- // Get the DACL.
- if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
- &bDaclDefaulted))
- {
- _tprintf_s(_T("GetSecurityDescriptorDacl failed(%d)\n"), GetLastError());
- goto dacl_cleanup;
- }
- // Build the ACE.
- BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
- SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
- SET_ACCESS, NO_INHERITANCE);
- dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
- if (dwError != ERROR_SUCCESS)
- {
- printf("SetEntriesInAcl failed(%d)\n", dwError);
- goto dacl_cleanup;
- }
- // Initialize a new security descriptor.
- if (!InitializeSecurityDescriptor(&sd,
- SECURITY_DESCRIPTOR_REVISION))
- {
- printf("InitializeSecurityDescriptor failed(%d)\n", GetLastError());
- goto dacl_cleanup;
- }
- // Set the new DACL in the security descriptor.
- if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
- {
- printf("SetSecurityDescriptorDacl failed(%d)\n", GetLastError());
- goto dacl_cleanup;
- }
- // Set the new DACL for the service object.
- if (!SetServiceObjectSecurity(schService,
- DACL_SECURITY_INFORMATION, &sd))
- {
- printf("SetServiceObjectSecurity failed(%d)\n", GetLastError());
- goto dacl_cleanup;
- }
- else printf("Service DACL updated successfully\n");
- dacl_cleanup:
- CloseServiceHandle(schSCManager);
- CloseServiceHandle(schService);
- if (NULL != pNewAcl)
- LocalFree((HLOCAL)pNewAcl);
- if (NULL != psd)
- HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
- }
- void StopSvc(IN LPCTSTR lpSvcName)
- {
- TCHAR szSvcName[MAX_PATH] = { 0 };
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- _stprintf_s(szSvcName, _T("%s"), g_scVariant.scName);
- else
- _stprintf_s(szSvcName, _T("%s"), lpSvcName);
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwBytesNeeded;
- DWORD dwTimeout = 30000; // 30-second time-out
- DWORD dwWaitTime;
- SC_HANDLE schSCManager;
- SC_HANDLE schService;
- // Get a handle to the SCM database.
- schSCManager = OpenSCManager(
- NULL, // local computer
- NULL, // ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
- if (NULL == schSCManager)
- {
- printf("OpenSCManager failed (%d)\n", GetLastError());
- return;
- }
- // Get a handle to the service.
- schService = OpenService(
- schSCManager, // SCM database
- szSvcName, // name of service
- SERVICE_STOP |
- SERVICE_QUERY_STATUS |
- SERVICE_ENUMERATE_DEPENDENTS);
- if (schService == NULL)
- {
- printf("OpenService failed (%d)\n", GetLastError());
- CloseServiceHandle(schSCManager);
- return;
- }
- // Make sure the service is not already stopped.
- if (!QueryServiceStatusEx(
- schService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded))
- {
- printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
- goto stop_cleanup;
- }
- if (ssp.dwCurrentState == SERVICE_STOPPED)
- {
- printf("Service is already stopped.\n");
- goto stop_cleanup;
- }
- // If a stop is pending, wait for it.
- while (ssp.dwCurrentState == SERVICE_STOP_PENDING)
- {
- printf("Service stop pending...\n");
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- dwWaitTime = ssp.dwWaitHint / 10;
- if (dwWaitTime < 1000)
- dwWaitTime = 1000;
- else if (dwWaitTime > 10000)
- dwWaitTime = 10000;
- Sleep(dwWaitTime);
- if (!QueryServiceStatusEx(
- schService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded))
- {
- printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
- goto stop_cleanup;
- }
- if (ssp.dwCurrentState == SERVICE_STOPPED)
- {
- printf("Service stopped successfully.\n");
- goto stop_cleanup;
- }
- if (GetTickCount() - dwStartTime > dwTimeout)
- {
- printf("Service stop timed out.\n");
- goto stop_cleanup;
- }
- }
- // If the service is running, dependencies must be stopped first.
- StopDependentServices();
- // Send a stop code to the service.
- if (!ControlService(
- schService,
- SERVICE_CONTROL_STOP,
- (LPSERVICE_STATUS)&ssp))
- {
- printf("ControlService failed (%d)\n", GetLastError());
- goto stop_cleanup;
- }
- // Wait for the service to stop.
- while (ssp.dwCurrentState != SERVICE_STOPPED)
- {
- Sleep(ssp.dwWaitHint);
- if (!QueryServiceStatusEx(
- schService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded))
- {
- printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
- goto stop_cleanup;
- }
- if (ssp.dwCurrentState == SERVICE_STOPPED)
- break;
- if (GetTickCount() - dwStartTime > dwTimeout)
- {
- printf("Wait timed out\n");
- goto stop_cleanup;
- }
- }
- printf("Service stopped successfully\n");
- stop_cleanup:
- CloseServiceHandle(schService);
- CloseServiceHandle(schSCManager);
- }
- BOOL StopDependentServices()
- {
- DWORD i;
- DWORD dwBytesNeeded;
- DWORD dwCount;
- LPENUM_SERVICE_STATUS lpDependencies = NULL;
- ENUM_SERVICE_STATUS ess;
- SC_HANDLE hDepService;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwTimeout = 30000; // 30-second time-out
- SC_HANDLE schSCManager = NULL;
- SC_HANDLE schService = NULL;
- // Pass a zero-length buffer to get the required buffer size.
- if (EnumDependentServices(schService, SERVICE_ACTIVE,
- lpDependencies, 0, &dwBytesNeeded, &dwCount))
- {
- // If the Enum call succeeds, then there are no dependent
- // services, so do nothing.
- return TRUE;
- }
- else
- {
- if (GetLastError() != ERROR_MORE_DATA)
- return FALSE; // Unexpected error
- // Allocate a buffer for the dependencies.
- lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(
- GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded);
- if (!lpDependencies)
- return FALSE;
- __try {
- // Enumerate the dependencies.
- if (!EnumDependentServices(schService, SERVICE_ACTIVE,
- lpDependencies, dwBytesNeeded, &dwBytesNeeded,
- &dwCount))
- return FALSE;
- for (i = 0; i < dwCount; i++)
- {
- ess = *(lpDependencies + i);
- // Open the service.
- hDepService = OpenService(schSCManager,
- ess.lpServiceName,
- SERVICE_STOP | SERVICE_QUERY_STATUS);
- if (!hDepService)
- return FALSE;
- __try {
- // Send a stop code.
- if (!ControlService(hDepService,
- SERVICE_CONTROL_STOP,
- (LPSERVICE_STATUS)&ssp))
- return FALSE;
- // Wait for the service to stop.
- while (ssp.dwCurrentState != SERVICE_STOPPED)
- {
- Sleep(ssp.dwWaitHint);
- if (!QueryServiceStatusEx(
- hDepService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded))
- return FALSE;
- if (ssp.dwCurrentState == SERVICE_STOPPED)
- break;
- if (GetTickCount() - dwStartTime > dwTimeout)
- return FALSE;
- }
- }
- __finally
- {
- // Always release the service handle.
- CloseServiceHandle(hDepService);
- }
- }
- }
- __finally
- {
- // Always free the enumeration buffer.
- HeapFree(GetProcessHeap(), 0, lpDependencies);
- }
- }
- return TRUE;
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void DoQuerySvc(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- {
- _tprintf_s(_T("要查询的服务名称无效\n"));
- return;
- }
- SC_HANDLE hSCM;
- SC_HANDLE hSvc;
- LPQUERY_SERVICE_CONFIG lpsc;
- LPSERVICE_DESCRIPTION lpsd;
- DWORD dwBytesNeeded, cbBfuSize, dwError;
- // 获取SCM句柄;
- hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (hSCM == NULL)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // 获取服务句柄;
- hSvc = OpenService(
- hSCM,
- lpSvcName,
- SERVICE_QUERY_CONFIG // 需要查询设置的权限;
- );
- if (hSvc == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(hSCM);
- return;
- }
- // 获取服务设置信息;
- if (!QueryServiceConfig(hSvc, NULL, 0, &dwBytesNeeded))
- {
- dwError = GetLastError();
- if (ERROR_INSUFFICIENT_BUFFER == dwError)
- {
- cbBfuSize = dwBytesNeeded;
- lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBfuSize);
- }
- else
- {
- _tprintf_s(_T("QueryServiceConfig failed (%d)\n"), dwError);
- goto cleanup;
- }
- }
- if (!QueryServiceConfig(hSvc, lpsc, cbBfuSize, &dwBytesNeeded))
- {
- _tprintf_s(_T("QuerySericeConfig failed (%d)\n"), GetLastError());
- goto cleanup;
- }
- if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded))
- {
- dwError = GetLastError();
- if (ERROR_INSUFFICIENT_BUFFER == dwError)
- {
- cbBfuSize = dwBytesNeeded;
- lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBfuSize);
- }
- else
- {
- _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
- goto cleanup;
- }
- }
- if (!QueryServiceConfig2(hSvc, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpsd, cbBfuSize, &dwBytesNeeded))
- {
- _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
- goto cleanup;
- }
- //////////////////////////////////////////////////////////////////////////
- // 查询成功,组织要返回的东西;
- _tprintf(TEXT("%s configuration: \n"), g_scVariant.scName);
- _tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType);
- _tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType);
- _tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl);
- _tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName);
- _tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName);
- if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
- _tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription);
- if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
- _tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup);
- if (lpsc->dwTagId != 0)
- _tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId);
- if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
- _tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies);
- // 释放资源;
- LocalFree(lpsc);
- LocalFree(lpsd);
- cleanup:
- CloseServiceHandle(hSvc);
- CloseServiceHandle(hSCM);
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void DoDisableSvc(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- {
- _tprintf_s(_T("要禁用的服务名称无效\n"));
- return;
- }
- SC_HANDLE schSCM;
- SC_HANDLE schSvc;
- // 打开SCM;
- schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (schSCM == NULL)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // 获取服务句柄;
- schSvc = OpenService(schSCM, lpSvcName, SERVICE_CHANGE_CONFIG);
- if (schSvc == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCM);
- return;
- }
- if (!ChangeServiceConfig(
- schSvc,
- SERVICE_NO_CHANGE, // service type: no change
- SERVICE_DISABLED, // service start type
- SERVICE_NO_CHANGE, // error control: no change
- NULL, // binary path: no change
- NULL, // load order group: no change
- NULL, // tag ID: no change
- NULL, // dependencies: no change
- NULL, // account name: no change
- NULL, // password: no change
- NULL)) // display name: no change
- {
- _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
- }
- CloseServiceHandle(schSvc);
- CloseServiceHandle(schSCM);
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void DoEnableSvc(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- {
- _tprintf_s(_T("要启用的服务名称无效\n"));
- return;
- }
- SC_HANDLE schSCM;
- SC_HANDLE schSvc;
- // Get a handle to the SCM database.
- // 获取SCM数据库句柄;
- schSCM = OpenSCManager(
- NULL, // local computer
- NULL, // ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
- if (NULL == schSCM)
- {
- printf("OpenSCManager failed (%d)\n", GetLastError());
- return;
- }
- // Get a handle to the service.
- // 获取服务句柄值;
- schSvc = OpenService(
- schSCM, // SCM database
- lpSvcName, // name of service
- SERVICE_CHANGE_CONFIG); // need change config access
- if (schSvc == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCM);
- return;
- }
- // Change the service start type.
- // 改变服务启动类型;
- if (!ChangeServiceConfig(
- schSvc, // 服务句柄;
- SERVICE_NO_CHANGE, // service type: no change
- SERVICE_DEMAND_START, // service start type
- SERVICE_NO_CHANGE, // error control: no change
- NULL, // binary path: no change
- NULL, // load order group: no change
- NULL, // tag ID: no change
- NULL, // dependencies: no change
- NULL, // account name: no change
- NULL, // password: no change
- NULL)) // display name: no change
- {
- _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
- }
- else
- {
- _tprintf_s(_T("Service enabled successfully.\n"));
- }
- CloseServiceHandle(schSvc);
- CloseServiceHandle(schSCM);
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void DoUpdateSvcDesc(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- {
- _tprintf_s(_T("要更新描述的服务名称无效\n"));
- return;
- }
- SC_HANDLE schSCM;
- SC_HANDLE schSvc;
- SERVICE_DESCRIPTION sd;
- LPTSTR szDesc = TEXT("This is a test description");
- // Get a handle to the SCM database.
- // 获取SCM数据库句柄;
- schSCM = OpenSCManager(
- NULL, // NULL表示本地计算机;
- NULL, // NULL表示:ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
- if (NULL == schSCM)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // Get a handle to the service.
- // 获取服务句柄值;
- schSvc = OpenService(
- schSCM, // SCM 数据库句柄;
- lpSvcName, // 服务名称;
- SERVICE_CHANGE_CONFIG); // need change config access
- if (schSvc == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCM);
- return;
- }
- // Change the service description.
- // 改变服务描述;
- sd.lpDescription = szDesc;
- if (!ChangeServiceConfig2(
- schSvc, // 服务句柄;
- SERVICE_CONFIG_DESCRIPTION, // 要改变的类型: description;
- &sd)) // 新描述;
- {
- _tprintf_s(_T("ChangeServiceConfig2 failed\n"));
- }
- else
- {
- _tprintf_s(_T("Service description updated successfully.\n"));
- }
- CloseServiceHandle(schSvc);
- CloseServiceHandle(schSCM);
- }
- /************************************************************************/
- /* 函数:[4/23/2016 home];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void DoDeleteSvc(IN LPCTSTR lpSvcName)
- {
- if (lpSvcName == NULL || lpSvcName[0] == _T('\0'))
- {
- _tprintf_s(_T("要删除的服务名称无效\n"));
- return;
- }
- SC_HANDLE schSCM;
- SC_HANDLE schSvc;
- SERVICE_STATUS ssStatus;
- // 打开服务管理器;
- schSCM = OpenSCManager(
- NULL, // NULL表示本地计算机;
- NULL, // NULL表示ServicesActive database
- SC_MANAGER_ALL_ACCESS); // full access rights
- if (NULL == schSCM)
- {
- _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
- return;
- }
- // 打开服务;
- schSvc = OpenService(
- schSCM, // SCM database
- lpSvcName, // name of service
- SERVICE_STOP | DELETE // need delete access
- );
- if (schSvc == NULL)
- {
- _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
- CloseServiceHandle(schSCM);
- return;
- }
- // 删除服务关,需要先停止服务;
- if (!::ControlService(schSvc, SERVICE_CONTROL_STOP, &ssStatus))
- {
- _tprintf_s(_T("删除服务前停止服务失败 (%d)\n"), GetLastError());
- }
- // 删除服务;
- if (!DeleteService(schSvc))
- {
- _tprintf_s(_T("DeleteService failed (%d)\n"), GetLastError());
- SvcReportEvent(_T("Service could not be deleted"));
- }
- else
- {
- _tprintf_s(_T("Service deleted successfully\n"));
- }
- CloseServiceHandle(schSvc);
- CloseServiceHandle(schSCM);
- }
- /************************************************************************/
- /* 函数:SetCallBack[5/5/2016 Home];
- /* 描述:设置回调函数;
- /* 参数:;
- /* [IN] lpStartWorkCallBack:工作开始回调指针;
- /* [IN] lpEndofWorkCallBack:工作结束回调指针;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void SetCallBack(IN LPVOID lpStartWorkCallBack, IN LPVOID lpEndofWorkCallBack)
- {
- if (g_scVariant.lpStartWorkCallBack == NULL)
- g_scVariant.lpStartWorkCallBack = (WorkEndofCallback)lpStartWorkCallBack;
- if (g_scVariant.lpEndofWorkCallBack == NULL)
- g_scVariant.lpEndofWorkCallBack = (WorkEndofCallback)lpEndofWorkCallBack;
- }
- /************************************************************************/
- /* 函数:StartProcess[5/6/2016 IT];
- /* 描述:在服务进程里,调用外部EXE;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL StartProcess(IN LPCTSTR lpExePath)
- {
- #if 0
- if (!lpExePath || !PathFileExists(lpExePath))
- {
- return FALSE;
- }
- HANDLE hToken;
- if (!GetTokenByName(hToken, _T("EXPLORER.EXE")))
- {
- return FALSE;
- }
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.lpDesktop = TEXT("winsta0\\default");
- BOOL bResult = CreateProcessAsUser(hToken, lpExePath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
- DWORD dwError = GetLastError();// 返回740错误,表示服务必须在Admin账号下运行才能创建成功;
- //CreateProcessWithTokenW(hToken, )
- CloseHandle(hToken);
- if (bResult)
- {
- // WriteLogAlways(_T("C:\\serverlog.txt"),_T("CreateProcessAsUser ok"));
- }
- else
- {
- //WriteLogAlways(_T("C:\\servererrlog.txt"),_T("CreateProcessAsUser failed"));
- }
- #else
- HANDLE hPtoken = NULL;
- GetExplorerToken(&hPtoken);
- //if(!GetTokenByName(hPtoken,_T("EXPLORER.EXE")))
- //{
- // return FALSE;
- //}
- PROCESS_INFORMATION pi;
- STARTUPINFOW si = { sizeof(STARTUPINFO), NULL, L"", NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_USESHOWWINDOW, 0, 0, NULL, 0, 0, 0 };
- si.wShowWindow = SW_SHOW;
- si.lpDesktop = NULL;
- ZeroMemory(&pi, sizeof(pi));
- static HMODULE advapi32_dll = LoadLibraryW(L"advapi32.dll");
- if (!advapi32_dll)
- return FALSE;
- /*static F_CreateProcessWithTokenW f_CreateProcessWithTokenW = (F_CreateProcessWithTokenW)(
- GetProcAddress(advapi32_dll,"CreateProcessWithTokenW"));
- if (f_CreateProcessWithTokenW == NULL)
- return ;
- */
- BOOL bResult = CreateProcessWithTokenW(hPtoken, LOGON_WITH_PROFILE, NULL, (LPWSTR)lpExePath, NULL, NULL, NULL, &si, &pi);
- DWORD dwError = GetLastError();
- Sleep(1000);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- #endif
- return bResult;
- }
- /************************************************************************/
- /* 函数:[5/6/2016 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL GetTokenByName(IN HANDLE &hToken, IN LPCTSTR lpName)
- {
- if (!lpName)
- {
- return FALSE;
- }
- BOOL bRet = FALSE;
- HANDLE hProcessSnap = NULL;
- PROCESSENTRY32 pe32 = { 0 };
- hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hProcessSnap == INVALID_HANDLE_VALUE)
- return FALSE;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hProcessSnap, &pe32))
- {
- do
- {
- CString exefile = pe32.szExeFile;
- CString paraname = lpName;
- if (!exefile.CompareNoCase(lpName))
- {
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
- bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
- CloseHandle(hProcessSnap);
- return bRet;
- }
- } while (Process32Next(hProcessSnap, &pe32));
- bRet = TRUE;
- }
- else
- bRet = FALSE;
- CloseHandle(hProcessSnap);
- return bRet;
- }
- /************************************************************************/
- /* 函数:[5/6/2016 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- // Jeff.Hacker. WINDOWS NT 以上的内核需要提权,才能对系统进行高级管理;
- BOOL GetDebugPriv()
- {
- // 返回的访问令牌指针;
- HANDLE hToken;
- // 接收所返回的制定特权名称的信息;
- LUID sedebugnameValue;
- // 新特权信息的指针(结构体);
- TOKEN_PRIVILEGES tkp;
- DWORD dwCurProcId = GetCurrentProcessId();
- // 要修改访问权限的进程句柄;
- HANDLE hCurProc;
- hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
- if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
- {
- //ShowSystemErrorInfo(_T("升级包OpenProcessToken失败."),GetLastError());
- return FALSE;
- }
- if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
- {
- //ShowSystemErrorInfo(_T("升级包LookupPrivilegeValue失败."),GetLastError());
- CloseHandle(hToken);
- return FALSE;
- }
- tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Luid = sedebugnameValue;
- tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
- {
- //ShowSystemErrorInfo(_T("升级包AdjustTokenPrivileges失败."),GetLastError());
- CloseHandle(hToken);
- return FALSE;
- }
- CloseHandle(hCurProc);
- CloseHandle(hToken);
- return TRUE;
- }
- DWORD GetExplorerToken(OUT HANDLE* phExplorerToken)
- {
- DWORD dwStatus = ERROR_FILE_NOT_FOUND;
- BOOL bRet = FALSE;
- HANDLE hProcess = NULL;
- HANDLE hProcessSnap = NULL;
- TCHAR szExplorerPath[MAX_PATH] = { 0 };
- TCHAR FileName[MAX_PATH] = { 0 };
- PROCESSENTRY32 pe32 = { 0 };
- __try
- {
- GetWindowsDirectory(szExplorerPath, MAX_PATH);
- _tcscat_s(szExplorerPath, MAX_PATH, _T("\\Explorer.EXE"));
- hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hProcessSnap == INVALID_HANDLE_VALUE)
- {
- dwStatus = GetLastError();
- __leave;
- }
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (!Process32First(hProcessSnap, &pe32))
- {
- dwStatus = GetLastError();
- __leave;
- }
- int ii = 0;
- do
- {
- hProcess = OpenProcess(PROCESS_ALL_ACCESS/*PROCESS_QUERY_INFORMATION*/, FALSE, pe32.th32ProcessID);
- if (NULL != hProcess)
- {
- ii++;
- //if ( GetModuleFileNameEx(hProcess , NULL , FileName , MAX_PATH) )
- //{
- if (_tcsicmp(pe32.szExeFile, _T("Explorer.EXE")) == 0)
- {
- HANDLE hToken;
- if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken))
- {
- HANDLE hNewToken = NULL;
- DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);
- *phExplorerToken = hNewToken;
- dwStatus = 0;
- CloseHandle(hToken);
- }
- break;
- }
- //}
- CloseHandle(hProcess);
- hProcess = NULL;
- }
- } while (Process32Next(hProcessSnap, &pe32));
- }
- __finally
- {
- if (NULL != hProcess)
- {
- CloseHandle(hProcess);
- }
- if (NULL != hProcessSnap)
- {
- CloseHandle(hProcessSnap);
- }
- }
- return dwStatus;
- }
- // 打进服务事件日志里;
- void LogEvent(IN LPCTSTR pFormat, ...)
- {
- TCHAR chMsg[MAX_PATH];
- HANDLE hEventLog;
- LPTSTR lpszStrings[1];
- va_list pArg;
- va_start(pArg, pFormat);
- StringCchVPrintf(chMsg, MAX_PATH, pFormat, pArg);
- va_end(pArg);
- lpszStrings[0] = chMsg;
- hEventLog = RegisterEventSource(NULL, g_scVariant.scName);
- if (hEventLog != NULL)
- {
- ReportEvent(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);
- if (hEventLog)
- DeregisterEventSource(hEventLog);
- }
- }
- };
|