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