FLT_PREOP_SYNCHRONIZE が返される場合
Note
ミニフィルター ドライバーでは、操作前と操作後の呼び出しでリソースを保持するためにFLT_PREOP_SYNCHRONIZEを使用しないでください (I/O 呼び出し全体でリソースを保持しないのと同じです)。 これを行うには、デッドロックが発生する可能性があるため、安全ではありません。
ミニフィルター ドライバーの操作前コールバック ルーチンが、FLT_PREOP_SYNCHRONIZEを返すことによって I/O 操作を同期する場合、フィルター マネージャーは、I/O の完了時にそのフィルターの操作後コールバック ルーチンを呼び出します。
- フィルターがドレインされていない場合、フィルター マネージャーは、IRQL <= APC_LEVELで、操作前コールバックと同じスレッド コンテキストで、そのフィルターの操作後コールバック ルーチンを呼び出します。 (このスレッド コンテキストは、必ずしも元のスレッドのコンテキストではないことに注意してください)。
- フィルターがドレインされている場合、フィルター マネージャーは元のスレッドと同期しません。
Note
フィルターの操作前コールバック ルーチンが FLT_PREOP_SYNCHRONIZE を返す場合は、操作の操作後コールバック ルーチンを実装する必要があります。
フィルターの操作前コールバック ルーチンがFLT_PREOP_SYNCHRONIZEを返す場合は、CompletionContext 出力パラメーターに NULL 以外の値を返すことができます。 このパラメーターは、対応する操作後コールバック ルーチンに渡される省略可能なコンテキスト ポインターです。 操作後コールバック ルーチンは、CompletionContext 入力パラメーターでこのポインターを受け取ります。
ミニフィルター ドライバーの操作前コールバック ルーチンは、IRP ベースの I/O 操作に対してのみFLT_PREOP_SYNCHRONIZEを返す必要があります。 ただし、この状態値は、他の操作の種類に対して返すことができます。 IRP ベースの I/O 操作ではない I/O 操作に対して返される場合、フィルター マネージャーは、この戻り値を FLT_PREOP_SUCCESS_WITH_CALLBACK したかのように扱います。 操作が IRP ベースの I/O 操作であるかどうかを確認するには、FLT_IS_IRP_OPERATION マクロを使用します。
これらの操作は既にフィルター マネージャーによって同期されているため、作成操作の FLT_PREOP_SYNCHRONIZE をフィルターで返さないでください。 ミニフィルター ドライバーが、IRP_MJ_CREATE 操作の操作前および操作後のコールバック ルーチンを登録している場合、作成後コールバック ルーチンは、作成前コールバック ルーチンと同じスレッド コンテキストで IRQL = PASSIVE_LEVEL で呼び出されます。
ミニフィルター ドライバーは、非同期の読み取りまたは書き込み操作のFLT_PREOP_SYNCHRONIZEを返してはなりません。 これにより、ミニフィルター ドライバーとシステムパフォーマンスの両方が大幅に低下し、変更されたページ ライター スレッドがブロックされた場合などにデッドロックが発生する可能性があります。 IRP ベースの読み取りまたは書き込み操作の FLT_PREOP_SYNCHRONIZE を返す前に、ミニフィルター ドライバーは FltIsOperationSynchronous を呼び出して操作が同期していることを確認する必要があります。
次の種類の I/O 操作は同期できません。
Oplock ファイル システム制御 (FSCTL) 操作 (MajorFunction はIRP_MJ_FILE_SYSTEM_CONTROL; FsControlCode は、FSCTL_REQUEST_FILTER_OPLOCK、FSCTL_REQUEST_BATCH_OPLOCK、FSCTL_REQUEST_OPLOCK_LEVEL_1、またはFSCTL_REQUEST_OPLOCK_LEVEL_2。)
ディレクトリ変更操作の通知 (MajorFunction はIRP_MJ_DIRECTORY_CONTROL; MinorFunction はIRP_MN_NOTIFY_CHANGE_DIRECTORYです。)
バイト範囲ロック要求 (MajorFunction は IRP_MJ_LOCK_CONTROL; MinorFunction は IRP_MN_LOCKです。)
これらの操作に対して FLT_PREOP_SYNCHRONIZE を返すことはできません。