SVERROR QuerySvcConfig()

in host/common/win32/service.cpp [681:825]


SVERROR QuerySvcConfig(InmService& svc)
{
    SC_HANDLE schSCManager = NULL ;
    SC_HANDLE schService  = NULL ;
    LPQUERY_SERVICE_CONFIG lpsc = NULL ; 
    LPSERVICE_DESCRIPTION lpsd = NULL ;
    DWORD dwBytesNeeded = 0 ;
    DWORD cbBufSize = 0 ;
    DWORD dwError = 0 ; 
    SVERROR bRet = SVS_FALSE ;
    svc.m_svcStartType = INM_SVCTYPE_NONE ;
    svc.m_svcStatus = INM_SVCSTAT_NONE ;

    schSCManager = OpenSCManager( 
        NULL,                    // local computer
        NULL,                    // ServicesActive database 
        SC_MANAGER_ALL_ACCESS);  // full access rights 
 
    if (NULL != schSCManager) 
    {
        DebugPrintf(SV_LOG_DEBUG, "Opened scmanager\n");
        schService = OpenService( 
            schSCManager,          // SCM database 
            svc.m_serviceName.c_str(),       // name of service 
            SERVICE_QUERY_CONFIG); // need query config access 
     
        if (schService != NULL)
        {
            DebugPrintf(SV_LOG_DEBUG, "Opened handle to service %s\n", svc.m_serviceName.c_str());
            if( !QueryServiceConfig( 
                schService, 
                NULL, 
                0, 
                &dwBytesNeeded))
            {
                dwError = GetLastError();
                if( ERROR_INSUFFICIENT_BUFFER == dwError )
                {
                    cbBufSize = dwBytesNeeded;
                    lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
                }
          
                if( QueryServiceConfig( 
                    schService, 
                    lpsc, 
                    cbBufSize, 
                    &dwBytesNeeded) ) 
                {

                    if( !QueryServiceConfig2( 
                        schService, 
                        SERVICE_CONFIG_DESCRIPTION,
                        NULL, 
                        0, 
                        &dwBytesNeeded))
                    {
                        dwError = GetLastError();
                        if( ERROR_INSUFFICIENT_BUFFER == dwError )
                        {
                            cbBufSize = dwBytesNeeded;
                            lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
                        }
                     
                        if (QueryServiceConfig2( 
                            schService, 
                            SERVICE_CONFIG_DESCRIPTION,
                            (LPBYTE) lpsd, 
                            cbBufSize, 
                            &dwBytesNeeded) ) 
                        {
                            switch( lpsc->dwStartType )
                            {
                                case SERVICE_AUTO_START :
                                    svc.m_svcStartType = INM_SVCTYPE_AUTO ;
                                    break ;
                                case SERVICE_BOOT_START :
                                    svc.m_svcStartType  = INM_SVCTYPE_AUTO ;
                                    break ;
                                case SERVICE_DEMAND_START :
                                    svc.m_svcStartType = INM_SVCTYPE_MANUAL ;
                                    break ;
                                case SERVICE_DISABLED :
                                    svc.m_svcStartType = INM_SVCTYPE_DISABLED ;
                                    break ;
                                case SERVICE_SYSTEM_START :
                                    svc.m_svcStartType = INM_SVCTYPE_AUTO ;
                                    break ;
                                default :
                                    svc.m_svcStartType = INM_SVCTYPE_NONE ;
                                    break ;
                            }

                            svc.m_binPathName = lpsc->lpBinaryPathName ;
                            svc.m_logonUser = lpsc->lpServiceStartName ;
                            svc.m_displayName = lpsc->lpDisplayName ;
                            if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
                            {
                                svc.m_discription = lpsd->lpDescription ; 
                            }
                            if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
                            {
                                svc.m_dependencies = lpsc->lpDependencies ;
                            }
                            getServiceStatus(svc.m_serviceName, svc.m_svcStatus) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcName        : %s\n", svc.m_serviceName.c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "svcStartUpType : %s\n", svc.typeAsStr().c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcStatus      : %s\n", svc.statusAsStr().c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcDescription : %s\n", svc.m_discription.c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcLogonUser   : %s\n", svc.m_logonUser.c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcBinPath     : %s\n", svc.m_binPathName.c_str()) ;
                            DebugPrintf(SV_LOG_DEBUG, "SvcDepedencies : %s\n", svc.m_dependencies.c_str()) ;
                            bRet = SVS_OK ;
                        }
                    }
                }
            }
            CloseServiceHandle(schService);
        }
        else
        {
            DWORD err = GetLastError();
			std::stringstream sserr;
			sserr << err;
            DebugPrintf(SV_LOG_DEBUG, "Failed to open handle to service %s with error %s\n", svc.m_serviceName.c_str(), sserr.str().c_str());
            svc.m_svcStatus = INM_SVCSTAT_NOTINSTALLED ;
        }
        CloseServiceHandle(schSCManager);
    }
    else
    {
        DWORD err = GetLastError();
		std::stringstream sserr;
		sserr << err;
        DebugPrintf(SV_LOG_ERROR, "Failed to open scmanager with error %s\n", sserr.str().c_str());
    }
    if( lpsc != NULL )
    {
        LocalFree(lpsc); 
    }
    if( lpsd != NULL )
    {
        LocalFree(lpsd);
    }
    return bRet ;
}