Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2022
- 68 participants
- 3274 messages
[PATCH 6/6] kernelbase: Cleanup and simplify LocalReAlloc.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)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
June 3, 2022
[PATCH 5/6] kernelbase: Use HEAP_ADD_USER_INFO for HLOCAL allocations.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/kernelbase/memory.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index cac456d01be..625ff56fdef 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -685,6 +685,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH HeapWalk( HANDLE heap, PROCESS_HEAP_ENTRY *entry )
* Global/local heap functions
***********************************************************************/
+/* some undocumented flags (names are made up) */
+#define HEAP_ADD_USER_INFO 0x00000100
+
/* not compatible with windows */
struct kernelbase_global_data
{
@@ -798,15 +801,15 @@ HGLOBAL WINAPI DECLSPEC_HOTPATCH GlobalFree( HLOCAL handle )
*/
HLOCAL WINAPI DECLSPEC_HOTPATCH LocalAlloc( UINT flags, SIZE_T size )
{
+ DWORD heap_flags = HEAP_ADD_USER_INFO;
HANDLE heap = GetProcessHeap();
struct mem_entry *mem;
- DWORD heap_flags = 0;
HLOCAL handle;
void *ptr;
TRACE_(globalmem)( "flags %#x, size %#Ix\n", flags, size );
- if (flags & LMEM_ZEROINIT) heap_flags = HEAP_ZERO_MEMORY;
+ if (flags & LMEM_ZEROINIT) heap_flags |= HEAP_ZERO_MEMORY;
if (!(flags & LMEM_MOVEABLE)) /* pointer */
{
@@ -936,13 +939,15 @@ 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;
struct mem_entry *mem;
HLOCAL ret = 0;
- DWORD heap_flags = (flags & LMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0;
void *ptr;
TRACE_(globalmem)( "handle %p, size %#Ix, flags %#x\n", handle, size, flags );
+ if (flags & LMEM_ZEROINIT) heap_flags |= HEAP_ZERO_MEMORY;
+
RtlLockHeap( GetProcessHeap() );
if (flags & LMEM_MODIFY) /* modify flags */
{
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
June 3, 2022
[PATCH 4/6] ntdll: Add block padding when HEAP_ADD_USER_INFO flag is set.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/kernel32/tests/heap.c | 3 +--
dlls/ntdll/heap.c | 5 +++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 99602bd2969..057342de9e9 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -2274,14 +2274,13 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
expect_size = max( alloc_size, 2 * sizeof(void *) );
expect_size = ALIGN_BLOCK_SIZE( expect_size + extra_size + 2 * sizeof(void *) );
diff = min( llabs( ptr2 - ptr1 ), llabs( ptr1 - ptr0 ) );
- todo_wine
ok( diff == expect_size, "got diff %#Ix\n", diff );
ok( !memcmp( ptr0 + alloc_size, tail_buf, tail_size ), "missing block tail\n" );
ok( !memcmp( ptr1 + alloc_size, tail_buf, tail_size ), "missing block tail\n" );
ok( !memcmp( ptr2 + alloc_size, tail_buf, tail_size ), "missing block tail\n" );
- todo_wine
+ todo_wine_if( global_flags & FLG_HEAP_ENABLE_FREE_CHECK )
ok( !memcmp( ptr0 + alloc_size + tail_size, padd_buf, 2 * sizeof(void *) ), "unexpected padding\n" );
tmp_ptr = (void *)0xdeadbeef;
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index afbf8703da0..ce2d2b920b5 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -214,6 +214,7 @@ C_ASSERT( offsetof(struct heap, subheap) <= COMMIT_MASK );
/* some undocumented flags (names are made up) */
#define HEAP_PRIVATE 0x00001000
+#define HEAP_ADD_USER_INFO 0x00000100
#define HEAP_PAGE_ALLOCS 0x01000000
#define HEAP_VALIDATE 0x10000000
#define HEAP_VALIDATE_ALL 0x20000000
@@ -457,7 +458,7 @@ static RTL_CRITICAL_SECTION_DEBUG process_heap_cs_debug =
static inline ULONG heap_get_flags( const struct heap *heap, ULONG flags )
{
if (flags & (HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED)) flags |= HEAP_CHECKING_ENABLED;
- flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY | HEAP_CHECKING_ENABLED;
+ flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY | HEAP_CHECKING_ENABLED | HEAP_ADD_USER_INFO;
return heap->flags | flags;
}
@@ -1485,7 +1486,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
static SIZE_T heap_get_block_size( struct heap *heap, ULONG flags, SIZE_T size )
{
- static const ULONG padd_flags = HEAP_VALIDATE | HEAP_VALIDATE_ALL | HEAP_VALIDATE_PARAMS;
+ static const ULONG padd_flags = HEAP_VALIDATE | HEAP_VALIDATE_ALL | HEAP_VALIDATE_PARAMS | HEAP_ADD_USER_INFO;
static const ULONG check_flags = HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_CHECKING_ENABLED;
SIZE_T overhead;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
June 3, 2022
[PATCH 3/6] ntdll: Rename HEAP to struct heap and remove typedef.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/ntdll/heap.c | 115 ++++++++++++++++++++++------------------------
1 file changed, 56 insertions(+), 59 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 3ac819a37ac..afbf8703da0 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -162,15 +162,13 @@ static const SIZE_T free_list_sizes[] =
};
#define HEAP_NB_FREE_LISTS (ARRAY_SIZE(free_list_sizes) + HEAP_NB_SMALL_FREE_LISTS)
-struct tagHEAP;
-
typedef struct DECLSPEC_ALIGN(ALIGNMENT) tagSUBHEAP
{
SIZE_T __pad[sizeof(SIZE_T) / sizeof(DWORD)];
SIZE_T size; /* Size of the whole sub-heap */
SIZE_T commitSize; /* Committed size of the sub-heap */
struct list entry; /* Entry in sub-heap list */
- struct tagHEAP *heap; /* Main heap structure */
+ struct heap *heap; /* Main heap structure */
struct block block;
} SUBHEAP;
@@ -178,7 +176,7 @@ typedef struct DECLSPEC_ALIGN(ALIGNMENT) tagSUBHEAP
C_ASSERT( sizeof(SUBHEAP) == offsetof(SUBHEAP, block) + sizeof(struct block) );
C_ASSERT( sizeof(SUBHEAP) == 4 * ALIGNMENT );
-typedef struct tagHEAP
+struct heap
{ /* win32/win64 */
DWORD_PTR unknown1[2]; /* 0000/0000 */
DWORD ffeeffee; /* 0008/0010 */
@@ -202,12 +200,12 @@ typedef struct tagHEAP
RTL_CRITICAL_SECTION cs;
struct entry free_lists[HEAP_NB_FREE_LISTS];
SUBHEAP subheap;
-} HEAP;
+};
/* subheap must be last and aligned */
-C_ASSERT( sizeof(HEAP) == offsetof(HEAP, subheap) + sizeof(SUBHEAP) );
-C_ASSERT( sizeof(HEAP) % ALIGNMENT == 0 );
-C_ASSERT( offsetof(HEAP, subheap) <= COMMIT_MASK );
+C_ASSERT( sizeof(struct heap) == offsetof(struct heap, subheap) + sizeof(SUBHEAP) );
+C_ASSERT( sizeof(struct heap) % ALIGNMENT == 0 );
+C_ASSERT( offsetof(struct heap, subheap) <= COMMIT_MASK );
#define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
@@ -222,7 +220,7 @@ C_ASSERT( offsetof(HEAP, subheap) <= COMMIT_MASK );
#define HEAP_VALIDATE_PARAMS 0x40000000
#define HEAP_CHECKING_ENABLED 0x80000000
-static HEAP *processHeap; /* main process heap */
+static struct heap *processHeap; /* main process heap */
/* check if memory range a contains memory range b */
static inline BOOL contains( const void *a, SIZE_T a_size, const void *b, SIZE_T b_size )
@@ -312,7 +310,7 @@ static inline BOOL check_subheap( const SUBHEAP *subheap )
return contains( base, subheap->size, &subheap->block, base + subheap->commitSize - (char *)&subheap->block );
}
-static BOOL heap_validate( const HEAP *heap );
+static BOOL heap_validate( const struct heap *heap );
/* mark a block of memory as innacessible for debugging purposes */
static inline void valgrind_make_noaccess( void const *ptr, SIZE_T size )
@@ -428,7 +426,7 @@ static void valgrind_notify_free_all( SUBHEAP *subheap )
/* locate a free list entry of the appropriate size */
/* size is the size of the whole block including the arena header */
-static inline struct entry *find_free_list( HEAP *heap, SIZE_T block_size, BOOL last )
+static inline struct entry *find_free_list( struct heap *heap, SIZE_T block_size, BOOL last )
{
struct entry *list, *end = heap->free_lists + ARRAY_SIZE(heap->free_lists);
unsigned int i;
@@ -456,32 +454,32 @@ static RTL_CRITICAL_SECTION_DEBUG process_heap_cs_debug =
0, 0, { (DWORD_PTR)(__FILE__ ": main process heap section") }
};
-static inline ULONG heap_get_flags( const HEAP *heap, ULONG flags )
+static inline ULONG heap_get_flags( const struct heap *heap, ULONG flags )
{
if (flags & (HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED)) flags |= HEAP_CHECKING_ENABLED;
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY | HEAP_CHECKING_ENABLED;
return heap->flags | flags;
}
-static void heap_lock( HEAP *heap, ULONG flags )
+static void heap_lock( struct heap *heap, ULONG flags )
{
if (heap_get_flags( heap, flags ) & HEAP_NO_SERIALIZE) return;
RtlEnterCriticalSection( &heap->cs );
}
-static void heap_unlock( HEAP *heap, ULONG flags )
+static void heap_unlock( struct heap *heap, ULONG flags )
{
if (heap_get_flags( heap, flags ) & HEAP_NO_SERIALIZE) return;
RtlLeaveCriticalSection( &heap->cs );
}
-static void heap_set_status( const HEAP *heap, ULONG flags, NTSTATUS status )
+static void heap_set_status( const struct heap *heap, ULONG flags, NTSTATUS status )
{
if (status == STATUS_NO_MEMORY && (flags & HEAP_GENERATE_EXCEPTIONS)) RtlRaiseStatus( status );
if (status) RtlSetLastWin32ErrorAndNtStatusFromNtStatus( status );
}
-static void heap_dump( const HEAP *heap )
+static void heap_dump( const struct heap *heap )
{
const struct block *block;
const ARENA_LARGE *large;
@@ -490,7 +488,7 @@ static void heap_dump( const HEAP *heap )
SIZE_T size;
TRACE( "heap: %p\n", heap );
- TRACE( " next %p\n", LIST_ENTRY( heap->entry.next, HEAP, entry ) );
+ TRACE( " next %p\n", LIST_ENTRY( heap->entry.next, struct heap, entry ) );
TRACE( " free_lists: %p\n", heap->free_lists );
for (i = 0; i < HEAP_NB_FREE_LISTS; i++)
@@ -582,10 +580,9 @@ static const char *debugstr_heap_entry( struct rtl_heap_entry *entry )
* Pointer to the heap
* NULL: Failure
*/
-static HEAP *HEAP_GetPtr(
- HANDLE heap /* [in] Handle to the heap */
-) {
- HEAP *heapPtr = heap;
+static struct heap *HEAP_GetPtr( HANDLE heap )
+{
+ struct heap *heapPtr = heap;
BOOL valid = TRUE;
if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
@@ -610,7 +607,7 @@ static HEAP *HEAP_GetPtr(
}
-static SUBHEAP *find_subheap( const HEAP *heap, const struct block *block, BOOL heap_walk )
+static SUBHEAP *find_subheap( const struct heap *heap, const struct block *block, BOOL heap_walk )
{
SUBHEAP *subheap;
@@ -630,7 +627,7 @@ static SUBHEAP *find_subheap( const HEAP *heap, const struct block *block, BOOL
static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T block_size )
{
const char *end = (char *)subheap_base( subheap ) + subheap_size( subheap ), *commit_end;
- HEAP *heap = subheap->heap;
+ struct heap *heap = subheap->heap;
ULONG flags = heap->flags;
SIZE_T size;
void *addr;
@@ -658,7 +655,7 @@ static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block,
static inline BOOL subheap_decommit( SUBHEAP *subheap, const void *commit_end )
{
char *base = subheap_base( subheap );
- HEAP *heap = subheap->heap;
+ struct heap *heap = subheap->heap;
SIZE_T size;
void *addr;
@@ -684,7 +681,7 @@ static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T blo
{
const char *end = (char *)block + block_size, *commit_end = subheap_commit_end( subheap );
struct entry *entry = (struct entry *)block, *list;
- HEAP *heap = subheap->heap;
+ struct heap *heap = subheap->heap;
DWORD flags = heap->flags;
struct block *next;
@@ -723,7 +720,7 @@ static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T blo
static void free_used_block( SUBHEAP *subheap, struct block *block )
{
- HEAP *heap = subheap->heap;
+ struct heap *heap = subheap->heap;
struct entry *entry;
SIZE_T block_size;
@@ -791,7 +788,7 @@ static inline void shrink_used_block( SUBHEAP *subheap, struct block *block, UIN
/***********************************************************************
* allocate_large_block
*/
-static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
+static void *allocate_large_block( struct heap *heap, DWORD flags, SIZE_T size )
{
ARENA_LARGE *arena;
SIZE_T block_size = ROUND_SIZE( sizeof(*arena) + size, COMMIT_MASK );
@@ -820,7 +817,7 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
/***********************************************************************
* free_large_block
*/
-static void free_large_block( HEAP *heap, void *ptr )
+static void free_large_block( struct heap *heap, void *ptr )
{
ARENA_LARGE *arena = (ARENA_LARGE *)ptr - 1;
LPVOID address = arena;
@@ -834,7 +831,7 @@ static void free_large_block( HEAP *heap, void *ptr )
/***********************************************************************
* realloc_large_block
*/
-static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T size )
+static void *realloc_large_block( struct heap *heap, DWORD flags, void *ptr, SIZE_T size )
{
ARENA_LARGE *arena = (ARENA_LARGE *)ptr - 1;
SIZE_T old_size = arena->data_size;
@@ -867,7 +864,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz
/***********************************************************************
* find_large_block
*/
-static ARENA_LARGE *find_large_block( const HEAP *heap, const void *ptr )
+static ARENA_LARGE *find_large_block( const struct heap *heap, const void *ptr )
{
ARENA_LARGE *arena;
@@ -877,7 +874,7 @@ static ARENA_LARGE *find_large_block( const HEAP *heap, const void *ptr )
return NULL;
}
-static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena )
+static BOOL validate_large_arena( const struct heap *heap, const ARENA_LARGE *arena )
{
const char *err = NULL;
@@ -904,7 +901,7 @@ static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena )
/***********************************************************************
* HEAP_CreateSubHeap
*/
-static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
+static SUBHEAP *HEAP_CreateSubHeap( struct heap *heap, LPVOID address, DWORD flags,
SIZE_T commitSize, SIZE_T totalSize )
{
struct entry *pEntry;
@@ -1016,7 +1013,7 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
}
-static struct block *find_free_block( HEAP *heap, SIZE_T block_size, SUBHEAP **subheap )
+static struct block *find_free_block( struct heap *heap, SIZE_T block_size, SUBHEAP **subheap )
{
struct list *ptr = &find_free_list( heap, block_size, FALSE )->entry;
struct entry *entry;
@@ -1072,7 +1069,7 @@ static struct block *find_free_block( HEAP *heap, SIZE_T block_size, SUBHEAP **s
}
-static BOOL is_valid_free_block( const HEAP *heap, const struct block *block )
+static BOOL is_valid_free_block( const struct heap *heap, const struct block *block )
{
const SUBHEAP *subheap;
unsigned int i;
@@ -1086,8 +1083,8 @@ static BOOL validate_free_block( const SUBHEAP *subheap, const struct block *blo
{
const char *err = NULL, *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap );
const struct entry *entry = (struct entry *)block;
+ struct heap *heap = subheap->heap;
const struct block *prev, *next;
- HEAP *heap = subheap->heap;
DWORD flags = heap->flags;
if ((ULONG_PTR)(block + 1) % ALIGNMENT)
@@ -1139,7 +1136,7 @@ static BOOL validate_free_block( const SUBHEAP *subheap, const struct block *blo
static BOOL validate_used_block( const SUBHEAP *subheap, const struct block *block )
{
const char *err = NULL, *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap );
- const HEAP *heap = subheap->heap;
+ const struct heap *heap = subheap->heap;
DWORD flags = heap->flags;
const struct block *next;
int i;
@@ -1192,7 +1189,7 @@ static BOOL validate_used_block( const SUBHEAP *subheap, const struct block *blo
}
-static BOOL heap_validate_ptr( const HEAP *heap, const void *ptr, SUBHEAP **subheap )
+static BOOL heap_validate_ptr( const struct heap *heap, const void *ptr, SUBHEAP **subheap )
{
const struct block *arena = (struct block *)ptr - 1;
const ARENA_LARGE *large_arena;
@@ -1211,7 +1208,7 @@ static BOOL heap_validate_ptr( const HEAP *heap, const void *ptr, SUBHEAP **subh
return validate_used_block( *subheap, arena );
}
-static BOOL heap_validate( const HEAP *heap )
+static BOOL heap_validate( const struct heap *heap )
{
const ARENA_LARGE *large_arena;
const struct block *block;
@@ -1245,7 +1242,7 @@ static BOOL heap_validate( const HEAP *heap )
return TRUE;
}
-static inline struct block *unsafe_block_from_ptr( const HEAP *heap, const void *ptr, SUBHEAP **subheap )
+static inline struct block *unsafe_block_from_ptr( const struct heap *heap, const void *ptr, SUBHEAP **subheap )
{
struct block *block = (struct block *)ptr - 1;
const char *err = NULL, *base, *commit_end;
@@ -1305,7 +1302,7 @@ static DWORD heap_flags_from_global_flag( DWORD flag )
*/
static void heap_set_debug_flags( HANDLE handle )
{
- HEAP *heap = HEAP_GetPtr( handle );
+ struct heap *heap = HEAP_GetPtr( handle );
ULONG global_flags = RtlGetNtGlobalFlags();
DWORD flags, force_flags;
@@ -1382,8 +1379,8 @@ static void heap_set_debug_flags( HANDLE handle )
HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T commitSize,
PVOID unknown, PRTL_HEAP_DEFINITION definition )
{
+ struct heap *heap;
SUBHEAP *subheap;
- HEAP *heap;
/* Allocate the heap block */
@@ -1428,7 +1425,7 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c
*/
HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
{
- HEAP *heapPtr = HEAP_GetPtr( heap );
+ struct heap *heapPtr = HEAP_GetPtr( heap );
SUBHEAP *subheap, *next;
ARENA_LARGE *arena, *arena_next;
struct block **pending, **tmp;
@@ -1436,7 +1433,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
void *addr;
TRACE("%p\n", heap );
- if (!heapPtr && heap && (((HEAP *)heap)->flags & HEAP_VALIDATE_PARAMS) &&
+ if (!heapPtr && heap && (((struct heap *)heap)->flags & HEAP_VALIDATE_PARAMS) &&
NtCurrentTeb()->Peb->BeingDebugged)
{
DbgPrint( "Attempt to destroy an invalid heap\n" );
@@ -1486,7 +1483,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
return 0;
}
-static SIZE_T heap_get_block_size( HEAP *heap, ULONG flags, SIZE_T size )
+static SIZE_T heap_get_block_size( struct heap *heap, ULONG flags, SIZE_T size )
{
static const ULONG padd_flags = HEAP_VALIDATE | HEAP_VALIDATE_ALL | HEAP_VALIDATE_PARAMS;
static const ULONG check_flags = HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_CHECKING_ENABLED;
@@ -1502,7 +1499,7 @@ static SIZE_T heap_get_block_size( HEAP *heap, ULONG flags, SIZE_T size )
return ROUND_SIZE( size + overhead, ALIGNMENT - 1 );
}
-static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret )
+static NTSTATUS heap_allocate( struct heap *heap, ULONG flags, SIZE_T size, void **ret )
{
SIZE_T old_block_size, block_size;
struct block *block;
@@ -1538,9 +1535,9 @@ static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret
*/
void *WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
{
+ struct heap *heapPtr;
void *ptr = NULL;
NTSTATUS status;
- HEAP *heapPtr;
if (!(heapPtr = HEAP_GetPtr( heap )))
status = STATUS_INVALID_HANDLE;
@@ -1559,7 +1556,7 @@ void *WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T
}
-static NTSTATUS heap_free( HEAP *heap, void *ptr )
+static NTSTATUS heap_free( struct heap *heap, void *ptr )
{
struct block *block;
SUBHEAP *subheap;
@@ -1576,8 +1573,8 @@ static NTSTATUS heap_free( HEAP *heap, void *ptr )
*/
BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *ptr )
{
+ struct heap *heapPtr;
NTSTATUS status;
- HEAP *heapPtr;
if (!ptr) return TRUE;
@@ -1598,7 +1595,7 @@ BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *pt
}
-static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size, void **ret )
+static NTSTATUS heap_reallocate( struct heap *heap, ULONG flags, void *ptr, SIZE_T size, void **ret )
{
SIZE_T old_block_size, old_size, block_size;
struct block *next, *block;
@@ -1661,9 +1658,9 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
*/
void *WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, void *ptr, SIZE_T size )
{
+ struct heap *heapPtr;
void *ret = NULL;
NTSTATUS status;
- HEAP *heapPtr;
if (!ptr) return NULL;
@@ -1719,7 +1716,7 @@ ULONG WINAPI RtlCompactHeap( HANDLE heap, ULONG flags )
*/
BOOLEAN WINAPI RtlLockHeap( HANDLE heap )
{
- HEAP *heapPtr = HEAP_GetPtr( heap );
+ struct heap *heapPtr = HEAP_GetPtr( heap );
if (!heapPtr) return FALSE;
heap_lock( heapPtr, 0 );
return TRUE;
@@ -1740,14 +1737,14 @@ BOOLEAN WINAPI RtlLockHeap( HANDLE heap )
*/
BOOLEAN WINAPI RtlUnlockHeap( HANDLE heap )
{
- HEAP *heapPtr = HEAP_GetPtr( heap );
+ struct heap *heapPtr = HEAP_GetPtr( heap );
if (!heapPtr) return FALSE;
heap_unlock( heapPtr, 0 );
return TRUE;
}
-static NTSTATUS heap_size( HEAP *heap, const void *ptr, SIZE_T *size )
+static NTSTATUS heap_size( struct heap *heap, const void *ptr, SIZE_T *size )
{
const struct block *block;
SUBHEAP *subheap;
@@ -1769,8 +1766,8 @@ static NTSTATUS heap_size( HEAP *heap, const void *ptr, SIZE_T *size )
SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
{
SIZE_T size = ~(SIZE_T)0;
+ struct heap *heapPtr;
NTSTATUS status;
- HEAP *heapPtr;
if (!(heapPtr = HEAP_GetPtr( heap )))
status = STATUS_INVALID_PARAMETER;
@@ -1792,8 +1789,8 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
*/
BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, const void *ptr )
{
+ struct heap *heapPtr;
SUBHEAP *subheap;
- HEAP *heapPtr;
BOOLEAN ret;
if (!(heapPtr = HEAP_GetPtr( heap )))
@@ -1811,7 +1808,7 @@ BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, const void *ptr )
}
-static NTSTATUS heap_walk_blocks( const HEAP *heap, const SUBHEAP *subheap, struct rtl_heap_entry *entry )
+static NTSTATUS heap_walk_blocks( const struct heap *heap, const SUBHEAP *subheap, struct rtl_heap_entry *entry )
{
const char *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap ), *end = base + subheap_size( subheap );
const struct block *block, *blocks = first_block( subheap );
@@ -1856,7 +1853,7 @@ static NTSTATUS heap_walk_blocks( const HEAP *heap, const SUBHEAP *subheap, stru
return STATUS_SUCCESS;
}
-static NTSTATUS heap_walk( const HEAP *heap, struct rtl_heap_entry *entry )
+static NTSTATUS heap_walk( const struct heap *heap, struct rtl_heap_entry *entry )
{
const ARENA_LARGE *large;
const struct list *next;
@@ -1915,8 +1912,8 @@ static NTSTATUS heap_walk( const HEAP *heap, struct rtl_heap_entry *entry )
NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, void *entry_ptr )
{
struct rtl_heap_entry *entry = entry_ptr;
+ struct heap *heapPtr;
NTSTATUS status;
- HEAP *heapPtr;
if (!entry) return STATUS_INVALID_PARAMETER;
@@ -1959,7 +1956,7 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
{
*heaps++ = processHeap;
LIST_FOR_EACH( ptr, &processHeap->entry )
- *heaps++ = LIST_ENTRY( ptr, HEAP, entry );
+ *heaps++ = LIST_ENTRY( ptr, struct heap, entry );
}
RtlLeaveCriticalSection( &processHeap->cs );
return total;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
June 3, 2022
[PATCH 2/6] ntdll: Pass a block pointer to initialize_block.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/ntdll/heap.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 3184ae43dab..3ac819a37ac 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -368,17 +368,21 @@ static inline void mark_block_tail( struct block *block, DWORD flags )
}
/* initialize contents of a newly created block of memory */
-static inline void initialize_block( void *ptr, SIZE_T size, DWORD flags )
+static inline void initialize_block( struct block *block, SIZE_T old_size, SIZE_T size, DWORD flags )
{
+ char *data = (char *)(block + 1);
+
+ if (size <= old_size) return;
+
if (flags & HEAP_ZERO_MEMORY)
{
- valgrind_make_writable( ptr, size );
- memset( ptr, 0, size );
+ valgrind_make_writable( data + old_size, size - old_size );
+ memset( data + old_size, 0, size - old_size );
}
else if (flags & HEAP_FREE_CHECKING_ENABLED)
{
- valgrind_make_writable( ptr, size );
- memset( ptr, ARENA_INUSE_FILLER, size );
+ valgrind_make_writable( data + old_size, size - old_size );
+ memset( data + old_size, ARENA_INUSE_FILLER, size - old_size );
}
}
@@ -840,7 +844,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz
{
/* FIXME: we could remap zero-pages instead */
valgrind_notify_resize( arena + 1, old_size, size );
- if (size > old_size) initialize_block( (char *)ptr + old_size, size - old_size, flags );
+ initialize_block( &arena->block, old_size, size, flags );
arena->data_size = size;
valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size,
arena->block_size - sizeof(*arena) - arena->data_size );
@@ -1522,7 +1526,7 @@ static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret
block_set_type( block, ARENA_INUSE_MAGIC );
shrink_used_block( subheap, block, 0, old_block_size, block_size, size );
- initialize_block( block + 1, size, flags );
+ initialize_block( block, 0, size, flags );
mark_block_tail( block, flags );
*ret = block + 1;
@@ -1643,7 +1647,7 @@ static NTSTATUS heap_reallocate( HEAP *heap, ULONG flags, void *ptr, SIZE_T size
valgrind_notify_resize( block + 1, old_size, size );
shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size );
- if (size > old_size) initialize_block( (char *)(block + 1) + old_size, size - old_size, flags );
+ initialize_block( block, old_size, size, flags );
mark_block_tail( block, flags );
/* Return the new arena */
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
June 3, 2022
[PATCH 1/6] ntdll: Use a block member in large blocks.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/kernel32/tests/heap.c | 3 ---
dlls/ntdll/heap.c | 26 +++++++++++++++++---------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 91f582f36de..99602bd2969 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -354,9 +354,7 @@ static void test_HeapCreate(void)
ok( !!ptrs[i], "HeapAlloc failed, error %lu\n", GetLastError() );
align |= (UINT_PTR)ptrs[i];
}
- todo_wine_if( sizeof(void *) == 8 )
ok( !(align & (8 * sizeof(void *) - 1)), "got wrong alignment\n" );
- todo_wine_if( sizeof(void *) == 8 )
ok( align & (8 * sizeof(void *)), "got wrong alignment\n" );
for (i = 0; i < ARRAY_SIZE(ptrs); ++i)
{
@@ -2228,7 +2226,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
ok( !!ptr2, "HeapAlloc failed, error %lu\n", GetLastError() );
align = (UINT_PTR)ptr0 | (UINT_PTR)ptr1 | (UINT_PTR)ptr2;
- todo_wine_if( sizeof(void *) == 8 || alloc_size == 0x7efe9 )
ok( !(align & (8 * sizeof(void *) - 1)), "wrong align\n" );
expect_size = max( alloc_size, 2 * sizeof(void *) );
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 0ecff6f6cba..3184ae43dab 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -91,6 +91,7 @@ C_ASSERT( sizeof(struct block) == 8 );
#define BLOCK_FLAG_FREE 0x00000001
#define BLOCK_FLAG_PREV_FREE 0x00000002
#define BLOCK_FLAG_FREE_LINK 0x00000003
+#define BLOCK_FLAG_LARGE 0x00000004
/* entry to link free blocks in free lists */
@@ -103,18 +104,21 @@ struct DECLSPEC_ALIGN(ALIGNMENT) entry
C_ASSERT( sizeof(struct entry) == 2 * ALIGNMENT );
-typedef struct
+typedef struct region
{
+ SIZE_T __pad[sizeof(SIZE_T) / sizeof(DWORD)];
struct list entry; /* entry in heap large blocks list */
SIZE_T data_size; /* size of user data */
SIZE_T block_size; /* total size of virtual memory block */
- DWORD pad[2]; /* padding to ensure 16-byte alignment of data */
- DWORD size; /* fields for compatibility with normal arenas */
- DWORD magic; /* these must remain at the end of the structure */
+ SIZE_T pad; /* padding to ensure 16-byte alignment of data */
+ struct block block;
} ARENA_LARGE;
+/* block must be last and aligned */
+C_ASSERT( sizeof(struct region) == offsetof(struct region, block) + sizeof(struct block) );
+C_ASSERT( sizeof(struct region) == 4 * ALIGNMENT );
+
#define ARENA_SIZE_MASK (~3)
-#define ARENA_LARGE_SIZE 0xfedcba90 /* magic value for 'size' field in large blocks */
/* Value for arena 'magic' field */
#define ARENA_INUSE_MAGIC 0x455355
@@ -800,8 +804,8 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
arena = address;
arena->data_size = size;
arena->block_size = block_size;
- arena->size = ARENA_LARGE_SIZE;
- arena->magic = ARENA_LARGE_MAGIC;
+ block_set_type( &arena->block, ARENA_LARGE_MAGIC );
+ block_set_size( &arena->block, BLOCK_FLAG_LARGE, 0 );
list_add_tail( &heap->large_list, &arena->entry );
valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size,
arena->block_size - sizeof(*arena) - arena->data_size );
@@ -875,8 +879,12 @@ static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena )
if ((ULONG_PTR)arena & COMMIT_MASK)
err = "invalid block alignment";
- else if (arena->size != ARENA_LARGE_SIZE || arena->magic != ARENA_LARGE_MAGIC)
- err = "invalid block header";
+ else if (block_get_size( &arena->block ))
+ err = "invalid block size";
+ else if (block_get_flags( &arena->block ) != BLOCK_FLAG_LARGE)
+ err = "invalid block flags";
+ else if (block_get_type( &arena->block ) != ARENA_LARGE_MAGIC)
+ err = "invalid block type";
else if (!contains( arena, arena->block_size, arena + 1, arena->data_size ))
err = "invalid block size";
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
June 3, 2022
[PATCH v2 2/2] dwmapi: Return S_OK from DwmFlush().
by Jactry Zeng
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53035
Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
Superseded patch 236602.
---
dlls/dwmapi/dwmapi_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dwmapi/dwmapi_main.c b/dlls/dwmapi/dwmapi_main.c
index 1fb522e389a..1a65410c7eb 100644
--- a/dlls/dwmapi/dwmapi_main.c
+++ b/dlls/dwmapi/dwmapi_main.c
@@ -92,7 +92,7 @@ HRESULT WINAPI DwmFlush(void)
if (!once++) FIXME("() stub\n");
- return E_NOTIMPL;
+ return S_OK;
}
/**********************************************************************
--
2.35.1
June 3, 2022
[PATCH v2 1/2] dwmapi: Fill rateRefresh/rateCompose and qpcRefreshPeriod of DWM_TIMING_INFO from DwmGetCompositionTimingInfo().
by Jactry Zeng
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53035
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53038
Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
Superseded patch 236601.
---
dlls/dwmapi/Makefile.in | 1 +
dlls/dwmapi/dwmapi_main.c | 27 ++++++++++++++++++++++++++-
dlls/dwmapi/tests/Makefile.in | 2 +-
dlls/dwmapi/tests/dwmapi.c | 22 ++++++++++++++++++++++
4 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/dlls/dwmapi/Makefile.in b/dlls/dwmapi/Makefile.in
index e63dbc2ea00..37411a57608 100644
--- a/dlls/dwmapi/Makefile.in
+++ b/dlls/dwmapi/Makefile.in
@@ -1,4 +1,5 @@
MODULE = dwmapi.dll
+IMPORTS = user32
IMPORTLIB = dwmapi
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/dwmapi/dwmapi_main.c b/dlls/dwmapi/dwmapi_main.c
index 6bb086a87d1..1fb522e389a 100644
--- a/dlls/dwmapi/dwmapi_main.c
+++ b/dlls/dwmapi/dwmapi_main.c
@@ -211,12 +211,28 @@ HRESULT WINAPI DwmRegisterThumbnail(HWND dest, HWND src, PHTHUMBNAIL thumbnail_i
return E_NOTIMPL;
}
+static int get_display_frequency(void)
+{
+ DEVMODEA mode;
+
+ memset(&mode, 0, sizeof(mode));
+ mode.dmSize = sizeof(mode);
+ if (EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode))
+ return mode.dmDisplayFrequency;
+ else
+ {
+ WARN("Failed to query display frequency, returning a fallback value.\n");
+ return 60;
+ }
+}
+
/**********************************************************************
* DwmGetCompositionTimingInfo (DWMAPI.@)
*/
HRESULT WINAPI DwmGetCompositionTimingInfo(HWND hwnd, DWM_TIMING_INFO *info)
{
- static int i;
+ LARGE_INTEGER performance_frequency;
+ static int i, display_frequency;
if (!info)
return E_INVALIDARG;
@@ -229,6 +245,15 @@ HRESULT WINAPI DwmGetCompositionTimingInfo(HWND hwnd, DWM_TIMING_INFO *info)
memset(info, 0, info->cbSize);
info->cbSize = sizeof(DWM_TIMING_INFO);
+ display_frequency = get_display_frequency();
+ info->rateRefresh.uiNumerator = display_frequency;
+ info->rateRefresh.uiDenominator = 1;
+ info->rateCompose.uiNumerator = display_frequency;
+ info->rateCompose.uiDenominator = 1;
+
+ QueryPerformanceFrequency(&performance_frequency);
+ info->qpcRefreshPeriod = performance_frequency.QuadPart / display_frequency;
+
return S_OK;
}
diff --git a/dlls/dwmapi/tests/Makefile.in b/dlls/dwmapi/tests/Makefile.in
index 6c6130401d6..e819e3ca09a 100644
--- a/dlls/dwmapi/tests/Makefile.in
+++ b/dlls/dwmapi/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = dwmapi.dll
-IMPORTS = dwmapi
+IMPORTS = dwmapi user32
C_SRCS = \
dwmapi.c
diff --git a/dlls/dwmapi/tests/dwmapi.c b/dlls/dwmapi/tests/dwmapi.c
index 696aa9c9d86..29dbcbe74bd 100644
--- a/dlls/dwmapi/tests/dwmapi.c
+++ b/dlls/dwmapi/tests/dwmapi.c
@@ -35,7 +35,11 @@ static void test_DwmIsCompositionEnabled(void)
static void test_DwmGetCompositionTimingInfo(void)
{
+ LARGE_INTEGER performance_frequency;
+ int result, display_frequency;
DWM_TIMING_INFO timing_info;
+ QPC_TIME refresh_period;
+ DEVMODEA mode;
BOOL enabled;
HRESULT hr;
@@ -56,9 +60,27 @@ static void test_DwmGetCompositionTimingInfo(void)
hr = DwmGetCompositionTimingInfo(NULL, &timing_info);
ok(hr == MILERR_MISMATCHED_SIZE, "Got hr %#lx.\n", hr);
+ memset(&mode, 0, sizeof(mode));
+ mode.dmSize = sizeof(mode);
+ result = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode);
+ ok(!!result, "Failed to get display mode %#lx.\n", GetLastError());
+ display_frequency = mode.dmDisplayFrequency;
+ ok(!!QueryPerformanceFrequency(&performance_frequency), "Failed to get performance counter frequency.\n");
+ refresh_period = performance_frequency.QuadPart / display_frequency;
+
timing_info.cbSize = sizeof(timing_info);
hr = DwmGetCompositionTimingInfo(NULL, &timing_info);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(timing_info.cbSize == sizeof(timing_info), "Got wrong struct size %d.\n", timing_info.cbSize);
+ ok(timing_info.rateRefresh.uiDenominator == 1 && timing_info.rateRefresh.uiNumerator == display_frequency,
+ "Got wrong monitor refresh rate %d/%d.\n", timing_info.rateRefresh.uiDenominator,
+ timing_info.rateRefresh.uiNumerator);
+ ok(timing_info.rateCompose.uiDenominator == 1 && timing_info.rateCompose.uiNumerator == display_frequency,
+ "Got wrong composition rate %d/%d.\n", timing_info.rateCompose.uiDenominator,
+ timing_info.rateCompose.uiNumerator);
+ ok(timing_info.qpcRefreshPeriod == refresh_period
+ || broken(timing_info.qpcRefreshPeriod == display_frequency), /* win10 v1507 */
+ "Got wrong monitor refresh period %s.\n", wine_dbgstr_longlong(timing_info.qpcRefreshPeriod));
}
START_TEST(dwmapi)
--
2.35.1
June 3, 2022
Re: [PATCH] user32: Perform HID ioctls on the right file handle.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
June 3, 2022