windows-nt/Source/XPSP1/NT/admin/wmi/wbem/providers/viewprovider/vpput.cpp
2020-09-26 16:20:57 +08:00

378 lines
9.7 KiB
C++

//***************************************************************************
//
// VPPUT.CPP
//
// Module: WBEM VIEW PROVIDER
//
// Purpose: Contains the PutInstance implementation
//
// Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <provexpt.h>
#include <provcoll.h>
#include <provtempl.h>
#include <provmt.h>
#include <typeinfo.h>
#include <process.h>
#include <objbase.h>
#include <stdio.h>
#include <wbemidl.h>
#include <provcont.h>
#include <provevt.h>
#include <provthrd.h>
#include <provlog.h>
#include <cominit.h>
#include <dsgetdc.h>
#include <lmcons.h>
#include <instpath.h>
#include <genlex.h>
#include <sql_1.h>
#include <objpath.h>
#include <vpdefs.h>
#include <vpquals.h>
#include <vpserv.h>
#include <vptasks.h>
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;
}