HRESULT Service_Monitor::StopServiceByName()

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;
    }