windows-nt/Source/XPSP1/NT/base/tools/kdexts2/errorlog.c
2020-09-26 16:20:57 +08:00

188 lines
4.7 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
errorlog.c
Abstract:
WinDbg Extension Api
Author:
Wesley Witt (wesw) 15-Aug-1993
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
DECLARE_API( errlog )
/*++
Routine Description:
This routine dumps the contents of the error log list. It uses a nasty
hack to get started (i.e. a duplicate structure definition) because the
error log list entries are not defined in a public header.
Arguments:
args - not used
Return Value:
None
--*/
{
ULONG64 listAddress;
ULONG result;
ULONG i;
ULONG64 next;
ULONG64 entryAddress;
ULONG64 HeadFlink;
ULONG ErrLogOff, DataOff;
listAddress = GetNtDebuggerData( IopErrorLogListHead );
if (!listAddress) {
dprintf("Can't find error log list head\n");
goto exit;
}
if (GetFieldValue(listAddress,
"nt!_LIST_ENTRY",
"Flink",
HeadFlink)) {
dprintf("%08p: Could not read error log list head\n", listAddress);
goto exit;
}
//
// walk the list.
//
next = HeadFlink;
if (next == 0) {
dprintf("ErrorLog is empty\n");
goto exit;
}
if (next == listAddress) {
dprintf("errorlog is empty\n");
} else {
dprintf("PacketAdr DeviceObj DriverObj Function ErrorCode UniqueVal FinalStat\n");
}
GetFieldOffset("nt!ERROR_LOG_ENTRY", "ListEntry", &ErrLogOff);
GetFieldOffset("nt!IO_ERROR_LOG_PACKET", "DumpData", &DataOff);
while(next != listAddress) {
ULONG64 DeviceObject, DriverObject;
ULONG DumpDataSize;
if (next != 0) {
entryAddress = next - ErrLogOff;
} else {
break;
}
//
// Read the internal error log packet structure.
//
if (GetFieldValue(entryAddress,
"nt!ERROR_LOG_ENTRY",
"DeviceObject",
DeviceObject)) {
dprintf("%08p: Cannot read entry\n", entryAddress);
goto exit;
}
GetFieldValue(entryAddress,"ERROR_LOG_ENTRY","DriverObject", DriverObject);
GetFieldValue(entryAddress,"ERROR_LOG_ENTRY","ListEntry.Flink", next);
//
// now calculate the address and read the io_error_log_packet
//
entryAddress = entryAddress + GetTypeSize("ERROR_LOG_ENTRY");
if (GetFieldValue(entryAddress,
"nt!IO_ERROR_LOG_PACKET",
"DumpDataSize",
DumpDataSize)) {
dprintf("%08p: Cannot read packet\n", entryAddress);
goto exit;
}
//
// read again to get the dumpdata if necessary. This just rereads
// the entire packet into a new buffer and hopes the cache is enabled
// behind the DbgKdReadxx routine for performance.
//
InitTypeRead(entryAddress, nt!IO_ERROR_LOG_PACKET);
dprintf("%08p %08p %08p %2x %08lx %08lx %08lx\n",
entryAddress,
DeviceObject,
DriverObject,
(UCHAR) ReadField(MajorFunctionCode),
(ULONG) ReadField(ErrorCode),
(ULONG) ReadField(UniqueErrorValue),
(ULONG) ReadField(FinalStatus));
dprintf("\t\t ");
DumpDriver(DriverObject, 0, 0);
if (DumpDataSize) {
PULONG dumpData;
dumpData = LocalAlloc(LPTR, DumpDataSize);
if (dumpData == NULL) {
dprintf("%08lx: Cannot allocate memory for dumpData (%u)\n", DumpDataSize);
goto exit;
}
if ((!ReadMemory(entryAddress + DataOff,
dumpData,
DumpDataSize,
&result)) || (result != DumpDataSize)) {
LocalFree(dumpData);
dprintf("%08p: Cannot read packet and dump data\n", entryAddress);
goto exit;
}
dprintf("\n\t\t DumpData: ");
for (i = 0; (i * sizeof(ULONG)) < DumpDataSize; i++) {
dprintf("%08lx ", dumpData[i]);
if ((i & 0x03) == 0x03) {
dprintf("\n\t\t ");
}
if (CheckControlC()) {
break;
}
}
LocalFree(dumpData);
}
dprintf("\n");
if (CheckControlC()) {
goto exit;
}
}
exit:
return S_OK;
}