Функция FltCancellableWaitForMultipleObjects (fltkernel.h)

FltCancellableWaitForMultipleObjects выполняет отменяемую операцию ожидания (ожидание, которое может быть завершено) для одного или нескольких объектов диспетчера.

Синтаксис

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 указывает на нулевое значение (то есть *Timeout == 0), подпрограмма возвращается без ожидания. Если вызывающий объект предоставляет указатель NULL (то есть Timeout == NULL), подпрограмма ожидает неограниченное время, пока любой или все объекты диспетчера не будут заданы в состояние сигнала.

Положительное значение указывает абсолютное время относительно 1 января 1601 г. Отрицательное значение указывает интервал относительно текущего времени. Абсолютное время истечения срока действия отслеживает любые изменения системного времени; Изменения системного времени не влияют на относительный срок действия.

Если указано время ожидания, ожидание автоматически выполняется, если ни одно из указанных условий ожидания не выполняется по истечении заданного интервала.

Значение времени ожидания, равное нулю (то есть *Timeout == 0) позволяет протестировать набор условий ожидания и условно выполнять любые дополнительные действия, если ожидание может быть немедленно выполнено, как при приобретении мьютекса.

[in, optional] WaitBlockArray

Если Count <= THREAD_WAIT_OBJECTS, Функция WaitBlockArray может иметь значение NULL. В противном случае этот параметр должен указывать на буфер памяти с байтами sizeof(KWAIT_BLOCK) * Count . Подпрограмма использует этот буфер для хранения записей при выполнении операции ожидания.

[in] CallbackData

Указатель на структуру FLT_CALLBACK_DATA , представляющую операцию ввода-вывода, выданную пользователем и которая может быть отменена пользователем. Этот параметр является необязательным и может иметь значение NULL. Вызывающий объект должен убедиться, что операция ввода-вывода будет оставаться действительной в течение всего времени выполнения этой процедуры и что операции ввода-вывода не должны иметь набора подпрограмм отмены (например, функция FltSetCancelCompletion не должна вызываться для операции ввода-вывода). Обратите внимание, что CallbackData должен храниться вызывающим, так как он не может быть передан драйверу более низкого уровня.

Возвращаемое значение

FltCancellableWaitForMultipleObjects может возвращать одно из следующих значений:

Код возврата Описание
STATUS_SUCCESS Вызывающий объект указал WaitAll для параметра WaitType , а все объекты диспетчера в массиве ObjectArray были заданы в состояние сигнала.
STATUS_TIMEOUT Время ожидания истекло до выполнения указанного набора условий ожидания. Это значение также может быть возвращено, если указанный набор условий ожидания не может быть немедленно выполнен, а время ожидания равно нулю.
STATUS_WAIT_0 по STATUS_WAIT_63 Вызывающий объект указал WaitAny для WaitType , а для одного из объектов диспетчера в массиве ObjectArray задано состояние сигнала. Нижние шесть битов возвращаемого значения кодируют отсчитываемый от нуля индекс объекта, удовлетворяющего ожидания.
STATUS_ABANDONED_WAIT_0 по STATUS_ABANDONED_WAIT_63 Вызывающий попытался дождаться мьютекса, который был оставлен. Нижние шесть бит возвращаемого значения кодируют отсчитываемый от нуля индекс мьютекса в массиве ObjectArray .
STATUS_CANCELLED Ожидание было прервано запросом на отмену операции ввода-вывода. Обратите внимание, что это значение возвращается только в том случае, если CallbackData , соответствующий операции на основе IRP, передается в fltCancellableWaitForMultipleObjects , а ввод-вывод был отменен подпрограммой, такой как FltCancelIo.
STATUS_THREAD_IS_TERMINATING Ожидание было прервано, так как приложение или пользователь завершили поток.

Возвращаемое значение указывает только состояние ожидания.

Обратите внимание, что макрос NT_SUCCESS возвращает значение FALSE ("сбой") для STATUS_CANCELLED и STATUS_THREAD_IS_TERMINATING значения состояния и TRUE ("успешно") для всех остальных значений состояния.

Комментарии

FltCancellableWaitForMultipleObjects выполняет отменяемую операцию ожидания для объектов диспетчера. Если пользователь или приложение завершает поток или операция ввода-вывода, связанная с потоком, была отменена подпрограммой, такой как FltCancelIo, ожидание отменяется.

