[RTL/HEAP]

- Implement missing parts of a virtual block allocations support.
- Minor fixes to handling extra stuff in heap blocks.
- Wine's heap regression tests now run through the end without crashing and show 277 failures.

svn path=/trunk/; revision=49010
This commit is contained in:
Aleksey Bragin
2010-10-06 09:19:24 +00:00
parent 3ca783f940
commit b2e1788e8e
+50 -8
View File
@@ -2404,7 +2404,9 @@ BOOLEAN NTAPI RtlFreeHeap(
PHEAP_ENTRY HeapEntry;
USHORT TagIndex = 0;
SIZE_T BlockSize;
PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
BOOLEAN Locked = FALSE;
NTSTATUS Status;
/* Freeing NULL pointer is a legal operation */
if (!Ptr) return TRUE;
@@ -2440,7 +2442,24 @@ BOOLEAN NTAPI RtlFreeHeap(
if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
{
/* Big allocation */
ASSERT(FALSE);
VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
/* Remove it from the list */
RemoveEntryList(&VirtualEntry->Entry);
// TODO: Tagging
BlockSize = 0;
Status = ZwFreeVirtualMemory(NtCurrentProcess(),
(PVOID *)&VirtualEntry,
&BlockSize,
MEM_RELEASE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed releasing memory with Status 0x%08X\n", Status);
// TODO: Set this status in user mode
}
}
else
{
@@ -2516,6 +2535,26 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
return FALSE;
}
PHEAP_ENTRY_EXTRA NTAPI
RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry)
{
PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
/* Check if it's a big block */
if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
{
VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
/* Return a pointer to the extra stuff*/
return &VirtualEntry->ExtraStuff;
}
else
{
/* This is a usual entry, which means extra stuff follows this block */
return (PHEAP_ENTRY_EXTRA)(HeapEntry + HeapEntry->Size - 1);
}
}
/***********************************************************************
* RtlReAllocateHeap
@@ -2870,12 +2909,11 @@ RtlReAllocateHeap(HANDLE HeapPtr,
/* Process extra stuff if it exists */
if (NewInUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
{
UNIMPLEMENTED;
NewExtra = NULL;//RtlpGetExtraStuffPointer(NewInUseEntry);
NewExtra = RtlpGetExtraStuffPointer(NewInUseEntry);
if (InUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
{
OldExtra = NULL;//RtlpGetExtraStuffPointer(InUseEntry);
OldExtra = RtlpGetExtraStuffPointer(InUseEntry);
NewExtra->Settable = OldExtra->Settable;
}
else
@@ -3031,6 +3069,13 @@ RtlSizeHeap(
PHEAP_ENTRY HeapEntry;
SIZE_T EntrySize;
// FIXME This is a hack around missing SEH support!
if (!Heap)
{
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_HANDLE);
return (SIZE_T)-1;
}
/* Force flags */
Flags |= Heap->Flags;
@@ -3049,10 +3094,7 @@ RtlSizeHeap(
/* Get size of this block depending if it's a usual or a big one */
if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
{
// FIXME implement
UNIMPLEMENTED;
ASSERT(FALSE);
EntrySize = 0;
EntrySize = RtlpGetSizeOfBigBlock(HeapEntry);
}
else
{