Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

294 lines
10 KiB

#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);
}