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.
377 lines
10 KiB
377 lines
10 KiB
//***************************************************************************
|
|
|
|
//
|
|
|
|
// 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;
|
|
}
|