////////////////////////////////////////////////////////////////////////////// // // 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( )