//*************************************************************************** // // Copyright (c) 2000 Microsoft Corporation // // REFRESHER.CPP // // alanbos 20-Jan-00 Created. // // Defines the implementation of ISWbemRefresher and ISWbemRefreshableItem // //*************************************************************************** #include "precomp.h" //*************************************************************************** // // CSWbemRefresher::CSWbemRefresher // // DESCRIPTION: // // Constructor. // //*************************************************************************** CSWbemRefreshableItem::CSWbemRefreshableItem( ISWbemRefresher *pRefresher, long iIndex, IDispatch *pServices, IWbemClassObject *pObject, IWbemHiPerfEnum *pObjectSet ) : m_pISWbemRefresher (pRefresher), m_iIndex (iIndex), m_bIsSet (VARIANT_FALSE), m_pISWbemObjectEx (NULL), m_pISWbemObjectSet (NULL), m_cRef (0) { m_Dispatch.SetObj (this, IID_ISWbemRefreshableItem, CLSID_SWbemRefreshableItem, L"SWbemRefreshableItem"); // Note that we do NOT AddRef m_pISWbemRefresher. To do so would create // a circular reference between this object and the refresher, since the // refresher's map already holds a reference to this object. if (pServices) { CComQIPtr pISWbemInternalServices (pServices); if (pISWbemInternalServices) { CSWbemServices *pCSWbemServices = new CSWbemServices (pISWbemInternalServices); if (pCSWbemServices) pCSWbemServices->AddRef (); if (pObject) { // Create a new CSWbemObject for ourselves CSWbemObject *pCSWbemObject = new CSWbemObject (pCSWbemServices, pObject); if (pCSWbemObject){ if(FAILED(pCSWbemObject->QueryInterface (IID_ISWbemObjectEx, (void**) &m_pISWbemObjectEx))){ delete pCSWbemObject; } } } if (pObjectSet) { // Create a new CSWbemHiPerfObjectSet for ourselves CSWbemHiPerfObjectSet *pCSWbemHiPerfObjectSet = new CSWbemHiPerfObjectSet (pCSWbemServices, pObjectSet); if (pCSWbemHiPerfObjectSet) { if(SUCCEEDED(pCSWbemHiPerfObjectSet->QueryInterface (IID_ISWbemObjectSet, (void**) &m_pISWbemObjectSet))){ m_bIsSet = VARIANT_TRUE; } else { delete pCSWbemHiPerfObjectSet; } } } if (pCSWbemServices) pCSWbemServices->Release (); } } InterlockedIncrement(&g_cObj); } //*************************************************************************** // // CSWbemRefreshableItem::~CSWbemRefreshableItem // // DESCRIPTION: // // Destructor. // //*************************************************************************** CSWbemRefreshableItem::~CSWbemRefreshableItem(void) { InterlockedDecrement(&g_cObj); if (m_pISWbemObjectEx) { m_pISWbemObjectEx->Release (); m_pISWbemObjectEx = NULL; } if (m_pISWbemObjectSet) { m_pISWbemObjectSet->Release (); m_pISWbemObjectSet = NULL; } } //*************************************************************************** // HRESULT CSWbemRefreshableItem::QueryInterface // long CSWbemRefreshableItem::AddRef // long CSWbemRefreshableItem::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CSWbemRefreshableItem::QueryInterface ( IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL; if (IID_IUnknown==riid) *ppv = reinterpret_cast(this); else if (IID_ISWbemRefreshableItem==riid) *ppv = (ISWbemRefresher *)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) CSWbemRefreshableItem::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CSWbemRefreshableItem::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; } delete this; return 0; } //*************************************************************************** // // CSWbemRefresher::CSWbemRefresher // // DESCRIPTION: // // Constructor. // //*************************************************************************** CSWbemRefresher::CSWbemRefresher() : m_iCount (0), m_bAutoReconnect (VARIANT_TRUE), m_pIWbemConfigureRefresher (NULL), m_pIWbemRefresher (NULL), m_cRef (0) { m_Dispatch.SetObj (this, IID_ISWbemRefresher, CLSID_SWbemRefresher, L"SWbemRefresher"); InterlockedIncrement(&g_cObj); } //*************************************************************************** // // CSWbemRefresher::~CSWbemRefresher // // DESCRIPTION: // // Destructor. // //*************************************************************************** CSWbemRefresher::~CSWbemRefresher(void) { InterlockedDecrement(&g_cObj); // Remove all items from the refresher DeleteAll (); if (m_pIWbemConfigureRefresher) m_pIWbemConfigureRefresher->Release (); if (m_pIWbemRefresher) m_pIWbemRefresher->Release (); } //*************************************************************************** // HRESULT CSWbemRefresher::QueryInterface // long CSWbemRefresher::AddRef // long CSWbemRefresher::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CSWbemRefresher::QueryInterface ( IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL; if (IID_IUnknown==riid) *ppv = reinterpret_cast(this); else if (IID_ISWbemRefresher==riid) *ppv = (ISWbemRefresher *)this; else if (IID_IDispatch==riid) *ppv = (IDispatch *)this; else if (IID_IObjectSafety==riid) *ppv = (IObjectSafety *)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) CSWbemRefresher::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CSWbemRefresher::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; } delete this; return 0; } //*************************************************************************** // // SCODE CSWbemRefresher::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 CSWbemRefresher::get__NewEnum ( IUnknown **ppUnk ) { HRESULT hr = E_FAIL; ResetLastErrors (); if (NULL != ppUnk) { *ppUnk = NULL; CEnumRefresher *pEnumRefresher = new CEnumRefresher (this); if (!pEnumRefresher) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnumRefresher->QueryInterface (IID_IUnknown, (PPVOID) ppUnk))) delete pEnumRefresher; } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::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 CSWbemRefresher::get_Count ( long *plCount ) { HRESULT hr = E_FAIL; ResetLastErrors (); if (NULL != plCount) { *plCount = m_ObjectMap.size (); hr = S_OK; } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::Add // // DESCRIPTION: // // Add a single instance to the refresher // // PARAMETERS: // // pISWbemServicesEx the SWbemServicesEx to use // bsInstancePath the relative path of the instance // iFlags flags // pSWbemContext context // ppSWbemRefreshableItem addresses the SWbemRefreshableItem on successful return // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::Add ( ISWbemServicesEx *pISWbemServicesEx, BSTR bsInstancePath, long iFlags, IDispatch *pSWbemContext, ISWbemRefreshableItem **ppSWbemRefreshableItem ) { HRESULT hr = WBEM_E_FAILED; ResetLastErrors (); if ((NULL == ppSWbemRefreshableItem) || (NULL == pISWbemServicesEx) || (NULL == bsInstancePath)) hr = WBEM_E_INVALID_PARAMETER; else { // Extract the context CComPtr pIWbemContext; //Can't assign directly because the raw pointer gets AddRef'd twice and we leak, //So we use Attach() instead to prevent the smart pointer from AddRef'ing. pIWbemContext.Attach(CSWbemNamedValueSet::GetIWbemContext (pSWbemContext)); // Extract the IWbemServices CComPtr pIWbemServices; pIWbemServices.Attach( CSWbemServices::GetIWbemServices (pISWbemServicesEx)); if (pIWbemServices) { // Get our refresher - may need to create on demand if (NULL == m_pIWbemConfigureRefresher) CreateRefresher (); if (m_pIWbemConfigureRefresher) { IWbemClassObject *pObject = NULL; long iIndex = 0; if (SUCCEEDED(hr = m_pIWbemConfigureRefresher->AddObjectByPath (pIWbemServices, bsInstancePath, iFlags, pIWbemContext, &pObject, &iIndex))) { CSWbemRefreshableItem *pRefreshableItem = new CSWbemRefreshableItem (this, iIndex, pISWbemServicesEx, pObject, NULL); if (!pRefreshableItem) hr = WBEM_E_OUT_OF_MEMORY; else if (SUCCEEDED(hr =pRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem, (void**) ppSWbemRefreshableItem))) { m_ObjectMap [iIndex] = pRefreshableItem; pRefreshableItem->AddRef (); } else delete pRefreshableItem; } } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::AddEnum // // DESCRIPTION: // // Add a single enum (shallow instance) to the refresher // // PARAMETERS: // // pISWbemServicesEx the SWbemServicesEx to use // bsClassName the name of the class // iFlags flags // pSWbemContext context // ppSWbemRefreshableItem addresses the SWbemRefreshableItem on successful return // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::AddEnum ( ISWbemServicesEx *pISWbemServicesEx, BSTR bsClassName, long iFlags, IDispatch *pSWbemContext, ISWbemRefreshableItem **ppSWbemRefreshableItem ) { HRESULT hr = WBEM_E_FAILED; ResetLastErrors (); if ((NULL == ppSWbemRefreshableItem) || (NULL == pISWbemServicesEx) || (NULL == bsClassName)) hr = WBEM_E_INVALID_PARAMETER; else { // Extract the context CComPtr pIWbemContext; //Can't assign directly because the raw pointer gets AddRef'd twice and we leak, //So we use Attach() instead to prevent the smart pointer from AddRef'ing. pIWbemContext.Attach(CSWbemNamedValueSet::GetIWbemContext (pSWbemContext)); // Extract the IWbemServices CComPtr pIWbemServices; pIWbemServices.Attach( CSWbemServices::GetIWbemServices (pISWbemServicesEx)); if (pIWbemServices) { // Get our refresher - may need to create on demand if (NULL == m_pIWbemConfigureRefresher) CreateRefresher (); if (m_pIWbemConfigureRefresher) { IWbemHiPerfEnum *pIWbemHiPerfEnum = NULL; long iIndex = 0; if (SUCCEEDED(hr = m_pIWbemConfigureRefresher->AddEnum (pIWbemServices, bsClassName, iFlags, pIWbemContext, &pIWbemHiPerfEnum, &iIndex))) { CSWbemRefreshableItem *pRefreshableItem = new CSWbemRefreshableItem (this, iIndex, pISWbemServicesEx, NULL, pIWbemHiPerfEnum); if (!pRefreshableItem) hr = WBEM_E_OUT_OF_MEMORY; else if (SUCCEEDED(hr =pRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem, (void**) ppSWbemRefreshableItem))) { m_ObjectMap [iIndex] = pRefreshableItem; pRefreshableItem->AddRef (); } else delete pRefreshableItem; } } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::Remove // // DESCRIPTION: // // Remove object from refresher // // PARAMETERS: // // iIndex Index of object to retrieve // iFlags Flags // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::Remove ( long iIndex, long iFlags ) { HRESULT hr = WBEM_E_FAILED; ResetLastErrors (); if (m_pIWbemConfigureRefresher) { if (0 != iFlags) hr = WBEM_E_INVALID_PARAMETER; else { hr = m_pIWbemConfigureRefresher->Remove (iIndex, (VARIANT_TRUE == m_bAutoReconnect) ? WBEM_FLAG_REFRESH_AUTO_RECONNECT : WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT); if (WBEM_S_FALSE == hr) hr = WBEM_E_NOT_FOUND; if (SUCCEEDED(hr)) { // Now remove from our collection RefreshableItemMap::iterator theIterator = m_ObjectMap.find (iIndex); if (theIterator != m_ObjectMap.end ()) EraseItem (theIterator); } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::DeleteAll // // DESCRIPTION: // // Remove all items from refresher // // PARAMETERS: // // none // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::DeleteAll ( ) { ResetLastErrors (); RefreshableItemMap::iterator next; while ((next = m_ObjectMap.begin ()) != m_ObjectMap.end ()) { CSWbemRefreshableItem *pRefreshableItem = (*next).second; long iIndex = 0; if (m_pIWbemConfigureRefresher && pRefreshableItem && SUCCEEDED(pRefreshableItem->get_Index (&iIndex))) { HRESULT hr = m_pIWbemConfigureRefresher->Remove (iIndex, (VARIANT_TRUE == m_bAutoReconnect) ? WBEM_FLAG_REFRESH_AUTO_RECONNECT : WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT); } EraseItem (next); } return WBEM_S_NO_ERROR; } //*************************************************************************** // // SCODE CSWbemRefresher::Refresh // // DESCRIPTION: // // Refresh all objects in this refresher. // // PARAMETERS: // // lFlags Flags // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::Refresh ( long iFlags ) { HRESULT hr = WBEM_E_FAILED; ResetLastErrors (); if (0 != iFlags) hr = WBEM_E_INVALID_PARAMETER; else if (m_pIWbemRefresher) { hr = m_pIWbemRefresher->Refresh ((VARIANT_TRUE == m_bAutoReconnect) ? WBEM_FLAG_REFRESH_AUTO_RECONNECT : WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT); } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemRefresher::Item // // DESCRIPTION: // // Get object from the enumeration by index. // // PARAMETERS: // // iIndex Index of object to retrieve // lFlags Flags // ppSWbemRefreshableItem On successful return addresses the object // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_NOT_FOUND index out of range // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemRefresher::Item ( long iIndex, ISWbemRefreshableItem **ppSWbemRefreshableItem ) { HRESULT hr = WBEM_E_NOT_FOUND; ResetLastErrors (); if (NULL == ppSWbemRefreshableItem) hr = WBEM_E_INVALID_PARAMETER; else { *ppSWbemRefreshableItem = NULL; RefreshableItemMap::iterator theIterator; theIterator = m_ObjectMap.find (iIndex); if (theIterator != m_ObjectMap.end ()) { CSWbemRefreshableItem *pRefreshableItem = (*theIterator).second; if (SUCCEEDED(pRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem, (PPVOID) ppSWbemRefreshableItem))) { hr = WBEM_S_NO_ERROR; } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // void CSWbemRefresher::CreateRefresher // // DESCRIPTION: // // Create the underlying WMI refresher objects. // // PARAMETERS: // // none // // RETURN VALUES: // // none //*************************************************************************** void CSWbemRefresher::CreateRefresher () { HRESULT hr; if (NULL == m_pIWbemRefresher) { if (SUCCEEDED(hr = CoCreateInstance( CLSID_WbemRefresher, NULL, CLSCTX_INPROC_SERVER, IID_IWbemRefresher, (void**) &m_pIWbemRefresher ))) { IWbemConfigureRefresher *pConfigureRefresher = NULL; // Get ourselves a refresher configurator hr = m_pIWbemRefresher->QueryInterface (IID_IWbemConfigureRefresher, (void**) &m_pIWbemConfigureRefresher); } } } //*************************************************************************** // // void CSWbemRefresher::EraseItem // // DESCRIPTION: // // Scrub out an item. // // PARAMETERS: // // none // // RETURN VALUES: // // none //*************************************************************************** void CSWbemRefresher::EraseItem (RefreshableItemMap::iterator iterator) { CSWbemRefreshableItem *pRefresherObject = (*iterator).second; // Remove from the map m_ObjectMap.erase (iterator); // Ensure the item is unhooked from the parent. pRefresherObject->UnhookRefresher (); // Release the item as it is no longer in the map pRefresherObject->Release (); } // CEnumRefresher Methods //*************************************************************************** // // CEnumRefresher::CEnumRefresher // // DESCRIPTION: // // Constructor. // //*************************************************************************** CEnumRefresher::CEnumRefresher(CSWbemRefresher *pRefresher) { m_cRef=0; m_pCSWbemRefresher = pRefresher; m_pCSWbemRefresher->AddRef (); m_Iterator = m_pCSWbemRefresher->m_ObjectMap.begin (); InterlockedIncrement(&g_cObj); } CEnumRefresher::CEnumRefresher(CSWbemRefresher *pRefresher, RefreshableItemMap::iterator iterator) : m_Iterator (iterator) { m_cRef=0; m_pCSWbemRefresher = pRefresher; m_pCSWbemRefresher->AddRef (); InterlockedIncrement(&g_cObj); } //*************************************************************************** // // CEnumRefresher::~CEnumRefresher // // DESCRIPTION: // // Destructor. // //*************************************************************************** CEnumRefresher::~CEnumRefresher(void) { InterlockedDecrement(&g_cObj); if (m_pCSWbemRefresher) m_pCSWbemRefresher->Release (); } //*************************************************************************** // HRESULT CEnumRefresher::QueryInterface // long CEnumRefresher::AddRef // long CEnumRefresher::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CEnumRefresher::QueryInterface ( IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL; if (IID_IUnknown==riid || IID_IEnumVARIANT==riid) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return ResultFromScode(E_NOINTERFACE); } STDMETHODIMP_(ULONG) CEnumRefresher::AddRef(void) { long l = InterlockedIncrement(&m_cRef); return l; } STDMETHODIMP_(ULONG) CEnumRefresher::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; } delete this; return 0; } //*************************************************************************** // // SCODE CEnumRefresher::Reset // // DESCRIPTION: // // Reset the enumeration // // PARAMETERS: // // RETURN VALUES: // // S_OK success // S_FALSE otherwise // //*************************************************************************** HRESULT CEnumRefresher::Reset () { HRESULT hr = S_FALSE; m_Iterator = m_pCSWbemRefresher->m_ObjectMap.begin (); return hr; } //*************************************************************************** // // SCODE CEnumRefresher::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: // // S_OK success // S_FALSE not all elements could be returned // //*************************************************************************** HRESULT CEnumRefresher::Next ( ULONG cElements, VARIANT FAR* pVar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK; ULONG l2 = 0; if (NULL != pcElementFetched) *pcElementFetched = 0; if ((NULL != pVar) && (m_pCSWbemRefresher)) { for (ULONG l = 0; l < cElements; l++) VariantInit (&pVar [l]); // Retrieve the next cElements elements. for (l2 = 0; l2 < cElements; l2++) { if (m_Iterator != m_pCSWbemRefresher->m_ObjectMap.end ()) { CSWbemRefreshableItem *pCSWbemRefreshableItem = (*m_Iterator).second; m_Iterator++; ISWbemRefreshableItem *pISWbemRefreshableItem = NULL; if (SUCCEEDED(pCSWbemRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem, (PPVOID) &pISWbemRefreshableItem))) { // Set the object into the variant array; note that pObject // has been addref'd as a result of the QI() call above pVar[l2].vt = VT_DISPATCH; pVar[l2].pdispVal = pISWbemRefreshableItem; } } else break; } if (NULL != pcElementFetched) *pcElementFetched = l2; } if (FAILED(hr)) return hr; return (l2 < cElements) ? S_FALSE : S_OK; } //*************************************************************************** // // SCODE CEnumRefresher::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 CEnumRefresher::Clone ( IEnumVARIANT **ppEnum ) { HRESULT hr = E_FAIL; if (NULL != ppEnum) { *ppEnum = NULL; if (m_pCSWbemRefresher) { CEnumRefresher *pEnum = new CEnumRefresher (m_pCSWbemRefresher, m_Iterator); if (!pEnum) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnum->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum))) delete pEnum;; } } return hr; } //*************************************************************************** // // SCODE CEnumRefresher::Skip // // DESCRIPTION: // // Skip specified number of elements // // PARAMETERS: // // ppEnum on successful return addresses the clone // // RETURN VALUES: // // S_OK success // S_FALSE end of sequence reached prematurely // //*************************************************************************** HRESULT CEnumRefresher::Skip( ULONG cElements ) { HRESULT hr = S_FALSE; if (m_pCSWbemRefresher) { ULONG l2; // Retrieve the next cElements elements. for (l2 = 0; l2 < cElements; l2++) { if (m_Iterator != m_pCSWbemRefresher->m_ObjectMap.end ()) m_Iterator++; else break; } if (l2 == cElements) hr = S_OK; } return hr; } // CSWbemHiPerfObjectSet methods //*************************************************************************** // // CSWbemHiPerfObjectSet::CSWbemHiPerfObjectSet // // DESCRIPTION: // // Constructor. // //*************************************************************************** CSWbemHiPerfObjectSet::CSWbemHiPerfObjectSet(CSWbemServices *pService, IWbemHiPerfEnum *pIWbemHiPerfEnum) : m_SecurityInfo (NULL), m_pSWbemServices (pService), m_pIWbemHiPerfEnum (pIWbemHiPerfEnum), m_cRef (0) { m_Dispatch.SetObj (this, IID_ISWbemObjectSet, CLSID_SWbemObjectSet, L"SWbemObjectSet"); if (m_pIWbemHiPerfEnum) m_pIWbemHiPerfEnum->AddRef (); if (m_pSWbemServices) { m_pSWbemServices->AddRef (); // Use the SWbemServices security object here since // IWbemHiPerfEnum is not a remote interface CSWbemSecurity *pSecurity = m_pSWbemServices->GetSecurityInfo (); m_SecurityInfo = new CSWbemSecurity (pSecurity); if (pSecurity) pSecurity->Release (); } InterlockedIncrement(&g_cObj); } //*************************************************************************** // // CSWbemHiPerfObjectSet::~CSWbemHiPerfObjectSet // // DESCRIPTION: // // Destructor. // //*************************************************************************** CSWbemHiPerfObjectSet::~CSWbemHiPerfObjectSet(void) { InterlockedDecrement(&g_cObj); if (m_pSWbemServices) m_pSWbemServices->Release (); if (m_SecurityInfo) m_SecurityInfo->Release (); if (m_pIWbemHiPerfEnum) m_pIWbemHiPerfEnum->Release (); } //*************************************************************************** // HRESULT CSWbemHiPerfObjectSet::QueryInterface // long CSWbemHiPerfObjectSet::AddRef // long CSWbemHiPerfObjectSet::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CSWbemHiPerfObjectSet::QueryInterface ( IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL; if (IID_IUnknown==riid) *ppv = reinterpret_cast(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) CSWbemHiPerfObjectSet::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CSWbemHiPerfObjectSet::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; } delete this; return 0; } //*************************************************************************** // // SCODE CSWbemHiPerfObjectSet::ReadObjects // // DESCRIPTION: // // Gets the objects out of the enumerator // // PARAMETERS: // // RETURN VALUES: // // WBEM_S_NO_ERROR success // WBEM_E_FAILED otherwise // //*************************************************************************** // Bug Id 566345 HRESULT CSWbemHiPerfObjectSet::ReadObjects (unsigned long & iCount , IWbemObjectAccess ***ppIWbemObjectAccess) { *ppIWbemObjectAccess = NULL; iCount = 0; HRESULT hr = WBEM_E_FAILED; if (m_pIWbemHiPerfEnum) { // Start by getting the object count if (WBEM_E_BUFFER_TOO_SMALL == (hr = m_pIWbemHiPerfEnum->GetObjects (0L, 0L, NULL, &iCount))) { hr = S_OK; if(iCount > 0) { *ppIWbemObjectAccess = new IWbemObjectAccess*[iCount]; if (*ppIWbemObjectAccess) { ZeroMemory( *ppIWbemObjectAccess, iCount * sizeof(IWbemObjectAccess*) ); unsigned long dummy = 0; hr = m_pIWbemHiPerfEnum->GetObjects ( 0L, iCount, *ppIWbemObjectAccess, &dummy ); if(FAILED(hr)) { delete [] (*ppIWbemObjectAccess); *ppIWbemObjectAccess = NULL; iCount = 0; } } else { hr = E_OUTOFMEMORY; } } } } return hr; } //*************************************************************************** // // SCODE CSWbemHiPerfObjectSet::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 CSWbemHiPerfObjectSet::get__NewEnum ( IUnknown **ppUnk ) { HRESULT hr = E_FAIL; ResetLastErrors (); if (NULL != ppUnk) { *ppUnk = NULL; CEnumVarHiPerf *pEnumVar = new CEnumVarHiPerf (this); if (!pEnumVar) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnumVar->QueryInterface (IID_IUnknown, (PPVOID) ppUnk))) delete pEnumVar; } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemHiPerfObjectSet::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 CSWbemHiPerfObjectSet::get_Count ( long *plCount ) { HRESULT hr = E_FAIL; *plCount = 0; ResetLastErrors (); if (NULL == plCount) hr = WBEM_E_INVALID_PARAMETER; else { unsigned long iCount = 0; IWbemObjectAccess **ppIWbemObjectAccess = NULL; hr = ReadObjects (iCount,&ppIWbemObjectAccess); if(SUCCEEDED(hr)) // Bug Id 566345 { *plCount = iCount; hr = WBEM_S_NO_ERROR; if(ppIWbemObjectAccess) delete [] ppIWbemObjectAccess; } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemHiPerfObjectSet::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 CSWbemHiPerfObjectSet::Item ( BSTR bsObjectPath, long lFlags, ISWbemObject **ppObject ) { HRESULT hr = WBEM_E_FAILED; ResetLastErrors (); if ((NULL == ppObject) || (NULL == bsObjectPath)) hr = WBEM_E_INVALID_PARAMETER; else { CWbemPathCracker objectPath; if (objectPath = bsObjectPath) { unsigned long iCount = 0; IWbemObjectAccess **ppIWbemObjectAccess = NULL; hr = ReadObjects (iCount,&ppIWbemObjectAccess); if(SUCCEEDED(hr)) // Bug Id 566345 { bool found = false; for (unsigned long i = 0; !found && (i < iCount); i++) { CComPtr pIWbemClassObject; hr = WBEM_E_NOT_FOUND; // Iterate through the enumerator to try to find the element with the // specified path. if (SUCCEEDED(ppIWbemObjectAccess [i]->QueryInterface (IID_IWbemClassObject, (void**) &pIWbemClassObject))) { 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; } } } } if (found) hr = S_OK; if (ppIWbemObjectAccess) delete [] ppIWbemObjectAccess; } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr); return hr; } //*************************************************************************** // // SCODE CSWbemHiPerfObjectSet::get_Security_ // // DESCRIPTION: // // Return the security configurator // // WBEM_S_NO_ERROR success // WBEM_E_INVALID_PARAMETER bad input parameters // WBEM_E_FAILED otherwise // //*************************************************************************** HRESULT CSWbemHiPerfObjectSet::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; } // CEnumVarHiPerfHiPerf methods //*************************************************************************** // // CEnumVarHiPerf::CEnumVarHiPerf // // DESCRIPTION: // // Constructor. // //*************************************************************************** CEnumVarHiPerf::CEnumVarHiPerf(CSWbemHiPerfObjectSet *pCSWbemHiPerfObjectSet) : m_cRef (0), m_iCount (0), m_iPos (0), m_ppIWbemObjectAccess (NULL), m_pCSWbemHiPerfObjectSet (NULL) { if (pCSWbemHiPerfObjectSet) { m_pCSWbemHiPerfObjectSet = pCSWbemHiPerfObjectSet; m_pCSWbemHiPerfObjectSet->AddRef (); HRESULT hr = pCSWbemHiPerfObjectSet->ReadObjects (m_iCount,&m_ppIWbemObjectAccess); } InterlockedIncrement(&g_cObj); } //*************************************************************************** // // CEnumVarHiPerf::~CEnumVarHiPerf // // DESCRIPTION: // // Destructor. // //*************************************************************************** CEnumVarHiPerf::~CEnumVarHiPerf(void) { InterlockedDecrement(&g_cObj); if (m_pCSWbemHiPerfObjectSet) m_pCSWbemHiPerfObjectSet->Release (); if (m_ppIWbemObjectAccess) delete [] m_ppIWbemObjectAccess; } //*************************************************************************** // HRESULT CEnumVarHiPerf::QueryInterface // long CEnumVarHiPerf::AddRef // long CEnumVarHiPerf::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CEnumVarHiPerf::QueryInterface ( IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL; if (IID_IUnknown==riid || IID_IEnumVARIANT==riid) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return ResultFromScode(E_NOINTERFACE); } STDMETHODIMP_(ULONG) CEnumVarHiPerf::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CEnumVarHiPerf::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; } delete this; return 0; } //*************************************************************************** // // SCODE CEnumVarHiPerf::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: // // S_OK success // S_FALSE not all elements could be returned // //*************************************************************************** HRESULT CEnumVarHiPerf::Next ( ULONG cElements, VARIANT FAR* pVar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK; ULONG l2 = 0; if (NULL != pcElementFetched) *pcElementFetched = 0; if (NULL != pVar) { for (ULONG l = 0; l < cElements; l++) VariantInit (&pVar [l]); // Retrieve the next cElements elements. for (l2 = 0; l2 < cElements; l2++) { CComPtr pIWbemClassObject; if (m_iPos < m_iCount) { if (SUCCEEDED(hr = m_ppIWbemObjectAccess [m_iPos]->QueryInterface (IID_IWbemClassObject, (void**) &pIWbemClassObject))) { m_iPos++; // Make a new ISWbemObjectEx CSWbemObject *pCSWbemObject = new CSWbemObject (m_pCSWbemHiPerfObjectSet->GetSWbemServices (), pIWbemClassObject); ISWbemObjectEx *pISWbemObjectEx = NULL; if (!pCSWbemObject) hr = WBEM_E_OUT_OF_MEMORY; else if (SUCCEEDED(hr = pCSWbemObject->QueryInterface (IID_ISWbemObjectEx, (PPVOID) &pISWbemObjectEx))) { // Set the object into the variant array pVar[l2].vt = VT_DISPATCH; pVar[l2].pdispVal = pISWbemObjectEx; } else { delete pCSWbemObject; hr = WBEM_E_FAILED; } } if (FAILED(hr)) break; } else break; // No more elements } if (NULL != pcElementFetched) *pcElementFetched = l2; SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ()); } if (FAILED(hr)) return hr; return (l2 < cElements) ? S_FALSE : S_OK; } //*************************************************************************** // // SCODE CEnumVarHiPerf::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 CEnumVarHiPerf::Clone ( IEnumVARIANT **ppEnum ) { HRESULT hr = E_FAIL; if (NULL != ppEnum) { *ppEnum = NULL; CEnumVarHiPerf *pEnumVar = new CEnumVarHiPerf (m_pCSWbemHiPerfObjectSet); if (!pEnumVar) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnumVar->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum))) delete pEnumVar; SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ()); } return hr; } //*************************************************************************** // // SCODE CEnumVarHiPerf::Skip // // DESCRIPTION: // // Create a copy of this enumeration // // PARAMETERS: // // ppEnum on successful return addresses the clone // // RETURN VALUES: // // S_OK success // S_FALSE end of sequence reached prematurely // //*************************************************************************** HRESULT CEnumVarHiPerf::Skip( ULONG cElements ) { HRESULT hr = S_FALSE; if (m_iPos + cElements > m_iCount) m_iPos = m_iCount; else { m_iPos += cElements; hr = S_OK; } SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ()); return hr; }