次の方法で共有


FltCancellableWaitForMultipleObjects 関数 (fltkernel.h)

FltCancellableWaitForMultipleObjects は、1 つ以上のディスパッチャー オブジェクトに対してキャンセル可能な待機操作 (終了可能な待機) を実行します。

構文

NTSTATUS FLTAPI FltCancellableWaitForMultipleObjects(
  [in]           ULONG              Count,
  [in]           PVOID []           ObjectArray,
  [in]           WAIT_TYPE          WaitType,
  [in, optional] PLARGE_INTEGER     Timeout,
  [in, optional] PKWAIT_BLOCK       WaitBlockArray,
  [in]           PFLT_CALLBACK_DATA CallbackData
);

パラメーター

[in] Count

待機するオブジェクトの数。

[in] ObjectArray

呼び出し元がストレージを提供するディスパッチャー オブジェクト (イベント、ミューテックス、セマフォ、スレッド、タイマー) へのポインターの配列へのポインター。

[in] WaitType

WaitAll のいずれかの値を持つ列挙。指定されたすべてのオブジェクトが、待機が満たされる前にシグナル状態を取得する必要があることを示します。または WaitAny。待機が満たされる前に、いずれかのオブジェクトがシグナル状態を取得する必要があることを示します。

[in, optional] Timeout

省略可能なタイムアウト値へのポインター。 このパラメーターは、待機が完了する 100 ナノ秒単位の絶対時間または相対時間を指定します。

Timeout が 0 の値 (つまり、*Timeout == 0) を指している場合、ルーチンは待機せずに を返します。 呼び出し元が NULL ポインター (つまり、Timeout == NULL) を提供する場合、ルーチンは、ディスパッチャー オブジェクトの一部またはすべてがシグナル状態に設定されるまで無期限に待機します。

正の値は、1601 年 1 月 1 日を基準とした絶対時間を指定します。 負の値は、現在の時刻を基準とした間隔を指定します。 絶対有効期限は、システム時刻の変更を追跡します。相対有効期限は、システム時間の変更の影響を受けません。

Timeout を指定した場合、指定された間隔の有効期限が切れたときに指定された待機条件が満たされない場合、待機は自動的に満たされます。

タイムアウト値 0 (つまり、*Timeout == 0) を使用すると、一連の待機条件をテストし、ミューテックスの取得と同様に、待機をすぐに満たすことができる場合は、条件付きで追加のアクションを実行できます。

[in, optional] WaitBlockArray

Count <= THREAD_WAIT_OBJECTSの場合、WaitBlockArray は NULL にすることができます。 それ以外の場合、このパラメーターはバイトの sizeof(KWAIT_BLOCK) * Count メモリ バッファーを指す必要があります。 このルーチンは、待機操作の実行中にレコードを保持するためにこのバッファーを使用します。

[in] CallbackData

ユーザー によって発行 され、ユーザーが取り消すことができる I/O 操作を表すFLT_CALLBACK_DATA構造体へのポインター。 このパラメーターは省略可能であり、NULL にすることができます。 呼び出し元は、このルーチンの期間中、I/O 操作が有効であり続け、I/O に取り消しルーチンが設定されていないことを確認する必要があります (たとえば、 FltSetCancelCompletion 関数が I/O 操作で呼び出されていない必要があります)。 CallbackData は、下位レベルのドライバーに渡すことができないため、呼び出し元が保持する必要があることに注意してください。

戻り値

FltCancellableWaitForMultipleObjects は、次のいずれかの値を返すことができます。

リターン コード 説明
STATUS_SUCCESS 呼び出し元が WaitType パラメーターに WaitAll を指定し、 ObjectArray 配列内のすべてのディスパッチャー オブジェクトがシグナル状態に設定されています。
STATUS_TIMEOUT 指定した待機条件のセットが満たされる前にタイムアウトが発生しました。 この値は、指定した待機条件のセットをすぐに満たすことができない場合や、Timeout が 0 に設定されている場合にも返すことができます。
STATUS_WAIT_63によるSTATUS_WAIT_0 呼び出し元が WaitTypeWaitAny を指定し、ObjectArray 配列内のディスパッチャー オブジェクトの 1 つがシグナル状態に設定されています。 戻り値の下位 6 ビットは、待機を満たすオブジェクトの 0 から始まるインデックスをエンコードします。
STATUS_ABANDONED_WAIT_63によるSTATUS_ABANDONED_WAIT_0 呼び出し元が、破棄されたミューテックスを待機しようとしました。 戻り値の下位 6 ビットは、 ObjectArray 配列内のミューテックスの 0 から始まるインデックスをエンコードします。
STATUS_CANCELLED I/O 操作の保留中の取り消し要求によって待機が中断されました。 この値は、IRP ベースの操作に対応する CallbackDataFltCancellableWaitForMultipleObjects に渡され、I/O が FltCancelIo などのルーチンによって取り消された場合にのみ返されることに注意してください。
STATUS_THREAD_IS_TERMINATING アプリケーションまたはユーザーがスレッドを終了したため、待機が中断されました。

戻り値は、待機の状態のみを示します。

NT_SUCCESS マクロは、STATUS_CANCELLEDの 場合は FALSE ("failure") を返し、その他のすべての状態値に対して状態値をSTATUS_THREAD_IS_TERMINATINGし、 TRUE ("success") を返します。

注釈

FltCancellableWaitForMultipleObjects は、ディスパッチャー オブジェクトに対してキャンセル可能な待機操作を実行します。 ユーザーまたはアプリケーションがスレッドを終了した場合、またはスレッドに関連付けられている I/O 操作が FltCancelIo などのルーチンによって取り消された場合、待機は取り消されます。

ルーチンは、 I/O 完了/取り消しガイドラインをサポートするように設計されています。 これらのガイドラインの目的は、ユーザーがアプリケーションをすばやく終了できるようにすることです。 この場合、アプリケーションは、I/O および現在の I/O 操作を実行しているスレッドをすばやく終了できる必要があります。 このルーチンは、ユーザー スレッドが I/O 完了、ディスパッチャー オブジェクト、または同期変数に対してカーネル内でブロック (つまり待機) する方法を提供します。これにより、待機を簡単に取り消すことができます。 このルーチンでは、スレッドがユーザーまたはアプリケーションによって終了された場合に、スレッドの待機を終了することもできます。

たとえば、リダイレクターは、ユーザー モードの I/O を処理し、セカンダリ要求が完了するまで同期的に待機するために、1 つ以上のセカンダリ I/O 操作を作成する必要がある場合があります。 これを行う 1 つの方法は、セカンダリ I/O 操作の完了ルーチンによって通知されるイベントを設定し、イベントが通知されるのを待つ方法です。 次に、取り消し可能な待機操作を実行するために、 FltCancellableWaitForMultipleObjects が呼び出され、セカンダリ I/O 操作と元のユーザー モード I/O 操作に関連付けられているイベントが渡されます。 保留中の終了イベントが発生した場合、または元のユーザー モード I/O 操作が取り消された場合、スレッドのイベントが通知されるまでの待機は取り消されます。

待機を終了しても、呼び出し元によって発行された I/O 操作 (呼び出し元が個別に処理する必要がある) は自動的に取り消されないことに注意してください。

各スレッド オブジェクトには、複数のオブジェクトを同時に待機するために使用できる待機ブロックの配列が組み込まれています。 追加の待機ブロック ストレージを割り当てず、後で割り当てを解除する必要がないため、可能な限り、待機ブロックの組み込み配列を複数待機操作で使用する必要があります。 ただし、同時に待機する必要があるオブジェクトの数が組み込みの待機ブロックの数を超える場合は、 WaitBlockArray パラメーターを使用して、待機操作で使用する待機ブロックの代替セットを指定します。 ドライバーは 、WaitBlockArray に十分な大きさのメモリ バッファーを割り当てる必要があります。 バッファーを初期化する必要はありません。ドライバーはそれを不透明な構造体として扱うことができます。 ルーチンが戻ったら、バッファーを解放できます。

Count が MAXIMUM_WAIT_OBJECTS より大きい場合、または WaitBlockArray が NULL で Count がTHREAD_WAIT_OBJECTSより大きい場合、システムは バグ チェック 0xC: MAXIMUM_WAIT_OBJECTS_EXCEEDEDを発行します。

FltCancellableWaitForMultipleObjects に渡される ObjectArray パラメーター内の 1 つ以上の要素がミューテックスを参照する場合は、特別な考慮事項が適用されます。 待機中のディスパッチャー オブジェクトがミューテックスの場合、APC 配信は待機中の他のすべてのディスパッチャー オブジェクトの場合と同じです。 ただし、 FltCancellableWaitForMultipleObjects が STATUS_SUCCESS で返され、スレッドが実際にミューテックスを保持すると、特別なカーネル モードの APC のみが配信されます。 カーネル モードとユーザー モードの両方の他のすべての APC の配信は無効になっています。 APC の配信に関するこの制限は、ミューテックスが解放されるまで保持されます。

ミューテックスは、MINLONG 回だけ再帰的に取得できます。 この制限を超えると、ルーチンによってSTATUS_MUTANT_LIMIT_EXCEEDED例外が発生します。

CallbackData パラメーターが有効なフィルター マネージャー IRP を表す場合は、IRQL PASSIVE_LEVELで FltCancellableWaitForMultipleObjects ルーチンを呼び出す必要があります。 それ以外の場合は、IRQL でAPC_LEVEL以下のルーチンを呼び出すことができます。 通常のカーネル APCs は、必要に応じて、呼び出し元が KeEnterCriticalRegion または FsRtlEnterFileSystem ルーチンを呼び出すことによって無効にすることができます。 ただし、特殊なカーネル APC を無効にすることはできません。

CallbackData がフィルター マネージャー IRP 操作を表しているが、CallbackData 構造体の IRP が NULL の場合、FltCancellableWaitForMultipleObjects はデバッグ ビルドでアサートします。

要件

要件
サポートされている最小のクライアント Windows Vista
対象プラットフォーム ユニバーサル
Header fltkernel.h (Ntifs.h、Fltkernel.h を含む)
Library Fltmgr.lib
IRQL 「解説」を参照してください。

こちらもご覧ください

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject