You must know this to understand Windows Driver Model





//++
//
// PIO_STACK_LOCATION
// IoGetCurrentIrpStackLocation(
//     IN PIRP Irp
//     )
//
// Routine Description:
//
//     This routine is invoked to return a pointer to the current stack location
//     in an I/O Request Packet (IRP).
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet.
//
// Return Value:
//
//     The function value is a pointer to the current stack location in the
//     packet.
//
//--

#define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )




//++
//
// PIO_STACK_LOCATION
// IoGetNextIrpStackLocation(
//     IN PIRP Irp
//     )
//
// Routine Description:
//
//     This routine is invoked to return a pointer to the next stack location
//     in an I/O Request Packet (IRP).
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet.
//
// Return Value:
//
//     The function value is a pointer to the next stack location in the packet.
//
//--

#define IoGetNextIrpStackLocation( Irp ) (\
    (Irp)->Tail.Overlay.CurrentStackLocation - 1 )





//++
//
// VOID
// IoSetNextIrpStackLocation (
//     IN OUT PIRP Irp
//     )
//
// Routine Description:
//
//     This routine is invoked to set the current IRP stack location to
//     the next stack location, i.e. it "pushes" the stack.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet (IRP).
//
// Return Value:
//
//     None.
//
//--

#define IoSetNextIrpStackLocation( Irp ) {      \
    (Irp)->CurrentLocation--;                   \
    (Irp)->Tail.Overlay.CurrentStackLocation--; }




//++
//
// VOID
// IoSkipCurrentIrpStackLocation (
//     IN PIRP Irp
//     )
//
// Routine Description:
//
//     This routine is invoked to increment the current stack location of
//     a given IRP.
//
//     If the caller wishes to call the next driver in a stack, and does not
//     wish to change the arguments, nor does he wish to set a completion
//     routine, then the caller first calls IoSkipCurrentIrpStackLocation
//     and the calls IoCallDriver.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet.
//
// Return Value:
//
//     None
//
//--

#define IoSkipCurrentIrpStackLocation( Irp ) { \
    (Irp)->CurrentLocation++; \
    (Irp)->Tail.Overlay.CurrentStackLocation++; }




//++
//
// VOID
// IoCopyCurrentIrpStackLocationToNext(
//     IN PIRP Irp
//     )
//
// Routine Description:
//
//     This routine is invoked to copy the IRP stack arguments and file
//     pointer from the current IrpStackLocation to the next
//     in an I/O Request Packet (IRP).
//
//     If the caller wants to call IoCallDriver with a completion routine
//     but does not wish to change the arguments otherwise,
//     the caller first calls IoCopyCurrentIrpStackLocationToNext,
//     then IoSetCompletionRoutine, then IoCallDriver.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet.
//
// Return Value:
//
//     None.
//
//--

#define IoCopyCurrentIrpStackLocationToNext( Irp ) { \
    PIO_STACK_LOCATION __irpSp; \
    PIO_STACK_LOCATION __nextIrpSp; \
    __irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \
    __nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \
    RtlCopyMemory( __nextIrpSp, __irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
    __nextIrpSp->Control = 0; }

#define FIELD_OFFSET(type, field) ( (LONG) (LONG_PTR) &(((type*) 0)->field))



//++
//
// PDRIVER_CANCEL
// IoSetCancelRoutine(
//     IN PIRP Irp,
//     IN PDRIVER_CANCEL CancelRoutine
//     )
//
// Routine Description:
//
//     This routine is invoked to set the address of a cancel routine which
//     is to be invoked when an I/O packet has been canceled.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet itself.
//
//     CancelRoutine - Address of the cancel routine that is to be invoked
//         if the IRP is cancelled.
//
// Return Value:
//
//     Previous value of CancelRoutine field in the IRP.
//
//--

#define IoSetCancelRoutine( Irp, NewCancelRoutine ) (  \
    (PDRIVER_CANCEL) InterlockedExchangePointer( (PVOID *) &(Irp)->CancelRoutine, (PVOID) (NewCancelRoutine) ) )




