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.
 
 
 
 
 
 

396 lines
7.8 KiB

/*++
Copyright (c) 1993-2001 Microsoft Corporation
Module Name:
log.cpp
Abstract:
This file implements the access to the postmortem log file.
Author:
Wesley Witt (wesw) 1-May-1993
Environment:
User Mode
--*/
#include "pch.cpp"
#define BYTE_ORDER_MARK 0xFEFF
#define MAX_PRINTF_BUF_SIZE (1024 * 4)
enum LOG_TYPE {
LT_ANSI,
LT_UNICODE
};
//
// global variables for this module
//
static HANDLE hFile = NULL;
static DWORD dwStartingPos = 0;
static WCHAR wchBOM = BYTE_ORDER_MARK;
static DWORD dwLogType = LT_ANSI;
void
WriteAnsiCharsToLogFile(
WCHAR *pszUnicode,
DWORD dwCharCount
)
{
char szAnsiBuf[MAX_PRINTF_BUF_SIZE] = {0};
DWORD nCharTranslated;
WCHAR szWcharBuf[MAX_PRINTF_BUF_SIZE] = {0};
nCharTranslated = WideCharToMultiByte(CP_ACP, WC_SEPCHARS | WC_COMPOSITECHECK,
pszUnicode, dwCharCount,
szAnsiBuf, sizeof(szAnsiBuf), NULL, NULL);
WriteFile( hFile, szAnsiBuf, nCharTranslated, &nCharTranslated, NULL );
#if 0
nCharTranslated = MultiByteToWideChar(CP_ACP, WC_SEPCHARS | WC_COMPOSITECHECK,
szAnsiBuf, nCharTranslated,
szWcharBuf, sizeof(szWcharBuf)/sizeof(WCHAR));
WriteFile( hFile, szWcharBuf, nCharTranslated, &nCharTranslated, NULL );
#endif
}
void
__cdecl
lprintf(
DWORD dwFormatId,
...
)
/*++
Routine Description:
This is function is a printf style function for printing messages
in a message file.
Arguments:
dwFormatId - format id in the message file
... - var args
Return Value:
None.
--*/
{
_TCHAR buf[MAX_PRINTF_BUF_SIZE] = {0};
DWORD dwCount;
va_list args;
va_start( args, dwFormatId );
dwCount = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
NULL,
dwFormatId,
MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), // Default language
buf,
sizeof(buf) / sizeof(_TCHAR),
&args
);
va_end(args);
if (dwCount == 0) {
// Failure, nothing to write.
return;
}
#ifdef UNICODE
// We currently want all of the output to be in ANSI
if (dwLogType == LT_ANSI) {
WriteAnsiCharsToLogFile(buf, dwCount);
} else {
WriteFile( hFile, buf, dwCount * sizeof(_TCHAR), &dwCount, NULL );
}
#else
WriteFile( hFile, buf, dwCount, &dwCount, NULL );
#endif
return;
}
void
__cdecl
lprintfs(
_TCHAR *format,
...
)
/*++
Routine Description:
This is function is a printf replacement that writes the output to
the DrWatson log file.
Arguments:
format - print format
... - var args
Return Value:
None.
--*/
{
_TCHAR buf[MAX_PRINTF_BUF_SIZE] = {0};
int chars;
DWORD cb;
va_list arg_ptr;
va_start(arg_ptr, format);
chars = _vsntprintf(buf, _tsizeof(buf), format, arg_ptr);
buf[_tsizeof(buf) - 1] = 0;
if (chars < 0 || chars == _tsizeof(buf)) {
cb = _tsizeof(buf) - 1;
} else {
cb = chars;
}
va_end(arg_ptr);
Assert( hFile != NULL );
#ifdef UNICODE
// We currently want all of the output to be in ANSI
if (dwLogType == LT_ANSI) {
WriteAnsiCharsToLogFile(buf, cb);
} else {
WriteFile( hFile, buf, cb * sizeof(_TCHAR), &cb, NULL );
}
#else
WriteFile( hFile, buf, cb * sizeof(_TCHAR), &cb, NULL );
#endif
}
void
OpenLogFile(
_TCHAR *szFileName,
BOOL fAppend,
BOOL fVisual
)
/*++
Routine Description:
Opens the DrWatson logfile for reading & writting.
Arguments:
szFileName - logfile name
fAppend - append the new data to the end of the file or
create a new file
fVisual - visual notification
Return Value:
None.
--*/
{
DWORD size;
DWORD Retries = 10;
//
// The log file may be in use by another instance
// of Dr. Watson, so try and open it several times
// with a wait inbetween.
//
for (;;) {
hFile = CreateFile( szFileName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ,
NULL,
fAppend ? OPEN_ALWAYS : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
break;
}
if (fVisual) {
NonFatalError( LoadRcString(IDS_INVALID_LOGFILE) );
_tgetcwd( szFileName, MAX_PATH );
if (!BrowseForDirectory(NULL, szFileName, MAX_PATH )) {
FatalError( GetLastError(),
LoadRcString(IDS_CANT_OPEN_LOGFILE) );
}
MakeLogFileName( szFileName );
}
else if (Retries-- == 0) {
ExitProcess( 1 );
}
else {
Sleep(1000);
}
}
if (!fAppend || GetLastError() != ERROR_ALREADY_EXISTS) {
//
// The file was just created, so put a header in it.
//
dwLogType = LT_UNICODE;
WriteFile( hFile, &wchBOM, sizeof(_TCHAR), &size, NULL );
lprintfs( _T("\r\n") );
lprintf( MSG_BANNER );
lprintfs( _T("\r\n") );
} else {
#ifdef UNICODE
//
// Check if the file is Unicode or ANSI
//
WCHAR wchHdr = 0;
dwLogType = LT_ANSI;
if (ReadFile( hFile, &wchHdr, sizeof(TCHAR), &size, NULL )) {
if (wchHdr == wchBOM) {
dwLogType = LT_UNICODE;
}
}
#endif
SetFilePointer( hFile, 0, 0, FILE_END );
}
dwStartingPos = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
}
void
CloseLogFile(
void
)
/*++
Routine Description:
Closes the DrWatson logfile & releases the semaphore that
protects it.
Arguments:
None.
Return Value:
None.
--*/
{
CloseHandle( hFile );
}
_TCHAR *
GetLogFileData(
PDWORD pdwLogFileDataSize
)
/*++
Routine Description:
Reads in all of the logfile data that has been written since it was
opened. The data is placed into a buffer allocated by this function.
The caller is responsible for freeing the memory.
Arguments:
pdwLogFileDataSize - pointer to a dword that contains the size
in bytes of the data that is read.
Return Value:
Valid character pointer to the logfile data
NULL - could not read the data.
--*/
{
DWORD dwCurrPos;
_TCHAR *p;
DWORD size;
dwCurrPos = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
*pdwLogFileDataSize = 0;
size = dwCurrPos - dwStartingPos;
p = (_TCHAR *) calloc( size, sizeof(_TCHAR) );
if (p == NULL) {
return NULL;
}
SetFilePointer( hFile, dwStartingPos, NULL, FILE_BEGIN );
if (!ReadFile( hFile, p, size, &size, NULL )) {
free( p );
p = NULL;
size = 0;
}
SetFilePointer( hFile, dwCurrPos, NULL, FILE_BEGIN );
*pdwLogFileDataSize = size;
return p;
}
void
MakeLogFileName(
_TCHAR *szName
)
/*++
Routine Description:
Concatenates the base logfile name on to the string passed in.
Arguments:
szName - buffer for the logfile name.
Return Value:
None.
--*/
{
if (_tcslen(szName) + 16 < MAX_PATH) {
_tcscat( szName, _T("\\drwtsn32.log") );
}
}