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 返回与 Buffer中的数据匹配的项之后的树中的下一个条目。 值为 FALSE 指示 RtlEnumerateGenericTableLikeADirectory 返回与 Buffer中的数据匹配的树中的条目。
[in, out] RestartKey
一个值,该值确定开始或恢复泛型表元素的枚举的位置。 如果 *RestartKeyNULL,则枚举将从 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指示的表项一起恢复。 如果 *RestartKeyNULL,则此参数对枚举没有影响。
[in] Buffer
确定枚举开始位置的键表达式,当 *RestartKeyNULL时。 调用方可以传入与表中特定条目匹配的已保存密钥,并且枚举将在保存的键指定的项处开始,前提是 *RestartKeyNULL,并且 NextFlagFALSE。 若要返回紧随已保存密钥的密钥,请在此处传入密钥,请将 *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 包含可分页代码。
要求
要求 | 价值 |
---|---|
目标平台 | 普遍 |
标头 | ntddk.h (包括 Ntddk.h、Ntifs.h、FltKernel.h) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= APC_LEVEL (请参阅“备注”部分) |