Delivery and completion of IRP in a layered driving Model
Source: Internet
Author: User
In the Windows layered driver model, devices in the device stack generally implement the driver function by processing the IRP sent from the upper layer. Here we will summarize and summarize several common IRP transfer and completion methods:
1. Completed in the driver of this layer
1.1 In this layer, the driver is synchronized.
After completing the synchronization at this layer, set IRP-> iostatus. Status and IRP-> iostatus. Information, call iocompleterequest to complete the IRP, and return the completion status of the IRP.
1.2 asynchronous completion in the local driver
In this layer, after asynchronous completion, an IRP is usually obtained and then queued/started to be processed separately. At the same time, iomarkirppending is called to mark the IRP as pending, and then return status_pending. At this time, the IRP is not actually completed. You need to call iocompleterequest after the pending operations are completed.
2. Forward to the underlying driver
2.1 This layer is not processed
Sometimes, for some IRPs, the local driver does not need to do any processing. In this case, you can use ioskipcurrentirpstacklocation to skip the current device stack, call iocalldriver to forward the IRP to the underlying driver, and return the forwarded result directly. This processing method does not need to care whether the underlying driver processes the IRP in synchronous or asynchronous mode. After the IRP is forwarded to the lower layer, it has nothing to do with it.
2.2 synchronous forwarding
Sometimes IRPs cannot be directly processed at the current layer, so they need to be forwarded to the lower layer. After the lower layer completes processing, the IRPs can be modified on the result before returning it. In this case, you can use the synchronous forwarding method for processing. First, initialize an unstimulated event in the corresponding dispatch routine and call iocopycurrentirpstacklocationtonext to copy the device stack parameters at the current layer to the lower layer. Then set a completionroutine and pass the previously initialized event to it as the context. Call iocalldriver to forward the IRP to the lower layer and determine whether the returned value is status_pending. Yes is the event before wait. In completionroutine, determine whether the IRP is pendingreturned. If yes, iocalldriver returns status_pending, and then triggers the event. Completionroutine returns status_more_processing_required so that our dispatch routine can regain control of the IRP. This layer of dispatch waits for the end to obtain control again, and then performs corresponding processing. Then, you need to call iocompleterequest again to complete the IRP.
Synchronous Forwarding is a common IRP Processing Method in drivers. Generally, the local dispatch forwards the IRP to the lower layer and waits for the completionroutine to stimulate the event to form a forwardirpsynchronous function. Several dispatches only need one forwardirpsynchronous, and the code is relatively simple.
Do not call iomarkirppending in the local dispatch, because the upper-layer requests are processed synchronously at the local layer. In synchronous forwarding, if the underlying driver uses the synchronous method, the local dispatch does not (or does not need to) Wait. When iocalldriver returns the completionroutine, it has been called and has no performance loss.
2.3 asynchronous forwarding
Asynchronous forwarding can also be used to obtain the processing opportunity when the underlying driver completes the IRP. It mainly uses an asynchronous processing mechanism. First, this layer dispatch calls iocopycurrentirpstacklocationtonext to copy the device stack parameters of this layer to the lower layer, sets the corresponding completionroutine, and then calls iocalldriver to forward the IRP to the lower-layer driver, and directly return the forwarded result to the upper-layer caller. In completionroutine, you must call iomarkirppending to determine whether the IRP is pendingreturned. Then, the lower-layer driver can perform corresponding operations on the result of processing the IRP. Finally, status_continue_completion (same as STATUS_SUCCESS) is returned ).
Asynchronous forwarding has the best performance in asynchronous processing, but the processing logic is placed in completionroutine. Therefore, multiple dispatches need to write multiple completionroutine. Synchronous forwarding usually requires only one forwardirpsynchronous for several dispatches, and the code is relatively simple.
It is worth noting that the IRQL run by each dispatch routine is determined by the call relationship. If the upper-layer caller has the possibility of running at dispatch_level, the dispatch of the current layer also needs to be designed according to the running at dispatch_level. For example, if the IRP passed to the local dispatch is forwarded in the startio routine driven by the upper layer, the code for processing this type of IRP may run at dispatch_level.
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.