[PATCH 6/6] kernelbase: Cleanup and simplify LocalReAlloc.

Rémi Bernon wine at gitlab.winehq.org
Fri Jun 3 03:14:28 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/kernel32/heap.c       |   2 +
 dlls/kernel32/tests/heap.c |  11 ----
 dlls/kernelbase/memory.c   | 108 ++++++++++++++-----------------------
 3 files changed, 42 insertions(+), 79 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index df094c94257..6a1a02c814b 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -315,6 +315,8 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
  */
 HGLOBAL WINAPI GlobalReAlloc( HGLOBAL handle, SIZE_T size, UINT flags )
 {
+    struct mem_entry *mem;
+    if ((mem = unsafe_mem_from_HLOCAL( handle )) && mem->lock) return 0;
     return LocalReAlloc( handle, size, flags );
 }
 
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 057342de9e9..39d2aea3965 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -1633,9 +1633,7 @@ static void test_GlobalAlloc(void)
     mem = GlobalAlloc( GMEM_FIXED, 10 );
     ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() );
     tmp_mem = GlobalReAlloc( mem, 9, GMEM_MODIFY );
-    todo_wine
     ok( !!tmp_mem, "GlobalAlloc failed, error %lu\n", GetLastError() );
-    todo_wine
     ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem );
     size = GlobalSize( mem );
     ok( size == 10, "GlobalSize returned %Iu\n", size );
@@ -1649,9 +1647,7 @@ static void test_GlobalAlloc(void)
         "got error %lu\n", GetLastError() );
     if (tmp_mem) mem = tmp_mem;
     tmp_mem = GlobalReAlloc( mem, 1024 * 1024, GMEM_MODIFY );
-    todo_wine
     ok( !!tmp_mem, "GlobalAlloc failed, error %lu\n", GetLastError() );
-    todo_wine
     ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem );
     size = GlobalSize( mem );
     ok( size == 10, "GlobalSize returned %Iu\n", size );
@@ -1986,9 +1982,7 @@ static void test_LocalAlloc(void)
     mem = LocalAlloc( LMEM_FIXED, 10 );
     ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() );
     tmp_mem = LocalReAlloc( mem, 9, LMEM_MODIFY );
-    todo_wine
     ok( !!tmp_mem, "LocalAlloc failed, error %lu\n", GetLastError() );
-    todo_wine
     ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem );
     size = LocalSize( mem );
     ok( size == 10, "LocalSize returned %Iu\n", size );
@@ -2002,9 +1996,7 @@ static void test_LocalAlloc(void)
         "got error %lu\n", GetLastError() );
     if (tmp_mem) mem = tmp_mem;
     tmp_mem = LocalReAlloc( mem, 1024 * 1024, LMEM_MODIFY );
-    todo_wine
     ok( !!tmp_mem, "LocalAlloc failed, error %lu\n", GetLastError() );
-    todo_wine
     ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem );
     size = LocalSize( mem );
     ok( size == 10, "LocalSize returned %Iu\n", size );
@@ -2103,13 +2095,10 @@ static void test_LocalAlloc(void)
     tmp_mem = LocalHandle( ptr );
     ok( tmp_mem == mem, "LocalHandle returned unexpected handle\n" );
     tmp_mem = LocalDiscard( mem );
-    todo_wine
     ok( !!tmp_mem, "LocalDiscard failed, error %lu\n", GetLastError() );
-    todo_wine
     ok( tmp_mem == mem, "LocalDiscard returned unexpected handle\n" );
     ret = LocalUnlock( mem );
     ok( !ret, "LocalUnlock succeeded, error %lu\n", GetLastError() );
-    todo_wine
     ok( GetLastError() == ERROR_NOT_LOCKED, "got error %lu\n", GetLastError() );
 
     tmp_mem = LocalDiscard( mem );
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 625ff56fdef..4660bb4f561 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -939,7 +939,8 @@ LPVOID WINAPI DECLSPEC_HOTPATCH LocalLock( HLOCAL handle )
  */
 HLOCAL WINAPI DECLSPEC_HOTPATCH LocalReAlloc( HLOCAL handle, SIZE_T size, UINT flags )
 {
-    DWORD heap_flags = HEAP_ADD_USER_INFO;
+    DWORD heap_flags = HEAP_ADD_USER_INFO | HEAP_NO_SERIALIZE;
+    HANDLE heap = GetProcessHeap();
     struct mem_entry *mem;
     HLOCAL ret = 0;
     void *ptr;
@@ -948,90 +949,61 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalReAlloc( HLOCAL handle, SIZE_T size, UINT f
 
     if (flags & LMEM_ZEROINIT) heap_flags |= HEAP_ZERO_MEMORY;
 
-    RtlLockHeap( GetProcessHeap() );
-    if (flags & LMEM_MODIFY) /* modify flags */
+    RtlLockHeap( heap );
+    if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
     {
-        if (unsafe_ptr_from_HLOCAL( handle ) && (flags & LMEM_MOVEABLE))
+        if (!(flags & LMEM_MOVEABLE))
         {
-            /* make a fixed block moveable
-             * actually only NT is able to do this. But it's soo simple
-             */
-            if (handle == 0)
-            {
-                WARN_(globalmem)( "null handle\n" );
-                SetLastError( ERROR_NOACCESS );
-            }
-            else
-            {
-                size = RtlSizeHeap( GetProcessHeap(), 0, handle );
-                ret = LocalAlloc( flags, size );
-                ptr = LocalLock( ret );
-                memcpy( ptr, handle, size );
-                LocalUnlock( ret );
-                LocalFree( handle );
-            }
+            heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
+            if (!(flags & LMEM_MODIFY) || !(flags & LMEM_MOVEABLE)) ret = handle;
+            else ret = HeapReAlloc( heap, heap_flags, ptr, size );
         }
-        else if ((mem = unsafe_mem_from_HLOCAL( handle )) && (flags & LMEM_DISCARDABLE))
+        else if (flags & LMEM_MODIFY)
         {
-            /* change the flags to make our block "discardable" */
-            mem->flags |= LMEM_DISCARDABLE >> 8;
-            ret = handle;
+            size = RtlSizeHeap( heap, 0, handle );
+            ret = LocalAlloc( flags, size );
+            ptr = LocalLock( ret );
+            memcpy( ptr, handle, size );
+            LocalUnlock( ret );
+            LocalFree( handle );
         }
-        else SetLastError( ERROR_INVALID_PARAMETER );
+        else ret = HeapReAlloc( heap, heap_flags, handle, size );
     }
-    else
+    else if ((mem = unsafe_mem_from_HLOCAL( handle )))
     {
-        if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
+        if (!(flags & LMEM_MODIFY))
         {
-            /* reallocate fixed memory */
-            if (!(flags & LMEM_MOVEABLE)) heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
-            ret = HeapReAlloc( GetProcessHeap(), heap_flags, ptr, size );
-        }
-        else if ((mem = unsafe_mem_from_HLOCAL( handle )))
-        {
-            /* reallocate a moveable block */
-            if (size != 0)
+            if (size)
             {
-                if (size <= INT_MAX - HLOCAL_STORAGE)
+                if (!mem->ptr) ptr = HeapAlloc( heap, heap_flags, size + HLOCAL_STORAGE );
+                else ptr = HeapReAlloc( heap, heap_flags, (char *)mem->ptr - HLOCAL_STORAGE, size + HLOCAL_STORAGE );
+                if (!ptr) SetLastError( ERROR_OUTOFMEMORY );
+                else
                 {
-                    if (mem->ptr)
-                    {
-                        if ((ptr = HeapReAlloc( GetProcessHeap(), heap_flags, (char *)mem->ptr - HLOCAL_STORAGE,
-                                                size + HLOCAL_STORAGE )))
-                        {
-                            mem->ptr = (char *)ptr + HLOCAL_STORAGE;
-                            ret = handle;
-                        }
-                    }
-                    else
-                    {
-                        if ((ptr = HeapAlloc( GetProcessHeap(), heap_flags, size + HLOCAL_STORAGE )))
-                        {
-                            *(HLOCAL *)ptr = handle;
-                            mem->ptr = (char *)ptr + HLOCAL_STORAGE;
-                            ret = handle;
-                        }
-                    }
+                    mem->flags &= ~MEM_FLAG_DISCARDED;
+                    mem->ptr = (char *)ptr + HLOCAL_STORAGE;
+                    ret = handle;
                 }
-                else SetLastError( ERROR_OUTOFMEMORY );
             }
             else
             {
-                if (mem->lock == 0)
-                {
-                    if (mem->ptr)
-                    {
-                        HeapFree( GetProcessHeap(), 0, (char *)mem->ptr - HLOCAL_STORAGE );
-                        mem->ptr = NULL;
-                    }
-                    ret = handle;
-                }
-                else WARN_(globalmem)( "not freeing memory associated with locked handle\n" );
+                if (mem->ptr) HeapFree( heap, heap_flags, (char *)mem->ptr - HLOCAL_STORAGE );
+                mem->flags |= MEM_FLAG_DISCARDED;
+                mem->lock = 0;
+                mem->ptr = NULL;
+                ret = handle;
             }
         }
-        else SetLastError( ERROR_INVALID_HANDLE );
+        else if (flags & LMEM_DISCARDABLE)
+        {
+            mem->flags |= MEM_FLAG_DISCARDABLE;
+            ret = handle;
+        }
+        else SetLastError( ERROR_INVALID_PARAMETER );
     }
-    RtlUnlockHeap( GetProcessHeap() );
+    else SetLastError( ERROR_INVALID_HANDLE );
+    RtlUnlockHeap( heap );
+
     return ret;
 }
 
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/178



More information about the wine-devel mailing list