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
要传递给 match 函数的数据。
[in] NextFlag
如果 RestartKey 不为 NULL,则值为 TRUE 表示枚举将跳过元素。 如果 为 FALSE ,则枚举会从上次调用 RtlEnumerateGenericTableLikeADirectory 时中断的位置恢复。 如果 RestartKey 为 NULL,则值为 TRUE 指示 RtlEnumerateGenericTableLikeADirectory 在与 Buffer 中的数据匹配的条目之后返回树中的下一个条目。 值为 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 期间从树中删除节点,枚举将从 Buffer 中所述的树中的位置恢复,无论 RestartKey 的值是什么。
[in, out] DeleteCount
输出时,该值指示从表中删除的条目的当前计数。 调用方必须在下次调用 RtlEnumerateGenericTableLikeADirectory 时传回此值。 此值可帮助 RtlEnumerateGenericTableLikeADirectory 例程确定在调用 RtlEnumerateGenericTableLikeADirectory 之间是否从表删除。 如果进行了删除,枚举会随着与 Buffer 中的数据匹配的表项(而不是 RestartKey 指示的表项)一起恢复。 如果 RestartKey 为 NULL,则此参数对 枚举无效。
[in] Buffer
一个键表达式,用于确定 在 RestartKey 为 NULL 时从何处开始枚举。 调用方可以传入与表中特定条目匹配的已保存键,枚举将从保存的键指定的条目开始,前提是 RestartKey 为 NULL 且 NextFlag 为 FALSE。 若要返回紧跟在已保存密钥之后的密钥,请在此处传递密钥,将 RestartKey 设置为 NULL , 将 NextFlag 设置为 TRUE。 如果已删除保存的密钥,枚举将从下一个匹配的键开始。
返回值
RtlEnumerateGenericTableLikeADirectory 例程返回指向与枚举中的下一个 table 元素关联的用户定义的结构的指针。 如果没有更多新元素可返回,则返回值为 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 运行:
调用方在 Table 或 Buffer 处分配的内存是可分页的。
调用方提供的 MatchFunction 包含可分页代码。
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
标头 | ntddk.h (包括 Ntddk.h、Ntifs.h、FltKernel.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= APC_LEVEL (请参阅备注部分) |