Funzione RtlCreateHeap (ntifs.h)
La routine RtlCreateHeap crea un oggetto heap che può essere utilizzato dal processo chiamante. Questa routine riserva spazio nello spazio indirizzi virtuale del processo e alloca l'archiviazione fisica per una parte iniziale specificata di questo blocco.
Sintassi
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
);
Parametri
[in] Flags
Flag che specificano attributi facoltativi dell'heap. Queste opzioni influiscono sull'accesso successivo al nuovo heap tramite chiamate alle funzioni heap (RtlAllocateHeap e RtlFreeHeap).
I chiamanti devono impostare questo parametro su zero se non sono richiesti attributi facoltativi.
Questo parametro può essere uno o più dei valori seguenti.
Valore | Significato |
---|---|
HEAP_GENERATE_EXCEPTIONS | Specifica che il sistema indicherà un errore dell'heap generando un'eccezione, ad esempio STATUS_NO_MEMORY, anziché restituire NULL. |
HEAP_GROWABLE | Specifica che l'heap è espandibile. Deve essere specificato se heapBase è NULL. |
HEAP_NO_SERIALIZE | Specifica che l'esclusione reciproca non verrà usata quando le funzioni heap allocano e liberano memoria da questo heap. Il valore predefinito, quando non viene specificato HEAP_NO_SERIALIZE, consiste nel serializzare l'accesso all'heap. La serializzazione dell'accesso heap consente a due o più thread di allocare e liberare memoria contemporaneamente dallo stesso heap. |
[in, optional] HeapBase
Specifica una delle due azioni seguenti:
Se heapBase è un valore non NULL, specifica l'indirizzo di base per un blocco di memoria allocata dal chiamante da usare per l'heap.
Se heapBase è NULL, RtlCreateHeap alloca la memoria di sistema per l'heap dallo spazio indirizzi virtuale del processo.
[in, optional] ReserveSize
Se ReserveSize è un valore diverso da zero, specifica la quantità iniziale di memoria, in byte, da riservare per l'heap. RtlCreateHeap arrotonda ReserveSize fino al limite di pagina successivo e quindi riserva un blocco di tale dimensione per l'heap.
Questo parametro è facoltativo e può essere zero. La tabella seguente riepiloga l'interazione dei parametri
Valori | Risultato |
---|---|
ReserveSize zero, CommitSize zero | 64 pagine sono inizialmente riservate all'heap. Viene eseguito inizialmente il commit di una pagina. |
ReserveSize zero, CommitSize diverso da zero | RtlCreateHeap imposta ReserveSize essere uguale a CommitSizee quindi arrotonda ReserveSize fino al multiplo più vicino di (PAGE_SIZE * 16). |
ReserveSize diverso da zero, CommitSize zero | Inizialmente viene eseguito il commit di una pagina per l'heap. |
ReserveSize diverso da zero, CommitSize diverso da zero | Se |
[in, optional] CommitSize
Se CommitSize è un valore diverso da zero, specifica la quantità iniziale di memoria, espressa in byte, per eseguire il commit per l'heap. RtlCreateHeap arrotonda CommitSize fino al limite di pagina successivo e quindi esegue il commit di un blocco di tale dimensione nello spazio indirizzi virtuale del processo per l'heap.
Questo parametro è facoltativo e può essere zero.
[in, optional] Lock
Puntatore a una struttura ERESOURCE opaca da usare come blocco delle risorse. Questo parametro è facoltativo e può essere NULL. Se fornito dal chiamante, la struttura deve essere allocata da un pool non di paging e inizializzata chiamando ExInitializeResourceLite o ExReinitializeResourceLite. Se il flag HEAP_NO_SERIALIZE è impostato, questo parametro deve essere NULL.
[in, optional] Parameters
Puntatore a una struttura RTL_HEAP_PARAMETERS che contiene parametri da applicare durante la creazione dell'heap. Questo parametro è facoltativo e può essere NULL.
Valore restituito
RtlCreateHeap restituisce un handle da usare per accedere all'heap creato.
Osservazioni
RtlCreateHeap crea un oggetto heap privato da cui il processo chiamante può allocare blocchi di memoria chiamando RtlAllocateHeap. Le dimensioni del commit iniziale determinano il numero di pagine inizialmente allocate per l'heap. Le dimensioni di riserva iniziali determinano il numero di pagine inizialmente riservate per l'heap. Le pagine riservate ma non sottoposte a commit creano un blocco nello spazio indirizzi virtuale del processo in cui l'heap può espandersi.
Se le richieste di allocazione effettuate da RtlAllocateHeap superare le dimensioni iniziali del commit dell'heap, il sistema esegue il commit di pagine aggiuntive di archiviazione fisica per l'heap, fino alle dimensioni massime dell'heap. Se l'heap non è scalabile, la dimensione massima è limitata alle dimensioni iniziali della riserva.
Se l'heap è espandibile, le dimensioni sono limitate solo dalla memoria disponibile. Se le richieste da RtlAllocateHeap superare le dimensioni correnti delle pagine di cui è stato eseguito il commit, il sistema chiama ZwAllocateVirtualMemory per ottenere la memoria necessaria, presupponendo che l'archiviazione fisica sia disponibile.
Inoltre, se l'heap non è scalabile, si verifica una limitazione assoluta: la dimensione massima di un blocco di memoria nell'heap è 0x7F000 byte. La soglia di memoria virtuale dell'heap è uguale alla dimensione massima del blocco heap o al valore della
Se l'heap è scalabile, le richieste di allocare blocchi superiori alla soglia di memoria virtuale dell'heap non hanno esito negativo automaticamente; il sistema chiama ZwAllocateVirtualMemory per ottenere la memoria necessaria per tali blocchi di grandi dimensioni.
La memoria di un oggetto heap privato è accessibile solo al processo che lo ha creato.
Il sistema usa memoria dall'heap privato per archiviare le strutture di supporto dell'heap, quindi non tutte le dimensioni dell'heap specificate sono disponibili per il processo. Ad esempio, se RtlAllocateHeap richiede 64 kilobyte (K) da un heap con una dimensione massima di 64 K, la richiesta potrebbe non riuscire a causa del sovraccarico del sistema.
Se HEAP_NO_SERIALIZE non viene specificato (impostazione predefinita semplice), l'heap serializzerà l'accesso all'interno del processo chiamante. La serializzazione garantisce l'esclusione reciproca quando due o più thread tentano di allocare o liberare contemporaneamente blocchi dallo stesso heap. La serializzazione prevede un costo di prestazioni ridotto, ma deve essere usata ogni volta che più thread allocano e liberano memoria dallo stesso heap.
L'impostazione di HEAP_NO_SERIALIZE elimina l'esclusione reciproca nell'heap. Senza serializzazione, due o più thread che usano lo stesso handle heap potrebbero tentare di allocare o liberare memoria contemporaneamente, causando probabilmente il danneggiamento nell'heap. Pertanto, HEAP_NO_SERIALIZE può essere usato in modo sicuro solo nelle situazioni seguenti:
Il processo ha un solo thread.
Il processo ha più thread, ma un solo thread chiama le funzioni dell'heap per un heap specifico.
Il processo ha più thread e l'applicazione fornisce il proprio meccanismo per l'esclusione reciproca in un heap specifico.
Nota
Per proteggersi da una violazione di accesso, usare la gestione delle eccezioni strutturata per proteggere qualsiasi codice che scrive o legge da un heap. Per altre informazioni sulla gestione delle eccezioni strutturate con gli accessi alla memoria, vedere Gestione delle eccezioni**.
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Windows XP |
piattaforma di destinazione | Universale |
intestazione |
ntifs.h (include Ntifs.h) |
libreria |
Ntoskrnl.lib |
dll | NtosKrnl.exe (modalità kernel); Ntdll.dll (modalità utente) |
IRQL | < DISPATCH_LEVEL |