RtlCreateHeap-Funktion (ntifs.h)
Die RtlCreateHeap-Routine erstellt ein Heapobjekt, das vom aufrufenden Prozess verwendet werden kann. Diese Routine reserviert Speicherplatz im virtuellen Adressraum des Prozesses und ordnet physischen Speicher für einen angegebenen anfänglichen Teil dieses Blocks zu.
Syntax
NTSYSAPI PVOID RtlCreateHeap(
[in] ULONG Flags,
[in, optional] PVOID HeapBase,
[in, optional] SIZE_T ReserveSize,
[in, optional] SIZE_T CommitSize,
[in, optional] PVOID Lock,
[in, optional] PRTL_HEAP_PARAMETERS Parameters
);
Parameter
[in] Flags
Flags, die optionale Attribute des Heaps angeben. Diese Optionen wirken sich auf den nachfolgenden Zugriff auf den neuen Heap durch Aufrufe der Heapfunktionen (RtlAllocateHeap und RtlFreeHeap) aus.
Aufrufer sollten diesen Parameter auf 0 festlegen, wenn keine optionalen Attribute angefordert werden.
Dieser Parameter kann einen oder mehrere der folgenden Werte aufweisen.
Wert | Bedeutung |
---|---|
HEAP_GENERATE_EXCEPTIONS | Gibt an, dass das System einen Heapfehler anzeigt, indem eine Ausnahme ausgelöst wird, z. B. STATUS_NO_MEMORY, anstatt NULL zurückzugeben. |
HEAP_GROWABLE | Gibt an, dass der Heap wachsen kann. Muss angegeben werden, wenn HeapBase NULL ist. |
HEAP_NO_SERIALIZE | Gibt an, dass der gegenseitige Ausschluss nicht verwendet wird, wenn die Heapfunktionen Speicher aus diesem Heap zuweisen und freigeben. Wenn HEAP_NO_SERIALIZE nicht angegeben ist, wird standardmäßig der Zugriff auf den Heap serialisiert. Durch die Serialisierung des Heapzugriffs können zwei oder mehr Threads gleichzeitig Arbeitsspeicher aus demselben Heap zuweisen und freigeben. |
[in, optional] HeapBase
Gibt eine von zwei Aktionen an:
Wenn HeapBase ein Wert ohne NULL ist, gibt er die Basisadresse für einen Block des vom Aufrufer zugewiesenen Speichers an, der für den Heap verwendet werden soll.
Wenn HeapBase NULL ist, ordnet RtlCreateHeap den Systemspeicher für den Heap aus dem virtuellen Adressraum des Prozesses zu.
[in, optional] ReserveSize
Wenn ReserveSize ein nonzero-Wert ist, gibt er die anfängliche Arbeitsspeichermenge in Bytes an, die für den Heap reserviert werden soll. RtlCreateHeap rundet ReserveSize bis zur Grenze der nächsten Seite auf und reserviert dann einen Block dieser Größe für den Heap.
Dieser Parameter ist optional und kann null sein. In der folgenden Tabelle wird die Interaktion der Parameter "ReserveSize" und "CommitSize" zusammengefasst.
Werte | Ergebnis |
---|---|
ReservierenSize 0, CommitSize 0 | 64 Seiten sind zunächst für den Heap reserviert. Zunächst wird eine Seite festgelegt. |
ReserveSize zero, CommitSize nonzero | RtlCreateHeap legt ReserveSize auf CommitSize fest und rundet dann ReserveSize auf das nächste Vielfache von (PAGE_SIZE * 16) auf. |
ReserveSize nonzero, CommitSize zero | Zunächst wird eine Seite für den Heap festgelegt. |
ReserveSize nonzero, CommitSize nonzero | Wenn CommitSize größer als ReserveSize ist, reduziert RtlCreateHeapCommitSize auf ReserveSize. |
[in, optional] CommitSize
Wenn CommitSize ein nonzero-Wert ist, gibt er die anfängliche Menge an Arbeitsspeicher in Bytes an, die für den Heap committ werden soll. RtlCreateHeap rundet CommitSize bis zur Begrenzung der nächsten Seite ab und committet dann einen Block dieser Größe im virtuellen Adressraum des Prozesses für den Heap.
Dieser Parameter ist optional und kann null sein.
[in, optional] Lock
Zeiger auf eine undurchsichtige ERESOURCE-Struktur, die als Ressourcensperre verwendet werden soll. Dieser Parameter ist optional und kann NULL sein. Wenn sie vom Aufrufer bereitgestellt wird, muss die Struktur aus einem nicht ausgestellten Pool zugeordnet und durch Aufrufen von ExInitializeResourceLite oder ExReinitializeResourceLite initialisiert werden. Wenn das HEAP_NO_SERIALIZE-Flag festgelegt ist, muss dieser Parameter NULL sein.
[in, optional] Parameters
Zeiger auf eine RTL_HEAP_PARAMETERS-Struktur , die Parameter enthält, die beim Erstellen des Heaps angewendet werden sollen. Dieser Parameter ist optional und kann NULL sein.
Rückgabewert
RtlCreateHeap gibt ein Handle zurück, das beim Zugriff auf den erstellten Heap verwendet werden soll.
Hinweise
RtlCreateHeap erstellt ein privates Heap-Objekt, von dem aus der aufrufende Prozess Speicherblöcke zuordnen kann, indem RtlAllocateHeap aufgerufen wird. Die anfängliche Commitgröße bestimmt die Anzahl der Seiten, die anfänglich für den Heap zugewiesen werden. Die anfängliche Reservegröße bestimmt die Anzahl der Seiten, die anfänglich für den Heap reserviert sind. Seiten, die reserviert, aber nicht festgelegt sind, erstellen einen Block im virtuellen Adressraum des Prozesses, in den sich der Heap erweitern kann.
Wenn Zuordnungsanforderungen von RtlAllocateHeap die anfängliche Commitgröße des Heaps überschreiten, werden vom System zusätzliche Seiten des physischen Speichers für den Heap bis zur maximalen Größe des Heaps committen. Wenn der Heap nicht nachwachsen kann, ist seine maximale Größe auf die anfängliche Reservegröße beschränkt.
Wenn der Heap wachsen kann, wird seine Größe nur durch den verfügbaren Arbeitsspeicher begrenzt. Wenn Anforderungen von RtlAllocateHeap die aktuelle Größe der committeten Seiten überschreiten, ruft das System ZwAllocateVirtualMemory auf, um den benötigten Arbeitsspeicher abzurufen, vorausgesetzt, der physische Speicher ist verfügbar.
Wenn der Heap nicht nachwachsen kann, tritt außerdem eine absolute Einschränkung auf: Die maximale Größe eines Speicherblocks im Heap beträgt 0x7F000 Bytes. Der Schwellenwert für den virtuellen Arbeitsspeicher des Heaps entspricht der maximalen Heapblockgröße oder dem Wert des VirtualMemoryThreshold-Elements der Parameters-Struktur , je nachdem, welcher Wert kleiner ist. Der Heap muss möglicherweise auch die Anforderungsgröße zu Metadaten- und Ausrichtungszwecken abpaden, sodass Anforderungen zum Zuweisen von Blöcken innerhalb von 4096 Bytes (1 Seite) des VirtualMemoryThreshold möglicherweise fehlschlagen, auch wenn die maximale Größe des Heaps groß genug ist, um den Block zu enthalten. (Weitere Informationen zu VirtualMemoryThreshold finden Sie in den Membern des Parameters-Parameters zu RtlCreateHeap.)
Wenn der Heap vergrößert werden kann, schlagen Anforderungen zum Zuweisen von Blöcken, die den Schwellenwert für den virtuellen Speicher des Heaps überschreiten, nicht automatisch fehl. das System ruft ZwAllocateVirtualMemory auf, um den für diese großen Blöcke erforderlichen Arbeitsspeicher abzurufen.
Auf den Arbeitsspeicher eines privaten Heapobjekts kann nur der Prozess zugreifen, der es erstellt hat.
Das System verwendet Arbeitsspeicher aus dem privaten Heap, um Heapunterstützungsstrukturen zu speichern, sodass nicht die gesamte angegebene Heapgröße für den Prozess verfügbar ist. Wenn RtlAllocateHeap beispielsweise 64 KB (K) von einem Heap mit einer maximalen Größe von 64 KB anfordert, schlägt die Anforderung möglicherweise aufgrund des Systemaufwands fehl.
Wenn HEAP_NO_SERIALIZE nicht angegeben ist (der einfache Standardwert), serialisiert der Heap den Zugriff innerhalb des aufrufenden Prozesses. Die Serialisierung stellt einen gegenseitigen Ausschluss sicher, wenn zwei oder mehr Threads versuchen, gleichzeitig Blöcke aus demselben Heap zuzuweisen oder frei zu geben. Die Serialisierung verursacht geringe Leistungskosten, muss jedoch immer dann verwendet werden, wenn mehrere Threads Arbeitsspeicher aus demselben Heap zuweisen und freizugeben.
Durch festlegen HEAP_NO_SERIALIZE wird der gegenseitige Ausschluss auf dem Heap beseitigt. Ohne Serialisierung können zwei oder mehr Threads, die dasselbe Heaphandle verwenden, versuchen, gleichzeitig Arbeitsspeicher zuzuweisen oder freizugeben, was wahrscheinlich zu Einer Beschädigung des Heaps führt. Daher können HEAP_NO_SERIALIZE nur in den folgenden Situationen sicher verwendet werden:
Der Prozess verfügt nur über einen Thread.
Der Prozess verfügt über mehrere Threads, aber nur ein Thread ruft die Heapfunktionen für einen bestimmten Heap auf.
Der Prozess verfügt über mehrere Threads, und die Anwendung bietet einen eigenen Mechanismus zum gegenseitigen Ausschluss von einem bestimmten Heap.
Hinweis
Um sich vor einer Zugriffsverletzung zu schützen, verwenden Sie die strukturierte Ausnahmebehandlung, um Code zu schützen, der in einen Heap schreibt oder daraus liest. Weitere Informationen zur strukturierten Ausnahmebehandlung mit Speicherzugriffen finden Sie unter Behandeln von Ausnahmen**.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Windows XP |
Zielplattform | Universell |
Header | ntifs.h (include Ntifs.h) |
Bibliothek | Ntoskrnl.lib |
DLL | NtosKrnl.exe (Kernelmodus); Ntdll.dll (Benutzermodus) |
IRQL | < DISPATCH_LEVEL |