驅動中PAGED_CODE的作用

功能:這個宏可以確保調用線程運行在一個允許分頁的足夠低IRQL級別。

參數: 無參數

返回值: 無

注意:
如果IRQL > APC_LEVEL,則PAGED_CODE()會對系統產生一個斷言。

1.這個宏的調用必須在驅動程序開始位置,並且包含可分頁代碼或者可訪問分頁代碼

2.這個宏定義只在驅動代碼執行宏時檢查IRQL,如果此宏之後提高 IRQL等級 ,將無法檢測改變。

3.必須使用其它 Static Driver Verifier 和Driver Verifier去檢測等級,當IRQL在不適當的時候被提升 

4.此宏定義只在checked builds.版本中運行

簡而言之,Windows並沒有將運行在Ring 0的代碼全部視爲內核,而是區分爲Kernel和Executive,Executive可以理解爲“管理層”的意思,解釋爲“執行體”不合理。

其中,Kernel是狹義的內核,裏面的代碼包括用到的數據,都是常駐在物理內存中的,不支持分頁機制。

而除此之外的代碼和數據,是支持分頁機制的,並且可以被交換到pagefile中,即並非總是在物理內存中的。

 

對於驅動來說,應該屬於後者,因此在驅動中的函數的頭部都會使用PAGED_CODE來判斷一下,

#define PAGED_CODE() PAGED_ASSERT(KeGetCurrentIrql() <= APC_LEVEL);

 
  1. #define PASSIVE_LEVEL 0 // Passive release level

  2. #define LOW_LEVEL 0 // Lowest interrupt level

  3. #define APC_LEVEL 1 // APC interrupt level

  4. #define DISPATCH_LEVEL 2 // Dispatcher level

  5. #define CMCI_LEVEL 5 // CMCI handler level

  6.  
  7. #define PROFILE_LEVEL 27 // timer used for profiling.

  8. #define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86

  9. #define CLOCK2_LEVEL 28 // Interval clock 2 level

  10. #define IPI_LEVEL 29 // Interprocessor interrupt level

  11. #define POWER_LEVEL 30 // Power failure level

  12. #define HIGH_LEVEL 31 // Highest interrupt level

  13.  
  14. #define CLOCK_LEVEL (CLOCK2_LEVEL)

如果當前的中斷請求級別(IRQL)太高(DPC以上),那麼很可能屬於Kernel部分,因此需要避免這種情況。

發佈了875 篇原創文章 · 獲贊 301 · 訪問量 255萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章