[PATCH 2/2] ntdll: allow HeapSize to work with global GMEM_MOVEABLE pointers
Damjan Jovanovic
damjan.jov at gmail.com
Sat Oct 26 01:39:44 CDT 2019
This patch attempts to address the problem by patching RtlSizeHeap()
to subtract 8 (8 being HGLOBAL_STORAGE) from the pointer if it doesn't
seem like a valid pointer, to cater to GMEM_MOVEABLE pointers actually
starting 8 bytes earlier.
I am not familiar with the internals of Windows' memory management so
this might not be the best solution, but all the heap tests pass so it
can't be that wrong either ;). It certainly gets wxWidgets
applications working.
Signed-off-by: Damjan Jovanovic <damjan.jov at gmail.com>
---
dlls/kernel32/tests/heap.c | 2 +-
dlls/ntdll/heap.c | 50 ++++++++++++++++++++++++--------------
2 files changed, 33 insertions(+), 19 deletions(-)
-------------- next part --------------
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index eff3242498..c26e12fd92 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -343,7 +343,7 @@ static void test_heap(void)
mem = GlobalLock(gbl);
ok(mem != NULL, "returned error %d\n", GetLastError());
size = HeapSize(GetProcessHeap(), 0, mem);
- todo_wine ok(size != (SIZE_T)-1 && size >= 100, "HeapSize returned %lu\n", size);
+ ok(size != (SIZE_T)-1 && size >= 100, "HeapSize returned %lu\n", size);
GlobalFree(gbl);
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index e8ac1ffa7a..5707ae37f0 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -2004,24 +2004,7 @@ BOOLEAN WINAPI RtlUnlockHeap( HANDLE heap )
}
-/***********************************************************************
- * RtlSizeHeap (NTDLL.@)
- *
- * Get the actual size of a memory block allocated from a Heap.
- *
- * PARAMS
- * heap [I] Heap that block was allocated from
- * flags [I] HEAP_ flags from "winnt.h"
- * ptr [I] Block to get the size of
- *
- * RETURNS
- * Success: The size of the block.
- * Failure: -1, heap or ptr are invalid.
- *
- * NOTES
- * The size may be bigger than what was passed to RtlAllocateHeap().
- */
-SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
+SIZE_T rtl_size_heap_0( HANDLE heap, ULONG flags, const void *ptr, BOOL retry )
{
SIZE_T ret;
const ARENA_INUSE *pArena;
@@ -2040,6 +2023,14 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
pArena = (const ARENA_INUSE *)ptr - 1;
if (!validate_block_pointer( heapPtr, &subheap, pArena ))
{
+ if (retry && validate_block_pointer( heapPtr, &subheap, (const ARENA_INUSE *) (((BYTE*)ptr) - 8) - 1))
+ {
+ /* It came from GlobalAlloc() with GMEM_MOVEABLE */
+ SIZE_T originalSize = rtl_size_heap_0(heap, flags, ((BYTE*)ptr) - 8, FALSE);
+ if (originalSize != ~0UL)
+ return originalSize - 8;
+ return originalSize;
+ }
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
ret = ~0UL;
}
@@ -2059,6 +2050,29 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
}
+/***********************************************************************
+ * RtlSizeHeap (NTDLL.@)
+ *
+ * Get the actual size of a memory block allocated from a Heap.
+ *
+ * PARAMS
+ * heap [I] Heap that block was allocated from
+ * flags [I] HEAP_ flags from "winnt.h"
+ * ptr [I] Block to get the size of
+ *
+ * RETURNS
+ * Success: The size of the block.
+ * Failure: -1, heap or ptr are invalid.
+ *
+ * NOTES
+ * The size may be bigger than what was passed to RtlAllocateHeap().
+ */
+SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
+{
+ return rtl_size_heap_0(heap, flags, ptr, TRUE);
+}
+
+
/***********************************************************************
* RtlValidateHeap (NTDLL.@)
*
More information about the wine-devel
mailing list