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

1060 lines
30 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
irp.c
Abstract:
WinDbg Extension Api
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
//#include "irpverif.h"
#pragma hdrstop
typedef
BOOLEAN
(WINAPI *IRP_FILTER_ROUTINE)(
ULONG64 Irp,
PVOID FilterContext
);
typedef struct _IRP_FILTER {
IRP_FILTER_ROUTINE FilterRoutine;
PVOID FilterContext;
} IRP_FILTER, *PIRP_FILTER;
typedef struct _SEARCH_CONTEXT {
ULONG FirstTime;
IRP_FILTER Filter;
} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
#define TAG 0
#define NONPAGED_ALLOC 1
#define NONPAGED_FREE 2
#define PAGED_ALLOC 3
#define PAGED_FREE 4
#define NONPAGED_USED 5
#define PAGED_USED 6
VOID
DumpIrp(
ULONG64 IrpToDump,
ULONG DumpLevel
);
BOOLEAN
IrpFilterUserEvent(
ULONG64 Irp,
PVOID FilterContext
);
BOOLEAN
IrpFilterDevice(
ULONG64 Irp,
PVOID FilterContext
);
BOOLEAN
IrpFilterFileObject(
ULONG64 Irp,
PVOID FilterContext
);
BOOLEAN
IrpFilterThread(
ULONG64 Irp,
PVOID FilterContext
);
BOOLEAN
IrpFilterMdlProcess(
ULONG64 Irp,
PVOID FilterContext
);
BOOLEAN
IrpFilterArg(
ULONG64 Irp,
PVOID FilterContext
);
DECLARE_API( irp )
/*++
Routine Description:
Dumps the specified Irp
Arguments:
args - Address
Return Value:
None
--*/
{
ULONG64 irpToDump;
ULONG dumpLevel = 0 ;
char irpExprBuf[256] ;
char dumpLevelBuf[256] ;
if (!*args) {
irpToDump = EXPRLastDump;
} else {
//
// !Irp IrpAddress DumpLevel
// where IrpAddress can be an expression
// and DumpLevel is a decimal level of any non-decimal string for 1
irpExprBuf[0] = '\0' ;
dumpLevelBuf[0] = '\0' ;
if (!sscanf(args, "%s %s", irpExprBuf, dumpLevelBuf)) {
irpExprBuf[0] = '\0' ;
dumpLevelBuf[0] = '\0' ;
}
if (irpExprBuf) {
if (IsHexNumber(irpExprBuf)) {
irpToDump = GetExpression( irpExprBuf ) ;
} else {
irpToDump = GetExpression( irpExprBuf ) ;
if (irpToDump==0) {
dprintf("An error occured trying to evaluate the expression\n") ;
return E_INVALIDARG ;
}
}
if (IsDecNumber(dumpLevelBuf)) {
if (!sscanf(dumpLevelBuf, "%d", &dumpLevel) ) {
dumpLevel = 0;
}
} else if (dumpLevelBuf[0]) {
dumpLevel = 1 ;
} else {
dumpLevel = 0 ;
}
}
}
if (irpToDump == 0) {
dprintf("Free build - use !irpfind to scan memory for any active IRPs\n") ;
} else {
DumpIrp(irpToDump, (ULONG) dumpLevel);
}
return S_OK;
}
DECLARE_API( irpzone )
/*++
Routine Description:
Dumps both the small irp zone and the large irp zone. Only irps that
are currently allocated are dumped. "args" controls the type of dump.
If "args" is present then the Irp is sent to the DumpIrp routine to be
disected. Otherwise, only the irp, its thread and the driver holding the
irp (i.e. the driver of the last stack) is printed.
Arguments:
args - a string pointer. If anything is in the string it indicates full
information (i.e. call DumpIrp).
Return Value:
None.
--*/
{
ULONG listAddress;
BOOLEAN fullOutput = FALSE;
dprintf("irpzone is no longer supported. Use irpfind to search " \
"nonpaged pool for active Irps\n");
return S_OK;
}
VOID
DumpIrp(
ULONG64 IrpToDump,
ULONG DumpLevel
)
/*++
Routine Description:
This routine dumps an Irp. It does not check to see that the address
supplied actually locates an Irp. This is done to allow for dumping
Irps post mortem, or after they have been freed or completed.
Arguments:
IrpToDump - the address of the irp.
DumpLevel - 0 Summary
1 Extended information
2 Debug tracking info iff available
Return Value:
None
--*/
{
PCHAR buffer;
ULONG64 irpStackAddress;
ULONG64 result64=0;
ULONG result;
// IRP irp;
CCHAR irpStackIndex;
LARGE_INTEGER runTime ;
#if DBG
// PIOV_REQUEST_PACKET irpTrackingData ;
#endif
BOOLEAN delayed ;
ULONG Type=0, StackCount=0, CurrentLocation=0, Flags=0, PendingReturned=0;
ULONG Io_Status=0, Cancel=0, CancelIrql=0, ApcEnvironment=0, Overlay_Alloc_High=0;
ULONG Overlay_Alloc_Low=0, RequestorMode=0, IrpSize;
ULONG64 Tail_Overlay_CurrStack=0, MdlAddress=0, Associated_MasterIrp=0;
ULONG64 ThreadListEntry_Flink=0, ThreadListEntry_Blink=0, Io_Information=0;
ULONG64 CancelRoutine=0, UserIosb=0, UserEvent=0, UserBuffer=0, Overlay_Async_UserApcRoutine=0;
ULONG64 Overlay_Async_UserApcContext=0, Tail_Overlay_Thread=0, Tail_Overlay_AuxBuffer=0;
ULONG64 Tail_Overlay_List_Flink=0, Tail_Overlay_List_Blink=0, Tail_Overlay_OrigFile=0;
ULONG64 Tail_CompletionKey=0;
BYTE Tail_Apc[100]={0};
UCHAR IrpType[]= "nt!_IRP";
if ( (GetFieldValue(IrpToDump, IrpType, "Type", Type)) ) {
dprintf("%08p: Could not read Irp\n", IrpToDump);
return;
}
GetFieldValue(IrpToDump, IrpType, "StackCount", StackCount);
GetFieldValue(IrpToDump, IrpType, "CurrentLocation", CurrentLocation);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.CurrentStackLocation", Tail_Overlay_CurrStack);
GetFieldValue(IrpToDump, IrpType, "MdlAddress", MdlAddress);
GetFieldValue(IrpToDump, IrpType, "AssociatedIrp.MasterIrp", Associated_MasterIrp);
GetFieldValue(IrpToDump, IrpType, "Flags", Flags);
GetFieldValue(IrpToDump, IrpType, "RequestorMode", RequestorMode);
GetFieldValue(IrpToDump, IrpType, "PendingReturned", PendingReturned);
GetFieldValue(IrpToDump, IrpType, "ThreadListEntry.Flink", ThreadListEntry_Flink);
GetFieldValue(IrpToDump, IrpType, "ThreadListEntry.Blink", ThreadListEntry_Blink);
GetFieldValue(IrpToDump, IrpType, "IoStatus.Status", Io_Status);
GetFieldValue(IrpToDump, IrpType, "IoStatus.Information", Io_Information);
GetFieldValue(IrpToDump, IrpType, "Cancel", Cancel);
GetFieldValue(IrpToDump, IrpType, "CancelIrql", CancelIrql);
GetFieldValue(IrpToDump, IrpType, "CancelRoutine", CancelRoutine);
GetFieldValue(IrpToDump, IrpType, "ApcEnvironment", ApcEnvironment);
GetFieldValue(IrpToDump, IrpType, "UserIosb", UserIosb);
GetFieldValue(IrpToDump, IrpType, "UserEvent", UserEvent);
GetFieldValue(IrpToDump, IrpType, "UserBuffer", UserBuffer);
GetFieldValue(IrpToDump, IrpType, "Overlay.AsynchronousParameters.UserApcRoutine", Overlay_Async_UserApcRoutine);
GetFieldValue(IrpToDump, IrpType, "Overlay.AsynchronousParameters.UserApcContext", Overlay_Async_UserApcContext);
GetFieldValue(IrpToDump, IrpType, "Overlay.AllocationSize.High", Overlay_Alloc_High);
GetFieldValue(IrpToDump, IrpType, "Overlay.AllocationSize.Low", Overlay_Alloc_Low);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.Thread", Tail_Overlay_Thread);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.AuxiliaryBuffer", Tail_Overlay_AuxBuffer);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.ListEntry.Flink", Tail_Overlay_List_Flink);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.ListEntry.Blink", Tail_Overlay_List_Blink);
GetFieldValue(IrpToDump, IrpType, "Tail.Overlay.OriginalFileObject", Tail_Overlay_OrigFile);
GetFieldValue(IrpToDump, IrpType, "Tail.Apc", Tail_Apc);
GetFieldValue(IrpToDump, IrpType, "Tail.CompletionKey", Tail_CompletionKey);
IrpSize = GetTypeSize("nt!_IRP");
if (Type != IO_TYPE_IRP) {
dprintf("IRP signature does not match, probably not an IRP\n");
return;
}
dprintf("Irp is active with %d stacks %d is current (= %#08p)\n",
StackCount,
CurrentLocation,
Tail_Overlay_CurrStack);
if ((MdlAddress != 0) && (Type == IO_TYPE_IRP)) {
dprintf(" Mdl = %08p ", MdlAddress);
} else {
dprintf(" No Mdl ");
}
if (Associated_MasterIrp != 0) {
dprintf("%s = %08p ",
(Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
(Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
"Irp count",
Associated_MasterIrp);
}
dprintf("Thread %08p: ", Tail_Overlay_Thread);
if (StackCount > 30) {
dprintf("Too many Irp stacks to be believed (>30)!!\n");
return;
} else {
if (CurrentLocation > StackCount) {
dprintf("Irp is completed. ");
} else {
dprintf("Irp stack trace. ");
}
}
if (PendingReturned) {
dprintf("Pending has been returned\n");
} else {
dprintf("\n");
}
if (DumpLevel>0) {
dprintf("Flags = %08lx\n", Flags);
dprintf("ThreadListEntry.Flink = %08p\n", ThreadListEntry_Flink);
dprintf("ThreadListEntry.Blink = %08p\n", ThreadListEntry_Blink);
dprintf("IoStatus.Status = %08lx\n", Io_Status);
dprintf("IoStatus.Information = %08p\n", Io_Information);
dprintf("RequestorMode = %08lx\n", RequestorMode);
dprintf("Cancel = %02lx\n", Cancel);
dprintf("CancelIrql = %lx\n", CancelIrql);
dprintf("ApcEnvironment = %02lx\n", ApcEnvironment);
dprintf("UserIosb = %08p\n", UserIosb);
dprintf("UserEvent = %08p\n", UserEvent);
dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08p\n", Overlay_Async_UserApcRoutine);
dprintf("Overlay.AsynchronousParameters.UserApcContext = %08p\n", Overlay_Async_UserApcContext);
dprintf(
"Overlay.AllocationSize = %08lx - %08lx\n",
Overlay_Alloc_High,
Overlay_Alloc_Low);
dprintf("CancelRoutine = %08p\n", CancelRoutine);
dprintf("UserBuffer = %08p\n", UserBuffer);
dprintf("&Tail.Overlay.DeviceQueueEntry = %08p\n", 0);// &Tail_Overlay_DeviceQueueEntry);
dprintf("Tail.Overlay.Thread = %08p\n", Tail_Overlay_Thread);
dprintf("Tail.Overlay.AuxiliaryBuffer = %08p\n", Tail_Overlay_AuxBuffer);
dprintf("Tail.Overlay.ListEntry.Flink = %08p\n", Tail_Overlay_List_Flink);
dprintf("Tail.Overlay.ListEntry.Blink = %08p\n", Tail_Overlay_List_Blink);
dprintf("Tail.Overlay.CurrentStackLocation = %08p\n", Tail_Overlay_CurrStack);
dprintf("Tail.Overlay.OriginalFileObject = %08p\n", Tail_Overlay_OrigFile);
dprintf("Tail.Apc = %08lx\n", *((PULONG) &Tail_Apc));
dprintf("Tail.CompletionKey = %08p\n", Tail_CompletionKey);
}
irpStackAddress = (ULONG64) IrpToDump + GetTypeSize("nt!_IRP");
buffer = LocalAlloc(LPTR, 256);
if (buffer == NULL) {
dprintf("Can't allocate 256 bytes\n");
return;
}
dprintf(" cmd flg cl Device File Completion-Context\n");
for (irpStackIndex = 1; (ULONG) irpStackIndex <= StackCount; irpStackIndex++) {
ULONG MajorFunction=0, MinorFunction=0, Flags=0, Control=0, irpStackSize;
ULONG64 DeviceObject=0, FileObject=0, CompletionRoutine=0, Context=0;
ULONG64 Others_Argument1=0, Others_Argument2=0, Others_Argument3=0, Others_Argument4=0;
UCHAR IOStack[] = "nt!_IO_STACK_LOCATION";
if ( GetFieldValue(irpStackAddress, IOStack, "MajorFunction", MajorFunction)) {
dprintf("%p: Could not read IrpStack\n", irpStackAddress);
goto exit;
}
irpStackSize = GetTypeSize(IOStack);
GetFieldValue(irpStackAddress, IOStack, "MinorFunction", MinorFunction);
GetFieldValue(irpStackAddress, IOStack, "Flags", Flags);
GetFieldValue(irpStackAddress, IOStack, "DeviceObject", DeviceObject);
GetFieldValue(irpStackAddress, IOStack, "FileObject", FileObject);
GetFieldValue(irpStackAddress, IOStack, "CompletionRoutine", CompletionRoutine);
GetFieldValue(irpStackAddress, IOStack, "Context", Context);
GetFieldValue(irpStackAddress, IOStack, "Control", Control);
GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument1",Others_Argument1);
GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument2",Others_Argument2);
GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument3",Others_Argument3);
GetFieldValue(irpStackAddress, IOStack, "Parameters.Others.Argument4",Others_Argument4);
dprintf("%c[%3x,%2x] %2x %2x %08p %08p %08p-%08p %s %s %s %s\n",
(ULONG) irpStackIndex == CurrentLocation ? '>' : ' ',
MajorFunction,
MinorFunction,
Flags,
Control,
DeviceObject,
FileObject,
CompletionRoutine,
Context,
(Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
(Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
(Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
(Control & SL_PENDING_RETURNED) ? "pending" : "");
if (DeviceObject != 0) {
dprintf("\t ");
DumpDevice(DeviceObject, 0, FALSE);
}
if (CompletionRoutine != 0) {
GetSymbol(CompletionRoutine, buffer, &result64);
dprintf("\t%s\n", buffer);
} else {
dprintf("\n");
}
dprintf("\t\t\tArgs: %08p %08p %08p %08p\n",
Others_Argument1,
Others_Argument2,
Others_Argument3,
Others_Argument4);
irpStackAddress += irpStackSize;
if (CheckControlC()) {
goto exit;
}
}
if (DumpLevel>=2) {
dprintf("Extra information not available.\n") ;
}
exit:
LocalFree(buffer);
}
//+---------------------------------------------------------------------------
//
// Function: CheckForIrp
//
// Synopsis: Matches pool chunk against an irp
//
// Arguments: [Tag] --
// [Filter] --
// [Flags] -- 0 nonpaged pool 1 paged pool 2 special pool 4 dump irp
// [PoolTrackTable] --
// [PoolHeader] --
// [BlockSize] --
// [Data] --
//
// Returns:
//
// History: 7-28-1999 benl Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOLEAN WINAPI CheckForIrp(
PCHAR Tag,
PCHAR Filter,
ULONG Flags,
ULONG64 PoolHeader,
ULONG BlockSize,
ULONG64 Data,
PVOID Context
)
{
ULONG64 Irp = Data;
ULONG Result;
ULONG64 irpSp;
// MDL Mdl;
PSEARCH_CONTEXT SearchContext = (PSEARCH_CONTEXT)Context;
ULONG PoolType, SizeOfIRP;
// dprintf("Call Hdr %p, Data %p \n", PoolHeader, Data);
if (PoolHeader) {
if (GetFieldValue(PoolHeader, "nt!_POOL_HEADER", "PoolType", PoolType)) {
dprintf("Unable to read nt!_POOL_HEADER type.\n");
}
}
if (((PoolHeader == 0) ||
(Flags & 0x2) ||
(PoolType != 0)) &&
(CheckSingleFilter (Tag, Filter))) {
ULONG Type=0, CurrentLocation, StackCount, MajorFunction, MinorFunction;
ULONG64 Thread, DeviceObject, MdlAddress;
if (!GetFieldValue(Irp, "nt!_IRP", "Type", Type)) {
if (Type == IO_TYPE_IRP) {
SizeOfIRP = GetTypeSize("nt!_IRP");
if (Flags & 0x4) {
if (SearchContext->FirstTime) {
dprintf(" Irp [ Thread ] irpStack: (Mj,Mn) DevObj [Driver]\n");
SearchContext->FirstTime = FALSE;
}
dprintf("%08p: ", Data);
DumpIrp(Data, 0);
dprintf("\n");
} else {
if ((SearchContext->Filter.FilterRoutine == NULL) ||
(SearchContext->Filter.FilterRoutine(Irp, SearchContext->Filter.FilterContext))) {
if (SearchContext->FirstTime) {
dprintf(" Irp [ Thread ] irpStack: (Mj,Mn) DevObj [Driver]\n");
SearchContext->FirstTime = FALSE;
}
GetFieldValue(Irp, "nt!_IRP", "CurrentLocation", CurrentLocation);
GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount);
GetFieldValue(Irp, "nt!_IRP", "MdlAddress", MdlAddress);
GetFieldValue(Irp, "nt!_IRP", "Tail.Overlay.Thread",
Thread);
irpSp = Irp + SizeOfIRP +
(CurrentLocation - 1)*GetTypeSize("nt!_IO_STACK_LOCATION");
dprintf("%08p [%08p] ", Data, Thread);
if (CurrentLocation > StackCount) {
dprintf("Irp is complete (CurrentLocation "
"%d > StackCount %d)",
CurrentLocation,
StackCount);
} else {
GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "MajorFunction", MajorFunction);
GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "MinorFunction", MinorFunction);
GetFieldValue(irpSp, "nt!_IO_STACK_LOCATION", "DeviceObject", DeviceObject);
dprintf("irpStack: (%2x,%2x)",
MajorFunction,
MinorFunction);
dprintf(" %08p [", DeviceObject);
DumpDevice(DeviceObject, 0, FALSE);
dprintf("]");
}
if (MdlAddress) {
ULONG64 Process;
if (!GetFieldValue(MdlAddress,
"nt!_MDL",
"Process",
Process)) {
dprintf( " 0x%p", Process );
}
}
dprintf("\n");
}
}
} else {
// dprintf("%08lx (size %04lx) uninitialized or overwritten IRP\n",
// irpAddress,
// PoolBlock.Header.BlockSize << POOL_BLOCK_SHIFT);
}
} else {
dprintf("Possible IRP @ %p - unable to read addr/type\n", Data );
}
return TRUE;
} else {
#ifdef SHOW_PROGRESS
dprintf("%c", turnTable[turn]);
turn = (turn + 1) % 4;
#endif
}
return FALSE;
} // CheckForIrp
DECLARE_API(irpfind)
/*++
Routine Description:
finds Irps in non-paged pool
Arguments:
args -
Return Value:
None
--*/
{
ULONG Flags = 0;
ULONG64 RestartAddr = 0;
ULONG TagName;
UCHAR Field[20];
ULONG64 Match=0;
SEARCH_CONTEXT Context;
Context.FirstTime = TRUE;
Context.Filter.FilterRoutine = NULL;
Field[0] = '\0';
if (args) {
PCHAR pc;
ULONG64 tmp;
if (GetExpressionEx(args, &tmp, &args)) {
Flags = (ULONG) tmp;
if (GetExpressionEx(args, &RestartAddr, &args)) {
if (!sscanf(args, "%19s %x", &Field, &Match)) {
Match = 0;
}
}
}
}
//
// Sign extend the address if necc.
//
if (RestartAddr != 0) {
if (RestartAddr >= 0x80000000 && RestartAddr <= 0xFFFFFFFF) {
RestartAddr += 0xFFFFFFFF00000000;
}
}
if ((_stricmp(Field, "userevent") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterUserEvent;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRP with UserEvent == %08p\n",Match);
} else if ((_stricmp(Field, "device") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterDevice;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRPs with device object == %08p\n",Match);
} else if ((_stricmp(Field, "fileobject") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterFileObject;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRPs with file object == %08p\n",Match);
} else if ((_stricmp(Field, "mdlprocess") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterMdlProcess;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRPs with mdl process == %08p\n",Match);
} else if ((_stricmp(Field, "thread") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterThread;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRPs with thread == %08p\n",Match);
} else if ((_stricmp(Field, "arg") == 0) &&
(Match != 0)) {
Context.Filter.FilterRoutine = IrpFilterArg;
Context.Filter.FilterContext = (PVOID)&Match;
dprintf("Looking for IRPs with arg == %08p\n",Match);
}
TagName = '?prI';
SearchPool( TagName, Flags, RestartAddr, &CheckForIrp, &Context );
return S_OK;
}
BOOLEAN
IrpFilterUserEvent(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the userevent field of an IRP matches the supplied
parameter
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the user event
Return Value:
TRUE if the specified irp has userevent == FilterContext
FALSE otherwise
--*/
{
ULONG64 pEvent = *((PULONG64) FilterContext);
ULONG64 UserEvent;
if (GetFieldValue(Irp, "nt!_IRP", "UserEvent", UserEvent)) {
return FALSE;
}
if (UserEvent == pEvent) {
return(TRUE);
} else {
return(FALSE);
}
}
BOOLEAN
IrpFilterDevice(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the specified IRP matches the supplied
device object
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the device object
Return Value:
TRUE if the specified irp has a device == FilterContext
FALSE otherwise
--*/
{
ULONG64 IrpStack = (Irp+GetTypeSize("nt!_IRP"));
ULONG StackCount, Stksize;
ULONG64 DeviceObject;
ULONG i;
if (GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount)) {
return FALSE;
}
if (StackCount > 30) {
return(FALSE);
}
Stksize = GetTypeSize("nt!_IO_STACK_LOCATION");
for (i=0; i<StackCount; i++) {
if (!GetFieldValue(Irp + i*Stksize,
"nt!_IO_STACK_LOCATION",
"DeviceObject",
DeviceObject)) {
if (DeviceObject == *((PULONG64) FilterContext)) {
return(TRUE);
}
}
}
return(FALSE);
}
BOOLEAN
IrpFilterFileObject(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
supplied parameter
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the file object
Return Value:
TRUE if the specified irp has userevent == FilterContext
FALSE otherwise
--*/
{
ULONG64 pFile = *((PULONG64) FilterContext);
ULONG64 OriginalFileObject;
if (GetFieldValue(Irp, "nt!_IRP",
"Tail.Overlay.OriginalFileObject",
OriginalFileObject)) {
return FALSE;
}
if (OriginalFileObject == pFile) {
return(TRUE);
} else {
return(FALSE);
}
}
BOOLEAN
IrpFilterThread(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
supplied parameter
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the file object
Return Value:
TRUE if the specified irp has userevent == FilterContext
FALSE otherwise
--*/
{
ULONG64 pThread = *((PULONG64) FilterContext);
ULONG64 Thread;
if (GetFieldValue(Irp, "nt!_IRP",
"Tail.Overlay.Thread",
Thread)) {
return FALSE;
}
if (Thread == pThread) {
return(TRUE);
} else {
return(FALSE);
}
}
BOOLEAN
IrpFilterMdlProcess(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the Tail.Overlay.OriginalFileObject field of an IRP matches the
supplied parameter
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the file object
Return Value:
TRUE if the specified irp has userevent == FilterContext
FALSE otherwise
--*/
{
ULONG64 pProcess = *((PULONG64) FilterContext);
ULONG64 Process, MdlAddress;
if (GetFieldValue(Irp, "nt!_IRP",
"MdlAddress",
MdlAddress)) {
return FALSE;
}
if (MdlAddress == 0) {
return(FALSE);
}
if (GetFieldValue(MdlAddress, "nt!_MDL", "Process", Process)) {
return FALSE;
}
if (Process == pProcess) {
return(TRUE);
} else {
return(FALSE);
}
}
BOOLEAN
IrpFilterArg(
IN ULONG64 Irp,
IN PVOID FilterContext
)
/*++
Routine Description:
Checks to see if the specified IRP matches the supplied
argument
Arguments:
Irp - Supplies the irp to filter
FilterContext - supplies the argument to match
Return Value:
TRUE if the specified irp has argument == FilterContext
FALSE otherwise
--*/
{
ULONG64 IrpStack = (Irp+GetTypeSize("nt!_IRP"));
ULONG StackCount, Stksize;
ULONG i;
if (GetFieldValue(Irp, "nt!_IRP", "StackCount", StackCount)) {
return FALSE;
}
Stksize = GetTypeSize("nt!_IO_STACK_LOCATION");
if (!Stksize || (StackCount > 30)) {
return(FALSE);
}
for (i=0; i<StackCount; i++) {
ULONG64 Argument1,Argument2,Argument3,Argument4;
GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
"Parameters.Others.Argument1",Argument1);
GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
"Parameters.Others.Argument2",Argument2);
GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
"Parameters.Others.Argument3",Argument3);
GetFieldValue(Irp + i*Stksize, "nt!_IO_STACK_LOCATION",
"Parameters.Others.Argument4",Argument4);
if ((Argument1 == *((PULONG64)FilterContext)) ||
(Argument2 == *((PULONG64)FilterContext)) ||
(Argument3 == *((PULONG64)FilterContext)) ||
(Argument4 == *((PULONG64)FilterContext))) {
return(TRUE);
}
}
return(FALSE);
}
HRESULT
GetIrpInfo(
ULONG64 Irp,
PDEBUG_IRP_INFO pIrp
)
{
ULONG Type;
UCHAR TypeName[]= "nt!_IRP";
ULONG irpStackIndex;
ULONG64 irpStackAddress;
ZeroMemory(pIrp, sizeof(DEBUG_IRP_INFO));
pIrp->SizeOfStruct = sizeof(DEBUG_IRP_INFO);
pIrp->IrpAddress = Irp;
if ( (GetFieldValue(Irp, TypeName, "Type", Type)) ) {
//dprintf("%08p: Could not read Irp\n", IrpToDump);
return E_INVALIDARG;
}
if (Type != IO_TYPE_IRP) {
return E_INVALIDARG;
}
GetFieldValue(Irp, TypeName, "StackCount", pIrp->StackCount);
GetFieldValue(Irp, TypeName, "CurrentLocation", pIrp->CurrentLocation);
GetFieldValue(Irp, TypeName, "MdlAddress", pIrp->MdlAddress);
GetFieldValue(Irp, TypeName, "CancelRoutine", pIrp->CancelRoutine);
GetFieldValue(Irp, TypeName, "Tail.Overlay.Thread", pIrp->Thread);
for (irpStackIndex = pIrp->StackCount,
irpStackAddress = Irp + GetTypeSize("nt!_IRP") + (pIrp->StackCount - 1)* GetTypeSize("nt!_IO_STACK_LOCATION");
irpStackIndex >= 1;
irpStackIndex++, irpStackAddress -= GetTypeSize("nt!_IO_STACK_LOCATION")) {
if ( InitTypeRead(irpStackAddress, nt!_IO_STACK_LOCATION)) {
return E_INVALIDARG;
}
pIrp->CurrentStack.DeviceObject = ReadField(DeviceObject);
if (!pIrp->CurrentStack.DeviceObject) {
// To be implemented later, we are only interested in current one now
continue;
}
pIrp->CurrentStack.StackAddress = irpStackAddress;
pIrp->CurrentStack.CompletionRoutine = ReadField(CompletionRoutine);
pIrp->CurrentStack.FileObject = ReadField(FileObject);
pIrp->CurrentStack.Major = (UCHAR) ReadField(MajorFunction);
pIrp->CurrentStack.Minor = (UCHAR) ReadField(MinorFunction);
break;
}
return S_OK;
}
EXTENSION_API( GetIrpInfo )(
PDEBUG_CLIENT Client,
ULONG64 Irp,
PDEBUG_IRP_INFO pIrp
)
{
HRESULT Hr = E_FAIL;
INIT_API();
if (pIrp && (pIrp->SizeOfStruct == sizeof(DEBUG_IRP_INFO))) {
Hr = GetIrpInfo(Irp, pIrp);
}
EXIT_API();
return Hr;
}