mirror of
https://github.com/reactos/reactos.git
synced 2024-09-04 09:39:07 +00:00
[HEAP]
- Fix RtlQuery/SetHeapInformation prototypes, move them to an appropriate place. - Implement RtlQuery/SetHeapInformation. - Implement in-place block growing. - Amount of winetest heap failures is down to 6 (3 exceptions still happen). svn path=/trunk/; revision=49111
This commit is contained in:
parent
dff2d51166
commit
0568f4e2ce
|
@ -707,6 +707,17 @@ RtlProtectHeap(
|
||||||
IN BOOLEAN Protect
|
IN BOOLEAN Protect
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RtlQueryHeapInformation (
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
|
OUT PVOID HeapInformation OPTIONAL,
|
||||||
|
IN SIZE_T HeapInformationLength OPTIONAL,
|
||||||
|
OUT PSIZE_T ReturnLength OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
PWSTR
|
PWSTR
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -728,6 +739,16 @@ RtlReAllocateHeap(
|
||||||
SIZE_T Size
|
SIZE_T Size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RtlSetHeapInformation (
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
|
IN PVOID HeapInformation OPTIONAL,
|
||||||
|
IN SIZE_T HeapInformationLength OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -735,6 +756,27 @@ RtlLockHeap(
|
||||||
IN HANDLE Heap
|
IN HANDLE Heap
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RtlMultipleAllocateHeap (
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN DWORD Flags,
|
||||||
|
IN SIZE_T Size,
|
||||||
|
IN DWORD Count,
|
||||||
|
OUT PVOID * Array
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
RtlMultipleFreeHeap (
|
||||||
|
IN PVOID HeapHandle,
|
||||||
|
IN DWORD Flags,
|
||||||
|
IN DWORD Count,
|
||||||
|
OUT PVOID * Array
|
||||||
|
);
|
||||||
|
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -4958,50 +4958,6 @@ typedef enum _HEAP_INFORMATION_CLASS {
|
||||||
HeapEnableTerminationOnCorruption
|
HeapEnableTerminationOnCorruption
|
||||||
} HEAP_INFORMATION_CLASS;
|
} HEAP_INFORMATION_CLASS;
|
||||||
|
|
||||||
NTSYSAPI
|
|
||||||
DWORD
|
|
||||||
NTAPI
|
|
||||||
RtlSetHeapInformation (
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
|
||||||
IN PVOID HeapInformation OPTIONAL,
|
|
||||||
IN SIZE_T HeapInformationLength OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSYSAPI
|
|
||||||
DWORD
|
|
||||||
NTAPI
|
|
||||||
RtlQueryHeapInformation (
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
|
||||||
OUT PVOID HeapInformation OPTIONAL,
|
|
||||||
IN SIZE_T HeapInformationLength OPTIONAL,
|
|
||||||
OUT PSIZE_T ReturnLength OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Multiple alloc-free APIS
|
|
||||||
//
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
NTAPI
|
|
||||||
RtlMultipleAllocateHeap (
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN DWORD Flags,
|
|
||||||
IN SIZE_T Size,
|
|
||||||
IN DWORD Count,
|
|
||||||
OUT PVOID * Array
|
|
||||||
);
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
NTAPI
|
|
||||||
RtlMultipleFreeHeap (
|
|
||||||
IN PVOID HeapHandle,
|
|
||||||
IN DWORD Flags,
|
|
||||||
IN DWORD Count,
|
|
||||||
OUT PVOID * Array
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef enum _PROCESSOR_CACHE_TYPE {
|
typedef enum _PROCESSOR_CACHE_TYPE {
|
||||||
CacheUnified,
|
CacheUnified,
|
||||||
CacheInstruction,
|
CacheInstruction,
|
||||||
|
|
|
@ -1934,7 +1934,7 @@ RtlProtectHeap(IN PVOID HeapHandle,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
|
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
|
||||||
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
|
@ -1945,7 +1945,7 @@ RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlQueryHeapInformation(HANDLE HeapHandle,
|
RtlQueryHeapInformation(HANDLE HeapHandle,
|
||||||
HEAP_INFORMATION_CLASS HeapInformationClass,
|
HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
|
@ -1979,7 +1979,7 @@ RtlQueryHeapInformation(HANDLE HeapHandle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
||||||
IN DWORD Flags,
|
IN DWORD Flags,
|
||||||
|
@ -1991,7 +1991,7 @@ RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlMultipleFreeHeap(IN PVOID HeapHandle,
|
RtlMultipleFreeHeap(IN PVOID HeapHandle,
|
||||||
IN DWORD Flags,
|
IN DWORD Flags,
|
||||||
|
|
|
@ -955,32 +955,32 @@ RtlpRemoveHeapFromProcessList(PHEAP Heap)
|
||||||
Use classic, lernt from university times algorithm for removing an entry
|
Use classic, lernt from university times algorithm for removing an entry
|
||||||
from a static array */
|
from a static array */
|
||||||
|
|
||||||
Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
|
Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
|
||||||
Next = Current + 1;
|
Next = Current + 1;
|
||||||
|
|
||||||
/* How many items we need to shift to the left */
|
/* How many items we need to shift to the left */
|
||||||
Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
|
Count = Peb->NumberOfHeaps - (Heap->ProcessHeapsListIndex - 1);
|
||||||
|
|
||||||
/* Move them all in a loop */
|
/* Move them all in a loop */
|
||||||
while (--Count)
|
while (--Count)
|
||||||
{
|
{
|
||||||
/* Copy it and advance next pointer */
|
/* Copy it and advance next pointer */
|
||||||
*Current = *Next;
|
*Current = *Next;
|
||||||
|
|
||||||
/* Update its index */
|
/* Update its index */
|
||||||
(*Current)->ProcessHeapsListIndex -= 1;
|
(*Current)->ProcessHeapsListIndex -= 1;
|
||||||
|
|
||||||
/* Advance pointers */
|
/* Advance pointers */
|
||||||
Current++;
|
Current++;
|
||||||
Next++;
|
Next++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrease total number of heaps */
|
/* Decrease total number of heaps */
|
||||||
Peb->NumberOfHeaps--;
|
Peb->NumberOfHeaps--;
|
||||||
|
|
||||||
/* Zero last unused item */
|
/* Zero last unused item */
|
||||||
Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
|
Peb->ProcessHeaps[Peb->NumberOfHeaps] = NULL;
|
||||||
Heap->ProcessHeapsListIndex = 0;
|
Heap->ProcessHeapsListIndex = 0;
|
||||||
|
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
|
RtlLeaveHeapLock(&RtlpProcessHeapsListLock);
|
||||||
|
@ -1977,6 +1977,8 @@ RtlpAllocateNonDedicated(PHEAP Heap,
|
||||||
|
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
||||||
|
DPRINT1("HEAP: Allocation failed!\n");
|
||||||
|
DPRINT1("Flags %x\n", Heap->Flags);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2016,7 +2018,8 @@ RtlAllocateHeap(IN PVOID HeapPtr,
|
||||||
if (Size >= 0x80000000)
|
if (Size >= 0x80000000)
|
||||||
{
|
{
|
||||||
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY);
|
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY);
|
||||||
return FALSE;
|
DPRINT1("HEAP: Allocation failed!\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flags & (
|
if (Flags & (
|
||||||
|
@ -2167,6 +2170,7 @@ RtlAllocateHeap(IN PVOID HeapPtr,
|
||||||
// Set STATUS!
|
// Set STATUS!
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
||||||
|
DPRINT1("HEAP: Allocation failed!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2202,6 +2206,7 @@ RtlAllocateHeap(IN PVOID HeapPtr,
|
||||||
|
|
||||||
/* Release the lock */
|
/* Release the lock */
|
||||||
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
|
||||||
|
DPRINT1("HEAP: Allocation failed!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,7 +2282,8 @@ BOOLEAN NTAPI RtlFreeHeap(
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed releasing memory with Status 0x%08X\n", Status);
|
DPRINT1("HEAP: Failed releasing memory with Status 0x%08X. Heap %p, ptr %p, base address %p\n",
|
||||||
|
Status, Heap, Ptr, VirtualEntry);
|
||||||
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(Status);
|
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2351,8 +2357,225 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
|
||||||
IN SIZE_T Size,
|
IN SIZE_T Size,
|
||||||
IN SIZE_T Index)
|
IN SIZE_T Index)
|
||||||
{
|
{
|
||||||
/* We always fail growing in place now */
|
UCHAR EntryFlags, RememberFlags;
|
||||||
return FALSE;
|
PHEAP_FREE_ENTRY FreeEntry, UnusedEntry, FollowingEntry;
|
||||||
|
SIZE_T FreeSize, PrevSize, TailPart, AddedSize = 0;
|
||||||
|
PHEAP_ENTRY_EXTRA OldExtra, NewExtra;
|
||||||
|
|
||||||
|
/* We can't grow beyond specified threshold */
|
||||||
|
if (Index > Heap->VirtualMemoryThreshold)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Get entry flags */
|
||||||
|
EntryFlags = InUseEntry->Flags;
|
||||||
|
|
||||||
|
/* Get the next free entry */
|
||||||
|
FreeEntry = (PHEAP_FREE_ENTRY)(InUseEntry + InUseEntry->Size);
|
||||||
|
|
||||||
|
if (EntryFlags & HEAP_ENTRY_LAST_ENTRY)
|
||||||
|
{
|
||||||
|
/* There is no next block, just uncommitted space. Calculate how much is needed */
|
||||||
|
FreeSize = (Index - InUseEntry->Size) << HEAP_ENTRY_SHIFT;
|
||||||
|
FreeSize = ROUND_UP(FreeSize, PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Find and commit those pages */
|
||||||
|
FreeEntry = RtlpFindAndCommitPages(Heap,
|
||||||
|
Heap->Segments[InUseEntry->SegmentOffset],
|
||||||
|
&FreeSize,
|
||||||
|
FreeEntry);
|
||||||
|
|
||||||
|
/* Fail if it failed... */
|
||||||
|
if (!FreeEntry) return FALSE;
|
||||||
|
|
||||||
|
/* It was successful, perform coalescing */
|
||||||
|
FreeSize = FreeSize >> HEAP_ENTRY_SHIFT;
|
||||||
|
FreeEntry = RtlpCoalesceFreeBlocks(Heap, FreeEntry, &FreeSize, FALSE);
|
||||||
|
|
||||||
|
/* Check if it's enough */
|
||||||
|
if (FreeSize + InUseEntry->Size < Index)
|
||||||
|
{
|
||||||
|
/* Still not enough */
|
||||||
|
RtlpInsertFreeBlock(Heap, FreeEntry, FreeSize);
|
||||||
|
Heap->TotalFreeSize += FreeSize;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember flags of this free entry */
|
||||||
|
RememberFlags = FreeEntry->Flags;
|
||||||
|
|
||||||
|
/* Sum up sizes */
|
||||||
|
FreeSize += InUseEntry->Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The next block indeed exists. Check if it's free or in use */
|
||||||
|
if (FreeEntry->Flags & HEAP_ENTRY_BUSY) return FALSE;
|
||||||
|
|
||||||
|
/* Next entry is free, check if it can fit the block we need */
|
||||||
|
FreeSize = InUseEntry->Size + FreeEntry->Size;
|
||||||
|
if (FreeSize < Index) return FALSE;
|
||||||
|
|
||||||
|
/* Remember flags of this free entry */
|
||||||
|
RememberFlags = FreeEntry->Flags;
|
||||||
|
|
||||||
|
/* Remove this block from the free list */
|
||||||
|
RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE, FALSE);
|
||||||
|
Heap->TotalFreeSize -= FreeEntry->Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevSize = (InUseEntry->Size << HEAP_ENTRY_SHIFT) - InUseEntry->UnusedBytes;
|
||||||
|
FreeSize -= Index;
|
||||||
|
|
||||||
|
/* Don't produce too small blocks */
|
||||||
|
if (FreeSize <= 2)
|
||||||
|
{
|
||||||
|
Index += FreeSize;
|
||||||
|
FreeSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process extra stuff */
|
||||||
|
if (RememberFlags & HEAP_ENTRY_EXTRA_PRESENT)
|
||||||
|
{
|
||||||
|
/* Calculate pointers */
|
||||||
|
OldExtra = (PHEAP_ENTRY_EXTRA)(InUseEntry + InUseEntry->Size - 1);
|
||||||
|
NewExtra = (PHEAP_ENTRY_EXTRA)(InUseEntry + Index - 1);
|
||||||
|
|
||||||
|
/* Copy contents */
|
||||||
|
*NewExtra = *OldExtra;
|
||||||
|
|
||||||
|
// FIXME Tagging
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update sizes */
|
||||||
|
InUseEntry->Size = Index;
|
||||||
|
InUseEntry->UnusedBytes = ((Index << HEAP_ENTRY_SHIFT) - Size);
|
||||||
|
|
||||||
|
/* Check if there is a free space remaining after merging those blocks */
|
||||||
|
if (!FreeSize)
|
||||||
|
{
|
||||||
|
/* Update flags and sizes */
|
||||||
|
InUseEntry->Flags |= RememberFlags & HEAP_ENTRY_LAST_ENTRY;
|
||||||
|
|
||||||
|
/* Either update previous size of the next entry or mark it as a last
|
||||||
|
entry in the segment*/
|
||||||
|
if (RememberFlags & HEAP_ENTRY_LAST_ENTRY)
|
||||||
|
Heap->Segments[InUseEntry->SegmentOffset]->LastEntryInSegment = InUseEntry;
|
||||||
|
else
|
||||||
|
(InUseEntry + InUseEntry->Size)->PreviousSize = InUseEntry->Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Complex case, we need to split the block to give unused free space
|
||||||
|
back to the heap */
|
||||||
|
UnusedEntry = (PHEAP_FREE_ENTRY)(InUseEntry + Index);
|
||||||
|
UnusedEntry->PreviousSize = Index;
|
||||||
|
UnusedEntry->SegmentOffset = InUseEntry->SegmentOffset;
|
||||||
|
|
||||||
|
/* Update the following block or set the last entry in the segment */
|
||||||
|
if (RememberFlags & HEAP_ENTRY_LAST_ENTRY)
|
||||||
|
{
|
||||||
|
/* Set last entry and set flags and size */
|
||||||
|
Heap->Segments[InUseEntry->SegmentOffset]->LastEntryInSegment = InUseEntry;
|
||||||
|
UnusedEntry->Flags = RememberFlags;
|
||||||
|
UnusedEntry->Size = FreeSize;
|
||||||
|
|
||||||
|
/* Insert it to the heap and update total size */
|
||||||
|
RtlpInsertFreeBlockHelper(Heap, UnusedEntry, FreeSize, FALSE);
|
||||||
|
Heap->TotalFreeSize += FreeSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* There is a block after this one */
|
||||||
|
FollowingEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)UnusedEntry + FreeSize);
|
||||||
|
|
||||||
|
if (FollowingEntry->Flags & HEAP_ENTRY_BUSY)
|
||||||
|
{
|
||||||
|
/* Update flags and set size of the unused space entry */
|
||||||
|
UnusedEntry->Flags = RememberFlags & (~HEAP_ENTRY_LAST_ENTRY);
|
||||||
|
UnusedEntry->Size = FreeSize;
|
||||||
|
|
||||||
|
/* Update previous size of the following entry */
|
||||||
|
FollowingEntry->PreviousSize = FreeSize;
|
||||||
|
|
||||||
|
/* Insert it to the heap and update total free size */
|
||||||
|
RtlpInsertFreeBlockHelper(Heap, UnusedEntry, FreeSize, FALSE);
|
||||||
|
Heap->TotalFreeSize += FreeSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* That following entry is also free, what a fortune! */
|
||||||
|
RememberFlags = FollowingEntry->Flags;
|
||||||
|
|
||||||
|
/* Remove it */
|
||||||
|
RtlpRemoveFreeBlock(Heap, FollowingEntry, FALSE, FALSE);
|
||||||
|
Heap->TotalFreeSize -= FollowingEntry->Size;
|
||||||
|
|
||||||
|
/* And make up a new combined block */
|
||||||
|
FreeSize += FollowingEntry->Size;
|
||||||
|
UnusedEntry->Flags = RememberFlags;
|
||||||
|
|
||||||
|
/* Check where to put it */
|
||||||
|
if (FreeSize <= HEAP_MAX_BLOCK_SIZE)
|
||||||
|
{
|
||||||
|
/* Fine for a dedicated list */
|
||||||
|
UnusedEntry->Size = FreeSize;
|
||||||
|
|
||||||
|
if (RememberFlags & HEAP_ENTRY_LAST_ENTRY)
|
||||||
|
Heap->Segments[UnusedEntry->SegmentOffset]->LastEntryInSegment = (PHEAP_ENTRY)UnusedEntry;
|
||||||
|
else
|
||||||
|
((PHEAP_ENTRY)UnusedEntry + FreeSize)->PreviousSize = FreeSize;
|
||||||
|
|
||||||
|
/* Insert it back and update total size */
|
||||||
|
RtlpInsertFreeBlockHelper(Heap, UnusedEntry, FreeSize, FALSE);
|
||||||
|
Heap->TotalFreeSize += FreeSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The block is very large, leave all the hassle to the insertion routine */
|
||||||
|
RtlpInsertFreeBlock(Heap, UnusedEntry, FreeSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy user settable flags */
|
||||||
|
InUseEntry->Flags &= ~HEAP_ENTRY_SETTABLE_FLAGS;
|
||||||
|
InUseEntry->Flags |= ((Flags & HEAP_SETTABLE_USER_FLAGS) >> 4);
|
||||||
|
|
||||||
|
/* Properly "zero out" (and fill!) the space */
|
||||||
|
if (Flags & HEAP_ZERO_MEMORY)
|
||||||
|
{
|
||||||
|
RtlZeroMemory((PCHAR)(InUseEntry + 1) + PrevSize, Size - PrevSize);
|
||||||
|
}
|
||||||
|
else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
|
||||||
|
{
|
||||||
|
/* Calculate tail part which we need to fill */
|
||||||
|
TailPart = PrevSize & (sizeof(ULONG) - 1);
|
||||||
|
|
||||||
|
/* "Invert" it as usual */
|
||||||
|
if (TailPart) TailPart = 4 - TailPart;
|
||||||
|
|
||||||
|
if (Size > (PrevSize + TailPart))
|
||||||
|
AddedSize = (Size - (PrevSize + TailPart)) & ~(sizeof(ULONG) - 1);
|
||||||
|
|
||||||
|
if (AddedSize)
|
||||||
|
{
|
||||||
|
RtlFillMemoryUlong((PCHAR)(InUseEntry + 1) + PrevSize + TailPart,
|
||||||
|
AddedSize,
|
||||||
|
ARENA_INUSE_FILLER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the new tail */
|
||||||
|
if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
|
||||||
|
{
|
||||||
|
RtlFillMemory((PCHAR)(InUseEntry + 1) + Size,
|
||||||
|
HEAP_ENTRY_SIZE,
|
||||||
|
HEAP_TAIL_FILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PHEAP_ENTRY_EXTRA NTAPI
|
PHEAP_ENTRY_EXTRA NTAPI
|
||||||
|
@ -3270,18 +3493,34 @@ RtlProtectHeap(IN PVOID HeapHandle,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
|
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
|
||||||
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
IN HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
IN PVOID HeapInformation,
|
IN PVOID HeapInformation,
|
||||||
IN SIZE_T HeapInformationLength)
|
IN SIZE_T HeapInformationLength)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
/* Setting heap information is not really supported except for enabling LFH */
|
||||||
return 0;
|
if (HeapInformationClass == 0) return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Check buffer length */
|
||||||
|
if (HeapInformationLength < sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* The provided buffer is too small */
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for a special magic value for enabling LFH */
|
||||||
|
if (*(PULONG)HeapInformation == 2)
|
||||||
|
{
|
||||||
|
DPRINT1("RtlSetHeapInformation() needs to enable LFH\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlQueryHeapInformation(HANDLE HeapHandle,
|
RtlQueryHeapInformation(HANDLE HeapHandle,
|
||||||
HEAP_INFORMATION_CLASS HeapInformationClass,
|
HEAP_INFORMATION_CLASS HeapInformationClass,
|
||||||
|
@ -3289,11 +3528,29 @@ RtlQueryHeapInformation(HANDLE HeapHandle,
|
||||||
SIZE_T HeapInformationLength OPTIONAL,
|
SIZE_T HeapInformationLength OPTIONAL,
|
||||||
PSIZE_T ReturnLength OPTIONAL)
|
PSIZE_T ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PHEAP Heap = (PHEAP)HeapHandle;
|
||||||
return 0;
|
|
||||||
|
/* Only HeapCompatibilityInformation is supported */
|
||||||
|
if (HeapInformationClass != HeapCompatibilityInformation)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* Set result length */
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(ULONG);
|
||||||
|
|
||||||
|
/* Check buffer length */
|
||||||
|
if (HeapInformationLength < sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* It's too small, return needed length */
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return front end heap type */
|
||||||
|
*(PULONG)HeapInformation = Heap->FrontEndHeapType;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
||||||
IN DWORD Flags,
|
IN DWORD Flags,
|
||||||
|
@ -3305,7 +3562,7 @@ RtlMultipleAllocateHeap(IN PVOID HeapHandle,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlMultipleFreeHeap(IN PVOID HeapHandle,
|
RtlMultipleFreeHeap(IN PVOID HeapHandle,
|
||||||
IN DWORD Flags,
|
IN DWORD Flags,
|
||||||
|
|
Loading…
Reference in a new issue