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.
 
 
 
 
 
 

240 lines
7.7 KiB

/************************************************************************************************
Copyright (c) 2001 Microsoft Corporation
Module Name: ServiceSetup.cpp.
Abstract: Implements the CServiceSetup class. See ServiceSetup.h for details.
Notes:
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#include "stdafx.h"
#include "ServiceSetup.h"
/************************************************************************************************
Member: CServiceSetup::CServiceSetup, constructor, public.
Synopsis: Copies initialization data to member variables.
Arguments: [szServiceName] - the SCM short name for the service.
This will identify uniquely each service in the system.
[szDisplayName] - the name that's displayed for the users in the SCM.
Notes: The display name would only be necessary in the install case. May change that
later.
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
CServiceSetup::CServiceSetup(LPCTSTR szServiceName, LPCTSTR szDisplay)
{
ASSERT(!(NULL == szServiceName));
ASSERT(!(NULL == szDisplay));
_tcsncpy(m_szServiceName, szServiceName, _MAX_PATH-1);
_tcsncpy(m_szDisplayName, szDisplay,_MAX_PATH-1);
m_szServiceName[_MAX_PATH-1]=0;
m_szDisplayName[_MAX_PATH-1]=0;
}
/************************************************************************************************
Member: CServiceSetup::Install, public.
Synopsis: Install service in the SCM.
Arguments: [szDescription] - the service description as it will appear in the SCM.
[dwType, dwStart, lpDepends, lpName, lpPassword] - see CreateService API call
documentation.
Notes: If the service is already installed, Install() does nothing. It must be
removed first to be reinstalled.
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
void CServiceSetup::Install(LPCTSTR szDescription, DWORD dwType, DWORD dwStart,
LPCTSTR lpDepends, LPCTSTR lpName, LPCTSTR lpPassword)
{
SC_HANDLE hSCM = NULL;
SC_HANDLE hService = NULL;
if(IsInstalled())
{
return;
}
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if(!hSCM)
{
ErrorPrinter(_T("OpenSCManager"));
goto cleanup;
}
// get the service executable path (this executable)
TCHAR szFilePath[_MAX_PATH+1];
szFilePath[_MAX_PATH]=0;
if(0==::GetModuleFileName(NULL, szFilePath, _MAX_PATH))
{
goto cleanup;
}
hService = CreateService(hSCM, m_szServiceName, m_szDisplayName, SERVICE_ALL_ACCESS, dwType, dwStart, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, lpDepends, lpName, lpPassword);
if (!hService)
{
ErrorPrinter(_T("CreateService"));
goto cleanup;
}
else
{
_tprintf(_T("%s Created\n"), m_szServiceName);
}
// change service description
SERVICE_DESCRIPTION sd;
sd.lpDescription = const_cast<LPTSTR>(szDescription);
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, static_cast<LPVOID>(&sd));
SERVICE_FAILURE_ACTIONS sfa;
SC_ACTION saArray[3];
saArray[0].Type=SC_ACTION_RESTART;
saArray[0].Delay=60000;//One minute in milliseconds
saArray[1].Type=SC_ACTION_RESTART;
saArray[1].Delay=60000;//One minute in milliseconds
saArray[2].Type=SC_ACTION_NONE;
saArray[2].Delay=0;
sfa.dwResetPeriod=24*60*60;//One day in seconds
sfa.lpRebootMsg=NULL;
sfa.lpCommand=NULL;
sfa.cActions=3;
sfa.lpsaActions=saArray;
ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sfa);
cleanup:
if (hService)
{
CloseServiceHandle(hService);
}
if (hSCM)
{
CloseServiceHandle(hSCM);
}
return;
}
/************************************************************************************************
Member: CServiceSetup::Remove, public.
Synopsis: Unregisters the service in the SCM.
Arguments: [bForce] - if the service is running, force it to stop and then remove.
Notes:
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
void CServiceSetup::Remove(bool bForce)
{
SC_HANDLE hSCM = NULL;
SC_HANDLE hService = NULL;
BOOL bSuccess = FALSE;
hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (!hSCM)
{
ErrorPrinter(_T("OpenSCManager"));
return;
}
hService = ::OpenService(hSCM, m_szServiceName, DELETE | SERVICE_STOP);
if (!hService)
{
ErrorPrinter(_T("OpenService"));
goto cleanup;
}
// force the service to stop
if(TRUE == bForce)
{
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
_tprintf(_T("%s stopped\n"), m_szServiceName);
Sleep(2000);
}
bSuccess = ::DeleteService(hService);
if(bSuccess)
{
_tprintf(_T("%s removed\n"), m_szServiceName);
}
else
{
ErrorPrinter(_T("DeleteService"));
}
cleanup:
if (hService)
{
CloseServiceHandle(hService);
}
if(hSCM)
{
CloseServiceHandle(hSCM);
}
return;
}
/************************************************************************************************
Member: CServiceSetup::IsInstalled, public.
Synopsis: Checks for the existence of the service in the system.
Notes:
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
bool CServiceSetup::IsInstalled()
{
bool bInstalled = false;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if(NULL != hSCM)
{
// try to open the service for configuration, if it succeeds, then the service exists
SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
if(NULL != hService)
{
bInstalled = true;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bInstalled;
}
/************************************************************************************************
Member: CServiceSetup::ErrorPrinter, public.
Synopsis: Message printing for class error handling.
Arguments: [bForce] - if the service is running, force it to stop and then remove.
Notes: ISSUE: Standarlize all error printing and handling among classes.
History: 01/24/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
DWORD CServiceSetup::ErrorPrinter(LPCTSTR psz, DWORD dwErr)
{
LPVOID lpvMsgBuf=NULL;
if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, dwErr,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpvMsgBuf, 0, 0))
{
_tprintf(_T("%s failed: Unknown error %x\n"), psz, dwErr);
}
else
{
_tprintf(_T("%s failed: %s\n"), psz, (LPTSTR)lpvMsgBuf);
}
LocalFree(lpvMsgBuf);
return dwErr;
}
// End of file ServiceSetup.cpp.