|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997 - 2000
//
// File: H N C E N U M . H
//
// Contents: Generic WMI enumerator template
//
// Notes:
//
// Author: jonburs 20 June 2000
//
//----------------------------------------------------------------------------
template< class EnumInterface, class ItemInterface, class WrapperClass > class CHNCEnum : public CComObjectRootEx<CComMultiThreadModel>, public EnumInterface { private: typedef CHNCEnum<EnumInterface, ItemInterface, WrapperClass> _ThisClass;
//
// The IEnumWbemClassObject we're wrapping
//
IEnumWbemClassObject *m_pwcoEnum;
//
// The IWbemServices for our namespace
//
IWbemServices *m_pwsNamespace;
public:
BEGIN_COM_MAP(_ThisClass) COM_INTERFACE_ENTRY(EnumInterface) END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
//
// Object Creation
//
CHNCEnum() { m_pwcoEnum = NULL; m_pwsNamespace = NULL; };
HRESULT Initialize( IWbemServices *pwsNamespace, IEnumWbemClassObject *pwcoEnum ) { _ASSERT(NULL == m_pwsNamespace); _ASSERT(NULL == m_pwcoEnum); _ASSERT(NULL != pwsNamespace); _ASSERT(NULL != pwcoEnum);
m_pwcoEnum = pwcoEnum; m_pwcoEnum->AddRef(); m_pwsNamespace = pwsNamespace; m_pwsNamespace->AddRef();
return S_OK; };
//
// Object Destruction
//
HRESULT FinalRelease() { if (NULL != m_pwcoEnum) { m_pwcoEnum->Release(); }
if (NULL != m_pwsNamespace) { m_pwsNamespace->Release(); }
return S_OK; };
//
// EnumInterface methods
//
STDMETHODIMP Next( ULONG cElt, ItemInterface **rgElt, ULONG *pcEltFetched ) { HRESULT hr = S_OK; ULONG cInstancesFetched = 0; IWbemClassObject **rgpwcoInstances = NULL; CComObject<WrapperClass> *pWrapper = NULL; LONG i;
_ASSERT(NULL != m_pwcoEnum);
if (NULL == rgElt) { hr = E_POINTER; } else if (0 == cElt) { hr = E_INVALIDARG; } else if (1 != cElt && NULL == pcEltFetched) { hr = E_POINTER; }
if (S_OK == hr) { //
// Zero the output array
//
ZeroMemory(rgElt, cElt * sizeof(ItemInterface*)); //
// Allocate enough memory to hold pointers to the instances we
// were asked to fetch.
//
rgpwcoInstances = new IWbemClassObject*[cElt]; if (NULL != rgpwcoInstances) { ZeroMemory(rgpwcoInstances, sizeof(IWbemClassObject*) * cElt); } else { hr = E_OUTOFMEMORY; } }
if (S_OK == hr) { //
// Grab the requested number of instances from the contained
// WMI enumeration.
//
hr = m_pwcoEnum->Next( WBEM_INFINITE, cElt, rgpwcoInstances, &cInstancesFetched ); }
if (SUCCEEDED(hr)) { //
// For each instance we retrieved, create the wrapper
// object.
//
for (i = 0; static_cast<ULONG>(i) < cInstancesFetched; i++) { hr = CComObject<WrapperClass>::CreateInstance(&pWrapper);
if (SUCCEEDED(hr)) { pWrapper->AddRef(); hr = pWrapper->Initialize( m_pwsNamespace, rgpwcoInstances[i] ); if (SUCCEEDED(hr)) { //
// QI for the desired interface, and place into
// the output array
//
hr = pWrapper->QueryInterface( IID_PPV_ARG(ItemInterface, &rgElt[i]) );
//
// This can only fail if we were given incorrect
// template arguments.
//
_ASSERT(SUCCEEDED(hr)); }
pWrapper->Release(); }
if (FAILED(hr)) { break; } }
if (FAILED(hr)) { //
// Something went wrong, and we destroy all of the objects
// we just created and QI'd. (The position of the last object
// created is one less than the current value of i.)
//
for (i-- ; i >= 0; i--) { if (NULL != rgElt[i]) { rgElt[i]->Release(); } } }
//
// Release all of the instances we retrieved
//
for (ULONG j = 0; j < cInstancesFetched; j++) { if (NULL != rgpwcoInstances[j]) { rgpwcoInstances[j]->Release(); } } }
//
// If necessary, release the memory we used to hold the
// instance pointers.
//
if (NULL != rgpwcoInstances) { delete [] rgpwcoInstances; }
if (SUCCEEDED(hr)) { //
// Set the number of items we retrieved
//
if (NULL != pcEltFetched) { *pcEltFetched = cInstancesFetched; }
//
// Normalize return value
//
if (cInstancesFetched == cElt) { hr = S_OK; } else { hr = S_FALSE; } }
return hr; };
STDMETHODIMP Clone( EnumInterface **ppEnum )
{ HRESULT hr = S_OK; IEnumWbemClassObject *pwcoClonedEnum; CComObject<_ThisClass> *pNewEnum;
if (NULL == ppEnum) { hr = E_POINTER; } else { //
// Attempt to clone the embedded enumeration.
//
pwcoClonedEnum = NULL; hr = m_pwcoEnum->Clone(&pwcoClonedEnum); }
if (WBEM_S_NO_ERROR == hr) { //
// Create an initialized a new instance of ourselves
//
hr = CComObject<_ThisClass>::CreateInstance(&pNewEnum); if (SUCCEEDED(hr)) { pNewEnum->AddRef(); hr = pNewEnum->Initialize(m_pwsNamespace, pwcoClonedEnum);
if (SUCCEEDED(hr)) { hr = pNewEnum->QueryInterface( IID_PPV_ARG(EnumInterface, ppEnum) );
//
// This QI should never fail, unless we were given
// bogus template arguments.
//
_ASSERT(SUCCEEDED(hr)); }
pNewEnum->Release(); }
//
// Release the cloned enum. New enum object will have
// AddReffed it...
//
pwcoClonedEnum->Release(); }
return hr; };
//
// Skip and Reset simply delegate to the contained enumeration.
//
STDMETHODIMP Reset() { _ASSERT(NULL != m_pwcoEnum); return m_pwcoEnum->Reset(); };
STDMETHODIMP Skip( ULONG cElt ) { _ASSERT(NULL != m_pwcoEnum); return m_pwcoEnum->Skip(WBEM_INFINITE, cElt); }; };
|