handle模板三 - 服务管理工具类

1、scmgrutil.h

///
// scmgrutil.h
//

#if (_MSC_VER >= 1020)
#pragma once
#endif

#ifndef __SCMGRUTIL_H__
#define __SCMGRUTIL_H__

#ifdef _WIN32_WCE
    #error scmgrutil.h compiles under Windows only
#endif

#include <winsvc.h>
#include "atlmiscutil.h"

///
// Classes in this file:
//
// CServiceManager
// CService
// CServiceStatus
// CServiceConfig
// CServiceDescription
// CServiceSidInfo
// CServicePreshutdownInfo
// CServiceFailureActions
// CServiceDelayedInfo
// CServicePrivilegesInfo
// CServiceFailureActionsFlag
// CServiceStatusEnumeration
// CServiceCtrlHandlerImpl<T>

namespace atlutil {

///
// Interface of the CServiceHandleTraits class
//

struct CServiceHandleTraits : public CHandleTraits
{
    typedef SC_HANDLE HANDLET_PTR;
    static BOOL WINAPI Destroy(HANDLET_PTR hHandle);
};


///
// Interface of the CServiceManager class
//

class CServiceManager : public CHandle<CServiceHandleTraits>
{
// Constructors
public:
    CServiceManager();

// Operations
public:
    SC_HANDLE Open(DWORD dwDesiredAccess = SC_MANAGER_ALL_ACCESS, LPCTSTR pszDatabaseName = NULL, LPCTSTR pszMachineName = NULL);

#if defined(__ATLSTR_H__) || defined(__AFXSTR_H__)
    CString GetServiceName(LPCTSTR pszDisplayName);
    CString GetServiceDisplayName(LPCTSTR pszServiceName);
#endif

    BOOL GetServiceName(LPCTSTR pszDisplayName, LPTSTR pszServiceName, DWORD& dwBufferLength);
    BOOL GetServiceDisplayName(LPCTSTR pszServiceName, LPTSTR pszDisplayName, DWORD& dwBufferLength);
};


///
// Interface of the CService class
//

class CService : public CHandle<CServiceHandleTraits>
{
// Constructors
public:
    CService();

// Operations
public:
    SC_HANDLE Create(SC_HANDLE hSCManager, LPCTSTR pszServiceName, LPCTSTR pszBinaryPathName, LPCTSTR pszDisplayName = NULL, DWORD dwDesiredAccess = SERVICE_ALL_ACCESS, DWORD dwServiceType = SERVICE_WIN32_SHARE_PROCESS, DWORD dwStartType = SERVICE_AUTO_START, DWORD dwErrorControl = SERVICE_ERROR_NORMAL, LPDWORD pdwTagId = NULL, LPCTSTR pszDependencies = NULL, LPCTSTR pszServiceStartName = NULL, LPCTSTR pszLoadOrderGroup = NULL, LPCTSTR pszPassword = NULL);
    SC_HANDLE Open(SC_HANDLE hSCManager, LPCTSTR pszServiceName, DWORD dwDesiredAccess = SERVICE_ALL_ACCESS);

    BOOL Delete();
    BOOL Start(LPCTSTR* ppszServiceArgs = NULL, DWORD dwServiceArgs = 0);
    BOOL Control(SERVICE_STATUS& status, DWORD dwControl = SERVICE_CONTROL_STOP);

    BOOL ChangeConfig(DWORD dwStartType, DWORD dwServiceType, DWORD dwErrorControl, LPCTSTR pszDisplayName, LPCTSTR pszServiceStartName, LPCTSTR pszPassword = NULL, LPCTSTR pszDependencies = NULL, LPCTSTR pszBinaryPathName = NULL, LPCTSTR pszLoadOrderGroup = NULL, LPDWORD pdwTagId = NULL);
    BOOL ChangeConfig2(DWORD dwInfoLevel, LPVOID pvConfigInfo);
    BOOL SetSecurity(PSECURITY_DESCRIPTOR pSecurityDescriptor, SECURITY_INFORMATION dwSecurityInformation = OWNER_SECURITY_INFORMATION);

#if (_WIN32_WINNT >= 0x0600)
    BOOL ControlEx(DWORD dwControl, LPVOID pControlParams, DWORD dwInfoLevel = SERVICE_CONTROL_STATUS_REASON_INFO);
#endif
};


///
// Interface of the CServiceStatus class
//

class CServiceStatus : public SERVICE_STATUS_PROCESS
{
// Constructors
public:
    CServiceStatus();

// Operations
public:
    BOOL Query(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel = SC_STATUS_PROCESS_INFO);
    BOOL Verify(SC_HANDLE hService, DWORD dwVerifiedState, SC_STATUS_TYPE InfoLevel = SC_STATUS_PROCESS_INFO);

#ifdef _CRT_DEBUG_DUMP
    template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif

// Attributes
public:
    BOOL IsPaused() const;
    BOOL IsRunning() const;
    BOOL IsPending() const;
    BOOL IsStopped() const;

