Поделиться через


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

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

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

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

[in, optional] WaitBlockArray

Если число <= 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 through 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. Не нужно инициализировать буфер, и драйверы могут рассматривать его как непрозрачную структуру. После возврата подпрограммы буфер можно освободить.

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

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

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

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

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

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows Vista
целевая платформа Всеобщий
заголовка fltkernel.h (include Ntifs.h, Fltkernel.h)
библиотеки Fltmgr.lib
IRQL См. раздел "Примечания".

См. также

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject