LOG.C

/*++ 

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" );
}