    BOOL IsStopPending() const;
    BOOL IsStartPending() const;
    BOOL IsPausePending() const;
    BOOL IsContinuePending() const;
};


///
// Interface of the CServiceConfig class
//

class CServiceConfig : public CHeapBuffer<QUERY_SERVICE_CONFIG>
{
// Constructors
public:
    CServiceConfig();

// Operations
public:
    BOOL Query(SC_HANDLE hService);

#ifdef _CRT_DEBUG_DUMP
    template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif
};


///
// Interface of the CServiceConfigInfo class
//

template <typename _Ty, DWORD dwInfoLevel>
class CServiceConfigInfo : public CHeapBuffer<_Ty>
{
// Constructors
public:
    CServiceConfigInfo();

// Operations
public:
    BOOL Query(SC_HANDLE hService);
};


///
// Interface of the CServiceConfigInfoT class
//

template <typename TBase, DWORD dwInfoLevel>
class CServiceConfigInfoT : public TBase
{
// Constructors
public:
    CServiceConfigInfoT();

// Operations
public:
    BOOL Query(SC_HANDLE hService);
};


///
// Interface of the CServiceStatusEnumeration class
//

class CServiceStatusEnumeration : public CHeapBuffer<ENUM_SERVICE_STATUS_PROCESS>
{
// Constructors
public:
    CServiceStatusEnumeration();

// Operations
public:
    BOOL EnumStatus(SC_HANDLE hSCManager, DWORD dwServiceType = SERVICE_WIN32, DWORD dwServiceState = SERVICE_STATE_ALL, LPCTSTR pszGroupName = NULL, SC_ENUM_TYPE InfoLevel = SC_ENUM_PROCESS_INFO);

#ifdef _CRT_DEBUG_DUMP
    template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif

// Data members
public:
    DWORD m_dwCount;
};


///
// Interface of the CServiceCtrlHandlerImpl class
//

template <typename T>
class ATL_NO_VTABLE CServiceCtrlHandlerImpl
{
// Constructors
protected:
    CServiceCtrlHandlerImpl();

// Overridables
public:
    DWORD SCHandler_OnPause();
    DWORD SCHandler_OnStop();
    DWORD SCHandler_OnContinue();

    DWORD SCHandler_OnShutdown();
    DWORD SCHandler_OnPreShutdown();

    DWORD SCHandler_OnInterrogate();
    DWORD SCHandler_OnParamChange();

// Operations
public:
    SERVICE_STATUS_HANDLE SCHandler_Register(LPCTSTR pszServiceName);

// Attributes
public:
    BOOL SCHandler_IsEmpty() const;

// Implementation
protected:
    static DWORD WINAPI SCHandler_ServiceControl(DWORD dwControl, DWORD dwEventType, LPVOID pEventData, LPVOID pContext);

// Data members
public:
    SERVICE_STATUS_HANDLE m_hServiceStatus;
};

}  // namespace atlutil

#include "scmgrutil.inl"

#endif  // __SCMGRUTIL_H__

2、scmgrutil.inl

///
// scmgrutil.inl


#if (_MSC_VER >= 1020)
#pragma once
#endif

#ifndef __SCMGRUTIL_INL__
#define __SCMGRUTIL_INL__

#ifndef __SCMGRUTIL_H__
    #error scmgrutil.inl requires scmgrutil.h to be included first
#endif

