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-Tabelle (AVL) (RTL_AVL_TABLE), die durch einen Aufruf von RtlInitializeGenericTableAvl initialisiert 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 der Daten in Bytes im Puffer.
[out, optional] NewElement
Bei der Ausgabe bedeutet der Wert TRUE , dass das Einfügen des neuen Elements in die generische Tabelle erfolgreich war. Ein Wert von FALSE bedeutet, dass beim Einfügen ein Fehler aufgetreten ist.
[in] NodeOrParent
Das Suchergebnis eines vorherigen Aufrufs von RtlLookupElementGenericTableFullAvl. Dieser Wert gibt für die RtlInsertElementGenericTableFullAvl-Routine an, ob die Struktur derzeit leer ist, oder wenn nicht leer, ob der neue Eintrag links oder rechts neben dem übergeordneten Eintrag eingefügt werden soll. Der SearchResult-Parameter kann einen der folgenden Werte aufweisen:
TableEmptyTree
Die Struktur war leer. Der Inhalt von NodeOrParent wurde nicht geändert.
TableFoundNode
Die RtlInsertElementGenericTableFullAvl-Routine hat einen Tabelleneintrag gefunden, 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 sich der Von RtlInsertElementGenericTableFullAvl gesuchte Eintrag in der Tabelle befindet, wäre er 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 sich der Von RtlInsertElementGenericTableFullAvl gesuchte Eintrag in der Tabelle befindet, wäre er das richtige untergeordnete Element des Eintrags, auf den NodeOrParent verweist.
[in] SearchResult
Ein Zeiger auf einen Tabelleneintrag. Wenn die RtlInsertElementGenericTableFullAvl-Routine mit einem Eintrag übereinstimmt, zeigt NodeOrParent auf den übereinstimmenden Eintrag. Wenn die RtlInsertElementGenericTableFullAvl-Routine keine Übereinstimmung findet, zeigt NodeOrParent auf den Eintrag, der das übergeordnete Element des Eintrags ist, nach dem die RtlInsertElementGenericTableFullAvl-Routine gesucht hat.
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 übereinstimmenden Eintrag gefunden wird, aber RtlInsertElementGenericTableFullAvl den neuen Eintrag nicht einfügen kann (z. B. weil die AllocateRoutine fehlschlägt), gibt RtlInsertElementGenericTableFullAvlNULL zurück.
Hinweise
Um einen Eintrag einzufügen, ruft RtlInsertElementGenericTableFullAvl die CompareRoutine und AllocateRoutine auf, die registriert wurden, als die generische Tabelle von RtlInitializeGenericTableAvl initialisiert wurde. Nach dem Einfügen des neuen Eintrags balanciert RtlInsertElementGenericTableFullAvl die AVL-Linkstruktur neu aus.
Wenn ein neuer Eintrag in die Tabelle eingefügt wird, werden seine Daten aus Puffer in den neuen Eintrag kopiert. Daher ist der von RtlInsertElementGenericTableFullAvl zurückgegebene Zeiger nie gleich Puffer.
Wenn compareRoutine des Aufrufers GenericEqual zurückgibt, wird davon ausgegangen, dass die Daten bei Buffer die Daten für einen vorhandenen Eintrag in der generischen Tabelle 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 bereits ein übereinstimmenden Eintrag in der generischen Tabelle vorhanden ist, gibt RtlInsertElementGenericTableFullAvl einen Zeiger auf die Daten des vorhandenen Eintrags zurück und legt NewElement auf FALSE fest.
Wenn bereits kein übereinstimmenden Eintrag in der Tabelle vorhanden ist, weist die RtlInsertElementGenericTableFullAvl-Routine genügend Speicherplatz für die Benutzerdaten des neuen Eintrags (BufferSize) und die dem neuen Eintrag zugeordneten Links zu. Daher ist die Gesamtanzahl der Bytes mindestens BufferSize + sizeof(BALANCED_LINKS). Der Aufrufer sollte nicht die ersten Sizeof(BALANCED_LINKS)-Bytes des Arbeitsspeichers verwenden, den die AllocateRoutine zuweist.
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-Bäumen (AVL). 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 Sie Ntddk.h einschließen:
#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 von RtlInsertElementGenericTableFull. Beim Aufruf von RtlInsertElementGenericTableFullAvl muss der Aufrufer eine RTL_AVL_TABLE Tabellenstruktur übergeben, anstatt RTL_GENERIC_TABLE.
Aufrufer von RtlInsertElementGenericTableFullAvl müssen bei IRQL < DISPATCH_LEVEL ausgeführt werden, wenn eine der folgenden Bedingungen erfüllt ist:
- Der vom Aufrufer zugewiesene Arbeitsspeicher bei Table oder bei Buffer kann ausgelagert werden.
- Die vom Aufrufer bereitgestellte CompareRoutine oder AllocateRoutine enthält ausserwählbaren Code.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Verfügbar in Windows XP und höheren Versionen der Windows-Betriebssysteme. |
Zielplattform | Universell |
Header | ntddk.h (include Ntddk.h, Ntifs.h) |
Bibliothek | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | < DISPATCH_LEVEL (siehe Abschnitt Hinweise) |