I/O Stack
When any kernel mode program creates an IRP, it also creates an io_stack_location structure array associated with it: each stack unit in the array corresponds to a driver that will process the IRP, there is also a stack unit for the IRP creator (see Figure 5-3 ). The stack unit contains the type code and parameter information of the IRP and the address of the completed function. The following figure shows the structure of the stack unit.
Data Structure of I/O stack units:
Majorfunction(Uchar) is the primary function code of the IRP. This code should be the same value as irp_mj_read and correspond to a dispatch function pointer in the majorfunction table of the driver object. If the code exists in the I/O stack unit of a special driver, it may start with, for example, irp_mj_read, and then be converted into other code by the driver, and send it along the driver stack to the lower-layer driver. I will give an example in Chapter 11th (USB Bus) that the USB driver converts standard read or write requests to internal control operations to submit requests to the USB bus driver.
Minorfunction(Uchar) is the sub-function code of the IRP. It further points out the main function category of the IRP. For example, an irp_mj_pnp request has a dozen sub-function codes, such as irp_mn_start_device and irp_mn_remove_device.
Parameters(Union) is the union of several sub-structures. Each request type has its own special parameters, and each sub-structure is a parameter. These sub-structures include create (irp_mj_create request), read (irp_mj_read request), and startdevice (irp_mj_pnp irp_mn_start_device sub-type.
Deviceobject(Pdevice_object) is the address of the device object corresponding to the stack unit. This field is filled by the iocalldriver function.
Fileobject(Pfile_object) is the address of the kernel file object, and the IRP object is the object. The driver usually uses the fileobject pointer when processing the clear request (irp_mj_cleanup) to distinguish IRP irrelevant to the file object in the queue.
Completionroutine(Pio_completion_routine) is the address of an I/O completion routine, which is set by the driver corresponding to the stack unit at the higher level. You must never directly set this field. You should call the iosetcompletionroutine function, which knows how to refer to the stack unit of the next driver. The lowest-level drivers of the device stack do not need to complete the routine because they must directly complete the request. However, the request initiator sometimes needs a completion routine, but usually does not have its own stack unit. This is why each level-1 driver uses the stack unit of the next level driver to save its own complete routine pointer.
Context(Pvoid) is an arbitrary context-related value and is passed as a parameter to the completion routine. You must never directly set this field. It is automatically set by the iosetcompletionroutine function and its value comes from a parameter of this function.
The IRP structure is a partial opaque structure that represents an I/O Request Packet. Drivers can use the following members of the IRP structure.
Typedef struct _ IRP {
.
.
Pmdl mdladdress;
Ulong flags;
Union {
Struct _ IRP * masterirp;
.
.
Pvoid systembuffer;
} Associatedirp;
.
.
Io_status_block iostatus;
Kprocessor_mode requestormode;
Boolean pendingreturned;
.
.
Boolean cancel;
Kirql cancelirql;
.
.
Pdriver_cancel cancelroutine;
Pvoid userbuffer;
Union {
Struct {
.
.
Union {
Kdevice_queue_entry devicequeueentry;
Struct {
Pvoid drivercontext [4];
};
};
.
.
Pethread thread;
.
.
List_entry listentry;
.
.
} Overlay;
.
.
} Tail;
} IRP, * pirp;
Members
Mdladdress
Pointer to an MDL describing a user buffer, if the driver is using direct I/O, And the IRP major function code is one of the following:
Irp_mj_read
The MDL describes an empty buffer that the device or driver fills in.
Irp_mj_write
The MDL describes a buffer that contains data for the device or driver.
Irp_mj_device_controlor irp_mj_internal_device_control
If the ioctl Code specifies the method_in_direct transfer type, the MDL describes a buffer that contains data for the device or driver.
If the ioctl Code specifies the method_out_direct transfer type, the MDL describes an empty buffer that the device or driver fills in.
For more information about the buffers that are associated with method_in_direct and method_out_direct transfer types in IOCTL codes, see buffer descriptions for I/O control codes.
If the driver is not using direct I/O, this pointer is null.
Flags
File System drivers use this field, which is read-only for all drivers. network and, possibly, highest-level device drivers also might read this field, which can be set with one or more of the following system-defined masks:
Irp_nocache
Irp_paging_io
Irp_mount_completion
Irp_synchronous_api
Irp_associated_irp
Irp_buffered_io
Irp_deallocate_buffer
Irp_input_operation
Irp_synchronous_paging_io
Irp_create_operation
Irp_read_operation
Irp_write_operation
Irp_close_operation
Irp_defer_io_completion
Associatedirp. masterirp
Pointer to the master IRP in an IRP that was created by a highest-level driver's call to iomakeassociatedirp.
Associatedirp. systembuffer
Pointer to a system-space buffer.
If the driver is using buffered I/O, the buffer's purpose is determined by the IRP Major Function Code, as follows:
Irp_mj_read
The buffer records es data from the device or driver. The buffer's length is specified by parameters. Read. lengthin the driver's io_stack_locationstructure.
Irp_mj_write
The buffer supplies data for the device or driver. The buffer's length is specified by parameters. Write. lengthin the driver's io_stack_location structure.
Irp_mj_device_controlor irp_mj_internal_device_control
The buffer represents both the input and output buffers that are supplied to deviceiocontroland iobuilddeviceiocontrolrequest. Output Data overwrites input data.
For input, the buffer's length is specified by parameters. deviceiocontrol. inputbufferlengthin the driver's io_stack_location structure.
For output, the buffer's length is specified by parameters. deviceiocontrol. outputbufferlengthin the driver's io_stack_location structure.
For more information, see buffer descriptions for I/O control codes.
If the driver is using direct I/O, the buffer's purpose is determined by the IRP Major Function Code, as follows:
Irp_mj_read
Null.
Irp_mj_write
Null.
Irp_mj_device_controlor irp_mj_internal_device_control
The buffer represents the input buffer that is supplied to deviceiocontroland iobuilddeviceiocontrolrequest.
The buffer's length is specified by parameters. deviceiocontrol. inputbufferlengthin the driver's io_stack_location structure.
For more information, see buffer descriptions for I/O control codes.
Iostatus
Contains the io_status_blockstructure in which a driver stores status and information before calling iocompleterequest.
Requestormode
Indicates the Execution Mode of the original requester of the operation, one of usermodeor kernelmode.
Pendingreturned
If set to true, a driver has marked the IRP pending. each iocompletionroutine shoshould check the value of this flag. if the flag is true, and if the iocompletionroutine will not return status_more_processing_required, the routine shocould call iomarkirppendingto propagate the pending status to drivers above it in the device stack.
Cancel
If set to true, the IRP either is or shoshould be canceled.
Cancelirql
Contains the IRQL at which a driver is running when ioacquirecancelspinlockis called.
Cancelroutine
Contains the entry point for a driver-supplied cancelroutine to be called if the IRP is canceled. null indicates that the IRP is not currently cancelable.
Userbuffer
Contains the address of an output buffer if the major function code in the I/O stack location is irp_mj_device_controlor irp_mj_internal_device_controland the I/O control code was defined with method_neither.
Tail. Overlay. devicequeueentry
If IRPs are queued in the device queue associated with the driver's device object, this field links IRPs in the device queue. These links can be used only while the driver is processing the IRP.
Tail. Overlay. drivercontext
If IRPs are not queued in the device queue associated with the driver's device object, this field can be used by the driver to store up to four pointers. this field can be used only while the driver owns the IRP.
Tail. Overlay. Thread
Is a pointer to the caller's thread control block. higher-level drivers that allocate IRPs for lower-level removable-media drivers must set this field in the IRPs they allocate. otherwise, the FSD cannot determine which thread to require y if the underlying device driver indicates that the media requires verification.
Tail. Overlay. listentry
If a driver manages its own internal queues of IRPs, it uses this field to link one IRP to the next. these links can be used only while the driver is holding the IRP in its queue or is processing the IRP.
Headers
Defined in WDM. Hand ntddk. H. Include WDM. Hor ntddk. h.
Comments
Uninitialized ented members of the IRP structure are reserved, used only by the I/O manager or, in some cases, by fsds.
An IRP is the basic I/O manager structure used to communicate with drivers and to allow drivers to communicate with each other. A packet consists of two different parts:
Header, or fixed part of the packet? This is used by the I/O manager to store information about the original request, such as the caller's device-independent parameters, the address of the device object upon which a file is open, and so on. it is also used by drivers to store information such as the final status of the request.
I/O stack locations? Following the header is a set of I/O stack locations, one per driver in the chain of layered drivers for which the request is bound. each stack location contains the parameters, function codes, and context used by the corresponding driver to determine what it is supposed to be doing. for more information, see the io_stack_locationstructure.
While a higher-level driver might check the value of the cancelboolean in an IRP, that driver cannot assume the IRP will be completed with status_cancelled by a lower-level driver even if the value is true.
See alsoiocreatedevice, iogetcurrentirpstacklocation, iogetnextirpstacklocation, iosetcancelroutine, iosetnextirpstacklocation, io_stack_location, io_status_block
From: http://blog.csdn.net/bluesun777/archive/2008/02/27/2124761.aspx