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

579 lines
15 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2001 Microsoft Corporation
//
// Module Name:
// Logger.cpp
//
// Description:
// ClCfgSrv Logger implementation.
//
// Maintained By:
// David Potter (DavidP) 11-DEC-2000
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include "Logger.h"
DEFINE_THISCLASS("CClCfgSrvLogger")
//****************************************************************************
//
// Global Static Variables
//
//****************************************************************************
IGlobalInterfaceTable * CClCfgSrvLogger::sm_pgit = NULL;
CRITICAL_SECTION * CClCfgSrvLogger::sm_pcritsec = NULL;
bool CClCfgSrvLogger::sm_fRevokingFromGIT= false;
DWORD CClCfgSrvLogger::sm_cookieGITLogger = 0;
//****************************************************************************
//
// Constructor / Destructor
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CClCfgSrvLogger::S_HrCreateInstance(
// IUnknown ** ppunkOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CClCfgSrvLogger::S_HrCreateInstance(
IUnknown ** ppunkOut
)
{
TraceFunc( "" );
HRESULT hr;
CClCfgSrvLogger * pccsl = NULL;
if ( ppunkOut == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
} // if:
pccsl = new CClCfgSrvLogger();
if ( pccsl == NULL )
{
hr = THR( E_OUTOFMEMORY );
goto Cleanup;
} // if: error allocating object
hr = THR( pccsl->HrInit() );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: HrInit() failed
hr = THR( pccsl->TypeSafeQI( IUnknown, ppunkOut ) );
Cleanup:
if ( pccsl != NULL )
{
pccsl->Release();
} // if:
HRETURN( hr );
} //*** CClCfgSrvLogger::S_HrCreateInstance( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClCfgSrvLogger::CClCfgSrvLogger( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
CClCfgSrvLogger::CClCfgSrvLogger( void )
: m_cRef( 1 )
{
TraceFunc( "" );
InterlockedIncrement( &g_cObjects );
TraceFuncExit();
} //*** CClCfgSrvLogger::CClCfgSrvLogger( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CClCfgSrvLogger::HrInit( )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClCfgSrvLogger::HrInit( void )
{
TraceFunc( "" );
HRESULT hr = S_OK;
Assert( m_cRef == 1 );
Assert( sm_pgit == NULL );
// Create the Global Interface Table object.
hr = THR( CoCreateInstance(
CLSID_StdGlobalInterfaceTable
, NULL
, CLSCTX_INPROC_SERVER
, IID_IGlobalInterfaceTable
, reinterpret_cast< void ** >( &sm_pgit )
) );
if ( FAILED( hr ) )
goto Cleanup;
//
// Create a critical section so that the object can be removed from
// the GIT in Release().
//
if ( sm_pcritsec == NULL )
{
PCRITICAL_SECTION pcritsecNew =
(PCRITICAL_SECTION) HeapAlloc( GetProcessHeap(), 0, sizeof( CRITICAL_SECTION ) );
if ( pcritsecNew == NULL )
{
hr = E_OUTOFMEMORY;
goto Cleanup;
} // if: creation failed
InitializeCriticalSection( pcritsecNew );
// Make sure we only have one log critical section
InterlockedCompareExchangePointer( (PVOID *) &sm_pcritsec, pcritsecNew, 0 );
if ( sm_pcritsec != pcritsecNew )
{
DeleteCriticalSection( pcritsecNew );
HeapFree( GetProcessHeap(), 0, pcritsecNew );
} // if: already have another critical section
} // if: no critical section created yet
// Open the log file.
hr = THR( HrLogOpen() );
if ( FAILED( hr ) )
goto Cleanup;
// Release the critical section on the log file.
hr = THR( HrLogRelease() );
if ( FAILED( hr ) )
goto Cleanup;
Cleanup:
HRETURN( hr );
} //*** CClCfgSrvLogger::HrInit( )
//////////////////////////////////////////////////////////////////////////////
//++
//
// CClCfgSrvLogger::~CClCfgSrvLogger( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
CClCfgSrvLogger::~CClCfgSrvLogger( void )
{
TraceFunc( "" );
HRESULT hr;
Assert( m_cRef == 0 );
// Close the log file.
THR( HrLogClose() );
InterlockedDecrement( &g_cObjects );
TraceFuncExit();
} //*** CClCfgSrvLogger::~CClCfgSrvLogger( )
//****************************************************************************
//
// IUnknown
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CClCfgSrvLogger::QueryInterface(
// REFIID riidIn,
// LPVOID * ppvOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClCfgSrvLogger::QueryInterface(
REFIID riidIn,
LPVOID * ppvOut
)
{
TraceQIFunc( riidIn, ppvOut );
HRESULT hr = E_NOINTERFACE;
if ( IsEqualIID( riidIn, IID_IUnknown ) )
{
*ppvOut = static_cast< ILogger * >( this );
hr = S_OK;
} // if: IUnknown
else if ( IsEqualIID( riidIn, IID_ILogger ) )
{
*ppvOut = TraceInterface( __THISCLASS__, ILogger, this, 0 );
hr = S_OK;
} // else if: ILogger
if ( SUCCEEDED( hr ) )
{
((IUnknown*) *ppvOut)->AddRef( );
} // if: success
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
} //*** CClCfgSrvLogger::QueryInterface( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP_( ULONG )
// CClCfgSrvLogger::AddRef( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CClCfgSrvLogger::AddRef( void )
{
TraceFunc( "[IUnknown]" );
InterlockedIncrement( &m_cRef );
RETURN( m_cRef );
} //*** CClCfgSrvLogger::AddRef( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP_( ULONG )
// CClCfgSrvLogger::Release( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CClCfgSrvLogger::Release( void )
{
TraceFunc( "[IUnknown]" );
LONG cRef;
//
// Need to use a critical section since we are using multiple variables.
//
EnterCriticalSection( sm_pcritsec );
//
// If the count will be reduced down to 1 and the interface has
// been added to the GIT, then the only reference to this object
// is from the GIT. In this case, we want to the object to be
// removed from the GIT and deleted.
//
if ( ( m_cRef == 2 )
&& ( sm_cookieGITLogger != 0 )
&& ( ! sm_fRevokingFromGIT ) )
{
//
// Remove the interface from the GIT.
// Indicate we are currently revoking from the GIT, then
// exit the critical section so that we can be re-entered.
//
Assert( sm_pgit != NULL );
sm_fRevokingFromGIT = true;
LeaveCriticalSection( sm_pcritsec );
THR( sm_pgit->RevokeInterfaceFromGlobal( sm_cookieGITLogger ) );
EnterCriticalSection( sm_pcritsec );
sm_fRevokingFromGIT = false;
sm_cookieGITLogger = 0;
sm_pgit->Release();
sm_pgit = NULL;
} // if: only the GIT holds a reference
LeaveCriticalSection( sm_pcritsec );
InterlockedDecrement( &m_cRef );
cRef = m_cRef;
if ( cRef == 0 )
{
TraceDo( delete this );
}
RETURN( cRef );
} //*** CClCfgSrvLogger::Release( )
//****************************************************************************
//
// ILogger
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CClCfgSrvLogger::LogMsg(
// LPCWSTR pcszMsgIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CClCfgSrvLogger::LogMsg(
LPCWSTR pcszMsgIn
)
{
TraceFunc( "[ILogger]" );
HRESULT hr = S_OK;
::LogMsg( pcszMsgIn );
HRETURN( hr );
} //*** CClCfgSrvLogger::LogMsg( )
//****************************************************************************
//
// Private Functions
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CClCfgSrvLogger::S_HrGetLogger(
// ILogger ** pplLoggerOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CClCfgSrvLogger::S_HrGetLogger(
ILogger ** pplLoggerOut
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
// Validate arguments.
if ( pplLoggerOut == NULL )
{
hr = E_POINTER;
goto Cleanup;
}
//
// If the object has not been created yet, create one.
// Otherwise, extract the interface from the GIT.
//
if ( sm_cookieGITLogger == 0 )
{
// Create a new object.
hr = THR( CoCreateInstance(
CLSID_ClCfgSrvLogger
, NULL
, CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
, IID_ILogger
, reinterpret_cast< void ** >( pplLoggerOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
// Register this interface in the GIT.
Assert( sm_pgit != NULL );
hr = THR( sm_pgit->RegisterInterfaceInGlobal(
reinterpret_cast< IUnknown * >( *pplLoggerOut )
, IID_ILogger
, &sm_cookieGITLogger
) );
if ( FAILED( hr ) )
goto Cleanup;
} // if: no object yet
else
{
// Get the interface from the GIT.
Assert( sm_pgit != NULL );
hr = THR( sm_pgit->GetInterfaceFromGlobal(
sm_cookieGITLogger
, IID_ILogger
, reinterpret_cast< void ** >( pplLoggerOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
} // else: object already created
Cleanup:
HRETURN( hr );
} //*** CClCfgSrvLogger::S_HrGetLogger( )
//****************************************************************************
//
// Global Functions
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CClCfgSrvLogger::S_HrLogStatusReport(
// LPCWSTR pcszNodeNameIn,
// CLSID clsidTaskMajorIn,
// CLSID clsidTaskMinorIn,
// ULONG ulMinIn,
// ULONG ulMaxIn,
// ULONG ulCurrentIn,
// HRESULT hrStatusIn,
// LPCWSTR pcszDescriptionIn,
// FILETIME * pftTimeIn,
// LPCWSTR pcszReferenceIn
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CClCfgSrvLogger::S_HrLogStatusReport(
ILogger * plLogger
, LPCWSTR pcszNodeNameIn
, CLSID clsidTaskMajorIn
, CLSID clsidTaskMinorIn
, ULONG ulMinIn
, ULONG ulMaxIn
, ULONG ulCurrentIn
, HRESULT hrStatusIn
, LPCWSTR pcszDescriptionIn
, FILETIME * pftTimeIn
, LPCWSTR pcszReferenceIn
)
{
TraceFunc( "" );
HRESULT hr = S_OK;
FILETIME ft;
LPWSTR psz = NULL;
BSTR bstrLogMsg = NULL;
if ( pftTimeIn == NULL )
{
GetSystemTimeAsFileTime( &ft );
pftTimeIn = &ft;
} // if: no file time specified
//
// TODO: 21 NOV 2000 GalenB
//
// Need to log the timestamp and reference params.
//
//
// Shorten the FDQN DNS name to only the hostname.
//
if ( pcszNodeNameIn != NULL )
{
psz = wcschr( pcszNodeNameIn, L'.' );
if ( psz != NULL )
{
*psz = L'\0';
} // if:
} // if:
#define x "%1!ws!: %28!ws! (hr=0x%27!08x!,{%2!08X!-%3!04X!-%4!04X!-%5!02X!%6!02X!-%7!02X!%8!02X!%9!02X!%10!02X!%11!02X!%12!02X!},{%13!08X!-%14!04X!-%15!04X!-%16!02X!%17!02X!-%18!02X!%19!02X!%20!02X!%21!02X!%22!02X!%23!02X!},%24!u!,%25!u!,%26!u!), %29!ws!"
hr = THR( HrFormatStringIntoBSTR(
g_hInstance
, IDS_FORMAT_LOG_MESSAGE
, &bstrLogMsg
, pcszNodeNameIn // 1
, clsidTaskMajorIn.Data1 // 2
, clsidTaskMajorIn.Data2 // 3
, clsidTaskMajorIn.Data3 // 4
, clsidTaskMajorIn.Data4[ 0 ] // 5
, clsidTaskMajorIn.Data4[ 1 ] // 6
, clsidTaskMajorIn.Data4[ 2 ] // 7
, clsidTaskMajorIn.Data4[ 3 ] // 8
, clsidTaskMajorIn.Data4[ 4 ] // 9
, clsidTaskMajorIn.Data4[ 5 ] // 10
, clsidTaskMajorIn.Data4[ 6 ] // 11
, clsidTaskMajorIn.Data4[ 7 ] // 12
, clsidTaskMinorIn.Data1 // 13
, clsidTaskMinorIn.Data2 // 14
, clsidTaskMinorIn.Data3 // 15
, clsidTaskMinorIn.Data4[ 0 ] // 16
, clsidTaskMinorIn.Data4[ 1 ] // 17
, clsidTaskMinorIn.Data4[ 2 ] // 18
, clsidTaskMinorIn.Data4[ 3 ] // 19
, clsidTaskMinorIn.Data4[ 4 ] // 20
, clsidTaskMinorIn.Data4[ 5 ] // 21
, clsidTaskMinorIn.Data4[ 6 ] // 22
, clsidTaskMinorIn.Data4[ 7 ] // 23
, ulMinIn // 24
, ulMaxIn // 25
, ulCurrentIn // 26
, hrStatusIn // 27
, pcszDescriptionIn // 28
, pcszReferenceIn // 29
) );
//
// Restore the FQDN DNS name.
//
if ( psz != NULL )
{
*psz = L'.';
}
if ( hr == S_OK )
{
plLogger->LogMsg( bstrLogMsg );
}
TraceSysFreeString( bstrLogMsg );
HRETURN( hr );
} //*** CClCfgSrvLogger::S_HrLogStatusReport( )