/**********************************************************************/ /** Microsoft Windows NT **/ /** Copyright(c) Microsoft Corp., 1991 **/ /**********************************************************************/ /* SrvCntrl.cxx OLDNAME: NCPASVCS.CXX: Service Controller interface. FILE HISTORY: DavidHov 11/16/92 Created */ #include "pch.hxx" // Precompiled header #pragma hdrstop #define SVC_CTRL_ACCESS (GENERIC_ALL) #define SVC_CTRL_START_ACCESS (GENERIC_READ | GENERIC_EXECUTE) /******************************************************************* NAME: NcpaStartService SYNOPSIS: Generic "start a service which may already be running" function ENTRY: const TCHAR * name of service BOOL TRUE if service is allowed to already be running (default TRUE) const TCHAR * * optional parameter list for svc INT number of arguments in param list EXIT: Nothing RETURNS: APIERR if failure NOTES: HISTORY: ********************************************************************/ APIERR NcpaStartService ( const TCHAR * pszSvcName, SC_MANAGER * pScMgr, BOOL fStartOk, INT cArgs, const TCHAR * * pszParams ) { APIERR err = 0 ; SC_MANAGER * pScManager = pScMgr ; SC_SERVICE * pScService = NULL ; SERVICE_STATUS svcStatus ; DWORD dwSleepTotal = 0 ; // Period to sleep while waiting for service to become "running" const DWORD dwSvcSleepInterval = 500 ; // Maximum time to wait for service to attain "running" state const DWORD dwSvcMaxSleep = 180000 ; do // Pseudo-loop for error breakuot { // If necessaryt, construct an SC_MANAGER to handle the request if ( pScManager == NULL ) { pScManager = new SC_MANAGER( NULL, SVC_CTRL_ACCESS ) ; if ( pScManager == NULL ) { err = ERROR_NOT_ENOUGH_MEMORY ; break ; } if ( err = pScManager->QueryError() ) break ; } pScService = new SC_SERVICE( *pScManager, pszSvcName ) ; if ( pScService == NULL ) { err = ERROR_NOT_ENOUGH_MEMORY ; break ; } if ( err = pScService->QueryError() ) { break ; } if ( (err = pScService->QueryStatus( & svcStatus )) ) break ; if ( svcStatus.dwCurrentState == SERVICE_RUNNING ) { // See if it's OK that the service is already // running... if ( ! fStartOk ) err = ERROR_SERVICE_ALREADY_RUNNING ; break ; } // Start the requested service, passing the given // parameters. if ( err = pScService->Start( cArgs, pszParams ) ) { break ; } // Wait for the service to attain "running" status; but // wait no more than 3 minute. for ( dwSleepTotal = 0 ; dwSleepTotal < dwSvcMaxSleep && (err = pScService->QueryStatus( & svcStatus )) == 0 && svcStatus.dwCurrentState == SERVICE_START_PENDING ; dwSleepTotal += dwSvcSleepInterval ) { ::Sleep( dwSvcSleepInterval ) ; } if ( err ) break ; // Is the service running or did we time out? if ( svcStatus.dwCurrentState != SERVICE_RUNNING ) { err = dwSleepTotal > dwSvcMaxSleep ? ERROR_SERVICE_REQUEST_TIMEOUT : svcStatus.dwWin32ExitCode ; break ; } } while ( FALSE ) ; delete pScService ; if ( pScManager != pScMgr ) { delete pScManager ; } return err ; } /******************************************************************* NAME: NcpaStartGroup SYNOPSIS: Starts all members of Service Order Group ENTRY: const TCHAR * name of group SC_MANAGER * pointer to SC_MANAGER if you have one BOOL TRUE if errors should be ignored EXIT: Nothing RETURNS: APIERR if failure NOTES: HISTORY: ********************************************************************/ APIERR NcpaStartGroup ( const TCHAR * pszGroupName, SC_MANAGER * pScMgr, BOOL fIgnoreErrors ) { SC_MANAGER * pScManager = pScMgr ; APIERR err = 0; do // Pseudo-loop for error breakuot { // If necessary, construct an SC_MANAGER to handle the request if ( pScManager == NULL ) { pScManager = new SC_MANAGER( NULL, SVC_CTRL_ACCESS ) ; if ( pScManager == NULL ) { err = ERROR_NOT_ENOUGH_MEMORY ; break ; } if ( err = pScManager->QueryError() ) break ; } SERVICE_ENUM enumServices( NULL, TRUE, SERVICE_WIN32|SERVICE_DRIVER, pszGroupName ); if ( err = enumServices.GetInfo() != NERR_Success ) { break; } SERVICE_ENUM_ITER iterServices( enumServices ); const SERVICE_ENUM_OBJ * psvc; while( ( psvc = iterServices() ) != NULL ) { APIERR errService = NcpaStartService ( psvc->QueryServiceName(), pScManager, TRUE, 0, NULL ); if ( !fIgnoreErrors && errService ) { err = errService; break; } } } while (FALSE); if ( pScManager != pScMgr ) { delete pScManager ; } return err; } // End of NCPASVCS.CXX