共用方式為


MmLockPagableCodeSection 巨集 (wdm.h)

MmLockPagableCodeSection 例程鎖定驅動程式程式代碼的區段,其中包含一組以特殊編譯程式指示詞標示的驅動程式例程,進入系統空間。

語法

void MmLockPagableCodeSection(
  [in]  Address
);

參數

[in] Address

指定符號位址。 此位址通常是驅動程式程式代碼區段中的驅動程式函式名稱,其已標示為 #pragma alloc_text (PAGExxxx, driverfunction)。 當此函式傳回時,保證 PAGExxxx 區段中的所有函式都會遭到鎖定。

傳回值

沒有

言論

MmLockPagableCodeSection 會傳回作系統用來識別驅動程式程式代碼這一節的不透明值。 這個不透明的值後續可以傳遞至 MmLockPagableSectionByHandle (如果驅動程式解除鎖定,然後重新鎖定區段),或 MmUnlockPagableImageSection

MmLockPagableCodeSection 例程和 MmUnlockPagableImageSection (執行相反動作的例程) 支援可以執行下列動作的驅動程式:

  • 延遲將驅動程式例程子集載入常駐記憶體,直到驅動程式裝置的傳入 I/O 要求,才需要這些例程來處理 IRP。

  • 讓相同的驅動程式例程子集在完成 I/O 要求處理後可供分頁使用,而且目前不會預期驅動程式裝置的其他要求。

mmLockPagableCodeSectionmmLockPagableSectionByHandleMmUnlockPagableImageSection 適用於具有下列特性的裝置和中繼驅動程式:

  • 驅動程式具有在執行系統時可能不需要的程式代碼路徑,但如果需要,驅動程式的程式代碼必須常駐,因為它會在任意線程內容中執行,或在 IRQL >= DISPATCH_LEVEL。

  • 驅動程式可以確切判斷何時應該載入可分頁的例程,以及何時可以再次分頁。

例如,系統提供的容錯磁碟驅動器支援建立鏡像集、等量集和磁碟區集。 然而,特定計算機只能使用鏡像集進行設定,只有等量集、只有磁碟區集,或這三個可能選項的任意組合。 在這些情況下,系統 ftdisk 驅動程式會將明確支援鏡像、等量和磁碟區集的例程標示為屬於可分頁程式代碼區段,以減少其載入影像的大小。 在驅動程式初始化期間,只有當使用者已將磁碟設定為具有鏡像、等量或磁碟區集時,才能將可分頁的程式代碼區段設為常駐。 如果用戶動態重新分割磁碟,ftdisk 驅動程式會鎖定支持使用者要求的任何鏡像、等量或磁碟區集所需的任何其他可分頁程式代碼區段。

與其他範例一樣,系統提供的序列和平行驅動程式具有 DispatchCreateDispatchClose 例程,這些例程會在特定埠開啟時分別針對獨佔 I/O 開啟,以及開啟之埠的句柄發行時呼叫。 然而,序列和平行 I/O 要求是零星的,取決於使用者目前正在執行的應用程式,以及使用者目前正在執行的應用程式選項。 在這些情況下,系統序列和平行驅動程式會將許多例程標示為屬於可分頁程式代碼區段,讓 DispatchCreate 例程只有在第一個埠為 I/O 開啟時,才會使居民化映射的大小。

請注意,上述每個系統驅動程式都滿足兩個可分頁區段的準則:驅動程式具有在執行系統時可能不需要的程式代碼路徑,而驅動程式可以確切判斷其可分頁區段何時應該載入,而且可以再次分頁。

由於鎖定區段是昂貴的作業,因此,如果驅動程式在多個位置鎖定可分頁的程式代碼區段,請針對第一個要求使用 MmLockPagableCodeSection。 呼叫 MmLockPagableSectionByHandle 傳遞 MmLockPagableCodeSection所傳回的句柄,以提出後續鎖定要求。 透過句柄鎖定可大幅改善驅動程式效能,因為記憶體管理員會使用不透明的傳回值來快速找出相關的區段,而不是搜尋載入的模組清單。 呼叫 MmUnlockPagableImageSection來解除鎖定區段。

可分頁程式代碼區段中的每個驅動程式例程都必須以下列編譯程式指示詞標示:

#pragma alloc_text(PAGExxxx, DriverRoutine)

其中 xxxx 是呼叫端可分頁區段的選擇性四個字元、唯一標識符,DriverRoutine 是可分頁程式代碼區段中要包含的進入點。 關鍵詞 PAGE 和驅動程序決定後置詞,最多可有四個字元,會區分大小寫:也就是說,PAGE 必須大寫。

例如,MmLockPagableCodeSection 的單一呼叫,例如,驅動程式的 DispatchCreate 例程,會導致整個區段,其中包含標示為相同 PAGExxxx 標識符的每個驅動程式例程,都會鎖定在系統空間中。

某些類型的驅動程式例程不能成為任何驅動程式可分頁區段的一部分,包括:

  • 永遠不要讓ISR可分頁。 即使裝置裝置未使用,設備驅動器還是可能會收到假斷,特別是當中斷向量可以共享時。 一般而言,即使驅動程式可以明確停用其裝置上的中斷,ISR 不應該設為可分頁。

  • 如果驅動程式無法控制 DPC 已排入佇列,例如任何 DpcForIsrCustomDpc 可能從 ISR 排入佇列的例程,永遠不要讓 DPC 例程成為可分頁。 一般而言,在 IRQL >= DISPATCH_LEVEL 執行的驅動程式例程,而且可以在任意線程內容中呼叫或回應隨機外部事件,不應設為可分頁。

  • 請勿在任何可能屬於系統分頁 I/O 路徑的驅動程式中,將 DispatchReadDispatchWrite 例程分頁。 可能包含系統頁面檔案的磁碟驅動程序必須具有 dispatchRead ,且 DispatchWrite 系統執行時常駐的例程,如同在這類磁碟驅動程式上方分層的所有驅動程式一樣。

請注意,以編譯程式指示詞標記的可分頁區段中例程 #pragma alloc_text(PAGExxxx, ...) 與以編譯程式指示詞標示的例程 #pragma alloc_text(INIT, ...)不同。INIT 區段中的例程無法分頁,而且只要驅動程式從 DriverEntry 傳回 或其 重新初始化 例程,就會立即捨棄。

記憶體管理員會在任何驅動程式的可分頁區段上維護內部鎖定計數。 呼叫 mmLockPagableCodeSection 遞增此計數,且遞減計數 mmUnlockPagableImageSection 遞減計數。 除非此計數為零,否則無法分頁驅動程式的可分頁區段。

如需建立可分頁程式代碼區段的詳細資訊,請參閱 讓驅動程式可分頁

要求

要求 價值
目標平臺 桌面
標頭 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
連結庫 NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <=APC_LEVEL

另請參閱

mmLockPagableDataSection

mmLockPagableSectionByHandle

mmPageEntireDriver

mmResetDriverPaging

mmUnlockPagableImageSection