Share via


ファイル ストリーム、ストリーム コンテキスト、ストリーム別コンテキスト

Note

最適な信頼性とパフォーマンスを実現するには、レガシ ファイル システム フィルター ドライバーではなく、フィルター マネージャーのサポートがあるファイル システム ミニフィルター ドライバーを使用します。 レガシ ドライバーをミニフィルター ドライバーに移植するには、「レガシ フィルター ドライバーの移植ガイドライン」を参照してください。

ファイル ストリームは、ファイル データを保持するために使用されるバイトのシーケンスです。 通常、ファイルに含まれるファイル ストリームは 1 つだけです。具体的には、ファイルの既定のデータ ストリームです。 ただし、複数のデータ ストリームをサポートするファイル システムでは、各ファイルに複数のファイル ストリームを含めることができます。 これらのストリームの 1 つは、名前のない既定のデータ ストリームです。 その他は代替データ ストリームという名前です。 ファイルを開くと、実際にはそのファイルのストリームが開きます。

ファイル システムは初めてファイル ストリームを開く際、ファイル システム固有のストリーム コンテキスト構造体 (ファイル制御ブロック (FCB) やストリーム制御ブロック (SCB) など) を作成し、この構造体のアドレスを生成されるファイル オブジェクトの FsContext メンバーに格納します。

ローカル ファイル システムでは、既に開いているファイル ストリームを再度開いた場合 (共有読み取りアクセスなどのために)、I/O サブシステムは別のファイル オブジェクトを作成しますが、ファイル システムによって新しいストリーム コンテキストが作成されることはありません。 両方のファイル オブジェクトが、同じストリーム コンテキスト構造体のアドレスを受け取ります。 したがって、ローカル ファイル システムの場合、ストリーム コンテキスト ポインターはファイル ストリームを一意に識別します。

ストリーム別コンテキストをサポートするネットワーク ファイル システムで、既に開いているファイル ストリームを同じネットワーク共有名または IP アドレスを使用して再度開く場合の動作は、ローカル ファイル システムの動作と同じです。 I/O サブシステムは新しいファイル オブジェクトを作成しますが、ファイル システムは新しいストリーム コンテキストを作成しません。 代わりに、両方のファイル オブジェクトに同じ FsContext ポインター値を割り当てます。 ただし、異なるパス (たとえば、別の共有名や、以前に共有名を使用して開かれたファイルの IP アドレス) を使用してファイル ストリームを開いた場合、ファイル システムは新しいストリーム コンテキストを作成します。 したがって、ストリーム別コンテキストをサポートするネットワーク ファイル システムの場合、FsContext ポインターはファイル ストリームを一意に識別しません。

ストリーム別コンテキストは、メンバーの 1 つとして FSRTL_PER_STREAM_CONTEXT 構造体を含むフィルター定義の構造体です。 フィルター ドライバーはこの構造体を使用して、ファイル システムが開く各ファイル ストリームに関する情報を追跡します。

ストリーム別コンテキストに対するファイル システムのサポート

Windows XP 以降では、ストリーム別コンテキストをサポートするファイル システムは FSRTL_ADVANCED_FCB_HEADER 構造体を含むストリーム コンテキスト構造体を使用する必要があります。

ファイル システムは、特定のファイル ストリームに関連付けられているストリーム別コンテキストのグローバル リストを所有します。 ファイル システムは、ファイル ストリームの新しいストリーム コンテキスト (FSRTL_ADVANCED_FCB_HEADER オブジェクト) を作成するときに、このリストを初期化するための FsRtlSetupAdvancedHeader を呼び出します。 レガシ ファイル システム フィルター ドライバーが FsRtlInsertPerStreamContext を呼び出すと、フィルターによって作成されたストリーム別コンテキストがグローバル リストに追加されます。

ファイル システムはファイル ストリームのストリーム コンテキストを削除するときに、FsRtlTeardownPerStreamContexts を呼び出して、フィルターがファイル ストリームに関連付けたすべてのストリーム別コンテキストを解放します。 このルーチンは、グローバル リスト内のストリーム別コンテキストごとに FreeCallback ルーチンを呼び出します。 FreeCallback ルーチンでは、ファイル ストリームのファイル オブジェクトが既に解放されていると想定する必要があります。

ファイル システムが特定のファイル オブジェクトで表されるファイル ストリームのストリーム別コンテキストをサポートしているかどうかをクエリするには、そのファイル オブジェクトに対して FsRtlSupportsPerStreamContexts を呼び出します。 ファイル システムでは、ファイルの種類によって、ストリーム別コンテキストがサポートされる場合とされない場合とがあります。 たとえば、NTFS と FAT では現在、ページング ファイルのストリーム別コンテキストはサポートされていません。 したがって、FsRtlSupportsPerStreamContexts があるファイル ストリームに対して TRUE を返しても、すべてのファイル ストリームに対して TRUE が返されるということではありません。