Reading Notebook: 03-August-10
Comments in italics are mine and express my own views, thoughts and opinions
Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:
Scatter/gather (p. 566) - you can find examples of scatter/gather I/O residues left on a thread raw stack in Hardware Activity pattern and corresponding case study:
http://www.dumpanalysis.org/blog/index.php/2010/05/08/crash-dump-analysis-patterns-part-98/
and
IRP (pp. 566 - 567) - here is an expanded IRP structure from x64 W2K8:
0: kd> dt -r1 _IRP
ntdll!_IRP
+0x000 Type : Int2B
+0x002 Size : Uint2B
+0x008 MdlAddress : Ptr64 _MDL
+0x000 Next : Ptr64 _MDL
+0x008 Size : Int2B
+0x00a MdlFlags : Int2B
+0x010 Process : Ptr64 _EPROCESS
+0x018 MappedSystemVa : Ptr64 Void
+0x020 StartVa : Ptr64 Void
+0x028 ByteCount : Uint4B
+0x02c ByteOffset : Uint4B
+0x010 Flags : Uint4B
+0x018 AssociatedIrp : <unnamed-tag>
+0x000 MasterIrp : Ptr64 _IRP
+0x000 IrpCount : Int4B
+0x000 SystemBuffer : Ptr64 Void
+0x020 ThreadListEntry : _LIST_ENTRY
+0x000 Flink : Ptr64 _LIST_ENTRY
+0x008 Blink : Ptr64 _LIST_ENTRY
+0x030 IoStatus : _IO_STATUS_BLOCK
+0x000 Status : Int4B
+0x000 Pointer : Ptr64 Void
+0x008 Information : Uint8B
+0x040 RequestorMode : Char
+0x041 PendingReturned : UChar
+0x042 StackCount : Char
+0x043 CurrentLocation : Char
+0x044 Cancel : UChar
+0x045 CancelIrql : UChar
+0x046 ApcEnvironment : Char
+0x047 AllocationFlags : UChar
+0x048 UserIosb : Ptr64 _IO_STATUS_BLOCK
+0x000 Status : Int4B
+0x000 Pointer : Ptr64 Void
+0x008 Information : Uint8B
+0x050 UserEvent : Ptr64 _KEVENT
+0x000 Header : _DISPATCHER_HEADER
+0x058 Overlay : <unnamed-tag>
+0x000 AsynchronousParameters : <unnamed-tag>
+0x000 AllocationSize : _LARGE_INTEGER
+0x068 CancelRoutine : Ptr64 void
+0x070 UserBuffer : Ptr64 Void
+0x078 Tail : <unnamed-tag>
+0x000 Overlay : <unnamed-tag>
+0x000 Apc : _KAPC
+0x000 CompletionKey : Ptr64 Void
IRP stack locations (pp. 568 - 569) - here is a corresponding structure from x64 W2K8:
0: kd> dt _IO_STACK_LOCATION
ntdll!_IO_STACK_LOCATION
+0x000 MajorFunction : UChar
+0x001 MinorFunction : UChar
+0x002 Flags : UChar
+0x003 Control : UChar
+0x008 Parameters : <unnamed-tag>
+0x028 DeviceObject : Ptr64 _DEVICE_OBJECT
+0x030 FileObject : Ptr64 _FILE_OBJECT
+0x038 CompletionRoutine : Ptr64 long
+0x040 Context : Ptr64 Void
Buffered I/O (p. 570) - this part of IRP references a buffer (user input data is copied there and device output is copied there):
+0x018 AssociatedIrp : <unnamed-tag>
+0x000 MasterIrp : Ptr64 _IRP
+0x000 IrpCount : Int4B
+0×000 SystemBuffer : Ptr64 Void
These parts of I/O stack location structure handle buffer lengths:
+0x000 DeviceIoControl : <unnamed-tag>
+0×000 OutputBufferLength : Uint4B
+0×008 InputBufferLength : Uint4B
+0×010 IoControlCode : Uint4B
+0×018 Type3InputBuffer : Ptr64 Void
+0x000 Read : <unnamed-tag>
+0×000 Length : Uint4B
+0×008 Key : Uint4B
+0×010 ByteOffset : _LARGE_INTEGER
+0x000 Write : <unnamed-tag>
+0×000 Length : Uint4B
+0×008 Key : Uint4B
+0×010 ByteOffset : _LARGE_INTEGER
Direct I/O (p. 570) - these parts of IRP handle IOCTL input data (SystemBuffer, via buffering) and IOCTL output/Read/Write data (MdlAddress):
+0x008 MdlAddress : Ptr64 _MDL
+0x000 Next : Ptr64 _MDL
+0x008 Size : Int2B
+0x00a MdlFlags : Int2B
+0x010 Process : Ptr64 _EPROCESS
+0x018 MappedSystemVa : Ptr64 Void
+0x020 StartVa : Ptr64 Void
+0x028 ByteCount : Uint4B
+0x02c ByteOffset : Uint4B
+0x018 AssociatedIrp : <unnamed-tag>
+0x000 MasterIrp : Ptr64 _IRP
+0x000 IrpCount : Int4B
+0x000 SystemBuffer : Ptr64 Void
Neither I/O (p. 571) - these parts handle input data (IO_STACK_LOCATION.Parameters.DeviceIoControl.Type3InputBuffer) and output data (IRP.UserBuffer):
+0x000 DeviceIoControl : <unnamed-tag>
+0x000 OutputBufferLength : Uint4B
+0x008 InputBufferLength : Uint4B
+0x010 IoControlCode : Uint4B
+0×018 Type3InputBuffer : Ptr64 Void
+0×070 UserBuffer : Ptr64 Void
I/O status block and kernel APC (pp. 575 - 577) - this is a part of IRP structure:
+0x030 IoStatus : _IO_STATUS_BLOCK
+0x000 Status : Int4B
+0x000 Pointer : Ptr64 Void
+0x008 Information : Uint8B
KeSynchronizeExecution (p. 578) - here is a stack trace fragment showing it in action:
[...]
b9ada518 8088d661 SCSIPORT!SpStartIoSynchronized+0x14f
b9ada550 80a60147 nt!KeSynchronizeExecution+0×21
b9ada57c f72523a6 hal!HalBuildScatterGatherList+0×1c7
b9ada5c8 8081cfa2 SCSIPORT!ScsiPortStartIo+0×36a
b9ada5ec f725262f nt!IoStartPacket+0×82
b9ada620 f7252146 SCSIPORT!ScsiPortFdoDispatch+0×270
b9ada63c f7251dc3 SCSIPORT!SpDispatchRequest+0×68
b9ada658 f7251299 SCSIPORT!ScsiPortPdoScsi+0×129
b9ada66c 8081df85 SCSIPORT!ScsiPortGlobalDispatch+0×1d
b9ada680 f723e607 nt!IofCallDriver+0×45
b9ada690 f723e2b2 CLASSPNP!SubmitTransferPacket+0xbb
b9ada6c4 f723e533 CLASSPNP!ServiceTransferRequest+0×1e4
b9ada6e8 8081df85 CLASSPNP!ClassReadWrite+0×159
b9ada6fc f74c80cf nt!IofCallDriver+0×45
b9ada70c 8081df85 PartMgr!PmReadWrite+0×95
b9ada720 f7317053 nt!IofCallDriver+0×45
b9ada73c 8081df85 ftdisk!FtDiskReadWrite+0×1a9
b9ada750 f72bf8bc nt!IofCallDriver+0×45
b9ada768 8081df85 volsnap!VolSnapRead+0×52
b9ada77c f7163a62 nt!IofCallDriver+0×45
b9ada788 f71638d9 Ntfs!NtfsSingleAsync+0×91
b9ada960 f7164156 Ntfs!NtfsNonCachedIo+0×2db
b9adaa4c f7164079 Ntfs!NtfsCommonRead+0xaf5
b9adabf8 8081df85 Ntfs!NtfsFsdRead+0×113
b9adac0c f721cc45 nt!IofCallDriver+0×45
b9adac34 8081df85 fltmgr!FltpDispatch+0×6f
b9adac48 bafd5373 nt!IofCallDriver+0×45
[…]
IRP and layered drivers (pp. 578 - 586) - here’s a UML-style diagram (#3) for IRP flow:
http://www.dumpanalysis.org/blog/index.php/2006/10/08/uml-and-device-drivers/
Associated IRP (pp. 585 - 586) - this is a part of IRP structure:
+0x018 AssociatedIrp : <unnamed-tag>
+0x000 MasterIrp : Ptr64 _IRP
File object vs. thread IRP association (p. 587)
Thread Termination and pending IRP (pp. 589 - 590) - this pattern uses I/O cancellation as an example:
http://www.dumpanalysis.org/blog/index.php/2007/12/14/crash-dump-analysis-patterns-part-42a/