• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            小默

            [轉載]分層驅動模型中IRP的傳遞與完成

            本文轉自Hanke空間,原文地址:http://hi.baidu.com/hankebao/blog/item/7e8329804e0ce9d2bc3e1e2b.html
            ---------
            在Windows分層驅動模型中,設備棧中的設備一般都是通過對上層傳來的IRP做相應的處理來實現(xiàn)驅動的功能。這里對常用的幾種IRP傳遞及完成的方式進行歸納和總結:

            1. 在本層驅動中完成

            1.1 在本層驅動中以同步方式完成
            在本層同步完成一般做完相應處理后,設置Irp->IoStatus.Status和Irp->IoStatus.Information,調(diào)用IoCompleteRequest完成該IRP,return IRP的完成狀態(tài)即可。

            1.2 在本層驅動中以異步方式完成
            在本層異步完成一般是得到IRP后將其入隊/起線程另行處理,同時調(diào)用IoMarkIrpPending將該IRP標記為Pending,之后即可return STATUS_PENDING。此時該IRP并未真正完成,需待未決的操作在他處完成后調(diào)用IoCompleteRequest才真正完成


            2. 轉發(fā)至下層驅動

            2.1 本層不作處理
            有時對于某些IRP,本層驅動不需要做任何處理。此時可調(diào)用IoSkipCurrentIrpStackLocation跳過當前設備棧,然后調(diào)用IoCallDriver將IRP轉發(fā)至下層驅動,并將轉發(fā)的結果直接返回。此種處理方式并不需要關心下層驅動處理IRP的方式究竟是同步還是異步。IRP轉發(fā)至下層后就與己無關了

            2.2 同步轉發(fā)方式
            有時IRP在本層無法直接處理,需要將其轉發(fā)至下層,待下層處理完后在其結果上進行修改再將其返回(和上面矛盾?)。這時可以采用同步轉發(fā)方式進行處理。首先在相應dispatch routine中初始化一個未激發(fā)的event,調(diào)用IoCopyCurrentIrpStackLocationToNext將本層設備棧參數(shù)復制到下層。然后設置一個CompletionRoutine,將剛才初始化過的event作為context傳給它。之后調(diào)用IoCallDriver轉發(fā)IRP至下層,并判斷返回值是否為STATUS_PENDING是則wait之前的event在CompletionRoutine中判斷該IRP是否PendingReturned,是則說明之前IoCallDriver返回了STATUS_PENDING,于是激發(fā)eventCompletionRoutine返回STATUS_MORE_PROCESSING_REQUIRED使我們的dispatch routine重新取得對該IRP的控制權。本層dispatch等待結束再次獲得控制權后,進行相應處理,之后需再次調(diào)用IoCompleteRequest完成該IRP
            同步轉發(fā)是驅動中常用的一種IRP處理方式。一般會將本層dispatch轉發(fā)IRP至下層并等待CompletionRoutine激發(fā)event的行為獨立成一個ForwardIrpSynchronous的函數(shù)。幾個dispatch只需一個ForwardIrpSynchronous,代碼相對簡單。
            注意不要在本層dispatch中調(diào)用IoMarkIrpPending,因為上層的請求在本層被同步處理了。在同步轉發(fā)中,如果下層驅動也采用同步方式處理,則本層dispatch不會(也不需要)wait,IoCallDriver返回時CompletionRoutine已經(jīng)被調(diào)用,性能上也沒有什么損失。

            2.3 異步轉發(fā)方式
            異步轉發(fā)也能在下層驅動完成IRP時獲得處理的機會,其主要是采用了異步處理機制。首先本層dispatch調(diào)用IoCopyCurrentIrpStackLocationToNext將本層設備棧參數(shù)復制到下層,設置相應的CompletionRoutine,然后調(diào)用IoCallDriver將IRP轉發(fā)至下層驅動,并將轉發(fā)的結果直接return給上層調(diào)用者。在CompletionRoutine中再判斷該IRP是否PendingReturned,是則需要調(diào)用IoMarkIrpPending。之后可對下層驅動處理該IRP的結果進行相應操作。最后返回STATUS_CONTINUE_COMPLETION(同STATUS_SUCCESS)。
            異步轉發(fā)在異步處理時性能最佳,但處理的邏輯放在了CompletionRoutine中,因此多個dispatch需要編寫多個CompletionRoutine。而同步轉發(fā)往往幾個dispatch只需一個ForwardIrpSynchronous即可,代碼相對簡單。


            值得注意的是,各個dispatch routine運行的IRQL是由調(diào)用關系決定的。如果上層調(diào)用者有運行在DISPATCH_LEVEL的可能,則本層的dispatch也需要按照運行在DISPATCH_LEVEL來設計。比如傳遞至本層dispatch的IRP是在上層驅動的StartIO例程中轉發(fā)的,則本層處理該類IRP的代碼就可能運行在DISPATCH_LEVEL。

            posted on 2009-12-30 19:07 小默 閱讀(1069) 評論(0)  編輯 收藏 引用 所屬分類: Windows

            導航

            統(tǒng)計

            留言簿(13)

            隨筆分類(287)

            隨筆檔案(289)

            漏洞

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            久久99精品久久久久久久久久| 亚洲成色999久久网站| 久久高清一级毛片| 婷婷久久综合九色综合九七| 久久人人爽人人人人爽AV| 亚洲国产精品无码久久一区二区| 99精品国产在热久久| 老司机午夜网站国内精品久久久久久久久 | 国产成人无码精品久久久性色| 狠狠综合久久AV一区二区三区| 久久久久久久久无码精品亚洲日韩| 精品综合久久久久久888蜜芽| 久久久91人妻无码精品蜜桃HD| 亚洲va中文字幕无码久久不卡 | 99国产欧美久久久精品蜜芽| 国内精品久久久久久久coent| 日本欧美久久久久免费播放网| 成人精品一区二区久久久| 久久这里只有精品18| 日本精品久久久久影院日本| 久久精品国产亚洲av日韩| 看全色黄大色大片免费久久久| 国产成人精品久久一区二区三区| 精品久久久中文字幕人妻| 亚洲狠狠久久综合一区77777| 久久w5ww成w人免费| 亚洲中文字幕久久精品无码APP| 欧美亚洲日本久久精品| 成人a毛片久久免费播放| AV狠狠色丁香婷婷综合久久| 精品综合久久久久久98| 亚州日韩精品专区久久久| 国产精品狼人久久久久影院| 久久Av无码精品人妻系列| 国产精品美女久久福利网站| 久久天天躁狠狠躁夜夜av浪潮| 青青草原综合久久大伊人精品| 大伊人青草狠狠久久| 久久人妻少妇嫩草AV无码专区| 久久精品国产第一区二区三区| 久久综合给合久久国产免费 |