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

1215 lines
34 KiB
C

/*++
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;
}