/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
ui.c
Abstract:
This file contains all functions that access the application event log.
Author:
Wesley Witt (wesw) 1-May-1993
Environment:
User Mode
--*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "drwatson.h"
#include "proto.h"
#include "messages.h"
char * AddString( char *p, char *s );
char * AddNumber( char *p, char *f, DWORD dwNumber );
char * GetDWORD( PDWORD pdwData, char *p );
char * GetWORD( PWORD pwData, char *p );
char * GetString( char *s, char *p, DWORD size );
BOOL
ElClearAllEvents( void )
{
HANDLE hEventLog;
char szAppName[MAX_PATH];
GetAppName( szAppName, sizeof(szAppName) );
hEventLog = OpenEventLog( NULL, szAppName );
Assert( hEventLog != NULL );
ClearEventLog( hEventLog, NULL );
CloseEventLog( hEventLog );
RegSetNumCrashes(0);
return TRUE;
}
BOOL
ElEnumCrashes( PCRASHINFO crashInfo, CRASHESENUMPROC lpEnumFunc )
{
char *p;
HANDLE hEventLog;
char *szEvBuf;
EVENTLOGRECORD *pevlr;
DWORD dwRead;
DWORD dwNeeded;
DWORD dwBufSize = 4096;
BOOL rc;
BOOL ec;
char szAppName[MAX_PATH];
GetAppName( szAppName, sizeof(szAppName) );
hEventLog = OpenEventLog( NULL, szAppName );
if (hEventLog == NULL) {
return FALSE;
}
szEvBuf = (char *) malloc( dwBufSize );
if (szEvBuf == NULL) {
return FALSE;
}
while (TRUE) {
try_again:
rc = ReadEventLog(hEventLog,
EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,
0,
(EVENTLOGRECORD *) szEvBuf,
dwBufSize,
&dwRead,
&dwNeeded);
if (!rc) {
ec = GetLastError();
if (ec != ERROR_INSUFFICIENT_BUFFER) {
goto exit;
}
free( szEvBuf );
dwBufSize = dwNeeded + 1024;
szEvBuf = (char *) malloc( dwBufSize );
if (szEvBuf == NULL) {
return FALSE;
}
goto try_again;
}
if (dwRead == 0) {
break;
}
GetAppName( szAppName, sizeof(szAppName) );
p = szEvBuf;
do {
pevlr = (EVENTLOGRECORD *) p;
p += pevlr->StringOffset;
p = GetString( crashInfo->crash.szAppName, p, sizeof(crashInfo->crash.szAppName) );
p = GetWORD ( &crashInfo->crash.time.wMonth, p );
p = GetWORD ( &crashInfo->crash.time.wDay, p );
p = GetWORD ( &crashInfo->crash.time.wYear, p );
p = GetWORD ( &crashInfo->crash.time.wHour, p );
p = GetWORD ( &crashInfo->crash.time.wMinute, p );
p = GetWORD ( &crashInfo->crash.time.wSecond, p );
p = GetWORD ( &crashInfo->crash.time.wMilliseconds, p );
p = GetDWORD ( &crashInfo->crash.dwExceptionCode, p );
p = GetDWORD ( &crashInfo->crash.dwAddress, p );
p = GetString( crashInfo->crash.szFunction, p, sizeof(crashInfo->crash.szFunction) );
p = (char *) ((DWORD)pevlr + sizeof(EVENTLOGRECORD));
if (strcmp( p, szAppName) == 0) {
crashInfo->dwCrashDataSize = pevlr->DataLength;
crashInfo->pCrashData = (char *) ((DWORD)pevlr + pevlr->DataOffset);
if (!lpEnumFunc( crashInfo )) {
goto exit;
}
}
//
// update the pointer & read count
//
dwRead -= pevlr->Length;
p = (char *) ((DWORD)pevlr + pevlr->Length);
} while ( dwRead > 0 );
}
exit:
free( szEvBuf );
CloseEventLog( hEventLog );
return TRUE;
}
BOOL
ElSaveCrash( PCRASHES crash, DWORD dwMaxCrashes )
{
char szStrings[4096];
LPSTR p = szStrings;
HANDLE hEventSrc;
LPSTR pp[20];
char *pLogFileData;
DWORD dwLogFileDataSize;
char szAppName[MAX_PATH];
if (dwMaxCrashes > 0) {
if (RegGetNumCrashes() >= dwMaxCrashes) {
return FALSE;
}
}
RegSetNumCrashes( RegGetNumCrashes()+1 );
p = AddString( pp[0] = p, crash->szAppName );
p = AddNumber( pp[1] = p, "%2d", crash->time.wMonth );
p = AddNumber( pp[2] = p, "%2d", crash->time.wDay );
p = AddNumber( pp[3] = p, "%4d", crash->time.wYear );
p = AddNumber( pp[4] = p, "%2d", crash->time.wHour );
p = AddNumber( pp[5] = p, "%2d", crash->time.wMinute );
p = AddNumber( pp[6] = p, "%2d", crash->time.wSecond );
p = AddNumber( pp[7] = p, "%3d", crash->time.wMilliseconds );
p = AddNumber( pp[8] = p, "%08x", crash->dwExceptionCode );
p = AddNumber( pp[9] = p, "%08x", crash->dwAddress );
p = AddString( pp[10] = p, crash->szFunction );
GetAppName( szAppName, sizeof(szAppName) );
hEventSrc = RegisterEventSource( NULL, szAppName );
if (hEventSrc == NULL) {
return FALSE;
}
pLogFileData = GetLogFileData( &dwLogFileDataSize );
ReportEvent( hEventSrc,
EVENTLOG_INFORMATION_TYPE,
0,
MSG_CRASH,
NULL,
11,
dwLogFileDataSize,
pp,
pLogFileData
);
DeregisterEventSource( hEventSrc );
free( pLogFileData );
return TRUE;
}
char *
AddString( char *p, char *s )
{
strcpy( p, s );
p += (strlen(s) + 1);
return p;
}
char *
AddNumber( char *p, char *f, DWORD dwNumber )
{
char buf[20];
wsprintf( buf, f, dwNumber );
return AddString( p, buf );
}
char *
GetString( char *s, char *p, DWORD size )
{
strncpy( s, p, size );
return p + strlen(p) + 1;
}
char *
GetDWORD( PDWORD pdwData, char *p )
{
sscanf( p, "%x", pdwData );
return p + strlen(p) + 1;
}
char *
GetWORD( PWORD pwData, char *p )
{
*pwData = atoi( p );
return p + strlen(p) + 1;
}