存取預先操作回呼常式中的使用者緩衝區
迷你篩選驅動程式 的預先操作回呼常式 應該將 IRP 型 I/O 作業中的緩衝區視為如下所示:
檢查緩衝區是否存在 MDL。 您可以在作業FLT_PARAMETERS的MdlAddress或OutputMdlAddress 參數中找到 MDL指標。 迷你篩選驅動程式可以呼叫 FltDecodeParameters 來查詢 MDL 指標。
取得有效 MDL 的其中一個方法是在回呼資料中尋找 I/O 參數區塊 minorFunction 成員 FLT_IO_PARAMETER_BLOCK的 IRP_MN_MDL旗標。 下列範例示範如何檢查IRP_MN_MDL旗標。
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; if (FlagOn(CallbackData->Iopb->MinorFunction, IRP_MN_MDL)) { ReadMdl = &CallbackData->Iopb->Parameters.Read.MdlAddress; }
不過,只能針對讀取和寫入作業設定IRP_MN_MDL旗標。 最好使用 FltDecodeParameters 來擷取 MDL,因為常式會檢查是否有任何作業的有效 MDL。 在下列範例中,如果有效,則只會傳回 MDL 參數。
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; status = FltDecodeParameters(CallbackData, &ReadMdl, NULL, NULL, NULL);
如果緩衝區存在 MDL,請呼叫 MmGetSystemAddressForMdlSafe 以取得緩衝區的系統位址,然後使用這個位址來存取緩衝區。
從上一個範例繼續,下列程式碼會取得系統位址。
if (*ReadMdl != NULL) { ReadAddress = MmGetSystemAddressForMdlSafe(*ReadMdl, NormalPagePriority); if (ReadAddress == NULL) { CallbackData->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; CallbackData->IoStatus.Information = 0; } }
如果緩衝區沒有 MDL,請使用緩衝區位址來存取緩衝區。 若要確保使用者空間緩衝區位址有效,迷你篩選驅動程式必須使用ProbeForRead或ProbeForWrite等常式,並在try/ 中封入所有緩衝區參考,但區塊除外。
預先操作回呼常式應該在快速 I/O 作業中處理緩衝區,如下所示:
使用緩衝區位址來存取緩衝區 (,因為快速 I/O 作業不能有 MDL) 。
若要確保使用者空間緩衝區位址有效,迷你篩選驅動程式必須使用ProbeForRead或ProbeForWrite等常式,並在try/ 中封入所有緩衝區參考,但區塊除外。
對於可以是快速 I/O 或 IRP 架構的作業,所有緩衝區參考都應該包含在try/中,但區塊除外。 雖然您不需要針對使用緩衝 I/O 的 IRP 型作業括住這些參考,但區塊除外的嘗試/ 是安全的預防措施。