IRP_MJ_WRITE (FS 與篩選驅動程式 )

傳送時

I/O 管理員或文件系統驅動程式會傳送IRP_MJ_WRITE要求。 例如,當使用者模式應用程式呼叫 Win32 函式,例如 WriteFile 或內核模式元件呼叫 ZwWriteFile 時,可以傳送此要求。

作業:檔案系統驅動程式

文件系統驅動程式應該擷取和譯碼檔案物件,以判斷參數和次要函式程序代碼。

針對 MDL 寫入要求,文件系統應該檢查次要函式程式代碼,以判斷要求的作業。 以下是有效的次要函式程序代碼,只能用於快取的檔案 I/O:

  • IRP_MN_COMPLETE
  • IRP_MN_COMPLETE_MDL
  • IRP_MN_COMPLETE_MDL_DPC
  • IRP_MN_COMPRESSED
  • IRP_MN_DPC
  • IRP_MN_MDL
  • IRP_MN_MDL_DPC
  • IRP_MN_NORMAL

如需如何處理此 IRP 的詳細資訊,請研究 Windows 驅動程式套件 (WDK) 中包含的 FASTFAT 範例。

作業:舊版文件系統篩選驅動程式

篩選驅動程式應該執行任何必要的處理,並根據篩選的性質執行下列其中一個動作:

  • 完成或失敗 IRP,或
  • 將 IRP 向下傳遞至堆疊上的下一個較低驅動程式。

參數

文件系統或篩選驅動程式會針對指定的 IRP 呼叫 IoGetCurrentIrpStackLocation ,以取得 IRP 中自己堆疊位置的指標。 在下列參數中,Irp 指向 IRP,而 IrpSp 指向IO_STACK_LOCATION。 驅動程式可以使用下列 IRP 成員和 IRP 堆疊位置中設定的資訊來處理建立要求:

  • DeviceObject 是目標裝置物件的指標。

  • 如果 deviceObject-Flags> 中設定了DO_BUFFERED_IO旗標,Irp-AssociatedIrp.SystemBuffer> 會指向系統提供的緩衝區作為中繼系統緩衝區。 否則,這個成員會設定為 NULL

  • Irp-IoStatus> 指向IO_STATUS_BLOCK結構,該結構會接收最終完成狀態和所要求作業的相關信息。 如果IRP_MJ_WRITE要求失敗,文件系統的寫入分派例程會傳回錯誤 NTSTATUS 值,而且 Irp-IoStatus.Information> 的值未定義且不應該使用。

  • Irp-MdlAddress> 是記憶體描述元清單 (MDL) 的位址,描述要寫入數據的頁面。

  • IrpSp-FileObject> 指向與 DeviceObject 相關聯的檔案物件。 如果在 IrpSp-FileObject-Flags>>設定了FO_SYNCHRONOUS_IO旗標,則會針對同步 I/O 開啟檔案物件。

    IrpSp-FileObject> 參數包含 RelatedFileObject 字段的指標,這也是FILE_OBJECT結構。 FILE_OBJECT 結構的 RelatedFileObject 字段在處理IRP_MJ_WRITE期間無效,因此不應該使用。

  • IrpSp-Flags>:如果已設定SL_FORCE_DIRECT_WRITE旗標,核心模式驅動程式可以寫入通常無法寫入的磁碟區區域,因為直接寫入封鎖。 直接寫入封鎖是在 Windows Vista 和更新版本的作業系統中基於安全性考慮而實作的。 在檔案系統層和儲存堆疊層檢查此旗標。 如需直接寫入封鎖的詳細資訊,請參閱 封鎖磁碟區和磁碟的直接寫入作業。 SL_FORCE_DIRECT_WRITE旗標適用於 Windows Vista 和更新版本的 Windows。

  • IrpSp-MajorFunction> 設定為 IRP_MJ_WRITE。

  • IrpSp-MinorFunction> 會指定所要求的作業,並包含下列其中一個值。 如果未指定次要函式程式代碼,則作業是標準寫入(相當於IRP_MN_NORMAL)。

    MinorFunction 描述
    IRP_MN_NORMAL 寫入要求適用於標準寫入作業
    IRP_MN_DPC 寫入要求來自 DPC 例程
    IRP_MN_MDL 會傳回描述 Irp-MdlAddress>檔案快取數據的 MDL;呼叫端會使用此 MDL 直接將數據寫入快取
    IRP_MN_COMPLETE 本身未使用;只會與至少IRP_MN_MDL一起發生。 請參閱<備註>。
    IRP_MN_COMPRESSED 寫入要求適用於壓縮檔案
    IRP_MN_MDL_DPC 寫入要求來自 DPC 例程,並傳回 MDL,描述 Irp-MdlAddress> 中檔案的快取數據
    IRP_MN_COMPLETE_MDL 表示使用 MDL 直接將數據寫入快取的呼叫端,使用 MDL 完成
    IRP_MN_COMPLETE_MDL_DPC 表示使用 MDL 直接將數據寫入快取的呼叫端,使用 MDL 完成;寫入要求來自 DPC 例程
  • IrpSp-Parameters.Write.ByteOffset> 是LARGE_INTEGER變數,指定要寫入之數據檔案內的起始位移。

    在某些情況下,此參數可能包含特殊值。 例如,當為 true 時,下列條件表示應該使用目前的檔尾,而不是明確的檔案位移值:IrpSp-Parameters.Write.ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE 和 IrpSp-Parameters.Write.ByteOffset.HighPart>> == -1

  • IrpSp-Parameters.Write.Key> 是與目標檔案上位元組範圍鎖定相關聯的索引鍵 值。

  • IrpSp-Parameters.Write.Length> 是要寫入之數據的位元組長度。 如果寫入作業成功,則會在 Irp-IoStatus>指向之IO_STATUS_BLOCK結構的信息成員中傳回寫入的位元組數目。

