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) ,则例程将无限期等待,直到任何或所有调度程序对象都设置为信号状态。

正值指定相对于 1601 年 1 月 1 日绝对时间。 负值指定相对于当前时间的间隔。 绝对过期时间跟踪系统时间中的任何更改;相对过期时间不受系统时间更改的影响。

如果指定了 Timeout,则当给定的间隔过期时,如果未满足任何指定的等待条件,则会自动满足等待。

一个零 (超时值,即*Timeout == 0) 允许测试一组等待条件,并在可以立即满足等待条件的情况下有条件地执行任何其他操作,如获取互斥体。

[in, optional] WaitBlockArray

如果 Count <= THREAD_WAIT_OBJECTS,则 WaitBlockArray 可以为 NULL。 否则,此参数必须指向字节的 sizeof(KWAIT_BLOCK) * Count 内存缓冲区。 例程在执行等待操作时使用此缓冲区进行记录保留。

[in] CallbackData

指向 FLT_CALLBACK_DATA 结构的指针,该结构表示由用户发出且可由用户取消的 I/O 操作。 此参数是可选的,可以为 NULL。 调用方必须确保 I/O 操作在此例程期间保持有效,并且 I/O 不得设置取消例程 (例如,不能对 I/O 操作) 调用 FltSetCancelCompletion 函数。 请注意, CallbackData 必须由调用方持有,因为它不能传递给较低级别的驱动程序。

返回值

FltCancellableWaitForMultipleObjects 可以返回以下值之一:

返回代码 说明
STATUS_SUCCESS 调用方为 WaitType 参数指定 WaitAll,ObjectArray 数组中的所有调度程序对象都已设置为信号状态。
STATUS_TIMEOUT 在满足指定的等待条件集之前发生超时。 当无法立即满足指定的等待条件集并且 Timeout 设置为零时,也可以返回此值。
STATUS_WAIT_0到STATUS_WAIT_63 WaitType 指定的调用方和 ObjectArray 数组中的调度程序对象之一已设置为信号状态。 返回值的较低 6 位对满足等待的 对象的从零开始的索引进行编码。
STATUS_ABANDONED_WAIT_0到STATUS_ABANDONED_WAIT_63 调用方试图等待已放弃的互斥体。 返回值的下六位对 ObjectArray 数组中互斥体从零开始的索引进行编码。
STATUS_CANCELLED 等待因 I/O 操作的挂起的取消请求而中断。 请注意,仅当与基于 IRP 的操作对应的 CallbackData 传递给 FltCancellableWaitForMultipleObjects 并且 I/O 被 FltCancelIo 等例程取消时,才会返回此值。
STATUS_THREAD_IS_TERMINATING 由于应用程序或用户已终止线程,因此等待已中断。

返回值仅指示等待状态。

请注意,NT_SUCCESS宏对STATUS_CANCELLED和STATUS_THREAD_IS_TERMINATING状态值返回 FALSE (“failure”) ,所有其他状态值返回 TRUE (“success”) 。

注解

FltCancellableWaitForMultipleObjects 对调度程序对象执行可取消的等待操作。 如果用户或应用程序终止线程,或者与线程关联的 I/O 操作被 FltCancelIo 等例程取消,则取消等待。

该例程旨在支持 I/O 完成/取消指南。 这些准则的目标是允许用户快速终止应用程序。 这反过来又要求应用程序能够快速终止正在执行 I/O 的线程和任何当前 I/O 操作。 此例程为用户提供了一种阻止 (的方法,即在内核中等待 I/O 完成、调度程序对象或同步变量) ,从而允许轻松取消等待。 如果线程被用户或应用程序终止,此例程还允许线程的等待终止。

例如,重定向程序可能需要创建一个或多个辅助 I/O 操作,以便处理用户模式 I/O 并同步等待辅助请求完成。 执行此操作的一种方法是设置一个事件,该事件将由辅助 I/O 操作的完成例程发出信号,然后等待事件发出信号。 然后,若要执行可取消的等待操作,将调用 FltCancellableWaitForMultipleObjects ,传入与辅助 I/O 操作和原始用户模式 I/O 操作关联的事件。 如果发生挂起的终止事件或取消原始用户模式 I/O 操作,则线程等待事件发出信号将被取消。

请注意,终止等待不会自动取消调用方发出的任何 I/O 操作 -必须由调用方单独处理。

每个线程对象都有一个内置的等待块数组,可用于同时等待多个对象。 应尽可能在等待多次操作中使用内置的等待块数组,因为无需分配额外的等待块存储,以后再解除分配。 但是,如果必须同时等待的对象数大于内置等待块的数量,请使用 WaitBlockArray 参数指定要在等待操作中使用的备用等待块集。 驱动程序只需为 WaitBlockArray 分配足够大的内存缓冲区。 无需初始化缓冲区,驱动程序可以将它视为不透明结构。 例程返回后,可以释放缓冲区。

如果 Count 大于 MAXIMUM_WAIT_OBJECTS 或者 WaitBlockArray 为 NULL 且 Count 大于 THREAD_WAIT_OBJECTS,系统会发出 Bug 检查0xC:MAXIMUM_WAIT_OBJECTS_EXCEEDED

当传递给 FltCancellableWaitForMultipleObjects的 ObjectArray 参数中的一个或多个元素引用互斥体时,需要特别注意。 如果等待的调度程序对象是互斥体,则 APC 传递与等待期间所有其他调度程序对象的传递相同。 但是,一旦 FltCancellableWaitForMultipleObjects 返回STATUS_SUCCESS且线程实际持有互斥体,则仅传递特殊的内核模式 APC。 已禁用所有其他 APC(内核模式和用户模式)的传递。 在互斥释放之前,对 APC 的传递限制一直存在。

互斥体只能以递归方式获取 MINLONG 次。 如果超出此限制,则例程将引发STATUS_MUTANT_LIMIT_EXCEEDED异常。

如果 CallbackData 参数表示有效的筛选器管理器 IRP,则必须在 IRQL PASSIVE_LEVEL调用 FltCancellableWaitForMultipleObjects 例程。 否则,可以在 IRQL 中调用例程,小于或等于APC_LEVEL。 如果需要,调用方可以通过调用 KeEnterCriticalRegionFsRtlEnterFileSystem 例程来禁用正常的内核 APC。 但是,不得禁用特殊内核 APC。

如果 CallbackData 表示筛选器管理器 IRP 操作,但 CallbackData 结构中的 IRP 为 NULL,则 FltCancellableWaitForMultipleObjects 将在调试版本上断言。

要求

要求
最低受支持的客户端 Windows Vista
目标平台 通用
标头 fltkernel.h (包括 Ntifs.h、Fltkernel.h)
Library Fltmgr.lib
IRQL 请参见“备注”部分。

另请参阅

ExInitializeFastMutex

FltCancelIo

FltCancellableWaitForSingleObject

FltSetCancelCompletion

FsRtlCancellableWaitForMultipleObjects

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphore

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject