|
|
#include "stdafx.h"
#include "common.h"
#include "svc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
//----------------------------------------------------------------------------------------
//Routine Description:
// This routine allocates a buffer for the specified service's configuration parameters,
// and retrieves those parameters into the buffer. The caller is responsible for freeing
// the buffer.
//Remarks:
// The pointer whose address is contained in ServiceConfig is guaranteed to be NULL upon
// return if any error occurred.
//-----------------------------------------------------------------------------------------
DWORD RetrieveServiceConfig(IN SC_HANDLE ServiceHandle,OUT LPQUERY_SERVICE_CONFIG *ServiceConfig) { DWORD ServiceConfigSize = 0, Err; if (NULL == ServiceConfig) { return ERROR_INVALID_PARAMETER; } *ServiceConfig = NULL; while(TRUE) { if(QueryServiceConfig(ServiceHandle, *ServiceConfig, ServiceConfigSize, &ServiceConfigSize)) { //assert(*ServiceConfig);
return NO_ERROR; } else { Err = GetLastError(); if(*ServiceConfig) {free(*ServiceConfig);*ServiceConfig=NULL;} if(Err == ERROR_INSUFFICIENT_BUFFER) { // Allocate a larger buffer, and try again.
if(!(*ServiceConfig = (LPQUERY_SERVICE_CONFIG) malloc(ServiceConfigSize))) { return ERROR_NOT_ENOUGH_MEMORY; } } else { if (ServiceConfig) { *ServiceConfig = NULL; } return Err; } } } }
// returns SVC_NOTEXIST if the service does not exist
// returns SVC_DISABLED if the service is disabled
// returns SVC_AUTO_START if the the service is auto start
// returns SVC_MANUAL_START if the the service is not auto start
int GetServiceStartupMode(LPCTSTR lpMachineName, LPCTSTR lpServiceName) { int iReturn = SVC_NOTEXIST; SC_HANDLE hScManager = NULL; SC_HANDLE hService = NULL; LPQUERY_SERVICE_CONFIG ServiceConfig=NULL;
// check if lpMachineName starts with \\ // if it doesn't then make sure it does, or it's null (for local machine)
LPTSTR lpNewMachineName = NULL; if (_tcsicmp(lpMachineName, _T("")) != 0) { DWORD dwSize = 0; // Check if it starts with "\\"
if (_tcsncmp(lpMachineName, _T("\\\\"), 2) == 0) { dwSize = (_tcslen(lpMachineName) * sizeof(TCHAR)) + (1 * sizeof(TCHAR)); lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize); if(lpNewMachineName != NULL) { _tcscpy(lpNewMachineName, lpMachineName); } } else { dwSize = ((_tcslen(lpMachineName) * sizeof(TCHAR)) + (3 * sizeof(TCHAR))); lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize); if(lpNewMachineName != NULL) { _tcscpy(lpNewMachineName, _T("\\\\")); _tcscat(lpNewMachineName, lpMachineName); } } }
if ((hScManager = OpenSCManager(lpNewMachineName, NULL, GENERIC_ALL )) == NULL || (hService = OpenService( hScManager, lpServiceName, GENERIC_ALL )) == NULL ) { // Failed, or more likely the service doesn't exist
iReturn = SVC_NOTEXIST; goto IsThisServiceAutoStart_Exit; }
if(RetrieveServiceConfig(hService, &ServiceConfig) != NO_ERROR) { iReturn = SVC_NOTEXIST; goto IsThisServiceAutoStart_Exit; }
if(!ServiceConfig) { iReturn = SVC_NOTEXIST; goto IsThisServiceAutoStart_Exit; }
// SERVICE_AUTO_START Specifies a device driver or service started by the service control manager automatically during system startup.
// SERVICE_BOOT_START Specifies a device driver started by the system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
// SERVICE_DEMAND_START Specifies a device driver or service started by the service control manager when a process calls the StartService function.
// SERVICE_DISABLED Specifies a device driver or service that can no longer be started.
// SERVICE_SYSTEM_START Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
if (SERVICE_DISABLED == ServiceConfig->dwStartType) { iReturn = SVC_DISABLED; } else if (SERVICE_DEMAND_START == ServiceConfig->dwStartType) { iReturn = SVC_MANUAL_START; } else { iReturn = SVC_AUTO_START; }
IsThisServiceAutoStart_Exit: if (ServiceConfig) {free(ServiceConfig);} if (hService) {CloseServiceHandle(hService);} if (hScManager) {CloseServiceHandle(hScManager);} if (lpNewMachineName) {LocalFree(lpNewMachineName);} return iReturn; }
// SERVICE_DISABLED
// SERVICE_AUTO_START
// SERVICE_DEMAND_START
INT ConfigServiceStartupType(LPCTSTR lpMachineName, LPCTSTR lpServiceName, int iNewType) { INT err = 0; SC_HANDLE hScManager = NULL; SC_HANDLE hService = NULL; LPQUERY_SERVICE_CONFIG ServiceConfig = NULL; DWORD dwNewServiceStartupType = 0; BOOL bDoStuff = FALSE;
// check if lpMachineName starts with \\ // if it doesn't then make sure it does, or it's null (for local machine)
LPTSTR lpNewMachineName = NULL; if (_tcsicmp(lpMachineName, _T("")) != 0) { DWORD dwSize = 0; // Check if it starts with "\\"
if (_tcsncmp(lpMachineName, _T("\\\\"), 2) == 0) { dwSize = (_tcslen(lpMachineName) * sizeof(TCHAR)) + (1 * sizeof(TCHAR)); lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize); if(lpNewMachineName != NULL) { _tcscpy(lpNewMachineName, lpMachineName); } } else { dwSize = ((_tcslen(lpMachineName) * sizeof(TCHAR)) + (3 * sizeof(TCHAR))); lpNewMachineName = (LPTSTR) LocalAlloc(LPTR, dwSize); if(lpNewMachineName != NULL) { _tcscpy(lpNewMachineName, _T("\\\\")); _tcscat(lpNewMachineName, lpMachineName); } } }
do { if ((hScManager = ::OpenSCManager( lpMachineName, NULL, GENERIC_ALL )) == NULL || (hService = ::OpenService( hScManager, lpServiceName, GENERIC_ALL )) == NULL ) { err = GetLastError(); if (ERROR_SERVICE_DOES_NOT_EXIST != err) { } break; }
if(RetrieveServiceConfig(hService, &ServiceConfig) != NO_ERROR) { err = GetLastError(); break; }
if(!ServiceConfig) { err = GetLastError(); break; }
// only set this on non-kernel drivers
if ( (ServiceConfig->dwServiceType & SERVICE_WIN32_OWN_PROCESS) || (ServiceConfig->dwServiceType & SERVICE_WIN32_SHARE_PROCESS)) { // default it incase someone changes code below and logic gets messed up
dwNewServiceStartupType = ServiceConfig->dwStartType;
// if this service is disabled,
// they don't do anything, just leave it alone.
if (!(dwNewServiceStartupType == SERVICE_DISABLED)) { if (iNewType == SERVICE_DISABLED) { dwNewServiceStartupType = SERVICE_DISABLED; bDoStuff = TRUE; } else if (iNewType == SERVICE_AUTO_START) { // if the service is already the type we want then don't do jack
// SERVICE_AUTO_START
// SERVICE_BOOT_START
// SERVICE_DEMAND_START
// SERVICE_DISABLED
// SERVICE_SYSTEM_START
if (SERVICE_AUTO_START == dwNewServiceStartupType || SERVICE_BOOT_START == dwNewServiceStartupType || SERVICE_SYSTEM_START == dwNewServiceStartupType ) { // it's already auto start
// we don't have to do anything
} else { dwNewServiceStartupType = SERVICE_AUTO_START; bDoStuff = TRUE; } } else { // we want to make it manual start
// check if it's already that way
if (!(SERVICE_DEMAND_START == dwNewServiceStartupType)) { dwNewServiceStartupType = SERVICE_DEMAND_START; bDoStuff = TRUE; } } } else { if (iNewType == SERVICE_AUTO_START) { dwNewServiceStartupType = SERVICE_AUTO_START; bDoStuff = TRUE; } else { dwNewServiceStartupType = SERVICE_DEMAND_START; bDoStuff = TRUE; } }
if (TRUE == bDoStuff) { if ( !::ChangeServiceConfig(hService, SERVICE_NO_CHANGE, dwNewServiceStartupType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ) { err = GetLastError(); break; } } else { break; }
} else { break; }
} while ( FALSE );
if (ServiceConfig) {free(ServiceConfig);} if (hService) {CloseServiceHandle(hService);} if (hScManager) {CloseServiceHandle(hScManager);} if (lpNewMachineName) {LocalFree(lpNewMachineName);} return(err); }
|