功能:這個宏可以確保調用線程運行在一個允許分頁的足夠低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);
-
#define PASSIVE_LEVEL 0 // Passive release level
-
#define LOW_LEVEL 0 // Lowest interrupt level
-
#define APC_LEVEL 1 // APC interrupt level
-
#define DISPATCH_LEVEL 2 // Dispatcher level
-
#define CMCI_LEVEL 5 // CMCI handler level
-
#define PROFILE_LEVEL 27 // timer used for profiling.
-
#define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86
-
#define CLOCK2_LEVEL 28 // Interval clock 2 level
-
#define IPI_LEVEL 29 // Interprocessor interrupt level
-
#define POWER_LEVEL 30 // Power failure level
-
#define HIGH_LEVEL 31 // Highest interrupt level
-
#define CLOCK_LEVEL (CLOCK2_LEVEL)
如果當前的中斷請求級別(IRQL)太高(DPC以上),那麼很可能屬於Kernel部分,因此需要避免這種情況。