|
|
//***************************************************************************
//
// Copyright (c) 1998-1999 Microsoft Corporation
//
// QUALSET.CPP
//
// alanbos 15-Aug-96 Created.
//
// Defines the implementation of ISWbemQualifierSet
//
//***************************************************************************
#include "precomp.h"
//***************************************************************************
//
// CSWbemQualifierSet::CSWbemQualifierSet
//
// DESCRIPTION:
//
// Constructor.
//
//***************************************************************************
CSWbemQualifierSet::CSWbemQualifierSet(IWbemQualifierSet *pQualSet, ISWbemInternalObject *pSWbemObject) : m_pSite (NULL) { m_Dispatch.SetObj (this, IID_ISWbemQualifierSet, CLSID_SWbemQualifierSet, L"SWbemQualifierSet"); m_pIWbemQualifierSet = pQualSet; m_pIWbemQualifierSet->AddRef ();
if (pSWbemObject) m_pSite = new CWbemObjectSite (pSWbemObject);
m_cRef=1; InterlockedIncrement(&g_cObj); }
//***************************************************************************
//
// CSWbemQualifierSet::~CSWbemQualifierSet
//
// DESCRIPTION:
//
// Destructor.
//
//***************************************************************************
CSWbemQualifierSet::~CSWbemQualifierSet() { InterlockedDecrement(&g_cObj);
if (m_pIWbemQualifierSet) { m_pIWbemQualifierSet->EndEnumeration (); m_pIWbemQualifierSet->Release (); }
if (m_pSite) m_pSite->Release (); }
//***************************************************************************
// HRESULT CSWbemQualifierSet::QueryInterface
// long CSWbemQualifierSet::AddRef
// long CSWbemQualifierSet::Release
//
// DESCRIPTION:
//
// Standard Com IUNKNOWN functions.
//
//***************************************************************************
STDMETHODIMP CSWbemQualifierSet::QueryInterface (
IN REFIID riid, OUT LPVOID *ppv ) { *ppv=NULL;
if (IID_IUnknown==riid) *ppv = reinterpret_cast<IUnknown*>(this); else if (IID_ISWbemQualifierSet==riid) *ppv = (ISWbemQualifierSet *)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) CSWbemQualifierSet::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; }
STDMETHODIMP_(ULONG) CSWbemQualifierSet::Release(void) { LONG cRef = InterlockedDecrement(&m_cRef); if (0 != cRef) { _ASSERT(cRef > 0); return cRef; }
delete this; return 0; }
//***************************************************************************
// HRESULT CSWbemQualifierSet::InterfaceSupportsErrorInfo
//
// DESCRIPTION:
//
// Standard Com ISupportErrorInfo functions.
//
//***************************************************************************
STDMETHODIMP CSWbemQualifierSet::InterfaceSupportsErrorInfo (IN REFIID riid) { return (IID_ISWbemQualifierSet == riid) ? S_OK : S_FALSE; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::Item
//
// DESCRIPTION:
//
// Get a qualifier
//
// PARAMETERS:
//
// bsName The name of the qualifier
// lFlags Flags
// ppQual On successful return addresses the ISWbemQualifier
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
// Other WBEM error codes may be returned by ConnectServer etc., in which
// case these are passed on to the caller.
//
//***************************************************************************
HRESULT CSWbemQualifierSet::Item ( BSTR bsName, long lFlags, ISWbemQualifier ** ppQual ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppQual) hr = WBEM_E_INVALID_PARAMETER; else if (m_pIWbemQualifierSet) { if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (bsName, lFlags, NULL, NULL))) { if (!(*ppQual = new CSWbemQualifier (m_pIWbemQualifierSet, bsName, m_pSite))) hr = WBEM_E_OUT_OF_MEMORY; } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::Add
//
// DESCRIPTION:
//
// Put a qualifier
//
// PARAMETERS:
//
// bsName The name of the qualifier
// pVal Pointer to new value
// flavor Flavor
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::Add ( BSTR bsName, VARIANT *pVal, VARIANT_BOOL propagatesToSubclasses, VARIANT_BOOL propagatesToInstances, VARIANT_BOOL overridable, long lFlags, ISWbemQualifier **ppQualifier ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if ((NULL == pVal) || (NULL == ppQualifier)) hr = WBEM_E_INVALID_PARAMETER; else if (m_pIWbemQualifierSet) { long flavor = 0;
if (propagatesToSubclasses) flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
if (propagatesToInstances) flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
if (!overridable) flavor |= WBEM_FLAVOR_NOT_OVERRIDABLE;
// Make sure we have a decent qualifier value to use
if(((VT_ARRAY | VT_VARIANT) == V_VT(pVal)) || ((VT_ARRAY | VT_VARIANT | VT_BYREF) == V_VT(pVal))) { VARIANT vTemp; VariantInit (&vTemp);
if (S_OK == ConvertArray(&vTemp, pVal, TRUE)) hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor); VariantClear(&vTemp); } else if ((VT_DISPATCH == V_VT(pVal)) || ((VT_DISPATCH|VT_BYREF) == V_VT(pVal))) { // Could be a JScript IDispatchEx array
VARIANT vTemp; VariantInit (&vTemp);
if (S_OK == ConvertDispatchToArray (&vTemp, pVal, CIM_ILLEGAL, true)) hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor);
VariantClear (&vTemp); } else { // Only certain types, I4, R8, BOOL and BSTR are acceptable qualifier
// values. Convert the data if need be
VARTYPE vtOK = GetAcceptableQualType(pVal->vt);
if(vtOK != pVal->vt) { VARIANT vTemp; VariantInit(&vTemp);
if (S_OK == QualifierVariantChangeType (&vTemp, pVal, vtOK)) hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor);
VariantClear(&vTemp); } else hr = m_pIWbemQualifierSet->Put (bsName, pVal, flavor); }
if (SUCCEEDED (hr)) { if (!(*ppQualifier = new CSWbemQualifier (m_pIWbemQualifierSet, bsName, m_pSite))) hr = WBEM_E_OUT_OF_MEMORY; } }
if (FAILED(hr)) m_Dispatch.RaiseException (hr); else { // Propagate the change to the owning site
if (m_pSite) m_pSite->Update (); }
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::Remove
//
// DESCRIPTION:
//
// Delete a qualifier
//
// PARAMETERS:
//
// bsName The name of the qualifier
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::Remove ( BSTR bsName, long lFlags ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (m_pIWbemQualifierSet) hr = m_pIWbemQualifierSet->Delete (bsName);
// Translate default reset case to an error
if (WBEM_S_RESET_TO_DEFAULT == hr) hr = wbemErrResetToDefault;
if (FAILED(hr)) m_Dispatch.RaiseException (hr);
if (SUCCEEDED(hr) || (wbemErrResetToDefault == hr)) { // Propagate the change to the owning site
if (m_pSite) m_pSite->Update (); }
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::BeginEnumeration
//
// DESCRIPTION:
//
// Begin an enumeration of the qualifiers
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::BeginEnumeration ( ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (m_pIWbemQualifierSet) { hr = m_pIWbemQualifierSet->EndEnumeration (); hr = m_pIWbemQualifierSet->BeginEnumeration (0); } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::Next
//
// DESCRIPTION:
//
// Get next qualifier in enumeration
//
// PARAMETERS:
//
// lFlags Flags
// ppQual Next qualifier (or NULL if end of enumeration)
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::Next ( long lFlags, ISWbemQualifier ** ppQual ) { HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppQual) hr = WBEM_E_INVALID_PARAMETER; else if (m_pIWbemQualifierSet) { BSTR name = NULL; if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Next (lFlags, &name, NULL, NULL))) { if (!(*ppQual = new CSWbemQualifier (m_pIWbemQualifierSet, name, m_pSite))) hr = WBEM_E_OUT_OF_MEMORY;
SysFreeString (name); } } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::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 CSWbemQualifierSet::get__NewEnum ( IUnknown **ppUnk ) { HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != ppUnk) { *ppUnk = NULL; CQualSetEnumVar *pEnum = new CQualSetEnumVar (this);
if (!pEnum) hr = WBEM_E_OUT_OF_MEMORY; else if (FAILED(hr = pEnum->QueryInterface (IID_IUnknown, (PPVOID) ppUnk))) delete pEnum; } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; } //***************************************************************************
//
// SCODE CSWbemQualifierSet::get_Count
//
// DESCRIPTION:
//
// Return the number of items in the collection
//
// PARAMETERS:
//
// plCount on successful return addresses cardinality
//
// RETURN VALUES:
//
// S_OK success
// E_FAIL otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::get_Count ( long *plCount ) { HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != plCount) { *plCount = 0;
/*
* This is not the most efficient way of obtaining the count, * but it is the only way that is: * (a) Supported by the underlying interface * (b) Does not require access to any other interface * (c) Does not affect the current enumeration position */
if (m_pIWbemQualifierSet) { SAFEARRAY *pArray = NULL;
if (WBEM_S_NO_ERROR == m_pIWbemQualifierSet->GetNames (0, &pArray)) { long lUBound = 0, lLBound = 0; SafeArrayGetUBound (pArray, 1, &lUBound); SafeArrayGetLBound (pArray, 1, &lLBound); *plCount = lUBound - lLBound + 1; SafeArrayDestroy (pArray); hr = S_OK; } } } if (FAILED(hr)) m_Dispatch.RaiseException (hr);
return hr; }
//***************************************************************************
//
// SCODE CSWbemQualifierSet::CQualifierSetDispatchHelp::HandleError
//
// DESCRIPTION:
//
// Provide bespoke handling of error conditions in the bolierplate
// Dispatch implementation.
//
// PARAMETERS:
//
// dispidMember, wFlags,
// pdispparams, pvarResult,
// puArgErr, All passed directly from IDispatch::Invoke
// hr The return code from the bolierplate invoke
//
// RETURN VALUES:
// The new return code (to be ultimately returned from Invoke)
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemQualifierSet::CQualifierSetDispatchHelp::HandleError ( DISPID dispidMember, unsigned short wFlags, DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, UINT FAR* puArgErr, HRESULT hr ) { /*
* We are looking for calls on the default member (the Item method) which * are PUTs that supplied an argument. These are triggered by attempts * to set a value of a qualifier (Item) in the collection. * The first argument should be the new value for the item, and the second * argument should be the name of the item. */ if ((DISPID_VALUE == dispidMember) && (DISP_E_MEMBERNOTFOUND == hr) && (2 == pdispparams->cArgs) && (DISPATCH_PROPERTYPUT == wFlags)) { // Looks promising - get the object to try and resolve this
ISWbemQualifierSet *pQualifierSet = NULL;
if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemQualifierSet, (PPVOID) &pQualifierSet))) { VARIANT valueVar; VariantInit (&valueVar); if (SUCCEEDED(VariantCopy(&valueVar, &pdispparams->rgvarg[0]))) { VARIANT nameVar; VariantInit (&nameVar); if (SUCCEEDED(VariantCopy(&nameVar, &pdispparams->rgvarg[1]))) { // Check name is a BSTR and use it to get the item
if (VT_BSTR == V_VT(&nameVar)) { ISWbemQualifier *pQualifier = NULL;
if (SUCCEEDED (pQualifierSet->Item (V_BSTR(&nameVar), 0, &pQualifier))) { // Try and put the value
if (SUCCEEDED (pQualifier->put_Value (&valueVar))) hr = S_OK; else { hr = DISP_E_TYPEMISMATCH; if (puArgErr) *puArgErr = 0; }
pQualifier->Release (); } } else { hr = DISP_E_TYPEMISMATCH; if (puArgErr) *puArgErr = 1; }
VariantClear (&nameVar); }
VariantClear (&valueVar); }
pQualifierSet->Release (); } }
return hr; }
|