DWORD StopService( SC_HANDLE hSCM, SC_HANDLE hService,BOOL fStopDependencies, DWORD dwTimeout ) { SERVICE_STATUS ss; DWORD dwStartTime = GetTickCount(); // Make sure the service is not already stopped if ( !QueryServiceStatus( hService, &ss ) ) return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED ) return ERROR_SUCCESS; // If a stop is pending, just wait for it while ( ss.dwCurrentState == SERVICE_STOP_PENDING ) { Sleep( ss.dwWaitHint ); if ( !QueryServiceStatus( hService, &ss ) ) return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED ) return ERROR_SUCCESS; if ( GetTickCount() - dwStartTime > dwTimeout ) return ERROR_TIMEOUT; } // If the service is running, dependencies must be stopped first if ( fStopDependencies ) { DWORD i; DWORD dwBytesNeeded; DWORD dwCount; LPENUM_SERVICE_STATUS lpDependencies = NULL; ENUM_SERVICE_STATUS ess; SC_HANDLE hDepService; // Pass a zero-length buffer to get the required buffer size if ( EnumDependentServices( hService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount ) ) { // If the Enum call succeeds, then there are no dependent // services so do nothing } else {
if ( GetLastError() != ERROR_MORE_DATA ) return GetLastError(); // Unexpected error // Allocate a buffer for the dependencies lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded ); if ( !lpDependencies ) return GetLastError(); __try { // Enumerate the dependencies if ( !EnumDependentServices( hService, SERVICE_ACTIVE, lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount ) ) return GetLastError(); for ( i = 0; i < dwCount; i++ ) { ess = *(lpDependencies + i); // Open the service hDepService = OpenService( hSCM, ess.lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS ); if ( !hDepService ) return GetLastError(); __try { // Send a stop code if ( !ControlService( hDepService, SERVICE_CONTROL_STOP, &ss ) ) return GetLastError(); // Wait for the service to stop while ( ss.dwCurrentState != SERVICE_STOPPED ) { Sleep( ss.dwWaitHint ); if ( !QueryServiceStatus( hDepService, &ss ) ) return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED ) break; if ( GetTickCount() - dwStartTime > dwTimeout ) return ERROR_TIMEOUT; } } __finally { // Always release the service handle CloseServiceHandle( hDepService ); } } } __finally { // Always free the enumeration buffer HeapFree( GetProcessHeap(), 0, lpDependencies ); } } } // Send a stop code to the main service if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) ) return GetLastError(); // Wait for the service to stop while ( ss.dwCurrentState != SERVICE_STOPPED ) { Sleep( ss.dwWaitHint ); if ( !QueryServiceStatus( hService, &ss ) ) return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED ) break; if ( GetTickCount() - dwStartTime > dwTimeout ) return ERROR_TIMEOUT; } // Return success return ERROR_SUCCESS; }
ControlService
相关API
CreateService, OpenService
{ SERVICE_STATUS ss;
DWORD dwStartTime = GetTickCount(); // Make sure the service is not already stopped
if ( !QueryServiceStatus( hService, &ss ) )
return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED )
return ERROR_SUCCESS; // If a stop is pending, just wait for it
while ( ss.dwCurrentState == SERVICE_STOP_PENDING ) { Sleep( ss.dwWaitHint );
if ( !QueryServiceStatus( hService, &ss ) )
return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED )
return ERROR_SUCCESS; if ( GetTickCount() - dwStartTime > dwTimeout )
return ERROR_TIMEOUT;
} // If the service is running, dependencies must be stopped first
if ( fStopDependencies ) { DWORD i;
DWORD dwBytesNeeded;
DWORD dwCount; LPENUM_SERVICE_STATUS lpDependencies = NULL;
ENUM_SERVICE_STATUS ess;
SC_HANDLE hDepService; // Pass a zero-length buffer to get the required buffer size
if ( EnumDependentServices( hService, SERVICE_ACTIVE,
lpDependencies, 0, &dwBytesNeeded, &dwCount ) ) { // If the Enum call succeeds, then there are no dependent
// services so do nothing } else {
if ( GetLastError() != ERROR_MORE_DATA )
return GetLastError(); // Unexpected error // Allocate a buffer for the dependencies
lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded ); if ( !lpDependencies )
return GetLastError(); __try { // Enumerate the dependencies
if ( !EnumDependentServices( hService, SERVICE_ACTIVE,
lpDependencies, dwBytesNeeded, &dwBytesNeeded,
&dwCount ) )
return GetLastError(); for ( i = 0; i < dwCount; i++ ) { ess = *(lpDependencies + i); // Open the service
hDepService = OpenService( hSCM, ess.lpServiceName,
SERVICE_STOP | SERVICE_QUERY_STATUS );
if ( !hDepService )
return GetLastError(); __try { // Send a stop code
if ( !ControlService( hDepService, SERVICE_CONTROL_STOP,
&ss ) )
return GetLastError(); // Wait for the service to stop
while ( ss.dwCurrentState != SERVICE_STOPPED ) { Sleep( ss.dwWaitHint );
if ( !QueryServiceStatus( hDepService, &ss ) )
return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED )
break; if ( GetTickCount() - dwStartTime > dwTimeout )
return ERROR_TIMEOUT;
} } __finally { // Always release the service handle
CloseServiceHandle( hDepService ); } } } __finally { // Always free the enumeration buffer
HeapFree( GetProcessHeap(), 0, lpDependencies ); }
}
} // Send a stop code to the main service
if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) )
return GetLastError(); // Wait for the service to stop
while ( ss.dwCurrentState != SERVICE_STOPPED ) { Sleep( ss.dwWaitHint );
if ( !QueryServiceStatus( hService, &ss ) )
return GetLastError(); if ( ss.dwCurrentState == SERVICE_STOPPED )
break; if ( GetTickCount() - dwStartTime > dwTimeout )
return ERROR_TIMEOUT;
} // Return success
return ERROR_SUCCESS;
}