#include "pch.h" #pragma hdrstop #include #include #include #include #define PROCESS_SIZE 16 INT InetStartService( LPCTSTR lpServiceName ); TCHAR gServicesWhichMustBeRestarted[20][PROCESS_SIZE]; int gServicesWhichMustBeRestarted_nextuse; int gServicesWhichMustBeRestarted_total; int ServicesRestartList_EntryExists(LPCTSTR szServiceName) { int iFoundMatch = FALSE; // loop thru the whole list for(int i=0; i < gServicesWhichMustBeRestarted_total;i++) { if (_tcsicmp(gServicesWhichMustBeRestarted[i], szServiceName) == 0) { iFoundMatch = TRUE; break; } } return iFoundMatch; } int ServicesRestartList_Add(LPCTSTR szServiceName) { DbgPrint(("ServicesRestartList_Add() on Service %S"), szServiceName); // check if this value already exists in the globalarary if (ServicesRestartList_EntryExists(szServiceName)) {return FALSE;} // move info into global array if (gServicesWhichMustBeRestarted_nextuse <= 20) { _tcscpy(gServicesWhichMustBeRestarted[gServicesWhichMustBeRestarted_nextuse],szServiceName); // increment counter to array // increment next use space ++gServicesWhichMustBeRestarted_total; ++gServicesWhichMustBeRestarted_nextuse; } return TRUE; } int ServicesRestartList_RestartServices(void) { int iReturn = FALSE; INT err = 0; // loop thru the whole list and restart the services in reverse // order from how they were entered? if (gServicesWhichMustBeRestarted_total >= 1) { DbgPrint(("RestartServices() Start.")); for(int i=0; i < gServicesWhichMustBeRestarted_total;i++) { err = InetStartService(gServicesWhichMustBeRestarted[i]); DbgPrint(("Start service %S. err=%x"), gServicesWhichMustBeRestarted[i], err); } DbgPrint(("RestartServices() End.")); } return iReturn; } INT InetStartService( LPCTSTR lpServiceName ) { INT err = 0; const DWORD dwSvcSleepInterval = 500 ; const DWORD dwSvcMaxSleep = 180000 ; SC_HANDLE hScManager = NULL; SC_HANDLE hService = NULL; DbgPrint(("Starting %S service..."), lpServiceName); do { // set up the service first if ((hScManager = OpenSCManager( NULL, NULL, GENERIC_ALL )) == NULL || (hService = ::OpenService( hScManager, lpServiceName, GENERIC_ALL )) == NULL ) { err = GetLastError(); break; } SERVICE_STATUS svcStatus; if ( !QueryServiceStatus( hService, &svcStatus )) { err = ::GetLastError(); break; } if ( svcStatus.dwCurrentState == SERVICE_RUNNING ) break; // service already started and running if ( !::StartService( hService, 0, NULL )) { err = ::GetLastError(); break; } // Wait for the service to attain "running" status; but // wait no more than 3 minute. DWORD dwSleepTotal; for ( dwSleepTotal = 0 ; dwSleepTotal < dwSvcMaxSleep && (QueryServiceStatus( hService, &svcStatus )) //&& svcStatus.dwCurrentState == SERVICE_START_PENDING ; && svcStatus.dwCurrentState != SERVICE_RUNNING ; dwSleepTotal += dwSvcSleepInterval ) { ::Sleep( dwSvcSleepInterval ) ; } if ( svcStatus.dwCurrentState != SERVICE_RUNNING ) { err = dwSleepTotal > dwSvcMaxSleep ? ERROR_SERVICE_REQUEST_TIMEOUT : svcStatus.dwWin32ExitCode; break; } } while ( FALSE ); if (hService) CloseServiceHandle(hService); if (hScManager) CloseServiceHandle(hScManager); DbgPrint(("Service started with 0x%x"), err); return(err); } // //Routine Description: // Stop the named service and all those services which depend upon it. // And if the service is hung and can't be stopped, then kill the darn thing. // //Arguments: // ServiceName (Name of service to stop) // //Return Status: // TRUE - Indicates service successfully stopped // FALSE - Timeout occurred. // int StopServiceAndDependencies(LPCTSTR ServiceName, int AddToRestartList) { DbgPrint(("StopServiceAndDependencies():%S Service"), ServiceName); int Err = 0; int iBeforeServiceStatus = 0; SC_HANDLE ScManagerHandle = NULL; SC_HANDLE ServiceHandle = NULL; SERVICE_STATUS ServiceStatus; DWORD Timeout; DWORD TimeoutMaxSecs = 60 * 10; //10mins -- iisadmin may take a long time int iReturn = FALSE; // // Open a handle to the Service. // ScManagerHandle = OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT ); if (ScManagerHandle == NULL) { Err = GetLastError(); DbgPrint(("StopServiceAndDependencies():OpenSCManager: Err on Service %S Err=0x%x FAILED"), ServiceName, Err); goto Cleanup; } ServiceHandle = OpenService(ScManagerHandle,ServiceName,SERVICE_QUERY_STATUS | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_STOP | SERVICE_QUERY_CONFIG ); if ( ServiceHandle == NULL ) { Err = GetLastError(); if (Err == ERROR_SERVICE_DOES_NOT_EXIST) { iReturn = TRUE; DbgPrint(("StopServiceAndDependencies():%S Service does not exist."), ServiceName); } else { DbgPrint(("StopServiceAndDependencies():OpenService: Err on Service %S Err=0x%x FAILED"), ServiceName, Err); } goto Cleanup; } // Get the before service status. if (QueryServiceStatus(ServiceHandle, &ServiceStatus)) { iBeforeServiceStatus = ServiceStatus.dwCurrentState; } // // Ask the service to stop. // if ( !ControlService( ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus) ) { Err = GetLastError(); // If there are dependent services running, // determine their names and stop them. if ( Err == ERROR_DEPENDENT_SERVICES_RUNNING ) { BYTE ConfigBuffer[4096]; LPENUM_SERVICE_STATUS ServiceConfig = (LPENUM_SERVICE_STATUS) &ConfigBuffer; DWORD BytesNeeded; DWORD ServiceCount; DWORD ServiceIndex; // // Get the names of the dependent services. // if ( !EnumDependentServices( ServiceHandle,SERVICE_ACTIVE,ServiceConfig,sizeof(ConfigBuffer),&BytesNeeded,&ServiceCount ) ) { Err = GetLastError(); DbgPrint(("StopServiceAndDependencies():EnumDependentServices: Err on Service %S Err=0x%x FAILED"), ServiceName, Err); goto Cleanup; } // // Stop those services. // for ( ServiceIndex=0; ServiceIndex