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 Driver Kit (WDK) に含まれている FASTFAT サンプルを参照してください。

操作: レガシー ファイル システム フィルター ドライバー

フィルター ドライバーは必要な処理を実行し、フィルターの性質に応じて次のアクションのいずれかを実行する必要があります。

  • IRP を完了するか失敗するか、または
  • IRP をスタック上の 1 つ下のドライバーに渡します。

パラメーター

ファイル システムまたはフィルター ドライバーは、指定された IRP で IoGetCurrentIrpStackLocation を呼び出して、IRP 内の独自のスタックの場所へのポインターを取得します。 次のパラメーターでは、IrpIRP を指し、IrpSpIO_STACK_LOCATION を指します。 ドライバーは、IRP の次のメンバーと IRP スタックの場所に設定されている情報を使用して、作成要求を処理できます。

  • DeviceObject ターゲット デバイス オブジェクトへのポインターです。

  • Irp->AssociatedIrp.SystemBuffer は、DO_BUFFERED_IO フラグが DeviceObject->Flags で設定されている場合、中間システム バッファーとして使用されるシステム提供のバッファーを指します。 それ以外の場合、このメンバーは NULL に設定されます。

  • Irp->Ioステータス は、最終的な完了ステータスと要求された操作に関する情報を受け取る IO_STATUS_BLOCK構造体を指します。 IRP_MJ_WRITE リクエストが失敗した場合、ファイル システムの書き込みディスパッチ ルーチンはエラー NTSTATUS 値を返します。Irp->IoStatus.Information の値は未定義なので使用しないでください。

  • Irp->MdlAddress はデータが書き込まれるページを記述するメモリ記述子リスト (MDL) のアドレスです。

  • IrpSp->FileObject は、DeviceObject に関連付けられているファイル オブジェクトを指します。 FO_SYNCHRONOUS_IO フラグが IrpSp->FileObject->Flags で設定されている場合、ファイル オブジェクトは同期 I/O 用に開かれています。

    IrpSp->FileObject パラメーターには、FILE_OBJECT構造体でもある RelatedFileObject フィールドへのポインターが含まれています。 FILE_OBJECT 構造体の RelatedFileObject フィールドは、IRP_MJ_WRITE の処理中は無効であるため、使用しないでください。

  • IrpSp->フラグ: SL_FORCE_DIRECT_WRITE フラグが設定されている場合、カーネル モード ドライバーは、直接書き込みブロックのために通常は書き込めないボリューム領域に書き込むことができます。 Windows Vista 以降のオペレーティング システムでは、セキュリティ上の理由から直接書き込みブロックが実装されました。 このフラグは、ファイル システム層とストレージ スタック層の両方でチェックされます。 直接書き込みブロックの詳細については、「ボリュームおよびディスクへの直接書き込み操作のブロック」を参照してください。 SL_FORCE_DIRECT_WRITE フラグは、Windows Vista 以降のバージョンの Windows で使用できます。

  • IrpSp->MajorFunction は IRP_MJ_WRITE に設定されます。

  • IrpSp->MinorFunction 要求される操作を指定し、次のいずれかを含みます。

    • 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
  • 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 構造体の Information メンバーに返されます。

解説

ファイル システムは、ファイルの終わりでの書き込みおよび読み取り操作を、基礎となるファイル ストレージ デバイスのセクター サイズの倍数まで丸めます。 フィルターが事前読み取りまたは事前書き込み操作を処理する場合、バッファーの割り当てと交換を行うフィルターは、割り当てられたバッファーのサイズを、関連するデバイスのセクター サイズの倍数に切り上げる必要があります。 そうしないと、基盤となるファイル システムから転送されるデータの長さが、割り当てられたバッファの長さを超えてしまいます。 バッファのスワップの詳細については、「swapBuffers ミニフィルターのサンプル」を参照してください。

関連項目

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE (WDK カーネル リファレンス)

ZwWriteFile