Leaked source code of windows server 2003
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

//////////////////////////////////////////////////////////////////////////////
//
// 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
//
//****************************************************************************