IRP_MJ_WRITE (FS およびフィルター ドライバー)
送信時
I/O マネージャーまたはファイル システム ドライバーは、IRP_MJ_WRITE リクエストを送信します。 この要求は、たとえば、ユーザー モード アプリケーションが WriteFile などの Win32 関数を呼び出すときや、カーネル モード コンポーネントが 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 内の独自のスタックの場所へのポインターを取得します。 次のパラメーターでは、Irp は IRP を指し、IrpSp は IO_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_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 ルーチンからのものであり、Irp->MdlAddress 内のファイルのキャッシュされたデータを記述する MDL を返します 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 構造体の Information メンバーに返されます。
解説
ファイル システムは、ファイルの終わりでの書き込みおよび読み取り操作を、基礎となるファイル ストレージ デバイスのセクター サイズの倍数まで丸めます。 フィルターがプリスレッド操作またはプリライト操作を処理する場合、バッファーを割り当ておよびスワップするフィルターは、割り当てられたバッファーのサイズを、関連付けられているデバイスのセクター サイズの倍数に切り上げる必要があります。 そうでない場合、基になるファイル システムから転送されるデータの長さが、バッファーの割り当てられた長さを超えています。 バッファのスワップの詳細については、「swapBuffers ミニフィルターのサンプル」を参照してください。
次の箇条書きでは、標準書き込みと IRP ベースの MDL 書き込みについて説明します。
標準書き込みを実行するには:
- 発行者は、MajorFunction = IRP_MJ_WRITE、MinorFunction = IRP_MN_NORMAL (つまり、0) で IRP を構築し、Irp-AssociatedIrp.SystemBuffer> で書き込むデータを提供します。
- IRP をファイル システムに送信する場合、書き込むデータは既に IRP にあります。 したがって、ファイル システムが IRP の処理を完了すると、書き込みが完了します。たとえば、キャッシュされた書き込みのためにバッファーからキャッシュにデータをコピーします。
IRP ベースの MDL 書き込みを実行するには:
- 発行者は、MajorFunction = IRP_MJ_WRITE、MinorFunction = IRP_MN_MDLで IRP を構築しますが、データ バッファーは提供しません。 この IRP をファイル システムに送信します。
- ファイル システムは、MDL を構築し、IRP に配置し、IRP を完了します。
- 発行者はその MDL を使用して、ファイルのキャッシュにデータを直接コピーします。
- 発行者がキャッシュへのデータのコピーを完了すると、MajorFunction = IRP_MJ_WRITE、MinorFunction = (IRP_MN_MDL |IRP_MN_COMPLETE)、ファイル システムに送信します。
- ファイル システムによって MDL が解放され、書き込み操作が完了しました。