|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2002 Microsoft Corporation
//
// Module Name:
// ClusterService.cpp
//
// Description:
// Implementation of CClusterService class
//
// Author:
// Henry Wang (HenryWa) 19-JAN-2000
//
//////////////////////////////////////////////////////////////////////////////
#include "Pch.h"
#include "EventProv.h"
#include "EventProv.tmh"
#include "clustergroup.h"
//****************************************************************************
//
// CEventProv
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// CEventProv::CEventProv( void )
//
// Description:
// Constructor.
//
// Arguments:
// None.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
CEventProv::CEventProv( void ) : m_pNs( 0 ) , m_pSink( 0 ) , m_cRef( 0 ) , m_pEventAdd( 0 ) , m_pEventRemove( 0 ) , m_pEventState( 0 ) , m_pEventGroupState( 0 ) , m_pEventResourceState( 0 ) , m_pEventProperty( 0 ) , m_hThread( 0 ) , m_esStatus( esPENDING ) { UINT idx; for ( idx = 0; idx < EVENT_TABLE_SIZE ; idx++ ) { m_EventTypeTable[ idx ].m_pwco = NULL; m_EventTypeTable[ idx ].m_pfn = NULL; } InterlockedIncrement( &g_cObj );
} //*** CEventProv::CEventProv()
//////////////////////////////////////////////////////////////////////////////
//++
//
// CEventProv::!CEventProv( void )
//
// Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
CEventProv::~CEventProv( void ) { InterlockedDecrement( &g_cObj );
if ( m_hThread != NULL ) { CloseHandle( m_hThread ); }
if ( m_pNs != NULL ) { m_pNs->Release(); }
if ( m_pSink != NULL ) { m_pSink->Release(); }
if ( m_pEventAdd != NULL ) { m_pEventAdd->Release(); }
if ( m_pEventRemove != NULL ) { m_pEventRemove->Release(); }
if ( m_pEventState != NULL ) { m_pEventState->Release(); }
if ( m_pEventGroupState != NULL ) { m_pEventGroupState->Release(); }
if ( m_pEventResourceState != NULL ) { m_pEventResourceState->Release(); }
if ( m_pEventProperty != NULL ) { m_pEventProperty->Release(); }
} //*** CEventProv::~CEventProv()
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CEventProv::QueryInterface(
// REFIID riid,
// LPVOID * ppv
// )
//
// Description:
// Query for interfaces supported by this COM object.
//
// Arguments:
// riid -- Interface being queried for.
// ppv -- Pointer in which to return interface pointer.
//
// Return Values:
// NOERROR
// E_NOINTERFACE
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CEventProv::QueryInterface( REFIID riid, LPVOID * ppv ) { *ppv = 0;
if ( IID_IUnknown == riid || IID_IWbemEventProvider == riid ) { *ppv = (IWbemEventProvider *) this; AddRef(); return NOERROR; }
if ( IID_IWbemEventProviderSecurity == riid ) { *ppv = (IWbemEventProviderSecurity *) this; AddRef(); return NOERROR; }
if ( IID_IWbemProviderInit == riid ) { *ppv = (IWbemProviderInit *) this; AddRef(); return NOERROR; }
return E_NOINTERFACE;
} //*** CEventProv::QueryInterface()
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP_( ULONG )
// CEventProv::AddRef( void )
//
// Description:
// Add a reference to the COM object.
//
// Arguments:
// None.
//
// Return Values:
// New reference count.
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CEventProv::AddRef( void ) { return InterlockedIncrement( (LONG *) &m_cRef );
} //*** CEventProv::AddRef()
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP_( ULONG )
// CEventProv::Release( void )
//
// Description:
// Release a reference on the COM object.
//
// Arguments:
// None.
//
// Return Values:
// New reference count.
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CEventProv::Release( void ) { LONG cRef = InterlockedDecrement( (LONG *) &m_cRef ); if ( 0L == cRef ) { m_esStatus = esPENDING_STOP; CancelIo( m_hChange ); //
// wait for the thread completely stopped
//
while ( ! m_fStopped ) { Sleep( 100 ); } delete this; } return cRef;
} //*** CEventProv::Release()
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CEventProv::ProvideEvents(
// IWbemObjectSink * pSinkIn,
// long lFlagsIn
// )
//
// Description:
// Start the provider to generate event
// Called by wmi
//
// Arguments:
// pSinkIn -- WMI sink pointer to send event back
// lFlagsIn -- WMI flag
//
// Return Values:
// WBEM_NO_ERROR
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT CEventProv::ProvideEvents( IWbemObjectSink * pSinkIn, long lFlagsIn ) { DWORD dwTID; HRESULT hr = WBEM_NO_ERROR; // Copy the sink.
// ==============
m_pSink = pSinkIn; m_pSink->AddRef();
// Create the event thread.
// ========================
m_hThread = CreateThread( 0, 0, CEventProv::S_EventThread, this, 0, &dwTID );
// Wait for provider to be 'ready'.
// ================================
while ( m_esStatus != esRUNNING ) { Sleep( 100 ); }
return hr;
} //*** CEventProv::ProvideEvents
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CEventProv::AccessCheck(
// WBEM_CWSTR wszQueryLanguage,
// WBEM_CWSTR wszQuery,
// long lSidLength,
// const BYTE* pSid
// )
//
// Description:
// Checks the access permissions when a consumer attempts to subscribe to the event specified in wszQuery.
// The consumer is permitted to subscribe to the event if it has access permission for the event,
// otherwise subscription is prevented.
//
// Arguments:
// wszQueryLanguageIn -- Language of the following query filter. For this version of WMI, it will be "WQL".
// wszQueryIn -- Text of the event query filter, which was registered by a logical consumer.
// lSidLengthIn -- Integer that contains the SID length, or 0 if the subscription builder's token is available.
// pSidIn -- Pointer to the constant byte integer type that contains the SID, or NULL if the subscription
// builder's token is available.
//
// Return Values:
// WBEM_S_NO_ERROR -- The user has permission to subscribe to the event.
// WBEM_E_ACCESS_DENIED -- The user does not have permission to access the event.
// WBEM_E_FAILED -- Indicates a provider failure.
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT CEventProv::AccessCheck( WBEM_CWSTR wszQueryLanguageIn, WBEM_CWSTR wszQueryIn, long lSidLengthIn, const BYTE * pSidIn ) { HRESULT hr = WBEM_S_NO_ERROR; SAFECLUSTER shCluster;
//
// Impersonate the client and call OpenCluster
//
hr = CoImpersonateClient(); if( FAILED( hr ) ) { goto Cleanup; }
try { //
// OpenCluster should fail with ERROR_ACCESS_DENIED if the client in unprivileged.
// Otherwise it should succeed.
//
shCluster = OpenCluster( NULL ); } catch ( CProvException provException ) { hr = provException.hrGetError(); }
Cleanup:
//
// Based on the MSDN definition, this function has to return 1 of the 3 return values
// listed above in the function header, so let's make it happen.
//
if ( FAILED( hr ) ) { if ( hr == HRESULT_FROM_WIN32( ERROR_ACCESS_DENIED ) ) { hr = WBEM_E_ACCESS_DENIED; } else { hr = WBEM_E_FAILED; } } // if: FAILED( hr )
else { hr = WBEM_S_NO_ERROR; } // else: hr succeeded
return hr;
} //*** CEventProv::AccessCheck
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// DWORD
// WINAPI
// CEventProv::S_EventThread(
// LPVOID pArgIn
// )
//
// Description:
// Event thread proc.
//
// Arguments:
// pArgIn --
//
// Return Values:
// Any return values from CEventProv::InstanceThread().
//
//--
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CEventProv::S_EventThread( LPVOID pArgIn ) { // Make transition to the per-instance method.
// ===========================================
((CEventProv *) pArgIn)->InstanceThread(); return 0;
} //*** CEventProv::S_EventThread()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CEventProv::InstanceThread( void )
//
// Description:
// This function is started as seperated thread, waiting for cluster
// event notification and then send event back to wmi
//
// Arguments:
// None.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::InstanceThread( void ) { SAFECLUSTER shCluster; //SAFECHANGE shChange;
DWORD dwError; DWORD_PTR dwpNotifyKey; DWORD cchName = MAX_PATH; DWORD dwFilterType; CWstrBuf wsbName; CError er; DWORD cchReturnedName;
try { m_esStatus = esRUNNING; m_fStopped = FALSE; shCluster = OpenCluster( NULL ); m_hChange = CreateClusterNotifyPort( (HCHANGE) INVALID_HANDLE_VALUE, shCluster, ( cntCLUSTER_STATE_CHANGE | cntOBJECT_ADD | cntOBJECT_REMOVE | cntPROPERTY_CHANGE | cntGROUP_STATE_CHANGE | cntRESOURCE_STATE_CHANGE ), 1 );
wsbName.SetSize( cchName );
while ( m_esStatus == esRUNNING ) { cchReturnedName = cchName; wsbName.Empty(); // Null out the name field
//TracePrint(("Call GetClusterNotify to get next notification event\n"));
dwError = GetClusterNotify( m_hChange, &dwpNotifyKey, &dwFilterType, wsbName, &cchReturnedName, 400 );
if ( dwError == ERROR_MORE_DATA ) { cchName = ++cchReturnedName; wsbName.SetSize( cchName ); dwError = GetClusterNotify( m_hChange, &dwpNotifyKey, &dwFilterType, wsbName, &cchReturnedName, 400 ); } // if: more data
if ( dwError == ERROR_SUCCESS ) { CWbemClassObject wco; UINT idx; DWORD dwType; SEventTypeTable * pTypeEntry = NULL; //
// locate table index for the event type
//
dwType = dwFilterType; for ( idx = 0 ; (idx < EVENT_TABLE_SIZE) && ! ( dwType & 0x01 ) ; idx++ ) { dwType = dwType >> 1; } TracePrint(("Received <%ws> event, ChangeEvent = %!EventIdx!", wsbName, dwFilterType)); pTypeEntry = &m_EventTypeTable[ idx ]; if ( pTypeEntry->m_pwco != NULL ) { pTypeEntry->m_pwco->SpawnInstance( 0, &wco );
try { pTypeEntry->m_pfn( wco, pTypeEntry->m_pwszMof, //pwszName,
wsbName, pTypeEntry->m_eotObjectType, dwFilterType ); } // try
catch ( ... ) { TracePrint((" **** Exception on last Event call\n")); } // catch
} // if:
er = m_pSink->Indicate( 1, &wco );
} // if: success
} // while: running
} // try
catch( ... ) { TracePrint(("Exiting event provider loop! %lx\n", m_esStatus)); // bugbug: when error occured, event provider should be shut down,
// the provider should notify wmi and clean up.
// wmi doesn't handle this release call correctly.
m_pSink->Release(); //
// set it to null to provent being released again by destructor
//
m_pSink = NULL; } // catch
m_fStopped = TRUE; } //*** CEventProv::InstanceThread()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetEventProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set an event property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetEventProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { CObjPath op;
TracePrint(("Set event property for <%ws>:<%ws>, Event = %!EventIdx!", pwszMofClassNameIn, pwszObjectNameIn, dwEventMinorIn )); pwcoInout.SetProperty( pwszObjectNameIn, PVD_PROP_EVENT_NAME ); pwcoInout.SetProperty( static_cast< DWORD >( eotObjectTypeIn ), PVD_PROP_EVENT_TYPE ); pwcoInout.SetProperty( static_cast< DWORD >( 0 ), PVD_PROP_EVENT_TYPEMAJOR ); pwcoInout.SetProperty( dwEventMinorIn, PVD_PROP_EVENT_TYPEMINOR );
//
// setting object path
//
if ( ! op.Init( NULL ) ) { TracePrint((" **** Out of memory! Throwing exception.\n")); throw WBEM_E_OUT_OF_MEMORY; } op.SetClass( pwszMofClassNameIn );
//
// net interface objectpath is different from all the other objects
//
if ( eotObjectTypeIn == eotNET_INTERFACE ) { SAFECLUSTER shCluster; SAFENETINTERFACE shNetInterface; DWORD cbName = MAX_PATH; CWstrBuf wsbName; DWORD cbReturn; CError er;
shCluster = OpenCluster( NULL ); wsbName.SetSize( cbName ); shNetInterface = OpenClusterNetInterface( shCluster, pwszObjectNameIn );
//
// NOTE - I didn't handle error_more_data, since max_path should be
// large enough for node name
//
er = ClusterNetInterfaceControl( shNetInterface, NULL, CLUSCTL_NETINTERFACE_GET_NODE, NULL, 0, wsbName, cbName, &cbReturn );
op.AddProperty( PVD_PROP_NETINTERFACE_SYSTEMNAME, wsbName ); op.AddProperty( PVD_PROP_NETINTERFACE_DEVICEID, pwszObjectNameIn ); } //if: event is net interface
else { op.AddProperty( PVD_PROP_NAME, pwszObjectNameIn ); }
pwcoInout.SetProperty( static_cast< LPCWSTR >( op.GetObjectPathString() ), PVD_PROP_EVENT_PATH );
} //*** CEventProv::S_SetEventProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_AddEvent(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set an event property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_AddEvent( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) {
switch ( eotObjectTypeIn ) { case eotGROUP: case eotRESOURCE: case eotRESOURCE_TYPE: case eotNODE: case eotNETWORK: case eotNET_INTERFACE: {
TracePrint(("Add event for <%ws>:<%ws>, Event = %!EventIdx!\n", pwszMofClassNameIn, pwszObjectNameIn, dwEventMinorIn ));
S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
break; }
default: TracePrint(("Add object event for <%ws>:<%ws>, Event = %!EventIdx!\n", pwszMofClassNameIn, pwszObjectNameIn, dwEventMinorIn )); TracePrint((" **** Unknown Object Type!\n")); throw WBEM_E_INVALID_PARAMETER; }
return;
} //*** CEventProv::S_AddEvent()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_DeleteEvent(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set an event property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_DeleteEvent( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) {
switch ( eotObjectTypeIn ) { case eotGROUP: case eotRESOURCE: case eotRESOURCE_TYPE: case eotNODE: case eotNETWORK: case eotNET_INTERFACE: {
TracePrint(("Delete event for <%ws>:<%ws>, Event = %!EventIdx!\n", pwszMofClassNameIn, pwszObjectNameIn, dwEventMinorIn ));
S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
break; }
default: TracePrint(("Delete object event for <%ws>:<%ws>, Event = %!EventIdx!\n", pwszMofClassNameIn, pwszObjectNameIn, dwEventMinorIn )); TracePrint((" **** Unknown Object Type!\n")); throw WBEM_E_INVALID_PARAMETER; }
return;
} //*** CEventProv::S_DeleteEvent()
#if 0
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetClusterStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a node state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetClusterStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { DWORD dwState; DWORD dwError;
dwError = GetNodeClusterState( NULL, &dwState );
if ( dwError != ERROR_SUCCESS ) { TracePrint((" **** Failed to get the node cluster state. Throwing exception!\n")); throw CProvException( dwError ); }
pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetClusterStateProperty()
#endif
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetNodeStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a node state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetNodeStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { SAFECLUSTER shCluster; SAFENODE shNode; DWORD dwState;
shCluster = OpenCluster( NULL ); shNode = OpenClusterNode( shCluster, pwszObjectNameIn ); dwState = GetClusterNodeState( shNode );
if ( dwState == ClusterNodeStateUnknown ) { TracePrint((" **** SetNodeStateProperty... node state unknown. Throwing exception!\n")); throw CProvException( GetLastError() ); }
pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetNodeStateProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetNetworkStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a network state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetNetworkStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { SAFECLUSTER shCluster; SAFENETWORK shNetwork; DWORD dwState;
shCluster = OpenCluster( NULL ); shNetwork = OpenClusterNetwork( shCluster, pwszObjectNameIn ); dwState = GetClusterNetworkState( shNetwork ); if ( dwState == ClusterNetworkStateUnknown ) { TracePrint((" **** SetNetworkStateProperty... network state unknown. Throwing exception!\n")); throw CProvException( GetLastError() ); }
pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetNetworkStateProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetNetInterfaceStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a network interface state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetNetInterfaceStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { SAFECLUSTER shCluster; SAFENETINTERFACE shNetInterface; DWORD dwState;
shCluster = OpenCluster( NULL ); shNetInterface = OpenClusterNetInterface( shCluster, pwszObjectNameIn ); dwState = GetClusterNetInterfaceState( shNetInterface ); if ( dwState == ClusterNetInterfaceStateUnknown ) { TracePrint((" **** SetNetInterfaceStateProperty... network interface state unknown. Throwing exception!\n")); throw CProvException( GetLastError() ); }
pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetNetInterfaceStateProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetGroupStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a group state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetGroupStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { SAFECLUSTER shCluster; SAFEGROUP shGroup; DWORD dwState; DWORD cchName = MAX_PATH; CWstrBuf wsbNodeName;
wsbNodeName.SetSize( cchName ); shCluster = OpenCluster( NULL ); shGroup = OpenClusterGroup( shCluster, pwszObjectNameIn );
dwState = GetClusterGroupState( shGroup, wsbNodeName, &cchName ); if ( dwState == ClusterGroupStateUnknown ) { //
// BUGBUG I am not handling error_more_data here, since it's not possible that
// nodeName exceed MAX_PATH, assuming it use netbios name
//
TracePrint(("ClusterGroup State is UNKNOWN. Throwing exception!\n")); throw CProvException( GetLastError() ); } else { TracePrint(("Setting group state for group <%ws> to %!GroupState!\n", pwszObjectNameIn, dwState )); pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); pwcoInout.SetProperty( wsbNodeName, PVD_PROP_EVENT_NODE ); }
S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetGroupStateProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// void
// CEventProv::S_SetResourceStateProperty(
// CWbemClassObject & pwcoInout,
// LPCWSTR pwszMofClassNameIn,
// LPCWSTR pwszObjectNameIn,
// EEventObjectType eotObjectTypeIn,
// DWORD dwEventMinorIn
// )
//
// Description:
// Set a resource state property.
//
// Arguments:
// pwcoInout --
// pwszMofClassNameIn --
// pwszObjectNameIn --
// eotObjectTypeIn --
// dwEventMinorIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::S_SetResourceStateProperty( CWbemClassObject & pwcoInout, LPCWSTR pwszMofClassNameIn, LPCWSTR pwszObjectNameIn, EEventObjectType eotObjectTypeIn, DWORD dwEventMinorIn ) { SAFECLUSTER shCluster; SAFERESOURCE shResource; DWORD dwState; DWORD cchNodeName = MAX_PATH; CWstrBuf wsbNodeName; DWORD cchGroupName = MAX_PATH; CWstrBuf wsbGroupName;
shCluster = OpenCluster( NULL ); wsbNodeName.SetSize( cchNodeName ); wsbGroupName.SetSize( cchGroupName ); shResource = OpenClusterResource( shCluster, pwszObjectNameIn ); if ( !shResource.BIsNULL() ) { dwState = GetClusterResourceState( shResource, wsbNodeName, &cchNodeName, wsbGroupName, &cchGroupName ); } else { dwState = (DWORD) ClusterResourceStateUnknown; }
TracePrint(("Setting resource state for resource <%ws> to %!ResourceState!\n", pwszObjectNameIn, dwState )); pwcoInout.SetProperty( dwState, PVD_PROP_EVENT_NEWSTATE ); pwcoInout.SetProperty( wsbNodeName, PVD_PROP_EVENT_NODE ); pwcoInout.SetProperty( wsbGroupName, PVD_PROP_EVENT_GROUP );
S_SetEventProperty( pwcoInout, pwszMofClassNameIn, pwszObjectNameIn, eotObjectTypeIn, dwEventMinorIn );
return;
} //*** CEventProv::S_SetResourceStateProperty()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CEventProv::InsertTable(
// DWORD dwIdxIn,
// CLUSTER_CHANGE eTypeIn,
// EEventObjectType eotObjectTypeIn,
// LPCWSTR pwszMofIn,
// IWbemClassObject * pwcoIn,
// FPSETPROP pfnIn
// )
//
// Description:
// Insert values in the event table.
//
// Arguments:
// dwIdxIn --
// eTypeIn --
// eotObjectTypeIn --
// pwszMofIn --
// pwcoIn --
// pfnIn --
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CEventProv::InsertTable( DWORD dwIdxIn, CLUSTER_CHANGE eTypeIn, EEventObjectType eotObjectTypeIn, LPCWSTR pwszMofIn, IWbemClassObject * pwcoIn, FPSETPROP pfnIn ) { m_EventTypeTable[ dwIdxIn ].m_eType = eTypeIn; m_EventTypeTable[ dwIdxIn ].m_eotObjectType = eotObjectTypeIn; m_EventTypeTable[ dwIdxIn ].m_pwszMof = pwszMofIn; m_EventTypeTable[ dwIdxIn ].m_pwco = pwcoIn; m_EventTypeTable[ dwIdxIn ].m_pfn= pfnIn;
return;
} //*** CEventProv::InsertTable()
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CEventProv::Initialize(
// LPWSTR pwszUserIn,
// LONG lFlagsIn,
// LPWSTR pwszNamespaceIn,
// LPWSTR pwszLocaleIn,
// IWbemServices * pNamespaceIn,
// IWbemContext * pCtxIn,
// IWbemProviderInitSink * pInitSinkIn
// )
//
// Description:
// Initializing the provider by setting up a lookup table.
// called by wmi only once to create provider object.
//
// Arguments:
// pwszUserIn -- User name
// lFlagsIn -- WMI flag
// pwszNamespaceIn -- Name space
// pwszLocaleIn -- Locale string
// pCtxIn -- WMI context
// pInitSinkIn -- WMI sink pointer
//
// Return Values:
// WBEM_NO_ERROR
// WBEM_E_FAILED
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT CEventProv::Initialize( LPWSTR pwszUserIn, LONG lFlagsIn, LPWSTR pwszNamespaceIn, LPWSTR pwszLocaleIn, IWbemServices * pNamespaceIn, IWbemContext * pCtxIn, IWbemProviderInitSink * pInitSinkIn ) { HRESULT hr; CError er;
UNREFERENCED_PARAMETER( pwszUserIn ); UNREFERENCED_PARAMETER( lFlagsIn ); UNREFERENCED_PARAMETER( pwszNamespaceIn ); UNREFERENCED_PARAMETER( pwszLocaleIn );
m_pNs = pNamespaceIn; m_pNs->AddRef();
//
// Grab the class definition for the event.
//
try { er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_ADD ), 0, pCtxIn, &m_pEventAdd, 0 ); er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_REMOVE ), 0, pCtxIn, &m_pEventRemove, 0 ); er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_STATECHANGE ), 0, pCtxIn, &m_pEventState, 0 ); er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_GROUPSTATECHANGE ), 0, pCtxIn, &m_pEventGroupState, 0 ); er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_RESOURCESTATECHANGE ), 0, pCtxIn, &m_pEventResourceState, 0 ); #if 0
er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_NODESTATECHANGE ), 0, pCtxIn, &m_pEventNodeState, 0 ); #endif
er = m_pNs->GetObject( _bstr_t( PVD_CLASS_EVENT_PROP ), 0, pCtxIn, &m_pEventProperty, 0 );
//
// initialize mapping table
//
//
// node events
//
InsertTable( 0, CLUSTER_CHANGE_NODE_STATE, eotNODE, PVD_CLASS_NODE, m_pEventState, S_SetNodeStateProperty ); InsertTable( 1, CLUSTER_CHANGE_NODE_DELETED, eotNODE, PVD_CLASS_NODE, m_pEventRemove, S_SetEventProperty ); InsertTable( 2, CLUSTER_CHANGE_NODE_ADDED, eotNODE, PVD_CLASS_NODE, m_pEventAdd, S_SetEventProperty ); InsertTable( 3, CLUSTER_CHANGE_NODE_PROPERTY, eotNODE, PVD_CLASS_NODE, m_pEventProperty, S_SetEventProperty ); //
// registry event, don't care
//
//
// Resource
//
InsertTable( 8, CLUSTER_CHANGE_RESOURCE_STATE, eotRESOURCE, PVD_CLASS_RESOURCE, m_pEventResourceState, S_SetResourceStateProperty ); InsertTable( 9, CLUSTER_CHANGE_RESOURCE_DELETED, eotRESOURCE, PVD_CLASS_RESOURCE, m_pEventRemove, S_DeleteEvent ); InsertTable( 10, CLUSTER_CHANGE_RESOURCE_ADDED, eotRESOURCE, PVD_CLASS_RESOURCE, m_pEventAdd, S_AddEvent ); InsertTable( 11, CLUSTER_CHANGE_RESOURCE_PROPERTY, eotRESOURCE, PVD_CLASS_RESOURCE, m_pEventProperty, S_SetEventProperty ); //
// group
//
InsertTable( 12, CLUSTER_CHANGE_GROUP_STATE, eotGROUP, PVD_CLASS_GROUP, m_pEventGroupState, S_SetGroupStateProperty ); InsertTable( 13, CLUSTER_CHANGE_GROUP_DELETED, eotGROUP, PVD_CLASS_GROUP, m_pEventRemove, S_DeleteEvent ); InsertTable( 14, CLUSTER_CHANGE_GROUP_ADDED, eotGROUP, PVD_CLASS_GROUP, m_pEventAdd, S_AddEvent ); InsertTable( 15, CLUSTER_CHANGE_GROUP_PROPERTY, eotGROUP, PVD_CLASS_GROUP, m_pEventProperty, S_SetEventProperty );
//
// Resource Type
//
InsertTable( 16, CLUSTER_CHANGE_RESOURCE_TYPE_DELETED, eotRESOURCE_TYPE, PVD_CLASS_RESOURCETYPE, m_pEventRemove, S_SetEventProperty ); InsertTable( 17, CLUSTER_CHANGE_RESOURCE_TYPE_ADDED, eotRESOURCE_TYPE, PVD_CLASS_RESOURCETYPE, m_pEventAdd, S_SetEventProperty ); InsertTable( 18, CLUSTER_CHANGE_RESOURCE_TYPE_PROPERTY, eotRESOURCE_TYPE, PVD_CLASS_RESOURCETYPE, m_pEventProperty, S_SetEventProperty );
//
// skip 19 - CLUSTER_CHANGE_CLUSTER_RECONNECT
//
//
// network
//
InsertTable( 20, CLUSTER_CHANGE_NETWORK_STATE, eotNETWORK, PVD_CLASS_NETWORK, m_pEventState, S_SetNetworkStateProperty ); InsertTable( 21, CLUSTER_CHANGE_NETWORK_DELETED, eotNETWORK, PVD_CLASS_NETWORK, m_pEventRemove, S_SetEventProperty ); InsertTable( 22, CLUSTER_CHANGE_NETWORK_ADDED, eotNETWORK, PVD_CLASS_NETWORK, m_pEventAdd, S_SetEventProperty ); InsertTable( 23, CLUSTER_CHANGE_NETWORK_PROPERTY, eotNETWORK, PVD_CLASS_NETWORK, m_pEventProperty, S_SetEventProperty ); //
// net interface
//
InsertTable( 24, CLUSTER_CHANGE_NETINTERFACE_STATE, eotNET_INTERFACE, PVD_CLASS_NETWORKINTERFACE, m_pEventState, S_SetNetInterfaceStateProperty ); InsertTable( 25, CLUSTER_CHANGE_NETINTERFACE_DELETED, eotNET_INTERFACE, PVD_CLASS_NETWORKINTERFACE, m_pEventRemove, S_SetEventProperty ); InsertTable( 26, CLUSTER_CHANGE_NETINTERFACE_ADDED, eotNET_INTERFACE, PVD_CLASS_NETWORKINTERFACE, m_pEventAdd, S_SetEventProperty ); InsertTable( 27, CLUSTER_CHANGE_NETINTERFACE_PROPERTY, eotNET_INTERFACE, PVD_CLASS_NETWORKINTERFACE, m_pEventProperty, S_SetEventProperty ); //
// other
//
InsertTable( 28, CLUSTER_CHANGE_QUORUM_STATE, eotQUORUM, PVD_CLASS_RESOURCE, m_pEventState, S_SetResourceStateProperty ); /* InsertTable(
29, CLUSTER_CHANGE_CLUSTER_STATE, eotCLUSTER, PVD_CLASS_CLUSTER, m_pEventState, S_SetClusterStateProperty ); */ InsertTable( 30, CLUSTER_CHANGE_CLUSTER_PROPERTY, eotCLUSTER, PVD_CLASS_CLUSTER, m_pEventProperty, S_SetEventProperty ); //
// skip 31 - CLUSTER_CHANGE_HANDLE_CLOSE
//
// Tell CIMOM that we're up and running.
// =====================================
hr = WBEM_S_INITIALIZED; } // try
catch ( ... ) { hr = WBEM_E_FAILED; } // catch
pInitSinkIn->SetStatus( hr, 0 ); return WBEM_S_NO_ERROR;
} //*** CEventProv::Initialize()
//////////////////////////////////////////////////////////////////////////////
//++
//
// static
// HRESULT
// CEventProv::S_HrCreateThis(
// IUnknown * pUnknownOuterIn,
// VOID ** ppvOut
// )
//
// Description:
// Create a CEventProv object.
//
// Arguments:
// pUnknownOutIn --
// ppvOut --
//
// Return Values:
// S_OK
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT CEventProv::S_HrCreateThis( IUnknown * pUnknownOuterIn, VOID ** ppvOut ) { *ppvOut = new CEventProv(); return S_OK;
} //*** CEventProv::S_HrCreateThis()
|