mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[NTOSKRNL]
- Keep APC delivery disabled while holding a Heap Lock, not just while acquiring/releasing it (Dedicated to Timo and Ged). - Store the Heap Lock in non-paged pool, the only place where executive resources belong (Dedicated to patient people). [RTL] - Restructure/simplify/correct Heap and Heap Segment initialization (partially to cope with the changed Heap Lock interface). - Restrict the location of Heap Segment headers to the base address of the Heap Segment (which frees up a whopping 60 bytes per Heap!). - Cater for acquiring the Heap Lock exclusively or shared (the latter is only available in kernel-mode); only exclusive locking is used for now. - Use a plain critical section to guard the Process Heap list, no reason to disguise it as a Heap Lock (saves us a handful more bytes). svn path=/trunk/; revision=53761
This commit is contained in:
parent
cf0a380afd
commit
2e6e9dd622
6 changed files with 214 additions and 227 deletions
|
@ -112,32 +112,30 @@ RtlGetNtGlobalFlags(VOID)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlDeleteHeapLock(
|
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
return RtlDeleteCriticalSection(&Lock->CriticalSection);
|
return RtlDeleteCriticalSection(&Lock->CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlEnterHeapLock(
|
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Exclusive);
|
||||||
|
|
||||||
return RtlEnterCriticalSection(&Lock->CriticalSection);
|
return RtlEnterCriticalSection(&Lock->CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlInitializeHeapLock(
|
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
return RtlInitializeCriticalSection(&Lock->CriticalSection);
|
return RtlInitializeCriticalSection(&(*Lock)->CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlLeaveHeapLock(
|
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
return RtlLeaveCriticalSection(&Lock->CriticalSection);
|
return RtlLeaveCriticalSection(&Lock->CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
HEAP_LOCK RtlpProcessHeapsListLock;
|
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
|
||||||
|
|
||||||
/* Bitmaps stuff */
|
/* Bitmaps stuff */
|
||||||
|
|
||||||
|
@ -82,44 +82,58 @@ UCHAR FillPattern[HEAP_ENTRY_SIZE] =
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID NTAPI
|
NTSTATUS NTAPI
|
||||||
RtlpInitializeHeap(PHEAP Heap,
|
RtlpInitializeHeap(OUT PHEAP Heap,
|
||||||
PULONG HeaderSize,
|
IN ULONG Flags,
|
||||||
ULONG Flags,
|
IN PHEAP_LOCK Lock OPTIONAL,
|
||||||
BOOLEAN AllocateLock,
|
IN PRTL_HEAP_PARAMETERS Parameters)
|
||||||
PVOID Lock)
|
|
||||||
{
|
{
|
||||||
PVOID NextHeapBase = Heap + 1;
|
|
||||||
PHEAP_UCR_DESCRIPTOR UcrDescriptor;
|
|
||||||
ULONG NumUCRs = 8;
|
ULONG NumUCRs = 8;
|
||||||
ULONG i;
|
ULONG Index;
|
||||||
|
SIZE_T HeaderSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PHEAP_UCR_DESCRIPTOR UcrDescriptor;
|
||||||
|
|
||||||
/* Add UCRs size */
|
/* Preconditions */
|
||||||
*HeaderSize += NumUCRs * sizeof(*UcrDescriptor);
|
ASSERT(Heap != NULL);
|
||||||
|
ASSERT(Parameters != NULL);
|
||||||
|
ASSERT(!(Flags & HEAP_LOCK_USER_ALLOCATED));
|
||||||
|
ASSERT(!(Flags & HEAP_NO_SERIALIZE) || (Lock == NULL)); /* HEAP_NO_SERIALIZE => no lock */
|
||||||
|
|
||||||
/* Prepare a list of UCRs */
|
/* Start out with the size of a plain Heap header */
|
||||||
InitializeListHead(&Heap->UCRList);
|
HeaderSize = ROUND_UP(sizeof(HEAP), sizeof(HEAP_ENTRY));
|
||||||
InitializeListHead(&Heap->UCRSegments);
|
|
||||||
UcrDescriptor = NextHeapBase;
|
|
||||||
|
|
||||||
for (i=0; i<NumUCRs; i++, UcrDescriptor++)
|
/* Check if space needs to be added for the Heap Lock */
|
||||||
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
InsertTailList(&Heap->UCRList, &UcrDescriptor->ListEntry);
|
if (Lock != NULL)
|
||||||
|
/* The user manages the Heap Lock */
|
||||||
|
Flags |= HEAP_LOCK_USER_ALLOCATED;
|
||||||
|
else
|
||||||
|
if (RtlpGetMode() == UserMode)
|
||||||
|
{
|
||||||
|
/* In user mode, the Heap Lock trails the Heap header */
|
||||||
|
Lock = (PHEAP_LOCK) ((ULONG_PTR) (Heap) + HeaderSize);
|
||||||
|
HeaderSize += ROUND_UP(sizeof(HEAP_LOCK), sizeof(HEAP_ENTRY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NextHeapBase = UcrDescriptor;
|
/* Add space for the initial Heap UnCommitted Range Descriptor list */
|
||||||
// TODO: Add tagging
|
UcrDescriptor = (PHEAP_UCR_DESCRIPTOR) ((ULONG_PTR) (Heap) + HeaderSize);
|
||||||
|
HeaderSize += ROUND_UP(NumUCRs * sizeof(HEAP_UCR_DESCRIPTOR), sizeof(HEAP_ENTRY));
|
||||||
|
|
||||||
/* Round up header size again */
|
/* Sanity check */
|
||||||
*HeaderSize = ROUND_UP(*HeaderSize, HEAP_ENTRY_SIZE);
|
ASSERT(HeaderSize <= PAGE_SIZE);
|
||||||
|
|
||||||
ASSERT(*HeaderSize <= PAGE_SIZE);
|
/* Initialise the Heap Entry header containing the Heap header */
|
||||||
|
Heap->Entry.Size = HeaderSize >> HEAP_ENTRY_SHIFT;
|
||||||
/* Initialize heap's header */
|
|
||||||
Heap->Entry.Size = (USHORT)((*HeaderSize) >> HEAP_ENTRY_SHIFT);
|
|
||||||
Heap->Entry.Flags = HEAP_ENTRY_BUSY;
|
Heap->Entry.Flags = HEAP_ENTRY_BUSY;
|
||||||
|
Heap->Entry.SmallTagIndex = LOBYTE(Heap->Entry.Size) ^ HIBYTE(Heap->Entry.Size) ^ Heap->Entry.Flags;
|
||||||
|
Heap->Entry.PreviousSize = 0;
|
||||||
|
Heap->Entry.SegmentOffset = 0;
|
||||||
|
Heap->Entry.UnusedBytes = 0;
|
||||||
|
|
||||||
|
/* Initialise the Heap header */
|
||||||
Heap->Signature = HEAP_SIGNATURE;
|
Heap->Signature = HEAP_SIGNATURE;
|
||||||
Heap->Flags = Flags;
|
Heap->Flags = Flags;
|
||||||
Heap->ForceFlags = (Flags & (HEAP_NO_SERIALIZE |
|
Heap->ForceFlags = (Flags & (HEAP_NO_SERIALIZE |
|
||||||
|
@ -131,32 +145,64 @@ RtlpInitializeHeap(PHEAP Heap,
|
||||||
HEAP_TAIL_CHECKING_ENABLED |
|
HEAP_TAIL_CHECKING_ENABLED |
|
||||||
HEAP_CREATE_ALIGN_16 |
|
HEAP_CREATE_ALIGN_16 |
|
||||||
HEAP_FREE_CHECKING_ENABLED));
|
HEAP_FREE_CHECKING_ENABLED));
|
||||||
Heap->HeaderValidateCopy = NULL;
|
|
||||||
Heap->HeaderValidateLength = ((PCHAR)NextHeapBase - (PCHAR)Heap);
|
|
||||||
|
|
||||||
/* Initialize free lists */
|
/* Initialise the Heap parameters */
|
||||||
for (i=0; i<HEAP_FREELISTS; i++)
|
Heap->VirtualMemoryThreshold = ROUND_UP(Parameters->VirtualMemoryThreshold, sizeof(HEAP_ENTRY)) >> HEAP_ENTRY_SHIFT;
|
||||||
|
Heap->SegmentReserve = Parameters->SegmentReserve;
|
||||||
|
Heap->SegmentCommit = Parameters->SegmentCommit;
|
||||||
|
Heap->DeCommitFreeBlockThreshold = Parameters->DeCommitFreeBlockThreshold >> HEAP_ENTRY_SHIFT;
|
||||||
|
Heap->DeCommitTotalFreeThreshold = Parameters->DeCommitTotalFreeThreshold >> HEAP_ENTRY_SHIFT;
|
||||||
|
Heap->MaximumAllocationSize = Parameters->MaximumAllocationSize;
|
||||||
|
Heap->CommitRoutine = Parameters->CommitRoutine;
|
||||||
|
|
||||||
|
/* Initialise the Heap validation info */
|
||||||
|
Heap->HeaderValidateCopy = NULL;
|
||||||
|
Heap->HeaderValidateLength = HeaderSize;
|
||||||
|
|
||||||
|
/* Initialise the Heap Lock */
|
||||||
|
if (!(Flags & HEAP_NO_SERIALIZE) && !(Flags & HEAP_LOCK_USER_ALLOCATED))
|
||||||
{
|
{
|
||||||
InitializeListHead(&Heap->FreeLists[i]);
|
Status = RtlInitializeHeapLock(&Lock);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
Heap->LockVariable = Lock;
|
||||||
|
|
||||||
|
/* Initialise the Heap alignment info */
|
||||||
|
if (Flags & HEAP_CREATE_ALIGN_16)
|
||||||
|
{
|
||||||
|
Heap->AlignMask = (ULONG) ~15;
|
||||||
|
Heap->AlignRound = 15 + sizeof(HEAP_ENTRY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Heap->AlignMask = (ULONG) ~(sizeof(HEAP_ENTRY) - 1);
|
||||||
|
Heap->AlignRound = 2 * sizeof(HEAP_ENTRY) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize "big" allocations list */
|
if (Flags & HEAP_TAIL_CHECKING_ENABLED)
|
||||||
|
Heap->AlignRound += sizeof(HEAP_ENTRY);
|
||||||
|
|
||||||
|
/* Initialise the Heap Segment list */
|
||||||
|
for (Index = 0; Index < HEAP_SEGMENTS; ++Index)
|
||||||
|
Heap->Segments[Index] = NULL;
|
||||||
|
|
||||||
|
/* Initialise the Heap Free Heap Entry lists */
|
||||||
|
for (Index = 0; Index < HEAP_FREELISTS; ++Index)
|
||||||
|
InitializeListHead(&Heap->FreeLists[Index]);
|
||||||
|
|
||||||
|
/* Initialise the Heap Virtual Allocated Blocks list */
|
||||||
InitializeListHead(&Heap->VirtualAllocdBlocks);
|
InitializeListHead(&Heap->VirtualAllocdBlocks);
|
||||||
|
|
||||||
/* Initialize lock */
|
/* Initialise the Heap UnCommitted Region lists */
|
||||||
if (AllocateLock)
|
InitializeListHead(&Heap->UCRSegments);
|
||||||
{
|
InitializeListHead(&Heap->UCRList);
|
||||||
Lock = NextHeapBase;
|
|
||||||
Status = RtlInitializeHeapLock((PHEAP_LOCK)Lock);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Initializing the lock failed!\n");
|
|
||||||
return /*NULL*/; // FIXME!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the lock variable */
|
/* Register the initial Heap UnCommitted Region Descriptors */
|
||||||
Heap->LockVariable = Lock;
|
for (Index = 0; Index < NumUCRs; ++Index)
|
||||||
|
InsertTailList(&Heap->UCRList, &UcrDescriptor[Index].ListEntry);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FORCEINLINE
|
VOID FORCEINLINE
|
||||||
|
@ -821,92 +867,76 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN NTAPI
|
BOOLEAN NTAPI
|
||||||
RtlpInitializeHeapSegment(PHEAP Heap,
|
RtlpInitializeHeapSegment(IN OUT PHEAP Heap,
|
||||||
PHEAP_SEGMENT Segment,
|
OUT PHEAP_SEGMENT Segment,
|
||||||
UCHAR SegmentIndex,
|
IN UCHAR SegmentIndex,
|
||||||
ULONG Flags,
|
IN ULONG SegmentFlags,
|
||||||
PVOID BaseAddress,
|
IN SIZE_T SegmentReserve,
|
||||||
PVOID UncommittedBase,
|
IN SIZE_T SegmentCommit)
|
||||||
PVOID LimitAddress)
|
|
||||||
{
|
{
|
||||||
ULONG Pages, CommitSize;
|
|
||||||
PHEAP_ENTRY HeapEntry;
|
PHEAP_ENTRY HeapEntry;
|
||||||
USHORT PreviousSize = 0, NewSize;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Pages = ((PCHAR)LimitAddress - (PCHAR)BaseAddress) / PAGE_SIZE;
|
/* Preconditions */
|
||||||
|
ASSERT(Heap != NULL);
|
||||||
|
ASSERT(Segment != NULL);
|
||||||
|
ASSERT(SegmentCommit >= PAGE_SIZE);
|
||||||
|
ASSERT(ROUND_DOWN(SegmentCommit, PAGE_SIZE) == SegmentCommit);
|
||||||
|
ASSERT(SegmentReserve >= SegmentCommit);
|
||||||
|
ASSERT(ROUND_DOWN(SegmentReserve, PAGE_SIZE) == SegmentReserve);
|
||||||
|
|
||||||
HeapEntry = (PHEAP_ENTRY)ROUND_UP(Segment + 1, HEAP_ENTRY_SIZE);
|
DPRINT("RtlpInitializeHeapSegment(%p %p %x %x %lx %lx)\n", Heap, Segment, SegmentIndex, SegmentFlags, SegmentReserve, SegmentCommit);
|
||||||
|
|
||||||
DPRINT("RtlpInitializeHeapSegment(%p %p %x %x %p %p %p)\n", Heap, Segment, SegmentIndex, Flags, BaseAddress, UncommittedBase, LimitAddress);
|
/* Initialise the Heap Entry header if this is not the first Heap Segment */
|
||||||
DPRINT("Pages %x, HeapEntry %p, sizeof(HEAP_SEGMENT) %x\n", Pages, HeapEntry, sizeof(HEAP_SEGMENT));
|
if ((PHEAP_SEGMENT) (Heap) != Segment)
|
||||||
|
|
||||||
/* Check if it's the first segment and remember its size */
|
|
||||||
if (Heap == BaseAddress)
|
|
||||||
PreviousSize = Heap->Entry.Size;
|
|
||||||
|
|
||||||
NewSize = ((PCHAR)HeapEntry - (PCHAR)Segment) >> HEAP_ENTRY_SHIFT;
|
|
||||||
|
|
||||||
if ((PVOID)(HeapEntry + 1) >= UncommittedBase)
|
|
||||||
{
|
{
|
||||||
/* Check if it goes beyond the limit */
|
Segment->Entry.Size = ROUND_UP(sizeof(HEAP_SEGMENT), sizeof(HEAP_ENTRY)) >> HEAP_ENTRY_SHIFT;
|
||||||
if ((PVOID)(HeapEntry + 1) >= LimitAddress)
|
Segment->Entry.Flags = HEAP_ENTRY_BUSY;
|
||||||
return FALSE;
|
Segment->Entry.SmallTagIndex = LOBYTE(Segment->Entry.Size) ^ HIBYTE(Segment->Entry.Size) ^ Segment->Entry.Flags;
|
||||||
|
Segment->Entry.PreviousSize = 0;
|
||||||
/* Need to commit memory */
|
Segment->Entry.SegmentOffset = SegmentIndex;
|
||||||
CommitSize = (PCHAR)(HeapEntry + 1) - (PCHAR)UncommittedBase;
|
Segment->Entry.UnusedBytes = 0;
|
||||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
|
||||||
(PVOID)&UncommittedBase,
|
|
||||||
0,
|
|
||||||
&CommitSize,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Committing page failed with status 0x%08X\n", Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Committed %d bytes at base %p\n", CommitSize, UncommittedBase);
|
|
||||||
|
|
||||||
/* Calcule the new uncommitted base */
|
|
||||||
UncommittedBase = (PVOID)((PCHAR)UncommittedBase + CommitSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the segment entry */
|
/* Sanity check */
|
||||||
Segment->Entry.PreviousSize = PreviousSize;
|
ASSERT((Segment->Entry.Size << HEAP_ENTRY_SHIFT) <= PAGE_SIZE);
|
||||||
Segment->Entry.Size = NewSize;
|
|
||||||
Segment->Entry.Flags = HEAP_ENTRY_BUSY;
|
|
||||||
Segment->Entry.SegmentOffset = SegmentIndex;
|
|
||||||
|
|
||||||
/* Initialize the segment itself */
|
/* Initialise the Heap Segment header */
|
||||||
Segment->SegmentSignature = HEAP_SEGMENT_SIGNATURE;
|
Segment->SegmentSignature = HEAP_SEGMENT_SIGNATURE;
|
||||||
|
Segment->SegmentFlags = SegmentFlags;
|
||||||
Segment->Heap = Heap;
|
Segment->Heap = Heap;
|
||||||
Segment->BaseAddress = BaseAddress;
|
|
||||||
Segment->FirstEntry = HeapEntry;
|
|
||||||
Segment->LastValidEntry = (PHEAP_ENTRY)((PCHAR)BaseAddress + Pages * PAGE_SIZE);
|
|
||||||
Segment->NumberOfPages = Pages;
|
|
||||||
Segment->NumberOfUnCommittedPages = ((PCHAR)LimitAddress - (PCHAR)UncommittedBase) / PAGE_SIZE;
|
|
||||||
InitializeListHead(&Segment->UCRSegmentList);
|
|
||||||
|
|
||||||
/* Insert uncommitted pages into UCR (uncommitted ranges) list */
|
|
||||||
if (Segment->NumberOfUnCommittedPages)
|
|
||||||
{
|
|
||||||
RtlpInsertUnCommittedPages(Segment, (ULONG_PTR)UncommittedBase, Segment->NumberOfUnCommittedPages * PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the segment index pointer */
|
|
||||||
Heap->Segments[SegmentIndex] = Segment;
|
Heap->Segments[SegmentIndex] = Segment;
|
||||||
|
|
||||||
/* Prepare a free heap entry */
|
/* Initialise the Heap Segment location information */
|
||||||
HeapEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
|
Segment->BaseAddress = Segment;
|
||||||
HeapEntry->PreviousSize = Segment->Entry.Size;
|
Segment->NumberOfPages = SegmentReserve >> PAGE_SHIFT;
|
||||||
HeapEntry->SegmentOffset = SegmentIndex;
|
|
||||||
|
|
||||||
/* Insert it */
|
/* Initialise the Heap Entries contained within the Heap Segment */
|
||||||
RtlpInsertFreeBlock(Heap, (PHEAP_FREE_ENTRY)HeapEntry, (PHEAP_ENTRY)UncommittedBase - HeapEntry);
|
Segment->FirstEntry = &Segment->Entry + Segment->Entry.Size;
|
||||||
|
Segment->LastValidEntry = (PHEAP_ENTRY) ((ULONG_PTR) (Segment) + SegmentReserve);
|
||||||
|
|
||||||
return TRUE;
|
if ((Segment->Entry.Size << HEAP_ENTRY_SHIFT) < SegmentCommit)
|
||||||
|
{
|
||||||
|
HeapEntry = Segment->FirstEntry;
|
||||||
|
|
||||||
|
/* Prepare a Free Heap Entry header */
|
||||||
|
HeapEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
|
||||||
|
HeapEntry->PreviousSize = Segment->Entry.Size;
|
||||||
|
HeapEntry->SegmentOffset = SegmentIndex;
|
||||||
|
|
||||||
|
/* Register the Free Heap Entry */
|
||||||
|
RtlpInsertFreeBlock(Heap, (PHEAP_FREE_ENTRY) HeapEntry, (SegmentCommit >> HEAP_ENTRY_SHIFT) - Segment->Entry.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise the Heap Segment UnCommitted Range information */
|
||||||
|
Segment->NumberOfUnCommittedPages = (SegmentReserve - SegmentCommit) >> PAGE_SHIFT;
|
||||||
|
Segment->NumberOfUnCommittedRanges = 0;
|
||||||
|
InitializeListHead(&Segment->UCRSegmentList);
|
||||||
|
|
||||||
|
/* Register the UnCommitted Range of the Heap Segment */
|
||||||
|
if (Segment->NumberOfUnCommittedPages != 0)
|
||||||
|
RtlpInsertUnCommittedPages(Segment, (ULONG_PTR) (Segment) + SegmentCommit, SegmentReserve - SegmentCommit);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
|
@ -944,7 +974,7 @@ RtlpAddHeapToProcessList(PHEAP Heap)
|
||||||
Peb = RtlGetCurrentPeb();
|
Peb = RtlGetCurrentPeb();
|
||||||
|
|
||||||
/* Acquire the lock */
|
/* Acquire the lock */
|
||||||
RtlEnterHeapLock(&RtlpProcessHeapsListLock);
|
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
|
|
||||||
//_SEH2_TRY {
|
//_SEH2_TRY {
|
||||||
/* Check if max number of heaps reached */
|
/* Check if max number of heaps reached */
|
||||||
|
@ -961,7 +991,7 @@ RtlpAddHeapToProcessList(PHEAP Heap)
|
||||||
// } _SEH2_FINALLY {
|
// } _SEH2_FINALLY {
|
||||||
|
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
|
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
|
|
||||||
// } _SEH2_END
|
// } _SEH2_END
|
||||||
}
|
}
|
||||||
|
@ -978,7 +1008,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
|
||||||
Peb = RtlGetCurrentPeb();
|
Peb = RtlGetCurrentPeb();
|
||||||
|
|
||||||
/* Acquire the lock */
|
/* Acquire the lock */
|
||||||
RtlEnterHeapLock(&RtlpProcessHeapsListLock);
|
RtlEnterCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
|
|
||||||
/* Check if we don't need anything to do */
|
/* Check if we don't need anything to do */
|
||||||
if ((Heap->ProcessHeapsListIndex == 0) ||
|
if ((Heap->ProcessHeapsListIndex == 0) ||
|
||||||
|
@ -986,7 +1016,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
|
||||||
(Peb->NumberOfHeaps == 0))
|
(Peb->NumberOfHeaps == 0))
|
||||||
{
|
{
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
|
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1023,7 +1053,7 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
|
||||||
Heap->ProcessHeapsListIndex = 0;
|
Heap->ProcessHeapsListIndex = 0;
|
||||||
|
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
|
RtlLeaveCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHEAP_FREE_ENTRY NTAPI
|
PHEAP_FREE_ENTRY NTAPI
|
||||||
|
@ -1228,13 +1258,7 @@ RtlpExtendHeap(PHEAP Heap,
|
||||||
|
|
||||||
/* Initialize heap segment if commit was successful */
|
/* Initialize heap segment if commit was successful */
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
Status = RtlpInitializeHeapSegment(Heap, Segment, EmptyIndex, 0, ReserveSize, CommitSize);
|
||||||
if (!RtlpInitializeHeapSegment(Heap, Segment, EmptyIndex, 0, Segment,
|
|
||||||
(PCHAR)Segment + CommitSize, (PCHAR)Segment + ReserveSize))
|
|
||||||
{
|
|
||||||
Status = STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If everything worked - cool */
|
/* If everything worked - cool */
|
||||||
if (NT_SUCCESS(Status)) return (PHEAP_FREE_ENTRY)Segment->FirstEntry;
|
if (NT_SUCCESS(Status)) return (PHEAP_FREE_ENTRY)Segment->FirstEntry;
|
||||||
|
@ -1298,8 +1322,7 @@ RtlCreateHeap(ULONG Flags,
|
||||||
ULONG NtGlobalFlags = RtlGetNtGlobalFlags();
|
ULONG NtGlobalFlags = RtlGetNtGlobalFlags();
|
||||||
ULONG HeapSegmentFlags = 0;
|
ULONG HeapSegmentFlags = 0;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG MaxBlockSize, HeaderSize;
|
ULONG MaxBlockSize;
|
||||||
BOOLEAN AllocateLock = FALSE;
|
|
||||||
|
|
||||||
/* Check for a special heap */
|
/* Check for a special heap */
|
||||||
if (RtlpPageHeapEnabled && !Addr && !Lock)
|
if (RtlpPageHeapEnabled && !Addr && !Lock)
|
||||||
|
@ -1422,25 +1445,9 @@ RtlCreateHeap(ULONG Flags,
|
||||||
if (RtlpHeapIsSpecial(Flags))
|
if (RtlpHeapIsSpecial(Flags))
|
||||||
return RtlDebugCreateHeap(Flags, Addr, TotalSize, CommitSize, Lock, Parameters);
|
return RtlDebugCreateHeap(Flags, Addr, TotalSize, CommitSize, Lock, Parameters);
|
||||||
|
|
||||||
/* Calculate header size */
|
/* Without serialization, a lock makes no sense */
|
||||||
HeaderSize = sizeof(HEAP);
|
if ((Flags & HEAP_NO_SERIALIZE) && (Lock != NULL))
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
|
||||||
{
|
|
||||||
if (Lock)
|
|
||||||
{
|
|
||||||
Flags |= HEAP_LOCK_USER_ALLOCATED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HeaderSize += sizeof(HEAP_LOCK);
|
|
||||||
AllocateLock = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Lock)
|
|
||||||
{
|
|
||||||
/* Invalid parameters */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
/* See if we are already provided with an address for the heap */
|
/* See if we are already provided with an address for the heap */
|
||||||
if (Addr)
|
if (Addr)
|
||||||
|
@ -1583,48 +1590,23 @@ RtlCreateHeap(ULONG Flags,
|
||||||
UncommittedAddress = (PCHAR)UncommittedAddress + CommitSize;
|
UncommittedAddress = (PCHAR)UncommittedAddress + CommitSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Created heap %p, CommitSize %x, ReserveSize %x\n", Heap, CommitSize, TotalSize);
|
|
||||||
|
|
||||||
/* Initialize the heap */
|
/* Initialize the heap */
|
||||||
RtlpInitializeHeap(Heap, &HeaderSize, Flags, AllocateLock, Lock);
|
Status = RtlpInitializeHeap(Heap, Flags, Lock, Parameters);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
/* Initialize heap's first segment */
|
|
||||||
if (!RtlpInitializeHeapSegment(Heap,
|
|
||||||
(PHEAP_SEGMENT)((PCHAR)Heap + HeaderSize),
|
|
||||||
0,
|
|
||||||
HeapSegmentFlags,
|
|
||||||
CommittedAddress,
|
|
||||||
UncommittedAddress,
|
|
||||||
(PCHAR)CommittedAddress + TotalSize))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to initialize heap segment\n");
|
DPRINT1("Failed to initialize heap (%x)\n", Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set other data */
|
/* Initialize heap's first segment */
|
||||||
Heap->ProcessHeapsListIndex = 0;
|
Status = RtlpInitializeHeapSegment(Heap, (PHEAP_SEGMENT) (Heap), 0, HeapSegmentFlags, TotalSize, CommitSize);
|
||||||
Heap->SegmentCommit = Parameters->SegmentCommit;
|
if (!NT_SUCCESS(Status))
|
||||||
Heap->SegmentReserve = Parameters->SegmentReserve;
|
|
||||||
Heap->DeCommitFreeBlockThreshold = Parameters->DeCommitFreeBlockThreshold >> HEAP_ENTRY_SHIFT;
|
|
||||||
Heap->DeCommitTotalFreeThreshold = Parameters->DeCommitTotalFreeThreshold >> HEAP_ENTRY_SHIFT;
|
|
||||||
Heap->MaximumAllocationSize = Parameters->MaximumAllocationSize;
|
|
||||||
Heap->VirtualMemoryThreshold = ROUND_UP(Parameters->VirtualMemoryThreshold, HEAP_ENTRY_SIZE) >> HEAP_ENTRY_SHIFT;
|
|
||||||
Heap->CommitRoutine = Parameters->CommitRoutine;
|
|
||||||
|
|
||||||
/* Set alignment */
|
|
||||||
if (Flags & HEAP_CREATE_ALIGN_16)
|
|
||||||
{
|
{
|
||||||
Heap->AlignMask = (ULONG)~15;
|
DPRINT1("Failed to initialize heap segment (%x)\n", Status);
|
||||||
Heap->AlignRound = 15 + sizeof(HEAP_ENTRY);
|
return NULL;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Heap->AlignMask = (ULONG)~(HEAP_ENTRY_SIZE - 1);
|
|
||||||
Heap->AlignRound = HEAP_ENTRY_SIZE - 1 + sizeof(HEAP_ENTRY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
|
DPRINT("Created heap %p, CommitSize %x, ReserveSize %x\n", Heap, CommitSize, TotalSize);
|
||||||
Heap->AlignRound += HEAP_ENTRY_SIZE;
|
|
||||||
|
|
||||||
/* Add heap to process list in case of usermode heap */
|
/* Add heap to process list in case of usermode heap */
|
||||||
if (RtlpGetMode() == UserMode)
|
if (RtlpGetMode() == UserMode)
|
||||||
|
@ -1634,7 +1616,6 @@ RtlCreateHeap(ULONG Flags,
|
||||||
// FIXME: What about lookasides?
|
// FIXME: What about lookasides?
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Heap %p, flags 0x%08x\n", Heap, Heap->Flags);
|
|
||||||
return Heap;
|
return Heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2063,7 +2044,7 @@ RtlAllocateHeap(IN PVOID HeapPtr,
|
||||||
/* Acquire the lock if necessary */
|
/* Acquire the lock if necessary */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2265,7 +2246,7 @@ BOOLEAN NTAPI RtlFreeHeap(
|
||||||
/* Lock if necessary */
|
/* Lock if necessary */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
Locked = TRUE;
|
Locked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2690,7 +2671,7 @@ RtlReAllocateHeap(HANDLE HeapPtr,
|
||||||
/* Acquire the lock if necessary */
|
/* Acquire the lock if necessary */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
Flags &= ~HEAP_NO_SERIALIZE;
|
Flags &= ~HEAP_NO_SERIALIZE;
|
||||||
}
|
}
|
||||||
|
@ -3071,7 +3052,7 @@ RtlLockHeap(IN HANDLE HeapPtr)
|
||||||
/* Lock if it's lockable */
|
/* Lock if it's lockable */
|
||||||
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -3651,7 +3632,7 @@ BOOLEAN NTAPI RtlValidateHeap(
|
||||||
/* Acquire the lock if necessary */
|
/* Acquire the lock if necessary */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3682,7 +3663,7 @@ RtlInitializeHeapManager(VOID)
|
||||||
Peb->NumberOfHeaps = 0;
|
Peb->NumberOfHeaps = 0;
|
||||||
|
|
||||||
/* Initialize the process heaps list protecting lock */
|
/* Initialize the process heaps list protecting lock */
|
||||||
RtlInitializeHeapLock(&RtlpProcessHeapsListLock);
|
RtlInitializeCriticalSection(&RtlpProcessHeapsListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3759,7 +3740,7 @@ RtlSetUserValueHeap(IN PVOID HeapHandle,
|
||||||
/* Lock if it's lockable */
|
/* Lock if it's lockable */
|
||||||
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3818,7 +3799,7 @@ RtlSetUserFlagsHeap(IN PVOID HeapHandle,
|
||||||
/* Lock if it's lockable */
|
/* Lock if it's lockable */
|
||||||
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3874,7 +3855,7 @@ RtlGetUserInfoHeap(IN PVOID HeapHandle,
|
||||||
/* Lock if it's lockable */
|
/* Lock if it's lockable */
|
||||||
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
if (!(Heap->Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
|
||||||
} HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
|
} HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern HEAP_LOCK RtlpProcessHeapsListLock;
|
extern RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
|
||||||
extern BOOLEAN RtlpPageHeapEnabled;
|
extern BOOLEAN RtlpPageHeapEnabled;
|
||||||
|
|
||||||
/* Functions declarations */
|
/* Functions declarations */
|
||||||
|
|
|
@ -163,7 +163,7 @@ RtlDebugAllocateHeap(PVOID HeapPtr,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -230,7 +230,7 @@ RtlDebugReAllocateHeap(HANDLE HeapPtr,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -288,7 +288,7 @@ RtlDebugFreeHeap(HANDLE HeapPtr,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -345,7 +345,7 @@ RtlDebugGetUserInfoHeap(PVOID HeapHandle,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -397,7 +397,7 @@ RtlDebugSetUserValueHeap(PVOID HeapHandle,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -461,7 +461,7 @@ RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
@ -516,7 +516,7 @@ RtlDebugSizeHeap(HANDLE HeapPtr,
|
||||||
/* Lock the heap ourselves */
|
/* Lock the heap ourselves */
|
||||||
if (!(Flags & HEAP_NO_SERIALIZE))
|
if (!(Flags & HEAP_NO_SERIALIZE))
|
||||||
{
|
{
|
||||||
RtlEnterHeapLock(Heap->LockVariable);
|
RtlEnterHeapLock(Heap->LockVariable, TRUE);
|
||||||
HeapLocked = TRUE;
|
HeapLocked = TRUE;
|
||||||
|
|
||||||
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
|
||||||
|
|
|
@ -86,19 +86,19 @@ RtlpCaptureStackLimits(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlDeleteHeapLock(PHEAP_LOCK Lock);
|
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlEnterHeapLock(PHEAP_LOCK Lock);
|
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlInitializeHeapLock(PHEAP_LOCK Lock);
|
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlLeaveHeapLock(PHEAP_LOCK Lock);
|
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -156,41 +156,49 @@ RtlGetCurrentPeb(VOID)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlDeleteHeapLock(
|
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
ExDeleteResource(&Lock->Resource);
|
ExDeleteResourceLite(&Lock->Resource);
|
||||||
|
ExFreePool(Lock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlEnterHeapLock(
|
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceExclusive(&Lock->Resource, TRUE);
|
|
||||||
KeLeaveCriticalRegion();
|
if (Exclusive)
|
||||||
|
ExAcquireResourceExclusiveLite(&Lock->Resource, TRUE);
|
||||||
|
else
|
||||||
|
ExAcquireResourceSharedLite(&Lock->Resource, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlInitializeHeapLock(
|
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
ExInitializeResource(&Lock->Resource);
|
PHEAP_LOCK HeapLock = ExAllocatePool(NonPagedPool, sizeof(HEAP_LOCK));
|
||||||
|
if (HeapLock == NULL)
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
ExInitializeResourceLite(&HeapLock->Resource);
|
||||||
|
*Lock = HeapLock;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlLeaveHeapLock(
|
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
|
||||||
PHEAP_LOCK Lock)
|
|
||||||
{
|
{
|
||||||
KeEnterCriticalRegion();
|
ExReleaseResourceLite(&Lock->Resource);
|
||||||
ExReleaseResource(&Lock->Resource);
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue