Partager via


FsRtlCancellableWaitForMultipleObjects, fonction (ntifs.h)

La routine FsRtlCancellableWaitForMultipleObjects exécute une opération d’attente annulable (une attente pouvant être arrêtée) sur un ou plusieurs objets de répartiteur.

Syntaxe

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
);

Paramètres

[in] Count

Nombre d’objets à attendre.

[in] ObjectArray

Pointeur vers un tableau de pointeurs vers des objets de répartiteur (événements, mutexes, sémaphores, threads et minuteurs) pour lesquels l’appelant fournit le stockage.

[in] WaitType

Soit WaitAll, ce qui indique que tous les objets spécifiés doivent atteindre un état signalé avant que l’attente soit satisfaite ; ou WaitAny, qui indique que l’un des objets doit atteindre un état signalé avant que l’attente soit satisfaite.

[in, optional] Timeout

Pointeur vers une valeur de délai d’attente facultative. Ce paramètre spécifie l’heure absolue ou relative, en 100 nanosecondes, à laquelle l’attente doit être terminée.

Si délai d’expiration pointe vers une valeur zéro (autrement dit, *Délai d’expiration == 0), la routine est retournée sans attendre. Si l’appelant fournit un pointeur NULL (autrement dit, Délai d’expiration == NULL), la routine attend indéfiniment jusqu’à ce que l’un ou l’ensemble des objets de répartiteur soient définis sur l’état signalé.

Une valeur positive spécifie une heure absolue, par rapport au 1er janvier 1601. Une valeur négative spécifie un intervalle par rapport à l’heure actuelle. Les heures d’expiration absolues suivent les modifications apportées à l’heure système ; les heures d’expiration relatives ne sont pas affectées par les modifications de temps système.

Si délai d’expiration est spécifié, l’attente est automatiquement satisfaite si aucune des conditions d’attente spécifiées n’est remplie lorsque l’intervalle donné expire.

Une valeur de délai d’attente égale à zéro (autrement dit, *Délai d’expiration == 0) vous permet de tester un ensemble de conditions d’attente et d’effectuer de manière conditionnelle toutes les actions supplémentaires si l’attente peut être immédiatement satisfaite, comme dans l’acquisition d’un mutex.

[in, optional] WaitBlockArray

Si count<= THREAD_WAIT_OBJECTS, WaitBlockArray peut avoir la valeur NULL. Sinon, ce paramètre doit pointer vers une mémoire tampon de sizeof(KWAIT_BLOCK * Count) octets. La routine utilise cette mémoire tampon pour la conservation des enregistrements lors de l’exécution de l’opération d’attente.

[in, optional] Irp

Pointeur vers l’IRP d’origine qui correspond à l’opération d’E/S qui a été émise par l’utilisateur et qui peut être annulée par l’utilisateur. L’appelant doit s’assurer que l’IRP restera valide pendant la durée de cette routine et que l’IRP ne doit pas avoir de routine d’annulation définie (par exemple, IoSetCancelRoutine ne doit pas avoir été appelé sur l’IRP). Notez que l’IRP doit être détenu par l’appelant, il ne peut pas être transmis à un pilote de niveau inférieur.

Valeur de retour

FsRtlCancellableWaitForMultipleObjects pouvez retourner l’une des valeurs suivantes :

Retourner le code Description
STATUS_SUCCESS L’appelant spécifié WaitAll pour le paramètre WaitType et tous les objets de répartiteur dans le tableau ObjectArray ont été définis sur l’état signalé.
STATUS_TIMEOUT Un délai d’attente s’est produit avant que l’ensemble spécifié de conditions d’attente ne soit rempli. Cette valeur peut être retournée lorsque l’ensemble spécifié de conditions d’attente ne peut pas être immédiatement rempli et délai d’expiration est défini sur zéro.
STATUS_WAIT_0 via STATUS_WAIT_63 L’appelant spécifié WaitAny pour WaitType et l’un des objets de répartiteur dans le tableau ObjectArray a été défini sur l’état signalé. Six bits inférieurs de la valeur de retour encodent l’index de base zéro de l’objet qui satisfait l’attente.
STATUS_ABANDONED_WAIT_0 via STATUS_ABANDONED_WAIT_63 L’appelant a tenté d’attendre un mutex abandonné. Six bits inférieurs de la valeur de retour encodent l’index de base zéro du mutex dans le tableau ObjectArray.
STATUS_CANCELLED L’attente a été interrompue par une demande d’annulation en attente sur l’IRP spécifié. Notez que cette valeur est retournée uniquement si un IRP valide est transmis à FsRtlCancellableWaitForMultipleObjects et que l’IRP a été annulé par CancelSynchronousIo.
STATUS_THREAD_IS_TERMINATING L’attente a été interrompue, car le thread a été arrêté par une application ou l’utilisateur.

La valeur de retour indique uniquement l’état de l’attente. Le cas échéant, l’état réel de la demande d’E/S doit être obtenu directement à partir d’un autre IRP généré dans le processus de gestion de l’IRP en mode utilisateur d’origine.

Notez que la macro NT_SUCCESS retourne FALSE (« échec ») pour les valeurs d’état STATUS_CANCELLED et STATUS_THREAD_IS_TERMINATING et TRUE (« réussite ») pour toutes les autres valeurs d’état.

