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.
727 lines
21 KiB
727 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
elfexts.c
|
|
|
|
Abstract:
|
|
|
|
This function contains the eventlog ntsd debugger extensions
|
|
|
|
Author:
|
|
|
|
Dan Hinsley (DanHi) 22-May-1993
|
|
IvanBrug 06 21 2001 converted to the latest debugger
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include <elfmain.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <time.h>
|
|
#include <elf.h>
|
|
#include <elfdef.h>
|
|
#include <elfcommn.h>
|
|
#include <elfproto.h>
|
|
#include <svcsp.h>
|
|
#include <elfextrn.h>
|
|
|
|
|
|
#define DbgPrint(_x_)
|
|
#define MAX_NAME 256
|
|
#define GET_DATA(DebugeeAddr, LocalAddr, Length) \
|
|
Status = ReadMemory( \
|
|
(MEMORY_ADDRESS)DebugeeAddr, \
|
|
(PVOID)LocalAddr, \
|
|
(ULONG)(Length), \
|
|
NULL \
|
|
);
|
|
|
|
HANDLE GlobalhCurrentProcess;
|
|
BOOL Status;
|
|
|
|
LPWSTR
|
|
GetUnicodeString(
|
|
PUNICODE_STRING pUnicodeString
|
|
)
|
|
{
|
|
MEMORY_ADDRESS Pointer;
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
GET_DATA(pUnicodeString, &UnicodeString, sizeof(UNICODE_STRING))
|
|
Pointer = (MEMORY_ADDRESS) UnicodeString.Buffer;
|
|
UnicodeString.Buffer = (LPWSTR) LocalAlloc(LMEM_ZEROINIT,
|
|
UnicodeString.Length + sizeof(WCHAR));
|
|
GET_DATA(Pointer, UnicodeString.Buffer, UnicodeString.Length)
|
|
|
|
return(UnicodeString.Buffer);
|
|
}
|
|
|
|
MEMORY_ADDRESS
|
|
GetLogFileAddress(
|
|
LPSTR LogFileName,
|
|
PLOGFILE LogFile
|
|
)
|
|
{
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING UnicodeString;
|
|
MEMORY_ADDRESS Pointer = 0;
|
|
MEMORY_ADDRESS LogFileAnchor = 0;
|
|
LPWSTR ModuleName = 0;
|
|
|
|
//
|
|
// Convert the string to UNICODE
|
|
//
|
|
|
|
RtlInitAnsiString(&AnsiString, LogFileName);
|
|
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
|
|
|
|
//
|
|
// Walk the logfile list looking for a match
|
|
//
|
|
|
|
LogFileAnchor = (MEMORY_ADDRESS)GetExpression("eventlog!LogFilesHead");
|
|
|
|
if (LogFileAnchor) {
|
|
GET_DATA(LogFileAnchor, &Pointer, sizeof(MEMORY_ADDRESS));
|
|
|
|
while (Pointer != LogFileAnchor) {
|
|
GET_DATA(Pointer, LogFile, sizeof(LOGFILE))
|
|
ModuleName = GetUnicodeString(LogFile->LogModuleName);
|
|
if (!_wcsicmp(ModuleName, UnicodeString.Buffer)) {
|
|
break;
|
|
}
|
|
LocalFree(ModuleName);
|
|
Pointer = (MEMORY_ADDRESS) LogFile->FileList.Flink;
|
|
}
|
|
} else {
|
|
dprintf("unable to resolve %s\n","eventlog!LogFilesHead");
|
|
}
|
|
|
|
RtlFreeUnicodeString(&UnicodeString);
|
|
|
|
if (Pointer == LogFileAnchor) {
|
|
return(0);
|
|
}
|
|
else {
|
|
LocalFree(ModuleName);
|
|
return(Pointer);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Dump an individual record
|
|
//
|
|
|
|
MEMORY_ADDRESS
|
|
DumpRecord(
|
|
MEMORY_ADDRESS Record,
|
|
DWORD RecordNumber,
|
|
MEMORY_ADDRESS StartOfFile,
|
|
MEMORY_ADDRESS EndOfFile
|
|
)
|
|
{
|
|
MEMORY_ADDRESS BufferLen = 0;
|
|
PCHAR TimeBuffer;
|
|
PEVENTLOGRECORD EventLogRecord;
|
|
LPWSTR Module;
|
|
LPWSTR Computer;
|
|
MEMORY_ADDRESS FirstPiece = 0;
|
|
time_t TempAligned;
|
|
|
|
GET_DATA(Record, &BufferLen, sizeof(DWORD));
|
|
|
|
//
|
|
// See if it's a ELF_SKIP_DWORD, and if it is, return the top of the
|
|
// file
|
|
//
|
|
|
|
if (BufferLen == ELF_SKIP_DWORD) {
|
|
return(StartOfFile + sizeof(ELF_LOGFILE_HEADER));
|
|
}
|
|
|
|
//
|
|
// See if it's the EOF record
|
|
//
|
|
|
|
if (BufferLen == ELFEOFRECORDSIZE) {
|
|
return(0);
|
|
}
|
|
|
|
BufferLen += sizeof(DWORD); // get room for length of next record
|
|
EventLogRecord = (PEVENTLOGRECORD) LocalAlloc(LMEM_ZEROINIT, BufferLen);
|
|
|
|
//
|
|
// If the record wraps, grab it piecemeal
|
|
//
|
|
|
|
if (EndOfFile && BufferLen + Record > EndOfFile) {
|
|
FirstPiece = EndOfFile - Record;
|
|
GET_DATA(Record, EventLogRecord, FirstPiece);
|
|
GET_DATA((StartOfFile + sizeof(ELF_LOGFILE_HEADER)),
|
|
((PBYTE) EventLogRecord + FirstPiece), BufferLen - FirstPiece);
|
|
}
|
|
else {
|
|
GET_DATA(Record, EventLogRecord, BufferLen);
|
|
}
|
|
|
|
//
|
|
// If it's greater than the starting record, print it out
|
|
//
|
|
|
|
if (EventLogRecord->RecordNumber >= RecordNumber) {
|
|
dprintf("\nRecord %d is %d [0x%X] bytes long starting at %p\n",
|
|
EventLogRecord->RecordNumber, EventLogRecord->Length,
|
|
EventLogRecord->Length, Record);
|
|
Module = (LPWSTR)(EventLogRecord+1);
|
|
Computer = (LPWSTR)((PBYTE) Module + ((wcslen(Module) + 1) * sizeof(WCHAR)));
|
|
dprintf("\tGenerated by %ws from system %ws\n", Module, Computer);
|
|
|
|
|
|
TempAligned = EventLogRecord->TimeGenerated;
|
|
TimeBuffer = ctime(&TempAligned);
|
|
if (TimeBuffer) {
|
|
dprintf("\tGenerated at %s", TimeBuffer);
|
|
}
|
|
else {
|
|
dprintf("\tGenerated time field is blank\n");
|
|
}
|
|
TempAligned = EventLogRecord->TimeWritten;
|
|
TimeBuffer = ctime(&TempAligned);
|
|
if (TimeBuffer) {
|
|
dprintf("\tWritten at %s", TimeBuffer);
|
|
}
|
|
else {
|
|
dprintf("\tTime written field is blank\n");
|
|
}
|
|
|
|
dprintf("\tEvent Id = %d\n", EventLogRecord->EventID);
|
|
dprintf("\tEventType = ");
|
|
switch (EventLogRecord->EventType) {
|
|
case EVENTLOG_SUCCESS:
|
|
dprintf("Success\n");
|
|
break;
|
|
case EVENTLOG_ERROR_TYPE:
|
|
dprintf("Error\n");
|
|
break;
|
|
case EVENTLOG_WARNING_TYPE:
|
|
dprintf("Warning\n");
|
|
break;
|
|
case EVENTLOG_INFORMATION_TYPE:
|
|
dprintf("Information\n");
|
|
break;
|
|
case EVENTLOG_AUDIT_SUCCESS:
|
|
dprintf("Audit Success\n");
|
|
break;
|
|
case EVENTLOG_AUDIT_FAILURE:
|
|
dprintf("Audit Failure\n");
|
|
break;
|
|
default:
|
|
dprintf("Invalid value 0x%X\n", EventLogRecord->EventType);
|
|
}
|
|
dprintf("\t%d strings at offset 0x%X\n", EventLogRecord->NumStrings,
|
|
EventLogRecord->StringOffset);
|
|
dprintf("\t%d bytes of data at offset 0x%X\n", EventLogRecord->DataLength,
|
|
EventLogRecord->DataOffset);
|
|
}
|
|
|
|
if (FirstPiece) {
|
|
Record = StartOfFile + sizeof(ELF_LOGFILE_HEADER) + BufferLen -FirstPiece;
|
|
}
|
|
else {
|
|
Record += EventLogRecord->Length;
|
|
}
|
|
|
|
LocalFree(EventLogRecord);
|
|
return(Record);
|
|
}
|
|
|
|
//
|
|
// Dump a record, or all records, or n records
|
|
//
|
|
|
|
|
|
DECLARE_API(record)
|
|
{
|
|
MEMORY_ADDRESS Pointer = 0;
|
|
LOGFILE LogFile;
|
|
MEMORY_ADDRESS StartOfFile;
|
|
MEMORY_ADDRESS EndOfFile = 0;
|
|
DWORD RecordNumber = 0;
|
|
|
|
INIT_API();
|
|
|
|
//
|
|
// Evaluate the argument string to get the address of
|
|
// the record to dump.
|
|
//
|
|
|
|
while (isspace(*lpArgumentString)) lpArgumentString++;
|
|
|
|
if (lpArgumentString && *lpArgumentString) {
|
|
if (*lpArgumentString == '.') {
|
|
if (GetLogFileAddress(lpArgumentString+1, &LogFile) == 0) {
|
|
dprintf("Logfile %s not found\n", lpArgumentString+1);
|
|
return;
|
|
}
|
|
Pointer = ((MEMORY_ADDRESS ) (LogFile.BaseAddress)) + LogFile.BeginRecord;
|
|
}
|
|
else if (*lpArgumentString == '#') {
|
|
RecordNumber = atoi(lpArgumentString + 1);
|
|
dprintf("Dumping records starting at record #%d\n", RecordNumber);
|
|
lpArgumentString = NULL;
|
|
}
|
|
else if (*lpArgumentString) {
|
|
Pointer = GetExpression(lpArgumentString);
|
|
}
|
|
else {
|
|
dprintf("Invalid lead character 0x%02X\n", *lpArgumentString);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//if (!lpArgumentString || *lpArgumentString) {
|
|
if (0 == Pointer){
|
|
if (GetLogFileAddress("system", &LogFile) == 0) {
|
|
dprintf("System Logfile not found\n");
|
|
return;
|
|
}
|
|
Pointer = ((MEMORY_ADDRESS ) (LogFile.BaseAddress)) + LogFile.BeginRecord;
|
|
}
|
|
|
|
StartOfFile = (MEMORY_ADDRESS ) LogFile.BaseAddress;
|
|
EndOfFile = (MEMORY_ADDRESS ) LogFile.BaseAddress + LogFile.ActualMaxFileSize;
|
|
|
|
dprintf("%p %p %p\n",Pointer,StartOfFile,EndOfFile );
|
|
//
|
|
// Dump records starting wherever they told us to
|
|
//
|
|
|
|
while (Pointer < EndOfFile && Pointer && !CheckControlC()) {
|
|
Pointer = DumpRecord(Pointer, RecordNumber, StartOfFile, EndOfFile);
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Dump a single LogModule structure if it matches MatchName (NULL matches
|
|
// all)
|
|
//
|
|
|
|
PLIST_ENTRY
|
|
DumpLogModule(
|
|
MEMORY_ADDRESS pLogModule,
|
|
LPWSTR MatchName
|
|
)
|
|
{
|
|
LOGMODULE LogModule;
|
|
WCHAR ModuleName[MAX_NAME / sizeof(WCHAR)];
|
|
|
|
GET_DATA(pLogModule, &LogModule, sizeof(LogModule));
|
|
GET_DATA(LogModule.ModuleName, &ModuleName, MAX_NAME);
|
|
|
|
if (!MatchName || !_wcsicmp(MatchName, ModuleName)) {
|
|
dprintf("\tModule Name %S\n", ModuleName);
|
|
dprintf("\tModule Atom 0x%2x\n", LogModule.ModuleAtom);
|
|
dprintf("\tPointer to LogFile %p\n", LogModule.LogFile);
|
|
}
|
|
|
|
return (LogModule.ModuleList.Flink);
|
|
}
|
|
|
|
//
|
|
// Dump selected, or all, LogModule structures
|
|
//
|
|
|
|
|
|
DECLARE_API(logmodule)
|
|
{
|
|
|
|
MEMORY_ADDRESS pLogModule = 0;
|
|
MEMORY_ADDRESS LogModuleAnchor = 0;
|
|
LPWSTR wArgumentString = NULL;
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
INIT_API();
|
|
|
|
UnicodeString.Buffer = NULL;
|
|
|
|
//
|
|
// Evaluate the argument string to get the address of
|
|
// the logmodule to dump. If no parm, dump them all.
|
|
//
|
|
while (isspace(*lpArgumentString)) lpArgumentString++;
|
|
|
|
if (lpArgumentString && *lpArgumentString == '.') {
|
|
lpArgumentString++;
|
|
RtlInitAnsiString(&AnsiString, lpArgumentString);
|
|
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
|
|
}
|
|
else if (lpArgumentString && *lpArgumentString) {
|
|
pLogModule = GetExpression(lpArgumentString);
|
|
DumpLogModule( pLogModule, NULL);
|
|
return;
|
|
}
|
|
|
|
LogModuleAnchor = GetExpression("eventlog!LogModuleHead");
|
|
|
|
if (LogModuleAnchor)
|
|
{
|
|
GET_DATA(LogModuleAnchor, &pLogModule, sizeof(MEMORY_ADDRESS));
|
|
|
|
while (pLogModule != LogModuleAnchor && !CheckControlC()) {
|
|
pLogModule =
|
|
(MEMORY_ADDRESS) DumpLogModule( pLogModule,
|
|
UnicodeString.Buffer);
|
|
if (!UnicodeString.Buffer) {
|
|
dprintf("\n");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dprintf("Unable ro resolve %s\n","eventlog!LogModuleHead");
|
|
}
|
|
if (UnicodeString.Buffer) {
|
|
RtlFreeUnicodeString(&UnicodeString);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Dump a single LogFile structure if it matches MatchName (NULL matches
|
|
// all)
|
|
//
|
|
|
|
PLIST_ENTRY
|
|
DumpLogFile(
|
|
HANDLE hCurrentProcess,
|
|
MEMORY_ADDRESS pLogFile,
|
|
LPWSTR MatchName
|
|
)
|
|
{
|
|
LOGFILE LogFile;
|
|
LPWSTR UnicodeName;
|
|
|
|
//
|
|
// Get the fixed part of the structure
|
|
//
|
|
|
|
GET_DATA(pLogFile, &LogFile, sizeof(LogFile))
|
|
|
|
//
|
|
// Get the Default module name
|
|
//
|
|
|
|
UnicodeName = GetUnicodeString(LogFile.LogModuleName);
|
|
|
|
//
|
|
// See if we're just looking for a particular one. If we are and
|
|
// this isn't it, bail out.
|
|
//
|
|
|
|
if (MatchName && _wcsicmp(MatchName, UnicodeName)) {
|
|
LocalFree(UnicodeName);
|
|
return (LogFile.FileList.Flink);
|
|
}
|
|
|
|
//
|
|
// Otherwise print it out
|
|
//
|
|
|
|
dprintf("%ws", UnicodeName);
|
|
LocalFree(UnicodeName);
|
|
|
|
//
|
|
// Now the file name of this logfile
|
|
//
|
|
|
|
UnicodeName = GetUnicodeString(LogFile.LogFileName);
|
|
dprintf(" : %ws\n", UnicodeName);
|
|
LocalFree(UnicodeName);
|
|
|
|
if (LogFile.Notifiees.Flink == LogFile.Notifiees.Blink) {
|
|
dprintf("\tNo active ChangeNotifies on this log\n");
|
|
}
|
|
else {
|
|
dprintf("\tActive Change Notify! Dump of this list not implemented\n");
|
|
}
|
|
|
|
dprintf("\tReference Count: %d\n\tFlags: ", LogFile.RefCount);
|
|
if (LogFile.Flags == 0) {
|
|
dprintf("No flags set ");
|
|
}
|
|
else {
|
|
if (LogFile.Flags & ELF_LOGFILE_HEADER_DIRTY) {
|
|
dprintf("Dirty ");
|
|
}
|
|
if (LogFile.Flags & ELF_LOGFILE_HEADER_WRAP) {
|
|
dprintf("Wrapped ");
|
|
}
|
|
if (LogFile.Flags & ELF_LOGFILE_LOGFULL_WRITTEN) {
|
|
dprintf("Logfull Written ");
|
|
}
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf("\tMax Files Sizes [Cfg:Curr:Next] 0x%X : 0x%X : 0x%X\n",
|
|
LogFile.ConfigMaxFileSize, LogFile.ActualMaxFileSize,
|
|
LogFile.NextClearMaxFileSize);
|
|
|
|
dprintf("\tRecord Numbers [Oldest:Curr] %d : %d\n",
|
|
LogFile.OldestRecordNumber, LogFile.CurrentRecordNumber);
|
|
|
|
dprintf("\tRetention period in days: %d\n", LogFile.Retention / 86400);
|
|
|
|
dprintf("\tBase Address: 0x%X\n", LogFile.BaseAddress);
|
|
|
|
dprintf("\tView size: 0x%X\n", LogFile.ViewSize);
|
|
|
|
dprintf("\tOffset of beginning record: 0x%X\n", LogFile.BeginRecord);
|
|
|
|
dprintf("\tOffset of ending record: 0x%X\n", LogFile.EndRecord);
|
|
|
|
return (LogFile.FileList.Flink);
|
|
}
|
|
|
|
//
|
|
// Dump selected, or all, LogFile structures
|
|
//
|
|
|
|
|
|
DECLARE_API(logfile)
|
|
{
|
|
|
|
MEMORY_ADDRESS pLogFile;
|
|
MEMORY_ADDRESS LogFileAnchor;
|
|
LPWSTR wArgumentString = NULL;
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING UnicodeString;
|
|
BOOL AllocateString = FALSE;
|
|
|
|
INIT_API();
|
|
|
|
UnicodeString.Buffer = NULL;
|
|
|
|
//
|
|
// Evaluate the argument string to get the address of
|
|
// the logfile to dump. If no parm, dump them all.
|
|
//
|
|
while (isspace(*lpArgumentString)) lpArgumentString++;
|
|
|
|
if (lpArgumentString && *lpArgumentString) {
|
|
if(*lpArgumentString == '.') {
|
|
lpArgumentString++;
|
|
RtlInitAnsiString(&AnsiString, lpArgumentString);
|
|
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
|
|
}
|
|
else {
|
|
pLogFile = GetExpression(lpArgumentString);
|
|
DumpLogFile(hCurrentProcess, pLogFile, NULL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
LogFileAnchor = GetExpression("eventlog!LogFilesHead");
|
|
|
|
GET_DATA(LogFileAnchor, &pLogFile, sizeof(MEMORY_ADDRESS))
|
|
|
|
while (pLogFile != LogFileAnchor) {
|
|
pLogFile =
|
|
(MEMORY_ADDRESS) DumpLogFile(hCurrentProcess, pLogFile,
|
|
UnicodeString.Buffer);
|
|
if (!UnicodeString.Buffer) {
|
|
dprintf("\n");
|
|
}
|
|
}
|
|
|
|
if (UnicodeString.Buffer) {
|
|
RtlFreeUnicodeString(&UnicodeString);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Dump a request packet structure
|
|
//
|
|
|
|
|
|
DECLARE_API(request)
|
|
{
|
|
ELF_REQUEST_RECORD Request;
|
|
MEMORY_ADDRESS Pointer;
|
|
DWORD RecordSize;
|
|
WRITE_PKT WritePkt;
|
|
READ_PKT ReadPkt;
|
|
CLEAR_PKT ClearPkt;
|
|
BACKUP_PKT BackupPkt;
|
|
LPWSTR FileName;
|
|
CHAR Address[32];
|
|
|
|
INIT_API();
|
|
|
|
//
|
|
// Evaluate the argument string to get the address of
|
|
// the request packet to dump.
|
|
//
|
|
while (isspace(*lpArgumentString)) lpArgumentString++;
|
|
|
|
if (lpArgumentString && *lpArgumentString) {
|
|
Pointer = GetExpression(lpArgumentString);
|
|
}
|
|
else {
|
|
dprintf("Must supply a request packet address\n");
|
|
return;
|
|
}
|
|
|
|
GET_DATA(Pointer, &Request, sizeof(ELF_REQUEST_RECORD))
|
|
|
|
switch (Request.Command ) {
|
|
case ELF_COMMAND_READ:
|
|
dprintf("\nRead packet\n");
|
|
GET_DATA(Request.Pkt.ReadPkt, &ReadPkt, sizeof(READ_PKT))
|
|
dprintf("\tLast Seek Position = %d\n", ReadPkt.LastSeekPos);
|
|
dprintf("\tLast Seek Record = %d\n", ReadPkt.LastSeekRecord);
|
|
dprintf("\tStart at record number %d\n", ReadPkt.RecordNumber);
|
|
dprintf("\tRead %d bytes into buffer at 0x%X\n",
|
|
ReadPkt.BufferSize, ReadPkt.Buffer);
|
|
if (ReadPkt.Flags & ELF_IREAD_UNICODE) {
|
|
dprintf("\tReturn in ANSI\n");
|
|
}
|
|
else {
|
|
dprintf("\tReturn in UNICODE\n");
|
|
}
|
|
dprintf("\tRead flags: ");
|
|
if (ReadPkt.ReadFlags & EVENTLOG_SEQUENTIAL_READ) {
|
|
dprintf("Sequential ");
|
|
}
|
|
if (ReadPkt.ReadFlags & EVENTLOG_SEEK_READ) {
|
|
dprintf("Seek ");
|
|
}
|
|
if (ReadPkt.ReadFlags & EVENTLOG_FORWARDS_READ) {
|
|
dprintf("Forward ");
|
|
}
|
|
if (ReadPkt.ReadFlags & EVENTLOG_BACKWARDS_READ) {
|
|
dprintf("Backwards ");
|
|
}
|
|
dprintf("\n");
|
|
break;
|
|
|
|
case ELF_COMMAND_WRITE:
|
|
dprintf("\nWrite packet\n");
|
|
if (Request.Flags == ELF_FORCE_OVERWRITE) {
|
|
dprintf("with ELF_FORCE_OVERWRITE enabled\n");
|
|
}
|
|
else {
|
|
dprintf("\n");
|
|
}
|
|
GET_DATA(Request.Pkt.WritePkt, &WritePkt, sizeof(WRITE_PKT))
|
|
RecordSize = (WritePkt.Datasize);
|
|
DumpRecord((MEMORY_ADDRESS)WritePkt.Buffer, 0, 0, 0);
|
|
break;
|
|
|
|
case ELF_COMMAND_CLEAR:
|
|
dprintf("\nClear packet\n");
|
|
GET_DATA(Request.Pkt.ClearPkt, &ClearPkt, sizeof(CLEAR_PKT))
|
|
FileName = GetUnicodeString(ClearPkt.BackupFileName);
|
|
dprintf("Backup filename = %ws\n", FileName);
|
|
LocalFree(FileName);
|
|
break;
|
|
|
|
case ELF_COMMAND_BACKUP:
|
|
dprintf("\nBackup packet\n");
|
|
GET_DATA(Request.Pkt.BackupPkt, &BackupPkt, sizeof(BACKUP_PKT))
|
|
FileName = GetUnicodeString(BackupPkt.BackupFileName);
|
|
dprintf("Backup filename = %ws\n", FileName);
|
|
LocalFree(FileName);
|
|
break;
|
|
|
|
case ELF_COMMAND_WRITE_QUEUED:
|
|
dprintf("\nQueued Write packet\n");
|
|
if (Request.Flags == ELF_FORCE_OVERWRITE) {
|
|
dprintf("with ELF_FORCE_OVERWRITE enabled\n");
|
|
}
|
|
else {
|
|
dprintf("\n");
|
|
}
|
|
dprintf("NtStatus = 0x%X\n", Request.Status);
|
|
break;
|
|
|
|
default:
|
|
dprintf("\nInvalid packet\n");
|
|
}
|
|
|
|
dprintf("\nLogFile for this packet:\n\n");
|
|
sprintf(Address,"%p",Request.LogFile);
|
|
logfile(hCurrentProcess,
|
|
hCurrentThread, dwCurrentPc, dwProcessor,
|
|
Address);
|
|
|
|
dprintf("\nLogModule for this packet:\n\n");
|
|
sprintf(Address,"%p",Request.Module);
|
|
logmodule(hCurrentProcess, hCurrentThread, dwCurrentPc, dwProcessor,
|
|
Address);
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Online help
|
|
//
|
|
|
|
|
|
DECLARE_API(help)
|
|
{
|
|
INIT_API();
|
|
|
|
dprintf("\nEventlog debugger Extensions\n");
|
|
|
|
if (!lpArgumentString || *lpArgumentString == '\0' ||
|
|
*lpArgumentString == '\n' || *lpArgumentString == '\r') {
|
|
dprintf("\tlogmodule - dump a logmodule structure\n");
|
|
dprintf("\tlogfile - dump a logfile structure\n");
|
|
dprintf("\trequest - dump a request record\n");
|
|
dprintf("\trecord - dump a eventlog record\n");
|
|
dprintf("\n\tEnter help <cmd> for detailed help on a command\n");
|
|
}
|
|
else {
|
|
if (!_stricmp(lpArgumentString, "logmodule")) {
|
|
dprintf("\tlogmodule <arg>, where <arg> can be one of:\n");
|
|
dprintf("\t\tno argument - dump all logmodule structures\n");
|
|
dprintf("\t\taddress - dump the logmodule at specified address\n");
|
|
dprintf("\t\t.string - dump the logmodule with name string\n");
|
|
}
|
|
else if (!_stricmp(lpArgumentString, "logfile")) {
|
|
dprintf("\tlogfile <arg>, where <arg> can be one of:\n");
|
|
dprintf("\t\tno argument - dump all logfile structures\n");
|
|
dprintf("\t\taddress - dump the logfile at specified address\n");
|
|
dprintf("\t\t.string - dump the logfile with name string\n");
|
|
}
|
|
else if (!_stricmp(lpArgumentString, "record")) {
|
|
dprintf("\trecord <arg>, where <arg> can be one of:\n");
|
|
dprintf("\t\tno argument - dump all records in system log\n");
|
|
dprintf("\t\taddress - dump records starting at specified address\n");
|
|
dprintf("\t\t.string - dump all records in the <string> log\n");
|
|
dprintf("\t\t#<nnn> - dumps records starting at nnn in system log\n");
|
|
dprintf("\t\t#<nnn> .string - dumps records starting at nnn in <string> log\n");
|
|
}
|
|
else if (!_stricmp(lpArgumentString, "request")) {
|
|
dprintf("\trequest - dump the request record at specified address\n");
|
|
}
|
|
else {
|
|
dprintf("\tInvalid command [%s]\n", lpArgumentString);
|
|
}
|
|
}
|
|
}
|