IoMarkIrpPending

IoMarkIrpPending

 

IoMarkIrpPending例程用於標記指定的IRP,標誌着某個驅動的分發例程(分發函數)因需要被其他的驅動程序進一步處理最終返回STATUS_PENDING狀態。

 

VOID IoMarkIrpPending( IN OUT PIRP  Irp );

 

參數:Irp

                 將被標記爲Pending狀態的IRP指針。

 

返回值:

                 無

 

Comments:

                 除非IRP的派遣例程完成這個IRP或向下層驅動傳遞,否則派遣例程必須調用IoMarkIrpPending掛起這個IRP。否則I/0 manager將在這個函數返回時試圖完成該IRP。

                 調用IoMarkIrpPending後,派遣例程必須返回STATUS_PENDING,儘管有些函數在派遣例程的IoMarkIrpPending返回前完成了這個IRP。

                 如果驅動隊列收到了IRP,它應該先把這些要進入隊列的IRP掛起(通過調用IoMarkIrpPending)在放入隊列。否則隊列中的未掛起的IRP可能被其他的驅動例程取出並完成(調用 IoCompleteRequest)和釋放(由系統來做),如果在這時再調用IoMarkIrpPending就會導致系統的crash。

                 如果驅動設置了一個完成例程然後向下層驅動傳遞IRP,它的完成例程應該檢測IRP->PendingReturned標誌域(Flag)。如果這個子域被設置成TRUE,完成例程就必須調用IoMarkIrpPending掛起該IRP。(完成例程不返回STATUS_PENDING,更多信息參考:Implementing an IoCompletion Routine)。

 

Warning:

                 創建和發送IRP給其他的設備棧不得在完成例程(Completion Routine)中調用IoMarkIrpPending掛起自己創建的IRP。這個調用會毀壞前面被分配的內存,因爲這是所有驅動對應的location stack中最後一個location stack,也就是前面已經沒有IRP_STACK_LOCATION了。

                 驅動程序把IRP向下傳遞後,等待一個事件對象不應該把IRP設置爲Pending,它的完成例程應該設置事件對象並返回STATUS_MORE_PROCESSING_REQUIRED。

 

必要條件:

                 IRQL:Any level

                 頭文件:在wdm.h中聲明,需要包含wdm.h,Ntddk.h,Ntifs.h。

下面是我對上面幾句話的理解:

“如果驅動隊列收到了IRP,它應該先把這些要進入隊列的IRP掛起(通過調用IoMarkIrpPending)在放入隊列。否則隊列中的未掛起的IRP可能被其他的驅動例程取出並完成(調用 IoCompleteRequest)和釋放(由系統來做),如果在這時再調用IoMarkIrpPending就會導致系統的crash。”

當然若IRP被IO manager Free掉了再引用肯定會引起系統的crash,因爲內存違規訪問。主要是這裏:“驅動收到IRP後要先掛起然後再入隊列,這樣可以防止系統crash”,我認爲IoMarkIrpPending函數會引起該IRP引用計數(reference)的“加1”,所以即使該IRP被一個其它的Driver完成(調用IoCompletionRequest,估計引起引用計數“減1”)也不會被IO manager Free掉,不過還有一種方式是IoFreeIrp,這種方式我認爲不適用與非自己創建的IRP,也可能這句不準確,更多IoFreeIrp的資料請自己查看DDK或WDK文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章