MmGetSystemAddressForMdlSafe 函式 (wdm.h)
MmGetSystemAddressForMdlSafe 巨集會傳回指定 MDL 所描述之緩衝區的非分頁系統空間虛擬位址。
語法
PVOID MmGetSystemAddressForMdlSafe(
[in] PMDL Mdl,
[in] ULONG Priority
);
參數
[in] Mdl
對應基底虛擬位址要對應的緩衝區指標。
[in] Priority
指定 MM_PAGE_PRIORITY 值,指出在低可用 PTE 條件下成功的重要性。 指定 LowPagePriority、NormalPagePriority或 HighPagePriority的優先順序值。 從 Windows 8 開始,指定的優先順序值可以是 bitwise-ORed 與 MdlMappingNoWrite 或 MdlMappingNoExecute 旗標。
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 必須描述鎖定的實體頁面。 您可以使用 MmProbeAndLockPages、MmBuildMdlForNonPagedPool、IoBuildPartialMdl或 MmAllocatePagesForMdlEx 例程來建置鎖定的 MDL。
不再需要 MmGetSystemAddressForMdlSafe 所傳回的系統地址空間對應時,必須釋放它。 發行對應所需的步驟取決於 MDL 的建置方式。 以下是四種可能的情況:
如果 MDL 是由呼叫 MmProbeAndLockPages 例程所建置,就不需要明確釋放系統地址空間對應。 相反地,如果已配置對應,則呼叫 MmUnlockPages 例程會釋放對應。
如果 MDL 是由呼叫 MmBuildMdlForNonPagedPool 例程所建置,MmGetSystemAddressForMdlSafe 重複使用現有的系統地址空間對應,而不是建立新的對應。 在此情況下,不需要清除 (也就是說,不需要解除鎖定和取消對應)。
如果 MDL 是由呼叫 IoBuildPartialMdl 例程所建置,則驅動程式必須呼叫 MmPrepareMdlForReuse 例程或 IoFreeMdl 例程來釋放系統地址空間對應。
如果 MDL 是由呼叫 MmAllocatePagesForMdlEx 例程所建置,驅動程式必須呼叫 MmUnmapLockedPages 例程來釋放系統地址空間對應。 如果 MmGetSystemAddressForMdlSafe MDL 多次呼叫,則後續 MmGetSystemAddressForMdlSafe 呼叫只會傳回第一次呼叫所建立的對應。 MmUnmapLockedPages 的呼叫就足以釋放此對應。
從 Windows 7 和 Windows Server 2008 R2 開始,就不需要明確呼叫 MmUnmapLockedPagesMmAllocatePagesForMdlEx所建立的 MDL。 相反地,呼叫 MmFreePagesFromMdl 例程會釋放系統地址空間對應,如果已配置系統地址空間對應。
若要建立新的系統地址空間對應,MmGetSystemAddressForMdlSafe 呼叫 MmMapLockedPagesSpecifyCache,並將 CacheType 參數設定為 mmCached。 需要 MmCached 以外的快取類型的驅動程式,應該直接呼叫 MmMapLockedPagesSpecifyCache,而不是直接呼叫 MmGetSystemAddressForMdlSafe。 如需 CacheType 參數的詳細資訊,請參閱 MmMapLockedPagesSpecifyCache。
在呼叫 MmMapLockedPagesSpecifyCache時,只有在 MDL 所描述的頁面還沒有與其相關聯的快取類型時,才會使用指定的快取類型。 不過,在幾乎所有情況下,頁面已經有相關聯的快取類型,而且新對應會使用此快取類型。 此規則的例外狀況是,不論頁面的原始快取類型為何,MmAllocatePagesForMdl配置的頁面,會將快取類型設定為 MmCached。
一次只能有一個線程安全地呼叫 MmGetSystemAddressForMdlSafe 特定 MDL,因為這個例程假設呼叫線程擁有 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) |