/*++ 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; iIrpToStopOn != 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; iFlink != 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; iStackCount; 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; }