namespace atlutil {

///
// Type definition
//

typedef CServiceConfigInfo<SERVICE_DESCRIPTION, SERVICE_CONFIG_DESCRIPTION> CServiceDescription;
typedef CServiceConfigInfo<SERVICE_FAILURE_ACTIONS, SERVICE_CONFIG_FAILURE_ACTIONS> CServiceFailureActions;

#if (_WIN32_WINNT >= 0x0600)
typedef CServiceConfigInfoT<SERVICE_SID_INFO, SERVICE_CONFIG_SERVICE_SID_INFO> CServiceSidInfo;
typedef CServiceConfigInfoT<SERVICE_PRESHUTDOWN_INFO, SERVICE_CONFIG_PRESHUTDOWN_INFO> CServicePreshutdownInfo;
typedef CServiceConfigInfoT<SERVICE_DELAYED_AUTO_START_INFO, SERVICE_CONFIG_DELAYED_AUTO_START_INFO> CServiceDelayedInfo;
typedef CServiceConfigInfoT<SERVICE_FAILURE_ACTIONS_FLAG, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG> CServiceFailureActionsFlag;
typedef CServiceConfigInfo<SERVICE_REQUIRED_PRIVILEGES_INFO, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO> CServicePrivilegesInfo;
#endif  // (_WIN32_WINNT >= 0x0600)


///
// Implementation of the CServiceHandleTraits class
//

inline BOOL WINAPI CServiceHandleTraits::Destroy(HANDLET_PTR hHandle)
{
    return ::CloseServiceHandle(hHandle);
}


///
// Implementation of the CServiceManager class
//

inline CServiceManager::CServiceManager()
{
}

inline SC_HANDLE CServiceManager::Open(DWORD dwDesiredAccess/* = SC_MANAGER_ALL_ACCESS*/, LPCTSTR pszDatabaseName/* = NULL*/, LPCTSTR pszMachineName/* = NULL*/)
{
    ATLASSERT(IsEmpty());
    return (m_hHandle = ::OpenSCManager(pszMachineName, pszDatabaseName, dwDesiredAccess));
}

#if defined(__ATLSTR_H__) || defined(__AFXSTR_H__)
inline CString CServiceManager::GetServiceName(LPCTSTR pszDisplayName)
{
    ATLASSERT(!IsEmpty());
    ATLASSERT(pszDisplayName);

    CString strServiceName;
    DWORD dwBufferLength = 0;

    if (!::GetServiceKeyName(m_hHandle, pszDisplayName, NULL, &dwBufferLength) && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        ATLASSERT(dwBufferLength != 0);
        ATLVERIFY(::GetServiceKeyName(m_hHandle, pszDisplayName, strServiceName.GetBuffer(++dwBufferLength), &dwBufferLength));
        strServiceName.ReleaseBuffer(dwBufferLength);
    }

    return strServiceName;
}

inline CString CServiceManager::GetServiceDisplayName(LPCTSTR pszServiceName)
{
    ATLASSERT(!IsEmpty());
    ATLASSERT(pszServiceName);

    CString strDisplayName;
    DWORD dwBufferLength = 0;

    if (!::GetServiceDisplayName(m_hHandle, pszServiceName, NULL, &dwBufferLength) && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        ATLASSERT(dwBufferLength != 0);
        ATLVERIFY(::GetServiceDisplayName(m_hHandle, pszServiceName, strDisplayName.GetBuffer(++dwBufferLength), &dwBufferLength));
        strDisplayName.ReleaseBuffer(dwBufferLength);
    }

    return strDisplayName;
}
#endif  // defined(__ATLSTR_H__) || defined(__AFXSTR_H__)

inline BOOL CServiceManager::GetServiceName(LPCTSTR pszDisplayName, LPTSTR pszServiceName, DWORD& dwBufferLength)
{
    ATLASSERT(!IsEmpty());
    ATLASSERT(pszDisplayName);

    return ::GetServiceKeyName(m_hHandle, pszDisplayName, pszServiceName, &dwBufferLength);
}

inline BOOL CServiceManager::GetServiceDisplayName(LPCTSTR pszServiceName, LPTSTR pszDisplayName, DWORD& dwBufferLength)
{
    ATLASSERT(!IsEmpty());
    ATLASSERT(pszServiceName);

    return ::GetServiceDisplayName(m_hHandle, pszServiceName, pszDisplayName, &dwBufferLength);
}


///
// Implementation of the CService class
//

inline CService::CService()
{
}

inline SC_HANDLE CService::Create(SC_HANDLE hSCManager, LPCTSTR pszServiceName, LPCTSTR pszBinaryPathName, LPCTSTR pszDisplayName/* = NULL*/, DWORD dwDesiredAccess/* = SERVICE_ALL_ACCESS*/, DWORD dwServiceType/* = SERVICE_WIN32_SHARE_PROCESS*/, DWORD dwStartType/* = SERVICE_AUTO_START*/, DWORD dwErrorControl/* = SERVICE_ERROR_NORMAL*/, LPDWORD pdwTagId/* = NULL*/, LPCTSTR pszDependencies/* = NULL*/, LPCTSTR pszServiceStartName/* = NULL*/, LPCTSTR pszLoadOrderGroup/* = NULL*/, LPCTSTR pszPassword/* = NULL*/)
{
    ATLASSERT(IsEmpty());
    ATLASSERT(hSCManager);
    ATLASSERT(pszServiceName);

    return (m_hHandle = ::CreateService(hSCManager, pszServiceName, pszDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, pszBinaryPathName, pszLoadOrderGroup, pdwTagId, pszDependencies, pszServiceStartName, pszPassword));
}

inline SC_HANDLE CService::Open(SC_HANDLE hSCManager, LPCTSTR pszServiceName, DWORD dwDesiredAccess/* = SERVICE_ALL_ACCESS*/)
{
    ATLASSERT(IsEmpty());
    ATLASSERT(hSCManager);
    ATLASSERT(pszServiceName);

    return (m_hHandle = ::OpenService(hSCManager, pszServiceName, dwDesiredAccess));
}

inline BOOL CService::Delete()
{
    ATLASSERT(!IsEmpty());
    return ::DeleteService(m_hHandle);
}

inline BOOL CService::Start(LPCTSTR* ppszServiceArgs/* = NULL*/, DWORD dwServiceArgs/* = 0*/)
{
    ATLASSERT(!IsEmpty());
    return ::StartService(m_hHandle, dwServiceArgs, ppszServiceArgs);
}

inline BOOL CService::Control(SERVICE_STATUS& status, DWORD dwControl/* = SERVICE_CONTROL_STOP*/)
{
    ATLASSERT(!IsEmpty());
    return ::ControlService(m_hHandle, dwControl, &status);
}

inline BOOL CService::ChangeConfig(DWORD dwStartType, DWORD dwServiceType, DWORD dwErrorControl, LPCTSTR pszDisplayName, LPCTSTR pszServiceStartName, LPCTSTR pszPassword/* = NULL*/, LPCTSTR pszDependencies/* = NULL*/, LPCTSTR pszBinaryPathName/* = NULL*/, LPCTSTR pszLoadOrderGroup/* = NULL*/, LPDWORD pdwTagId/* = NULL*/)
{
    ATLASSERT(!IsEmpty());
    return ::ChangeServiceConfig(m_hHandle, dwServiceType, dwStartType, dwErrorControl, pszBinaryPathName, pszLoadOrderGroup, pdwTagId, pszDependencies, pszServiceStartName, pszPassword, pszDisplayName);
}

inline BOOL CService::ChangeConfig2(DWORD dwInfoLevel, LPVOID pvConfigInfo)
{
    ATLASSERT(!IsEmpty());
    return ::ChangeServiceConfig2(m_hHandle, dwInfoLevel, pvConfigInfo);
}

inline BOOL CService::SetSecurity(PSECURITY_DESCRIPTOR pSecurityDescriptor, SECURITY_INFORMATION dwSecurityInformation/* = OWNER_SECURITY_INFORMATION*/)
{
    ATLASSERT(!IsEmpty());
    return ::SetServiceObjectSecurity(m_hHandle, dwSecurityInformation, pSecurityDescriptor);
}

#if (_WIN32_WINNT >= 0x0600)
inline BOOL CService::ControlEx(DWORD dwControl, LPVOID pControlParams, DWORD dwInfoLevel/* = SERVICE_CONTROL_STATUS_REASON_INFO*/)
{
    ATLASSERT(!IsEmpty());
    return ::ControlServiceEx(m_hHandle, dwControl, dwInfoLevel, pControlParams);
}
#endif  // (_WIN32_WINNT >= 0x0600)


///
// Implementation of the CServiceStatus class
//

inline CServiceStatus::CServiceStatus()
{
}

inline BOOL CServiceStatus::Query(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel/* = SC_STATUS_PROCESS_INFO*/)
{
    ATLASSERT(hService);

    DWORD cbSize = sizeof(SERVICE_STATUS_PROCESS);
    return ::QueryServiceStatusEx(hService, InfoLevel, (LPBYTE)this, cbSize, &cbSize);
}

inline BOOL CServiceStatus::Verify(SC_HANDLE hService, DWORD dwVerifiedState, SC_STATUS_TYPE InfoLevel/* = SC_STATUS_PROCESS_INFO*/)
{
    ATLASSERT(hService);
    ATLASSERT(dwVerifiedState <= SERVICE_PAUSED);
    ATLASSERT(dwVerifiedState >= SERVICE_STOPPED);

    BOOL bSuccessful = Query(hService, InfoLevel);
    while (bSuccessful && dwCurrentState != dwVerifiedState)
    {
        ::Sleep(200);
        bSuccessful = Query(hService, InfoLevel);
    }

    return bSuccessful;
}

#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void CServiceStatus::Dump(const _Pr& _Printer) const
{
    _Printer(_T("\n[ SERVICES STATUS ]\n[\n\tService Type\t\t\t\t= 0x%08lx\n\tCurrent State\t\t\t\t= 0x%08lx\n\tControls Accepted\t\t\t= 0x%08lx\n\
                \tWin32 Exit Code\t\t\t\t= 0x%08lx\n\tService Specific Exit Code\t= 0x%08lx\n\tCheck Point\t\t\t\t\t= 0x%08lx\n\tWait Hint\t\t\t\t\t= 0x%08lx\n\
                \tProcess Id\t\t\t\t\t= 0x%08lx\n\tService Flags\t\t\t\t= 0x%08lx\n]\n"), dwServiceType, dwCurrentState, dwControlsAccepted, dwWin32ExitCode,
                dwServiceSpecificExitCode, dwCheckPoint, dwWaitHint, dwProcessId, dwServiceFlags);
}
#endif  // _CRT_DEBUG_DUMP

inline BOOL CServiceStatus::IsPaused() const
{
    return (dwCurrentState == SERVICE_PAUSED);
}

inline BOOL CServiceStatus::IsRunning() const
{
    return (dwCurrentState == SERVICE_RUNNING);
}

inline BOOL CServiceStatus::IsPending() const
{
    return (dwCurrentState == SERVICE_START_PENDING || dwCurrentState == SERVICE_STOP_PENDING || dwCurrentState == SERVICE_CONTINUE_PENDING || dwCurrentState == SERVICE_PAUSE_PENDING);
}

inline BOOL CServiceStatus::IsStopped() const
{
    return (dwCurrentState == SERVICE_STOPPED);
}

inline BOOL CServiceStatus::IsStopPending() const
{
    return (dwCurrentState == SERVICE_STOP_PENDING);
}

inline BOOL CServiceStatus::IsStartPending() const
{
    return (dwCurrentState == SERVICE_START_PENDING);
}

inline BOOL CServiceStatus::IsPausePending() const
{
    return (dwCurrentState == SERVICE_PAUSE_PENDING);
}

inline BOOL CServiceStatus::IsContinuePending() const
{
    return (dwCurrentState == SERVICE_CONTINUE_PENDING);
}


///
// Implementation of the CServiceConfig class
//

inline CServiceConfig::CServiceConfig()
{
}

inline BOOL CServiceConfig::Query(SC_HANDLE hService)
{
    ATLASSERT(hService);
    ATLASSERT(IsEmpty());

    DWORD cbSize = 0;
    return ((!::QueryServiceConfig(hService, NULL, 0, &cbSize) && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) && AllocateBytes(cbSize) != NULL && ::QueryServiceConfig(hService, m_pBuffer, cbSize, &cbSize));
}

#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void CServiceConfig::Dump(const _Pr& _Printer) const
{
    _Printer(_T("\n[ SERVICES CONFIG ]\n[\n"));
    if (m_pBuffer != NULL)
    {
        _Printer(_T("\tService Type\t\t= 0x%08lx\n\tStart Type\t\t\t= 0x%08lx\n\tError Control\t\t= 0x%08lx\n\tBinary Path Name\t= %s\n\tLoad Order Group\t= %s\n\
                    \tTag ID\t\t\t\t= %u\n\tDependencies\t\t= "), m_pBuffer->dwServiceType, m_pBuffer->dwStartType, m_pBuffer->dwErrorControl,
                    m_pBuffer->lpBinaryPathName, m_pBuffer->lpLoadOrderGroup, m_pBuffer->dwTagId);

        if (m_pBuffer->lpDependencies != NULL)
        {
            LPCTSTR pszDependencies = m_pBuffer->lpDependencies;
            while (*pszDependencies != _T('\0'))
            {
                _Printer(_T("%s "), pszDependencies);
                pszDependencies += ::lstrlen(pszDependencies) + 1;
            }
        }
        _Printer(_T("\n\tService Start Name\t= %s\n\tDisplay Name\t\t= %s\n"), m_pBuffer->lpServiceStartName, m_pBuffer->lpDisplayName);
    }
    _Printer(_T("]\n"));
}
#endif  // _CRT_DEBUG_DUMP


///
// Implementation of the CServiceConfigInfo class
//

template <typename _Ty, DWORD dwInfoLevel>
inline CServiceConfigInfo<_Ty, dwInfoLevel>::CServiceConfigInfo()
{
}

template <typename _Ty, DWORD dwInfoLevel>
inline BOOL CServiceConfigInfo<_Ty, dwInfoLevel>::Query(SC_HANDLE hService)
{
    ATLASSERT(hService);
    ATLASSERT(IsEmpty());

    DWORD cbSize = 0;
    return ((!::QueryServiceConfig2(hService, dwInfoLevel, NULL, 0, &cbSize) && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) && AllocateBytes(cbSize) != NULL && ::QueryServiceConfig2(hService, dwInfoLevel, (LPBYTE)m_pBuffer, cbSize, &cbSize));
}


///
// Implementation of the CServiceConfigInfoT class
//

template <typename TBase, DWORD dwInfoLevel>
inline CServiceConfigInfoT<TBase, dwInfoLevel>::CServiceConfigInfoT()
{
}

template <typename TBase, DWORD dwInfoLevel>
inline BOOL CServiceConfigInfoT<TBase, dwInfoLevel>::Query(SC_HANDLE hService)
{
    ATLASSERT(hService);

    DWORD cbSize = sizeof(TBase);
    return ::QueryServiceConfig2(hService, dwInfoLevel, (LPBYTE)this, cbSize, &cbSize);
}


///
// Implementation of the CServiceStatusEnumeration class
//

inline CServiceStatusEnumeration::CServiceStatusEnumeration()
    : m_dwCount(0)
{
}

inline BOOL CServiceStatusEnumeration::EnumStatus(SC_HANDLE hSCManager, DWORD dwServiceType/* = SERVICE_WIN32*/, DWORD dwServiceState/* = SERVICE_STATE_ALL*/, LPCTSTR pszGroupName/* = NULL*/, SC_ENUM_TYPE InfoLevel/* = SC_ENUM_PROCESS_INFO*/)
{
    ATLASSERT(hSCManager);
    ATLASSERT(m_pBuffer == NULL);

    BOOL bSuccessful = FALSE;
    DWORD cbSize = 0, dwResumeHandle = 0;
    if ((!::EnumServicesStatusEx(hSCManager, InfoLevel, dwServiceType, dwServiceState, NULL, 0, &cbSize, &m_dwCount, &dwResumeHandle, pszGroupName) && ::GetLastError() == ERROR_MORE_DATA))
    {
        if (AllocateBytes(cbSize))
            bSuccessful = ::EnumServicesStatusEx(hSCManager, InfoLevel, dwServiceType, dwServiceState, (LPBYTE)m_pBuffer, cbSize, &cbSize, &m_dwCount, &dwResumeHandle, pszGroupName);
    }

    return bSuccessful;
}

#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void CServiceStatusEnumeration::Dump(const _Pr& _Printer) const
{
    _Printer(_T("\n[ SERVICES COUNT = %u ]\n"), m_dwCount);
    if (m_pBuffer != NULL)
    {
        for (DWORD i = 0; i < m_dwCount; ++i)
        {
            _Printer(_T("[\n\tService Name\t\t\t\t= %s\n\tService Display Name\t\t= %s\n\tService Type\t\t\t\t= 0x%08lx\n\tCurrent State\t\t\t\t= 0x%08lx\n\
                        \tControls Accepted\t\t\t= 0x%08lx\n\tWin32 Exit Code\t\t\t\t= 0x%08lx\n\tService Specific Exit Code\t= 0x%08lx\n\tCheck Point\t\t\t\t\t= 0x%08lx\n\
                        \tWait Hint\t\t\t\t\t= 0x%08lx\n\tProcess Id\t\t\t\t\t= 0x%08lx\n\tService Flags\t\t\t\t= 0x%08lx\n]\n"), m_pBuffer[i].lpServiceName,
                        m_pBuffer[i].lpDisplayName, m_pBuffer[i].ServiceStatusProcess.dwServiceType, m_pBuffer[i].ServiceStatusProcess.dwCurrentState, m_pBuffer[i].ServiceStatusProcess.dwControlsAccepted,
                        m_pBuffer[i].ServiceStatusProcess.dwWin32ExitCode, m_pBuffer[i].ServiceStatusProcess.dwServiceSpecificExitCode, m_pBuffer[i].ServiceStatusProcess.dwCheckPoint,
                        m_pBuffer[i].ServiceStatusProcess.dwWaitHint, m_pBuffer[i].ServiceStatusProcess.dwProcessId, m_pBuffer[i].ServiceStatusProcess.dwServiceFlags);
        }
    }
    _Printer(_T("\n"));
}
#endif  // _CRT_DEBUG_DUMP


///
// Implementation of the CServiceCtrlHandlerImpl class
//

template <typename T>
inline CServiceCtrlHandlerImpl<T>::CServiceCtrlHandlerImpl()
    : m_hServiceStatus(NULL)
{
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnPause()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnStop()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnContinue()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnShutdown()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnPreShutdown()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnInterrogate()
{
    return NO_ERROR;
}

template <typename T>
inline DWORD CServiceCtrlHandlerImpl<T>::SCHandler_OnParamChange()
{
    return NO_ERROR;
}

template <typename T>
inline SERVICE_STATUS_HANDLE CServiceCtrlHandlerImpl<T>::SCHandler_Register(LPCTSTR pszServiceName)
{
    ATLASSERT(pszServiceName);
    ATLASSERT(SCHandler_IsEmpty());

    return (m_hServiceStatus = ::RegisterServiceCtrlHandlerEx(pszServiceName, T::SCHandler_ServiceControl, static_cast<T*>(this)));
}

template <typename T>
inline BOOL CServiceCtrlHandlerImpl<T>::SCHandler_IsEmpty() const
{
    return (m_hServiceStatus == NULL);
}

template <typename T>
inline DWORD WINAPI CServiceCtrlHandlerImpl<T>::SCHandler_ServiceControl(DWORD dwControl, DWORD /*dwEventType*/, LPVOID /*pEventData*/, LPVOID pContext)
{
    T* pThis = reinterpret_cast<T*>(pContext);
    ATLASSERT(pThis);

    DWORD dwRetCode = NO_ERROR;
    switch (dwControl)
    {
    case SERVICE_CONTROL_STOP:
        dwRetCode = pThis->SCHandler_OnStop();
        break;

    case SERVICE_CONTROL_PAUSE:
        dwRetCode = pThis->SCHandler_OnPause();
        break;

    case SERVICE_CONTROL_CONTINUE:
        dwRetCode = pThis->SCHandler_OnContinue();
        break;

    case SERVICE_CONTROL_SHUTDOWN:
        dwRetCode = pThis->SCHandler_OnShutdown();
        break;

    case SERVICE_CONTROL_INTERROGATE:
        dwRetCode = pThis->SCHandler_OnInterrogate();
        break;

    case SERVICE_CONTROL_PARAMCHANGE:
        dwRetCode = pThis->SCHandler_OnParamChange();
        break;

    case SERVICE_CONTROL_PRESHUTDOWN:
        dwRetCode = pThis->SCHandler_OnPreShutdown();
        break;
    }

    return dwRetCode;
}

}  // namespace atlutil

#endif  // __SCMGRUTIL_INL__


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值