亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

IRP請求處理及完成機制

系統 1991 0

近來學習 Windows 內核方面的東西,覺得對 I/O 處理過程沒有一個總體的概念。于是,就花了很長的時間搜集了很多這方面的知識總結了一下。

在 Windows 內核中的請求基本上是通過 I/O Request Packet 完成的。前面說過,設備對象是唯一可以接受請求的實體。下面,我就來詳細地說下 IRP 請求是怎么樣一步一步完成的。

首先,我們就需要知道 IRP 是怎么產生。 IRP 是由 I/O 管理器發出的, I/O 管理器是用戶態與內核態之間的橋梁,當用戶態進程發出 I/O 請求時, I/O 管理器就捕獲這些請求,將其轉換為 IRP 請求,發送給驅動程序。 I/O 管理器無疑是非常重要的,具有核心地位。它負責所有 I/O 請求的調度和管理工作,根據請求的不同內容,選擇相應的驅動程序對象,設備對象,并生成、發送、釋放各種不同的 IRP 。整個 I/O 處理流程是在它的指揮下完成的。

一個 IRP 是從非分頁內存中分配的可變大小的結構,它包括兩部分: IRP 首部和輔助請求參數數組,如圖 1 所示。這兩部分都是由 I/O 管理器建立的。

IRP請求處理及完成機制

圖 1 IRP 簡單結構圖

IRP 首部中包含了指向 IRP 輸入輸出緩沖區指針、當前擁有 IRP 的驅動指針等。

緊接著首部的是一個 IO_STACK_LOCATION 結構的數組。它的大小由設備棧中的設備數確定(設備棧的概念會在下文中闡述)。 IO_STACK_LOCATION 結構中保存了一個 I/O 請求的參數及代碼、請求當前對應的設備指針、完成函數指針( IoCompletion )等。

那么,由 I/O 管理器產生的 IRP 請求發送到哪去了呢?這里我們就要來說說設備棧的概念了,操作系統用設備對象( device object )表示物理設備,每一個物理設備都有一個或多個設備對象與之相關聯,設備對象提供了在設備上的所有操作。也有一些設備對象并不表示物理設備。一個唯軟件驅動程序( software-only driver ,處理 I/O 請求,但是不把這些請求傳遞給硬件)也必須創建表示它的操作的設備對象。設備常常由多個設備對象所表示,每一個設備對象在驅動程序棧( driver stack )中對應一個驅動程序來管理設備的 I/O 請求。一個設備的所有設備對象被組織成一個設備棧( device stack )。而且, IO_STACK_LOCATION 數組中的每個元素和設備棧中的每個設備是一一對應的,一般情況下,只允許層次結構中的每個設備對象訪問它自己對應的 IO_STACK_LOCATION 。無論何時,一個請求操作都在一個設備上被完成, I/O 管理器把 IRP 請求傳遞給設備棧中頂部設備的驅動程序( IRP 是傳遞給設備對象的,通過設備對象的 DriverObject 成員找到驅動程序)。驅動程序訪問它對應的設備對象在 IRP 中 IO_STACK_LOCATION 數組中的元素檢查參數,以決定要進行什么操作(通過檢查結構中的 MajorFunction 字段,確定執行什么操作及如何解釋 Parameters 共用體字段的內容)。驅動程序可以根據 IO_STACK_LOCATION 結構中的 MajorFunction 字段進行處理。每一個驅動或者處理 IRP ,或者把它傳遞給設備棧中下一個設備對象的驅動程序。

傳遞 IRP 請求到底層設備的驅動程序需要經過下面幾個步驟:

1. 為下一個 IO_STACK_LOCATION 結構設置參數。可以有以下兩種方式:

· 調用 IoGetNextIrpStackLocation 函數獲得下個結構的指針,再對參數進行賦值;

