windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/stdprov/enuminst.cpp
2020-09-26 16:20:57 +08:00

295 lines
7.3 KiB
C++

/*++
Copyright (C) 1995-2001 Microsoft Corporation
Module Name:
ENUMINST.CPP
Abstract:
Implements the CEnumInst class which enumerates instances.
History:
a-davj 19-Oct-95 Created.
--*/
#include "precomp.h"
#include "impdyn.h"
//***************************************************************************
//
// CCFDyn::CCFDyn
//
// DESCRIPTION:
//
// Constructor.
//
// PARAMETERS:
//
// pEnumInfo Object which enumerates the key values
// lFlags flags passed to the CreateInstanceEnum call
// pClass name of the class
// pWBEMGateway pointer to WBEM core
// pProvider pointer to provider obect which was asked to create
// the enumerator.
//***************************************************************************
CEnumInst::CEnumInst(
IN CEnumInfo * pEnumInfo,
IN long lFlags,
IN WCHAR * pClass,
IN IWbemServices FAR* pWBEMGateway,
IN CImpDyn * pProvider,
IWbemContext *pCtx):
m_iIndex(0), m_pEnumInfo(0),m_pwcClass(0), m_lFlags(0), m_pCtx(0), m_pWBEMGateway(0),
m_pProvider(0), m_cRef(0), m_bstrKeyName(0), m_PropContextCache()
{
m_pwcClass = new WCHAR[wcslen(pClass)+1];
if(m_pwcClass == NULL) return;
wcscpy(m_pwcClass,pClass);
m_pWBEMGateway = pWBEMGateway;
m_pWBEMGateway->AddRef();
m_pProvider = pProvider;
m_pProvider->AddRef();
m_lFlags = lFlags;
m_pEnumInfo = pEnumInfo;
m_pEnumInfo->AddRef();
m_pCtx = pCtx;
if(pCtx) pCtx->AddRef();
InterlockedIncrement(&lObj);
// Get the KeyName
IWbemClassObject * pClassObj = NULL;
SCODE sc = m_pWBEMGateway->GetObject(pClass,0,m_pCtx,&pClassObj,NULL);
if(FAILED(sc)) return;
m_bstrKeyName = m_pProvider->GetKeyName(pClassObj);
pClassObj->Release();
}
//***************************************************************************
//
// CCFDyn::~CCFDyn
//
// DESCRIPTION:
//
// Destructor.
//
//***************************************************************************
CEnumInst::~CEnumInst(void)
{
if(m_pwcClass)
delete m_pwcClass;
if(m_pWBEMGateway != NULL) {
m_pWBEMGateway->Release();
m_pProvider->Release();
m_pEnumInfo->Release();
InterlockedDecrement(&lObj);
}
if(m_pEnumInfo != NULL)
delete m_pEnumInfo;
if(m_pCtx)
m_pCtx->Release();
if(m_bstrKeyName)
SysFreeString(m_bstrKeyName);
return;
}
//***************************************************************************
// HRESULT CEnumInst::QueryInterface
// long CEnumInst::AddRef
// long CEnumInst::Release
//
// DESCRIPTION:
//
// Standard Com IUNKNOWN functions.
//
//***************************************************************************
STDMETHODIMP CEnumInst::QueryInterface(
IN REFIID riid,
OUT PPVOID ppv)
{
*ppv=NULL;
if ((IID_IUnknown==riid || IID_IEnumWbemClassObject==riid)
&& m_pWBEMGateway != NULL)
{
*ppv=this;
AddRef();
return NOERROR;
}
else
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CEnumInst::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) CEnumInst::Release(void)
{
long lRet = InterlockedDecrement(&m_cRef);
if (0L!=lRet)
return lRet;
delete this;
return 0L;
}
//***************************************************************************
//
// CEnumInst::Reset
//
// DESCRIPTION:
//
// Sets pointer back to first element.
//
// RETURN VALUES:
//
// S_OK
//
//***************************************************************************
STDMETHODIMP CEnumInst::Reset()
{
m_iIndex = 0;
return S_OK;
}
//***************************************************************************
//
// CEnumInst::Clone
//
// DESCRIPTION:
//
// Create a duplicate of the enumerator
//
// PARAMETERS:
//
// pEnum Set to point to duplicate.
//
// RETURN VALUES:
//
// S_OK if all is well
// WBEM_E_OUT_OF_MEMORY if out of memory
// WBEM_E_INVALID_PARAMETER if passed a null
//
//***************************************************************************
STDMETHODIMP CEnumInst::Clone(
OUT IEnumWbemClassObject FAR* FAR* pEnum)
{
CEnumInst * pEnumObj;
SCODE sc;
if(pEnum == NULL)
return WBEM_E_INVALID_PARAMETER;
pEnumObj=new CEnumInst(m_pEnumInfo,m_lFlags,m_pwcClass,
m_pWBEMGateway,m_pProvider, m_pCtx);
if(pEnumObj == NULL)
return WBEM_E_OUT_OF_MEMORY;
sc = pEnumObj->QueryInterface(IID_IEnumWbemClassObject,(void **) pEnum);
if(FAILED(sc))
delete pEnumObj;
pEnumObj->m_iIndex = m_iIndex;
return S_OK;
}
//***************************************************************************
//
// CEnumInst::Skip
//
// DESCRIPTION:
//
// Skips one or more elements in the enumeration.
//
// PARAMETERS:
//
// nNum number of elements to skip
//
// RETURN VALUES:
//
// S_OK if we still are not past the end of the list
// S_FALSE if requested skip number would go beyond the end of the list
//
//***************************************************************************
STDMETHODIMP CEnumInst::Skip(long lTimeout,
IN ULONG nNum)
{
SCODE sc;;
int iTest = m_iIndex + nNum;
LPWSTR pwcKey;
sc = m_pProvider->GetKey(m_pEnumInfo,iTest,&pwcKey);
if(sc == S_OK) {
delete pwcKey;
m_iIndex = iTest;
return S_OK;
}
return S_FALSE;
}
//***************************************************************************
//
// CEnumInst::Next
//
// DESCRIPTION:
//
// Returns one or more instances.
//
// PARAMETERS:
//
// uCount Number of instances to return.
// pObj Pointer to array of objects.
// puReturned Pointer to number of objects successfully returned.
//
// RETURN VALUES:
// S_OK if all the request instances are returned. Note that WBEM_E_FAILED
// is returned even if there are some instances returned so long as the
// number is less than uCount. Also WBEM_E_INVALID_PARAMETER may be
// return if the arguments are bogus.
//
//***************************************************************************
STDMETHODIMP CEnumInst::Next(long lTimeout,
IN ULONG uCount,
OUT IWbemClassObject FAR* FAR* pObj,
OUT ULONG FAR* puReturned)
{
ULONG uIndex;
SCODE sc;
LPWSTR pwcKey;
if(pObj == NULL || puReturned == NULL)
return WBEM_E_INVALID_PARAMETER;
IWbemClassObject FAR* FAR* pNewInst = pObj;
*puReturned = 0;
for(uIndex = 0; uIndex < uCount; )
{
sc = m_pProvider->GetKey(m_pEnumInfo,m_iIndex,&pwcKey);
m_iIndex++;
if(sc != S_OK)
break; // if no more in registry, then we are done
sc = m_pProvider->CreateInst(m_pWBEMGateway,m_pwcClass,
pwcKey,pNewInst,m_bstrKeyName,
&m_PropContextCache, m_pCtx);
delete pwcKey;
if(sc == S_OK)
{
uIndex++;
pNewInst++;
(*puReturned)++; // add one to number of objects created
}
}
return (uIndex == uCount) ? S_OK : WBEM_E_FAILED;
}