WindowsXP-SP1/admin/wmi/wbem/scripting/context.cpp
2020-09-30 16:53:49 +02:00

1114 lines
26 KiB
C++

//***************************************************************************
//
// Copyright (c) 1998-2000 Microsoft Corporation
//
// CONTEXT.CPP
//
// alanbos 15-Aug-96 Created.
//
// Defines the implementation of ISWbemNamedValueSet
//
//***************************************************************************
#include "precomp.h"
//***************************************************************************
//
// CSWbemNamedValueSet::CSWbemNamedValueSet
//
// DESCRIPTION:
//
// Constructor.
//
//***************************************************************************
CSWbemNamedValueSet::CSWbemNamedValueSet()
: m_pCWbemPathCracker (NULL),
m_bMutable (true),
m_cRef (0),
m_pIWbemContext (NULL),
m_pSWbemServices (NULL)
{
m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
// Create a context
CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER,
IID_IWbemContext, (LPVOID *) &m_pIWbemContext);
InterlockedIncrement(&g_cObj);
}
//***************************************************************************
//
// CSWbemNamedValueSet::CSWbemNamedValueSet
//
// DESCRIPTION:
//
// Constructor.
//
//***************************************************************************
CSWbemNamedValueSet::CSWbemNamedValueSet(
CSWbemServices *pService,
IWbemContext *pContext
)
: m_pCWbemPathCracker (NULL),
m_bMutable (true),
m_cRef (0),
m_pIWbemContext (pContext),
m_pSWbemServices (pService)
{
m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
if (m_pIWbemContext)
m_pIWbemContext->AddRef ();
if (m_pSWbemServices)
m_pSWbemServices->AddRef ();
InterlockedIncrement(&g_cObj);
}
//***************************************************************************
//
// CSWbemNamedValueSet::CSWbemNamedValueSet
//
// DESCRIPTION:
//
// Constructor.
//
//***************************************************************************
CSWbemNamedValueSet::CSWbemNamedValueSet(
CWbemPathCracker *pCWbemPathCracker,
bool bMutable
)
: m_pCWbemPathCracker (pCWbemPathCracker),
m_bMutable (bMutable),
m_cRef (0),
m_pIWbemContext (NULL),
m_pSWbemServices (NULL)
{
m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
// Create a context
CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER,
IID_IWbemContext, (LPVOID *) &m_pIWbemContext);
if (m_pCWbemPathCracker)
{
m_pCWbemPathCracker->AddRef ();
// Artificial refcount hike as the following may do an AddRef/Release
// pair on this
m_cRef++;
BuildContextFromKeyList ();
m_cRef--;
}
InterlockedIncrement(&g_cObj);
}
//***************************************************************************
//
// CSWbemNamedValueSet::~CSWbemNamedValueSet
//
// DESCRIPTION:
//
// Destructor.
//
//***************************************************************************
CSWbemNamedValueSet::~CSWbemNamedValueSet(void)
{
InterlockedDecrement(&g_cObj);
if (m_pIWbemContext)
{
m_pIWbemContext->EndEnumeration ();
m_pIWbemContext->Release ();
m_pIWbemContext = NULL;
}
RELEASEANDNULL(m_pSWbemServices)
RELEASEANDNULL(m_pCWbemPathCracker)
}
//***************************************************************************
// HRESULT CSWbemNamedValueSet::QueryInterface
// long CSWbemNamedValueSet::AddRef
// long CSWbemNamedValueSet::Release
//
// DESCRIPTION:
//
// Standard Com IUNKNOWN functions.
//
//***************************************************************************
STDMETHODIMP CSWbemNamedValueSet::QueryInterface (
IN REFIID riid,
OUT LPVOID *ppv
)
{
*ppv=NULL;
if (IID_IUnknown==riid)
*ppv = reinterpret_cast<IUnknown*>(this);
else if (IID_IDispatch==riid)
*ppv = (IDispatch *)this;
else if (IID_ISWbemNamedValueSet==riid)
*ppv = (ISWbemNamedValueSet *)this;
else if (IID_ISWbemInternalContext==riid)
*ppv = (ISWbemInternalContext *) 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) CSWbemNamedValueSet::AddRef(void)
{
InterlockedIncrement(&m_cRef);
return m_cRef;
}
STDMETHODIMP_(ULONG) CSWbemNamedValueSet::Release(void)
{
InterlockedDecrement(&m_cRef);
if (0L!=m_cRef)
return m_cRef;
delete this;
return 0;
}
//***************************************************************************
// HRESULT CSWbemNamedValueSet::InterfaceSupportsErrorInfo
//
// DESCRIPTION:
//
// Standard Com ISupportErrorInfo functions.
//
//***************************************************************************
STDMETHODIMP CSWbemNamedValueSet::InterfaceSupportsErrorInfo (IN REFIID riid)
{
return (IID_ISWbemNamedValueSet == riid) ? S_OK : S_FALSE;
}
void CSWbemNamedValueSet::BuildContextFromKeyList ()
{
if (m_pCWbemPathCracker)
{
ULONG lKeyCount = 0;
if (m_pCWbemPathCracker->GetKeyCount (lKeyCount))
{
for (ULONG i = 0; i <lKeyCount; i++)
{
VARIANT var;
VariantInit (&var);
CComBSTR bsName;
WbemCimtypeEnum cimType;
if (m_pCWbemPathCracker->GetKey (i, bsName, var, cimType))
{
SetValueIntoContext (bsName, &var, 0);
}
VariantClear (&var);
}
}
}
}
//***************************************************************************
//
// CSWbemNamedValueSet::GetIWbemContext
//
// DESCRIPTION:
//
// Return the IWbemContext interface corresponding to this scriptable wrapper.
//
// PARAMETERS:
// ppContext holds the IWbemContext pointer on return
//
// RETURN VALUES:
// S_OK success
// E_FAIL otherwise
//
// NOTES:
// If successful, the returned interface is AddRef'd; the caller is
// responsible for release.
//
//***************************************************************************
STDMETHODIMP CSWbemNamedValueSet::GetIWbemContext (IWbemContext **ppContext)
{
HRESULT hr = S_OK; // By default if we have no context to copy
if (ppContext)
{
*ppContext = NULL;
if (m_pIWbemContext)
{
/*
* Before returning a context, we ensure that coercion is performed
* to render the type down to either an IUnknown or a Qualifier
* type. This is done for the benefit of imposing a fixed typing
* system for provider context, rather than have providers take
* the burden of using VariantChangeType etc. themselves.
*/
if (SUCCEEDED (hr = m_pIWbemContext->Clone (ppContext)))
{
if (SUCCEEDED (hr = (*ppContext)->BeginEnumeration (0)))
{
BSTR bsName = NULL;
VARIANT var;
VariantInit (&var);
while (WBEM_S_NO_ERROR == (*ppContext)->Next(0, &bsName, &var))
{
VARIANT vTemp;
VariantInit (&vTemp);
// Stage 1 of transformation involves homogenisation of
// arrays, transformation of JScript arrays, and weedling
// out of IWbemClassObject's
//
// If successful hr will be a a success code and vTemp will
// hold the value, which will either be a VT_UNKNOWN or a
// "simple" (non-object) type, or array thereof.
if((VT_ARRAY | VT_VARIANT) == V_VT(&var))
{
// A classical dispatch-style array of variants - map them
// down to a homogeneous array of primitive values
if (SUCCEEDED(hr = ConvertArray(&vTemp, &var)))
{
// Now check if we should map any VT_DISPATCH's inside
// the array
hr = MapToCIMOMObject(&vTemp);
}
}
else if (VT_DISPATCH == V_VT(&var))
{
// First try a JScript array - if this succeeds it
// will map to a regular SAFEARRAY. If not, we try
// to map to an IWbem interface
if (FAILED(ConvertDispatchToArray (&vTemp, &var)))
{
if (SUCCEEDED (hr = VariantCopy (&vTemp, &var)))
hr = MapToCIMOMObject(&vTemp);
}
}
else
{
// Just copy so we have the result in vTemp in all cases
hr = VariantCopy (&vTemp, &var);
}
// Stage 2 of the transformation involves casting of simple
// (non-VT_UNKNOWN) types to a qualifier type.
if (SUCCEEDED (hr))
{
if (VT_UNKNOWN != (V_VT(&vTemp) & ~(VT_ARRAY|VT_BYREF)))
{
// Not a VT_UNKNOWN so try to cast to a qualifier type
VARIANT vFinal;
VariantInit (&vFinal);
VARTYPE vtOK = GetAcceptableQualType(V_VT(&vTemp));
if (vtOK != V_VT(&vTemp))
{
// Need to coerce
if (SUCCEEDED(hr = QualifierVariantChangeType (&vFinal, &vTemp, vtOK)))
hr = (*ppContext)->SetValue (bsName, 0, &vFinal);
}
else
hr = (*ppContext)->SetValue (bsName, 0, &vTemp);
VariantClear (&vFinal);
}
else
hr = (*ppContext)->SetValue (bsName, 0, &vTemp);
}
VariantClear (&vTemp);
SysFreeString (bsName);
bsName = NULL;
VariantClear (&var);
}
(*ppContext)->EndEnumeration ();
}
}
}
}
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::Clone
//
// DESCRIPTION:
//
// Clone object
//
// PARAMETERS:
// ppCopy On successful return addresses the copy
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::Clone (
ISWbemNamedValueSet **ppCopy
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppCopy)
hr = WBEM_E_INVALID_PARAMETER;
else if (m_pIWbemContext)
{
IWbemContext *pWObject = NULL;
if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->Clone (&pWObject)))
{
// NB: the cloned set is always mutable
CSWbemNamedValueSet *pCopy =
new CSWbemNamedValueSet (m_pSWbemServices, pWObject);
if (!pCopy)
hr = WBEM_E_OUT_OF_MEMORY;
else if (FAILED(hr = pCopy->QueryInterface (IID_ISWbemNamedValueSet,
(PPVOID) ppCopy)))
delete pCopy;
pWObject->Release ();
}
}
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::BeginEnumeration
//
// DESCRIPTION:
//
// Kick off a value enumeration
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::BeginEnumeration (
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (m_pIWbemContext)
{
// Preface with an end enumeration just in case
hr = m_pIWbemContext->EndEnumeration ();
hr = m_pIWbemContext->BeginEnumeration (0);
}
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::Next
//
// DESCRIPTION:
//
// Iterate through value enumeration
//
// PARAMETERS:
// lFlags Flags
// ppNamedValue The next named value (or NULL if at end)
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::Next (
long lFlags,
ISWbemNamedValue **ppNamedValue
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppNamedValue)
hr = WBEM_E_INVALID_PARAMETER;
else
{
*ppNamedValue = NULL;
if (m_pIWbemContext)
{
BSTR name = NULL;
VARIANT var;
VariantInit (&var);
if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->Next (lFlags,
&name, &var)))
{
*ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
this, name, m_bMutable);
if (!(*ppNamedValue))
hr = WBEM_E_OUT_OF_MEMORY;
SysFreeString (name);
}
VariantClear (&var);
}
}
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::Add
//
// DESCRIPTION:
//
// Add named value to set
//
// PARAMETERS:
//
// bsName The property to update/create
// pVal The value
// lFlags Flags
// ppNamedValue The named value created
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::Add (
BSTR bsName,
VARIANT *pVal,
long lFlags,
ISWbemNamedValue **ppNamedValue
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if ((NULL == ppNamedValue) || (NULL == bsName) || (NULL == pVal))
hr = WBEM_E_INVALID_PARAMETER;
else if (!m_bMutable)
hr = WBEM_E_READ_ONLY;
else if (m_pIWbemContext)
{
*ppNamedValue = NULL;
if (VT_BYREF & V_VT(pVal))
{
// We must dereference all byref's
VARIANT var;
VariantInit (&var);
if (VT_ARRAY & V_VT(pVal))
{
var.vt = V_VT(pVal) & ~VT_BYREF;
hr = SafeArrayCopy (*(pVal->pparray), &(var.parray));
}
else
hr = VariantChangeType(&var, pVal, 0, V_VT(pVal) & ~VT_BYREF);
if (SUCCEEDED(hr))
hr = m_pIWbemContext->SetValue (bsName, lFlags, &var);
VariantClear (&var);
}
else if ((VT_ERROR == V_VT(pVal)) && (DISP_E_PARAMNOTFOUND == pVal->scode))
{
// Treat as NULL assignment
pVal->vt = VT_NULL;
hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
}
else
hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
if (SUCCEEDED (hr))
{
WbemCimtypeEnum cimtype = MapVariantTypeToCimType(pVal);
// Add to the path key list if we have one - note this MAY fail
if (m_pCWbemPathCracker)
{
if (!m_pCWbemPathCracker->SetKey (bsName, cimtype, *pVal))
{
// Rats - delete it
m_pIWbemContext->DeleteValue (bsName, 0);
hr = WBEM_E_FAILED;
}
}
if (SUCCEEDED(hr))
{
*ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
this, bsName);
if (!(*ppNamedValue))
hr = WBEM_E_OUT_OF_MEMORY;
}
}
}
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
return hr;
}
HRESULT CSWbemNamedValueSet::SetValueIntoContext (
BSTR bsName,
VARIANT *pVal,
ULONG lFlags
)
{
HRESULT hr = WBEM_E_FAILED;
if (m_pIWbemContext)
{
if (VT_BYREF & V_VT(pVal))
{
// We must dereference all byref's
VARIANT var;
VariantInit (&var);
if (VT_ARRAY & V_VT(pVal))
{
var.vt = V_VT(pVal) & ~VT_BYREF;
hr = SafeArrayCopy (*(pVal->pparray), &(var.parray));
}
else
hr = VariantChangeType(&var, pVal, 0, V_VT(pVal) & ~VT_BYREF);
if (SUCCEEDED(hr))
hr = m_pIWbemContext->SetValue (bsName, lFlags, &var);
VariantClear (&var);
}
else if ((VT_ERROR == V_VT(pVal)) && (DISP_E_PARAMNOTFOUND == pVal->scode))
{
// Treat as NULL assignment
pVal->vt = VT_NULL;
hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
}
else
hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
}
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::Item
//
// DESCRIPTION:
//
// Get named value
//
// PARAMETERS:
//
// bsName The value to retrieve
// lFlags Flags
// ppNamedValue On successful return addresses the value
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::Item (
BSTR bsName,
long lFlags,
ISWbemNamedValue **ppNamedValue
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (NULL == ppNamedValue)
hr = WBEM_E_INVALID_PARAMETER;
else if (m_pIWbemContext)
{
VARIANT var;
VariantInit (&var);
if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->GetValue (bsName, lFlags, &var)))
{
*ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
this, bsName, m_bMutable);
if (!(*ppNamedValue))
hr = WBEM_E_OUT_OF_MEMORY;
}
VariantClear (&var);
}
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::Remove
//
// DESCRIPTION:
//
// Delete named value
//
// PARAMETERS:
//
// bsName The value to delete
// lFlags Flags
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::Remove (
BSTR bsName,
long lFlags
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (!m_bMutable)
hr = WBEM_E_READ_ONLY;
else if (m_pIWbemContext)
hr = m_pIWbemContext->DeleteValue (bsName, lFlags);
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
else
{
// Remove from our key list if we have one
if (m_pCWbemPathCracker)
hr = m_pCWbemPathCracker->RemoveKey (bsName);
}
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::DeleteAll
//
// DESCRIPTION:
//
// Empty the bag
//
// PARAMETERS:
// None
//
// RETURN VALUES:
//
// WBEM_S_NO_ERROR success
// WBEM_E_INVALID_PARAMETER bad input parameters
// WBEM_E_FAILED otherwise
//
//***************************************************************************
HRESULT CSWbemNamedValueSet::DeleteAll (
)
{
HRESULT hr = WBEM_E_FAILED;
ResetLastErrors ();
if (!m_bMutable)
hr = WBEM_E_READ_ONLY;
else if (m_pIWbemContext)
hr = m_pIWbemContext->DeleteAll ();
if (FAILED(hr))
m_Dispatch.RaiseException (hr);
else
{
// Empty the key list
if (m_pCWbemPathCracker)
m_pCWbemPathCracker->RemoveAllKeys ();
}
return hr;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::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 CSWbemNamedValueSet::get__NewEnum (
IUnknown **ppUnk
)
{
HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != ppUnk)
{
*ppUnk = NULL;
CContextEnumVar *pEnum = new CContextEnumVar (this, 0);
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 CSWbemNamedValueSet::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 CSWbemNamedValueSet::get_Count (
long *plCount
)
{
HRESULT hr = E_FAIL;
ResetLastErrors ();
if (NULL != plCount)
{
*plCount = 0;
if (m_pIWbemContext)
{
/*
* 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
*/
SAFEARRAY *pArray = NULL;
if (WBEM_S_NO_ERROR == m_pIWbemContext->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;
}
//***************************************************************************
//
// CSWbemNamedValueSet::GetIWbemContext
//
// DESCRIPTION:
//
// Given an IDispatch interface which we hope is also an ISWbemNamedValueSet
// interface, return the underlying IWbemContext interface.
//
// PARAMETERS:
// pDispatch the IDispatch in question
//
// RETURN VALUES:
// The underlying IWbemContext interface, or NULL.
//
// NOTES:
// If successful, the returned interface is AddRef'd; the caller is
// responsible for release.
//
//***************************************************************************
/*
* THIS FUNCTION NEEDS FIXING
* Currently this function returns the context from the service provider
* obtained from the host, if there is one. If there isn't one then it uses
* the one passed in from the user. The correct behaviour is to _add_ the
* context from the user to the one provided by the service provider if there
* is one, if not just use the one from the user
*/
IWbemContext *CSWbemNamedValueSet::GetIWbemContext (
IDispatch *pDispatch,
IServiceProvider *pServiceProvider
)
{
_RD(static char *me = "CSWbemNamedValueSet::GetIWbemContext";)
IWbemContext *pContext = NULL;
ISWbemInternalContext *pIContext = NULL;
_RPrint(me, "Called", 0, "");
if (pServiceProvider) {
if (FAILED(pServiceProvider->QueryService(IID_IWbemContext,
IID_IWbemContext, (LPVOID *)&pContext))) {
_RPrint(me, "Failed to get context from services", 0, "");
pContext = NULL;
} else {
_RPrint(me, "Got context from services", 0, "");
;
}
}
if (pDispatch && !pContext)
{
if (SUCCEEDED (pDispatch->QueryInterface
(IID_ISWbemInternalContext, (PPVOID) &pIContext)))
{
pIContext->GetIWbemContext (&pContext);
pIContext->Release ();
}
}
return pContext;
}
/*
* Call GetIWbemContext to get the service context if there is one.
* Then wrap the result with an SWbemContext and return
*/
IDispatch *CSWbemNamedValueSet::GetSWbemContext(IDispatch *pDispatch,
IServiceProvider *pServiceProvider, CSWbemServices *pServices)
{
_RD(static char *me = "CSWbemNamedValueSet::GetSWbemContext";)
IDispatch *pDispatchOut = NULL;
IWbemContext *pContext = GetIWbemContext(pDispatch, pServiceProvider);
if (pContext) {
CSWbemNamedValueSet *pCSWbemNamedValueSet = new CSWbemNamedValueSet(pServices, pContext);
if (pCSWbemNamedValueSet)
{
if (FAILED(pCSWbemNamedValueSet->QueryInterface
(IID_IDispatch, (PPVOID) &pDispatchOut))) {
delete pCSWbemNamedValueSet;
pDispatchOut = NULL;
}
}
pContext->Release();
}
_RPrint(me, "Returning with context: ", (long)pDispatchOut, "");
return pDispatchOut;
}
//***************************************************************************
//
// SCODE CSWbemNamedValueSet::CContextDispatchHelp::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 CSWbemNamedValueSet::CContextDispatchHelp::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 named value (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
ISWbemNamedValueSet *pContext = NULL;
if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemNamedValueSet, (PPVOID) &pContext)))
{
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))
{
ISWbemNamedValue *pNamedValue = NULL;
if (SUCCEEDED (pContext->Item (V_BSTR(&nameVar), 0, &pNamedValue)))
{
// Try and put the value
if (SUCCEEDED (pNamedValue->put_Value (&valueVar)))
hr = S_OK;
else
{
hr = DISP_E_TYPEMISMATCH;
if (puArgErr)
*puArgErr = 0;
}
pNamedValue->Release ();
}
}
else
{
hr = DISP_E_TYPEMISMATCH;
if (puArgErr)
*puArgErr = 1;
}
VariantClear (&nameVar);
}
VariantClear (&valueVar);
}
pContext->Release ();
}
}
return hr;
}