2025-04-27 07:49:33 -04:00

836 lines
17 KiB
C++

/*
******************************************************************************
******************************************************************************
*
*
* INTEL CORPORATION PROPRIETARY INFORMATION
* This software is supplied under the terms of a license agreement or
* nondisclosure agreement with Intel Corporation and may not be copied or
* disclosed except in accordance with the terms of that agreement.
*
* Copyright (c) 1997, 1998 Intel Corporation All Rights Reserved
******************************************************************************
******************************************************************************
*
*
*
*
*
*/
#include "dmipch.h" // project wide include
#include "WbemDmiP.h" // project wide include
#include "CimClass.h"
#include "Strings.h"
#include "Exception.h"
#include "Trace.h"
#include "DmiData.h"
#include "WbemLoopBack.h"
//////////////////////////////////////////////////////////////////////////
//
// Each Instance of CWbemLoopBack is a connection to an IWbemServices
// in the path used in the call to attach server.
// to use CWbemLoopBack you must first call AttachServer then the
// wrapped cimom service you desire.
//
// meant to be used for the provider calling back into cimom for
// imperative data.
//////////////////////////////////////////////////////////////////////////
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
CWbemLoopBack::CWbemLoopBack()
{
DEV_TRACE ( L"\t\tCWbemLoopBack::CWbemLoopBack()" );
m_pIServices = NULL;
m_pIBindingRoot = NULL;
m_pIGroupRoot = NULL;
m_bConnected = FALSE;
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
CWbemLoopBack::~CWbemLoopBack()
{
DEV_TRACE ( L"\t\tCWbemLoopBack::~CWbemLoopBack()" );
RELEASE( m_pIGroupRoot );
RELEASE( m_pIBindingRoot );
RELEASE( m_pIServices );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::Init ( LPWSTR pPath )
{
m_cszNamespace.Set ( pPath );
}
void CWbemLoopBack::Connect ( IWbemContext* pICtx )
{
if ( m_bConnected )
return;
AttachServer( m_cszNamespace );
GetNetworkAddr( m_cszNWA, pICtx );
m_bConnected = TRUE;
}
void CWbemLoopBack::AttachServer(BSTR bstrPath)
{
HRESULT result;
IWbemLocator *pILocator = NULL ;
STAT_TRACE ( L"\t\tAttachServer(%s) to CIMOM loopback", bstrPath );
if(!bstrPath)
{
throw CException ( WBEM_E_FAILED , IDS_ATTACH_FAIL , IDS_NOPATH );
}
if ( FAILED ( CoCreateInstance (CLSID_WbemAdministrativeLocator, NULL ,
EXE_TYPE , IID_IWbemLocator , ( void ** ) &pILocator) ))
{
throw CException ( WBEM_E_FAILED , IDS_ATTACH_FAIL , IDS_CC_FAIL );
}
if ( FAILED ( result = pILocator->ConnectServer ( bstrPath , NULL, NULL,
NULL, 0L, NULL, NULL, &m_pIServices) ))
{
throw CException ( WBEM_E_FAILED , IDS_ATTACH_FAIL ,
IDS_CONNECTSERVER_FAIL , CString ( result ) );
}
RELEASE(pILocator);
}
// on failure this function leaves pbstrNetwork Addr empty
// likely cause of failure of this func is missing dminode instance
// for the current namespace
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetNetworkAddr( CString& cszNWA, IWbemContext* pICtx )
{
HRESULT result = NO_ERROR;
CCimObject DmiNodeInstance;
CVariant cvNWA;
CBstr cbClass ( NODE_PATH );
if(FAILED(result = m_pIServices->GetObject( cbClass, 0L, pICtx, DmiNodeInstance,
NULL)))
{
throw CException (WBEM_E_FAILED, IDS_GETNWA_FAIL ,
IDS_GETNODEI_FAIL );
}
DmiNodeInstance.GetProperty( DMI_NODE_ADDRESS, cvNWA);
cszNWA.Set( cvNWA.GetBstr() );
}
CString& CWbemLoopBack::NWA( IWbemContext* pICtx )
{
Connect ( pICtx );
return m_cszNWA;
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetNotifyStatusInstance( CCimObject& NotifyInstance,
ULONG ulStatus,
IWbemContext* pICtx )
{
Connect ( pICtx );
if(!m_pIServices)
{
throw CException ( WBEM_E_FAILED , IDS_GETNI_FAIL ,
IDS_NO_LOOPBACK );
}
NotifyInstance.Release();
if ( m_NotifyClass.IsEmpty ( ) )
{
if FAILED( m_pIServices->GetObject( NOTIFYSTATUS, 0L, pICtx,
m_NotifyClass, NULL ))
{
throw CException ( WBEM_E_FAILED, IDS_GETNI_FAIL,
IDS_GETNICLASS_FAIL );
}
}
NotifyInstance.Spawn( m_NotifyClass );
CVariant cvValue;
cvValue.Set ( (LONG) ulStatus );
NotifyInstance.PutPropertyValue ( STATUSCODE_PROPERTY,
cvValue );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
BOOL CWbemLoopBack::GetExtendedStatusInstance( CCimObject& Instance,
ULONG ulStatus,
BSTR bstrDescription,
BSTR bstrOperation,
BSTR bstrParameter,
IWbemContext* pICtx )
{
Connect ( pICtx );
if(!m_pIServices)
{
// we are in deep trouble if this occurs
CString cszT;
STAT_TRACE ( L"Failed to get __ExtendedStatus instance" );
STAT_TRACE ( L"CIMOM loopback interface not established" );
return FALSE;
}
Instance.Release();
if ( m_ExStatusClass.IsEmpty () )
{
if FAILED(m_pIServices->GetObject( EXSTATUS, 0L, pICtx, m_ExStatusClass, NULL ))
{
// we are in deep trouble if this occurs
STAT_TRACE ( L"\tFailed to get __ExtendedStatus instance" );
STAT_TRACE ( L"\tFailed to get __ExtendedStatus class");
return FALSE;
}
}
Instance.Spawn( m_ExStatusClass );
try
{
CVariant cvTemp;
cvTemp.Set ( ulStatus );
Instance.PutPropertyValue ( STATUSCODE_PROPERTY, cvTemp );
cvTemp.Set ( bstrDescription );
Instance.PutPropertyValue ( DESCRIPTION_PROPERTY , cvTemp );
cvTemp.Set ( bstrOperation );
Instance.PutPropertyValue ( OPERATION_PROPERTY , cvTemp );
cvTemp.Set ( PROVIDER_NAME );
Instance.PutPropertyValue ( PROVIDER_PROPERTY , cvTemp );
cvTemp.Set ( bstrParameter );
Instance.PutPropertyValue ( PARAMETER_PROPERTY , cvTemp );
}
catch ( CException& e )
{
CString cszDesc;
CString cszOp;
cszDesc.LoadString ( e.DescriptionId ( ) );
cszOp.LoadString ( e.OperationId ( ) ) ;
ERROR_TRACE ( L"\tGetExtendedStatus() failed" );
ERROR_TRACE ( L"\tjob ( %lX ) failed " , this );
ERROR_TRACE ( L"\t\te.Code = %lX" , e.WbemError ( ) ) ;
ERROR_TRACE ( L"\t\te.Description = %s ", cszDesc );
ERROR_TRACE ( L"\t\te.Operation = %s ", cszOp );
ERROR_TRACE ( L"\t\te.Param = %s ", e.Data() );
return FALSE;
}
catch ( ... )
{
ERROR_TRACE (
L"Unknown error caught, GetExtendedStatusInstance() failed" );
return FALSE;
}
return TRUE;
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetExtrinsicEventInstance ( CEvent& Event, CCimObject& Instance )
{
CVariant cvCompId;
Connect ( NULL );
cvCompId.Set ( Event.Component () );
CVariant cvEventTime;
cvEventTime.Set ( Event.Time() );
CVariant cvLanguage ;
cvLanguage.Set ( Event.Language() );
CVariant cvPath;
cvPath.Set ( Event.NWA () );
CCimObject Class;
if ( FAILED ( m_pIServices->GetObject ( DMIEVENT_CLASS , 0L , NULL ,
Class , NULL ) ))
{
throw CException ( WBEM_E_FAILED, IDS_GETEVENTI_FAIL ,
IDS_GETEVENTC_FAIL );
}
Instance.Spawn( Class );
Instance.PutPropertyValue( COMPONENT_ID, cvCompId );
Instance.PutPropertyValue( EVENT_TIME, cvEventTime );
Instance.PutPropertyValue( LANGUAGE_PROP, cvLanguage );
Instance.PutPropertyValue( MACHINE_PATH, cvPath );
// need to put property on rows here
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetInstanceCreationInstance ( CCimObject& EventInstance,
IUnknown* pIDispNewInstance,
IWbemContext* pICtx )
{
CCimObject EventClass;
Connect ( pICtx );
if(!m_pIServices)
{
throw CException ( WBEM_E_FAILED , IDS_GETICREATIONI_FAIL ,
IDS_NO_LOOPBACK );
}
EventInstance.Release();
if FAILED ( m_pIServices->GetObject( INSTANCE_CREATION_CLASS , 0L, pICtx,
EventClass, NULL ))
{
throw CException ( WBEM_E_FAILED, IDS_GETICREATIONI_FAIL ,
IDS_GETICRATIIONC_FAIL );
}
EventInstance.Spawn( EventClass );
CVariant cvValue;
cvValue.Set ( pIDispNewInstance );
EventInstance.PutPropertyValue ( TARGETI_PROPERTY , cvValue );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetInstanceDeletionInstance ( CCimObject& EventInstance,
IUnknown* pIDispOldInstance,
IWbemContext* pICtx )
{
CCimObject EventClass;
Connect ( pICtx );
if(!m_pIServices)
{
throw CException ( WBEM_E_FAILED, IDS_GETIDELI_FAIL ,
IDS_NO_LOOPBACK );
}
EventInstance.Release();
if FAILED(m_pIServices->GetObject( INSTANCE_DELEATION_CLASS ,
0L, pICtx, EventClass, NULL ))
{
throw CException ( WBEM_E_FAILED, IDS_GETIDELI_FAIL ,
IDS_GETIDELC_FAIL );
}
EventInstance.Spawn( EventClass );
CVariant cvDisp;
cvDisp.Set ( pIDispOldInstance );
EventInstance.PutPropertyValue ( TARGETI_PROPERTY , cvDisp );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetClassCreationInstance ( CCimObject& EventInstance,
IUnknown* pIDispNewClass,
IWbemContext* pICtx )
{
CCimObject EventClass;
Connect ( pICtx );
if(!m_pIServices)
{
throw CException ( WBEM_E_FAILED, IDS_GETCCREATIONI_FAIL ,
IDS_NO_LOOPBACK);
}
EventInstance.Release();
if FAILED(m_pIServices->GetObject( CLASS_CREATION_CLASS ,
0L, pICtx, EventClass, NULL ))
{
throw CException ( WBEM_E_FAILED, IDS_GETCCREATIONI_FAIL ,
IDS_GETCCREATIONC_FAIL );
}
EventInstance.Spawn( EventClass );
CVariant cvDisp;
cvDisp.Set ( pIDispNewClass );
EventInstance.PutPropertyValue ( TARGETC_PROPERTY , cvDisp );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetClassDeletionInstance ( CCimObject& EventInstance,
IUnknown* pIDispOldClass,
IWbemContext* pICtx )
{
CCimObject EventClass;
Connect ( pICtx );
if(!m_pIServices)
{
throw CException ( WBEM_E_FAILED , IDS_GETCDELI_FAIL ,
IDS_NO_LOOPBACK);
}
EventInstance.Release();
if FAILED(m_pIServices->GetObject( CLASS_DELETION_CLASS,
0L, pICtx, EventClass, NULL ))
{
throw CException ( WBEM_E_FAILED, IDS_GETCDELI_FAIL ,
IDS_GETCDELC_FAIL );
}
EventInstance.Spawn( EventClass );
CVariant cvDisp;
cvDisp.Set ( pIDispOldClass );
EventInstance.PutPropertyValue ( TARGETC_PROPERTY , cvDisp );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note: the IWbemClassObject** param must be initialized with a valid
// Interface pointer or null.
//
//***************************************************************************
void CWbemLoopBack::CreateNewClass(IWbemClassObject** ppINewClass,
IWbemContext* pICtx)
{
SCODE result = WBEM_NO_ERROR;
// make the loop back is connected
Connect ( pICtx );
// Don't orphan a previously assigned new class Interface
RELEASE (*ppINewClass );
// check to see if we've cached the null object already
if ( m_NullObject.IsEmpty () )
{
// get the null object and put it in the cache
if ( FAILED ( result = m_pIServices->GetObject ( NULL, 0, pICtx,
m_NullObject , NULL) ))
{
throw CException( WBEM_E_FAILED , IDS_CREATECLASS_FAIL ,
IDS_GETOBJECT_FAIL , CString ( result ) );
}
}
// give the caller a clone of the cached null object
( (IWbemClassObject*) m_NullObject) -> Clone( ppINewClass );
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::CreateNewDerivedClass(IWbemClassObject **ppINewClass,
BSTR bstrSuperClass,
IWbemContext* pICtx)
{
SCODE result = WBEM_NO_ERROR;
IWbemClassObject* pIEmptyClass = NULL;
Connect ( pICtx );
DEV_TRACE ( L"\t\tCCimClassWrap::CreateNewDerivedClass () \
calling GetObject ( %s )", bstrSuperClass );
Connect ( pICtx );
ASSERT(m_pIServices);
RELEASE ( *ppINewClass );
if ( ! IsCached( bstrSuperClass, &pIEmptyClass) )
{
if ( FAILED( result = m_pIServices->GetObject ( bstrSuperClass, 0,
pICtx, &pIEmptyClass, NULL) ))
{
throw CException( WBEM_E_FAILED , IDS_CREATENEWD_CLASS ,
IDS_GETOBJECT_FAIL , CString ( result ) ) ;
}
Cache( bstrSuperClass, pIEmptyClass );
}
result = pIEmptyClass->SpawnDerivedClass ( 0, ppINewClass );
RELEASE(pIEmptyClass);
if ( FAILED( result ))
{
throw CException( WBEM_E_FAILED , IDS_CREATENEWD_CLASS ,
IDS_SPAWN_FAIL , CString ( result ) );
}
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::GetObject(BSTR bstrPath, IWbemClassObject** ppIObject,
IWbemContext* pICtx )
{
SCODE result = WBEM_NO_ERROR;
Connect ( pICtx );
// AttatchServer must be called prior to CreateNewClass
ASSERT(m_pIServices);
MOT_TRACE ( L"CCimClassWrap::GetObject() name = %s", bstrPath );
RELEASE ( *ppIObject );
if( FAILED( result = m_pIServices->GetObject ( bstrPath, 0, pICtx,
ppIObject, NULL) ))
{
throw CException ( WBEM_E_FAILED, IDS_GETOBJECT_FAIL ,
IDS_GETOBJECT_FAIL , CString ( result) );
}
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
void CWbemLoopBack::Cache( LPWSTR wszClassName, IWbemClassObject* p )
{
if ( MATCH == wcsicmp( wszClassName, GROUP_ROOT) )
{
m_pIGroupRoot = p;
m_pIGroupRoot->AddRef();
}
if ( MATCH == wcsicmp( wszClassName, BINDING_ROOT) )
{
m_pIBindingRoot = p;
m_pIBindingRoot->AddRef();
}
}
//***************************************************************************
//
// Func:
// Purpose:
//
//
// Returns:
//
// In Params:
//
// Out Params:
//
// Note:
//
//***************************************************************************
BOOL CWbemLoopBack::IsCached( LPWSTR wszClassName, IWbemClassObject** pp )
{
if ( MATCH == wcsicmp( wszClassName, GROUP_ROOT) && m_pIGroupRoot)
{
*pp = m_pIGroupRoot;
m_pIGroupRoot->AddRef();
return TRUE;
}
if ( MATCH == wcsicmp( wszClassName, BINDING_ROOT) && m_pIBindingRoot)
{
*pp = m_pIBindingRoot;
m_pIBindingRoot->AddRef();
return TRUE;
}
return FALSE;
}