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.
501 lines
13 KiB
501 lines
13 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
CEventLogger.cpp
|
|
|
|
Abstract:
|
|
This file contains implementation of the CEventLogger class which is
|
|
used to log events across threads and processes.
|
|
|
|
|
|
Revision History:
|
|
Eugene Mesgar (eugenem) 6/16/99
|
|
created
|
|
|
|
Weiyou Cui (weiyouc) 31/Jan/2000
|
|
Set time resolution to milliseconds
|
|
|
|
******************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <dbgtrace.h>
|
|
#include "CEventLogger.h"
|
|
|
|
|
|
#ifdef THIS_FILE
|
|
|
|
#undef THIS_FILE
|
|
|
|
#endif
|
|
|
|
static char __szTraceSourceFile[] = __FILE__;
|
|
|
|
#define THIS_FILE __szTraceSourceFile
|
|
|
|
#define TRACE_FILEID (LPARAM)this
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Basic constructor
|
|
*/
|
|
CEventLogger::CEventLogger()
|
|
{
|
|
TraceFunctEnter("CEventLogger");
|
|
m_hSemaphore = NULL;
|
|
// m_hLogFile = NULL;
|
|
m_pszFileName = NULL;
|
|
TraceFunctLeave();
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Destructor
|
|
*/
|
|
|
|
CEventLogger::~CEventLogger()
|
|
{
|
|
|
|
TraceFunctEnter("~CEventLogger");
|
|
|
|
if(m_pszFileName)
|
|
{
|
|
free(m_pszFileName);
|
|
}
|
|
|
|
if ( m_hSemaphore )
|
|
{
|
|
CloseHandle( m_hSemaphore );
|
|
}
|
|
|
|
// if( m_hLogFile )
|
|
// {
|
|
// CloseHandle( m_hLogFile );
|
|
// }
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
|
|
/*
|
|
* Init method
|
|
*/
|
|
|
|
DWORD CEventLogger::Init(LPCTSTR szFileName, DWORD dwLogLevel)
|
|
{
|
|
TCHAR szBuf[MAX_BUFFER];
|
|
TCHAR *pTemp;
|
|
|
|
TraceFunctEnter("Init");
|
|
|
|
//Set the logging level
|
|
m_dwLoggingLevel = dwLogLevel;
|
|
|
|
//Get our own copy of the file name
|
|
m_pszFileName = _tcsdup( szFileName );
|
|
|
|
|
|
|
|
if(!m_pszFileName)
|
|
{
|
|
_ASSERT(0);
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
//brijeshk: open and close file everytime we want to log
|
|
// if( (m_hLogFile = CreateFile(m_pszFileName,
|
|
// GENERIC_READ | GENERIC_WRITE,
|
|
// FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
// NULL, // security attributes
|
|
// OPEN_ALWAYS,
|
|
// FILE_FLAG_RANDOM_ACCESS,
|
|
// NULL) // template file
|
|
// ) == INVALID_HANDLE_VALUE)
|
|
// {
|
|
// DWORD dwError;
|
|
// dwError = GetLastError();
|
|
// DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
|
|
// TraceFunctLeave();
|
|
// return(dwError);
|
|
// }
|
|
|
|
// fix the semaphore name problem -- all uppercase, remove backslashes
|
|
_tcscpy( szBuf, m_pszFileName );
|
|
CharUpper( szBuf );
|
|
pTemp = szBuf;
|
|
while( *pTemp != 0 )
|
|
{
|
|
if( *pTemp == _TEXT('\\') )
|
|
{
|
|
*pTemp = _TEXT(' ');
|
|
}
|
|
pTemp++;
|
|
}
|
|
|
|
|
|
// create the semaphore, it if dosn't already exist, we are the first
|
|
// logger app created.. so we can prune the logfile if needed.
|
|
if( (m_hSemaphore = CreateSemaphore(NULL, 0,1,szBuf)) == NULL )
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! DebugTrace( TRACE_FILEID,"CreateSemaphore Failed 0x%x",dwError);
|
|
TraceFunctLeave();
|
|
return(dwError);
|
|
}
|
|
|
|
// we now know we are the first process to open the file
|
|
if( GetLastError() != ERROR_ALREADY_EXISTS )
|
|
{
|
|
|
|
/*
|
|
* This is the place where we should "trim" the file.
|
|
*
|
|
*/
|
|
TruncateFileSize();
|
|
|
|
ReleaseSemaphore( m_hSemaphore, 1, NULL );
|
|
|
|
}
|
|
|
|
|
|
TraceFunctLeave();
|
|
return(ERROR_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Init Method
|
|
*/
|
|
|
|
DWORD CEventLogger::Init(LPCTSTR szFileName)
|
|
{
|
|
|
|
|
|
return( Init(szFileName,LEVEL_NORMAL) );
|
|
|
|
}
|
|
|
|
|
|
DWORD WINAPI ShowDialogBox( LPVOID lpParameter) // thread data
|
|
{
|
|
MessageBox(NULL,
|
|
(TCHAR *)lpParameter,
|
|
_TEXT("Windows System File Protection"),
|
|
MB_ICONEXCLAMATION | MB_OK );
|
|
|
|
|
|
free( lpParameter );
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
// we log in ascii
|
|
DWORD CEventLogger::LogEvent(DWORD dwEventLevel, LPCTSTR pszEventDesc, BOOL fPopUp)
|
|
{
|
|
TCHAR szBuf[500];
|
|
DWORD dwWritten;
|
|
SYSTEMTIME SystemTime;
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
HANDLE hLogFile = NULL;
|
|
|
|
TraceFunctEnter("LogEvent");
|
|
|
|
// brijeshk : open and close file everytime we log to it
|
|
if( (hLogFile = CreateFile(m_pszFileName,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // security attributes
|
|
OPEN_ALWAYS,
|
|
FILE_FLAG_RANDOM_ACCESS,
|
|
NULL) // template file
|
|
) == INVALID_HANDLE_VALUE)
|
|
{
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
if (!m_hSemaphore)
|
|
{
|
|
_ASSERT(0);
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
|
|
if( dwEventLevel > m_dwLoggingLevel)
|
|
{
|
|
dwError = ERROR_SUCCESS;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
|
|
// Lets try to get ahold of the logfile
|
|
if(WaitForSingleObject( m_hSemaphore, 900 ) == WAIT_TIMEOUT )
|
|
{
|
|
dwError = WAIT_TIMEOUT;
|
|
goto exit;
|
|
}
|
|
|
|
__try {
|
|
|
|
if( SetFilePointer(hLogFile, 0, 0, FILE_END ) == 0xFFFFFFFF )
|
|
{
|
|
// NOT 64-bits complaint!! DebugTrace(TRACE_FILEID,"SetFilePointer Failed 0x%x", GetLastError());
|
|
dwError = GetLastError();
|
|
goto exit;
|
|
}
|
|
|
|
|
|
GetLocalTime( &SystemTime );
|
|
|
|
|
|
// LEVEL [wMonth/wDay/wYear wHour:wMinute] Message\n
|
|
_stprintf(szBuf,_TEXT("%s [%02d/%02d/%d %02d:%02d:%02d:%03d] %s\r\n"),
|
|
m_aszERROR_LEVELS[dwEventLevel],
|
|
SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
|
|
SystemTime.wHour, SystemTime.wMinute,
|
|
SystemTime.wSecond, SystemTime.wMilliseconds,
|
|
pszEventDesc);
|
|
|
|
|
|
if(WriteFile(hLogFile,
|
|
szBuf,
|
|
_tcslen(szBuf) * sizeof(TCHAR),
|
|
&dwWritten,
|
|
NULL) == 0)
|
|
{
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "WriteFile Failed 0x%x", dwError);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
__finally {
|
|
ReleaseSemaphore( m_hSemaphore, 1, NULL );
|
|
}
|
|
|
|
|
|
// show a message
|
|
if( fPopUp )
|
|
{
|
|
DWORD dwThreadId;
|
|
HANDLE hThread;
|
|
LPTSTR pszTempStr=NULL;
|
|
|
|
if( (pszTempStr = _tcsdup( pszEventDesc )) == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "Error duplicating string for file popup ec: %d", dwError);
|
|
dwError = ERROR_INTERNAL_ERROR;
|
|
goto exit;
|
|
}
|
|
|
|
hThread = CreateThread( NULL, // pointer to security attributes
|
|
0, // default initial thread stack size
|
|
(LPTHREAD_START_ROUTINE) ShowDialogBox,
|
|
// pointer to thread function
|
|
(LPVOID)pszTempStr, //argument for new thread
|
|
0, // creation flags
|
|
&dwThreadId); // pointer to receive thread ID
|
|
if (INVALID_HANDLE_VALUE != hThread)
|
|
{
|
|
CloseHandle(hThread);
|
|
}
|
|
}
|
|
|
|
exit:
|
|
// brijeshk : open and close log file each time we log to it
|
|
if (NULL != hLogFile && INVALID_HANDLE_VALUE != hLogFile)
|
|
{
|
|
CloseHandle(hLogFile);
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return dwError;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* If the file is bigger than 40k, cut off the begining to leave the last 20k
|
|
* of the file
|
|
* --> the file should be locked at this point <--
|
|
*/
|
|
|
|
BOOL CEventLogger::TruncateFileSize()
|
|
{
|
|
DWORD dwSize = 0, dwNewSize = 0;
|
|
DWORD dwRead = 0, dwWritten = 0;
|
|
LPTSTR pcStr = NULL, pcEnd = NULL, pData = NULL;
|
|
HANDLE hLogFile = NULL;
|
|
BOOL fRc = TRUE;
|
|
|
|
TraceFunctEnter("TruncateFileSize");
|
|
|
|
// brijeshk : open the file as and when we need it
|
|
if( (hLogFile = CreateFile(m_pszFileName,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // security attributes
|
|
OPEN_ALWAYS,
|
|
FILE_FLAG_RANDOM_ACCESS,
|
|
NULL) // template file
|
|
) == INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
dwSize = GetFileSize( hLogFile, NULL );
|
|
|
|
if( dwSize < TRIM_AT_SIZE )
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
|
|
// goto the last portion of the file we want to preserve
|
|
if (FALSE == SetFilePointer(hLogFile, 0-NEW_FILE_SIZE, 0, FILE_END))
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "SetFilePointer failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
// allocate memory to store this block
|
|
pData = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NEW_FILE_SIZE);
|
|
if (NULL == pData)
|
|
{
|
|
// NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "Out of memory");
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
// read this block into memory
|
|
if (FALSE == ReadFile(hLogFile, pData, NEW_FILE_SIZE, &dwRead, NULL) ||
|
|
dwRead != NEW_FILE_SIZE)
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "ReadFile failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
// set the beginning and end of the block
|
|
pcStr = pData;
|
|
pcEnd = (LPTSTR) pData + NEW_FILE_SIZE - 1;
|
|
|
|
// move forward until we find a newline and then go one more!
|
|
while( (pcStr != pcEnd) && *(pcStr++) != _TEXT('\r') );
|
|
|
|
// this is a weird file- 20k and no newlines
|
|
if( pcStr == pcEnd )
|
|
{
|
|
// NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "No newline found");
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
// skip the /n as well
|
|
if (*pcStr == _TEXT('\n'))
|
|
{
|
|
pcStr++;
|
|
}
|
|
|
|
// close and open the file, purging everything in it
|
|
if (FALSE == CloseHandle(hLogFile))
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "CloseHandle failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
hLogFile = NULL;
|
|
|
|
if( (hLogFile = CreateFile(m_pszFileName,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // security attributes
|
|
CREATE_ALWAYS, // lose everything inside
|
|
FILE_FLAG_RANDOM_ACCESS,
|
|
NULL) // template file
|
|
) == INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
// now write back this block
|
|
|
|
// get the new size of the block
|
|
dwNewSize = (DWORD)(pcEnd - pcStr + 1);
|
|
|
|
if (FALSE == WriteFile(hLogFile, pcStr, dwNewSize, &dwWritten, NULL))
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
// NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "WriteFile failed 0x%x", dwError);
|
|
fRc = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
exit:
|
|
if (pData)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, pData);
|
|
}
|
|
|
|
if (hLogFile != NULL && hLogFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hLogFile);
|
|
}
|
|
|
|
|
|
TraceFunctLeave();
|
|
return fRc;
|
|
}
|
|
|
|
|
|
/*
|
|
* Error level indentifiers
|
|
*/
|
|
|
|
LPCTSTR CEventLogger::m_aszERROR_LEVELS[] = {
|
|
"None :",
|
|
"CRITICAL:",
|
|
"UNDEF :",
|
|
"NORMAL :",
|
|
"MINIMAL :",
|
|
"DEBUG :"
|
|
};
|
|
|
|
|