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