You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
692 lines
17 KiB
692 lines
17 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1999-2002 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_cs;
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Constructor / Destructor
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// HRESULT
|
|
// CServiceManager::S_HrCreateInstance(
|
|
// IUnknown ** ppunkOut
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CServiceManager::S_HrCreateInstance(
|
|
IUnknown ** ppunkOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
LPTHISCLASS pthis = NULL;
|
|
|
|
EnterCriticalSection( &sm_cs );
|
|
|
|
Assert( ppunkOut != NULL );
|
|
if ( ppunkOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( g_pspServiceManager != NULL )
|
|
{
|
|
hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
|
|
goto Cleanup;
|
|
} // if: assign new service manager
|
|
|
|
pthis = new CServiceManager();
|
|
if ( pthis == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
//
|
|
// Can't hold CS in Init.
|
|
//
|
|
LeaveCriticalSection( &sm_cs );
|
|
|
|
hr = THR( pthis->HrInit() );
|
|
EnterCriticalSection( &sm_cs );
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Assert( g_pspServiceManager == NULL );
|
|
|
|
// No REF - or we'll never die!
|
|
g_pspServiceManager = static_cast< IServiceProvider * >( pthis );
|
|
TraceMoveToMemoryList( g_pspServiceManager, g_GlobalMemoryList );
|
|
|
|
hr = THR( g_pspServiceManager->TypeSafeQI( IUnknown, ppunkOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if ( pthis != NULL )
|
|
{
|
|
pthis->Release();
|
|
} // if:
|
|
|
|
LeaveCriticalSection( &sm_cs );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CServiceManager::S_HrCreateInstance
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// HRESULT
|
|
// CServiceManager::S_HrGetManagerPointer( IServiceProvider ** ppspOut )
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CServiceManager::S_HrGetManagerPointer( IServiceProvider ** ppspOut )
|
|
{
|
|
TraceFunc( "ppspOut" );
|
|
|
|
HRESULT hr = HRESULT_FROM_WIN32( ERROR_PROCESS_ABORTED );
|
|
|
|
EnterCriticalSection( &sm_cs );
|
|
|
|
if ( g_pspServiceManager != NULL )
|
|
{
|
|
g_pspServiceManager->AddRef();
|
|
*ppspOut = g_pspServiceManager;
|
|
hr = S_OK;
|
|
} // if: valid service manager
|
|
else
|
|
{
|
|
//
|
|
// KB 18-JUN-2001 DavidP
|
|
// Don't wrap this with THR because it is expected to return
|
|
// E_POINTER on the very first call.
|
|
//
|
|
hr = E_POINTER;
|
|
} // else: no pointer
|
|
|
|
LeaveCriticalSection( &sm_cs );
|
|
|
|
HRETURN ( hr );
|
|
|
|
} //*** CServiceManager::S_HrGetManagerPointer
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CServiceManager::S_HrProcessInitialize
|
|
//
|
|
// Description:
|
|
// Do process initialization by intializing the critical section.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
//
|
|
// Remarks:
|
|
// This function is called from DllMain() when DLL_PROCESS_ATTACH
|
|
// is sent. This function is needed because we need a known point
|
|
// to create a critical section that synchronizes the creation and
|
|
// deletion of this object. Given this object's life cycle and
|
|
// static creator function it is possible to have a race when this
|
|
// object is destrying itself with the static creator function.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CServiceManager::S_HrProcessInitialize( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( InitializeCriticalSectionAndSpinCount( &sm_cs, RECOMMENDED_SPIN_COUNT ) == 0 )
|
|
{
|
|
DWORD scLastError = TW32( GetLastError() );
|
|
hr = HRESULT_FROM_WIN32( scLastError );
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CServiceManager::S_HrProcessInitialize
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CServiceManager::S_HrProcessUninitialize
|
|
//
|
|
// Description:
|
|
// Do process uninitialization by deleting the critical section.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
//
|
|
// Remarks:
|
|
// Delete the critical section that sychronizes the creation and
|
|
// deletion code.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CServiceManager::S_HrProcessUninitialize( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
DeleteCriticalSection( &sm_cs );
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CServiceManager::S_HrProcessUninitialize
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CServiceManager::CServiceManager
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CServiceManager::CServiceManager( void )
|
|
: m_cRef( 1 )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
InterlockedIncrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CServiceManager::CServiceManager
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// HRESULT
|
|
// CServiceManager::HrInit
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CServiceManager::HrInit( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr;
|
|
|
|
ITaskManager * ptm = NULL;
|
|
IDoTask * pdt = NULL;
|
|
IObjectManager * pom = NULL;
|
|
INotificationManager * pnm = NULL;
|
|
IConnectionManager * pcm = NULL;
|
|
ILogManager * plm = NULL;
|
|
|
|
// IUnknown
|
|
Assert( m_cRef == 1 );
|
|
|
|
// 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:
|
|
|
|
if ( pnm != NULL )
|
|
{
|
|
pnm->Release();
|
|
} // if:
|
|
|
|
if ( pcm != NULL )
|
|
{
|
|
pcm->Release();
|
|
} // if:
|
|
|
|
if ( plm != NULL )
|
|
{
|
|
plm->Release();
|
|
} // if:
|
|
|
|
if ( ptm != NULL )
|
|
{
|
|
ptm->Release();
|
|
} // if:
|
|
|
|
if ( pdt != NULL )
|
|
{
|
|
pdt->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CServiceManager::HrInit
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CServiceManager::~CServiceManager
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CServiceManager::~CServiceManager( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
EnterCriticalSection( &sm_cs );
|
|
|
|
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:
|
|
|
|
if ( m_dwConnectionManagerCookie != 0 )
|
|
{
|
|
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwConnectionManagerCookie ) );
|
|
} // if:
|
|
|
|
if ( m_dwNotificationManagerCookie != 0 )
|
|
{
|
|
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwNotificationManagerCookie ) );
|
|
} // if:
|
|
|
|
if ( m_dwObjectManagerCookie != 0 )
|
|
{
|
|
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwObjectManagerCookie ) );
|
|
} // if:
|
|
|
|
if ( m_dwTaskManagerCookie != 0 )
|
|
{
|
|
THR( m_pgit->RevokeInterfaceFromGlobal( m_dwTaskManagerCookie ) );
|
|
} // if:
|
|
|
|
m_pgit->Release();
|
|
} // if:
|
|
|
|
InterlockedDecrement( &g_cObjects );
|
|
|
|
LeaveCriticalSection( &sm_cs );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CServiceManager::~CServiceManager
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IUnknown
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CServiceManager::QueryInterface
|
|
//
|
|
// Description:
|
|
// Query this object for the passed in interface.
|
|
//
|
|
// Arguments:
|
|
// riidIn
|
|
// Id of interface requested.
|
|
//
|
|
// ppvOut
|
|
// Pointer to the requested interface.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// If the interface is available on this object.
|
|
//
|
|
// E_NOINTERFACE
|
|
// If the interface is not available.
|
|
//
|
|
// E_POINTER
|
|
// ppvOut was NULL.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CServiceManager::QueryInterface(
|
|
REFIID riidIn
|
|
, LPVOID * ppvOut
|
|
)
|
|
{
|
|
TraceQIFunc( riidIn, ppvOut );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Validate arguments.
|
|
//
|
|
|
|
Assert( ppvOut != NULL );
|
|
if ( ppvOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Handle known interfaces.
|
|
//
|
|
|
|
if ( IsEqualIID( riidIn, IID_IUnknown ) )
|
|
{
|
|
*ppvOut = static_cast< LPUNKNOWN >( this );
|
|
} // if: IUnknown
|
|
else if ( IsEqualIID( riidIn, IID_IServiceProvider ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IServiceProvider, this, 0 );
|
|
} // else if: IQueryService
|
|
else
|
|
{
|
|
*ppvOut = NULL;
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
//
|
|
// Add a reference to the interface if successful.
|
|
//
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
((IUnknown *) *ppvOut)->AddRef();
|
|
} // if: success
|
|
|
|
Cleanup:
|
|
|
|
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
|
|
|
|
} //*** CServiceManager::QueryInterface
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP_( ULONG )
|
|
// CServiceManager::AddRef
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CServiceManager::AddRef( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
InterlockedIncrement( &m_cRef );
|
|
|
|
CRETURN( m_cRef );
|
|
|
|
} //*** CServiceManager::AddRef
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// STDMETHODIMP_( ULONG )
|
|
// CServiceManager::Release
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_( ULONG )
|
|
CServiceManager::Release( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
LONG cRef;
|
|
|
|
cRef = InterlockedDecrement( &m_cRef );
|
|
if ( cRef == 0 )
|
|
{
|
|
TraceDo( delete this );
|
|
}
|
|
|
|
CRETURN( cRef );
|
|
|
|
} //*** CServiceManager::Release
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IServiceProvider
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// STDMETHODIMP
|
|
// CServiceManager::QueryService(
|
|
// REFCLSID rclsidIn
|
|
// , REFIID riidInIn
|
|
// , void ** ppvOutOut
|
|
// )
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CServiceManager::QueryService(
|
|
REFCLSID rclsidIn
|
|
, REFIID riidIn
|
|
, void ** ppvOut
|
|
)
|
|
{
|
|
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( riidIn, ppvOut ) );
|
|
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( riidIn, ppvOut ) );
|
|
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( riidIn, ppvOut ) );
|
|
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( riidIn, ppvOut ) );
|
|
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( riidIn, ppvOut ) );
|
|
plm->Release();
|
|
// fall thru
|
|
}
|
|
} // if: GIT pointer not NULL
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CServiceManager::QueryService
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Private Methods
|
|
//
|
|
//****************************************************************************
|