RtlCreateHeap - NtDoc

Native API online documentation, based on the System Informer (formerly Process Hacker) phnt headers
#ifndef _NTRTL_H

/**
 * The RtlCreateHeap routine creates a heap object that can be used by the calling process. This routine reserves
 * space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.
 *
 * \param Flags Flags specifying optional attributes of the heap.
 * \param HeapBase If HeapBase is a non-NULL value, it specifies the base address for a block of caller-allocated memory to use for the heap.
 * \param ReserveSize If ReserveSize is a nonzero value, it specifies the initial amount of memory, in bytes, to reserve for the heap.
 * \param CommitSize If CommitSize is a nonzero value, it specifies the initial amount of memory, in bytes, to commit for the heap.
 * \param Lock Pointer to an opaque structure to be used as the heap lock.
 * \param Parameters Pointer to a RTL_HEAP_PARAMETERS structure that contains parameters to be applied when creating the heap.
 * \return RtlCreateHeap returns a handle to be used in accessing the created heap.
 * \remarks https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlcreateheap
 */
_Success_(return != 0)
_Must_inspect_result_
_Ret_maybenull_
NTSYSAPI
HANDLE
NTAPI
RtlCreateHeap(
    _In_ ULONG Flags,
    _In_opt_ PVOID HeapBase,
    _In_opt_ SIZE_T ReserveSize,
    _In_opt_ SIZE_T CommitSize,
    _In_opt_ PVOID Lock,
    _When_((Flags & HEAP_CREATE_SEGMENT_HEAP) != 0, _In_reads_bytes_opt_(sizeof(RTL_SEGMENT_HEAP_PARAMETERS)))
    _When_((Flags & HEAP_CREATE_SEGMENT_HEAP) == 0, _In_reads_bytes_opt_(sizeof(RTL_HEAP_PARAMETERS)))
    _In_opt_ PVOID Parameters
    );

#endif

View code on GitHub
// ntifs.h

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
);
View the official Windows Driver Kit DDI reference

NtDoc

No description available.

Windows Driver Kit DDI reference (nf-ntifs-rtlcreateheap)

RtlCreateHeap function

Description

The RtlCreateHeap routine creates a heap object that can be used by the calling process. This routine reserves space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.

Parameters

Flags [in]

Flags specifying optional attributes of the heap. These options affect subsequent access to the new heap through calls to the heap functions (RtlAllocateHeap and RtlFreeHeap).

Callers should set this parameter to zero if no optional attributes are requested.

This parameter can be one or more of the following values.

Value Meaning
HEAP_GENERATE_EXCEPTIONS Specifies that the system will indicate a heap failure by raising an exception, such as STATUS_NO_MEMORY, instead of returning NULL.
HEAP_GROWABLE Specifies that the heap is growable. Must be specified if HeapBase is NULL.
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used when the heap functions allocate and free memory from this heap. The default, when HEAP_NO_SERIALIZE is not specified, is to serialize access to the heap. Serialization of heap access allows two or more threads to simultaneously allocate and free memory from the same heap.

HeapBase [in, optional]

Specifies one of two actions:

If HeapBase is a non-NULL value, it specifies the base address for a block of caller-allocated memory to use for the heap.

If HeapBase is NULL, RtlCreateHeap allocates system memory for the heap from the process's virtual address space.

ReserveSize [in, optional]

If ReserveSize is a nonzero value, it specifies the initial amount of memory, in bytes, to reserve for the heap. RtlCreateHeap rounds ReserveSize up to the next page boundary, and then reserves a block of that size for the heap.

This parameter is optional and can be zero. The following table summarizes the interaction of the ReserveSize and CommitSize parameters.

Values Result
ReserveSize zero, CommitSize zero 64 pages are initially reserved for the heap. One page is initially committed.
ReserveSize zero, CommitSize nonzero RtlCreateHeap sets ReserveSize to be equal to CommitSize, and then rounds ReserveSize up to the nearest multiple of (PAGE_SIZE * 16).
ReserveSize nonzero, CommitSize zero One page is initially committed for the heap.
ReserveSize nonzero, CommitSize nonzero If CommitSize is greater than ReserveSize, RtlCreateHeap reduces CommitSize to ReserveSize.

CommitSize [in, optional]

If CommitSize is a nonzero value, it specifies the initial amount of memory, in bytes, to commit for the heap. RtlCreateHeap rounds CommitSize up to the next page boundary, and then commits a block of that size in the process's virtual address space for the heap.

This parameter is optional and can be zero.

Lock [in, optional]

Pointer to an opaque ERESOURCE structure to be used as a resource lock. This parameter is optional and can be NULL. When provided by the caller, the structure must be allocated from nonpaged pool and initialized by calling ExInitializeResourceLite or ExReinitializeResourceLite. If the HEAP_NO_SERIALIZE flag is set, this parameter must be NULL.

Parameters [in, optional]

Pointer to a RTL_HEAP_PARAMETERS structure that contains parameters to be applied when creating the heap. This parameter is optional and can be NULL.

Return value

On success, RtlCreateHeap returns a handle to be used in accessing the created heap. If RtlCreateHeap fails for any reason, it returns NULL. Reason for failure include:

Remarks

RtlCreateHeap creates a private heap object from which the calling process can allocate memory blocks by calling RtlAllocateHeap. The initial commit size determines the number of pages that are initially allocated for the heap. The initial reserve size determines the number of pages that are initially reserved for the heap. Pages that are reserved but uncommitted create a block in the process's virtual address space into which the heap can expand.

If allocation requests made by RtlAllocateHeap exceed the heap's initial commit size, the system commits additional pages of physical storage for the heap, up to the heap's maximum size. If the heap is nongrowable, its maximum size is limited to its initial reserve size.

If the heap is growable, its size is limited only by available memory. If requests by RtlAllocateHeap exceed the current size of committed pages, the system calls ZwAllocateVirtualMemory to obtain the memory needed, assuming that the physical storage is available.

In addition, if the heap is nongrowable, an absolute limitation arises: the maximum size of a memory block in the heap is 0x7F000 bytes. The virtual memory threshold of the heap is equal to the maximum heap block size or the value of the VirtualMemoryThreshold member of the Parameters structure, whichever is less. The heap also may need to pad the request size for metadata and alignment purposes so requests to allocate blocks within 4096 Bytes (1 Page) of the VirtualMemoryThreshold may fail even if the maximum size of the heap is large enough to contain the block. (For more information about VirtualMemoryThreshold, see the members of the Parameters parameter to RtlCreateHeap.)

If the heap is growable, requests to allocate blocks larger than the heap's virtual memory threshold do not automatically fail; the system calls ZwAllocateVirtualMemory to obtain the memory needed for such large blocks.

The memory of a private heap object is accessible only to the process that created it.

The system uses memory from the private heap to store heap support structures, so not all of the specified heap size is available to the process. For example, if RtlAllocateHeap requests 64 kilobytes (K) from a heap with a maximum size of 64K, the request may fail because of system overhead.

If HEAP_NO_SERIALIZE is not specified (the simple default), the heap will serialize access within the calling process. Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap.

Setting HEAP_NO_SERIALIZE eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. Therefore, HEAP_NO_SERIALIZE can safely be used only in the following situations:

[!NOTE] To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a heap. For more information about structured exception handling with memory accesses, see Handling Exceptions**.

See also

RtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap


NTinternals.net (undocumented.ntinternals.net)

This function is documented in Windows Driver Kit.


Flags

Flags are defined in <WinNT.h>. Can be one of following:

Base

Base address, where heap should be created. If memory was previously allocated at this address, heap is created at the nearest possible virtual address.

Reserve

How much bytes should be reserved. See NtAllocateVirtualMemory.

Commit

How many bytes should be committed. If Reserve is greater than zero, Commit must be less or equal to Reserve.

Lock

If set, heap will be locked. See RtlLockHeap / RtlUnlockHeap.

RtlHeapParams

Pointer to RTL_HEAP_DEFINITION structure. On NT 4.0 all bytes of this (except length field) are set to zero.

Documented by

See also