RtlInsertElementGenericTableFullAvl-Funktion (ntddk.h)
Die RtlInsertElementGenericTableFullAvl Routine fügt einer generischen Tabelle einen neuen Eintrag hinzu.
Syntax
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
);
Parameter
[in] Table
Zeiger auf eine generische Adelson-Velsky/Landis (AVL)-Tabelle (RTL_AVL_TABLE), die durch einen Aufruf von RtlInitializeGenericTableAvlinitialisiert wurde.
[in] Buffer
Ein vom Aufrufer zugewiesener Puffer, der die Benutzerdaten enthält, die in das neue Element kopiert werden sollen. Weitere Informationen finden Sie unter RtlInitializeGenericTableAvl.
[in] BufferSize
Größe in Byte von Daten in Puffer.
[out, optional] NewElement
Bei der Ausgabe bedeutet ein Wert von TRUE, dass das Einfügen des neuen Elements in die generische Tabelle erfolgreich war. Ein Wert von FALSE bedeutet, dass die Einfügung fehlgeschlagen ist.
[in] NodeOrParent
Das Suchergebnis eines vorherigen Aufrufs von RtlLookupElementGenericTableFullAvl. Dieser Wert gibt den RtlInsertElementGenericTableFullAvl Routine an, ob die Struktur aktuell leer ist oder nicht leer ist, ob der neue Eintrag links oder rechts vom übergeordneten Eintrag eingefügt werden soll. Der parameter SearchResult kann einen der folgenden Werte aufweisen:
TableEmptyTree
Die Struktur war leer. Der Inhalt NodeOrParent- wurde nicht geändert.
TableFoundNode
Die RtlInsertElementGenericTableFullAvl Routine fand einen Tabelleneintrag, dessen Schlüssel mit den Daten in Bufferübereinstimmt. NodeOrParent- enthält einen Zeiger auf den übereinstimmenden Eintrag.
TableInsertAsLeft
Die RtlInsertElementGenericTableFullAvl Routine hat keinen Tabelleneintrag gefunden, dessen Schlüssel mit den Daten in Bufferübereinstimmt. Wenn der Eintrag, nach dem RtlInsertElementGenericTableFullAvl gesucht wurde, in der Tabelle enthalten wäre, wäre es das linke untergeordnete Element des Eintrags, auf den NodeOrParent verweist.
TableInsertAsRight
Die RtlInsertElementGenericTableFullAvl Routine hat keinen Tabelleneintrag gefunden, dessen Schlüssel mit den Daten in Bufferübereinstimmt. Wenn der Eintrag, nach dem RtlInsertElementGenericTableFullAvl gesucht wurde, in der Tabelle enthalten wäre, wäre es das richtige untergeordnete Element des Eintrags, auf den NodeOrParent verweist.
[in] SearchResult
Ein Zeiger auf einen Tabelleneintrag. Wenn die RtlInsertElementGenericTableFullAvl Routine einem Eintrag entspricht, NodeOrParent auf den übereinstimmenden Eintrag verweist. Wenn die RtlInsertElementGenericTableFullAvl Routine keine Übereinstimmung findet, verweist NodeOrParent auf den Eintrag, der das übergeordnete Element des Eintrags sein würde, nach dem RtlInsertElementGenericTableFullAvl Routine gesucht wurde.
Rückgabewert
RtlInsertElementGenericTableFullAvl gibt einen Zeiger auf die Benutzerdaten für den neu eingefügten Eintrag oder die Benutzerdaten für einen übereinstimmenden Eintrag zurück, der sich bereits in der generischen Tabelle befindet. Wenn kein übereinstimmender Eintrag gefunden wird, aber RtlInsertElementGenericTableFullAvl den neuen Eintrag nicht einfügen kann (z. B. weil die AllocateRoutine fehlschlägt), gibt RtlInsertElementGenericTableFullAvlNULLzurück.
Bemerkungen
Um einen Eintrag einzufügen, ruft RtlInsertElementGenericTableFullAvl die CompareRoutine und AllocateRoutine auf, die beim Initialisieren der generischen Tabelle von RtlInitializeGenericTableAvlregistriert wurden. Nach dem Einfügen des neuen Eintrags RtlInsertElementGenericTableFullAvl die AVL-Verknüpfungsstruktur neu ausbalanciert.
Wenn ein neuer Eintrag in die Tabelle eingefügt wird, werden die Daten aus Buffer in den neuen Eintrag kopiert. Der von RtlInsertElementGenericTableFullAvl zurückgegebene Zeiger entspricht also nie Buffer.
Wenn die CompareRoutine- des Aufrufers GenericEqualzurückgibt, werden die Daten bei Buffer angenommen, um die Daten für einen vorhandenen Eintrag in der generischen Tabelle zu duplizieren. In diesem Fall fügt RtlInsertElementGenericTableFullAvl den neuen Eintrag nicht hinzu (und ruft daher nicht die AllocateRoutine) auf, da eine generische Tabelle keine doppelten Einträge enthalten kann.
Wenn in der generischen Tabelle bereits ein übereinstimmener Eintrag vorhanden ist, gibt RtlInsertElementGenericTableFullAvl einen Zeiger auf die Daten des vorhandenen Eintrags zurück und legt NewElement- auf FALSEfest.
Wenn in der Tabelle bereits kein übereinstimmender Eintrag vorhanden ist, weistRtlInsertElementGenericTableFullAvl Routine ausreichend Platz für die Benutzerdaten des neuen Eintrags zu (BufferSize) sowie die Verknüpfungen, die dem neuen Eintrag zugeordnet sind. Die Gesamtzahl der Bytes beträgt somit mindestens BufferSize + Größe(BALANCED_LINKS). Der Aufrufer sollte nicht die erste Größe von(BALANCED_LINKS) Bytes des Speichers verwenden, den die AllocateRoutinezuweist.
Anrufer derRtl.. GenericTableAvl Routinen sind für die ausschließliche Synchronisierung des Zugriffs auf die generische Tabelle verantwortlich. Ein exklusiver schneller Mutex ist der effizienteste Synchronisierungsmechanismus für diesen Zweck.
Standardmäßig verwendet das Betriebssystem Splay-Strukturen, um generische Tabellen zu implementieren, aber die RtlInsertElementGenericTableFullAvl Routine funktioniert nur mit Adelson-Velsky/Landis (AVL)-Strukturen. Um die generischen Tabellenroutinen für die Verwendung von AVL-Strukturen anstelle von Wiedergabestrukturen in Ihrem Treiber zu konfigurieren, fügen Sie die folgende Define-Anweisung in eine allgemeine Headerdatei ein, bevor Ntddk.heingeschlossen wird:
#define RTL_USE_AVL_TABLES 0
Wenn RTL_USE_AVL_TABLES nicht definiert ist, müssen Sie die AVL-Form der generischen Tabellenroutinen verwenden. Verwenden Sie beispielsweise die RtlInsertElementGenericTableFullAvl Routine anstelle RtlInsertElementGenericTableFull. Im Aufruf von RtlInsertElementGenericTableFullAvlmuss der Aufrufer eine RTL_AVL_TABLE Tabellenstruktur statt RTL_GENERIC_TABLEübergeben.
Anrufer von RtlInsertElementGenericTableFullAvl müssen bei IRQL-< DISPATCH_LEVEL ausgeführt werden, wenn eine der folgenden Bedingungen gilt:
- Der vom Aufrufer zugewiesene Speicher in Table oder bei Buffer kann ausgelagert werden.
- Der vom Aufrufer bereitgestellte CompareRoutine oder AllocateRoutine- enthält ausgelagerten Code.
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Client- | Verfügbar in Windows XP und höheren Versionen von Windows-Betriebssystemen. |
Zielplattform- | Universal |
Header- | ntddk.h (enthalten Ntddk.h, Ntifs.h) |
Library | NtosKrnl.lib |
DLL- | NtosKrnl.exe |
IRQL- | < DISPATCH_LEVEL (siehe Abschnitt "Hinweise") |