· 調用 IoCopyCurrentIrpStackLocationToNext 函數(如果第 2 步中驅動設置了 IoCompletion 函數 ),或者調用 IoSkipCurrentIrpStackLocation 函數(如果第 2 步中驅動沒有設置 IoCompletion 函數 )把當前的參數傳遞給下一個。

2. 如果需要的話,調用 IoSetCompletionRoutine 函數設置 IoCompletion 函數進行后續處理。

3. 調用 IoCallDriver 函數將 IRP 請求傳遞給下一層驅動。這個函數會自動調整 IRP 棧指針,并且執行下一層驅動的派遣函數。

當驅動程序把 IRP 請求傳遞給下一層驅動之后,它就不再擁有對該請求的訪問權,強行訪問會導致系統崩潰。如果驅動程序在傳遞完之后還想再訪問該請求,就必須要設置 IoCompletion 函數。 IRP 請求可以再其他驅動程序或者其他線程中完成或取消。

當某一驅動程序調用 IoCompleteRequest 函數時, I/O 操作就完成了。這個函數使得 IRP 的堆棧指針向上移動一個位置,如圖 2 所示:


IRP請求處理及完成機制


圖 2 IRP 完成時棧指針的移動

圖 2 所示的當 C 驅動程序調用完 IoCompleteRequest 函數后 I/O 棧的情況。左邊的實線箭頭表明棧指針現在指向驅動 B 的參數和回調函數;虛線箭頭是之前的情況。右邊的空心箭頭指明了 IoCompletion 函數被調用的順序。

如果驅動程序把 IRP 請求傳遞給設備棧中的下層設備之前設置了 IoCompletion 函數,當 I/O 棧指針再次指回到該驅動程序時, I/O 管理器就將調用該 IoCompletion 函數。

IoCompletion 函數的返回值有兩種:

( 1 ) STATUS_CONTINUE_COMPLETION :告訴 I/O 管理器繼續執行上層驅動程序的 IoCompletion 函數。

( 2 ) STATUS_MORE_PROCESSING_REQUIRED :告訴 I/O 管理器停止執行上層驅動程序,并將棧指針停在當前位置。在當前驅 動程序調用 IoCompleteRequest 函數后再繼續執行上層驅動的 IoCompletion 函數。

當所有驅動都完成了它們相應的子請求時, I/O 請求就結束了。 I/O 管理器從 Irp?>IoStatus.Status 成員更新狀態信息,從 Irp?>IoStatus.Information 成員更新傳送字節數。

寫的比較倉促,如有不正之處,希望大家指教!


本文來自CSDN博客,轉載請標明出處: http://blog.csdn.net/vangoals/archive/2009/07/20/4363863.aspx

IRP請求處理及完成機制


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品久久自在自2021 | 天天干天天操天天添 | 久久免费福利视频 | 5060午夜一级毛片 | 欧美影院久久 | 亚洲一区二区三区高清网 | 色成网 | 亚洲国产美女视频 | 国产一区二区精品在线观看 | 99热久久这里只精品国产 | 亚洲婷婷网 | 欧美高清在线视频在线99精品 | 2022国产成人综合精品 | 第一福利影院 | 男人天堂a | 亚洲热热久久九九精品 | 青青青青爽视频在线播放 | 干成人| 欧美一区二区三区视视频 | 国产自产视频在线观看香蕉 | 97影院理论片在线观看 | 午夜深夜福利网址 | 国产一级毛片免 | 天天摸日日 | 亚洲免费在线观看视频 | 国产精品视频公开费视频 | 男人猛桶女人下面视频国产 | 日夜夜操 | 久草视频在线播放 | 国产成人aa在线观看视频 | 99re这里只有精品在线 | 日本一级特黄aa大片24免费 | 中文在线播放 | 亚洲欧美久久精品一区 | 成人影院在线观看视频 | 91在线看片一区国产 | 国内精品一级毛片免费看 | 国产欧美精品一区二区 | 国产女人综合久久精品视 | 日本精品视频在线 | 中文字幕在线看视频一区二区三区 |