今天是: Sunday, 6th July 2008
登录
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy.
欢迎来到知识库,这里是收集整理的地方。希望能够给你点帮助
在中间层驱动中处理IRP
Higher-level drivers have a different set of standard routines than lowest-level device drivers, with an overlapping subset of standard routines common to both types of drivers.
The set of routines for intermediate and highest-level drivers also varies according to the following criteria:
- The nature of the underlying physical device
- Whether an underlying device driver sets up device objects for direct or buffered I/O
- The design of the individual higher-level driver
The following figure illustrates the path an IRP might take through the standard routines of an intermediate
下图展示的驱动有下面的特性:
- The driver is layered over more than one physical device and possibly over more than one device driver.
- The driver sometimes allocates additional IRPs for lower-level drivers, depending on the requested operation in the input IRP.
- The driver has at least one file system driver layered above it, and that file system driver might be layered over other intermediate drivers at a higher level than this one.
IRP Path through Intermediate Driver Routines
As the figure shows, the I/O manager creates an IRP and sends it to the driver’s dispatch routine for the given major function code. Assuming the function code is IRP_MJ_WRITE, the dispatch routine is DDDispatchWrite. The intermediate driver’s I/O stack location is shown in the middle, with an indefinite number of I/O stack locations for higher- and lower-level drivers shown shaded.
分派IRPs
The mirror driver’s purpose is to send write requests to several physical devices, and to send read requests alternately to the drivers of these devices. For write requests, the driver creates duplicate IRPs for each device on which the data is to be written, assuming the parameters in the input IRP are valid.
The previous figure shows a call to
When the dispatch routine calls IoAllocateIrp, it specifies the number of I/O stack locations needed for the IRP. The driver must specify a stack location for each lower driver in the chain, getting the appropriate value from the device objects of each driver just below the mirror driver. Optionally, the driver can add one to this value when it calls IoAllocateIrp to get a stack location of its own for each IRP it allocates, as the driver in the previous figure does.
This intermediate driver’s dispatch routine calls
It calls
Next, it calls
调用IoSetCompletionRoutine 和 IoCallDriver
The dispatch routine in the previous figure calls
Because the driver in the previous figure mirrors in parallel, it passes both IRPs that it allocated on to the next-lower-level drivers by calling
在驱动 IoCompletion 函数中处理 IRPs
When either set of lower-level drivers completes the requested operation, the I/O manager calls the intermediate mirror driver’s IoCompletion routine. The mirror driver maintains a count in its own I/O stack location for the original IRP, to track when the lower drivers have completed all the duplicate IRPs.
Assuming that the I/O status block indicates that one set of lower drivers has completed the duplicate IRP shown in the
previous figure successfully, the mirror driver’s IoCompletion routine decrements its count but cannot complete the original IRP until it decrements the count to zero. If the decremented count is not yet zero, the IoCompletion routine calls
When the mirror driver’s IoCompletion routine is called again with the DupIRP2 shown in the previous figure, the IoCompletion routine decrements the count in the original IRP and determines that both sets of lower-level drivers have carried out the requested operations.
Assuming the I/O status block in DupIRP2 also is set with STATUS_SUCCESS, the IoCompletion routine copies the I/O status block from DupIRP2 into the original IRP and frees DupIRP2. It calls
If either set of lower-level drivers does not complete the mirror driver’s IRPs successfully, the mirror driver’s IoCompletion routine should log an error and attempt appropriate mirrored-data recovery.