Подпрограмма предназначена для поддержки рекомендаций по завершению и отмене ввода-вывода. Цель этих рекомендаций — позволить пользователям быстро завершать работу приложений. Это, в свою очередь, требует, чтобы приложения имели возможность быстро завершать потоки, выполняющие операции ввода-вывода, и любые текущие операции ввода-вывода. Эта подпрограмма позволяет пользовательским потокам блокировать (т. е. ожидать) в ядре для завершения ввода-вывода, объектов диспетчера или переменных синхронизации таким образом, чтобы ожидание было легко отменено. Эта подпрограмма также позволяет завершить ожидание потока, если поток завершается пользователем или приложением.

Например, перенаправлению может потребоваться создать одну или несколько вторичных операций ввода-вывода, чтобы обработать ввод-вывод в пользовательском режиме и синхронно дождаться завершения дополнительных запросов. Один из способов сделать это — настроить событие, которое будет сигнализироваться подпрограммой завершения дополнительных операций ввода-вывода, а затем ожидать передачи сигнала о событии. Затем для выполнения операции ожидания, допускающей отмену, вызывается метод FltCancellableWaitForMultipleObjects , передавая события, связанные с дополнительными операциями ввода-вывода и исходной операцией ввода-вывода в пользовательском режиме. Ожидание передачи сигнала о событии в потоке отменяется, если происходит событие завершения ожидания или если отменена исходная операция ввода-вывода в пользовательском режиме.

Обратите внимание, что завершение ожидания не приводит к автоматической отмене всех операций ввода-вывода, которые были выданы вызывающим абонентом, которые должны обрабатываться отдельно.

Каждый объект потока имеет встроенный массив блоков ожидания, который можно использовать для одновременного ожидания нескольких объектов. По возможности следует использовать встроенный массив блоков ожидания в операции с несколькими ожиданиями, так как дополнительное хранилище блоков ожидания не требуется выделять, а затем отменять выделение. Однако если количество объектов, которые необходимо ждать одновременно, больше количества встроенных блоков ожидания, используйте параметр WaitBlockArray , чтобы указать альтернативный набор блоков ожидания, которые будут использоваться в операции ожидания. Драйверам требуется выделить достаточно большой буфер памяти для WaitBlockArray. Вам не нужно инициализировать буфер, и драйверы могут рассматривать его как непрозрачную структуру. После возврата подпрограммы буфер можно освободить.

Если значение Count больше MAXIMUM_WAIT_OBJECTS или значение WaitBlockArray равно NULL, а Count больше THREAD_WAIT_OBJECTS, система выдает 0xC проверки ошибок: MAXIMUM_WAIT_OBJECTS_EXCEEDED.

Особое внимание следует учитывать, если один или несколько элементов в параметре ObjectArray , передаваемом в FltCancellableWaitForMultipleObjects, ссылаются на мьютекс. Если ожидающий объект диспетчера является мьютексом, доставка APC будет такой же, как и для всех остальных объектов диспетчера во время ожидания. Однако после того, как FltCancellableWaitForMultipleObjects возвращает STATUS_SUCCESS и поток фактически содержит мьютекс, доставляются только специальные APC режима ядра. Доставка всех остальных APC, как в режиме ядра, так и в пользовательском режиме, отключена. Это ограничение на доставку APC сохраняется до тех пор, пока мьютекс не будет освобожден.

Мьютекс можно рекурсивно получить только раз MINLONG. Если это ограничение превышено, подпрограмма вызывает исключение STATUS_MUTANT_LIMIT_EXCEEDED.

Подпрограмма FltCancellableWaitForMultipleObjects должна вызываться на PASSIVE_LEVEL IRQL, если параметр CallbackData представляет допустимый IRP диспетчера фильтров. В противном случае подпрограмма может быть вызвана в IRQL меньше или равна APC_LEVEL. При необходимости вызывающий объект может отключить обычные APC ядра, вызвав подпрограммы KeEnterCriticalRegion или FsRtlEnterFileSystem . Однако специальные APC ядра не должны быть отключены.

FltCancellableWaitForMultipleObjects будет утверждать в отладочных сборках, если CallbackData представляет операцию IRP диспетчера фильтров, но IRP в структуре CallbackData имеет значение NULL.

Требования

Требование Значение
Минимальная версия клиента Windows Vista
Целевая платформа Универсальное
Верхняя часть fltkernel.h (включая Ntifs.h, Fltkernel.h)
Библиотека Fltmgr.lib
IRQL См. раздел "Примечания".

См. также раздел

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject