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 返回 GenericLessThanGenericGreaterThanGenericEqual

[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 来解除分配要从泛型表中删除的元素的内存。 FreeRoutineAllocateRoutine 相反。

[in, optional] TableContext

指向泛型表的调用方提供的上下文的可选指针。 此参数可以为 NULL。

返回值

备注

文件系统调用 RtlInitializeGenericTable 以初始化泛型表以存储文件系统特定的数据,例如当前打开的文件的名称查找信息。 元素的排序顺序、结构和内容由调用方定义。

文件系统必须先调用 RtlInitializeGenericTable 来初始化泛型表,然后才能使用任何其他 Rtl...新泛 型表上的 GenericTable 例程。 初始化的泛型表结构应被视为不透明。

Rtl 的调用方 ...GenericTable 例程负责以独占方式同步对泛型表的访问。 独占快速互斥体是用于此目的的最有效同步机制。

调用方提供的 CompareRoutineAllocateRoutine 之前调用,以找到应插入新元素的适当位置。 在 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 例程,而不是 RtlInitializeGenericTableRtlInitializeGenericTableAvl 在 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 例程, CompareRoutineAllocateRoutineFreeRoutine 都必须是不可分页的代码,并且 AllocateRoutine 应从非分页池中分配内存。

要求

要求
目标平台 通用
标头 ntddk.h (包括 Ntddk.h、Ntifs.h、Fltkernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= DISPATCH_LEVEL (请参阅备注部分)

另请参阅

ExInitializeFastMutex

RtlDeleteElementGenericTable

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable

RtlInsertElementGenericTable

RtlLookupElementGenericTable

RtlNumberGenericTableElements