RtlInitializeGenericTable function

The RtlInitializeGenericTable routine initializes a generic table.

Syntax

NTSYSAPI VOID RtlInitializeGenericTable(
  PRTL_GENERIC_TABLE            Table,
  PRTL_GENERIC_COMPARE_ROUTINE  CompareRoutine,
  PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
  PRTL_GENERIC_FREE_ROUTINE     FreeRoutine,
  PVOID                         TableContext
);

Parameters

Table

A pointer to a caller-allocated buffer, which must be at least sizeof(RTL_GENERIC_TABLE) bytes in size, to contain the initialized generic table structure.

CompareRoutine

An entry point of a comparison callback routine, declared as follows:

RTL_GENERIC_COMPARE_RESULTS
(*PRTL_GENERIC_COMPARE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in PVOID  FirstStruct,
    __in PVOID  SecondStruct
    ); 
The CompareRoutine parameters are as follows:

Table

A pointer to the generic table.

FirstStruct

A pointer to the first item to be compared.

SecondStruct

A pointer to the second item to be compared.

The CompareRoutine must strictly track the ordering of all elements in the generic table so that it can identify any particular element. The caller-defined structure for element data usually includes a member whose value is unique and can be used as a sorting key. All Rtl...GenericTable routines that call the CompareRoutine take a buffer pointer as a parameter, which is passed in turn to the CompareRoutine. The buffer contains a caller-supplied key value to be matched by the CompareRoutine to the key of the element that is being searched for.

Given two such key values, the CompareRoutine returns GenericLessThan, GenericGreaterThan, or GenericEqual.

AllocateRoutine

An entry point of an allocation callback routine, declared as follows:

PVOID
(*PRTL_GENERIC_ALLOCATE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in CLONG  ByteSize
    );
The AllocateRoutine parameters are as follows:

Table

A pointer to the generic table.

ByteSize

The number of bytes to allocate.

For each new element, the AllocateRoutine is called to allocate memory for caller-supplied data plus some additional memory for use by the Rtl...GenericTable routines. Note that because of this "additional memory," caller-supplied routines must not access the first (sizeof(RTL_SPLAY_LINKS) + sizeof(LIST_ENTRY)) bytes of any element in the generic table.

FreeRoutine

An entry point of a deallocation callback routine, declared as follows:

VOID
(*PRTL_GENERIC_FREE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in PVOID  Buffer
    );
The FreeRoutine parameters are as follows:

Table

A pointer to the generic table.

Buffer

A pointer to the element that is being deleted.

Rtl...GenericTable routines call the FreeRoutine to deallocate memory for elements to be deleted from the generic table. The FreeRoutine is the opposite of the AllocateRoutine.

TableContext

An optional pointer to a caller-supplied context for the generic table. This parameter can be NULL.

Return Value

None

Remarks

File systems call RtlInitializeGenericTable to initialize a generic table to store file system-specific data, such as name-lookup information for currently open files. The sort order, structure, and contents of the elements are caller-defined.

File systems must call RtlInitializeGenericTable to initialize the generic table before they use any other Rtl...GenericTable routines on the new generic table. The initialized generic table structure should be considered opaque.

Callers of the Rtl...GenericTable routines are responsible for exclusively synchronizing access to the generic table. An exclusive fast mutex is the most efficient synchronization mechanism to use for this purpose.

The caller-supplied CompareRoutine is called before the AllocateRoutine to locate an appropriate location at which a new element should be inserted. The CompareRoutine also is called before the FreeRoutine to locate an element to be deleted.

By default, the operating system uses splay trees to implement generic tables. Under some circumstances, operations on a splay tree will make the tree deep and narrow and might even turn it into a straight line. Very deep trees degrade the performance of searches. You can ensure a more balanced, shallower tree implementation of generic tables by using Adelson-Velsky/Landis (AVL) trees. If you want to configure the generic table routines to use AVL trees instead of splay trees in your driver, insert the following define statement in a common header file before including Ntddk.h:

#define RTL_USE_AVL_TABLES 0
If RTL_USE_AVL_TABLES is not defined, you must use the AVL form of the generic table routines. For example, use the RtlInitializeGenericTableAvl routine instead of RtlInitializeGenericTable. RtlInitializeGenericTableAvl returns an initialized RTL_AVL_TABLE table structure in the buffer to which the Table parameter points. In the call to RtlInitializeGenericTableAvl, the caller must pass a PRTL_AVL_COMPARE_ROUTINE-typed comparison callback routine, a PRTL_AVL_ALLOCATE_ROUTINE-typed allocation callback routine, and a PRTL_AVL_FREE_ROUTINE-typed deallocation callback routine rather than the similar PRTL_GENERIC_Xxx-typed routines.

Callers of RtlInitializeGenericTable must be running at IRQL <= DISPATCH_LEVEL. Note that if Rtl...GenericTable routines are to be used at IRQL DISPATCH_LEVEL, the CompareRoutine, AllocateRoutine, and FreeRoutine must all be nonpageable code, and the AllocateRoutine should allocate memory from nonpaged pool.

Requirements

   
Minimum supported client This routine is available on Microsoft Windows 2000 and later versions of all Windows operating systems.
Target Platform Universal
Header ntddk.h (include Ntddk.h, Ntifs.h, Fltkernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (see Remarks section)

See Also

ExInitializeFastMutex

RtlDeleteElementGenericTable

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable

RtlInsertElementGenericTable

RtlLookupElementGenericTable

RtlNumberGenericTableElements