Debugging Tools for Windows

!irp

!irp扩展显示某个I/O请求包(IRP)的信息。

语法

!irp Address [Detail

参数

Address
指定IRP的16进制地址。

Detail
如果该参数包含了任何值,例如1,则输出重包含IRP的状态、内存描述符表(memory descriptor list (MDL))的地址、拥有者线程、它的所有I/O栈的堆栈信息、以及每个IRP堆栈位置的信息,包括主功能代码(major function code)和次功能代码(minor function code)的16进制数值。如果省略该参数,则只显示摘要信息。

DLL

Windows 2000 Kdextx86.dll
Windows XP和之后 Kdexts.dll

注释

下面这些信息有助于理解该扩展命令输出的内容。

IRP 主功能代码有下面这些:

Major Function Code 16进制代码
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
IRP_MJ_SCSI
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
IRP_MJ_MAXIMUM_FUNCTION
0x1B

即插即用(Plug and Play) 次功能代码有下面这些:

Minor Function Code 16进制代码
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
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

WMI次功能代码有:

Minor Function Code 16进制代码
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

电源管理的次功能代码有:

Minor Function Code 16进制代码
IRP_MN_WAIT_WAKE 0x00
IRP_MN_POWER_SEQUENCE 0x01
IRP_MN_SET_POWER 0x02
IRP_MN_QUERY_POWER 0x03

SCSI 次功能代码有:

Minor Function Code 16进制代码
IRP_MN_SCSI_CLASS 0x01

输出中还指出了当每个stack location当IRP完成或者stack location被处理时,在什么情况下完成例程会被调用。有三种可能的情况:

Success
表示当IRP以成功代码完成时完成例程会被调用。
Error
表示当IRP以错误代码完成时,完成例程会被调用。
Cancel
表示当尝试cancel该IRP时完成里程会被调用。

可能会出现上面三个的任何组合形式,只要满足其中一种条件,那么完成例程都会被调用。适当的值会在每个stack location信息的第一行末尾列出,紧跟Completion-Context之后。

下面是该扩展命令在Windows XP上的输出示例:

!irp 81183468
Irp is active with 2 stacks 2 is current (= 0x811834fc)
 No Mdl Thread 00000000: Irp stack trace.
     Cmd  flg cl Device   File     Completion-Context
 [  0, 0]   0  0 8145f470 00000000 00000000-00000000
                \Driver\E100B
                        Args: 00000000 00000000 00000000 00000000
 [ 16, 2]   0 e1 8145f470 00000000 8047f744-814187a8 Success Error Cancel pending
                \Driver\E100B    ntoskrnl!PopCompleteSystemPowerIrp
                        Args: 00000000 00000000 00000002 00000002

在Windows XP示例的第二个stack location处, 主功能代码是16,说明该IRP是发送给power stack的。次功能代码是2,所以power stack知道它是一个set 请求。该IRP被pending,并且当它完成时,不管指定的返回值是Success还是Error,ntoskrnl!PopCompleteSystemPowerIrp都会被调用。

下面是该扩展命令在Windows Vista上的输出示例:

0: kd> !irp 0x831f4a00
Irp is active with 8 stacks 5 is current (= 0x831f4b00)
 Mdl = 82b020d8 Thread 8c622118:  Irp stack trace.
     cmd  flg cl Device   File     Completion-Context
 [  0, 0]   0  0 00000000 00000000 00000000-00000000

                        Args: 00000000 00000000 00000000 00000000
 [  0, 0]   0  0 00000000 00000000 00000000-00000000

                        Args: 00000000 00000000 00000000 00000000
 [  0, 0]   0  0 00000000 00000000 00000000-00000000

                        Args: 00000000 00000000 00000000 00000000
 [  0, 0]   0  0 00000000 00000000 00000000-00000000

                        Args: 00000000 00000000 00000000 00000000
>[  3,34]  40 e1 828517a8 00000000 842511e0-00000000 Success Error Cancel pending
               \Driver\disk     partmgr!PmReadWriteCompletion
                        Args: 00007000 00000000 fe084e00 00000004
 [  3, 0]  40 e0 82851450 00000000 842414d4-82956350 Success Error Cancel
               \Driver\PartMgr  volmgr!VmpReadWriteCompletionRoutine
                        Args: 129131bb 000000de fe084e00 00000004
 [  3, 0]   0 e0 82956298 00000000 847eeed0-829e2ba8 Success Error Cancel
               \Driver\volmgr   Ntfs!NtfsMasterIrpSyncCompletionRoutine
                        Args: 00007000 00000000 1bdae400 00000000
 [  3, 0]   0  0 82ac2020 8e879410 00000000-00000000
               \FileSystem\Ntfs
                        Args: 00007000 00000000 00018400 00000000

注意驱动名边上的完成例程是设置在该stack location上的,并且它是被下一行的驱动设置的。上面的例子中, Ntfs!NtfsMasterIrpSyncCompletionRoutine是由\FileSystem\Ntfs设置的。 Ntfs!NtfsMasterIrpSyncCompletionRoutine上面的Completion-Context为 847eeed0-829e2ba8,指示了该完成例程的地址以及将会传递给Ntfs!NtfsMasterIrpSyncCompletionRoutine的context。从这里我们可以知道Ntfs!NtfsMasterIrpSyncCompletionRoutine的地址是847eeed0,将会被传递给它的context为 829e2ba8

附加信息

查看Plug and Play调试以及调试Interrupt Storms获得该扩展命令的应用。关于IRP的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。关于主功能代码和次功能代码的更多信息,查看Windows Driver Kit (WDK)文档。

Build machine: CAPEBUILD