[PATCH v2 4/5] ntdll: Implement RtlSetUserValueHeap.
Rémi Bernon
wine at gitlab.winehq.org
Thu Jun 9 07:16:01 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/kernel32/tests/heap.c | 13 +++----------
dlls/ntdll/heap.c | 36 ++++++++++++++++++++++++++++++++----
2 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 97f4d9c9fe3..4221fd39c0f 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,7 @@ 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 )
+ todo_wine_if( alloc_size == 0x7efe9 )
ok( !(align & (8 * sizeof(void *) - 1)), "wrong align\n" );
expect_size = max( alloc_size, 2 * sizeof(void *) );
@@ -2303,7 +2301,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
ok( tmp_flags == 0x200, "got flags %#lx\n", tmp_flags );
ret = pRtlSetUserValueHeap( heap, 0, ptr0, (void *)0xdeadbeef );
- todo_wine
ok( ret, "RtlSetUserValueHeap failed, error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
ret = pRtlSetUserFlagsHeap( heap, 0, ptr0, 0, 0x1000 );
@@ -2330,13 +2327,9 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
"got flags %#lx\n", tmp_flags );
user_ptr = (void **)(ptr0 + alloc_size + tail_size);
- todo_wine
ok( user_ptr[1] == (void *)0xdeadbeef, "unexpected user value\n" );
- if (user_ptr[1] == (void *)0xdeadbeef)
- {
- user_ptr[0] = (void *)0xdeadbeef;
- user_ptr[1] = (void *)0xdeadbee0;
- }
+ user_ptr[0] = (void *)0xdeadbeef;
+ user_ptr[1] = (void *)0xdeadbee0;
tmp_ptr = NULL;
tmp_flags = 0;
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 6d9f949b6a9..64d4f6644af 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -105,10 +105,11 @@ C_ASSERT( sizeof(struct entry) == 2 * ALIGNMENT );
typedef struct
{
+ 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 */
+ void *user_value;
DWORD size; /* fields for compatibility with normal arenas */
DWORD magic; /* these must remain at the end of the structure */
} ARENA_LARGE;
@@ -362,6 +363,12 @@ static inline void mark_block_tail( struct block *block, DWORD flags )
memset( tail, ARENA_TAIL_FILLER, ALIGNMENT );
}
valgrind_make_noaccess( tail, ALIGNMENT );
+ if (flags & HEAP_ADD_USER_INFO)
+ {
+ if (flags & HEAP_TAIL_CHECKING_ENABLED || RUNNING_ON_VALGRIND) tail += ALIGNMENT;
+ valgrind_make_writable( tail + sizeof(void *), sizeof(void *) );
+ memset( tail + sizeof(void *), 0, sizeof(void *) );
+ }
}
/* initialize contents of a newly created block of memory */
@@ -2001,10 +2008,31 @@ BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE heap, ULONG flags, void *ptr, void **u
/***********************************************************************
* RtlSetUserValueHeap (NTDLL.@)
*/
-BOOLEAN WINAPI RtlSetUserValueHeap( HANDLE heap, ULONG flags, void *ptr, void *user_value )
+BOOLEAN WINAPI RtlSetUserValueHeap( HANDLE handle, ULONG flags, void *ptr, void *user_value )
{
- FIXME( "heap %p, flags %#x, ptr %p, user_value %p stub!\n", heap, flags, ptr, user_value );
- return FALSE;
+ ARENA_LARGE *large = (ARENA_LARGE *)ptr - 1;
+ struct block *block;
+ BOOLEAN ret = TRUE;
+ SUBHEAP *subheap;
+ HEAP *heap;
+ char *tmp;
+
+ TRACE( "handle %p, flags %#x, ptr %p, user_value %p.\n", handle, flags, ptr, user_value );
+
+ if (!(heap = HEAP_GetPtr( handle ))) return TRUE;
+
+ heap_lock( heap, flags );
+ if (!(block = unsafe_block_from_ptr( heap, ptr, &subheap ))) ret = FALSE;
+ else if (!subheap) large->user_value = user_value;
+ else
+ {
+ tmp = (char *)block + block_get_size( block ) - block->tail_size + sizeof(void *);
+ if ((heap_get_flags( heap, flags ) & HEAP_TAIL_CHECKING_ENABLED) || RUNNING_ON_VALGRIND) tmp += ALIGNMENT;
+ *(void **)tmp = user_value;
+ }
+ heap_unlock( heap, flags );
+
+ return ret;
}
/***********************************************************************
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/201
More information about the wine-devel
mailing list