Association of IRP and Io_stack_location structures

Source: Internet
Author: User
Tags apc

irp! in an IRP structure stackcount--irp! currentlocation--irp! Currentstacklocation Three fields are intricately related, only in this article have been made memo.

The IRP structure is followed by a io_stack_location array typedef struct _IRP {CSHORT Type;  USHORT Size;  struct _MDL *mdladdress;  ULONG Flags;    Union {struct _IRP *masterirp;    Volatile LONG Irpcount;  PVOID SystemBuffer;  } associatedirp;  List_entry Threadlistentry;  return value Io_status_block iostatus;  Kprocessor_mode Requestormode;  BOOLEAN pendingreturned;  The stack depth from top to bottom of the entire device stack (length of the io_stack_location array) CHAR Stackcount;    Current device stack depth, counting from 1 */* In addition, a section of code in the IofCallDriver function: irp->currentlocation--;    if (irp->currentlocation <= 0) {KeBugCheckEx (no_more_irp_stack_locations, (ulong_ptr) Irp, 0, 0, 0);    Before invoking the next layer of equipment, first irp->currentlocation minus one, if Irp->currentlocation==0 is bugcheck, from here can be determined, currentlocation is counted from 1 Currentlocation is like the concept of the second layer (array element 1) of the first layer (corresponding to array element 0) in everyday spoken language */CHAR currentlocation; boolean  cancel;  kirql  cancelirql;  cchar  apcenvironment;  UCHAR  allocationflags;  pio_status_block  useriosb; //Sync object   Pkevent  userevent;  Union {    struct {      PIO_APC_ROUTINE  userapcroutine;      pvoid  userapccontext;   } asynchronousparameters;    large_integer  allocationsize; } Overlay;  volatile pdriver_cancel  cancelroutine;  pvoid  userbuffer;  Union {    struct {       _anonymous_union UNION {        kdevice_queue_entry   devicequeueentry;        _anonymous_struct STRUCT {           pvoid  drivercontext[4];       } dummystructname;     } dummyunionname;     //The thread that issued the IRP        pethread  thread;      pchar  auxiliarybuffer;       _anonymous_struct STRUCT {        list_entry  ListEntry;         _anonymous_union UNION {            //the stack array element pointer currently in use             /*       The relationship between      stackcount/currentlocation/currentstacklocation is still to be established from IOSIZEOFIRP and IOINITIALIZEIRP.             */          struct _io_stack_location  *currentstacklocation;          ulong  packettype;       } dummyunionname;      dummystructname;     //Device object associated file object       struct _file_object  * originalfileobject;   } overlay;    //The APC object used when the entire IRP is returned asynchronously &NBSP;&NBSP;&NBSp kapc  apc;    pvoid  completionkey; } Tail;} IRP;
As the note says,

The relationship between the stackcount/currentlocation/currentstacklocation and the three is still to be established from IOSIZEOFIRP and IOINITIALIZEIRP.
Next, take a look at the actions of IOSIZEOFIRP and ioinitializeirp on these fields in the IRP

Voidntapiioinitializeirp (in Pirp Irp, in USHORT packetsize, in CChar StackSize) {/* Clear    It */Iotrace (Io_irp_debug, "%s-initializing irp%p\n", __function__, IRP);    RtlZeroMemory (IRP, packetsize);    /* Set the Header and other data */Irp->type = IO_TYPE_IRP;    Irp->size = PacketSize; Irp->stackcount = stacksize;//The initial state when the current stack depth is actual depth (StackSize) +1//because the IRP at this time has not yet entered the device object stack irp->currentlocation =    StackSize + 1; Irp->apcenvironment = Kegetcurrentthread ()->apcstateindex;//io_stack_location array followed by the IRP, with only stacksize elements in the array ,//subscript from 0 to StackSize-1, so the pointer has crossed an element. Most importantly, the call to IoCallDriver will be called once iogetnextirpstacklocation, the array//pointer to the correct position, and then pass the IRP down/* or the old device stacksize=1 for example: irp- >currentlocation=2, the second device in the device stack (unfortunately there are only 1 devices on the stack), Irp->tail.overlay.currentstacklocation=&io_stack_ LOCATION[1]. The array has only element 0, so it is still out of bounds. When IofCallDriver is called, the Iosetnextirpstacklocation (IRP) is irp->currentlocation= 1, meaning to take the first element in the stack, Irp->tail.overlay.currentstacklocation--stack pointer to &io_stack_location[0], take stack element 0*/irp->tail.overlay.currentstacklocation = (PIO    _stack_location) (IRP + 1) + StackSize; /* Initialize the Thread List */Initializelisthead (&irp->threadlistentry);}

/* StackSize is the number of devices from the top level to the bottom of the device stack, with older devices as an example stacksize=1. So this macro will get the sizeof (IRP) and only an array of io_stack_location elements in the pool, subscript 0 */#define IOSIZEOFIRP (_stacksize) (   (USHORT) (sizeof ( IRP) + ((_stacksize) * (sizeof (io_stack_location))))


Association of IRP and Io_stack_location structures

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.