//++
//
// VOID
// IoSetCompletionRoutine(
//     IN PIRP Irp,
//     IN PIO_COMPLETION_ROUTINE CompletionRoutine,
//     IN PVOID Context,
//     IN BOOLEAN InvokeOnSuccess,
//     IN BOOLEAN InvokeOnError,
//     IN BOOLEAN InvokeOnCancel
//     )
//
// Routine Description:
//
//     This routine is invoked to set the address of a completion routine which
//     is to be invoked when an I/O packet has been completed by a lower-level
//     driver.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet itself.
//
//     CompletionRoutine - Address of the completion routine that is to be
//         invoked once the next level driver completes the packet.
//
//     Context - Specifies a context parameter to be passed to the completion
//         routine.
//
//     InvokeOnSuccess - Specifies that the completion routine is invoked when the
//         operation is successfully completed.
//
//     InvokeOnError - Specifies that the completion routine is invoked when the
//         operation completes with an error status.
//
//     InvokeOnCancel - Specifies that the completion routine is invoked when the
//         operation is being canceled.
//
// Return Value:
//
//     None.
//
//--

#define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \
    PIO_STACK_LOCATION __irpSp;                                               \
    ASSERT( (Success) | (Error) | (Cancel) ? (Routine) != NULL : TRUE );    \
    __irpSp = IoGetNextIrpStackLocation( (Irp) );                             \
    __irpSp->CompletionRoutine = (Routine);                                   \
    __irpSp->Context = (CompletionContext);                                   \
    __irpSp->Control = 0;                                                     \
    if ((Success)) { __irpSp->Control = SL_INVOKE_ON_SUCCESS; }               \
    if ((Error)) { __irpSp->Control |= SL_INVOKE_ON_ERROR; }                  \
    if ((Cancel)) { __irpSp->Control |= SL_INVOKE_ON_CANCEL; } }



//++
//
// VOID
// IoMarkIrpPending(
//     IN OUT PIRP Irp
//     )
//
// Routine Description:
//
//     This routine marks the specified I/O Request Packet (IRP) to indicate
//     that an initial status of STATUS_PENDING was returned to the caller.
//     This is used so that I/O completion can determine whether or not to
//     fully complete the I/O operation requested by the packet.
//
// Arguments:
//
//     Irp - Pointer to the I/O Request Packet to be marked pending.
//
// Return Value:
//
//     None.
//
//--

#define IoMarkIrpPending( Irp ) ( \
    IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )



//
//
// NTKERNELAPI
// NTSTATUS
// FASTCALL
// IofCallDriver(
//      IN PDEVICE_OBJECT DeviceObject,
//      IN OUT PIRP Irp
//      );
//
// Routine Description:
//
//     This routine is invoked to pass an I/O Request Packet (IRP) to another
//     driver at its dispatch routine.
//
// Arguments:
//
//     DeviceObject - Pointer to device object to which the IRP should be passed.
//
//     Irp - Pointer to IRP for request.
// 
// Return Value:
// 
//    Return status from driver's dispatch routine.
//
//

NTKERNELAPI
NTSTATUS
FASTCALL
IofCallDriver(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PIRP Irp
    )
{
    UCHAR MajorFunction;
    ASSERT( Irp->Type == IO_TYPE_IRP );
    
    Irp->CurrentLocation--;
    if( Irp->CurrentLocation == 0 )
    {
        KeBugCheckEx( NO_MORE_IRP_STACK_LOCATIONS, Irp, NULL, NULL, NULL );
    }

    Irp->Tail.Overlay.CurrentStackLocation--;
    Irp->Tail.Overlay.CurrentStackLocation->DeviceObject = DeviceObject;

    // Call dispatcher routine
    MajorFunction = Irp->Tail.Overlay.CurrentStackLocation->MajorFunction;
    return ( *(DeviceObject->DriverObject->MajorFunction[MajorFunction])(DeviceObject, Irp) );

}



 WinDbg FASTCALL analyze nt!IofCallDriver 
 FASTCALL - the first two DWORD-or-smaller arguments are passed
 in the ecx and edx registers. The remaining parameters are passed
 on the stack, pushed right to left. The callee cleans the stack.

kd> bp nt!IofCallDriver

kd> g
Breakpoint 0 hit
nt!IofCallDriver:
804e37c5 ff2500295580    jmp     dword ptr [nt!pIofCallDriver (80552900)]

kd> r
eax=81df2158 ebx=00000000 ecx=81e67020 edx=81df2158 esi=81e7c180 edi=81e67c08
eip=804e37c5 esp=f8973ec0 ebp=f8973ed0 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
nt!IofCallDriver:
804e37c5 ff2500295580    jmp     dword ptr [nt!pIofCallDriver (80552900)] ds:0023:80552900={nt!IopfCallDriver (804e37d0)}

