HRESULT Service_Monitor::StartServiceByName()

in src/ServiceMonitor/ServiceMonitor.cpp [44:126]


HRESULT Service_Monitor::StartServiceByName(LPCTSTR pServiceName, DWORD dwTimeOutSeconds)
{
    HRESULT hr = S_OK;
    SC_HANDLE hService = NULL;
    DWORD dwSleepTime = 0;
    DWORD dwRemainTime = dwTimeOutSeconds;

    hr = GetServiceHandle(pServiceName, &hService);

    if (SUCCEEDED(hr))
    {
        if (StartService(hService, 0, NULL) == FALSE)
        {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_SERVICE_ALREADY_RUNNING)
            {
                dwError = ERROR_SUCCESS;
            }
            else
            {
                hr = HRESULT_FROM_WIN32(dwError);
            }
        }
        //
        // Query service status to make sure service is in running state
        //
        while(dwRemainTime >0)
        {
            DWORD     dwBytes = 0;
            SERVICE_STATUS_PROCESS sStatus;

            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_RUNNING)
            {
                goto Finished;
            }
            else if(sStatus.dwCurrentState == SERVICE_START_PENDING)
            {
                dwSleepTime = rand() % 10 + 1;
                dwSleepTime = dwSleepTime < dwRemainTime ? dwSleepTime : dwRemainTime;
                dwRemainTime -= dwSleepTime;
                Sleep(dwSleepTime * 1000);
            }
            else
            {
                //
                // Service fails to start 
                //
                hr = E_FAIL;
                goto Finished;
            }
        }
        //
        // Cannot start service within given time period
        //
        hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
    }

    Finished:
    if(SUCCEEDED(hr))
    {
        _tprintf(L"\n Service '%s' started \n", pServiceName);
    }
    else
    {
        _tprintf(L"\nERROR: Failed to start or query status of service '%s' error [%x]\n", pServiceName, hr);
    }

    if (hService != NULL)
    {
        CloseServiceHandle(hService);
    }
    return hr;
}