Функция RtlInsertElementGenericTableFullAvl (ntddk.h)
Подпрограмма RtlInsertElementGenericTableFullAvl добавляет новую запись в универсальную таблицу.
Синтаксис
NTSYSAPI PVOID RtlInsertElementGenericTableFullAvl(
[in] PRTL_AVL_TABLE Table,
[in] PVOID Buffer,
[in] CLONG BufferSize,
[out, optional] PBOOLEAN NewElement,
[in] PVOID NodeOrParent,
[in] TABLE_SEARCH_RESULT SearchResult
);
Параметры
[in] Table
Указатель на универсальную таблицу Adelson-Velsky/Landis (AVL) (RTL_AVL_TABLE), которая была инициализирована вызовом RtlInitializeGenericTableAvl.
[in] Buffer
Выделенный вызывающим буфер, содержащий данные пользователя для копирования в новый элемент. Дополнительные сведения см. в разделе RtlInitializeGenericTableAvl.
[in] BufferSize
Размер в байтах данных в буфере .
[out, optional] NewElement
В выходных данных значение TRUE означает успешное вставка нового элемента в универсальной таблице. Значение FALSE означает сбой вставки.
[in] NodeOrParent
Результат поиска предыдущего вызова RtlLookupElementGenericTableFullAvl. Это значение указывает на RtlInsertElementGenericTableFullAvl подпрограмме, является ли дерево пустым или если не пустым, следует ли вставить новую запись слева или справа от родительской записи. Параметр SearchResult может иметь любое из следующих значений:
TableEmptyTree
Дерево было пустым. Содержимое NodeOrParent не было изменено.
TableFoundNode
Подпрограмма RtlInsertElementGenericTableFullAvlAvl обнаружила запись таблицы, ключ которой соответствует данным в буфере . NodeOrParent содержит указатель на соответствующую запись.
TableInsertAsLeft
Подпрограмма RtlInsertElementGenericTableFullAvl не не найти запись таблицы, ключ которой соответствует данным в буфере . Если запись, для RtlInsertElementGenericTableFullAvlAvl в таблице, это будет левый дочерний элемент записи, на которую NodeOrParent.
TableInsertAsRight
Подпрограмма RtlInsertElementGenericTableFullAvl не не найти запись таблицы, ключ которой соответствует данным в буфере . Если запись, которую RtlInsertElementGenericTableFullAvl искали в таблице, это будет правильный дочерний элемент записи, на которую NodeOrParent указывает.
[in] SearchResult
Указатель на запись таблицы. Если подпрограмма RtlInsertElementGenericTableFullAvl соответствует записи, NodeOrParent указывает на соответствующую запись. Если подпрограмме RtlInsertElementGenericTableFullAvl не удается найти совпадение, NodeOrParent указывает на запись, которая будет родительским элементом записи, RtlInsertElertGenericTableFullAvlAvl подпрограмме.
Возвращаемое значение
RtlInsertElementGenericTableFullAvl возвращает указатель на данные пользователя для только что вставленной записи или пользовательские данные для соответствующей записи, которая уже находится в универсальной таблице. Если запись не найдена, но RtlInsertElementGenericTableFullAvl не удается вставить новую запись (например, так как AllocateRoutine завершается ошибкой), RtlInsertElementGenericTableFullAvl возвращает NULL.
Замечания
Чтобы вставить запись, RtlInsertElementGenericTableFullAvl вызывает CompareRoutine и AllocateRoutine, зарегистрированные при инициализации универсальной таблицы RtlInitializeGenericTableAvl. После вставки новой записи RtlInsertElementGenericTableFullAvl перебалансирует дерево ссылок AVL.
При вставке новой записи в таблицу данные копируются из буфера в новую запись. Таким образом, указатель, возвращаемый RtlInsertElementGenericTableFullAvl, никогда не равен буферу.
Если вызывающий CompareRoutine возвращает GenericEqual, предполагается, что данные буфера дублируют данные для существующей записи в универсальной таблице. В этом случае RtlInsertElementGenericTableFullAvl не добавляет новую запись (и поэтому не вызывает AllocateRoutine), так как универсальная таблица не может иметь повторяющиеся записи.
Если соответствующая запись уже существует в универсальной таблице, RtlInsertElementGenericTableFullAvlAvl возвращает указатель на данные существующей записи и задает NewElement значением FALSE.
Если в таблице нет соответствующей записи,RtlInsertElementGenericTableFullAvlAvl подпрограмма выделяет достаточно места для пользовательских данных новой записи (BufferSize) и ссылок, связанных с новой записью. Таким образом, общее количество байтов будет по крайней мере BufferSize + sizeof(BALANCED_LINKS). Вызывающий объект не должен использовать первые размер(BALANCED_LINKS) памяти, выделенной AllocateRoutine.
ВызывающиеRtl.. Подпрограммы GenericTableAvl отвечают за исключительно синхронизацию доступа к универсальной таблице. Эксклюзивный быстрый мьютекс является наиболее эффективным механизмом синхронизации, используемым для этой цели.
По умолчанию операционная система использует деревья воспроизведения для реализации универсальных таблиц, но RtlInsertElementGenericTableFullAvl работает только с деревьями Adelson-Velsky/Landis (AVL). Чтобы настроить универсальные подпрограммы таблиц для использования деревьев AVL вместо деревьев воспроизведения в драйвере, вставьте следующую инструкцию определения в общий файл заголовка перед включением Ntddk.h:
#define RTL_USE_AVL_TABLES 0
Если RTL_USE_AVL_TABLES не определен, необходимо использовать форму AVL универсальных подпрограмм таблиц. Например, используйте подпрограмму RtlInsertElementGenericTableFullAvl вместо RtlInsertElementGenericTableFull. В вызове RtlInsertElementGenericTableFullAvlвызывающий объект должен передать структуру таблицы RTL_AVL_TABLE, а не RTL_GENERIC_TABLE.
Вызывающие RtlInsertElementGenericTableFullAvl должны выполняться в IRQL < DISPATCH_LEVEL, если имеет одно из следующих условий:
- Выделенная вызывающей памятью таблица или буфера можно пространить.
- Вызывающий CompareRoutine или AllocateRoutine содержит код, доступный для страниц.
Требования
Требование | Ценность |
---|---|
минимальные поддерживаемые клиентские | Доступно в Windows XP и более поздних версиях операционных систем Windows. |
целевая платформа | Всеобщий |
заголовка | ntddk.h (include Ntddk.h, Ntifs.h) |
библиотеки | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | < DISPATCH_LEVEL (см. раздел "Примечания") |