#define ARENA_FLAG_FREE 0x00000001 /* flags OR'ed with arena size */
#define ARENA_FLAG_PREV_FREE 0x00000002
-#define ARENA_SIZE_MASK (~3)
#define ARENA_INUSE_MAGIC 0x455355 /* Value for arena 'magic' field */
#define ARENA_FREE_MAGIC 0x45455246 /* Value for arena 'magic' field */
+#ifndef _WIN64
+#define ARENA_SIZE_MASK (~3L)
+#else
+#define ARENA_SIZE_MASK (~7L)
+#endif
+
#define ARENA_INUSE_FILLER 0x55
#define ARENA_FREE_FILLER 0xaa
/* Max size of the blocks on the free lists */
static const DWORD HEAP_freeListSizes[HEAP_NB_FREE_LISTS] =
{
- 0x10, 0x20, 0x80, 0x200, ~0UL
+ 0x10, 0x20, 0x80, 0x200, MAXULONG
};
-typedef struct
+typedef union
{
ARENA_FREE arena;
void *aligment[4];
{
SUBHEAP subheap; /* First sub-heap */
struct list entry; /* Entry in process heap list */
- RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */
- FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */
+ HEAP_LOCK lock; /* Critical section for serialization */
+ DECLSPEC_ALIGN(8) FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */
DWORD flags; /* Heap flags */
DWORD magic; /* Magic number */
PRTL_HEAP_COMMIT_ROUTINE commitRoutine;
{
if (!processHeap) /* do it by hand to avoid memory allocations */
{
- heap->critSection.DebugInfo = &process_heap_critsect_debug;
- heap->critSection.LockCount = -1;
- heap->critSection.RecursionCount = 0;
- heap->critSection.OwningThread = 0;
- heap->critSection.LockSemaphore = 0;
- heap->critSection.SpinCount = 0;
- process_heap_critsect_debug.CriticalSection = &heap->critSection;
+ heap->lock.CriticalSection.DebugInfo = &process_heap_critsect_debug;
+ heap->lock.CriticalSection.LockCount = -1;
+ heap->lock.CriticalSection.RecursionCount = 0;
+ heap->lock.CriticalSection.OwningThread = 0;
+ heap->lock.CriticalSection.LockSemaphore = 0;
+ heap->lock.CriticalSection.SpinCount = 0;
+ process_heap_critsect_debug.CriticalSection = &heap->lock.CriticalSection;
}
- else RtlInitializeHeapLock( &heap->critSection );
+ else RtlInitializeHeapLock( &heap->lock );
}
}
flags |= heapPtr->flags;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if (!(flags & HEAP_NO_SERIALIZE))
- RtlEnterHeapLock( &heapPtr->critSection );
+ RtlEnterHeapLock( &heapPtr->lock );
if (block)
{
ret = HEAP_ValidateInUseArena( subheap, (const ARENA_INUSE *)block - 1, quiet );
if (!(flags & HEAP_NO_SERIALIZE))
- RtlLeaveHeapLock( &heapPtr->critSection );
+ RtlLeaveHeapLock( &heapPtr->lock );
return ret;
}
subheap = subheap->next;
}
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
return ret;
}
if (processHeap)
{
HEAP *heapPtr = subheap->heap;
- RtlEnterHeapLock( &processHeap->critSection );
+ RtlEnterHeapLock( &processHeap->lock );
list_add_head( &processHeap->entry, &heapPtr->entry );
- RtlLeaveHeapLock( &processHeap->critSection );
+ RtlLeaveHeapLock( &processHeap->lock );
}
else
{
return heap; /* cannot delete the main process heap */
/* remove it from the per-process list */
- RtlEnterHeapLock( &processHeap->critSection );
+ RtlEnterHeapLock( &processHeap->lock );
list_remove( &heapPtr->entry );
- RtlLeaveHeapLock( &processHeap->critSection );
+ RtlLeaveHeapLock( &processHeap->lock );
}
- RtlDeleteHeapLock( &heapPtr->critSection );
+ RtlDeleteHeapLock( &heapPtr->lock );
subheap = &heapPtr->subheap;
while (subheap)
{
PVOID NTAPI
RtlAllocateHeap(HANDLE heap, /* [in] Handle of private heap block */
ULONG flags, /* [in] Heap allocation control flags */
- ULONG size) /* [in] Number of bytes to allocate */
+ SIZE_T size) /* [in] Number of bytes to allocate */
{
ARENA_FREE *pArena;
ARENA_INUSE *pInUse;
if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
/* Locate a suitable free block */
if (!(pArena = HEAP_FindFreeBlock( heapPtr, rounded_size, &subheap )))
{
TRACE("(%p,%08lx,%08lx): returning NULL\n",
heap, flags, size );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
return NULL;
}
else
mark_block_uninitialized( pInUse + 1, pInUse->size & ARENA_SIZE_MASK );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%08lx): returning %p\n", heap, flags, size, pInUse + 1 );
return (LPVOID)(pInUse + 1);
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08lx,%p): returning FALSE\n", heap, flags, ptr );
return FALSE;
HEAP_MakeInUseBlockFree( subheap, pInUse );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p): returning TRUE\n", heap, flags, ptr );
return TRUE;
error:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p): returning FALSE\n", heap, flags, ptr );
return FALSE;
//Flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY |
// HEAP_REALLOC_IN_PLACE_ONLY;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
rounded_size = ROUND_SIZE(size);
if (rounded_size < size) goto oom; /* overflow */
/* Return the new arena */
done:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p,%08lx): returning %p\n", heap, flags, ptr, size, pArena + 1 );
return (LPVOID)(pArena + 1);
oom:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_NO_MEMORY );
TRACE("(%p,%08x,%p,%08lx): returning oom\n", heap, flags, ptr, size );
return NULL;
error:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p,%08lx): returning error\n", heap, flags, ptr, size );
return NULL;
HEAP *heapPtr = HEAP_GetPtr( Heap );
if (!heapPtr)
return FALSE;
- RtlEnterHeapLock( &heapPtr->critSection );
+ RtlEnterHeapLock( &heapPtr->lock );
return TRUE;
}
HEAP *heapPtr = HEAP_GetPtr( Heap );
if (!heapPtr)
return FALSE;
- RtlLeaveHeapLock( &heapPtr->critSection );
+ RtlLeaveHeapLock( &heapPtr->lock );
return TRUE;
}
*
* @implemented
*/
-ULONG NTAPI
+SIZE_T NTAPI
RtlSizeHeap(
HANDLE heap,
ULONG flags,
PVOID ptr
)
{
- SIZE_T ret;
+ SIZE_T ret;
HEAP *heapPtr = HEAP_GetPtr( heap );
if (!heapPtr)
{
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE );
- return ~0UL;
+ return MAXULONG;
}
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterHeapLock( &heapPtr->lock );
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
- ret = ~0UL;
+ ret = MAXULONG;
}
else
{
const ARENA_INUSE *pArena = (const ARENA_INUSE *)ptr - 1;
ret = (pArena->size & ARENA_SIZE_MASK) - pArena->unused_bytes;
}
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveHeapLock( &heapPtr->lock );
TRACE("(%p,%08lx,%p): returning %08lx\n", heap, flags, ptr, ret );
return ret;
NTSTATUS Status = STATUS_SUCCESS;
struct list *ptr=NULL;
- RtlEnterHeapLock(&processHeap->critSection);
+ RtlEnterHeapLock(&processHeap->lock);
Status=HeapEnumerationRoutine(processHeap,lParam);
LIST_FOR_EACH( ptr, &processHeap->entry )
Status = HeapEnumerationRoutine(ptr,lParam);
}
- RtlLeaveHeapLock(&processHeap->critSection);
+ RtlLeaveHeapLock(&processHeap->lock);
return Status;
}
ULONG total = 1; /* main heap */
struct list *ptr;
ULONG i=0;
- RtlEnterHeapLock( &processHeap->critSection );
+ RtlEnterHeapLock( &processHeap->lock );
LIST_FOR_EACH( ptr, &processHeap->entry ) total++;
//if (total <= count)
{
*(heaps++) = LIST_ENTRY( ptr, HEAP, entry );
}
}
- RtlLeaveHeapLock( &processHeap->critSection );
+ RtlLeaveHeapLock( &processHeap->lock );
return i;
}
BOOLEAN Result = TRUE;
HEAP ** pptr;
- RtlEnterHeapLock( &processHeap->critSection );
+ RtlEnterHeapLock( &processHeap->lock );
for (pptr = (HEAP**)&NtCurrentPeb()->ProcessHeaps; *pptr; pptr++)
{
}
}
- RtlLeaveHeapLock( &processHeap->critSection );
+ RtlLeaveHeapLock( &processHeap->lock );
return Result;
}
RtlSetUserFlagsHeap(IN PVOID HeapHandle,
IN ULONG Flags,
IN PVOID BaseAddress,
- IN ULONG UserFlags)
+ IN ULONG UserFlagsReset,
+ IN ULONG UserFlagsSet)
{
HEAP *heapPtr;
PHEAP_USER_DATA udata;
udata = HEAP_AllocUserData(heapPtr, BaseAddress);
if (!udata) return FALSE;
}
- udata->UserFlags = UserFlags & HEAP_SETTABLE_USER_FLAGS;
+ udata->UserFlags = UserFlagsSet & HEAP_SETTABLE_USER_FLAGS;
return TRUE;
}
RtlExtendHeap(IN HANDLE Heap,
IN ULONG Flags,
IN PVOID P,
- IN ULONG Size)
+ IN SIZE_T Size)
{
/* TODO */
UNIMPLEMENTED;
return NULL;
}
-DWORD
+NTSTATUS
NTAPI
RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL,
IN HEAP_INFORMATION_CLASS HeapInformationClass,
return 0;
}
-DWORD
+NTSTATUS
NTAPI
RtlQueryHeapInformation(HANDLE HeapHandle,
HEAP_INFORMATION_CLASS HeapInformationClass,
SIZE_T HeapInformationLength OPTIONAL,
PSIZE_T ReturnLength OPTIONAL)
{
- UNIMPLEMENTED;
- return 0;
+ HEAP *heapPtr;
+
+ heapPtr = HEAP_GetPtr(HeapHandle);
+ if (!heapPtr)
+ {
+ RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE );
+ return FALSE;
+ }
+
+ UNIMPLEMENTED
+
+ switch (HeapInformationClass)
+ {
+ case HeapCompatibilityInformation:
+ if (ReturnLength) *ReturnLength = sizeof(ULONG);
+
+ if (HeapInformationLength < sizeof(ULONG))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ *(ULONG *)HeapInformation = 0; /* standard heap */
+ return STATUS_SUCCESS;
+ default:
+ return STATUS_INVALID_INFO_CLASS;
+ }
}
-DWORD
+NTSTATUS
NTAPI
RtlMultipleAllocateHeap(IN PVOID HeapHandle,
- IN DWORD Flags,
+ IN ULONG Flags,
IN SIZE_T Size,
- IN DWORD Count,
+ IN ULONG Count,
OUT PVOID *Array)
{
UNIMPLEMENTED;
return 0;
}
-DWORD
+NTSTATUS
NTAPI
RtlMultipleFreeHeap(IN PVOID HeapHandle,
- IN DWORD Flags,
- IN DWORD Count,
+ IN ULONG Flags,
+ IN ULONG Count,
OUT PVOID *Array)
{
UNIMPLEMENTED;