Remarques

La routine FsRtlCancellableWaitForMultipleObjects exécute une opération d’attente annulable sur les objets de répartiteur. Si le thread est arrêté par l’utilisateur ou par l’application, ou si CancelSynchronousIo publie une demande d’annulation sur un IRP threadé (IRP synchrone) associé au thread, l’attente est annulée.

La routine FsRtlCancellableWaitForMultipleObjects a été conçue pour prendre en charge les instructions d’achèvement/annulation des E/S à partir de Windows Vista. L’objectif de ces instructions est de permettre aux utilisateurs (ou applications) de mettre rapidement fin aux applications. Cela nécessite que les applications aient la possibilité de mettre fin rapidement aux threads qui exécutent des E/S ainsi qu’à toutes les opérations d’E/S actuelles. Cette routine permet aux threads utilisateur de bloquer (c’est-à-dire d’attendre) dans le noyau pour l’achèvement des E/S, des objets de répartiteur ou des variables de synchronisation d’une manière qui permet d’annuler facilement l’attente. Cette routine autorise également l’arrêt de l’attente du thread si le thread est arrêté par un utilisateur ou une application.

Par exemple, un redirecteur peut avoir besoin de créer un ou plusieurs IRP secondaires afin de traiter un IRP en mode utilisateur et d’attendre de façon synchrone que les IRP secondaires se terminent. Pour ce faire, vous devez configurer un événement qui sera signalé par la routine d’achèvement de l’IRP secondaire, puis attendez que l’événement soit signalé. Ensuite, pour effectuer une opération d’attente annulable, FsRtlCancellableWaitForMultipleObjects est appelée transmission de l’événement associé à l’IRP secondaire, ainsi que l’IRP en mode utilisateur d’origine. L’attente du thread pour que l’événement soit signalé est annulé si un événement d’arrêt en attente se produit ou si l’IRP en mode utilisateur d’origine est annulé.

Notez que la fin de l’attente n’annule pas automatiquement toutes les opérations d’E/S émises par l’appelant, qui doivent être gérées séparément par l’appelant.

Chaque objet thread a un tableau intégré de blocs d’attente qui peuvent être utilisés pour attendre plusieurs objets simultanément. Dans la mesure du possible, le tableau intégré de blocs d’attente doit être utilisé dans une opération d’attente multiple, car aucun stockage de bloc d’attente supplémentaire n’a besoin d’être alloué et libéré ultérieurement. Toutefois, si le nombre d’objets qui doivent être attendus simultanément est supérieur au nombre de blocs d’attente intégrés, utilisez le paramètre WaitBlockArray pour spécifier un autre ensemble de blocs d’attente à utiliser dans l’opération d’attente. Les pilotes doivent uniquement allouer une mémoire tampon suffisamment volumineuse pour WaitBlockArray. La mémoire tampon n’a pas besoin d’être initialisée et les pilotes peuvent le traiter comme une structure opaque. La mémoire tampon peut être libérée une fois la routine retournée.

Si Count est supérieur à MAXIMUM_WAIT_OBJECTS ou si WaitBlockArray a la valeur NULL et count est supérieur à THREAD_WAIT_OBJECTS, les problèmes système vérification des bogues 0xC : MAXIMUM_WAIT_OBJECTS_EXCEEDED.

Une considération particulière s’applique lorsque le paramètre ObjectArray passé à FsRtlCancellableWaitForMultipleObjects est un mutex. Si l’objet répartiteur sur lequel l’attente est activée est un mutex, la remise d’APC est la même que pour tous les autres objets de répartiteur pendant l’attente. Toutefois, une fois FsRtlCancellableWaitForMultipleObjects retourne avec STATUS_SUCCESS et le thread contient réellement le mutex, seules les API en mode noyau spécial sont remises. La remise de toutes les autres API, en mode noyau et en mode utilisateur, est désactivée. Cette restriction sur la remise des API persiste jusqu’à ce que le mutex soit libéré.

Un mutex peut être acquis de manière récursive uniquement à des heures MINLONG. Si cette limite est dépassée, la routine déclenche une exception STATUS_MUTANT_LIMIT_EXCEEDED.

FsRtlCancellableWaitForMultipleObjects doit être appelée au PASSIVE_LEVEL IRQL si le paramètre Irp facultatif pointe vers un IRP valide. Si le paramètre Irp n’est pas utilisé, la routine peut être appelée au niveau irQL inférieur ou égal à APC_LEVEL. Les API de noyau normales peuvent être désactivées par l’appelant, si nécessaire, en appelant les routines KeEnterCriticalRegion ou FsRtlEnterFileSystem. Toutefois, les API de noyau spéciales ne doivent pas être désactivées.

FsRtlCancellableWaitForMultipleObjects s’affirme sur les builds de débogage si le runtime d’intégration est supérieur ou égal à APC_LEVEL et que le paramètre Irp pointe vers un IRP valide.

Exigences

Exigence Valeur
client minimum pris en charge Windows Vista
plateforme cible Universel
d’en-tête ntifs.h (include Ntifs.h)
bibliothèque NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Voir la section Remarques.
règles de conformité DDI HwStorPortProhibitedDDIs(storport), PowerIrpDDis(wdm), SpNoWait(storport)

Voir aussi

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject