|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
ioverifier.c
Abstract:
WinDbg Extension code for accessing I/O Verifier information
Author:
Adrian J. Oney (adriao) 11-Oct-2000
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
BOOLEAN GetTheSystemTime ( OUT PLARGE_INTEGER Time );
VOID PrintIrpStack( IN ULONG64 IrpSp );
typedef enum {
IOV_EVENT_NONE = 0, IOV_EVENT_IO_ALLOCATE_IRP, IOV_EVENT_IO_CALL_DRIVER, IOV_EVENT_IO_CALL_DRIVER_UNWIND, IOV_EVENT_IO_COMPLETE_REQUEST, IOV_EVENT_IO_COMPLETION_ROUTINE, IOV_EVENT_IO_COMPLETION_ROUTINE_UNWIND, IOV_EVENT_IO_CANCEL_IRP, IOV_EVENT_IO_FREE_IRP
} IOV_LOG_EVENT;
#define VI_DATABASE_HASH_SIZE 256
#define VI_DATABASE_HASH_PRIME 131
#define VI_DATABASE_CALCULATE_HASH(Irp) \
(((((UINT_PTR) Irp)/PageSize)*VI_DATABASE_HASH_PRIME) % VI_DATABASE_HASH_SIZE)
#define IRP_ALLOC_COUNT 8
#define IRP_LOG_ENTRIES 16
#define TRACKFLAG_SURROGATE 0x00000002
#define TRACKFLAG_HAS_SURROGATE 0x00000004
#define TRACKFLAG_PROTECTEDIRP 0x00000008
#define TRACKFLAG_QUEUED_INTERNALLY 0x00000010
#define TRACKFLAG_BOGUS 0x00000020
#define TRACKFLAG_RELEASED 0x00000040
#define TRACKFLAG_SRB_MUNGED 0x00000080
#define TRACKFLAG_SWAPPED_BACK 0x00000100
#define TRACKFLAG_DIRECT_BUFFERED 0x00000200
#define TRACKFLAG_WATERMARKED 0x00100000
#define TRACKFLAG_IO_ALLOCATED 0x00200000
#define TRACKFLAG_UNWOUND_BADLY 0x00400000
#define TRACKFLAG_PASSED_AT_BAD_IRQL 0x02000000
#define TRACKFLAG_IN_TRANSIT 0x40000000
ENUM_NAME LogEntryTypes[] = { ENUM_NAME(IOV_EVENT_NONE), ENUM_NAME(IOV_EVENT_IO_ALLOCATE_IRP), ENUM_NAME(IOV_EVENT_IO_CALL_DRIVER), ENUM_NAME(IOV_EVENT_IO_CALL_DRIVER_UNWIND), ENUM_NAME(IOV_EVENT_IO_COMPLETE_REQUEST), ENUM_NAME(IOV_EVENT_IO_COMPLETION_ROUTINE), ENUM_NAME(IOV_EVENT_IO_COMPLETION_ROUTINE_UNWIND), ENUM_NAME(IOV_EVENT_IO_CANCEL_IRP), ENUM_NAME(IOV_EVENT_IO_FREE_IRP), {0,0} };
typedef enum {
IOV_SYMBOL_PROBLEM, IOV_NO_DATABASE, IOV_ACCESS_PROBLEM, IOV_WALK_TERMINATED, IOV_ALL_PACKETS_WALKED, IOV_CTRL_C
} IOV_WALK_RESULT;
typedef BOOL (*PFN_IOVERIFIER_PACKET_ENUM)(ULONG64 Packet, PVOID Context);
IOV_WALK_RESULT IoVerifierEnumIovPackets( IN ULONG64 TargetIrp OPTIONAL, IN PFN_IOVERIFIER_PACKET_ENUM Callback, IN PVOID Context, OUT ULONG *PacketsScanned );
typedef struct {
ULONG64 IrpToStopOn;
} DUMP_CONTEXT, *PDUMP_CONTEXT;
BOOL IoVerifierDumpIovPacketDetailed( IN ULONG64 IovPacketReal, IN PVOID Context );
BOOL IoVerifierDumpIovPacketSummary( IN ULONG64 IovPacketReal, IN PVOID Context );
DECLARE_API( iovirp ) /*++
Routine Description:
Temporary verifier irp data dumper until this is integrated into !irp itself
Arguments:
args - the irp to dump
Return Value:
None
--*/ { ULONG64 irpToDump = 0; IOV_WALK_RESULT walkResult; DUMP_CONTEXT dumpContext; ULONG packetsOutstanding;
irpToDump = GetExpression(args);
dumpContext.IrpToStopOn = irpToDump;
if (irpToDump == 0) {
dprintf("!Irp Outstanding !DevStack !DrvObj\n"); }
walkResult = IoVerifierEnumIovPackets( irpToDump, irpToDump ? IoVerifierDumpIovPacketDetailed : IoVerifierDumpIovPacketSummary, &dumpContext, &packetsOutstanding );
switch(walkResult) {
case IOV_SYMBOL_PROBLEM: dprintf("No information available - check symbols\n"); break;
case IOV_NO_DATABASE: dprintf("No information available - the verifier is probably disabled\n"); break;
case IOV_ACCESS_PROBLEM: dprintf("A problem occured reading memory\n"); break;
case IOV_WALK_TERMINATED: case IOV_ALL_PACKETS_WALKED: case IOV_CTRL_C: default: break; }
dprintf("Packets processed: 0x%x\n", packetsOutstanding); return S_OK; }
IOV_WALK_RESULT IoVerifierEnumIovPackets( IN ULONG64 TargetIrp OPTIONAL, IN PFN_IOVERIFIER_PACKET_ENUM Callback, IN PVOID Context, OUT ULONG *PacketsScanned ) { ULONG64 ViIrpDatabaseReal = 0; PVOID ViIrpDatabaseLocal; ULONG sizeofListEntry; ULONG start, end, i, hashLinkOffset; ULONG64 listEntryHead, listEntryNext, iovPacketReal, currentIrp;
*PacketsScanned = 0;
sizeofListEntry = GetTypeSize("nt!_LIST_ENTRY");
if (sizeofListEntry == 0) {
return IOV_SYMBOL_PROBLEM; }
ViIrpDatabaseReal = GetPointerValue("nt!ViIrpDatabase");
if (ViIrpDatabaseReal == 0) {
return IOV_NO_DATABASE; }
GetFieldOffset("nt!IOV_REQUEST_PACKET", "HashLink.Flink", &hashLinkOffset);
if (TargetIrp != 0) {
start = end = (ULONG ) (VI_DATABASE_CALCULATE_HASH(TargetIrp));
} else {
start = 0; end = VI_DATABASE_HASH_SIZE-1; }
for(i=start; i<=end; i++) {
listEntryHead = ViIrpDatabaseReal + (i*sizeofListEntry);
if (GetFieldValue(listEntryHead, "nt!_LIST_ENTRY", "Flink", listEntryNext)) {
return IOV_ACCESS_PROBLEM; }
while(listEntryNext != listEntryHead) {
(*PacketsScanned)++;
iovPacketReal = listEntryNext - hashLinkOffset;
if (GetFieldValue(iovPacketReal, "nt!IOV_REQUEST_PACKET", "HashLink.Flink", listEntryNext)) {
return IOV_ACCESS_PROBLEM; }
if (TargetIrp) {
if (GetFieldValue(iovPacketReal, "nt!IOV_REQUEST_PACKET", "TrackedIrp", currentIrp)) {
return IOV_ACCESS_PROBLEM; }
if (TargetIrp != currentIrp) {
continue; } }
if (CheckControlC()) {
return IOV_CTRL_C; }
if (Callback(iovPacketReal, Context) == FALSE) {
return IOV_WALK_TERMINATED; } }
if (CheckControlC()) {
return IOV_CTRL_C; } }
return IOV_ALL_PACKETS_WALKED; }
BOOL IoVerifierDumpIovPacketDetailed( IN ULONG64 IovPacketReal, IN PVOID Context ) { ULONG i, j; UCHAR symBuffer[256]; ULONG64 displacement, logBuffer, allocatorAddress, logBufferEntry; ULONG logBufferOffset, sizeofLogEntry, allocatorOffset; PDUMP_CONTEXT dumpContext;
dumpContext = (PDUMP_CONTEXT) Context;
InitTypeRead(IovPacketReal, nt!IOV_REQUEST_PACKET);
dprintf("IovPacket\t%1p\n", IovPacketReal); dprintf("TrackedIrp\t%1p\n", ReadField(TrackedIrp)); dprintf("HeaderLock\t%x\n", ReadField(HeaderLock)); dprintf("LockIrql\t%x\n", ReadField(LockIrql)); dprintf("ReferenceCount\t%x\n", ReadField(ReferenceCount)); dprintf("PointerCount\t%x\n", ReadField(PointerCount)); dprintf("HeaderFlags\t%08x\n", ReadField(HeaderFlags)); dprintf("ChainHead\t%1p\n", ReadField(ChainHead)); dprintf("Flags\t\t%08x\n", ReadField(Flags)); dprintf("DepartureIrql\t%x\n", ReadField(DepartureIrql)); dprintf("ArrivalIrql\t%x\n", ReadField(ArrivalIrql)); dprintf("StackCount\t%x\n", ReadField(StackCount)); dprintf("QuotaCharge\t%08x\n", ReadField(QuotaCharge)); dprintf("QuotaProcess\t%1p\n", ReadField(QuotaProcess)); dprintf("RealIrpCompletionRoutine\t%1p\n", ReadField(RealIrpCompletionRoutine)); dprintf("RealIrpControl\t\t\t%x\n", ReadField(RealIrpControl)); dprintf("RealIrpContext\t\t\t%1p\n", ReadField(RealIrpContext));
dprintf("TopStackLocation\t%x\n", ReadField(TopStackLocation)); dprintf("PriorityBoost\t\t%x\n", ReadField(PriorityBoost)); dprintf("LastLocation\t\t%x\n", ReadField(LastLocation)); dprintf("RefTrackingCount\t%x\n", ReadField(RefTrackingCount));
dprintf("SystemDestVA\t\t%1p\n", ReadField(SystemDestVA)); dprintf("VerifierSettings\t%1p\n", ReadField(VerifierSettings)); dprintf("pIovSessionData\t\t%1p\n", ReadField(pIovSessionData));
GetFieldOffset("nt!IOV_REQUEST_PACKET", "AllocatorStack", &allocatorOffset);
dprintf("Allocation Stack:\n"); for(i=0; i<IRP_ALLOC_COUNT; i++) {
allocatorAddress = GetPointerFromAddress(IovPacketReal + allocatorOffset + i*DBG_PTR_SIZE);
if (allocatorAddress) {
symBuffer[0]='!'; GetSymbol(allocatorAddress, symBuffer, &displacement); dprintf(" %s+%1p (%1p)\n",symBuffer,displacement,allocatorAddress); } } dprintf("\n");
//
// If this was compiled free, these will both come back zero.
//
i = (ULONG) ReadField(LogEntryTail); j = (ULONG) ReadField(LogEntryHead);
if (i == j) {
dprintf("IRP log entries: none stored\n"); } else {
GetFieldOffset("nt!IOV_REQUEST_PACKET", "LogEntries", &logBufferOffset); sizeofLogEntry = GetTypeSize("nt!IOV_LOG_ENTRY");
logBuffer = IovPacketReal + logBufferOffset;
while(i != j) {
logBufferEntry = logBuffer + i*sizeofLogEntry;
InitTypeRead(logBufferEntry, nt!IOV_LOG_ENTRY);
dprintf("%s\t", getEnumName((ULONG) ReadField(Event), LogEntryTypes)); dprintf("by %1p (%p) ", ReadField(Address), ReadField(Data)); dprintf("on .thread %1p\n", ReadField(Thread));
i = (i+1) % IRP_LOG_ENTRIES; } }
InitTypeRead(IovPacketReal, nt!IOV_REQUEST_PACKET);
return (dumpContext->IrpToStopOn != ReadField(TrackedIrp)); }
BOOL IoVerifierDumpIovPacketSummary( IN ULONG64 IovPacketReal, IN PVOID Context ) { ULONG64 trackedIrp, iovSessionData, currentLocation, deviceObject; ULONG64 topStackLocation; ULONG64 iovCurStackLocation, iovNextStackLocation, currentIoStackLocation; PDUMP_CONTEXT dumpContext; ULONG pvoidSize, stackDataOffset; LARGE_INTEGER startTime, elapsedTime; TIME_FIELDS parsedTime;
dumpContext = (PDUMP_CONTEXT) Context;
pvoidSize = IsPtr64() ? 8 : 4;
InitTypeRead(IovPacketReal, nt!IOV_REQUEST_PACKET);
trackedIrp = ReadField(TrackedIrp); if (trackedIrp == 0) {
//
// If there's no IRP, it means we are tracking something that has
// completed but hasn't unwound. Therefore we ignore it.
//
goto PrintSummaryExit; }
if (ReadField(Flags) & TRACKFLAG_HAS_SURROGATE) {
//
// We only want to display the surrogate in this case.
//
goto PrintSummaryExit; }
iovSessionData = ReadField(pIovSessionData); if (iovSessionData == 0) {
//
// We only want to display live IRPs
//
goto PrintSummaryExit; }
topStackLocation = ReadField(TopStackLocation);
InitTypeRead(trackedIrp, nt!IRP);
currentLocation = ReadField(CurrentLocation); currentIoStackLocation = ReadField(Tail.Overlay.CurrentStackLocation);
parsedTime.Minute = 0;
if (currentLocation >= topStackLocation) {
deviceObject = 0;
dprintf("%1p [Completed] ", trackedIrp);
} else {
GetFieldOffset("nt!IOV_SESSION_DATA", "StackData", &stackDataOffset);
iovCurStackLocation = iovSessionData + stackDataOffset + (GetTypeSize("nt!IOV_STACK_LOCATION")*currentLocation);
InitTypeRead(iovCurStackLocation, nt!IOV_STACK_LOCATION);
if (ReadField(InUse)) {
iovNextStackLocation = iovSessionData + stackDataOffset + (GetTypeSize("nt!IOV_STACK_LOCATION")*(currentLocation - 1));
InitTypeRead(iovNextStackLocation, nt!IOV_STACK_LOCATION);
//
// Calculate the elasped time for this slot.
//
if (currentLocation && ReadField(InUse)) {
startTime.QuadPart = ReadField(PerfDispatchStart.QuadPart);
} else {
GetTheSystemTime(&startTime); }
InitTypeRead(iovCurStackLocation, nt!IOV_STACK_LOCATION);
elapsedTime.QuadPart = startTime.QuadPart - ReadField(PerfDispatchStart.QuadPart);
RtlTimeToElapsedTimeFields( &elapsedTime, &parsedTime );
InitTypeRead(currentIoStackLocation, nt!IO_STACK_LOCATION);
deviceObject = ReadField(DeviceObject);
//
// Alright, we got the goods. Let's print what we know...
//
dprintf("%1p %ld:%02ld:%02ld.%04ld %1p ", trackedIrp, parsedTime.Hour, parsedTime.Minute, parsedTime.Second, parsedTime.Milliseconds, deviceObject );
} else {
InitTypeRead(currentIoStackLocation, nt!IO_STACK_LOCATION);
deviceObject = ReadField(DeviceObject);
dprintf("%08lx %08lx ", trackedIrp, deviceObject); } }
if (deviceObject) { DumpDevice(deviceObject, 20, FALSE); }
dprintf(" "); PrintIrpStack(currentIoStackLocation); #if 0
if (parsedTime.Minute && (irp.CancelRoutine == NULL)) {
//
// This IRP has been held over a minute with no cancel routine.
// Take a free moment to flame the driver writer.
//
dprintf("*") ; *Delayed = TRUE ; // Should *not* be set to false otherwise.
} #endif
dprintf("\n") ; #if 0
if (DumpLevel>0) {
IovPacketPrintDetailed( IovPacket, &irp, RunTime ); } #endif
PrintSummaryExit: return TRUE; }
/*
#include "precomp.h"
#include "irpverif.h"
#pragma hdrstop
VOID IovPacketPrintSummary( IN PIOV_REQUEST_PACKET IovPacket, IN LARGE_INTEGER *RunTime, IN ULONG DumpLevel, OUT PBOOLEAN Delayed, OUT PLIST_ENTRY NextListEntry );
BOOLEAN GetTheSystemTime ( OUT PLARGE_INTEGER Time );
VOID DumpAllTrackedIrps( VOID ) { int i, j ; ULONG result; LIST_ENTRY iovPacketTable[IRP_TRACKING_HASH_SIZE] ; PLIST_ENTRY listHead, listEntry; LIST_ENTRY nextListEntry; PIOV_REQUEST_PACKET pIovPacket; LARGE_INTEGER RunTime ; ULONG_PTR tableAddress ; BOOLEAN delayed = FALSE ;
tableAddress = GetExpression( "Nt!IovpIrpTrackingTable" ) ; if (tableAddress == 0) {
goto DumpNoMore; }
if (!ReadMemory(tableAddress, iovPacketTable, sizeof(LIST_ENTRY)*IRP_TRACKING_HASH_SIZE, &result)) {
goto DumpNoMore; }
dprintf("!Irp Outstanding !DevStack !DrvObj\n") ;
GetTheSystemTime(&RunTime); for(i=j=0; i<IRP_TRACKING_HASH_SIZE; i++) {
listEntry = &iovPacketTable[i]; listHead = ((PLIST_ENTRY)tableAddress)+i;
while(listEntry->Flink != listHead) {
j++;
pIovPacket = CONTAINING_RECORD( listEntry->Flink, IOV_REQUEST_PACKET, HashLink );
dprintf("[%x.%x] = %x\n", i, j, pIovPacket) ;
listEntry = &nextListEntry;
IovPacketPrintSummary( pIovPacket, &RunTime, 0, &delayed, listEntry );
if (IsListEmpty(listEntry)) { break; }
if (CheckControlC()) {
goto DumpNoMore; } } }
if (!j) {
dprintf("\nIrp tracking does not appear to be enabled. Use \"!patch " "IrpTrack\" in the\nchecked build to enable this feature.\n") ; }
if (delayed) {
dprintf("* PROBABLE DRIVER BUG: An IRP has been sitting in the driver for more\n" " than a minute without a cancel routine\n") ; }
DumpNoMore: return ; }
VOID IovPacketPrintDetailed( PIOV_REQUEST_PACKET IovPacket, PIRP IrpData, LARGE_INTEGER *RunTime ) { CHAR buffer[80]; ULONG displacement; IOV_REQUEST_PACKET iovPacketData; LARGE_INTEGER *startTime, elapsedTime ; TIME_FIELDS Times; IRP_ALLOC_DATA irpAllocData ; ULONG result; int i ;
if (!ReadMemory((ULONG_PTR) IovPacket, &iovPacketData, sizeof(IOV_REQUEST_PACKET), &result)) {
return; }
dprintf(" TrackingData - 0x%08lx\n", IovPacket);
dprintf(" TrackedIrp:0x%08lx\n", iovPacketData.TrackedIrp);
dprintf(" Flags:0x%08lx\n", iovPacketData.Flags);
if (iovPacketData.Flags&TRACKFLAG_ACTIVE) { dprintf(" TRACKFLAG_ACTIVE\n"); }
if (iovPacketData.Flags&TRACKFLAG_SURROGATE) { dprintf(" TRACKFLAG_SURROGATE\n"); }
if (iovPacketData.Flags&TRACKFLAG_HAS_SURROGATE) { dprintf(" TRACKFLAG_HAS_SURROGATE\n"); }
if (iovPacketData.Flags&TRACKFLAG_PROTECTEDIRP) { dprintf(" TRACKFLAG_PROTECTEDIRP\n"); }
if (iovPacketData.Flags&TRACKFLAG_QUEUED_INTERNALLY) { dprintf(" TRACKFLAG_QUEUED_INTERNALLY\n"); }
if (iovPacketData.Flags&TRACKFLAG_BOGUS) { dprintf(" TRACKFLAG_BOGUS\n"); }
if (iovPacketData.Flags&TRACKFLAG_RELEASED) { dprintf(" TRACKFLAG_RELEASED\n"); }
if (iovPacketData.Flags&TRACKFLAG_SRB_MUNGED) { dprintf(" TRACKFLAG_SRB_MUNGED\n"); }
if (iovPacketData.Flags&TRACKFLAG_SWAPPED_BACK) { dprintf(" TRACKFLAG_SWAPPED_BACK\n") ; }
if (iovPacketData.Flags&TRACKFLAG_WATERMARKED) { dprintf(" TRACKFLAG_WATERMARKED\n"); }
if (iovPacketData.Flags&TRACKFLAG_IO_ALLOCATED) { dprintf(" TRACKFLAG_IO_ALLOCATED\n"); }
if (iovPacketData.Flags&TRACKFLAG_IGNORE_NONCOMPLETES) { dprintf(" TRACKFLAG_IGNORE_NONCOMPLETES\n"); }
if (iovPacketData.Flags&TRACKFLAG_PASSED_FAILURE) { dprintf(" TRACKFLAG_PASSED_FAILURE\n"); }
if (iovPacketData.Flags&TRACKFLAG_IN_TRANSIT) { dprintf(" TRACKFLAG_IN_TRANSIT\n"); }
if (iovPacketData.Flags&TRACKFLAG_REMOVED_FROM_TABLE) { dprintf(" TRACKFLAG_REMOVED_FROM_TABLE\n"); }
dprintf(" AssertFlags:0x%08lx\n", iovPacketData.AssertFlags);
if (iovPacketData.AssertFlags&ASSERTFLAG_TRACKIRPS) { dprintf(" ASSERTFLAG_TRACKIRPS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_MONITOR_ALLOCS) { dprintf(" ASSERTFLAG_MONITOR_ALLOCS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_POLICEIRPS) { dprintf(" ASSERTFLAG_POLICEIRPS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_MONITORMAJORS) { dprintf(" ASSERTFLAG_MONITORMAJORS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_SURROGATE) { dprintf(" ASSERTFLAG_SURROGATE\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_SMASH_SRBS) { dprintf(" ASSERTFLAG_SMASH_SRBS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_CONSUME_ALWAYS) { dprintf(" ASSERTFLAG_CONSUME_ALWAYS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_FORCEPENDING) { dprintf(" ASSERTFLAG_FORCEPENDING\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_COMPLETEATDPC) { dprintf(" ASSERTFLAG_COMPLETEATDPC\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_COMPLETEATPASSIVE) { dprintf(" ASSERTFLAG_COMPLETEATPASSIVE\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_DEFERCOMPLETION) { dprintf(" ASSERTFLAG_DEFERCOMPLETION\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_ROTATE_STATUS) { dprintf(" ASSERTFLAG_ROTATE_STATUS\n"); }
if (iovPacketData.AssertFlags&ASSERTFLAG_SEEDSTACK) { dprintf(" ASSERTFLAG_SEEDSTACK\n"); }
dprintf(" ReferenceCount:0x%x PointerCount:0x%x\n", iovPacketData.ReferenceCount, iovPacketData.PointerCount ) ;
dprintf(" RealIrpCompletionRoutine:0x%08lx\n", iovPacketData.RealIrpCompletionRoutine ) ;
dprintf(" RealIrpControl:0x%02lx RealIrpContext:0x%08lx\n", iovPacketData.RealIrpControl, iovPacketData.RealIrpContext ) ;
dprintf(" TopStackLocation:0x%x LastLocation:0x%x StackCount:0x%x\n", iovPacketData.TopStackLocation, iovPacketData.LastLocation, iovPacketData.StackCount ) ;
dprintf("\n RefTrackingCount:0x%x\n", iovPacketData.RefTrackingCount ) ;
//
// Calculate the elasped time for the entire IRP
//
elapsedTime.QuadPart = RunTime->QuadPart - IrpTrackingEntry->PerfCounterStart.QuadPart; RtlTimeToElapsedTimeFields ( &elapsedTime, &Times);
dprintf(" IrpElapsedTime (hms) - %ld:%02ld:%02ld.%04ld\n", Times.Hour, Times.Minute, Times.Second, Times.Milliseconds );
//
// Preload symbols...
//
for(i=0; i<=IrpTrackingEntry->StackCount; i++) { if (StackLocationData[i].InUse) { GetSymbol((LPVOID)StackLocationData[i].LastDispatch, buffer, &displacement); } }
//
// Preload symbols...
//
for(i=0; i<IRP_ALLOC_COUNT; i++) { GetSymbol((LPVOID)iovPacketData.AllocatorStack[i], buffer, &displacement); }
dprintf("\n Stack at time of IoAllocateIrp:\n") ; for(i=0; i<IRP_ALLOC_COUNT; i++) { buffer[0] = '!'; GetSymbol((LPVOID)iovPacketData.AllocatorStack[i], buffer, &displacement); dprintf(" %s", buffer) ; if (displacement) { dprintf( "+0x%x", displacement ); } dprintf("\n") ; }
dprintf("\n ## InUse Head Flags IrpSp ElaspedTime Dispatch\n");
for(i=0; i<=IrpTrackingEntry->StackCount; i++) {
//
// Show each stack location
//
if (StackLocationData[i].InUse) {
if (i&&StackLocationData[i-1].InUse) {
startTime = &StackLocationData[i-1].PerfCounterStart ;
} else {
startTime = RunTime ; }
elapsedTime.QuadPart = startTime->QuadPart - StackLocationData[i].PerfCounterStart.QuadPart;
RtlTimeToElapsedTimeFields ( &elapsedTime, &Times);
buffer[0] = '!'; GetSymbol((LPVOID)StackLocationData[i].LastDispatch, buffer, &displacement);
dprintf( " %c%02lx Y %02lx %08lx %08lx %ld:%02ld:%02ld.%04ld %s", (IrpData->CurrentLocation == i) ? '>' : ' ', i, StackLocationData[i].OriginalRequestSLD - IrpTrackingPointer->StackData, StackLocationData[i].Flags, StackLocationData[i].IrpSp, Times.Hour, Times.Minute, Times.Second, Times.Milliseconds, buffer ) ;
if (displacement) { dprintf( "+0x%x", displacement ); }
} else {
dprintf( " %c%02lx N %08lx", (IrpData->CurrentLocation == i) ? '>' : ' ', i, StackLocationData[i].Flags ) ; } dprintf("\n") ; } dprintf("\n") ; } #endif
*/
PCHAR IrpMajorNames[] = { "IRP_MJ_CREATE", // 0x00
"IRP_MJ_CREATE_NAMED_PIPE", // 0x01
"IRP_MJ_CLOSE", // 0x02
"IRP_MJ_READ", // 0x03
"IRP_MJ_WRITE", // 0x04
"IRP_MJ_QUERY_INFORMATION", // 0x05
"IRP_MJ_SET_INFORMATION", // 0x06
"IRP_MJ_QUERY_EA", // 0x07
"IRP_MJ_SET_EA", // 0x08
"IRP_MJ_FLUSH_BUFFERS", // 0x09
"IRP_MJ_QUERY_VOLUME_INFORMATION", // 0x0a
"IRP_MJ_SET_VOLUME_INFORMATION", // 0x0b
"IRP_MJ_DIRECTORY_CONTROL", // 0x0c
"IRP_MJ_FILE_SYSTEM_CONTROL", // 0x0d
"IRP_MJ_DEVICE_CONTROL", // 0x0e
"IRP_MJ_INTERNAL_DEVICE_CONTROL", // 0x0f
"IRP_MJ_SHUTDOWN", // 0x10
"IRP_MJ_LOCK_CONTROL", // 0x11
"IRP_MJ_CLEANUP", // 0x12
"IRP_MJ_CREATE_MAILSLOT", // 0x13
"IRP_MJ_QUERY_SECURITY", // 0x14
"IRP_MJ_SET_SECURITY", // 0x15
"IRP_MJ_POWER", // 0x16
"IRP_MJ_SYSTEM_CONTROL", // 0x17
"IRP_MJ_DEVICE_CHANGE", // 0x18
"IRP_MJ_QUERY_QUOTA", // 0x19
"IRP_MJ_SET_QUOTA", // 0x1a
"IRP_MJ_PNP", // 0x1b
NULL } ;
#define MAX_NAMED_MAJOR_IRPS 0x1b
PCHAR PnPIrpNames[] = { "IRP_MN_START_DEVICE", // 0x00
"IRP_MN_QUERY_REMOVE_DEVICE", // 0x01
"IRP_MN_REMOVE_DEVICE - ", // 0x02
"IRP_MN_CANCEL_REMOVE_DEVICE", // 0x03
"IRP_MN_STOP_DEVICE", // 0x04
"IRP_MN_QUERY_STOP_DEVICE", // 0x05
"IRP_MN_CANCEL_STOP_DEVICE", // 0x06
"IRP_MN_QUERY_DEVICE_RELATIONS", // 0x07
"IRP_MN_QUERY_INTERFACE", // 0x08
"IRP_MN_QUERY_CAPABILITIES", // 0x09
"IRP_MN_QUERY_RESOURCES", // 0x0A
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS", // 0x0B
"IRP_MN_QUERY_DEVICE_TEXT", // 0x0C
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS", // 0x0D
"INVALID_IRP_CODE", //
"IRP_MN_READ_CONFIG", // 0x0F
"IRP_MN_WRITE_CONFIG", // 0x10
"IRP_MN_EJECT", // 0x11
"IRP_MN_SET_LOCK", // 0x12
"IRP_MN_QUERY_ID", // 0x13
"IRP_MN_QUERY_PNP_DEVICE_STATE", // 0x14
"IRP_MN_QUERY_BUS_INFORMATION", // 0x15
"IRP_MN_DEVICE_USAGE_NOTIFICATION", // 0x16
"IRP_MN_SURPRISE_REMOVAL", // 0x17
"IRP_MN_QUERY_LEGACY_BUS_INFORMATION", // 0x18
NULL } ;
#define MAX_NAMED_PNP_IRP 0x18
PCHAR WmiIrpNames[] = { "IRP_MN_QUERY_ALL_DATA", // 0x00
"IRP_MN_QUERY_SINGLE_INSTANCE", // 0x01
"IRP_MN_CHANGE_SINGLE_INSTANCE", // 0x02
"IRP_MN_CHANGE_SINGLE_ITEM", // 0x03
"IRP_MN_ENABLE_EVENTS", // 0x04
"IRP_MN_DISABLE_EVENTS", // 0x05
"IRP_MN_ENABLE_COLLECTION", // 0x06
"IRP_MN_DISABLE_COLLECTION", // 0x07
"IRP_MN_REGINFO", // 0x08
"IRP_MN_EXECUTE_METHOD", // 0x09
NULL } ;
#define MAX_NAMED_WMI_IRP 0x9
PCHAR PowerIrpNames[] = { "IRP_MN_WAIT_WAKE", // 0x00
"IRP_MN_POWER_SEQUENCE", // 0x01
"IRP_MN_SET_POWER", // 0x02
"IRP_MN_QUERY_POWER", // 0x03
NULL } ;
#define MAX_NAMED_POWER_IRP 0x3
VOID PrintIrpStack( IN ULONG64 IrpSp ) { ULONG majorFunction, minorFunction, type;
InitTypeRead(IrpSp, nt!IO_STACK_LOCATION);
majorFunction = (ULONG) ReadField(MajorFunction); minorFunction = (ULONG) ReadField(MinorFunction);
if ((majorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) && (minorFunction == IRP_MN_SCSI_CLASS)) {
dprintf("IRP_MJ_SCSI") ;
} else if (majorFunction<=MAX_NAMED_MAJOR_IRPS) {
dprintf(IrpMajorNames[majorFunction]) ;
} else if (majorFunction==0xFF) {
dprintf("IRP_MJ_BOGUS") ;
} else {
dprintf("IRP_MJ_??") ; }
switch(majorFunction) {
case IRP_MJ_SYSTEM_CONTROL: dprintf(".") ; if (minorFunction<=MAX_NAMED_WMI_IRP) {
dprintf(WmiIrpNames[minorFunction]) ; } else if (minorFunction==0xFF) {
dprintf("IRP_MN_BOGUS") ; } else { dprintf("(??)") ; } break ; case IRP_MJ_PNP: dprintf(".") ; if (minorFunction<=MAX_NAMED_PNP_IRP) {
dprintf(PnPIrpNames[minorFunction]) ; } else if (minorFunction==0xFF) {
dprintf("IRP_MN_BOGUS") ; } else {
dprintf("(??)") ; } switch(minorFunction) { case IRP_MN_QUERY_DEVICE_RELATIONS:
type = (ULONG) ReadField(Parameters.QueryDeviceRelations.Type); switch(type) { case BusRelations: dprintf("(BusRelations)") ; break ; case EjectionRelations: dprintf("(EjectionRelations)") ; break ; case PowerRelations: dprintf("(PowerRelations)") ; break ; case RemovalRelations: dprintf("(RemovalRelations)") ; break ; case TargetDeviceRelation: dprintf("(TargetDeviceRelation)") ; break ; default: dprintf("(??)") ; break ; } break ; case IRP_MN_QUERY_INTERFACE: break ; case IRP_MN_QUERY_DEVICE_TEXT: type = (ULONG) ReadField(Parameters.QueryId.Type);
switch(type) { case DeviceTextDescription: dprintf("(DeviceTextDescription)") ; break ; case DeviceTextLocationInformation: dprintf("(DeviceTextLocationInformation)") ; break ; default: dprintf("(??)") ; break ; } break ; case IRP_MN_WRITE_CONFIG: case IRP_MN_READ_CONFIG: dprintf("(WhichSpace=%x, Buffer=%x, Offset=%x, Length=%x)", ReadField(Parameters.ReadWriteConfig.WhichSpace), ReadField(Parameters.ReadWriteConfig.Buffer), ReadField(Parameters.ReadWriteConfig.Offset), ReadField(Parameters.ReadWriteConfig.Length) ); break; case IRP_MN_SET_LOCK: if (ReadField(Parameters.SetLock.Lock)) dprintf("(True)") ; else dprintf("(False)") ; break ; case IRP_MN_QUERY_ID: type = (ULONG) ReadField(Parameters.QueryId.IdType); switch(type) { case BusQueryDeviceID: dprintf("(BusQueryDeviceID)") ; break ; case BusQueryHardwareIDs: dprintf("(BusQueryHardwareIDs)") ; break ; case BusQueryCompatibleIDs: dprintf("(BusQueryCompatibleIDs)") ; break ; case BusQueryInstanceID: dprintf("(BusQueryInstanceID)") ; break ; default: dprintf("(??)") ; break ; } break ; case IRP_MN_QUERY_BUS_INFORMATION: // BUGBUG: Should print out
break ; case IRP_MN_DEVICE_USAGE_NOTIFICATION: type = (ULONG) ReadField(Parameters.UsageNotification.Type); switch(type) { case DeviceUsageTypeUndefined: dprintf("(DeviceUsageTypeUndefined") ; break ; case DeviceUsageTypePaging: dprintf("(DeviceUsageTypePaging") ; break ; case DeviceUsageTypeHibernation: dprintf("(DeviceUsageTypeHibernation") ; break ; case DeviceUsageTypeDumpFile: dprintf("(DeviceUsageTypeDumpFile") ; break ; default: dprintf("(??)") ; break ; } if (ReadField(Parameters.UsageNotification.InPath)) { dprintf(", InPath=TRUE)") ; } else { dprintf(", InPath=FALSE)") ; } break ; case IRP_MN_QUERY_LEGACY_BUS_INFORMATION: // BUGBUG: Should print out
break ; default: break ; } break ;
case IRP_MJ_POWER: dprintf(".") ; if (minorFunction<=MAX_NAMED_POWER_IRP) {
dprintf(PowerIrpNames[minorFunction]) ; } else if (minorFunction==0xFF) {
dprintf("IRP_MN_BOGUS") ; } else { dprintf("(??)") ; } break ;
default: break ; } }
BOOLEAN GetTheSystemTime ( OUT PLARGE_INTEGER Time ) { BYTE readTime[20]={0}; PCHAR SysTime;
ZeroMemory( Time, sizeof(*Time) );
SysTime = "SystemTime";
if (GetFieldValue(MM_SHARED_USER_DATA_VA, "nt!_KUSER_SHARED_DATA", SysTime, readTime)) { dprintf( "unable to read memory @ %lx or _KUSER_SHARED_DATA not found\n", MM_SHARED_USER_DATA_VA); return FALSE; }
*Time = *(LARGE_INTEGER UNALIGNED *)&readTime[0];
return TRUE; }
|