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.
 
 
 
 
 
 

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