in src/ServiceMonitor/ServiceMonitor.cpp [128:203]
HRESULT Service_Monitor::StopServiceByName(LPCTSTR pServiceName, DWORD dwTimeOutSeconds)
{
HRESULT hr = S_OK;
SC_HANDLE hService = NULL;
DWORD dwBytes = 0;
DWORD dwSleepTime = 0;
DWORD dwRemainTime = dwTimeOutSeconds;
SERVICE_STATUS_PROCESS sStatus;
hr = GetServiceHandle(pServiceName, &hService);
if (SUCCEEDED(hr))
{
while (dwRemainTime >0)
{
DWORD dwBytes = 0;
if (!QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&sStatus,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytes))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
if (sStatus.dwCurrentState == SERVICE_STOPPED)
{
goto Finished;
}
else if (sStatus.dwCurrentState == SERVICE_STOP_PENDING || sStatus.dwCurrentState == SERVICE_START_PENDING || sStatus.dwCurrentState == SERVICE_PAUSE_PENDING || sStatus.dwCurrentState == SERVICE_CONTINUE_PENDING)
{
dwSleepTime = rand() % 10 + 1;
dwSleepTime = dwSleepTime < dwRemainTime ? dwSleepTime : dwRemainTime;
dwRemainTime -= dwSleepTime;
Sleep(dwSleepTime * 1000);
}
else if (sStatus.dwCurrentState == SERVICE_RUNNING || sStatus.dwCurrentState == SERVICE_PAUSED)
{
if (!ControlService(hService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&sStatus))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Finished;
}
_tprintf(L"\nStopping service '%s'\n", pServiceName);
}
else
{
//
// Service fails to stop
//
hr = E_FAIL;
goto Finished;
}
}
//
// cannot stop service within given time period
//
hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
}
Finished:
if (SUCCEEDED(hr))
{
_tprintf(L"\n Service '%s' has been stopped \n", pServiceName);
}
else
{
_tprintf(L"\nERROR: Failed to stop or query status of service '%s' error [%x]\n", pServiceName, hr);
}
if (hService != NULL)
{
CloseServiceHandle(hService);
}
return hr;
}