RtlInsertElementGenericTable function (ntddk.h)

The RtlInsertElementGenericTable routine adds a new element to a generic table.

Syntax

NTSYSAPI PVOID RtlInsertElementGenericTable(
  [in]            PRTL_GENERIC_TABLE Table,
  [in]            PVOID              Buffer,
  [in]            CLONG              BufferSize,
  [out, optional] PBOOLEAN           NewElement
);

Parameters

[in] Table

Pointer to the generic table (RTL_GENERIC_TABLE). The table must have been initialized by calling RtlInitializeGenericTable.

[in] Buffer

Pointer to a caller-allocated buffer containing data to be copied into the new element. For more information, see the description of RtlInitializeGenericTable.

[in] BufferSize

Number of bytes to be allocated for caller-supplied data when the new element is inserted.

[out, optional] NewElement

Pointer to a variable that receives TRUE if a new element with the data at Buffer was inserted in the generic table; or FALSE if the new element was not inserted.

Return value

RtlInsertElementGenericTable returns a pointer to the newly inserted element's associated data, or it returns a pointer to the existing element's data if a matching element already exists in the generic table. If no matching element is found, but the new element cannot be inserted (for example, because the AllocateRoutine fails), RtlInsertElementGenericTable returns NULL.

Remarks

To insert an element, RtlInsertElementGenericTable calls the CompareRoutine and AllocateRoutine that were registered when the generic table was initialized by RtlInitializeGenericTable. After inserting the new element, RtlInsertElementGenericTable rebalances the splay link tree.

When a new element is inserted into the table, its data is copied from Buffer into the new element. Thus the pointer returned by RtlInsertElementGenericTable is never equal to Buffer.

If the caller's CompareRoutine returns GenericEqual, the data at Buffer is assumed to duplicate the data for an existing element in the generic table. In this case, RtlInsertElementGenericTable does not add the new element (and thus does not call the AllocateRoutine), because a generic table cannot have duplicate elements.

If a matching element already exists in the generic table, RtlInsertElementGenericTable returns a pointer to the existing element's data and sets NewElement to FALSE.

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.

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 RtlInsertElementGenericTableAvl routine instead of RtlInsertElementGenericTable. In the call to RtlInsertElementGenericTableAvl, the caller must pass a RTL_AVL_TABLE table structure rather than RTL_GENERIC_TABLE.

Callers of RtlInsertElementGenericTable must be running at IRQL < DISPATCH_LEVEL if either of the following conditions holds:

  • The caller-allocated memory at Table or at Buffer is pageable.
  • The caller-supplied CompareRoutine or AllocateRoutine contains pageable code.

Requirements

Requirement Value
Target Platform Universal
Header ntddk.h (include Ntddk.h, Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL < DISPATCH_LEVEL (see Remarks section)

See also

RtlDeleteElementGenericTable

RtlInitializeGenericTable