Функция 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

Указатель на буфер, выделенный вызывающим объектом, размер которого должен быть не менее sizeof(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... Подпрограммы GenericTable , вызывающие CompareRoutine , принимают указатель буфера в качестве параметра, который передается в свою очередь в CompareRoutine. Буфер содержит значение ключа, предоставленное вызывающим объектом, которое будет сопоставляться compareRoutine с ключом искомого элемента.

Если задано два таких значения ключа, CompareRoutine возвращает GenericLessThan, GenericGreaterThan или GenericEqual.

[in] AllocateRoutine

Точка входа подпрограммы обратного вызова выделения, объявленная следующим образом:

PVOID
(*PRTL_GENERIC_ALLOCATE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in CLONG  ByteSize
    );

Ниже приведены параметры AllocateRoutine .

Таблица (AllocateRoutine)

Указатель на универсальную таблицу.

ByteSize

Количество байтов, которые необходимо выделить.

Для каждого нового элемента метод AllocateRoutine вызывается для выделения памяти для данных, предоставленных вызывающей стороны, а также некоторой дополнительной памяти для использования Rtl... Подпрограммы GenericTable . Обратите внимание, что из-за этого "дополнительной памяти" подпрограммы, предоставляемые вызывающей стороной, не должны обращаться к первым (sizeof(RTL_SPLAY_LINKS) + sizeof(LIST_ENTRY)) байтам любого элемента в универсальной таблице.

[in] FreeRoutine

Точка входа подпрограммы обратного вызова отмены размещения, объявленная следующим образом:

VOID
(*PRTL_GENERIC_FREE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in PVOID  Buffer
    );

Ниже приведены параметры FreeRoutine .

Таблица (FreeRoutine)

Указатель на универсальную таблицу.

Буфер

Указатель на удаляемый элемент.

Rtl... Подпрограммы GenericTable вызывают FreeRoutine , чтобы освободить память для элементов, которые должны быть удалены из универсальной таблицы. FreeRoutine является противоположностью AllocateRoutine.

[in, optional] TableContext

Необязательный указатель на контекст, предоставленный вызывающим объектом, для универсальной таблицы. Этот параметр может принимать значение NULL.

Возвращаемое значение

None

Remarks

Файловые системы вызывают RtlInitializeGenericTable для инициализации универсальной таблицы для хранения данных, относящихся к файловой системе, таких как сведения о поиске имен для открытых файлов. Порядок сортировки, структура и содержимое элементов определяются вызывающим элементом.

Файловые системы должны вызывать RtlInitializeGenericTable для инициализации универсальной таблицы, прежде чем использовать любой другой Rtl... Подпрограммы GenericTable в новой универсальной таблице. Инициализированную структуру универсальной таблицы следует считать непрозрачной.

Абоненты Rtl... Подпрограммы GenericTable отвечают за исключительно синхронизацию доступа к универсальной таблице. Эксклюзивный быстрый мьютекс является наиболее эффективным механизмом синхронизации для этой цели.

Объект CompareRoutine , предоставленный вызывающей стороны, вызывается перед элементом AllocateRoutine , чтобы найти соответствующее расположение, в которое следует вставить новый элемент. CompareRoutine также вызывается перед FreeRoutine для поиска удаляемого элемента.

По умолчанию операционная система использует деревья splay для реализации универсальных таблиц. В некоторых случаях операции с деревом splay сделают дерево глубоким и узким и может даже превратить его в прямую линию. Очень глубокие деревья ухудшают производительность поиска. С помощью деревьев Adelson-Velsky/Landis (AVL) можно обеспечить более сбалансированную и неглубокую реализацию универсальных таблиц. Если вы хотите настроить универсальные подпрограммы таблицы для использования деревьев AVL вместо деревьев splay в драйвере, вставьте следующую инструкцию define в общий файл заголовка перед включением Ntddk.h:

`#define RTL_USE_AVL_TABLES 0`

Если вы хотите использовать таблицы AVL, а RTL_USE_AVL_TABLES не определен, необходимо использовать форму AVL универсальных подпрограмм таблиц. Например, используйте подпрограмму RtlInitializeGenericTableAvl вместо RtlInitializeGenericTable. RtlInitializeGenericTableAvl возвращает инициализированную структуру таблицы RTL_AVL_TABLE в буфере, на которую указывает параметр Table . При вызове RtlInitializeGenericTableAvl вызывающий объект должен передать PRTL_AVL_COMPARE_ROUTINE типизированной процедуры обратного вызова сравнения, PRTL_AVL_ALLOCATE_ROUTINE-типизированной процедуры обратного вызова выделения и PRTL_AVL_FREE_ROUTINE-типизированной процедуры обратного вызова для освобождения, а не аналогичные подпрограммы PRTL_GENERIC_Xxxx.

Вызывающие объект RtlInitializeGenericTable должны выполняться в среде IRQL <= DISPATCH_LEVEL. Обратите внимание, что если Rtl... Подпрограммы GenericTable должны использоваться на DISPATCH_LEVEL IRQL, compareRoutine, AllocateRoutine и FreeRoutine должны быть непайджируемым кодом, а Свойство AllocateRoutine должно выделять память из непагрегированного пула.

Требования

Требование Значение
Целевая платформа Универсальное
Верхняя часть ntddk.h (включая Ntddk.h, Ntifs.h, Fltkernel.h)
Библиотека NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= DISPATCH_LEVEL (см. раздел "Примечания")

См. также раздел

ExInitializeFastMutex

RtlDeleteElementGenericTable

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable

RtlInsertElementGenericTable

RtlLookupElementGenericTable

RtlNumberGenericTableElements