windows-nt/Source/XPSP1/NT/base/cluster/mgmt/cluscfg/middletier/servicemanager.cpp
2020-09-26 16:20:57 +08:00

596 lines
16 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2001 Microsoft Corporation
//
// Module Name:
// ServiceMgr.cpp
//
// Description:
// Service Manager implementation.
//
// Documentation:
// Yes.
//
// Maintained By:
// Galen Barbee (GalenB) 22-NOV-1999
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
// #include "ServiceMgr.h" - already included in DLL.H
DEFINE_THISCLASS("CServiceManager")
#define CServiceManager CServiceManager
#define LPTHISCLASS CServiceManager *
//****************************************************************************
//
// Protected Global
//
//****************************************************************************
IServiceProvider * g_pspServiceManager = NULL;
//****************************************************************************
//
// Class Static Variables
//
//****************************************************************************
CRITICAL_SECTION * CServiceManager::sm_pcs = NULL;
BOOL CServiceManager::sm_fShutDown = FALSE;
//****************************************************************************
//
// Constructor / Destructor
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// HRESULT
// CServiceManager::S_HrCreateInstance(
// IUnknown ** ppunkOut
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CServiceManager::S_HrCreateInstance(
IUnknown ** ppunkOut
)
{
TraceFunc( "" );
Assert( ppunkOut != NULL );
HRESULT hr;
LPUNKNOWN punk = NULL;
//
// Create a critical section to prevent lines from being fragmented.
//
if ( CServiceManager::sm_pcs == NULL )
{
PCRITICAL_SECTION pNewCritSect =
(PCRITICAL_SECTION) HeapAlloc( GetProcessHeap(), 0, sizeof( CRITICAL_SECTION ) );
if ( pNewCritSect == NULL )
{
hr = E_OUTOFMEMORY;
goto Cleanup;
} // if: creation failed
InitializeCriticalSection( pNewCritSect );
// Make sure we only have one log critical section
InterlockedCompareExchangePointer( (PVOID *) &CServiceManager::sm_pcs, pNewCritSect, 0 );
if ( CServiceManager::sm_pcs != pNewCritSect )
{
DeleteCriticalSection( pNewCritSect );
HeapFree( GetProcessHeap(), 0, pNewCritSect );
} // if: already have another critical section
} // if: no critical section created yet
Assert( CServiceManager::sm_pcs != NULL );
EnterCriticalSection( CServiceManager::sm_pcs );
if ( g_pspServiceManager != NULL )
{
hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
} // if: assign new service manager
else
{
LPTHISCLASS pthis = new CServiceManager( );
if ( pthis != NULL )
{
//
// Can't hold CS in Init.
//
LeaveCriticalSection( CServiceManager::sm_pcs );
hr = THR( pthis->Init( ) );
if ( SUCCEEDED( hr ) )
{
EnterCriticalSection( CServiceManager::sm_pcs );
if ( g_pspServiceManager == NULL )
{
// No REF - or we'll never die!
g_pspServiceManager = static_cast< IServiceProvider * >( pthis );
TraceMoveToMemoryList( g_pspServiceManager, g_GlobalMemoryList );
}
if ( SUCCEEDED( hr ) )
{
hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
}
} // if: its our pointer
} // if: got object
pthis->Release( );
} // else: create new one
LeaveCriticalSection( CServiceManager::sm_pcs );
Cleanup:
HRETURN( hr );
} //*** CServiceManager::S_HrCreateInstance( )
//////////////////////////////////////////////////////////////////////////////
//
// CServiceManager::CServiceManager( void )
//
//////////////////////////////////////////////////////////////////////////////
CServiceManager::CServiceManager( void )
{
TraceFunc( "" );
InterlockedIncrement( &g_cObjects );
TraceFuncExit();
} //*** CServiceManager::CServiceManager( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CServiceManager::Init( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CServiceManager::Init( void )
{
TraceFunc( "" );
HRESULT hr;
ITaskManager * ptm = NULL;
IDoTask * pdt = NULL;
IObjectManager * pom = NULL;
INotificationManager * pnm = NULL;
IConnectionManager * pcm = NULL;
ILogManager * plm = NULL;
// IUnknown stuff
Assert( m_cRef == 0 );
AddRef( );
// IServiceProvider
Assert( m_dwLogManagerCookie == 0 );
Assert( m_dwConnectionManagerCookie == 0 );
Assert( m_dwNotificationManagerCookie == 0 );
Assert( m_dwObjectManagerCookie == 0 );
Assert( m_dwTaskManagerCookie == 0 );
Assert( m_pgit == NULL );
// IServiceProvider stuff
hr = THR( HrCoCreateInternalInstance( CLSID_ObjectManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IObjectManager, &pom ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( HrCoCreateInternalInstance( CLSID_TaskManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( ITaskManager, &ptm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( HrCoCreateInternalInstance( CLSID_NotificationManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( INotificationManager, &pnm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( HrCoCreateInternalInstance( CLSID_ClusterConnectionManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IConnectionManager, &pcm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( HrCoCreateInternalInstance( CLSID_LogManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( ILogManager, &plm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Store the interfaces in the GIT.
//
hr = THR( CoCreateInstance(
CLSID_StdGlobalInterfaceTable
, NULL
, CLSCTX_INPROC_SERVER
, IID_IGlobalInterfaceTable
, reinterpret_cast< void ** >( &m_pgit )
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( m_pgit->RegisterInterfaceInGlobal( pom, IID_IObjectManager, &m_dwObjectManagerCookie ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( m_pgit->RegisterInterfaceInGlobal( ptm, IID_ITaskManager, &m_dwTaskManagerCookie ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( m_pgit->RegisterInterfaceInGlobal( pnm, IID_INotificationManager, &m_dwNotificationManagerCookie ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( m_pgit->RegisterInterfaceInGlobal( pcm, IID_IConnectionManager, &m_dwConnectionManagerCookie ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( m_pgit->RegisterInterfaceInGlobal( plm, IID_ILogManager, &m_dwLogManagerCookie ) );
if ( FAILED( hr ) )
goto Cleanup;
Cleanup:
if ( pom != NULL )
{
pom->Release( );
}
if ( pnm != NULL )
{
pnm->Release( );
}
if ( pcm != NULL )
{
pcm->Release( );
}
if ( plm != NULL )
{
plm->Release( );
}
if ( ptm != NULL )
{
ptm->Release( );
}
if ( pdt != NULL )
{
pdt->Release( );
}
HRETURN( hr );
} //*** CServiceManager::Init( )
//////////////////////////////////////////////////////////////////////////////
//
// CServiceManager::~CServiceManager( void )
//
//////////////////////////////////////////////////////////////////////////////
CServiceManager::~CServiceManager( void )
{
TraceFunc( "" );
//HRESULT hr;
//ITaskManager * ptm = NULL;
//IDoTask * pdt = NULL;
//IObjectManager * pom = NULL;
//INotificationManager * pnm = NULL;
//IConnectionManager * pcm = NULL;
//ILogManager * plm = NULL;
//
// Indicate that we are shutting down.
//
sm_fShutDown = TRUE;
EnterCriticalSection( CServiceManager::sm_pcs );
if ( g_pspServiceManager == static_cast< IServiceProvider * >( this ) )
{
TraceMoveFromMemoryList( g_pspServiceManager, g_GlobalMemoryList );
g_pspServiceManager = NULL;
} // if: its our pointer
if ( m_pgit != NULL )
{
if ( m_dwLogManagerCookie != 0 )
{
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwLogManagerCookie ) );
}
if ( m_dwConnectionManagerCookie != 0 )
{
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwConnectionManagerCookie ) );
}
if ( m_dwNotificationManagerCookie != 0 )
{
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwNotificationManagerCookie ) );
}
if ( m_dwObjectManagerCookie != 0 )
{
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwObjectManagerCookie ) );
}
if ( m_dwTaskManagerCookie != 0 )
{
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwTaskManagerCookie ) );
}
m_pgit->Release( );
}
LeaveCriticalSection( CServiceManager::sm_pcs );
//
// TODO: gpease 01-AUG-2000
// Figure out a way to free the CS.
//
InterlockedDecrement( &g_cObjects );
TraceFuncExit();
} //*** CServiceManager::~CServiceManager( )
//****************************************************************************
//
// IUnknown
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CServiceManager::QueryInterface(
// REFIID riidIn,
// LPVOID *ppvOut
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CServiceManager::QueryInterface(
REFIID riidIn,
LPVOID *ppvOut
)
{
TraceQIFunc( riidIn, ppvOut );
HRESULT hr = E_NOINTERFACE;
if ( IsEqualIID( riidIn, IID_IUnknown ) )
{
*ppvOut = static_cast< LPUNKNOWN >( this );
hr = S_OK;
} // if: IUnknown
else if ( IsEqualIID( riidIn, IID_IServiceProvider ) )
{
*ppvOut = TraceInterface( __THISCLASS__, IServiceProvider, this, 0 );
hr = S_OK;
} // else if: IQueryService
if ( SUCCEEDED( hr ) )
{
((IUnknown*) *ppvOut)->AddRef( );
} // if: success
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
} //*** CServiceManager::QueryInterface( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP_( ULONG )
// CServiceManager::AddRef( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CServiceManager::AddRef( void )
{
TraceFunc( "[IUnknown]" );
InterlockedIncrement( &m_cRef );
RETURN( m_cRef );
} //*** CServiceManager::AddRef( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP_( ULONG )
// CServiceManager::Release( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CServiceManager::Release( void )
{
TraceFunc( "[IUnknown]" );
LONG cRef;
InterlockedDecrement( &m_cRef );
cRef = m_cRef;
if ( cRef == 0 )
{
TraceDo( delete this );
}
RETURN( cRef );
} //*** CServiceManager::Release( )
//****************************************************************************
//
// IServiceProvider
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CServiceManager::QueryService(
// REFCLSID rclsidIn,
// REFIID riidInIn,
// void ** ppvOutOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CServiceManager::QueryService(
REFCLSID rclsidIn,
REFIID riidInIn,
void ** ppvOutOut
)
{
TraceFunc( "[IServiceProvider]" );
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
if ( m_pgit != NULL )
{
if ( IsEqualIID( rclsidIn, CLSID_ObjectManager ) )
{
IObjectManager * pom;
hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwObjectManagerCookie, TypeSafeParams( IObjectManager, &pom ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( pom->QueryInterface( riidInIn, ppvOutOut ) );
pom->Release( );
// fall thru
}
else if ( IsEqualIID( rclsidIn, CLSID_TaskManager ) )
{
ITaskManager * ptm;
hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwTaskManagerCookie, TypeSafeParams( ITaskManager, &ptm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( ptm->QueryInterface( riidInIn, ppvOutOut ) );
ptm->Release( );
// fall thru
}
else if ( IsEqualIID( rclsidIn, CLSID_NotificationManager ) )
{
INotificationManager * pnm;
hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwNotificationManagerCookie, TypeSafeParams( INotificationManager, &pnm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( pnm->QueryInterface( riidInIn, ppvOutOut ) );
pnm->Release( );
// fall thru
}
else if ( IsEqualIID( rclsidIn, CLSID_ClusterConnectionManager ) )
{
IConnectionManager * pcm;
hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwConnectionManagerCookie, TypeSafeParams( IConnectionManager, &pcm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( pcm->QueryInterface( riidInIn, ppvOutOut ) );
pcm->Release( );
// fall thru
}
else if ( IsEqualIID( rclsidIn, CLSID_LogManager ) )
{
ILogManager * plm;
hr = THR( m_pgit->GetInterfaceFromGlobal( m_dwLogManagerCookie, TypeSafeParams( ILogManager, &plm ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( plm->QueryInterface( riidInIn, ppvOutOut ) );
plm->Release( );
// fall thru
}
}
Cleanup:
HRETURN( hr );
} //*** CServiceManager::QueryService( )
//****************************************************************************
//
// Private Methods
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CServiceManager::S_HrGetManagerPointer(
// IServiceProvider ** ppspOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CServiceManager::S_HrGetManagerPointer(
IServiceProvider ** ppspOut
)
{
TraceFunc( "ppspOut" );
HRESULT hr = HRESULT_FROM_WIN32( ERROR_PROCESS_ABORTED );
if ( CServiceManager::sm_fShutDown == FALSE )
{
EnterCriticalSection( CServiceManager::sm_pcs );
if ( g_pspServiceManager != NULL )
{
*ppspOut = TraceInterface( __THISCLASS__,
IServiceProvider,
g_pspServiceManager,
0
);
(*ppspOut)->AddRef( );
hr = S_OK;
} // if: valid service manager
else
{
hr = E_POINTER;
} // else: no pointer
LeaveCriticalSection( CServiceManager::sm_pcs );
} // if: still up
HRETURN ( hr );
} //*** CServiceManager::S_HrGetManagerPointer( )