mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 04:11:30 +00:00
159 lines
3.6 KiB
C
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;
|
|
}
|
|
|