FsRtlCancellableWaitForMultipleObjects 関数 (ntifs.h)

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

構文

NTSTATUS FsRtlCancellableWaitForMultipleObjects(
  [in]           ULONG          Count,
  [in]           PVOID []       ObjectArray,
  [in]           WAIT_TYPE      WaitType,
  [in, optional] PLARGE_INTEGER Timeout,
  [in, optional] PKWAIT_BLOCK   WaitBlockArray,
  [in, optional] PIRP           Irp
);

パラメーター

[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, optional] Irp

ユーザーによって発行され、ユーザーが取り消すことができる I/O 操作に対応する元の IRP へのポインター。 呼び出し元は、このルーチンの期間中、IRP が有効なままであること、および IRP にキャンセル ルーチンが設定されていないことを確認する必要があります (たとえば、 IoSetCancelRoutine が IRP で呼び出されていない必要があります)。 IRP は呼び出し元が保持する必要があり、下位レベルのドライバーに渡すことはできません。

戻り値

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

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

戻り値は、待機の状態のみを示します。 該当する場合、I/O 要求の実際の状態は、元のユーザー モード IRP を処理するプロセスで生成された別の IRP から直接取得する必要があります。

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

注釈

FsRtlCancellableWaitForMultipleObjects ルーチンは、ディスパッチャー オブジェクトに対してキャンセル可能な待機操作を実行します。 スレッドがユーザーまたはアプリケーションによって終了した場合、または CancelSynchronousIo がスレッドに関連付けられているスレッド IRP (同期 IRP) にキャンセル要求を送信した場合、待機は取り消されます。

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

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

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

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

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

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

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

省略可能な Irp パラメーターが有効な IRP を指している場合は、IRQL PASSIVE_LEVELで FsRtlCancellableWaitForMultipleObjects呼び出す必要があります。 Irp パラメーターを使用しない場合は、IRQL でルーチンを呼び出すことができます以下のAPC_LEVELします。 通常のカーネル API は、必要に応じて、 KeEnterCriticalRegion ルーチンまたは FsRtlEnterFileSystem ルーチンを呼び出すことによって、呼び出し元によって無効にすることができます。 ただし、特殊なカーネル API を無効にすることはできません。

FSRtlCancellableWaitForMultipleObjects は、IRQL がAPC_LEVEL以上であり、 Irp パラメーターが有効な IRP を指している場合、デバッグ ビルドでアサートされます。

要件

要件
サポートされている最小のクライアント Windows Vista
対象プラットフォーム ユニバーサル
Header ntifs.h (Ntifs.h を含む)
Library NtosKrnl.lib
[DLL] NtosKrnl.exe
IRQL 「解説」を参照してください。
DDI コンプライアンス規則 HwStorPortProhibitedDDIs(storport), PowerIrpDDis(wdm), SpNoWait(storport)

こちらもご覧ください

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject