The RtlInsertElementGenericTableFullAvl routine adds a new entry to a generic table.
NTSYSAPI PVOID RtlInsertElementGenericTableFullAvl( PRTL_AVL_TABLE Table, PVOID Buffer, CLONG BufferSize, PBOOLEAN NewElement, PVOID NodeOrParent, TABLE_SEARCH_RESULT SearchResult );
A caller-allocated buffer that contains the user data to copy into the new element. For more information, see RtlInitializeGenericTableAvl.
Size in bytes of data in Buffer.
On output, a value of TRUE means the insertion of the new element in the generic table was successful. A value of FALSE means the insertion failed.
The search result of a previous call to RtlLookupElementGenericTableFullAvl. This value indicates to the RtlInsertElementGenericTableFullAvl routine whether the tree is currently empty, or if not empty, whether to insert the new entry to the left or the right of the parent entry. The SearchResult parameter can have any of the following values:
The tree was empty. The contents of NodeOrParent has not been altered.
The RtlInsertElementGenericTableFullAvl routine found a table entry whose key matches the data in Buffer. NodeOrParent contains a pointer to the matched entry.
The RtlInsertElementGenericTableFullAvl routine did not find a table entry whose key matches the data in Buffer. If the entry that RtlInsertElementGenericTableFullAvl searched for were in the table, it would be the left child of the entry that NodeOrParent points to.
The RtlInsertElementGenericTableFullAvl routine did not find a table entry whose key matches the data in Buffer. If the entry that RtlInsertElementGenericTableFullAvl searched for were in the table, it would be the right child of the entry that NodeOrParent points to.
A pointer to a table entry. If the RtlInsertElementGenericTableFullAvl routine matches an entry, NodeOrParent points to the matched entry. If the RtlInsertElementGenericTableFullAvl routine fails to find a match, NodeOrParent points to the entry that would be the parent of the entry that RtlInsertElementGenericTableFullAvl routine was searching for.
RtlInsertElementGenericTableFullAvl returns a pointer to the user data for the newly inserted entry, or the user data for a matching entry that is already in the generic table. If no matching entry is found, but RtlInsertElementGenericTableFullAvl cannot insert the new entry (for example, because the AllocateRoutine fails), RtlInsertElementGenericTableFullAvl returns NULL.
To insert an entry, RtlInsertElementGenericTableFullAvl calls the CompareRoutine and AllocateRoutine that were registered when the generic table was initialized by RtlInitializeGenericTableAvl. After inserting the new entry, RtlInsertElementGenericTableFullAvl rebalances the AVL link tree.
When a new entry is inserted into the table, its data is copied from Buffer into the new entry. Thus the pointer returned by RtlInsertElementGenericTableFullAvl 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 entry in the generic table. In this case, RtlInsertElementGenericTableFullAvl does not add the new entry (and thus does not call the AllocateRoutine), because a generic table cannot have duplicate entries.
If a matching entry already exists in the generic table, RtlInsertElementGenericTableFullAvl returns a pointer to the existing entry's data and sets NewElement to FALSE.
If there is no matching entry in the table already,RtlInsertElementGenericTableFullAvl routine allocates sufficient space for the user data of new entry (BufferSize) plus the links associated with the new entry. Thus the total number of bytes will be at least BufferSize + sizeof(BALANCED_LINKS). Caller should not use the first sizeof(BALANCED_LINKS) bytes of the memory that the AllocateRoutineallocates.
Callers of theRtl..GenericTableAvl 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, but the RtlInsertElementGenericTableFullAvl routine only works with Adelson-Velsky/Landis (AVL) trees. 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 RtlInsertElementGenericTableFullAvl routine instead of RtlInsertElementGenericTableFull. In the call to RtlInsertElementGenericTableFullAvl, the caller must pass a RTL_AVL_TABLE table structure rather than RTL_GENERIC_TABLE.
Callers of RtlInsertElementGenericTableFullAvl 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.
|Windows version||Available in Windows XP and later versions of the Windows operating systems.|
|Header||ntddk.h (include Ntddk.h, Ntifs.h)|
|IRQL||"< DISPATCH_LEVEL (see Remarks section)"|