Función RtlCreateHeap (ntifs.h)

La rutina RtlCreateHeap crea un objeto de montón que puede usar el proceso de llamada. Esta rutina reserva espacio en el espacio de direcciones virtuales del proceso y asigna almacenamiento físico para una parte inicial especificada de este bloque.

Sintaxis

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
);

Parámetros

[in] Flags

Marcas que especifican atributos opcionales del montón. Estas opciones afectan al acceso posterior al nuevo montón a través de llamadas a las funciones del montón (RtlAllocateHeap y RtlFreeHeap).

Los llamadores deben establecer este parámetro en cero si no se solicita ningún atributo opcional.

Este parámetro puede ser uno o varios de los valores siguientes.

HEAP_GENERATE_EXCEPTIONS

Especifica que el sistema indicará un error del montón generando una excepción, como STATUS_NO_MEMORY, en lugar de devolver NULL.

HEAP_GROWABLE

Especifica que el montón es de crecimiento. Se debe especificar si HeapBase es NULL.

HEAP_NO_SERIALIZE

Especifica que no se usará la exclusión mutua cuando las funciones del montón asignen y liberan memoria de este montón. El valor predeterminado, HEAP_NO_SERIALIZE no se especifica, es serializar el acceso al montón. La serialización del acceso al montón permite que dos o más subprocesos asignen y liberan memoria simultáneamente del mismo montón.

[in, optional] HeapBase

Especifica una de estas dos acciones:

Si HeapBase es un valor distinto de NULL , especifica la dirección base de un bloque de memoria asignada por el autor de la llamada que se usará para el montón.

Si HeapBase es NULL, RtlCreateHeap asigna memoria del sistema para el montón desde el espacio de direcciones virtuales del proceso.

[in, optional] ReserveSize

Si ReserveSize es un valor distinto de cero, especifica la cantidad inicial de memoria, en bytes, que se va a reservar para el montón. RtlCreateHeap redondea ReserveSize hasta el límite de página siguiente y, a continuación, reserva un bloque de ese tamaño para el montón.

Este parámetro es opcional y puede ser cero. En la tabla siguiente se resume la interacción de los parámetros ReserveSize y CommitSize .

Valores Resultado
ReserveSize zero, CommitSize zero Inicialmente se reservan 64 páginas para el montón. Una página se confirma inicialmente.
ReserveSize zero, CommitSize distinto de cero RtlCreateHeap establece ReserveSize para que sea igual a CommitSize y, a continuación, redondea ReserveSize al múltiplo más cercano de (PAGE_SIZE * 16).
ReserveSize distinto de cero, CommitSize cero Una página se confirma inicialmente para el montón.
ReserveSize distinto de cero, CommitSize distinto de cero Si CommitSize es mayor que ReserveSize, RtlCreateHeap reduce CommitSize a ReserveSize.

[in, optional] CommitSize

Si CommitSize es un valor distinto de cero, especifica la cantidad inicial de memoria, en bytes, que se va a confirmar para el montón. RtlCreateHeap redondea CommitSize hasta el límite de página siguiente y, a continuación, confirma un bloque de ese tamaño en el espacio de direcciones virtuales del proceso para el montón.

Este parámetro es opcional y puede ser cero.

[in, optional] Lock

Puntero a una estructura ERESOURCE opaca que se va a usar como bloqueo de recursos. Este parámetro es opcional y puede ser NULL. Cuando lo proporciona el autor de la llamada, la estructura debe asignarse desde un grupo sin página e inicializarse mediante una llamada a ExInitializeResourceLite o ExReinitializeResourceLite. Si se HEAP_NO_SERIALIZE marca, este parámetro debe ser NULL.

[in, optional] Parameters

Puntero a una RTL_HEAP_PARAMETERS estructura que contiene los parámetros que se aplicarán al crear el montón. Este parámetro es opcional y puede ser NULL.

typedef struct _RTL_HEAP_PARAMETERS {
    ULONG Length;
    SIZE_T SegmentReserve;
    SIZE_T SegmentCommit;
    SIZE_T DeCommitFreeBlockThreshold;
    SIZE_T DeCommitTotalFreeThreshold;
    SIZE_T MaximumAllocationSize;
    SIZE_T VirtualMemoryThreshold;
    SIZE_T InitialCommit;
    SIZE_T InitialReserve;
    PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
    SIZE_T Reserved[ 2 ];
} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS;
Miembro Valor
Longitud Tamaño, en bytes, de la RTL_HEAP_PARAMETERS estructura.
SegmentReserve Tamaño de reserva de segmento, en bytes. Si no se especifica este valor, se usa 1 MB.
SegmentCommit Tamaño de confirmación de segmento, en bytes. Si no se especifica este valor, PAGE_SIZE * 2.
DeCommitFreeBlockThreshold Umbral de bloque libre de confirmación, en bytes. Si no se especifica este valor, PAGE_SIZE se usa .
DeCommitTotalFreeThreshold Desacomprima el umbral libre total, en bytes. Si no se especifica este valor, se usa 65536.
MaximumAllocationSize Tamaño, en bytes, del bloque de memoria más grande que se puede asignar desde el montón. Si no se especifica este valor, se usa la diferencia entre las direcciones más alta y más baja, menos una página.
VirtualMemoryThreshold Umbral de memoria virtual, en bytes. Si no se especifica este valor, o si es mayor que el tamaño máximo del bloque del montón, se usa el tamaño máximo del bloque del montón 0x7F000.
InitialCommit Cantidad inicial de memoria, en bytes, que se va a confirmar para el montón.

Debe ser menor o igual que InitialReserve.

Si HeapBase y CommitRoutine no son NULL, este parámetro, que invalida el valor de CommitSize, debe ser un valor distinto de cero; De lo contrario, se omite.

InitialReserve Cantidad inicial de memoria, en bytes, que se reservará para el montón.

Si HeapBase y CommitRoutine no son NULL, este parámetro, que invalida el valor de ReserveSize, debe ser un valor distinto de cero; De lo contrario, se omite.

CommitRoutine Rutina de devolución de llamada para confirmar páginas desde el montón. Si este parámetro no es NULL, el montón debe ser no crecimiento.

Si HeapBase es NULL, CommitRoutine también debe ser NULL.

Reservados Reservado para uso del sistema. Los controladores deben establecer este parámetro en cero.
typedef NTSTATUS
(NTAPI * PRTL_HEAP_COMMIT_ROUTINE)(
    IN PVOID Base,
    IN OUT PVOID *CommitAddress,
    IN OUT PSIZE_T CommitSize
    );
Parámetro Significado
Base Dirección base del bloque de memoria asignada por el autor de la llamada que se usa para el montón.
CommitAddress Puntero a una variable que recibirá la dirección base de la región de páginas confirmada.
CommitSize Puntero a una variable que recibirá el tamaño real, en bytes, de la región de páginas asignada.

Valor devuelto

RtlCreateHeap devuelve un identificador que se usará para acceder al montón creado.

Observaciones

RtlCreateHeap crea un objeto de montón privado desde el que el proceso de llamada puede asignar bloques de memoria mediante una llamada a RtlAllocateHeap. El tamaño de confirmación inicial determina el número de páginas que se asignan inicialmente para el montón. El tamaño de reserva inicial determina el número de páginas que se reservan inicialmente para el montón. Las páginas reservadas pero no confirmadas crean un bloque en el espacio de direcciones virtuales del proceso en el que se puede expandir el montón.

Si las solicitudes de asignación realizadas por RtlAllocateHeap superan el tamaño de confirmación inicial del montón, el sistema confirma páginas adicionales de almacenamiento físico para el montón, hasta el tamaño máximo del montón. Si el montón no es crecimiento, su tamaño máximo se limita a su tamaño de reserva inicial.

Si el montón es de crecimiento, su tamaño solo está limitado por la memoria disponible. Si las solicitudes de RtlAllocateHeap superan el tamaño actual de las páginas confirmadas, el sistema llama a ZwAllocateVirtualMemory para obtener la memoria necesaria, suponiendo que el almacenamiento físico esté disponible.

Además, si el montón no es crecimiento, surge una limitación absoluta: el tamaño máximo de un bloque de memoria en el montón es 0x7F000 bytes. El umbral de memoria virtual del montón es igual al tamaño máximo del bloque del montón o al valor del miembro VirtualMemoryThreshold de la estructura Parameters , lo que sea menor. Es posible que el montón también tenga que paginar el tamaño de la solicitud con fines de alineación y metadatos para que las solicitudes para asignar bloques dentro de 4096 bytes (1 página) de VirtualMemoryThreshold puedan producir un error incluso si el tamaño máximo del montón es lo suficientemente grande como para contener el bloque. (Para obtener más información sobre VirtualMemoryThreshold, vea los miembros del parámetro Parameters en RtlCreateHeap).

Si el montón es ampliable, las solicitudes para asignar bloques mayores que el umbral de memoria virtual del montón no producirán errores automáticamente. El sistema llama a ZwAllocateVirtualMemory para obtener la memoria necesaria para bloques tan grandes.

La memoria de un objeto de montón privado solo es accesible para el proceso que lo creó.

El sistema usa memoria del montón privado para almacenar estructuras de compatibilidad del montón, por lo que no todo el tamaño del montón especificado está disponible para el proceso. Por ejemplo, si RtlAllocateHeap solicita 64 kilobytes (K) desde un montón con un tamaño máximo de 64 000, la solicitud puede producir un error debido a la sobrecarga del sistema.

Si HEAP_NO_SERIALIZE no se especifica (el valor predeterminado simple), el montón serializará el acceso dentro del proceso de llamada. La serialización garantiza la exclusión mutua cuando dos o más subprocesos intentan asignar o liberar bloques simultáneamente del mismo montón. La serialización tiene un pequeño costo de rendimiento, pero se debe usar cada vez que varios subprocesos asignan y liberan memoria del mismo montón.

Al HEAP_NO_SERIALIZE elimina la exclusión mutua en el montón. Sin la serialización, dos o más subprocesos que usan el mismo identificador de montón podrían intentar asignar o liberar memoria simultáneamente, lo que probablemente provocaría daños en el montón. Por lo tanto, HEAP_NO_SERIALIZE puede usarse de forma segura solo en las situaciones siguientes:

  • El proceso solo tiene un subproceso.
  • El proceso tiene varios subprocesos, pero solo un subproceso llama a las funciones del montón para un montón específico.
  • El proceso tiene varios subprocesos y la aplicación proporciona su propio mecanismo para la exclusión mutua en un montón específico.
Nota

Para protegerse contra una infracción de acceso, use el control estructurado de excepciones para proteger cualquier código que escriba en un montón o que lea desde él. Para obtener más información sobre el control estructurado de excepciones con accesos a memoria, vea Control de excepciones.

Requisitos

   
Cliente mínimo compatible Esta rutina está disponible en Microsoft Windows XP y versiones posteriores.
Plataforma de destino Universal
Encabezado ntifs.h (incluir Ntifs.h)
Library Ntoskrnl.lib
Archivo DLL NtosKrnl.exe (modo kernel); Ntdll.dll (modo de usuario)
IRQL < DISPATCH_LEVEL

Consulte también

RtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap