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 == 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 不得具有取消例程集(例如,FltSetCancelCompletion 函数不得在 I/O 操作上调用)。 请注意,调用方必须保留 CallbackData,因为它无法传递给较低级别的驱动程序。
返回值
FltCancellableWaitForMultipleObjects 可以返回以下值之一:
返回代码 | 描述 |
---|---|
STATUS_SUCCESS | 为 WaitType 参数指定 WaitAll 调用方,ObjectArray 数组中的所有调度程序对象都已设置为信号状态。 |
STATUS_TIMEOUT | 在满足指定的等待条件集之前发生超时。 当无法立即满足指定的等待条件集并且超时设置为零时,也可以返回此值。 |
通过STATUS_WAIT_63 STATUS_WAIT_0 | WaitType 指定的调用方 WaitAny,ObjectArray 数组中的调度程序对象之一已设置为信号状态。 返回值的下六位对满足等待的对象从零开始的索引进行编码。 |
通过STATUS_ABANDONED_WAIT_63 STATUS_ABANDONED_WAIT_0 | 调用方试图等待已放弃的互斥体。 返回值的下六位对 ObjectArray 数组中互斥体的从零开始的索引进行编码。 |
STATUS_CANCELLED | 等待被 I/O 操作的挂起取消请求中断。 请注意,仅当与基于 IRP 的操作对应的 CallbackData 传递给 FltCancellableWaitForMultipleObjects 并且 I/O 已被例程(如 FltCancelIo)取消时,才会返回此值。 |
STATUS_THREAD_IS_TERMINATING | 由于应用程序或用户已终止线程,等待中断。 |
返回值仅指示等待状态。
请注意,对于所有其他状态值,NT_SUCCESS宏返回STATUS_CANCELLED和STATUS_THREAD_IS_TERMINATING状态值 FALSE FALSE(“failure”),TRUE(“success”)。
言论
FltCancellableWaitForMultipleObjects 对调度程序对象执行可取消的等待操作。 如果用户或应用程序终止线程,或者与线程关联的 I/O 操作已被例程(如 FltCancelIo)取消,则等待将被取消。
例程旨在支持
例如,重定向程序可能需要创建一个或多个辅助 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 引用 mutex 的 ObjectArray 参数中的一个或多个元素时,需要特别考虑一下。 如果等待的调度程序对象是互斥体,则 APC 传递与等待期间所有其他调度程序对象的传递相同。 但是,FltCancellableWaitForMultipleObjects 返回STATUS_SUCCESS并且线程实际保存互斥体后,只传递特殊的内核模式 APC。 禁用了所有其他 APC(内核模式和用户模式)的传递。 在释放互斥体之前,对 APC 传递的这种限制会一直存在。
互斥体只能递归获取 MINLONG 时间。 如果超出此限制,则例程将引发STATUS_MUTANT_LIMIT_EXCEEDED异常。
如果 CallbackData 参数表示有效的筛选器管理器 IRP,则必须在 IRQL PASSIVE_LEVEL调用 FltCancellableWaitForMultipleObjects 例程。 否则,可以在 IRQL 中调用例程,或等于APC_LEVEL。 调用方可以根据需要通过调用 KeEnterCriticalRegion 或 FsRtlEnterFileSystem 例程来禁用正常内核 APC。 但是,不能禁用特殊内核 APC。
如果 CallbackData 表示筛选器管理器 IRP 操作,FltCancellableWaitForMultipleObjects 将在调试生成上断言,但 CallbackData 结构中的 IRP 为 NULL。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows Vista |
目标平台 | 普遍 |
标头 | fltkernel.h(包括 Ntifs.h、Fltkernel.h) |
库 | Fltmgr.lib |
IRQL | 请参阅“备注”部分。 |
另请参阅
FltCancellableWaitForSingleObject