MmGetSystemAddressForMdlSafe 函式 (wdm.h)

MmGetSystemAddressForMdlSafe 宏會傳回指定 MDL 所描述之緩衝區的非分頁系統空間虛擬位址。

語法

PVOID MmGetSystemAddressForMdlSafe(
  [in] PMDL  Mdl,
  [in] ULONG Priority
);

參數

[in] Mdl

緩衝區的指標,其對應的基底虛擬位址要對應。

[in] Priority

指定 MM_PAGE_PRIORITY 值,指出在低可用 PTE 條件下成功的重要性。 指定 LowPagePriority、NormalPagePriorityHighPagePriority 的優先順序值。 從 Windows 8 開始,指定的優先順序值可以是具有 MdlMappingNoWriteMdlMappingNoExecute 旗標的位 ORed。

  • LowPagePriority 表示如果系統對資源相當低,對應要求可能會失敗。 這種情況的範例是驅動程式可以處理對應失敗的非關鍵網路連線。

  • NormalPagePriority 表示如果系統對資源而言非常低,對應要求可能會失敗。 這種情況的範例是非關鍵本機文件系統要求。

  • HighPagePriority 表示除非系統完全不在資源外,否則對應要求不得失敗。 這種情況的範例是驅動程式中的分頁檔案路徑。

  • MdlMappingNoWrite 表示對應的實體頁面設定為無寫入 (只讀) 記憶體。 從 Windows 8 開始,此旗標位可以是位 ORed,其具有MM_PAGE_PRIORITY值,以指定停用寫入的記憶體。

  • MdlMappingNoExecute 指出對應的實體頁面要設定為無執行記憶體。 從 Windows 8 開始,這個旗標位可以是位 ORed,具有MM_PAGE_PRIORITY值來指定停用指令執行的記憶體。 最佳做法是,除非明確需要可執行記憶體,否則針對 Windows 8 和更新版本的 Windows 所撰寫的驅動程式應該一律指定無執行記憶體。

傳回值

MmGetSystemAddressForMdlSafe 會傳回基底系統空間虛擬位址,對應指定 MDL 所描述的實體頁面。 如果頁面尚未對應至系統地址空間,且嘗試對應頁面失敗,則會傳回 NULL

備註

如果指定的 MDL 尚未對應至系統地址空間,此例程會將指定的 MDL 所描述的實體頁面對應至系統地址空間。

程序設計 I/O (PIO) 裝置的驅動程式會呼叫此例程來對應使用者模式緩衝區,該緩衝區是由 Irp-MdlAddress> 上的 MDL 所描述,且已對應至使用者模式虛擬位址範圍,並對應至系統地址空間中的範圍。

在進入此例程時,指定的 MDL 必須描述鎖定的實體頁面。 您可以使用 MmProbeAndLockPagesMmBuildMdlForNonPagedPoolIoBuildPartialMdlMmAllocatePagesForMdlEx 例程來建置鎖定的 MDL。

當不再需要 MmGetSystemAddressForMdlSafe 所傳回的系統地址空間對應時,必須釋放它。 釋放對應所需的步驟取決於 MDL 的建置方式。 以下是四種可能的情況:

  • 如果 MDL 是由呼叫 MmProbeAndLockPages 例程所建置,就不需要明確釋放系統地址空間對應。 相反地,如果已配置 對應,則呼叫 MmUnlockPages 例程會釋放對應。

  • 如果 MDL 是由呼叫 MmBuildMdlForNonPagedPool 例程所建置, MmGetSystemAddressForMdlSafe 會重複使用現有的系統地址空間對應,而不是建立新的對應。 在此情況下,不需要清除 (也就是解除鎖定和取消對應) 。

  • 如果 MDL 是由呼叫 IoBuildPartialMdl 例程所建置,驅動程式必須呼叫 MmPrepareMdlForReuse 例程或 IoFreeMdl 例程來釋放系統地址空間對應。

  • 如果 MDL 是由呼叫 MmAllocatePagesForMdlEx 例程所建置,驅動程式必須呼叫 MmUnmapLockedPages 例程來釋放系統地址空間對應。 如果 MDL 呼叫 MmGetSystemAddressForMdlSafe 多次,後續 的 MmGetSystemAddressForMdlSafe 呼叫只會傳回第一次呼叫所建立的對應。 呼叫 MmUnmapLockedPages 就足以釋放此對應。

從 Windows 7 和 Windows Server 2008 R2 開始,就不需要針對 MmAllocatePagesForMdlEx 所建立的 MDL 明確呼叫 MmUnmapLockedPages。 相反地,如果已配置系統地址空間對應, 則呼叫 MmFreePagesFromMdl 例程會釋放系統地址空間對應。

若要建立新的系統地址空間對應, MmGetSystemAddressForMdlSafe 會呼叫 MmMapLockedPagesSpecifyCache ,並將 CacheType 參數設定為 MmCached。 需要 MmCached 以外的快取類型的驅動程式應該直接呼叫 MmMapLockedPagesSpecifyCache ,而不是呼叫 MmGetSystemAddressForMdlSafe。 如需 CacheType 參數的詳細資訊,請參閱 MmMapLockedPagesSpecifyCache

在呼叫 MmMapLockedPagesSpecifyCache 時,只有在 MDL 所描述的頁面還沒有與其相關聯的快取類型時,才會使用指定的快取類型。 不過,在幾乎所有情況下,頁面已經有相關聯的快取類型,而新的對應會使用此快取類型。 此規則的例外狀況是 MmAllocatePagesForMdl 所配置的頁面,不論頁面的原始快取類型為何,都會將快取類型設定為 MmCached

一次只能有一個線程安全地呼叫特定 MDL 的 MmGetSystemAddressForMdlSafe ,因為此例程假設呼叫線程擁有 MDL。 不過, MmGetSystemAddressForMdlSafe 可以透過從同一個線程進行所有呼叫來呼叫同一個 MDL 多次,或者,如果呼叫來自多個線程,請明確同步處理呼叫。

如果驅動程式必須將要求分割成較小的要求,驅動程式可以配置額外的 MDL,或者驅動程式可以使用 IoBuildPartialMdl 例程。

傳回的基位址與 MDL 中的虛擬位址位移相同。

Windows 98 不支援 MmGetSystemAddressForMdlSafe。 請改用 MmGetSystemAddressForMdl

由於此宏會呼叫 MmMapLockedPagesSpecifyCache,因此使用它可能需要連結到 NtosKrnl.lib。

規格需求

需求
最低支援的用戶端 Windows 2000
標頭 wdm.h
IRQL <= DISPATCH_LEVEL
DDI 合規性規則 MdlAfterReqCompletedIntIoctlA (kmdf) MdlAfterReqCompletedIoctlA (kmdf) MdlAfterReqCompletedReadA (kmdf) MdlAfterReqCompletedWriteA (kmdf)