RtlInitializeGenericTable 函数 (ntddk.h)
RtlInitializeGenericTable 例程初始化泛型表。
语法
NTSYSAPI VOID RtlInitializeGenericTable(
[out] PRTL_GENERIC_TABLE Table,
[in] PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
[in] PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
[in] PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
[in, optional] PVOID TableContext
);
参数
[out] Table
指向调用方分配的缓冲区的指针,该缓冲区 的大小必须至少 为 (RTL_GENERIC_TABLE) 字节的大小,才能包含初始化的泛型表结构。
[in] CompareRoutine
比较回调例程的入口点,声明如下:
RTL_GENERIC_COMPARE_RESULTS
(*PRTL_GENERIC_COMPARE_ROUTINE) (
__in struct _RTL_GENERIC_TABLE *Table,
__in PVOID FirstStruct,
__in PVOID SecondStruct
);
CompareRoutine 参数如下所示:
表 (CompareRoutine)
指向泛型表的指针。
FirstStruct
指向要比较的第一个项的指针。
SecondStruct
指向要比较的第二个项的指针。
CompareRoutine 必须严格跟踪泛型表中所有元素的顺序,以便它可以标识任何特定元素。 元素数据的调用方定义的结构通常包括其值唯一且可用作排序键的成员。 所有 Rtl... 调用 CompareRoutine 的 GenericTable 例程将缓冲区指针作为参数,该参数又传递到 CompareRoutine。 缓冲区包含调用方提供的键值,该键值由 CompareRoutine 与要搜索的元素的键进行匹配。
给定两个此类键值, CompareRoutine 返回 GenericLessThan、 GenericGreaterThan 或 GenericEqual。
[in] AllocateRoutine
分配回调例程的入口点,声明如下:
PVOID
(*PRTL_GENERIC_ALLOCATE_ROUTINE) (
__in struct _RTL_GENERIC_TABLE *Table,
__in CLONG ByteSize
);
AllocateRoutine 参数如下所示:
表 (AllocateRoutine)
指向泛型表的指针。
ByteSize
要分配的字节数。
对于每个新元素,将调用 AllocateRoutine 为调用方提供的数据分配内存,以及一些额外的内存供 Rtl...GenericTable 例程。 请注意,由于此“额外内存”,调用方提供的例程不得访问泛型表中任何元素的第一个 (size (RTL_SPLAY_LINKS) + sizeof (LIST_ENTRY) ) 字节。
[in] FreeRoutine
解除分配回调例程的入口点,声明如下:
VOID
(*PRTL_GENERIC_FREE_ROUTINE) (
__in struct _RTL_GENERIC_TABLE *Table,
__in PVOID Buffer
);
FreeRoutine 参数如下所示:
表 (FreeRoutine)
指向泛型表的指针。
Buffer
指向要删除的元素的指针。
Rtl。。。GenericTable 例程调用 FreeRoutine 来解除分配要从泛型表中删除的元素的内存。 FreeRoutine 与 AllocateRoutine 相反。
[in, optional] TableContext
指向泛型表的调用方提供的上下文的可选指针。 此参数可以为 NULL。
返回值
无
备注
文件系统调用 RtlInitializeGenericTable 以初始化泛型表以存储文件系统特定的数据,例如当前打开的文件的名称查找信息。 元素的排序顺序、结构和内容由调用方定义。
文件系统必须先调用 RtlInitializeGenericTable 来初始化泛型表,然后才能使用任何其他 Rtl...新泛 型表上的 GenericTable 例程。 初始化的泛型表结构应被视为不透明。
Rtl 的调用方 ...GenericTable 例程负责以独占方式同步对泛型表的访问。 独占快速互斥体是用于此目的的最有效同步机制。
调用方提供的 CompareRoutine 在 AllocateRoutine 之前调用,以找到应插入新元素的适当位置。 在 FreeRoutine 之前也调用 CompareRoutine,以查找要删除的元素。
默认情况下,操作系统使用 splay 树来实现泛型表。 在某些情况下,对 splay 树的操作将使树变得深而窄,甚至可能将其变成直线。 非常深的树会降低搜索的性能。 可以通过使用 Adelson-Velsky/Landis (AVL) 树来确保泛型表的更平衡、更浅的树实现。 如果要将泛型表例程配置为在驱动程序中使用 AVL 树而不是 splay 树,请在包含 Ntddk.h 之前在通用头文件中插入以下 define 语句:
`#define RTL_USE_AVL_TABLES 0`
如果要使用 AVL 表,并且未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。 例如,使用 RtlInitializeGenericTableAvl 例程,而不是 RtlInitializeGenericTable。 RtlInitializeGenericTableAvl 在 Table 参数指向的缓冲区中返回初始化的RTL_AVL_TABLE表结构。 在调用 RtlInitializeGenericTableAvl 时,调用方必须传递PRTL_AVL_COMPARE_ROUTINE类型的比较回调例程、PRTL_AVL_ALLOCATE_ROUTINE类型的分配回调例程和PRTL_AVL_FREE_ROUTINE类型的解除分配回调例程,而不是类似的PRTL_GENERIC_Xxx 类型的例程。
RtlInitializeGenericTable 的调用方必须在 IRQL <= DISPATCH_LEVEL 运行。 请注意,如果 Rtl...要在 IRQL DISPATCH_LEVEL使用 GenericTable 例程, CompareRoutine、 AllocateRoutine 和 FreeRoutine 都必须是不可分页的代码,并且 AllocateRoutine 应从非分页池中分配内存。
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
标头 | ntddk.h (包括 Ntddk.h、Ntifs.h、Fltkernel.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | IRQL <= DISPATCH_LEVEL (请参阅备注部分) |