共用方式為


存取預先操作回呼常式中的使用者緩衝區

迷你篩選驅動程式 的預先操作回呼常式 應該將 IRP 型 I/O 作業中的緩衝區視為如下所示:

  • 檢查緩衝區是否存在 MDL。 您可以在作業FLT_PARAMETERSMdlAddressOutputMdlAddress 參數中找到 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,請使用緩衝區位址來存取緩衝區。 若要確保使用者空間緩衝區位址有效,迷你篩選驅動程式必須使用ProbeForReadProbeForWrite等常式,並在try/ 中封入所有緩衝區參考,但區塊除外

預先操作回呼常式應該在快速 I/O 作業中處理緩衝區,如下所示:

  • 使用緩衝區位址來存取緩衝區 (,因為快速 I/O 作業不能有 MDL) 。

  • 若要確保使用者空間緩衝區位址有效,迷你篩選驅動程式必須使用ProbeForReadProbeForWrite等常式,並在try/ 中封入所有緩衝區參考,但區塊除外

對於可以是快速 I/O 或 IRP 架構的作業,所有緩衝區參考都應該包含在try/中,但區塊除外。 雖然您不需要針對使用緩衝 I/O 的 IRP 型作業括住這些參考,但區塊除外的嘗試/ 是安全的預防措施。