Author: fireball
Date: Wed Oct 6 09:19:24 2010
New Revision: 49010
URL:
http://svn.reactos.org/svn/reactos?rev=49010&view=rev
Log:
[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.
Modified:
trunk/reactos/lib/rtl/heap_rewrite.c
Modified: trunk/reactos/lib/rtl/heap_rewrite.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap_rewrite.c?rev…
==============================================================================
--- trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] Wed Oct 6 09:19:24 2010
@@ -2404,7 +2404,9 @@
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 @@
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
{
@@ -2514,6 +2533,26 @@
{
/* We always fail growing in place now */
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);
+ }
}
@@ -2870,12 +2909,11 @@
/* 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 @@
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 @@
/* 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
{