RtlEnumerateGenericTableLikeADirectory 函数 (ntddk.h)
RtlEnumerateGenericTableLikeADirectory 例程按排序规则顺序返回泛型表(一对一)的元素。
语法
NTSYSAPI PVOID RtlEnumerateGenericTableLikeADirectory(
[in] PRTL_AVL_TABLE Table,
[in, optional] PRTL_AVL_MATCH_FUNCTION MatchFunction,
[in, optional] PVOID MatchData,
[in] ULONG NextFlag,
[in, out] PVOID *RestartKey,
[in, out] PULONG DeleteCount,
[in] PVOID Buffer
);
参数
[in] Table
指向要枚举的 Adelson-Velsky/Landis (AVL) 表的指针 (RTL_AVL_TABLE) 。
[in, optional] MatchFunction
一个匹配函数,用于确定要返回的条目。 如果未指定,则返回所有节点。
[in, optional] MatchData
要传递给匹配函数的数据。
[in] NextFlag
如果 RestartKey 不 为 NULL,则 值为 TRUE 表示枚举将跳过元素。 如果 为 FALSE ,则枚举将在上一次对 RtlEnumerateGenericTableLikeADirectory 的调用中中断的位置恢复。 如果 RestartKey 为 NULL,则 TRUE 值指示 RtlEnumerateGenericTableLikeADirectory 在 与缓冲区中的数据匹配的条目之后返回树中的下一个条目。 FALSE 值指示 RtlEnumerateGenericTableLikeADirectory 返回与 Buffer 中的数据匹配的树中的条目。
[in, out] RestartKey
一个值,该值确定从何处开始或恢复泛型表元素的枚举。 如果 RestartKey 为 NULL,则枚举将从 Buffer 中所述的位置开始或恢复。 如果不是 NULL,则枚举从 RestartKey 指示的点恢复。 返回时, RestartKey 保存一个值,该值指示枚举离开的树中的位置。 在下一次调用 RtlEnumerateGenericTableLikeADirectory 调用方时,应传递相同的值以通知 RtlEnumerateGenericTableLikeADirectory ,以便恢复枚举。 下面的代码示例演示如何执行此操作:
NextFlag = FALSE;
RestartKey = NULL;
DeleteCount = 0;
// Initialize Buffer for start/resume point
Buffer = ...
for (ptr = NULL; ptr != NULL; ) {
// Value returned in RestartKey will be passed back in
// on following call (iteration):
ptr = RtlEnumerateGenericTableLikeADirectory(
&MyTable, NULL, NULL, TRUE, &RestartKey,
&DeleteCount, &Buffer, sizeof(LONG) );
...
// The value output in RestartKey will still be in
// RestartKey when the
// RtlEnumerationGenericTableLikeADirectory routine
// is called in the next iteration of this loop.
// This ensures that the enumeration will pick up
// where it left off.
}
如果在调用 RtlEnumerateGenericTableLikeADirectory 之间从树中删除节点,则无论 RestartKey 的值如何,枚举都从 Buffer 中所述的树中的位置恢复。
[in, out] DeleteCount
在输出中,一个值,该值指示从表中删除的条目的当前计数。 调用方必须在下一次调用 RtlEnumerateGenericTableLikeADirectory 时重新传递此值。 此值可帮助 RtlEnumerateGenericTableLikeADirectory 例程确定从表中删除是否在调用 RtlEnumerateGenericTableLikeADirectory 之间发生。 如果删除已发生,则枚举将恢复与 Buffer 中的数据匹配的表项,而不是 与 RestartKey 指示的表项一起恢复。 如果 RestartKey 为 NULL,此参数对枚举没有影响。
[in] Buffer
一个键表达式,用于确定 在 RestartKey 为 NULL 时开始枚举的位置。 调用方可以传入与表中特定条目匹配的已保存密钥,并且枚举将从保存的密钥指定的条目开始,前提是 RestartKey 为 NULL , NextFlag 为 FALSE。 若要返回紧跟保存的密钥的密钥,请在此处传入密钥,将 RestartKey 设置为 NULL , 将 NextFlag 设置为 TRUE。 如果已删除已保存的密钥,枚举将从下一个匹配的密钥开始。
返回值
RtlEnumerateGenericTableLikeADirectory 例程返回指向与枚举中的下一个表元素关联的用户定义的结构的指针。 如果没有更多新元素可返回返回值为 NULL。
备注
RtlEnumerateGenericTableLikeADirectory 例程提供了一种安全的方法,用于跨混合插入和删除操作枚举泛型表。 从第一个匹配的键名称开始, RtlEnumerateGenericTableLikeADirectory 将返回表中的每一个名称,除非在枚举期间插入或删除了名称。 在枚举 (期间插入或删除密钥名称时,例如,在调用 RtlEnumerateGenericTableLikeADirectory 之间) 它可能或可能不会包含在枚举中。 当 RtlEnumerateGenericTableLikeADirectory 处理名称所在的目录范围时,是否包含此类名称取决于名称的状态。
有四个例程可用于枚举泛型表:
默认情况下,操作系统使用 splay 树实现泛型表,但 RtlEnumerateGenericTableLikeADirectory 例程仅适用于 Adelson-Velsky/Landis (AVL) 树。 若要将泛型表例程配置为使用 AVL 树而不是驱动程序中的 splay 树,请在包括 Ntddk.h 之前在通用头文件中插入以下 define 语句:
#define RTL_USE_AVL_TABLES 0
如果未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。
如果满足以下任一条件, RtlEnumerateGenericTableLikeADirectory 的调用方必须在 IRQL <= APC_LEVEL运行:
- 表或缓冲区处的调用方分配的内存是可分页的。
- 调用方提供的 MatchFunction 包含可分页代码。
要求
最低受支持的客户端 | 此例程从 Windows XP 开始可用。 |
目标平台 | 通用 |
标头 | ntddk.h (包括 Ntddk.h、Ntifs.h、FltKernel.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= APC_LEVEL (请参阅“备注”部分) |