kd> !irp edx
Irp is active with 5 stacks 5 is current (= 0x81df2258)
 Mdl=81e98d38: No System Buffer: Thread 00000000:  Irp stack trace.  Pending has been returned
     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
 [  f, 0]   0 e0 81f87d98 00000000 f8590635-81e7c188 Success Error Cancel 
	       \Driver\atapi	CLASSPNP!ClasspMediaChangeDetectionCompletion
			Args: 81e7c188 00000000 001b0011 00000000
>[  0, 0]   2  0 81e67b50 00000000 00000000-00000000    
	       \Driver\Cdrom
			Args: 00000000 00000000 00000000 00000000

kd> !devobj ecx
Device object (81e67020) is for:
  \Driver\Imapi DriverObject 81e68f38
Current Irp 00000000 RefCount 0 Type 0000002d Flags 00004010
DevExt 81e670d8 DevObjExt 81e67660 
ExtensionFlags (0000000000)  
AttachedDevice (Upper) 81e67b50 \Driver\Cdrom
AttachedTo (Lower) 81f87d98 \Driver\atapi
Device queue is not busy.

kd> dt nt!_IRP 81df2158
   +0x000 Type             : 6
   +0x002 Size             : 0x190
   +0x004 MdlAddress       : 0x81e98d38 _MDL
   +0x008 Flags            : 0
   +0x00c AssociatedIrp    : __unnamed
   +0x010 ThreadListEntry  : _LIST_ENTRY [ 0x81df2168 - 0x81df2168 ]
   +0x018 IoStatus         : _IO_STATUS_BLOCK
   +0x020 RequestorMode    : 0 ''
   +0x021 PendingReturned  : 0x1 ''
   +0x022 StackCount       : 5 ''
   +0x023 CurrentLocation  : 5 ''
   +0x024 Cancel           : 0 ''
   +0x025 CancelIrql       : 0 ''
   +0x026 ApcEnvironment   : 0 ''
   +0x027 AllocationFlags  : 0x4 ''
   +0x028 UserIosb         : (null) 
   +0x02c UserEvent        : (null) 
   +0x030 Overlay          : __unnamed
   +0x038 CancelRoutine    : (null) 
   +0x03c UserBuffer       : (null) 
   +0x040 Tail             : __unnamed

kd> dt nt!_DEVICE_OBJECT 81e67020 
   +0x000 Type             : 3
   +0x002 Size             : 0x640
   +0x004 ReferenceCount   : 0
   +0x008 DriverObject     : 0x81e68f38 _DRIVER_OBJECT
   +0x00c NextDevice       : (null) 
   +0x010 AttachedDevice   : 0x81e67b50 _DEVICE_OBJECT
   +0x014 CurrentIrp       : (null) 
   +0x018 Timer            : (null) 
   +0x01c Flags            : 0x4010
   +0x020 Characteristics  : 0x101
   +0x024 Vpb              : (null) 
   +0x028 DeviceExtension  : 0x81e670d8 
   +0x02c DeviceType       : 0x2d
   +0x030 StackSize        : 2 ''
   +0x034 Queue            : __unnamed
   +0x05c AlignmentRequirement : 1
   +0x060 DeviceQueue      : _KDEVICE_QUEUE
   +0x074 Dpc              : _KDPC
   +0x094 ActiveThreadCount : 0
   +0x098 SecurityDescriptor : (null) 
   +0x09c DeviceLock       : _KEVENT
   +0x0ac SectorSize       : 0
   +0x0ae Spare1           : 1
   +0x0b0 DeviceObjectExtension : 0x81e67660 _DEVOBJ_EXTENSION
   +0x0b4 Reserved         : (null)

kd> k 
ChildEBP RetAddr  
f8973ebc f85905cb nt!IofCallDriver 
f8973ed0 f8590731 CLASSPNP!ClasspSendMediaStateIrp+0xb9 
f8973ef8 804e3d38 CLASSPNP!ClasspMediaChangeDetectionCompletion+0x141 
f8973f28 f849965e nt!IopfCompleteRequest+0xa2 
f8973f54 f8499b94 atapi!IdeProcessCompletedRequest+0x664 
f8973fd0 804dbbd4 atapi!IdePortCompletionDpc+0x204 
f8973ff4 804db89e nt!KiRetireDpcList+0x46 
f8973ff8 f860fa0c nt!KiDispatchInterrupt+0x2a