mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1113 lines
25 KiB
1113 lines
25 KiB
//***************************************************************************
|
|
//
|
|
// 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;
|
|
}
|