reactos/sdk/lib/rtl/heapuser.c
2023-12-17 22:28:24 +01:00

159 lines
3.6 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/rtl/heapuser.c
* PURPOSE: RTL Heap backend allocator (user mode only functions)
* PROGRAMMERS: Copyright 2010 Aleksey Bragin
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#include <heap.h>
#define NDEBUG
#include <debug.h>
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
/* Usermode only! */
VOID
NTAPI
RtlpAddHeapToProcessList(PHEAP Heap)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
//_SEH2_TRY {
/* Check if max number of heaps reached */
if (Peb->NumberOfHeaps == Peb->MaximumNumberOfHeaps)
{
// TODO: Handle this case
ASSERT(FALSE);
}
/* Add the heap to the process heaps */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = Heap;
Peb->NumberOfHeaps++;
Heap->ProcessHeapsListIndex = (USHORT)Peb->NumberOfHeaps;
// } _SEH2_FINALLY {
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
// } _SEH2_END
}
/* Usermode only! */
VOID
NTAPI
RtlpRemoveHeapFromProcessList(PHEAP Heap)
{
PPEB Peb;
PHEAP *Current, *Next;
ULONG Count;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Acquire the lock */
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
/* Check if we don't need anything to do */
if ((Heap->ProcessHeapsListIndex == 0) ||
(Heap->ProcessHeapsListIndex > Peb->NumberOfHeaps) ||
(Peb->NumberOfHeaps == 0))
{
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
return;
}
/* The process actually has more than one heap.
Use classic, lernt from university times algorithm for removing an entry
from a static array */
Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
Next = Current + 1;
/* How many items we need to shift to the left */
Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
/* Move them all in a loop */
while (--Count)
{
/* Copy it and advance next pointer */
*Current = *Next;
/* Update its index */
(*Current)->ProcessHeapsListIndex -= 1;
/* Advance pointers */
Current++;
Next++;
}
/* Decrease total number of heaps */
Peb->NumberOfHeaps--;
/* Zero last unused item */
Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
Heap->ProcessHeapsListIndex = 0;
/* Release the lock */
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
VOID
NTAPI
RtlInitializeHeapManager(VOID)
{
PPEB Peb;
/* Get PEB */
Peb = RtlGetCurrentPeb();
/* Initialize heap-related fields of PEB */
Peb->NumberOfHeaps = 0;
/* Initialize the process heaps list protecting lock */
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
}
ULONG NTAPI
RtlGetProcessHeaps(_In_ ULONG HeapCount, _Out_cap_(HeapCount) HANDLE *HeapArray)
{
PPEB Peb = RtlGetCurrentPeb();
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
ULONG nHeaps = Peb->NumberOfHeaps;
_SEH2_TRY
{
if (HeapArray)
{
for (ULONG n = 0; n < min(nHeaps, HeapCount); ++n)
{
HeapArray[n] = Peb->ProcessHeaps[n];
}
}
}
_SEH2_FINALLY
{
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
}
_SEH2_END;
/* TODO: Add RtlpDphPageHeapList here */
return nHeaps;
}