2025-11-27 16:46:48 +09:00

282 lines
7.2 KiB
C++

// =============================================================================
// Class Implementation : COXIteratorService
// =============================================================================
//
// Source file : OXIteratorService.cpp
// Version: 9.3
// This software along with its related components, documentation and files ("The Libraries")
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "OXIteratorService.h"
#include "UTB64Bit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define OXITERATORSERVICE_POS_NULL -2
// Data members -------------------------------------------------------------
// protected:
// CStringArray m_SrvKeyNames; // enumerated service key names
// CStringArray m_SrvDspNames; // enumerated service display names
// int m_nPos; // current index
// Member functions ---------------------------------------------------------
COXIteratorService::COXIteratorService(LPCTSTR pszKeyName /* = NULL */) :
COXService(pszKeyName)
{
m_nPos = OXITERATORSERVICE_POS_NULL;
}
COXIteratorService::COXIteratorService(const COXService& service) :
COXService(service)
{
m_nPos = OXITERATORSERVICE_POS_NULL;
}
COXIteratorService::COXIteratorService(const COXIteratorService& iteratorService) :
COXService(iteratorService)
{
if ((m_nPos = iteratorService.m_nPos) != OXITERATORSERVICE_POS_NULL)
{
m_SrvKeyNames.Copy(iteratorService.m_SrvKeyNames);
m_SrvDspNames.Copy(iteratorService.m_SrvDspNames);
}
}
COXIteratorService& COXIteratorService::operator=(const COXService& service)
{
End();
COXService::operator=(service);
return *this;
}
COXIteratorService& COXIteratorService::operator=(const COXIteratorService& iteratorService)
{
End();
COXService::operator=(iteratorService);
if ((m_nPos = iteratorService.m_nPos) != OXITERATORSERVICE_POS_NULL)
{
m_SrvKeyNames.Copy(iteratorService.m_SrvKeyNames);
m_SrvDspNames.Copy(iteratorService.m_SrvDspNames);
}
return *this;
}
BOOL COXIteratorService::StartIteration(
DWORD dwServiceType /* = SERVICE_WIN32 | SERVICE_DRIVER */,
DWORD dwServiceState /* = SERVICE_STATE_ALL */)
{
// we terminate a potential previous iteration
End();
if (!PrepareSCManager(SC_MANAGER_ENUMERATE_SERVICE))
return FALSE;
// get number of services first
DWORD dwBytesNeeded, dwServicesReturned, dwResumeHandle = 0;
BOOL bResult = ::EnumServicesStatus(c_hSCM,
dwServiceType, dwServiceState, NULL, 0,
&dwBytesNeeded, &dwServicesReturned, &dwResumeHandle);
// no services
if (bResult) return TRUE;
// abnormal failures
if (::GetLastError() != ERROR_MORE_DATA || dwBytesNeeded == 0)
{
SetLastError(FALSE);
return FALSE;
}
// get services again
LPENUM_SERVICE_STATUS pESSArray =
(LPENUM_SERVICE_STATUS)malloc(dwBytesNeeded);
if (pESSArray == NULL)
AfxThrowMemoryException();
dwResumeHandle = 0;
bResult = SetErrCode(::EnumServicesStatus(c_hSCM,
dwServiceType, dwServiceState, pESSArray, dwBytesNeeded,
&dwBytesNeeded, &dwServicesReturned, &dwResumeHandle));
if (bResult)
{
GetNamesFromESSArray(pESSArray, dwServicesReturned);
m_sKeyName = m_SrvKeyNames[m_nPos = 0];
}
free(pESSArray);
return bResult;
}
BOOL COXIteratorService::StartDependentIteration(
DWORD dwServiceState /* = SERVICE_STATE_ALL */)
{
// we terminate a potential previous iteration
CString sKeyName = GetKeyName();
End();
SetKeyName(sKeyName);
if (!PrepareSCHandle(SERVICE_ENUMERATE_DEPENDENTS))
return FALSE;
// get number of dependent services first
DWORD dwBytesNeeded, dwServicesReturned;
BOOL bResult = ::EnumDependentServices(m_hSC, dwServiceState, NULL, 0,
&dwBytesNeeded, &dwServicesReturned);
// no services
if (bResult) return TRUE;
// abnormal failures
if (::GetLastError() != ERROR_MORE_DATA || dwBytesNeeded == 0)
{
SetLastError(FALSE);
return FALSE;
}
// get services again
LPENUM_SERVICE_STATUS pESSArray =
(LPENUM_SERVICE_STATUS)malloc(dwBytesNeeded);
if (pESSArray == NULL)
AfxThrowMemoryException();
bResult = SetErrCode(::EnumDependentServices(m_hSC,
dwServiceState, pESSArray, dwBytesNeeded,
&dwBytesNeeded, &dwServicesReturned));
if (bResult)
{
GetNamesFromESSArray(pESSArray, dwServicesReturned);
m_sKeyName = m_SrvKeyNames[m_nPos = 0];
}
free(pESSArray);
return bResult;
}
BOOL COXIteratorService::Next()
{
ASSERT(m_nPos != OXITERATORSERVICE_POS_NULL);
if (m_nPos == OXITERATORSERVICE_POS_NULL ||
m_nPos == m_SrvKeyNames.GetSize())
return FALSE;
Empty();
m_nPos++;
if (m_nPos == m_SrvKeyNames.GetSize())
return FALSE;
m_sKeyName = m_SrvKeyNames[m_nPos];
return TRUE;
}
COXIteratorService& COXIteratorService::operator++()
{
Next();
return *this;
}
COXIteratorService COXIteratorService::operator+(int nOffset)
{
ASSERT(m_nPos != OXITERATORSERVICE_POS_NULL);
if (m_nPos == OXITERATORSERVICE_POS_NULL)
return *this;
Empty();
m_nPos += nOffset;
if (m_nPos <= -1)
m_nPos = -1;
else if (m_nPos >= m_SrvKeyNames.GetSize())
m_nPos = PtrToInt(m_SrvKeyNames.GetSize());
else
m_sKeyName = m_SrvKeyNames[m_nPos];
return *this;
}
BOOL COXIteratorService::Prev()
{
ASSERT(m_nPos != OXITERATORSERVICE_POS_NULL);
if (m_nPos == OXITERATORSERVICE_POS_NULL || m_nPos == -1)
return FALSE;
Empty();
m_nPos--;
if (m_nPos == -1) return FALSE;
m_sKeyName = m_SrvKeyNames[m_nPos];
return TRUE;
}
COXIteratorService& COXIteratorService::operator--()
{
Prev();
return *this;
}
COXIteratorService COXIteratorService::operator-(int nOffset)
{
return operator+(-nOffset);
}
void COXIteratorService::GetKeyNames(CStringArray& sBuffer)
{
ASSERT(m_nPos != OXITERATORSERVICE_POS_NULL);
sBuffer.Copy(m_SrvKeyNames);
}
void COXIteratorService::GetDisplayNames(CStringArray& sBuffer)
{
ASSERT(m_nPos != OXITERATORSERVICE_POS_NULL);
sBuffer.Copy(m_SrvDspNames);
}
int COXIteratorService::GetServiceCount()
{
return PtrToInt(m_SrvKeyNames.GetSize());
}
void COXIteratorService::End()
{
Empty();
m_SrvKeyNames.RemoveAll();
m_SrvDspNames.RemoveAll();
m_nPos = -1;
}
// protected:
void COXIteratorService::GetNamesFromESSArray(LPENUM_SERVICE_STATUS pESSArray,
DWORD dwServicesReturned)
// --- In : pESSArray, the service status array
// dwServicesReturned, service status number
// --- Out :
// --- Returns :
// --- Effect : copy service key names and display names from a
// service status array
{
m_SrvKeyNames.SetSize(dwServicesReturned);
m_SrvDspNames.SetSize(dwServicesReturned);
BYTE* pCurESS = (BYTE*)pESSArray;
for (DWORD i = 0; i < dwServicesReturned; i++)
{
m_SrvKeyNames[i] = ((LPENUM_SERVICE_STATUS)pCurESS)->lpServiceName;
m_SrvDspNames[i] = ((LPENUM_SERVICE_STATUS)pCurESS)->lpDisplayName;
pCurESS += sizeof(ENUM_SERVICE_STATUS);
}
}
// end of OXIteratorService.cpp