備註

文件系統會在檔尾四捨五入寫入和讀取作業,最多可達基礎檔案儲存裝置的多個扇區大小。 當篩選處理預先讀取或預先寫入作業時,配置和交換緩衝區的篩選需要將配置緩衝區的大小四捨五入到相關聯裝置的扇區大小倍數。 如果沒有,從基礎文件系統傳輸的數據長度超過緩衝區的配置長度。 如需交換緩衝區的詳細資訊,請參閱 swapBuffers Minifilter 範例

下列項目符號描述標準寫入與 IRP 型 MDL 寫入:

  • 若要執行標準寫入:

    1. 簽發者會建構具有 MajorFunction = IRP_MJ_WRITE、MinorFunction = IRP_MN_NORMAL (也就是 0) 的 IRP,並提供在 Irp-AssociatedIrp.SystemBuffer>寫入的數據。
    2. 當他們將 IRP 傳送至文件系統時,要寫入的數據已經位於 IRP 中。 因此,當文件系統完成處理 IRP 時,寫入就會完成;例如,將數據從緩衝區複製到快取寫入的快取。
  • 若要執行以 IRP 為基礎的 MDL 寫入:

    1. 簽發者會建構具有MajorFunction = IRP_MJ_WRITE、MinorFunction = IRP_MN_MDL 但未提供數據緩衝區的 IRP。 他們會將此 IRP 傳送至文件系統。
    2. 文件系統會建構 MDL、將它放在 IRP 中,然後完成 IRP。
    3. 簽發者使用該 MDL 將數據直接複製到檔案的快取中。
    4. 當簽發者將數據複製到快取時,會建構另一個具有 MajorFunction = IRP_MJ_WRITE、 MinorFunction = (IRP_MN_MDL |IRP_MN_COMPLETE)並將該檔案傳送至文件系統。
    5. 文件系統會釋放 MDL,而寫入作業現在已完成。

另請參閱

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE (WDK 核心參考)

ZwWriteFile