Listing 7: Implementation file for TAppLog class
#include <windows.h> #include <stdio.h> #include <stdarg.h> #include "tapplog.h" #include "mcmsg.h" static const char szRegBasePath[] = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"; TAppLog::TAppLog( char *src_name, LOG_LEVEL loglevel ) : m_loglevel( loglevel ) , m_hEventLog( 0 ) { memset( m_srcname, 0, sizeof( m_srcname ) ); strncpy( m_srcname, src_name, sizeof(m_srcname)-1); //== do not register the service here because it may have //== never been installed! } TAppLog::~TAppLog() { if( m_hEventLog ) DeregisterEventSource( m_hEventLog ); } bool TAppLog::IsInstalled( void ) { HKEY hKey = NULL; char szRegKey[1024]; sprintf( szRegKey, "%s%s", szRegBasePath, m_srcname ); if (::RegOpenKey(HKEY_LOCAL_MACHINE, szRegKey, &hKey) == ERROR_SUCCESS) { RegCloseKey( hKey ); return true; } return false; } bool TAppLog::Install( void ) { if( IsInstalled() ) return true; char szRegKey[1024]; char szFilePath[ _MAX_PATH ]; HKEY hKey = NULL; DWORD dwMsgTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; // Get the executable file path ::GetModuleFileName(NULL, szFilePath, sizeof(szFilePath)); sprintf( szRegKey, "%s%s", szRegBasePath, m_srcname ); int err = 0; if ((err = ::RegCreateKey(HKEY_LOCAL_MACHINE, szRegKey, &hKey)) != ERROR_SUCCESS) { //== write error to console here! fprintf( stderr, "TAppLog reports error %d creating registery key: %s\n", err, szRegKey ); // fprintf( stderr, "%s\n", szRegKey ); return false; } ::RegSetValueEx(hKey,"EventMessageFile", 0,REG_SZ, (CONST BYTE*)szFilePath, sizeof( szFilePath )); ::RegSetValueEx(hKey,"TypesSupported", 0, REG_DWORD, (CONST BYTE*)&dwMsgTypes, sizeof( DWORD )); RegCloseKey( hKey ); return true; } bool TAppLog::Uninstall( void ) { return true; } bool TAppLog::LogEvent( LOG_LEVEL level, char* argstr, ...) { va_list vl; va_start( vl, argstr ); return LogEventVL( level, argstr, vl ); } bool TAppLog::LogEventVL( LOG_LEVEL level, char* argstr, va_list vl ) { char msgbuff[1024]; //== only log the messages asked for if( level > m_loglevel ) return false; //== make sure we are installed if( !IsInstalled() ) Install(); //== have we registered the event source? if( !m_hEventLog ) { if( (m_hEventLog = ::RegisterEventSource( NULL, m_srcname )) == 0) return false; } //== build the message vsprintf( msgbuff, argstr, vl); //== determine ReportError type from msglevel //== get the base message from the resource file DWORD dwEventID = 0; WORD wType = 0; switch( level ) { case LOG_ERROR: wType = EVENTLOG_ERROR_TYPE; dwEventID = NTSRV_ERROR; break; case LOG_WARNING: dwEventID = NTSRV_WARN; wType = EVENTLOG_WARNING_TYPE; break; case LOG_INFORM: dwEventID = NTSRV_INFO; wType = EVENTLOG_INFORMATION_TYPE; break; default: dwEventID = NTSRV_NOTE; wType = EVENTLOG_INFORMATION_TYPE; } const char *pp_msgs[1]; pp_msgs[0] = msgbuff; //== Report the event BOOL bRetval = ReportEvent( m_hEventLog, // handle returned by RegisterEventSource wType, // event type to log 0, // event category dwEventID, // event identifier NULL, // user security identifier (optional) 1, // number of strings to merge with message 0, // size of binary data, in bytes pp_msgs, // array of strings to merge with message NULL // address of binary data ); //== if we are debugging echo everything to the debugger if( m_loglevel == LOG_DEBUG ) { ::OutputDebugString( msgbuff ); } return (bRetval != FALSE); } //End of File