Partager via


FltCancellableWaitForMultipleObjects, fonction (fltkernel.h)

Le FltCancellableWaitForMultipleObjects 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 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 de 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 100 nanosecondes à laquelle l’attente doit être terminée.

Si le délai d’attente pointe vers une valeur zéro (autrement dit, *Timeout == 0), la routine est retournée sans attendre. Si l’appelant fournit un pointeur NULL (autrement dit, Timeout == NULL), la routine attend indéfiniment jusqu’à ce que tous les 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 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 lorsque l’intervalle donné expire.

Une valeur de délai d’attente égale à zéro (autrement dit, *Timeout == 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] CallbackData

Pointeur vers la structure FLT_CALLBACK_DATA qui représente l’opération d’E/S é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 la durée de cette routine et que l’E/S ne doit pas avoir un jeu de routines d’annulation (par exemple, FltSetCancelCompletion fonction ne doit pas avoir été appelée sur l’opération d’E/S). Notez que le callbackData doit être conservé par l’appelant, car il ne peut pas être passé à un pilote de niveau inférieur.

Valeur de retour

FltCancellableWaitForMultipleObjects peut 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 également être retournée lorsque l’ensemble spécifié de conditions d’attente ne peut pas être immédiatement rempli et que le délai d’attente 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’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 que l’E/S a été annulée par une routine telle que FltCancelIo.
STATUS_THREAD_IS_TERMINATING L’attente a été interrompue, car une application ou l’utilisateur a arrêté le thread.

La valeur de retour indique uniquement l’état de l’attente.

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

Le 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/d’annulation d’E/S . L’objectif de ces instructions est de permettre aux utilisateurs de mettre rapidement fin aux applications. Cela nécessite que les applications aient la possibilité de mettre rapidement fin aux threads qui exécutent des E/S et des 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 une ou plusieurs opérations d’E/S secondaires afin de traiter une E/S en mode utilisateur et d’attendre de façon synchrone que les requêtes secondaires se terminent. Pour ce faire, vous devez configurer un événement qui sera signalé par la routine d’achèvement des opérations d’E/S secondaires, puis attendez que l’événement soit signalé. Ensuite, pour effectuer une opération d’attente annulable, FltCancellableWaitForMultipleObjects est appelée transmettre 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é 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 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 que vous pouvez utiliser pour attendre 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 bloc d’attente supplémentaire n’a besoin d’être alloué et libéré ultérieurement. Toutefois, si le nombre d’objets que 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 volumineuse pour WaitBlockArray. Vous n’avez pas besoin d’initialiser la mémoire tampon et les pilotes peuvent le traiter comme une structure opaque. Vous pouvez libérer la mémoire tampon une fois la routine retournée.

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

Une considération particulière s’applique lorsqu’un ou plusieurs des éléments du paramètre ObjectArray transmis à FltCancellableWaitForMultipleObjects fait référence à 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 FltCancellableWaitForMultipleObjects 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.

La routine FltCancellableWaitForMultipleObjects doit être appelée à l’PASSIVE_LEVEL IRQL si le paramètre CallbackData représente un IRP de gestionnaire de filtre valide. Sinon, la routine peut être appelée à IRQL moins ou égale à 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 le CallbackData représente une opération IRP du Gestionnaire de filtres, mais que l’IRP dans la structure CallbackData est NULL.

Exigences

Exigence Valeur
client minimum pris en charge Windows Vista
plateforme cible Universel
d’en-tête fltkernel.h (include Ntifs.h, Fltkernel.h)
bibliothèque Fltmgr.lib
IRQL Voir la section Remarques.

Voir aussi

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject