[RFC PATCH 03/11] ntdll: Split standard heap functions.

Rémi Bernon rbernon at codeweavers.com
Wed May 6 07:09:55 CDT 2020


---
 dlls/ntdll/heap.c       | 113 +++++++++++++++++++++++++++-------------
 dlls/ntdll/ntdll_misc.h |   7 +++
 2 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 0080a89fddb6..ac0a1c800163 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1335,8 +1335,6 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr,   /* [in] ptr to the heap */
     BOOL ret = FALSE;
     const ARENA_LARGE *large_arena;
 
-    flags &= HEAP_NO_SERIALIZE;
-    flags |= heapPtr->flags;
     /* calling HeapLock may result in infinite recursion, so do the critsect directly */
     if (!(flags & HEAP_NO_SERIALIZE))
         RtlEnterCriticalSection( &heapPtr->critSection );
@@ -1644,18 +1642,27 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
  *  This call does not SetLastError().
  */
 void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
+{
+    HEAP *heapPtr;
+
+    if (!(heapPtr = HEAP_GetPtr( heap )))
+        return NULL;
+
+    flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
+    flags |= heapPtr->flags;
+
+    return HEAP_std_allocate( heapPtr, flags, size );
+}
+
+void * HEAP_std_allocate( HEAP *heapPtr, ULONG flags, SIZE_T size )
 {
     ARENA_FREE *pArena;
     ARENA_INUSE *pInUse;
     SUBHEAP *subheap;
-    HEAP *heapPtr = HEAP_GetPtr( heap );
     SIZE_T rounded_size;
 
     /* Validate the parameters */
 
-    if (!heapPtr) return NULL;
-    flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
-    flags |= heapPtr->flags;
     rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags );
     if (rounded_size < size)  /* overflow */
     {
@@ -1668,10 +1675,10 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
 
     if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE && (flags & HEAP_GROWABLE))
     {
-        void *ret = allocate_large_block( heap, flags, size );
+        void *ret = allocate_large_block( heapPtr, flags, size );
         if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
         if (!ret && (flags & HEAP_GENERATE_EXCEPTIONS)) RtlRaiseStatus( STATUS_NO_MEMORY );
-        TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, ret );
+        TRACE("(%p,%08x,%08lx): returning %p\n", heapPtr, flags, size, ret );
         return ret;
     }
 
@@ -1680,7 +1687,7 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
     if (!(pArena = HEAP_FindFreeBlock( heapPtr, rounded_size, &subheap )))
     {
         TRACE("(%p,%08x,%08lx): returning NULL\n",
-                  heap, flags, size  );
+                  heapPtr, flags, size  );
         if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
         if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
         return NULL;
@@ -1709,7 +1716,7 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
 
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, pInUse + 1 );
+    TRACE("(%p,%08x,%08lx): returning %p\n", heapPtr, flags, size, pInUse + 1 );
     return pInUse + 1;
 }
 
@@ -1730,16 +1737,11 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
  */
 BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *ptr )
 {
-    ARENA_INUSE *pInUse;
-    SUBHEAP *subheap;
     HEAP *heapPtr;
 
-    /* Validate the parameters */
-
     if (!ptr) return TRUE;  /* freeing a NULL ptr isn't an error in Win2k */
 
-    heapPtr = HEAP_GetPtr( heap );
-    if (!heapPtr)
+    if (!(heapPtr = HEAP_GetPtr( heap )))
     {
         RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE );
         return FALSE;
@@ -1747,6 +1749,17 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
 
     flags &= HEAP_NO_SERIALIZE;
     flags |= heapPtr->flags;
+
+    return HEAP_std_free( heapPtr, flags, ptr );
+}
+
+BOOLEAN HEAP_std_free( HEAP *heapPtr, ULONG flags, void *ptr )
+{
+    ARENA_INUSE *pInUse;
+    SUBHEAP *subheap;
+
+    /* Validate the parameters */
+
     if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
 
     /* Inform valgrind we are trying to free memory, so it can throw up an error message */
@@ -1762,13 +1775,13 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
         HEAP_MakeInUseBlockFree( subheap, pInUse );
 
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
-    TRACE("(%p,%08x,%p): returning TRUE\n", heap, flags, ptr );
+    TRACE("(%p,%08x,%p): returning TRUE\n", heapPtr, flags, ptr );
     return TRUE;
 
 error:
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
     RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
-    TRACE("(%p,%08x,%p): returning FALSE\n", heap, flags, ptr );
+    TRACE("(%p,%08x,%p): returning FALSE\n", heapPtr, flags, ptr );
     return FALSE;
 }
 
@@ -1790,24 +1803,33 @@ error:
  */
 PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size )
 {
-    ARENA_INUSE *pArena;
     HEAP *heapPtr;
-    SUBHEAP *subheap;
-    SIZE_T oldBlockSize, oldActualSize, rounded_size;
-    void *ret;
 
-    if (!ptr) return NULL;
+    if (!ptr)
+        return NULL;
+
     if (!(heapPtr = HEAP_GetPtr( heap )))
     {
         RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE );
         return NULL;
     }
 
-    /* Validate the parameters */
-
     flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY |
              HEAP_REALLOC_IN_PLACE_ONLY;
     flags |= heapPtr->flags;
+
+    return HEAP_std_reallocate( heapPtr, flags, ptr, size );
+}
+
+void *HEAP_std_reallocate( HEAP *heapPtr, ULONG flags, void *ptr, SIZE_T size )
+{
+    ARENA_INUSE *pArena;
+    SUBHEAP *subheap;
+    SIZE_T oldBlockSize, oldActualSize, rounded_size;
+    void *ret;
+
+    /* Validate the parameters */
+
     if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
 
     rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
@@ -1903,20 +1925,20 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
     ret = pArena + 1;
 done:
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
-    TRACE("(%p,%08x,%p,%08lx): returning %p\n", heap, flags, ptr, size, ret );
+    TRACE("(%p,%08x,%p,%08lx): returning %p\n", heapPtr, flags, ptr, size, ret );
     return ret;
 
 oom:
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
     if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
     RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_NO_MEMORY );
-    TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heap, flags, ptr, size );
+    TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heapPtr, flags, ptr, size );
     return NULL;
 
 error:
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
     RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
-    TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heap, flags, ptr, size );
+    TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heapPtr, flags, ptr, size );
     return NULL;
 }
 
@@ -2005,18 +2027,26 @@ BOOLEAN WINAPI RtlUnlockHeap( HANDLE heap )
  */
 SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
 {
-    SIZE_T ret;
-    const ARENA_INUSE *pArena;
-    SUBHEAP *subheap;
-    HEAP *heapPtr = HEAP_GetPtr( heap );
+    HEAP *heapPtr;
 
-    if (!heapPtr)
+    if (!(heapPtr = HEAP_GetPtr( heap )))
     {
         RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE );
         return ~0UL;
     }
+
     flags &= HEAP_NO_SERIALIZE;
     flags |= heapPtr->flags;
+
+    return HEAP_std_get_allocated_size( heapPtr, flags, ptr );
+}
+
+SIZE_T HEAP_std_get_allocated_size( HEAP *heapPtr, ULONG flags, const void *ptr )
+{
+    SIZE_T ret;
+    const ARENA_INUSE *pArena;
+    SUBHEAP *subheap;
+
     if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
 
     pArena = (const ARENA_INUSE *)ptr - 1;
@@ -2036,7 +2066,7 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
     }
     if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    TRACE("(%p,%08x,%p): returning %08lx\n", heap, flags, ptr, ret );
+    TRACE("(%p,%08x,%p): returning %08lx\n", heapPtr, flags, ptr, ret );
     return ret;
 }
 
@@ -2057,8 +2087,19 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
  */
 BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, LPCVOID ptr )
 {
-    HEAP *heapPtr = HEAP_GetPtr( heap );
-    if (!heapPtr) return FALSE;
+    HEAP *heapPtr;
+
+    if (!(heapPtr = HEAP_GetPtr( heap )))
+        return FALSE;
+
+    flags &= HEAP_NO_SERIALIZE;
+    flags |= heapPtr->flags;
+
+    return HEAP_std_validate( heapPtr, flags, ptr );
+}
+
+BOOLEAN HEAP_std_validate( HEAP *heapPtr, ULONG flags, const void *ptr )
+{
     return HEAP_IsRealArena( heapPtr, flags, ptr, QUIET );
 }
 
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 13771d230a88..fc78a24dc9d3 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -283,6 +283,13 @@ static inline int get_unix_exit_code( NTSTATUS status )
     return status;
 }
 
+struct tagHEAP;
+void   *HEAP_std_allocate( struct tagHEAP *heap, ULONG flags, SIZE_T size );
+BOOLEAN HEAP_std_free( struct tagHEAP *heap, ULONG flags, void *ptr );
+void   *HEAP_std_reallocate( struct tagHEAP *heap, ULONG flags, void *ptr, SIZE_T size );
+SIZE_T  HEAP_std_get_allocated_size( struct tagHEAP *heap, ULONG flags, const void *ptr );
+BOOLEAN HEAP_std_validate( struct tagHEAP *heap, ULONG flags, const void *ptr );
+
 extern mode_t FILE_umask DECLSPEC_HIDDEN;
 extern HANDLE keyed_event DECLSPEC_HIDDEN;
 extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN;
-- 
2.26.1




More information about the wine-devel mailing list