/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
log.c
Abstract:
This file implements the access to the postmortem log file.
Author:
Wesley Witt (wesw) 1-May-1993
Environment:
User Mode
--*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <commdlg.h>
#include <direct.h>
#include "drwatson.h"
#include "proto.h"
#include "messages.h"
#include "resource.h"
//
// global variables for this module
//
static HANDLE hFile = NULL;
static HANDLE hLogProtect = NULL;
static DWORD dwStartingPos = 0;
void
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.
--*/
{
char buf[1024];
DWORD dwCount;
va_list args;
va_start( args, dwFormatId );
dwCount = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
NULL,
dwFormatId,
0, // GetUserDefaultLangID(),
buf,
sizeof(buf),
&args
);
Assert( dwCount != 0 );
WriteFile( hFile, buf, dwCount, &dwCount, NULL );
return;
}
void
lprintfs(char *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.
--*/
{
char buf[1024];
DWORD cb;
va_list arg_ptr;
va_start(arg_ptr, format);
cb = _vsnprintf(buf, sizeof(buf), format, arg_ptr);
Assert( hFile != NULL );
WriteFile( hFile, buf, cb, &cb, NULL );
return;
}
void
OpenLogFile( char *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.
--*/
{
char szName[1024];
GetAppName( szName, sizeof(szName) );
strcat( szName, "LogProtect" );
hLogProtect = OpenSemaphore( SEMAPHORE_MODIFY_STATE | SYNCHRONIZE, FALSE, szName);
if (hLogProtect == NULL) {
hLogProtect = CreateSemaphore( NULL, 0, 1, szName );
Assert( hLogProtect != NULL );
}
else {
WaitForSingleObject( hLogProtect, INFINITE );
}
openagain:
hFile = CreateFile( szFileName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ,
NULL,
fAppend ? OPEN_EXISTING : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (fAppend) {
if (hFile == INVALID_HANDLE_VALUE) {
//
// file does not exist, so lets create a new file
//
hFile = CreateFile( szFileName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
if (fVisual) {
NonFatalError( LoadRcString(IDS_INVALID_LOGFILE) );
_getcwd( szFileName, MAX_PATH );
if (!BrowseForDirectory( szFileName )) {
FatalError( LoadRcString(IDS_CANT_OPEN_LOGFILE) );
}
MakeLogFileName( szFileName );
goto openagain;
}
else {
ExitProcess( 1 );
}
}
//
// write the file banner
//
lprintfs( "\r\n" );
lprintf( MSG_BANNER );
lprintfs( "\r\n" );
}
SetFilePointer( hFile, 0, 0, FILE_END );
}
else {
//
// write the file banner
//
lprintfs( "\r\n" );
lprintf( MSG_BANNER );
lprintfs( "\r\n" );
}
Assert( hFile != INVALID_HANDLE_VALUE );
dwStartingPos = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
return;
}
void
CloseLogFile( void )
/*++
Routine Description:
Closes the DrWatson logfile & releases the semaphore that
protects it.
Arguments:
None.
Return Value:
None.
--*/
{
CloseHandle( hFile );
ReleaseSemaphore( hLogProtect, 1, NULL );
CloseHandle( hLogProtect );
}
char *
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;
char *p;
DWORD size;
dwCurrPos = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
*pdwLogFileDataSize = 0;
size = dwCurrPos - dwStartingPos;
p = (char *) malloc( size );
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( char *szName )
/*++
Routine Description:
Concatinates the base logfile name on to the string passed in.
Arguments:
szName - buffer for the logfile name.
Return Value:
None.
--*/
{
strcat( szName, "\\drwtsn32.log" );
}