//*************************************************************************** // // VPPUT.CPP // // Module: WBEM VIEW PROVIDER // // Purpose: Contains the PutInstance implementation // // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include "precomp.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern BOOL CompareSimplePropertyValues(VARIANT* v1, VARIANT* v2, CIMTYPE ct); PutInstanceTaskObject::PutInstanceTaskObject (CViewProvServ *a_Provider , IWbemClassObject *a_Inst , ULONG a_Flag , IWbemObjectSink *a_NotificationHandler, IWbemContext *pCtx) :WbemTaskObject (a_Provider, a_NotificationHandler, a_Flag, pCtx) { m_InstObject = a_Inst; if (m_InstObject != NULL) { m_InstObject->AddRef(); if (WBEM_FLAG_CREATE_ONLY == (a_Flag & WBEM_FLAG_CREATE_ONLY)) { m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ); m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ); m_ErrorObject.SetMessage ( L"The provider does not support instance creation via PutInstanceAsync." ); } } else { m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ; m_ErrorObject.SetMessage ( L"A non-null instance must be supplied as an argument" ) ; } } PutInstanceTaskObject::~PutInstanceTaskObject () { BOOL t_Status = TRUE; IWbemClassObject *t_NotifyStatus = NULL ; if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ()) { t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus ) ; } if ( t_Status ) { m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , t_NotifyStatus ) ; if (t_NotifyStatus) { t_NotifyStatus->Release () ; } } else { m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , NULL ) ; } if (m_InstObject != NULL) { m_InstObject->Release(); } } BOOL PutInstanceTaskObject::PutInstance() { DebugOut4( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("PutInstanceTaskObject :: PutInstance\r\n)") ) ; ) if (FAILED(m_ErrorObject.GetWbemStatus())) { return FALSE; } VARIANT v; VariantInit (&v); BOOL t_Status = SUCCEEDED(m_InstObject->Get(WBEM_PROPERTY_CLASS, 0, &v, NULL, NULL)); if (( t_Status ) && (VT_BSTR == v.vt)) { t_Status = SetClass(v.bstrVal) ; if (t_Status) { t_Status = ParseAndProcessClassQualifiers(m_ErrorObject); if (t_Status) { //only unions if (!m_bAssoc && !m_JoinOnArray.IsValid()) { t_Status = PerformPut(m_ErrorObject); } else { m_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_SUPPORTED ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; m_ErrorObject.SetMessage ( L"Operation only supported for Union views" ) ; } } } else { m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; m_ErrorObject.SetMessage ( L"Class definition not found" ) ; DebugOut4( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("PutInstanceTaskObject :: PutInstance:Dynamic NT Eventlog Provider does not support WRITE for this class\r\n") ) ; ) } } else { t_Status = FALSE ; m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_OBJECT ) ; m_ErrorObject.SetMessage ( L"Unable to obtain class name from object." ) ; DebugOut4( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("PutInstanceTaskObject :: PutInstance:Unable to obtain class name from object.\r\n") ) ; ) } VariantClear(&v); DebugOut4( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("PutInstanceTaskObject :: PutInstance:returning %lx\r\n"), t_Status ) ; ) return t_Status ; } BOOL PutInstanceTaskObject::PerformPut(WbemProvErrorObject &a_ErrorObject) { BOOL retVal = FALSE; VARIANT v; //Two step process, first get the instance being changed... if ( SUCCEEDED(m_InstObject->Get(WBEM_PROPERTY_RELPATH, 0, &v, NULL, NULL)) ) { if (v.vt == VT_BSTR) { IWbemClassObject* pSrcInst; BSTR refStr = MapFromView(v.bstrVal, NULL, &pSrcInst, TRUE); if (refStr != NULL) { //Second step... //map any property changes to the new instance and call PutInstance VARIANT vCls; if ( SUCCEEDED(pSrcInst->Get(WBEM_PROPERTY_CLASS, 0, &vCls, NULL, NULL)) ) { if (vCls.vt == VT_BSTR) { int index; if (m_ClassToIndexMap.Lookup(vCls.bstrVal, index)) { POSITION propPos = m_PropertyMap.GetStartPosition(); retVal = TRUE; while ((propPos != NULL) && retVal) { VARIANT vProp; CIMTYPE ct; CStringW propName; CPropertyQualifierItem* propProps; m_PropertyMap.GetNextAssoc(propPos, propName, propProps); if (!propProps->m_SrcPropertyNames[index].IsEmpty()) { if ( SUCCEEDED(m_InstObject->Get(propName, 0, &vProp, &ct, NULL)) ) { VARIANT vSProp; if ( SUCCEEDED (pSrcInst->Get(propProps->m_SrcPropertyNames[index], 0, &vSProp, &ct, NULL)) ) { if (!CompareSimplePropertyValues(&vProp, &vSProp, ct)) { if ( FAILED(pSrcInst->Put(propProps->m_SrcPropertyNames[index], 0, &vProp, ct)) ) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to Put property in source instance" ) ; } } VariantClear(&vSProp); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to Get property from source instance" ) ; } VariantClear(&vProp); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get property from view instance" ) ; } } } if (retVal) { //which namespace do we put into, try them all until we succeed CWbemServerWrap** pServs = m_NSpaceArray[index]->GetServerPtrs(); HRESULT hr = WBEM_E_FAILED; for (UINT i = 0; i < m_NSpaceArray[index]->GetCount(); i++) { if (pServs[i] != NULL) { IWbemServices *ptmpServ = pServs[i]->GetServerOrProxy(); if (ptmpServ) { hr = ptmpServ->PutInstance(pSrcInst, WBEM_FLAG_UPDATE_ONLY, m_Ctx, NULL); if ( FAILED(hr) && (HRESULT_FACILITY(hr) != FACILITY_ITF) && pServs[i]->IsRemote()) { if ( SUCCEEDED(UpdateConnection(&(pServs[i]), &ptmpServ)) ) { if (ptmpServ) { hr = ptmpServ->PutInstance(pSrcInst, WBEM_FLAG_UPDATE_ONLY, m_Ctx, NULL); } } } if (ptmpServ) { pServs[i]->ReturnServerOrProxy(ptmpServ); } if (SUCCEEDED (hr) ) { break; } } } } if ( FAILED (hr) ) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; #ifdef VP_SINGLE_NAMESPACE_TRIED wchar_t buff[100]; wsprintf(buff, L"PutInstance on source object failed with code: %lx", hr); a_ErrorObject.SetMessage ( buff ) ; #else //VP_SINGLE_NAMESPACE_TRIED a_ErrorObject.SetMessage ( L"PutInstance on source object failed" ) ; #endif //VP_SINGLE_NAMESPACE_TRIED } } } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Source instance class not found in source list" ) ; } } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Source instance has non string __Class property" ) ; } VariantClear(&vCls); } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Source instance has no __Class property" ) ; } pSrcInst->Release(); SysFreeString(refStr); } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Instance supplied could not be mapped to a single source instance" ) ; } } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ; a_ErrorObject.SetMessage ( L"Instance supplied has non string __RelPath property" ) ; } VariantClear(&v); } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_OBJECT ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ; a_ErrorObject.SetMessage ( L"Instance supplied has no __RelPath property" ) ; } return retVal; }