|
|
//***************************************************************************
//
// Copyright (c) 1998-1999 Microsoft Corporation
//
// ENUMOBJ.CPP
//
// alanbos 15-Aug-96 Created.
//
// Defines the implementation of ISWbemObjectSet
//
//***************************************************************************
#include "precomp.h"
//***************************************************************************
//
// CSWbemObjectSet::CSWbemObjectSet
//
// DESCRIPTION:
//
// Constructor.
//
//***************************************************************************
CSWbemObjectSet::CSWbemObjectSet(CSWbemServices *pService, IEnumWbemClassObject *pIEnumWbemClassObject, CSWbemSecurity *pSecurity) : m_SecurityInfo (NULL), m_bIsEmpty (false) { m_Dispatch.SetObj (this, IID_ISWbemObjectSet, CLSID_SWbemObjectSet, L"SWbemObjectSet"); m_cRef=0; m_firstEnumerator = true; m_pSWbemServices = pService;
if (m_pSWbemServices) { m_pSWbemServices->AddRef ();
if (pSecurity) m_SecurityInfo = new CSWbemSecurity (pIEnumWbemClassObject, pSecurity); else { pSecurity = m_pSWbemServices->GetSecurityInfo (); m_SecurityInfo = new CSWbemSecurity (pIEnumWbemClassObject, pSecurity);
if (pSecurity) pSecurity->Release (); } }
InterlockedIncrement(&g_cObj); }
CSWbemObjectSet::CSWbemObjectSet (void) : m_SecurityInfo (NULL), m_cRef (0), m_firstEnumerator (true), m_bIsEmpty (true), m_pSWbemServices (NULL) { m_Dispatch.SetObj (this, IID_ISWbemObjectSet, CLSID_SWbemObjectSet, L"SWbemObjectSet"); InterlockedIncrement(&g_cObj); }
//***************************************************************************
//
// CSWbemObjectSet::~CSWbemObjectSet
//
// DESCRIPTION:
//
// Destructor.
//
//***************************************************************************
CSWbemObjectSet::~CSWbemObjectSet(void) { InterlockedDecrement(&g_cObj);
RELEASEANDNULL(m_pSWbemServices) RELEASEANDNULL(m_SecurityInfo) }
//***************************************************************************
// HRESULT CSWbemObjectSet::QueryInterface
// long CSWbemObjectSet::AddRef
// long CSWbemObjectSet::Release
//
// DESCRIPTION:
//
// Standard Com IUNKNOWN functions.
//
//***************************************************************************
STDMETHODIMP CSWbemObjectSet::QueryInterface (
IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL;
if (IID_IUnknown==riid) *ppv = reinterpret_cast<IUnknown*>(this); else if (IID_ISWbemObjectSet==riid) *ppv = (ISWbemObjectSet *)this; else if (IID_IDispatch==riid) *ppv = (IDispatch *)this; else if (IID_ISupportErrorInfo==riid) *ppv = (ISupportErrorInfo *)this; else if (IID_IProvideClassInfo==riid) *ppv = (IProvideClassInfo *)this;
if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; }
return ResultFromScode(E_NOINTERFACE); }
STDMETHODIMP_(ULONG) CSWbemObjectSet::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; }
STDMETHODIMP_(ULONG) CSWbemObjectSet::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; }
delete this; return 0; }
//***************************************************************************
// HRESULT CSWbemObjectSet::InterfaceSupportsErrorInfo
//
// DESCRIPTION:
//
// Standard Com ISupportErrorInfo functions.
//
//***************************************************************************
STDMETHODIMP CSWbemObjectSet::InterfaceSupportsErrorInfo (IN REFIID riid) { return (IID_ISWbemObjectSet == riid) ? S_OK : S_FALSE; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::Reset
//
// DESCRIPTION:
//
// Reset the enumeration
//
// PARAMETERS:
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::Reset () { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) hr = pIEnumWbemClassObject->Reset ();
pIEnumWbemClassObject->Release ();
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken); } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::Next
//
// DESCRIPTION:
//
// Get the next object in the enumeration
//
// PARAMETERS:
//
// lTimeout Number of ms to wait for object (or WBEM_INFINITE for
// indefinite)
// ppObject On return may contain the next element (if any)
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::Next ( long lTimeout, ISWbemObject **ppObject ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppObject) hr = WBEM_E_INVALID_PARAMETER; else if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { *ppObject = NULL;
IWbemClassObject *pIWbemClassObject = NULL; ULONG returned = 0;
bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) hr = pIEnumWbemClassObject->Next (lTimeout, 1, &pIWbemClassObject, &returned);
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken);
if (SUCCEEDED(hr) && (0 < returned) && pIWbemClassObject) { CSWbemObject *pObject = new CSWbemObject (m_pSWbemServices, pIWbemClassObject, m_SecurityInfo);
if (!pObject) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pObject->QueryInterface (IID_ISWbemObject, (PPVOID) ppObject))) delete pObject;
pIWbemClassObject->Release (); } else if (WBEM_S_TIMEDOUT == hr) { /*
* Since a timeout would be indistinguishable from an end-of-enumeration * we flag it as a real error rather than an S-CODE. */ hr = wbemErrTimedout; }
SetWbemError (m_pSWbemServices); pIEnumWbemClassObject->Release (); } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::Clone
//
// DESCRIPTION:
//
// Create a copy of this enumeration
//
// PARAMETERS:
//
// ppEnum on successful return addresses the clone
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::Clone ( ISWbemObjectSet **ppEnum ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppEnum) hr = WBEM_E_INVALID_PARAMETER; else if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { *ppEnum = NULL; IEnumWbemClassObject *pIWbemEnum = NULL;
bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) hr = pIEnumWbemClassObject->Clone (&pIWbemEnum);
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken);
if (WBEM_S_NO_ERROR == hr) { CSWbemObjectSet *pEnum = new CSWbemObjectSet (m_pSWbemServices, pIWbemEnum, m_SecurityInfo);
if (!pEnum) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnum->QueryInterface (IID_ISWbemObjectSet, (PPVOID) ppEnum))) delete pEnum;
pIWbemEnum->Release (); } SetWbemError (m_pSWbemServices); pIEnumWbemClassObject->Release (); } } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::Skip
//
// DESCRIPTION:
//
// Skip over some objects in the enumeration
//
// PARAMETERS:
//
// lElements Number of elements to skip
// lTimeout Number of ms to wait for object (or WBEM_INFINITE for
// indefinite)
//
// RETURN VALUES:
//
// S_OK success
// S_FALSE otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::Skip ( ULONG lElements, long lTimeout ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) hr = pIEnumWbemClassObject->Skip (lTimeout, lElements);
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken);
/*
* Since a timeout would be indistinguishable from an end-of-enumeration * we flag it as a real error rather than an S-CODE. */ if (WBEM_S_TIMEDOUT == hr) hr = wbemErrTimedout;
SetWbemError (m_pSWbemServices); pIEnumWbemClassObject->Release (); } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; } //***************************************************************************
//
// SCODE CSWbemObjectSet::get__NewEnum
//
// DESCRIPTION:
//
// Return an IEnumVARIANT-supporting interface for collections
//
// PARAMETERS:
//
// ppUnk on successful return addresses the IUnknown interface
//
// RETURN VALUES:
//
// S_OK success
// E_FAIL otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::get__NewEnum ( IUnknown **ppUnk ) { HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != ppUnk) { *ppUnk = NULL; CEnumVar *pEnumVar = NULL;
if (m_bIsEmpty) { if (!(pEnumVar = new CEnumVar ())) hr = WBEM_E_OUT_OF_MEMORY; } else { /*
* If this is the first enumerator, use ourselves as the underlying * iterator. Otherwise clone a copy and use that. */
if (m_firstEnumerator) { if (!(pEnumVar = new CEnumVar (this))) hr = WBEM_E_OUT_OF_MEMORY; else m_firstEnumerator = false; } else { CSWbemObjectSet *pNewEnum = NULL;
/*
* Try to reset the cloned enumerator. This may not always * succeed, as some IEnumWbemClassObject's may not be * rewindable. */ if (SUCCEEDED (CloneObjectSet (&pNewEnum))) { HRESULT hr2 = pNewEnum->Reset (); if (!(pEnumVar = new CEnumVar (pNewEnum))) hr = WBEM_E_OUT_OF_MEMORY; pNewEnum->Release (); } } }
if (pEnumVar) if (FAILED(hr = pEnumVar->QueryInterface (IID_IUnknown, (PPVOID) ppUnk))) delete pEnumVar; }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::get_Count
//
// DESCRIPTION:
//
// Return the number of items in the collection
//
// PARAMETERS:
//
// plCount on successful return addresses the count
//
// RETURN VALUES:
//
// S_OK success
// E_FAIL otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::get_Count ( long *plCount ) { HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != plCount) { *plCount = 0;
if (m_bIsEmpty) hr = WBEM_S_NO_ERROR; else if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { /*
* Work out the current count - clone the object to avoid messing * with the iterator. */
IEnumWbemClassObject *pNewEnum = NULL;
bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) { if (WBEM_S_NO_ERROR == pIEnumWbemClassObject->Clone (&pNewEnum)) { // Secure the enumerator
m_SecurityInfo->SecureInterface (pNewEnum);
/*
* This will fail if the enumerator was created with the * WBEM_FLAG_FORWARD_ONLY option. */
if (WBEM_S_NO_ERROR == pNewEnum->Reset ()) { IWbemClassObject *pObject = NULL; ULONG lReturned = 0; HRESULT hrEnum; // Iterate through the enumerator to count the elements
while (SUCCEEDED(hrEnum = pNewEnum->Next (INFINITE, 1, &pObject, &lReturned))) { if (0 == lReturned) break; // We are done
// Getting here means we have at least one object returned
(*plCount) ++; pObject->Release (); }
if (SUCCEEDED(hrEnum)) hr = S_OK; else hr = hrEnum; }
pNewEnum->Release (); } }
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken);
pIEnumWbemClassObject->Release (); } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; } //***************************************************************************
//
// SCODE CSWbemObjectSet::Item
//
// DESCRIPTION:
//
// Get object from the enumeration by path.
//
// PARAMETERS:
//
// bsObjectPath The path of the object to retrieve
// lFlags Flags
// ppNamedObject On successful return addresses the object
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::Item ( BSTR bsObjectPath, long lFlags, ISWbemObject **ppObject ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if ((NULL == ppObject) || (NULL == bsObjectPath)) hr = WBEM_E_INVALID_PARAMETER; else if (!m_bIsEmpty) { CWbemPathCracker objectPath;
if (objectPath = bsObjectPath) { if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { /*
* Try to find the object - clone the object to avoid messing * with the iterator. */ IEnumWbemClassObject *pNewEnum = NULL;
bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) { if (WBEM_S_NO_ERROR == pIEnumWbemClassObject->Clone (&pNewEnum)) { // Secure the enumerator
m_SecurityInfo->SecureInterface (pNewEnum);
/*
* This will fail if the enumerator was created with the * WBEM_FLAG_FORWARD_ONLY option. */
if (WBEM_S_NO_ERROR == pNewEnum->Reset ()) { CComPtr<IWbemClassObject> pIWbemClassObject; ULONG lReturned = 0; bool found = false; hr = WBEM_E_NOT_FOUND; // Iterate through the enumerator to try to find the element with the
// specified path.
while (!found && (WBEM_S_NO_ERROR == pNewEnum->Next (INFINITE, 1, &pIWbemClassObject, &lReturned))) { // Getting here means we have at least one object returned; check the
// path
if (CSWbemObjectPath::CompareObjectPaths (pIWbemClassObject, objectPath)) { // Found it - assign to passed interface and break out
found = true; CSWbemObject *pObject = new CSWbemObject (m_pSWbemServices, pIWbemClassObject, m_SecurityInfo);
if (!pObject) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(pObject->QueryInterface (IID_ISWbemObject, (PPVOID) ppObject))) { hr = WBEM_E_FAILED; delete pObject; } }
pIWbemClassObject.Release();
}
if (found) hr = S_OK; } pNewEnum->Release (); } }
// Restore original privileges on this thread
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken);
pIEnumWbemClassObject->Release (); } } } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::get_Security_
//
// DESCRIPTION:
//
// Return the security configurator
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::get_Security_ ( ISWbemSecurity **ppSecurity ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppSecurity) hr = WBEM_E_INVALID_PARAMETER; else // Bug ID 566345
{ *ppSecurity = NULL;
if (m_SecurityInfo) { *ppSecurity = m_SecurityInfo; (*ppSecurity)->AddRef (); hr = WBEM_S_NO_ERROR; } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; }
//***************************************************************************
//
// SCODE CSWbemObjectSet::CloneObjectSet
//
// DESCRIPTION:
//
// Create a copy of this enumeration, returning a coclass not an interface
//
// PARAMETERS:
//
// ppEnum on successful return addresses the clone
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemObjectSet::CloneObjectSet ( CSWbemObjectSet **ppEnum ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppEnum) hr = WBEM_E_INVALID_PARAMETER; else { *ppEnum = NULL;
if (m_SecurityInfo) { IEnumWbemClassObject *pIEnumWbemClassObject = (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
if (pIEnumWbemClassObject) { IEnumWbemClassObject *pIWbemEnum = NULL;
bool needToResetSecurity = false; HANDLE hThreadToken = NULL; if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken)) hr = pIEnumWbemClassObject->Clone (&pIWbemEnum);
if (needToResetSecurity) m_SecurityInfo->ResetSecurity (hThreadToken); if (WBEM_S_NO_ERROR == hr) { *ppEnum = new CSWbemObjectSet (m_pSWbemServices, pIWbemEnum, m_SecurityInfo);
if (!(*ppEnum)) hr = WBEM_E_OUT_OF_MEMORY; else (*ppEnum)->AddRef ();
pIWbemEnum->Release (); }
SetWbemError (m_pSWbemServices);
pIEnumWbemClassObject->Release (); } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
|