//*************************************************************************** // // 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(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 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; }