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

1848 lines
39 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"
#include "WbemDmiP.h"
#include "ocidl.h"
#include "DmiData.h"
#include "DmiInterface.h"
#include "Strings.h"
#include "Exception.h"
#include "Trace.h"
#include "CimClass.h"
#include "WbemLoopBack.h"
#include "Mapping.h"
#include "MOTObjects.h"
#include "AsyncJob.h"
// the HOLD_CONNECTION constant is used to set weather or not
// the DMIP holds a connected IDualMgmt Node for it's life time.
// If HOLD_CONNECTION
#define HOLD_CONNECTION 1
void MakeConnectString( LPWSTR wszNWA, CString& cszConnectString )
{
CString cszConnectPath(wszNWA);
// If it's not a local connection, it must be
// a TCP|IP connection. See if it contains the
// DCE|TCP|IP string.
if(MATCH != wcsicmp(wszNWA, LOCAL))
{
// Add the DCE|TPC|IP| prefix if the path does
// not already have it.
if ( !cszConnectPath.Contains( CONNECT_PREFIX ) )
{
cszConnectString.Set( CONNECT_PREFIX );
cszConnectString.Append( wszNWA );
}
else
cszConnectString.Set( wszNWA );
}
else
cszConnectString.Set( wszNWA );
}
CConnection::CConnection ()
{
m_pINode = NULL;
m_pNext = NULL;
}
void CConnection::Init ( LPWSTR pNode )
{
CString cszPath;
VARIANT_BOOL vbConnect = FALSE;
SCODE result;
m_cszNWA.Set ( pNode );
MakeConnectString ( pNode , cszPath );
if ( FAILED ( CoCreateInstance (CLSID_DMIMgmtNode, NULL, EXE_TYPE,
IID_IDualMgmtNode, (void**) &m_pINode ) ) )
{
throw CException ( WBEM_E_FAILED , IDS_GETNODE_FAIL ,
IDS_CC_FAIL );
}
CBstr cbPath;
cbPath.Set ( cszPath );
result = m_pINode->Connect ( cbPath , &vbConnect);
if ( vbConnect == VARIANT_FALSE || FAILED ( result ) )
{
// todo fix error
throw CException ( WBEM_E_FAILED , IDS_GETNODE_FAIL ,
IDS_CC_FAIL );
}
MOT_TRACE ( L"\tMOT Node Connect");
}
void CConnection::Disconnect ( )
{
VARIANT_BOOL vbDone;
SCODE result;
result = m_pINode->Disconnect ( &vbDone );
MOT_TRACE ( L"\tMOT Node Disconnect vbDone = %lu result = %lu " , vbDone , result );
}
CConnection::~CConnection ()
{
if ( m_pINode )
{
long l = m_pINode->Release ( );
MOT_TRACE ( L"\tMOT Node Release = %lu" , l );
m_pINode = NULL;
}
}
CConnections::CConnections( )
{
m_pFirst = NULL;
m_pCurrent = NULL;
}
CConnections::~CConnections ( )
{
ClearAll( );
}
void CConnections::ClearAll ( )
{
if(!m_pFirst)
return;
MoveToHead( );
CConnection* p = NULL;
while(m_pCurrent)
{
p = m_pCurrent;
m_pCurrent->Disconnect();
m_pCurrent = m_pCurrent->m_pNext;
MYDELETE ( p );
}
m_pFirst = NULL;
}
void CConnections::MoveToHead ()
{
m_pCurrent = m_pFirst;
}
CConnection* CConnections::Next ()
{
if(!m_pCurrent)
{
// there are no items in the list on start or we have gone through
// the entire list
return NULL;
}
CConnection* p = m_pCurrent;
// get ready for next pass through
m_pCurrent = m_pCurrent->m_pNext;
return p;
}
void CConnections::Add ( CConnection* pAdd , LPWSTR pNWA )
{
pAdd->Init( pNWA );
if (!m_pFirst)
{
m_pFirst = pAdd;
}
else
{
CConnection* p = m_pFirst;
while (p->m_pNext)
p = p->m_pNext;
p->m_pNext = pAdd;
}
}
void CConnections::Remove ( LPWSTR pNWA)
{
}
BOOL CConnections::CheckIfAlready ( LPWSTR pNWA )
{
#if HOLD_CONNECTION
MoveToHead ();
while( m_pCurrent )
{
if ( m_pCurrent->NWA().Equals ( pNWA ) )
return TRUE; // Node exists in the list
Next();
}
CConnection* pNew = new CConnection;
Add ( pNew , pNWA );
return FALSE; // Node does not exist. It's newly created
#endif
}
////////////////////////////////////////////////////////////////
CConnections* _fConnections = NULL ;
////////////////////////////////////////////////////////////////
void dmiReadComponent ( LPWSTR wszNWA , LONG lComponent ,
CComponent* pComponent , CDmiError* pError )
{
CDComponentI IDC;
CString cszPath;
SCODE result = WBEM_NO_ERROR;
_fConnections->CheckIfAlready ( wszNWA );
//MOT_TRACE ( L"\tdmiReadComponent ( %s , %lu )" , wszNWA , lComponent );
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
pComponent->Read ( IDC );
IDC.Release ( );
}
void dmiReadComponents ( LPWSTR wszNWA , CComponents* pNewComponents ,
CDmiError* pError )
{
CDMgmtNodeI DMNI;
CDComponentsI DCSI;
CUnknownI Unk;
CEnumVariantI Enum;
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadComponents ( %s )" , wszNWA );
DMNI.CoCreate ( );
MakeConnectString( wszNWA, cszPath );
DMNI.Read ( cszPath );
DMNI.GetComponents( DCSI );
DCSI.GetUnk ( Unk );
// Get pointer to IEnumVariant interface of from IUNKNOWN
Unk.GetEnum ( Enum);
CVariant cvComponent;
while ( Enum.Next( cvComponent ) )
{
CDComponentI DCI;
// Get pointer to IDualComponents interface
DCI.QI ( cvComponent );
CComponent* pComponent = (CComponent*) new CComponent();
if( !pComponent )
{
throw CException ( WBEM_E_OUT_OF_MEMORY ,
IDS_MOT_COMPONENTS_READ , IDS_NO_MEM );
}
pComponent->Read( DCI );
pNewComponents->Add(pComponent);
DCI.Release();
cvComponent.Clear( );
}
pNewComponents->MoveToHead();
pNewComponents->m_bFilled = TRUE;
Enum.Release ( );
Unk.Release ( );
DCSI.Release ( );
DMNI.Release ( );
}
void dmiReadRow ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
CAttributes* pKeys , CRow* pNewRow , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadRow ( %s , %lu , %lu )" , wszNWA , lComponent, lGroup );
CString cszPath;
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lComponent );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lGroup );
if ( pKeys->Empty () )
{
cszPath.Append ( PIPE_STR );
// if row is scalar
cszPath.Append ( SCALAR_STR );
}
else
{
CString cszT;
pKeys->GetMOTPath ( cszT );
cszPath.Append ( cszT );
}
// Contruct and read the row
CDRowI DRI;
DRI.CoCreate ( );
if ( DRI.Read ( cszPath ) )
{
pNewRow->Read ( DRI );
return;
}
//don't throw error here incase read was for modify row
DRI.Release ();
}
void dmiReadNode ( LPWSTR wszNWA , CNode* pNewNode , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadNode ( %s )" , wszNWA );
CString cszPath;
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
// 2. Construct the node object
CDMgmtNodeI DNI;
DNI.CoCreate ( );
// 3. Read the node object
DNI.Read ( cszPath );
pNewNode->Read ( DNI );
}
void dmiAddComponent ( LPWSTR wszNWA , LPWSTR wszMif , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CString cszPath;
CVariant cvMifFile;
cvMifFile.Set ( wszMif );
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
// 2. Construct the node object
CDMgmtNodeI DNI;
DNI.CoCreate ( );
// 3. Read the node object
DNI.Read ( cszPath );
// 4. Add the component
DNI.AddComponent ( cvMifFile );
}
void dmiDeleteComponent ( LPWSTR wszNWA , LONG lComponent , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CString cszPath;
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
// 2. Construct the node object
CDMgmtNodeI DNI;
DNI.CoCreate ( );
// 3. Read the node object
DNI.Read ( cszPath );
// 4. Add the component
DNI.DeleteComponent ( lComponent );
}
void dmiAddGroup ( LPWSTR wszNWA , LONG lComponent ,
LPWSTR wszMif , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CDComponentI IDC;
CDGroupsI IDGS;
CString cszPath;
SCODE result = WBEM_NO_ERROR;
CVariant cvMifFile;
cvMifFile.Set ( wszMif );
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetGroups ( IDGS );
IDGS.Add ( cvMifFile );
}
void dmiReadGroups ( LPWSTR wszNWA , LONG lComponent ,
CGroups* pNewGroups , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadGroups ( %s , %lu )" , wszNWA , lComponent );
CDComponentI IDC;
CDGroupsI IDGS;
CString cszPath;
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetGroups ( IDGS );
pNewGroups->Read ( IDGS );
}
void dmiReadGroup ( LPWSTR wszNWA , LONG lComponent ,
LONG lGroup , CGroup* pNewGroup , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadGroup ( %s , %lu , %lu )" , wszNWA , lComponent, lGroup );
CDGroupI IDG;
CString cszPath;
SCODE result = WBEM_NO_ERROR;
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
cszPath.Append( PIPE_STR );
cszPath.Append( lGroup );
IDG.CoCreate ( );
IDG.Read( cszPath );
BOOL bComponentIdGroup;
pNewGroup->Read ( IDG , FALSE , &bComponentIdGroup );
}
void dmiDeleteGroup ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CDComponentI IDC;
CDGroupsI IDGS;
CString cszPath;
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetGroups ( IDGS );
IDGS.Remove ( lGroup );
}
void dmiAddLanguage ( LPWSTR wszNWA , LONG lComponent , LPWSTR wszMifFile ,
CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CDComponentI IDC;
CDLanguagesI IDLS;
CString cszPath;
CString cszMifFile ( wszMifFile );
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetLanguages ( IDLS );
IDLS.Add ( cszMifFile );
}
void dmiDeleteLanguage ( LPWSTR wszNWA , LONG lComponent , LPWSTR wszLanguage ,
CDmiError* )
{
CDComponentI IDC;
CDLanguagesI IDLS;
CString cszPath;
CString cszLanguage( wszLanguage );
_fConnections->CheckIfAlready ( wszNWA );
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetLanguages ( IDLS );
IDLS.Remove ( cszLanguage );
}
void dmiReadEnum ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
LONG lAttribute , CEnum* pNewEnum , CDmiError* pError )
{
_fConnections->CheckIfAlready ( wszNWA );
CDAttributeI DAI;
CDAttributesI DASI;
CDEnumColI DECI;
CDGroupI DGI;
CString cszPath;
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
cszPath.Append( PIPE_STR );
cszPath.Append( lGroup );
DGI.CoCreate ( );
DGI.Read ( cszPath );
DGI.GetAttributes ( DASI );
DASI.Item ( lAttribute , DAI );
DAI.GetDmiEnum ( DECI );
pNewEnum->Read ( DECI );
}
void dmiSetDefaultLanguage ( LPWSTR wszNWA , LPWSTR wszLanguage,
CDmiError* pError )
{
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
// 2. Construct the node object
CDMgmtNodeI DNI;
DNI.CoCreate ( );
// 3. Read the node object
DNI.Read ( cszPath );
// 4. set the language
CBstr cbLanguage ( wszLanguage );
DNI.PutLanguage ( cbLanguage );
}
void dmiGetLanguages ( LPWSTR wszNWA , LONG lComponent,
CLanguages* pNewLanguages , CDmiError* pError )
{
CDComponentI IDC;
CDLanguagesI IDLS;
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
MakeConnectString( wszNWA, cszPath );
cszPath.Append( PIPE_STR );
cszPath.Append( lComponent );
IDC.CoCreate ( );
IDC.Read( cszPath );
IDC.GetLanguages ( IDLS );
pNewLanguages->Read ( IDLS );
}
void dmiReadRows ( LPWSTR wszNWA , LONG lComponent, LONG lGroup ,
CRows* pNewRows , CDmiError* pError )
{
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
MOT_TRACE ( L"\tdmiReadRows ( %s , %lu , %lu )" , wszNWA , lComponent, lGroup );
// 1. contruct path
MakeConnectString( wszNWA, cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lComponent );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lGroup );
// Contruct and read the rows
CDGroupI DGI;
CDRowsI DRSI;
DGI.CoCreate ( );
DGI.Read ( cszPath );
DGI.GetRows ( DRSI );
pNewRows->Read ( DRSI );
}
/////////////// MOT EVENTS /////////////////////////////////////////////////
#define DISPID_DMI_EVENT 1
#define DISPID_DMI_NOTIFICATION 2
#define DISPID_DESCRIPTION 1
#define DISPID_NOTIFICATION_LANGUAGE 2
#define DISPID_NOTIFICATION 3
#define DISPID_EVENT_LANGUAGE 1
#define DISPID_ROWS 2
#define DISPID_COMPID 3
#define DISPID_EVENT_TIME 4
#define DISPID_PATH 5
class CMOTEvent : public IDispatch
{
public:
LONG m_cRef; //Object reference count
_DualDMIEngine* m_pIEngine;
IConnectionPoint* m_pConnPt;
IDualMgmtNode* m_pINode;
DWORD m_dwEventCookie;
CString m_cszNamespace;
//CString m_cszNWA;
CMOTEvent ();
~CMOTEvent ();
void Init ( LPWSTR wszNWA , IWbemObjectSink* pIWbemSink);
IWbemObjectSink* m_pCimomClient;
void HandleEvent( LCID, DISPPARAMS * );
void HandleNotification( LCID, DISPPARAMS * );
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(THIS_ UINT * );
STDMETHODIMP GetTypeInfo(THIS_ UINT, LCID, ITypeInfo ** );
STDMETHODIMP GetIDsOfNames(THIS_ REFIID , OLECHAR ** , UINT , LCID , DISPID* );
STDMETHODIMP Invoke(THIS_ DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
void ExtrinsicEvent ( CVariant& cvCompId, CVariant& cvEventTime, CVariant& cvLanguage , CVariant& cvPath, IDualColRows* pIDRows ) ;
void AddComponentNotification( IDualComponent* pIDComponent );
void DeleteComponentNotification( IDualComponent* pIDComponent );
void AddGroupNotification( IDualGroup* pIDGroup );
void DeleteGroupNotification( IDualGroup* pIDGroup );
void AddLanguageNotification( CVariant& cvLanuguage );
void DeleteLanguageNotification( CVariant& cvLanuguage );
CWbemLoopBack m_Wbem;
};
CMOTEvent::CMOTEvent ( )
{
m_cRef = 0;
m_pIEngine = NULL;
m_pConnPt = NULL;
m_pINode = NULL;
m_dwEventCookie =0;
m_pCimomClient = NULL;
}
CMOTEvent::~CMOTEvent ( )
{
m_cRef = 0;
RELEASE ( m_pINode );
RELEASE ( m_pConnPt );
RELEASE ( m_pIEngine );
// m_pCimomClient released by async trhead
}
void CMOTEvent::Init ( LPWSTR pNamespace , IWbemObjectSink* pIWbemSink)
{
m_pCimomClient = pIWbemSink;
// note need to do this addref in a free thread
m_pCimomClient->AddRef ( );
m_cszNamespace.Set ( pNamespace );
m_Wbem.Init ( pNamespace );
}
////////////// start mot events
//***************************************************************************
// IUNKNOWN
//
// CDmiInterface::QueryInterface
// CDmiInterface::AddRef
// CDmiInterface::Release
//
// Purpose:
// IUnknown members for CNotify object.
//***************************************************************************
STDMETHODIMP CMOTEvent::QueryInterface(REFIID riid, void** ppv)
{
*ppv=NULL;
if (IID_IUnknown == riid || IID_IDispatch == riid)
*ppv = this;
if (NULL != *ppv)
{
AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CMOTEvent::AddRef(void)
{
return InterlockedIncrement ( & m_cRef );
}
STDMETHODIMP_(ULONG) CMOTEvent::Release(void)
{
if ( 0L != InterlockedDecrement ( & m_cRef ) )
return m_cRef;
delete this;
return WBEM_NO_ERROR;
}
//***************************************************************************
// IDISPATCH
//
// CMOTEvent::GetTypeInfoCount
// CMOTEvent::GetTypeInfo
// CMOTEvent::GetIDsOfNames
// CMOTEvent::Invoke
//
// Purpose:
// IDispatch members for CNotify object.
//***************************************************************************
STDMETHODIMP CMOTEvent::GetTypeInfoCount(UINT *pctInfo)
{
// we don't support type information
*pctInfo = 0;
return WBEM_NO_ERROR;
}
STDMETHODIMP CMOTEvent::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo ** pptinfo)
{
pptinfo = NULL;
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP CMOTEvent::GetIDsOfNames(THIS_ REFIID riid, OLECHAR ** rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid)
{
SCODE result = ResultFromScode(DISP_E_UNKNOWNNAME);
if(IID_NULL != riid)
return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
rgdispid[0] = DISPID_UNKNOWN;
return NO_ERROR;
}
STDMETHODIMP CMOTEvent::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
{
STAT_TRACE ( L"CMOTEvent::Invoke(), Event or Notification Recieved" ) ;
if(IID_NULL != riid)
return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
switch (dispidMember)
{
case DISPID_DMI_EVENT:
{
HandleEvent( lcid, pdispparams );
break;
}
case DISPID_DMI_NOTIFICATION:
{
HandleNotification( lcid, pdispparams );
break;
}
default:
{
}
}
return NOERROR;
}
////////////////////////////////////////////////////////////////////////////////////////
void CMOTEvent::HandleEvent ( LCID lcid, DISPPARAMS* dpParams )
{
SCODE result = WBEM_NO_ERROR;
IEvent* pIEvent = NULL;
IDispatch* pIDispatch = NULL;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
IUnknown* pIUnk = NULL;
CVariant cvEventTime, cvCompId, cvLanguage, cvPath, cvRows;
IDualColRows* pIDRows = NULL;
if ( FAILED ( ( ( IDispatch* )dpParams->rgvarg[0].pdispVal )->QueryInterface ( IID_IUnknown, (void **) &pIUnk ) ))
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
// Verify we are dealing with an event object.
result = pIUnk->QueryInterface ( DIID_IEvent , (void **) &pIEvent );
RELEASE ( pIEvent );
if ( FAILED ( result ))
{
RELEASE ( pIUnk );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Get the dispatch interface so we can access the properites
result = pIUnk->QueryInterface ( IID_IDispatch, (void **) &pIDispatch ) ;
RELEASE ( pIUnk );
if ( FAILED ( result ) )
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
// Get the CompId (LONG)
if ( FAILED ( pIDispatch->Invoke( DISPID_COMPID, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvCompId, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Get the EventTime (STRING )
if ( FAILED ( pIDispatch->Invoke( DISPID_EVENT_TIME, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvEventTime, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Get the Language (STRING )
if ( FAILED ( pIDispatch->Invoke( DISPID_EVENT_LANGUAGE, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvLanguage, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Get the MachinePath ( STRING )
if ( FAILED ( pIDispatch->Invoke( DISPID_PATH, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvPath, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Get the Rows Object ( IDualColRows* )
if ( FAILED ( pIDispatch->Invoke( DISPID_ROWS, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvRows, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Now we are doing accessing the events properties release the Dispatch
// ptr
RELEASE ( pIDispatch );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
if FAILED ( ( (IDispatch *)cvRows )->QueryInterface ( IID_IUnknown, (void **) &pIUnk ) )
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
result = pIUnk->QueryInterface ( IID_IDualColRows, (void **) &pIDRows );
RELEASE ( pIUnk );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
// send object to cimom client
ExtrinsicEvent ( cvCompId, cvEventTime, cvLanguage , cvPath, pIDRows ) ;
RELEASE ( pIDRows );
}
void CMOTEvent::HandleNotification ( LCID lcid, DISPPARAMS* dpParams )
{
SCODE result = WBEM_NO_ERROR;
IDispatch* pIDispatch = NULL;
CVariant cvDescription;
CVariant cvNotificationObject;
CVariant cvLanuguage;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
IUnknown* pIUnk = NULL;
INotification* pINotification = NULL;
if ( FAILED ( ( ( IDispatch* )dpParams->rgvarg[0].pdispVal )->QueryInterface ( IID_IUnknown, (void **) &pIUnk ) ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
// Verify we are dealing with a notification object.
result = pIUnk->QueryInterface ( DIID_INotification, (void **) &pINotification );
RELEASE ( pINotification );
if ( FAILED ( result ))
{
RELEASE ( pIUnk );
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
}
// Get the dispatch interface so we can access the properites
result = pIUnk->QueryInterface ( IID_IDispatch, (void **) &pIDispatch ) ;
RELEASE ( pIUnk );
if ( FAILED ( result ) )
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
/// Get the description string
if ( FAILED ( pIDispatch->Invoke( DISPID_DESCRIPTION, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvDescription, NULL, NULL ) ))
{
RELEASE ( pIDispatch );
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
}
// Get the Notification object
CString cszDescription;
cszDescription.Set ( cvDescription.GetBstr() ) ;
if ( cszDescription.Contains ( L"component") )
{
// component added or deleted notification
IDualComponent*pIDComponent = NULL;
// get the component notification object
result = pIDispatch->Invoke( DISPID_NOTIFICATION, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvNotificationObject, NULL, NULL );
RELEASE ( pIDispatch );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
// Get the IDualComponentInterface
if FAILED ( ( (IDispatch *)cvNotificationObject )->QueryInterface ( IID_IUnknown, (void **) &pIUnk ) )
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
result = pIUnk->QueryInterface ( IID_IDualComponent, (void **) &pIDComponent );
RELEASE ( pIUnk );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
// call the mapping to create the appropreate objects
if ( cszDescription.Contains ( L"add") )
{
// component added
AddComponentNotification( pIDComponent );
}
else
{
// component deleted
DeleteComponentNotification( pIDComponent );
}
RELEASE ( pIDComponent );
return;
}
if ( cszDescription.Contains ( L"group") )
{
// group added or deleted
IDualGroup* pIDGroup = NULL;
// get the component notification object
result = pIDispatch->Invoke( DISPID_NOTIFICATION, IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvNotificationObject, NULL, NULL );
RELEASE ( pIDispatch );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
// Get the IDualComponentInterface
if ( FAILED ( ( (IDispatch *)cvNotificationObject )->QueryInterface ( IID_IUnknown, (void **) &pIUnk ) ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
result = pIUnk->QueryInterface ( IID_IDualGroup , (void **) &pIDGroup );
RELEASE ( pIUnk );
if ( FAILED ( result ))
throw CException ( WBEM_E_FAILED , IDS_HANDLENOTIFICATION_FAIL , IDS_GEN );
// call the mapping to create the appropreate objects
if ( cszDescription.Contains ( L"add") )
{
// group added
AddGroupNotification( pIDGroup );
}
else
{
// group deleted
DeleteGroupNotification( pIDGroup );
}
RELEASE ( pIDGroup );
return;
}
// must be language
/// Get the Language string
result = pIDispatch->Invoke( DISPID_NOTIFICATION_LANGUAGE , IID_NULL, lcid, DISPATCH_PROPERTYGET, &dispparamsNoArgs, cvLanuguage, NULL, NULL );
RELEASE ( pIDispatch );
if ( FAILED ( result ) )
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
if ( cszDescription.Contains ( L"add") )
{
// Language added
AddLanguageNotification( cvLanuguage );
}
else
{
// Language deleted
DeleteLanguageNotification( cvLanuguage );
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void CMOTEvent::ExtrinsicEvent ( CVariant& cvCompId, CVariant& cvEventTime, CVariant& cvLanguage ,
CVariant& cvPath, IDualColRows* pIDRows )
{
CVariant cvKeys;
IDualRow* pIDRow = NULL;
CEvent Event;
Event.SetComponent ( cvCompId.GetLong() );
Event.SetTime ( cvEventTime.GetBstr () );
Event.SetLanguage ( cvLanguage.GetBstr() );
if ( FAILED ( pIDRows->GetFirstRow( cvKeys, &pIDRow ) ) )
return;
// next lines remarked because mot does not return expected row object
#if 0
Event.m_Row.Read ( pIDRow );
CBstr cbPath;
pIDRow->get_Path ( cbPath );
Event.SetGroup ( cbPath.GetLastIdFromPath( ) ) ;
Event.m_Row.SetData ( NULL , cvCompId.GetLong () , Event.Group () );
#endif
Event.SetNWA ( m_Wbem.NWA( NULL ) );
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitEvent ( Event , m_cszNamespace , m_pCimomClient , &m_Wbem );
}
void CMOTEvent::AddComponentNotification( IDualComponent* pIDComponent )
{
CComponent Component;
// Create the instance of component that has been created
Component.Read ( pIDComponent );
Component.SetNWA ( m_Wbem.NWA( NULL ) );
CString cszPath;
// contruct path to component id group
MakeConnectString( m_Wbem.NWA( NULL ) , cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( Component.Id ( ) );
cszPath.Append ( PIPE_STR );
cszPath.Append ( 1 );
cszPath.Append ( PIPE_STR );
cszPath.Append ( SCALAR_STR );
CDRowI DRI;
DRI.CoCreate ( );
if ( ! DRI.Read ( cszPath ) )
throw CException ( WBEM_E_FAILED , 0 , 0 );
CRow Row;
Row.Read ( DRI );
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitAddComponentNotification ( Component , Row , m_cszNamespace
, m_pCimomClient, &m_Wbem );
}
void CMOTEvent::DeleteComponentNotification( IDualComponent* pIDComponent )
{
CComponent Component;
// Create the instance of component that has deleted to the greateset extent possible
Component.Read ( pIDComponent );
Component.SetNWA ( m_Wbem.NWA( NULL ) );
// contruct path to component id group
CString cszPath;
MakeConnectString( m_Wbem.NWA( NULL ) , cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( Component.Id ( ) );
cszPath.Append ( PIPE_STR );
cszPath.Append ( 1 );
cszPath.Append ( PIPE_STR );
cszPath.Append ( SCALAR_STR );
CDRowI DRI;
DRI.CoCreate ( );
DRI.Read ( cszPath );
CRow Row;
Row.Read ( DRI );
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitDeleteComponentNotification ( Component , Row
, m_cszNamespace , m_pCimomClient , &m_Wbem );
}
void CMOTEvent::AddGroupNotification( IDualGroup* pIDGroup )
{
CGroup Group;
LONG lComponentId;
CBstr cbPath;
BOOL bComponentId;
// Create the group class
Group.Read ( pIDGroup , FALSE , &bComponentId);
Group.SetNWA ( m_Wbem.NWA( NULL ) );
pIDGroup->get_Path ( cbPath );
lComponentId = cbPath.GetComponentIdFromGroupPath ( );
Group.SetComponent ( lComponentId);
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitAddGroupNotification ( Group , m_cszNamespace ,
m_pCimomClient , &m_Wbem );
}
void CMOTEvent::DeleteGroupNotification( IDualGroup* pIDGroup )
{
CGroup Group;
CComponent Component;
BOOL bComponentId;
CBstr cbPath;
long lComponentId;
// create the group class to the greatest extent possible
Group.Read ( pIDGroup , TRUE , &bComponentId);
Group.SetNWA ( m_Wbem.NWA( NULL ) );
pIDGroup->get_Path ( cbPath );
lComponentId = cbPath.GetComponentIdFromGroupPath ( );
Group.SetComponent ( lComponentId);
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitDeleteGroupNotification ( Group , m_cszNamespace ,
m_pCimomClient , &m_Wbem );
}
void CMOTEvent::AddLanguageNotification( CVariant& cvLanguage )
{
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitAddLanguageNotification ( cvLanguage , m_cszNamespace ,
m_pCimomClient , &m_Wbem );
}
void CMOTEvent::DeleteLanguageNotification( CVariant& cvLanguage )
{
// alloc new job context
CAsyncJob* pJob = new CAsyncJob();
// init the job context with the pertinant data
pJob->InitDeleteLanguageNotification ( cvLanguage , m_cszNamespace ,
m_pCimomClient , &m_Wbem );
}
/// end mot events
/////////////// End MOT EVENTS /////////////////////////////////////////////////
void dmiEnableEvents ( LPWSTR wszNamespace , IWbemObjectSink* pIWbemSink )
{
SCODE result = WBEM_NO_ERROR;
VARIANT_BOOL vbResult;
CMOTEvent* pEvents = new CMOTEvent;
pEvents->Init ( wszNamespace , pIWbemSink );
CString cszConnect;
MakeConnectString ( pEvents->m_Wbem.NWA ( NULL ) , cszConnect );
// If the node already exists, we don't want to resubscribe for
// events.
if ( _fConnections->CheckIfAlready ( cszConnect ) )
{
delete pEvents;
pEvents = NULL;
return;
}
// pEvents->Init ( wszNamespace , pIWbemSink );
if ( FAILED ( CoCreateInstance (CLSID_MOTDmiEngine, NULL ,
CLSCTX_INPROC_SERVER , IID__DualDMIEngine, ( void ** ) &pEvents->m_pIEngine)))
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// 2. register our sink with the engine
IConnectionPointContainer* pCPC = NULL;
if ( FAILED ( pEvents->m_pIEngine->QueryInterface(
IID_IConnectionPointContainer, ( void ** ) &pCPC)))
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
result = pCPC->FindConnectionPoint(DIID__DDualintEvents, &pEvents->m_pConnPt);
RELEASE ( pCPC );
if ( FAILED ( result ) )
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
if ( FAILED ( pEvents->m_pConnPt->Advise( pEvents , &pEvents->m_dwEventCookie) ))
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
pEvents->m_pConnPt->AddRef() ;
if ( FAILED ( CoCreateInstance (CLSID_DMIMgmtNode, NULL , EXE_TYPE ,
IID_IDualMgmtNode , ( void ** ) &pEvents->m_pINode )))
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
CBstr cbConnect;
cbConnect.Set ( cszConnect );
result = pEvents->m_pINode->Connect( cbConnect , &vbResult);
if ( FAILED ( result ) || vbResult == VARIANT_FALSE)
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
// Register to recieve events
result = pEvents->m_pIEngine->EnableEvents ( pEvents->m_pINode, &vbResult );
if ( FAILED ( result ) || vbResult == VARIANT_FALSE )
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
result = pEvents->m_pIEngine->EnableNotifications ( pEvents->m_pINode, &vbResult );
if ( FAILED ( result ) || vbResult == VARIANT_FALSE )
{
throw CException ( WBEM_E_FAILED , IDS_EVENT_INIT_FAIL , IDS_GEN );
}
}
void dmiDisableEvents ( )
{
}
void dmiDeleteRow ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
CAttributes* pKeys , CDmiError* pError )
{
CRow Row;
CRows Rows;
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
// 1. contruct path to the group;
MakeConnectString( wszNWA, cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lComponent );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lGroup );
// 2. read the group
CDGroupI DGI;
CDRowsI DRSI;
DGI.CoCreate ();
DGI.Read ( cszPath );
// 3. Get the rows collection from which
// row is to be remove
DGI.GetRows ( DRSI );
// 5. now do the the remove
DRSI.Remove ( pKeys );
}
void dmiModifyRow ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
CAttributes* pKeys , CRow* pNewRow, CDmiError* )
{
SCODE result;
CString cszPath;
_fConnections->CheckIfAlready ( wszNWA );
// 1. contruct path to the row;
MakeConnectString( wszNWA, cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lComponent );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lGroup );
if ( pKeys->Empty () )
{
cszPath.Append ( PIPE_STR );
// if row is scalar
cszPath.Append ( SCALAR_STR );
}
else
{
CString cszT;
pKeys->GetMOTPath ( cszT );
cszPath.Append ( cszT );
}
// Contruct and read the row
CDRowI DRI;
DRI.CoCreate ( );
DRI.Read ( cszPath );
CDAttributesI DASI;
DRI.GetAttributes ( DASI );
pNewRow->m_Attributes.MoveToHead();
CAttribute* pAttribute = NULL;
CVariant cvId;
CVariant cvNewValue;
CVariant cvT;
while ( pAttribute = pNewRow->m_Attributes.Next() )
{
CDAttributeI DAI;
cvId.Clear ( );
cvNewValue.Clear ( );
cvT.Clear ( );
// change the sp data
if ( pAttribute->IsWritable () && VT_NULL != pAttribute->Value().GetType() )
{
cvId.Set ( pAttribute->Id() );
if ( FAILED ( result = DASI.p->get_Item ( cvId , DAI ) ) )
{
throw CException ( WBEM_E_FAILED , IDS_COMMITROW_FAIL ,
IDS_GETITEM_FAIL , CString ( result ) ) ;
}
cvNewValue.Set ( (LPVARIANT)pAttribute->Value() );
// debug only
// verify object by getting current value
result = DAI.p->get_Value ( cvT );
MOT_TRACE ( L"\tMOT...\tcurrent value of %s is %s" , pAttribute->Name() , cvT.GetBstr() );
// end debug
if ( FAILED ( result = DAI.p->put_Value( cvNewValue ) ))
{
MOT_TRACE ( L"\tMOT...\tput_Value ( %lu ) on %s returned %lX" ,
pAttribute->Value().GetLong() , pAttribute->Name() , result );
throw CException ( WBEM_E_FAILED , IDS_COMMITROW_FAIL ,
IDS_PUTVALUE_FAIL , CString ( result ) ) ;
}
MOT_TRACE ( L"\tMOT...\t%s = %s written without error" , pAttribute->Name() , cvNewValue.GetBstr() );
}
else
{
MOT_TRACE ( L"\tMOT...\t%s not writable" , pAttribute->Name() );
}
DAI.Release ( );
}
}
void dmiAddRow ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
CRow* pNewRow, CDmiError* )
{
/////////////////////////////////
_fConnections->CheckIfAlready ( wszNWA );
CString cszPath;
MakeConnectString( wszNWA, cszPath );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lComponent );
cszPath.Append ( PIPE_STR );
cszPath.Append ( lGroup );
STAT_TRACE ( L"\t\tMOT adding row to %s" , cszPath );
// Create the row object that will be added
CDRowI DRINewRow;
CDAttributesI DASINewRow;
DRINewRow.CoCreate ( );
// Populate the new row object
LONG lIndex = 0;
CAttribute* pAttribute = NULL;
LONG lTemp = 0;
DRINewRow.GetAttributes( DASINewRow);
LONG lCount = pNewRow->m_Attributes.GetCount();
pNewRow->m_Attributes.MoveToHead();
IDualAttribute** IAttributeArray = new IDualAttribute*[lCount];
while( pAttribute = pNewRow->m_Attributes.Next() )
{
DEV_TRACE (
L"\t\t Attribute %lu = %s attribute.value= %s",
pAttribute->Id(), pAttribute->Name(),
pAttribute->Value().GetBstr() );
if ( FAILED ( CoCreateInstance (CLSID_DMIAttribute, NULL , EXE_TYPE ,
IID_IDualAttribute , ( void ** ) &IAttributeArray[lIndex])))
{
throw CException ( WBEM_E_FAILED , IDS_ADD_ROW_FAIL ,
IDS_CC_FAIL );
}
CBstr cbName;
cbName.Set ( pAttribute->Name() );
IAttributeArray[lIndex]->put_Name( cbName );
IAttributeArray[lIndex]->put_Value( pAttribute->Value() );
IAttributeArray[lIndex]->put_id( pAttribute->Id() );
DASINewRow.p->Add(IAttributeArray[lIndex], &lTemp);
lIndex++;
}
// Get Group Object that will recieve new row
CDGroupI DGI;
CDRowsI DRSI;
DGI.CoCreate ();
DGI.Read ( cszPath );
DGI.GetRows( DRSI );
DRSI.Add ( DRINewRow );
/// release the attributes array
/* gpf's does the row release free the attribute I's
for( lIndex = 0; lIndex < lCount; lIndex++)
{
LONG l = IAttributeArray[lIndex]->Release ( );
MOT_TRACE ( L"IAttriubte relase returned %lu" , l );
delete [] IAttributeArray ;
}
*/
}