Partager via


Fonction FltCancellableWaitForMultipleObjects (fltkernel.h)

FltCancellableWaitForMultipleObjects exécute une opération d’attente annulable (une attente qui peut être terminée) sur un ou plusieurs objets de répartiteur.

Syntaxe

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

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

Énumération avec la valeur waitAll, 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 unités de 100 nanosecondes, à laquelle l’attente doit être terminée.

Si le délai d’expiration pointe vers une valeur zéro (autrement dit, *Délai d’attente == 0), la routine retourne sans attendre. Si l’appelant fournit un pointeur NULL (c’est-à-dire, Délai d’attente == NULL), la routine attend indéfiniment jusqu’à ce que tous les objets de répartiteur soient définis à 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 changements d’heure système.

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

Une valeur de délai d’attente égale à zéro (autrement dit, *Délai d’attente == 0) vous permet de tester un ensemble de conditions d’attente et d’effectuer de manière conditionnelle des 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 d’octets sizeof(KWAIT_BLOCK) * Count . La routine utilise cette mémoire tampon pour la conservation des enregistrements lors de l’exécution de l’opération d’attente.

[in] CallbackData

Pointeur vers la structure FLT_CALLBACK_DATA qui représente l’opération d’E/S qui a été émise par l’utilisateur et qui peut être annulée par l’utilisateur. Ce paramètre est facultatif et peut être NULL. L’appelant doit s’assurer que l’opération d’E/S reste valide pendant toute la durée de cette routine et que les E/S ne doivent pas avoir de routine d’annulation (par exemple, la fonction FltSetCancelCompletion ne doit pas avoir été appelée sur l’opération d’E/S). Notez que callbackData doit être conservé par l’appelant, car il ne peut pas être passé à un pilote de niveau inférieur.

Valeur retournée

FltCancellableWaitForMultipleObjects peut retourner l’une des valeurs suivantes :

Code de retour Description
STATUS_SUCCESS L’appelant a spécifié WaitAll pour le paramètre WaitType et tous les objets de répartiteur du tableau ObjectArray ont été définis sur l’état signalé.
STATUS_TIMEOUT Un délai d’attente s’est produit avant que l’ensemble de conditions d’attente spécifié ne soit rempli. Cette valeur peut également être retournée lorsque l’ensemble de conditions d’attente spécifié ne peut pas être immédiatement rempli et que le délai d’expiration est défini sur zéro.
STATUS_WAIT_0 via STATUS_WAIT_63 L’appelant a 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é. Les six bits inférieurs de la valeur de retour encodent l’index de base zéro de l’objet qui a satisfait l’attente.
STATUS_ABANDONED_WAIT_0 à STATUS_ABANDONED_WAIT_63 L’appelant a tenté d’attendre un mutex qui a été abandonné. Les 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’opération d’E/S. Notez que cette valeur est retournée uniquement si CallbackData qui correspond à une opération basée sur IRP est passée à FltCancellableWaitForMultipleObjects et si les E/S ont été annulées par une routine telle que FltCancelIo.
STATUS_THREAD_IS_TERMINATING L’attente a été interrompue parce qu’une application ou l’utilisateur a mis fin au thread.

La valeur de retour indique uniquement le status de l’attente.

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

Remarques

FltCancellableWaitForMultipleObjects exécute une opération d’attente annulable sur les objets de répartiteur. Si l’utilisateur ou l’application termine le thread, ou si une opération d’E/S associée au thread a été annulée par une routine telle que FltCancelIo, l’attente est annulée.

La routine est conçue pour prendre en charge les instructions d’achèvement/annulation d’E/S. L’objectif de ces recommandations est de permettre aux utilisateurs de mettre rapidement fin aux applications. Cela, à son tour, nécessite que les applications aient la possibilité d’arrêter rapidement les threads qui exécutent des E/S et 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, les objets de répartiteur ou les variables de synchronisation de manière à ce que l’attente soit facilement annulée. Cette routine permet également d’arrêter 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 une ou plusieurs opérations d’E/S secondaires afin de traiter une E/S en mode utilisateur et d’attendre de manière synchrone que les demandes secondaires se terminent. Une façon de procéder consiste à configurer un événement qui sera signalé par la routine d’achèvement des opérations d’E/S secondaires, puis d’attendre que l’événement soit signalé. Ensuite, pour effectuer une opération d’attente annulable, FltCancellableWaitForMultipleObjects est appelé en passant les événements associés aux opérations d’E/S secondaires et l’opération d’E/S en mode utilisateur d’origine. L’attente du thread pour que l’événement soit signalé est annulée si un événement d’arrêt en attente se produit ou si l’opération d’E/S en mode utilisateur d’origine est annulée.

Notez que la fin de l’attente n’annule pas automatiquement 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 que vous pouvez utiliser pour attendre sur plusieurs objets simultanément. Dans la mesure du possible, vous devez utiliser le tableau intégré de blocs d’attente dans une opération d’attente multiple, car aucun stockage de blocs d’attente supplémentaire ne doit être alloué et libéré ultérieurement. Toutefois, si le nombre d’objets sur lesquels vous devez attendre 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 importante pour WaitBlockArray. Vous n’avez pas besoin d’initialiser la mémoire tampon et les pilotes peuvent la traiter comme une structure opaque. Vous pouvez libérer la mémoire tampon une fois que la routine est 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, le système émet la vérification des bogues 0xC : MAXIMUM_WAIT_OBJECTS_EXCEEDED.

Une considération particulière s’applique lorsqu’un ou plusieurs éléments du paramètre ObjectArray passé à FltCancellableWaitForMultipleObjects fait référence à un mutex. Si l’objet répartiteur attendu est un mutex, la remise APC est la même que pour tous les autres objets de répartiteur pendant l’attente. Toutefois, une fois que FltCancellableWaitForMultipleObjects retourne avec STATUS_SUCCESS et que le thread contient réellement le mutex, seuls les API spéciales en mode noyau sont livrées. La remise de tous 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 ne peut être acquis de manière récursive que des fois MINLONG. Si cette limite est dépassée, la routine déclenche une exception STATUS_MUTANT_LIMIT_EXCEEDED.

La routine FltCancellableWaitForMultipleObjects doit être appelée au PASSIVE_LEVEL IRQL si le paramètre CallbackData représente un IRP du gestionnaire de filtres valide. Sinon, la routine peut être appelée à l’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.

FltCancellableWaitForMultipleObjects s’affirme sur les builds de débogage si CallbackData représente une opération IRP du Gestionnaire de filtres, mais que l’IRP dans la structure CallbackData est NULL.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows Vista
Plateforme cible Universal
En-tête fltkernel.h (inclure Ntifs.h, Fltkernel.h)
Bibliothèque Fltmgr.lib
IRQL Consultez la section Notes.

Voir aussi

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject