ExInitializeZone

NTSTATUS
ExInitializeZone(

IN PZONE_HEADER Zone,
IN ULONG BlockSize,
IN PVOID InitialSegment,
IN ULONG InitialSegmentSize
);

ExInitializeZone initializes a zone header. After a successful initialization, fixed-size blocks can be allocated from and freed to the zone.

Parameters

Zone

Points to the zone header to be initialized, which is defined as follows:

typedef struct _ZONE_HEADER {

    SINGLE_LIST_ENTRY FreeList;

    SINGLE_LIST_ENTRY SegmentList;

    ULONG BlockSize;

    ULONG TotalSegmentSize;

} ZONE_HEADER, *PZONE_HEADER;

BlockSize

The size in bytes of the allocatable unit within the zone. This value must be less than InitialSegmentSize and must be 8-byte aligned.

InitialSegment

Points to a segment of storage allocated by the caller. The base address of this segment must be aligned on an 8-byte boundary.

InitialSegmentSize

Is the size in bytes of InitialSegment.

Return Value

ExInitializeZone returns one of the following:

Status Meaning
STATUS_UNSUCCESSFUL BlockSize or InitialSegment was not aligned properly, or BlockSize was larger than the initial segment size.
STATUS_SUCCESS The zone was successfully initialized.

Comments

Consider using a lookaside list instead of a zone. Lookaside lists are more efficient are are easier to manage.

The first ZONE_SEGMENT_HEADER-sized portion of the caller-allocated segment is used by the zone allocator. The remainder of the segment is divided into BlockSize blocks and made available for allocation and deallocation from the zone.

A driver should call MmQuerySystemSize and MmIsThisAnNtAsSystem before calling ExInitializeZone to determine an appropriate InitialSegmentSize. Callers of ExInitializeZone should specify an InitialSegmentSize of <= PAGE_SIZE if a preceding call to MmQuerySystemSize returns MmSmallSystem.

Memory for a zone must be resident if the zone blocks can be accessed by any code running at IRQL >= DISPATCH_LEVEL. Resident memory can be allocated with ExAllocatePool, using the input PoolType NonPagedPool.

Callers of the ExInterlocked..Zone routines also must provide resident storage for a spin lock, which must be initialized with KeInitializeSpinLock before any call is made to an ExInterlocked..Zone routine.

Callers of ExInitializeZone must be running at IRQL PASSIVE_LEVEL.

See Also

ExAllocateFromZone, ExAllocatePool, ExFreePool, ExFreeToZone, ExInitializeNPagedLookasideList, ExInitializePagedLookasideList, ExInterlockedAllocateFromZone, ExInterlockedFreeToZone, KeInitializeSpinLock, MmIsThisAnNtAsSystem, MmQuerySystemSize