How IRP and STACK_LOCATION are allocated.


PIRP
IoAllocateIrp(stacksize)
{
  irp = alloc(sizeof(IRP) + (stacksize * sizeof(IO_STACK_LOCATION));

  irp->StackCount = stacksize;
  irp->CurrentLocation = stacksize + 1;
  irp->Tail.Overlay.CurrentStackLocation = irp + sizeof(IRP) + (stacksize * sizeof(IO_STACK_LOCATION));
  ...
  return irp;
}

/* Example on x86 */

PIRP pIrp = IoAllocateIrp(3);

/* From WinDBG on x86 */
??sizeof(_IRP) = 0x70
??sizeof(_IO_STACK_LOCATION) = 0x24


pIrp
+ 0x00  +---------------------------------------+ 	irp
        |                                       |
        |                                       |
        | StackCount      = 3 ;                 | 
        | CurrentLocation = 4;                  |
        | Tail.Overlay.                         |
        | CurrentStackLocation = irp + 0xDC;    |
        |                                       |
+ 0x70  +---------------------------------------+ 	StackLocation_1
        |                                       |
        | StackLocation_1 (DeviceObject_1)      |
        |                                       |
+ 0x94  +---------------------------------------+ 	StackLocation_2
        |                                       |
        | StackLocation_2 (DeviceObject_2)      |
        |                                       |
+ 0xB8  +---------------------------------------+ 	StackLocation_3
        |                                       |
        | StackLocation_3 (DeviceObject_3)      |
        |                                       |
+ 0xDC  +---------------------------------------+  	irp->Tail.Overlay.CurrentStackLocation
        |                                       |
        | Not Valid                             |
        | StackLocation                         |
        +---------------------------------------+ 


After allocate IRP via IoAllocateIrp() we don't have valid CurrentStackLocation :-)