windows-nt/Source/XPSP1/NT/net/mmc/mprsnap/cservice.h
2020-09-26 16:20:57 +08:00

395 lines
11 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997 - 1998
//
// File: C S E R V I C E . H
//
// Contents: This file contains CService and CServiceManager, wrapper
// classes to the Win32 Service APIs.
//
// Notes: Note that not all functionallity is currently extended through
// these classes.
// Note that most functionality is inline in this file. What is
// not inline is in cservice.cpp
//
// Author: mikemi 6 Mar 1997
//
//----------------------------------------------------------------------------
#ifndef _CSERVICE_H_
#define _CSERVICE_H_
//#include "debugx.h"
//#include "ncbase.h"
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
size_t CchMsz(const TCHAR * msz);
class CService
{
friend class CServiceManager;
public:
CService()
{
_schandle = NULL;
};
~CService()
{
Close();
};
VOID Close()
{
BOOL frt;
if (_schandle)
{
frt = ::CloseServiceHandle( _schandle );
AssertSz(frt, "CloseServiceHandle failed!");
_schandle = NULL;
}
}
HRESULT HrDelete()
{
Assert(_schandle != NULL );
if (::DeleteService( _schandle ))
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT HrStart( DWORD cNumServiceArgs = 0,
LPCTSTR* papServiceArgs = NULL)
{
Assert(_schandle != NULL );
if (::StartService( _schandle, cNumServiceArgs, papServiceArgs ))
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT HrControl( DWORD dwControl )
{
SERVICE_STATUS sStatus;
Assert(_schandle != NULL );
AssertSz((dwControl != SERVICE_CONTROL_INTERROGATE),
"CService::HrControl does not support the SERVICE_CONTROL_INTERROGATE flag");
if ( ::ControlService( _schandle, dwControl, &sStatus ))
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT HrMoveOutOfState( DWORD dwState );
HRESULT HrQueryState( DWORD* pdwState );
HRESULT HrQueryStartType( DWORD* pdwStartType );
HRESULT HrSetStartType( DWORD dwStartType )
{
Assert(_schandle != NULL );
if (::ChangeServiceConfig( _schandle,
SERVICE_NO_CHANGE,
dwStartType,
SERVICE_NO_CHANGE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL))
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT HrQueryDependencies(OUT LPTSTR * pmszDependencyList);
HRESULT HrSetDependencies(IN LPCTSTR mszDependencyList)
{
Assert(_schandle != NULL );
if (::ChangeServiceConfig( _schandle,
SERVICE_NO_CHANGE, // ServiceType
SERVICE_NO_CHANGE, // StartType
SERVICE_NO_CHANGE, // ErrorControl
NULL, // BinaryPathName
NULL, // LoadOredrGroup
NULL, // TagId
mszDependencyList, // Dependencies
NULL, // ServiceStartName
NULL, // Password
NULL)) // DisplayName
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT HrSetDisplayName(IN LPCTSTR mszDisplayName)
{
Assert(_schandle != NULL );
if (::ChangeServiceConfig( _schandle,
SERVICE_NO_CHANGE, // ServiceType
SERVICE_NO_CHANGE, // StartType
SERVICE_NO_CHANGE, // ErrorControl
NULL, // BinaryPathName
NULL, // LoadOredrGroup
NULL, // TagId
NULL, // Dependencies
NULL, // ServiceStartName
NULL, // Password
mszDisplayName)) // DisplayName
{
return S_OK;
}
else
{
return HRESULT_FROM_WIN32(GetLastError());
}
}
HRESULT HrSetServiceObjectSecurity(
SECURITY_INFORMATION dwSecurityInformation,
PSECURITY_DESCRIPTOR lpSecurityDescriptor)
{
Assert(_schandle != NULL );
if (::SetServiceObjectSecurity( _schandle,
dwSecurityInformation, lpSecurityDescriptor))
{
return S_OK;
}
else
{
return HRESULT_FROM_WIN32(GetLastError());
}
}
private:
SC_HANDLE _schandle;
};
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
class CServiceManager
{
public:
CServiceManager()
{
_schandle = NULL;
_sclock = NULL;
};
~CServiceManager()
{
if (_sclock)
{
Unlock();
}
if (_schandle)
{
Close();
}
};
HRESULT HrOpen( DWORD dwDesiredAccess = SC_MANAGER_ALL_ACCESS,
LPCTSTR pszMachineName = NULL,
LPCTSTR pszDatabaseName = NULL )
{
if (_schandle != NULL)
{
Close();
}
_schandle = ::OpenSCManager( pszMachineName,
pszDatabaseName,
dwDesiredAccess );
if ( _schandle != NULL )
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
VOID Close()
{
BOOL frt;
Assert(_schandle != NULL );
frt = ::CloseServiceHandle( _schandle );
_schandle = NULL;
AssertSz(frt, "CloseServiceHandle failed!");
}
HRESULT HrLock()
{
INT cRetries = 3;
static const INT c_secWait = 30;
static const INT c_msecWait = (c_secWait / (cRetries - 1)) * 1000;
Assert(_schandle != NULL );
Assert(_sclock == NULL );
while (cRetries--)
{
_sclock = ::LockServiceDatabase( _schandle );
if (_sclock != NULL)
return S_OK;
else
{
if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED ||
!cRetries)
{
return HRESULT_FROM_WIN32(GetLastError());
}
Trace1("SCM is locked, waiting for %d seconds before retrying...", c_msecWait / 1000);
// wait for a bit to see if the database unlocks in that
Sleep(c_msecWait);
}
}
AssertSz(FALSE, "HrLock error");
return S_OK;
}
VOID Unlock()
{
BOOL frt;
Assert(_schandle != NULL );
Assert(_sclock != NULL );
frt = ::UnlockServiceDatabase( _sclock );
_sclock = NULL;
AssertSz(frt, "UnlockServiceDatabase failed!");
}
HRESULT HrQueryLocked(BOOL *pfLocked);
HRESULT HrOpenService( CService* pcsService,
LPCTSTR pszServiceName,
DWORD dwDesiredAccess = SERVICE_ALL_ACCESS )
{
// make sure the service is not in use
if (pcsService->_schandle != NULL)
{
pcsService->Close();
}
pcsService->_schandle = ::OpenService( _schandle, pszServiceName, dwDesiredAccess );
if ( pcsService->_schandle != NULL )
return S_OK;
else
{
DWORD dw=GetLastError();
return HRESULT_FROM_WIN32(dw);
}
}
HRESULT HrCreateService( CService* pcsService,
LPCTSTR pszServiceName,
LPCTSTR pszDisplayName,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR pszBinaryPathName,
LPCTSTR pslzDependencies = NULL,
LPCTSTR pszLoadOrderGroup = NULL,
PDWORD pdwTagId = NULL,
DWORD dwDesiredAccess = SERVICE_ALL_ACCESS,
LPCTSTR pszServiceStartName = NULL,
LPCTSTR pszPassword = NULL )
{
// make sure the service is not in use
if (pcsService->_schandle != NULL)
{
pcsService->Close();
}
pcsService->_schandle = ::CreateService( _schandle,
pszServiceName,
pszDisplayName,
dwDesiredAccess,
dwServiceType,
dwStartType,
dwErrorControl,
pszBinaryPathName,
pszLoadOrderGroup,
pdwTagId,
pslzDependencies,
pszServiceStartName,
pszPassword );
if ( pcsService->_schandle != NULL )
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
enum SERVICE_START_CRITERIA
{
SERVICE_NO_CRITERIA, // Start the service regardless
SERVICE_ONLY_AUTO_START // Only start the service if it is of type
// Auto-Start
};
HRESULT HrStartService(LPCTSTR szService)
{
return (HrStartServiceHelper(szService, SERVICE_NO_CRITERIA));
}
HRESULT HrStartAutoStartService(LPCTSTR szService)
{
return (HrStartServiceHelper(szService, SERVICE_ONLY_AUTO_START));
}
HRESULT HrStartServiceHelper(LPCTSTR szService,
SERVICE_START_CRITERIA eCriteria);
HRESULT HrStopService(LPCTSTR szService);
enum DEPENDENCY_ADDREMOVE
{
DEPENDENCY_ADD,
DEPENDENCY_REMOVE
};
HRESULT HrAddServiceDependency(LPCTSTR szServiceName, LPCTSTR szDependency)
{
return HrAddRemoveServiceDependency(szServiceName,
szDependency,
DEPENDENCY_ADD);
}
HRESULT HrRemoveServiceDependency(LPCTSTR szServiceName, LPCTSTR szDependency)
{
return HrAddRemoveServiceDependency(szServiceName,
szDependency,
DEPENDENCY_REMOVE);
}
HRESULT HrAddRemoveServiceDependency(LPCTSTR szServiceName,
LPCTSTR szDependency,
DEPENDENCY_ADDREMOVE enumFlag);
private:
SC_HANDLE _schandle;
SC_LOCK _sclock;
};
#endif // _CSERVICE_H_