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
Re: [PATCH 0/2] MR219: user32: Avoid use of setupapi in raw input device enumeration. - approved
by Rémi Bernon
This merge request was approved by Rémi Bernon.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/219
June 10, 2022
Re: [PATCH 0/1] MR213: nls: Add some of the missing codepage files. - closed
by Nikolay Sivov (@nsivov)
This merge request was closed by Nikolay Sivov.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/213
June 10, 2022
Re: [PATCH] comctl32: Add partial support for LVM_SETBKIMAGE.
by Dmitry Timoshkov
Zhiyi Zhang <zzhang(a)codeweavers.com> wrote:
Thanks for the review.
> Also, I found LVM_SETBKIMAGE is acting a bit weird on Windows. For example,
> if a LVM_SETBKIMAGE message trying to set a bitmap
> is sent the second time. The second message returns FALSE and the background
> image gets reset to none(from LVM_GETBKIMAGE). I don't know if we should
> implement such a behavior but I would be more comfortable with some tests.
According to my testing LVM_SETBKIMAGE always returns 0. Regarding calling
LVM_SETBKIMAGE again with the same hbitmap I'd guess that the control first
destroys previosuly assigned bitmap, and that leads to a being assigned bitmap
gets destroyed. The conrol then probably verifies bitmap validity before saving
it internally, and that would explain why LVM_GETBKIMAGE returns 0.
--
Dmitry.
June 10, 2022
Re: [PATCH 0/7] MR212: d3d11: Create dxgi resource objects for textures and buffers.
by Henri Verbeet
On Fri, 10 Jun 2022 at 01:38, Zebediah Figura <zfigura(a)codeweavers.com> wrote:
> This patch series looks sensible to me, given the current structure of
> the code, but I'm not familiar with all of the considerations here.
> Henri, do you have any thoughts?
I didn't review this line-by-line, but on a high level this seems fine.
June 10, 2022
[PATCH 6/6] kernelbase: Cleanup and simplify (Global|Local)ReAlloc.
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 | 22 +++++++-
dlls/kernel32/tests/heap.c | 15 ------
dlls/kernelbase/memory.c | 108 +++++++++++++------------------------
3 files changed, 56 insertions(+), 89 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index 3ba9e139171..a2910688e44 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(globalmem);
static HANDLE systemHeap; /* globally shared heap */
BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE handle, ULONG flags, void *ptr, void **user_value, ULONG *user_flags );
+BOOLEAN WINAPI RtlSetUserValueHeap( HANDLE handle, ULONG flags, void *ptr, void *user_value );
/***********************************************************************
* HEAP_CreateSystemHeap
@@ -174,7 +175,7 @@ struct kernelbase_global_data *kernelbase_global_data;
static inline struct mem_entry *unsafe_mem_from_HLOCAL( HLOCAL handle )
{
- struct mem_entry *mem = CONTAINING_RECORD( handle, struct mem_entry, ptr );
+ struct mem_entry *mem = CONTAINING_RECORD( *(volatile HANDLE *)&handle, struct mem_entry, ptr );
struct kernelbase_global_data *data = kernelbase_global_data;
if (((UINT_PTR)handle & ((sizeof(void *) << 1) - 1)) != sizeof(void *)) return NULL;
if (mem < data->mem_entries || mem >= data->mem_entries_end) return NULL;
@@ -253,7 +254,24 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
*/
HGLOBAL WINAPI GlobalReAlloc( HGLOBAL handle, SIZE_T size, UINT flags )
{
- return LocalReAlloc( handle, size, flags );
+ struct mem_entry *mem;
+ void *ptr;
+
+ if ((mem = unsafe_mem_from_HLOCAL( handle )) && mem->lock) return 0;
+ if (!(handle = LocalReAlloc( handle, size, flags ))) return 0;
+
+ /* GlobalReAlloc allows changing GMEM_FIXED to GMEM_MOVEABLE with GMEM_MODIFY */
+ if ((flags & (GMEM_MOVEABLE | GMEM_MODIFY)) == (GMEM_MOVEABLE | GMEM_MODIFY) &&
+ (ptr = unsafe_ptr_from_HLOCAL( handle )))
+ {
+ if (!(handle = LocalAlloc( flags, 0 ))) return 0;
+ RtlSetUserValueHeap( GetProcessHeap(), 0, ptr, handle );
+ mem = unsafe_mem_from_HLOCAL( handle );
+ mem->flags &= ~MEM_FLAG_DISCARDED;
+ mem->ptr = ptr;
+ }
+
+ return handle;
}
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 4496df35579..90c311b5683 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -1629,9 +1629,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 );
@@ -1645,9 +1643,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 );
@@ -2072,18 +2064,15 @@ static void test_LocalAlloc(void)
/* Check that we cannot change LMEM_FIXED to LMEM_MOVEABLE */
mem = LocalReAlloc( mem, 0, LMEM_MODIFY | LMEM_MOVEABLE );
ok( !!mem, "LocalReAlloc failed, error %lu\n", GetLastError() );
- todo_wine
ok( mem == ptr, "LocalReAlloc returned unexpected handle\n" );
size = LocalSize( mem );
ok( size == buffer_size, "LocalSize returned %Iu, error %lu\n", size, GetLastError() );
ptr = LocalLock( mem );
ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() );
- todo_wine
ok( ptr == mem, "got unexpected ptr %p\n", ptr );
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 = LocalReAlloc( mem, 2 * buffer_size, LMEM_MOVEABLE | LMEM_ZEROINIT );
@@ -2096,7 +2085,6 @@ static void test_LocalAlloc(void)
ok( size >= 2 * buffer_size, "LocalSize returned %Iu, error %lu\n", size, GetLastError() );
ptr = LocalLock( mem );
ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() );
- todo_wine
ok( ptr == mem, "got unexpected ptr %p\n", ptr );
ok( !memcmp( ptr, zero_buffer, buffer_size ), "LocalReAlloc didn't clear memory\n" );
ok( !memcmp( ptr + buffer_size, zero_buffer, buffer_size ),
@@ -2105,13 +2093,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 16a068f5b5f..e24a6f9aad0 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -964,7 +964,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;
@@ -973,92 +974,55 @@ 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))
- {
- /* 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 );
- }
- }
- else if ((mem = unsafe_mem_from_HLOCAL( handle )) && (flags & LMEM_DISCARDABLE))
+ if (flags & LMEM_MODIFY) ret = handle;
+ else
{
- /* change the flags to make our block "discardable" */
- mem->flags |= LMEM_DISCARDABLE >> 8;
- ret = handle;
+ if (!(flags & LMEM_MOVEABLE)) heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
+ ret = HeapReAlloc( heap, heap_flags, ptr, size );
+ if (ret) RtlSetUserValueHeap( heap, heap_flags, ret, ret );
+ else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
- else SetLastError( ERROR_INVALID_PARAMETER );
}
- else
+ else if ((mem = unsafe_mem_from_HLOCAL( handle )))
{
- if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
- {
- /* reallocate fixed memory */
- if (!(flags & LMEM_MOVEABLE)) heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
- ret = HeapReAlloc( GetProcessHeap(), heap_flags, ptr, size );
- if (ret) RtlSetUserValueHeap( GetProcessHeap(), heap_flags, ret, ret );
- }
- else if ((mem = unsafe_mem_from_HLOCAL( handle )))
+ if (!(flags & LMEM_MODIFY))
{
- /* reallocate a moveable block */
- if (size != 0)
+ if (size)
{
- if (size <= INT_MAX)
+ if (!mem->ptr) ptr = HeapAlloc( heap, heap_flags, size );
+ else ptr = HeapReAlloc( heap, heap_flags, mem->ptr, size );
+
+ if (!ptr) SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ else
{
- if (mem->ptr)
- {
- if ((ptr = HeapReAlloc( GetProcessHeap(), heap_flags, mem->ptr, size )))
- {
- RtlSetUserValueHeap( GetProcessHeap(), heap_flags, ptr, handle );
- mem->ptr = ptr;
- ret = handle;
- }
- }
- else
- {
- if ((ptr = HeapAlloc( GetProcessHeap(), heap_flags, size )))
- {
- RtlSetUserValueHeap( GetProcessHeap(), heap_flags, ptr, handle );
- *(HLOCAL *)ptr = handle;
- mem->ptr = ptr;
- ret = handle;
- }
- }
+ RtlSetUserValueHeap( heap, heap_flags, ptr, handle );
+ mem->flags &= ~MEM_FLAG_DISCARDED;
+ mem->ptr = ptr;
+ ret = handle;
}
- else SetLastError( ERROR_OUTOFMEMORY );
}
else
{
- if (mem->lock == 0)
- {
- if (mem->ptr)
- {
- HeapFree( GetProcessHeap(), 0, mem->ptr );
- mem->ptr = NULL;
- }
- ret = handle;
- }
- else WARN_(globalmem)( "not freeing memory associated with locked handle\n" );
+ HeapFree( heap, heap_flags, mem->ptr );
+ 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/222
June 10, 2022
[PATCH 5/6] kernel32: Cleanup and simplify (Global|Local)Handle.
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 | 91 ++++++++++----------------------------------
1 file changed, 21 insertions(+), 70 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index 2dac1555d8e..3ba9e139171 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -236,64 +236,10 @@ BOOL WINAPI GlobalUnlock( HGLOBAL handle )
/***********************************************************************
* GlobalHandle (KERNEL32.@)
- *
- * Get the handle associated with the pointer to a global memory block.
- *
- * RETURNS
- * Handle: Success
- * NULL: Failure
*/
HGLOBAL WINAPI GlobalHandle( const void *ptr )
{
- struct mem_entry *mem;
- HGLOBAL handle;
- ULONG flags;
-
- TRACE_(globalmem)( "ptr %p\n", ptr );
-
- if (!ptr)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
-
- RtlLockHeap( GetProcessHeap() );
- __TRY
- {
- handle = 0;
-
- /* note that if ptr is a pointer to a block allocated by */
- /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */
- /* will fail. */
- if ((ptr = unsafe_ptr_from_HLOCAL( (HLOCAL)ptr )))
- {
- if (!RtlGetUserInfoHeap( GetProcessHeap(), HEAP_NO_SERIALIZE, (void *)ptr, &handle, &flags ))
- {
- SetLastError( ERROR_INVALID_HANDLE );
- handle = 0;
- }
- break;
- }
- else handle = (HGLOBAL)ptr;
-
- /* Now test handle either passed in or retrieved from pointer */
- if ((mem = unsafe_mem_from_HLOCAL( handle )))
- {
- if (HeapValidate( GetProcessHeap(), HEAP_NO_SERIALIZE, mem->ptr )) /* obj(-handle) valid arena? */
- break; /* valid moveable block */
- }
- handle = 0;
- SetLastError( ERROR_INVALID_HANDLE );
- }
- __EXCEPT_PAGE_FAULT
- {
- SetLastError( ERROR_INVALID_HANDLE );
- handle = 0;
- }
- __ENDTRY
- RtlUnlockHeap( GetProcessHeap() );
-
- return handle;
+ return LocalHandle( ptr );
}
/***********************************************************************
@@ -438,23 +384,28 @@ UINT WINAPI LocalFlags( HLOCAL handle )
/***********************************************************************
* LocalHandle (KERNEL32.@)
- *
- * Get the handle associated with the pointer to a local memory block.
- *
- * RETURNS
- * Handle: Success
- * NULL: Failure
- *
- * NOTES
- * Windows memory management does not provide a separate local heap
- * and global heap.
*/
-HLOCAL WINAPI LocalHandle(
- LPCVOID ptr /* [in] Address of local memory block */
-) {
- return GlobalHandle( ptr );
-}
+HLOCAL WINAPI LocalHandle( const void *ptr )
+{
+ HLOCAL handle;
+ ULONG flags;
+
+ TRACE_(globalmem)( "ptr %p\n", ptr );
+ if (!ptr)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ if (!RtlGetUserInfoHeap( GetProcessHeap(), 0, (void *)ptr, &handle, &flags ))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return 0;
+ }
+
+ return handle;
+}
/***********************************************************************
* LocalShrink (KERNEL32.@)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/222
June 10, 2022
[PATCH 4/6] kernel32: Cleanup and simplify (Global|Local)Size.
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 | 88 ++++++++++++++------------------------------
1 file changed, 27 insertions(+), 61 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index e414ad03493..2dac1555d8e 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -313,56 +313,10 @@ HGLOBAL WINAPI GlobalReAlloc( HGLOBAL handle, SIZE_T size, UINT flags )
/***********************************************************************
* GlobalSize (KERNEL32.@)
- *
- * Get the size of a global memory object.
- *
- * PARAMS
- * handle [I] Handle of the global memory object
- *
- * RETURNS
- * Failure: 0
- * Success: Size in Bytes of the global memory object
- *
- * NOTES
- * When the handle is invalid, last error is set to ERROR_INVALID_HANDLE
- *
*/
SIZE_T WINAPI GlobalSize( HGLOBAL handle )
{
- struct mem_entry *mem;
- SIZE_T retval;
- void *ptr;
-
- TRACE_(globalmem)( "handle %p\n", handle );
-
- if (!((ULONG_PTR)handle >> 16))
- {
- SetLastError( ERROR_INVALID_HANDLE );
- return 0;
- }
-
- if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
- retval = HeapSize( GetProcessHeap(), 0, ptr );
- else
- {
- RtlLockHeap( GetProcessHeap() );
- if ((mem = unsafe_mem_from_HLOCAL( handle )))
- {
- if (!mem->ptr) /* handle case of GlobalAlloc( ??,0) */
- retval = 0;
- else
- retval = HeapSize( GetProcessHeap(), 0, mem->ptr );
- }
- else
- {
- WARN_(globalmem)( "invalid handle %p\n", handle );
- SetLastError( ERROR_INVALID_HANDLE );
- retval = 0;
- }
- RtlUnlockHeap( GetProcessHeap() );
- }
- if (retval == ~(SIZE_T)0) retval = 0;
- return retval;
+ return LocalSize( handle );
}
@@ -513,21 +467,33 @@ SIZE_T WINAPI LocalShrink( HGLOBAL handle, UINT newsize )
/***********************************************************************
* LocalSize (KERNEL32.@)
- *
- * Get the size of a local memory object.
- *
- * RETURNS
- * Size: Success
- * 0: Failure
- *
- * NOTES
- * Windows memory management does not provide a separate local heap
- * and global heap.
*/
-SIZE_T WINAPI LocalSize(
- HLOCAL handle /* [in] Handle of memory object */
-) {
- return GlobalSize( handle );
+SIZE_T WINAPI LocalSize( HLOCAL handle )
+{
+ HANDLE heap = GetProcessHeap();
+ struct mem_entry *mem;
+ SIZE_T ret = 0;
+ void *ptr;
+
+ TRACE_(globalmem)( "handle %p\n", handle );
+
+ RtlLockHeap( heap );
+ if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
+ ret = HeapSize( heap, HEAP_NO_SERIALIZE, ptr );
+ else if ((mem = unsafe_mem_from_HLOCAL( handle )))
+ {
+ if (!mem->ptr) ret = 0;
+ else ret = HeapSize( heap, HEAP_NO_SERIALIZE, mem->ptr );
+ }
+ else
+ {
+ WARN_(globalmem)( "invalid handle %p\n", handle );
+ SetLastError( ERROR_INVALID_HANDLE );
+ }
+ RtlUnlockHeap( heap );
+
+ if (ret == ~(SIZE_T)0) return 0;
+ return ret;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/222
June 10, 2022
[PATCH 3/6] kernelbase: Stop using an offset for HLOCAL pointers.
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 | 30 +++---------------------------
dlls/kernel32/tests/heap.c | 6 ------
dlls/kernelbase/memory.c | 27 +++++++++------------------
3 files changed, 12 insertions(+), 51 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index c1074e70e2e..e414ad03493 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -172,13 +172,6 @@ C_ASSERT(sizeof(struct mem_entry) == 2 * sizeof(void *));
struct kernelbase_global_data *kernelbase_global_data;
-/* align the storage needed for the HLOCAL on an 8-byte boundary thus
- * LocalAlloc/LocalReAlloc'ing with LMEM_MOVEABLE of memory with
- * size = 8*k, where k=1,2,3,... allocs exactly the given size.
- * The Minolta DiMAGE Image Viewer heavily relies on this, corrupting
- * the output jpeg's > 1 MB if not */
-#define HLOCAL_STORAGE (sizeof(HLOCAL) * 2)
-
static inline struct mem_entry *unsafe_mem_from_HLOCAL( HLOCAL handle )
{
struct mem_entry *mem = CONTAINING_RECORD( handle, struct mem_entry, ptr );
@@ -254,7 +247,6 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
{
struct mem_entry *mem;
HGLOBAL handle;
- LPCVOID test;
ULONG flags;
TRACE_(globalmem)( "ptr %p\n", ptr );
@@ -275,12 +267,7 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
/* will fail. */
if ((ptr = unsafe_ptr_from_HLOCAL( (HLOCAL)ptr )))
{
- if (HeapValidate( GetProcessHeap(), HEAP_NO_SERIALIZE, ptr ))
- {
- handle = (HGLOBAL)ptr; /* valid fixed block */
- break;
- }
- if (!RtlGetUserInfoHeap( GetProcessHeap(), HEAP_NO_SERIALIZE, (char *)ptr - HLOCAL_STORAGE, &handle, &flags ))
+ if (!RtlGetUserInfoHeap( GetProcessHeap(), HEAP_NO_SERIALIZE, (void *)ptr, &handle, &flags ))
{
SetLastError( ERROR_INVALID_HANDLE );
handle = 0;
@@ -292,8 +279,7 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
/* Now test handle either passed in or retrieved from pointer */
if ((mem = unsafe_mem_from_HLOCAL( handle )))
{
- test = mem->ptr;
- if (HeapValidate( GetProcessHeap(), HEAP_NO_SERIALIZE, (const char *)test - HLOCAL_STORAGE )) /* obj(-handle) valid arena? */
+ if (HeapValidate( GetProcessHeap(), HEAP_NO_SERIALIZE, mem->ptr )) /* obj(-handle) valid arena? */
break; /* valid moveable block */
}
handle = 0;
@@ -356,14 +342,7 @@ SIZE_T WINAPI GlobalSize( HGLOBAL handle )
}
if ((ptr = unsafe_ptr_from_HLOCAL( handle )))
- {
retval = HeapSize( GetProcessHeap(), 0, ptr );
- if (retval == ~(SIZE_T)0) /* It might be a GMEM_MOVEABLE data pointer */
- {
- retval = HeapSize( GetProcessHeap(), 0, (char *)ptr - HLOCAL_STORAGE );
- if (retval != ~(SIZE_T)0) retval -= HLOCAL_STORAGE;
- }
- }
else
{
RtlLockHeap( GetProcessHeap() );
@@ -372,10 +351,7 @@ SIZE_T WINAPI GlobalSize( HGLOBAL handle )
if (!mem->ptr) /* handle case of GlobalAlloc( ??,0) */
retval = 0;
else
- {
- retval = HeapSize( GetProcessHeap(), 0, (char *)mem->ptr - HLOCAL_STORAGE );
- if (retval != ~(SIZE_T)0) retval -= HLOCAL_STORAGE;
- }
+ retval = HeapSize( GetProcessHeap(), 0, mem->ptr );
}
else
{
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index ec2fe7479ca..4496df35579 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -1400,29 +1400,23 @@ static void test_GlobalAlloc(void)
ret = HeapValidate( GetProcessHeap(), 0, entry );
ok( !ret, "HeapValidate succeeded\n" );
ret = HeapValidate( GetProcessHeap(), 0, entry->ptr );
- todo_wine
ok( ret, "HeapValidate failed, error %lu\n", GetLastError() );
size = HeapSize( GetProcessHeap(), 0, entry->ptr );
- todo_wine
ok( size == alloc_size, "HeapSize returned %Iu\n", size );
tmp_mem = invalid_mem;
tmp_flags = 0xdeadbeef;
ret = pRtlGetUserInfoHeap( GetProcessHeap(), 0, entry->ptr, (void **)&tmp_mem, &tmp_flags );
ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() );
- todo_wine
ok( tmp_mem == mem, "got user ptr %p\n", tmp_mem );
todo_wine
ok( tmp_flags == 0x200, "got user flags %#lx\n", tmp_flags );
ret = pRtlSetUserValueHeap( GetProcessHeap(), 0, entry->ptr, invalid_mem );
- todo_wine
ok( ret, "RtlSetUserValueHeap failed, error %lu\n", GetLastError() );
tmp_mem = GlobalHandle( entry->ptr );
- todo_wine
ok( tmp_mem == invalid_mem, "GlobalHandle returned unexpected handle\n" );
ret = pRtlSetUserValueHeap( GetProcessHeap(), 0, entry->ptr, mem );
- todo_wine
ok( ret, "RtlSetUserValueHeap failed, error %lu\n", GetLastError() );
ptr = GlobalLock( mem );
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 409b35089e3..16a068f5b5f 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -752,13 +752,6 @@ C_ASSERT(sizeof(struct mem_entry) == 2 * sizeof(void *));
static struct mem_entry *next_free_mem;
static struct kernelbase_global_data global_data = {0};
-/* align the storage needed for the HLOCAL on an 8-byte boundary thus
- * LocalAlloc/LocalReAlloc'ing with LMEM_MOVEABLE of memory with
- * size = 8*k, where k=1,2,3,... allocs exactly the given size.
- * The Minolta DiMAGE Image Viewer heavily relies on this, corrupting
- * the output jpeg's > 1 MB if not */
-#define HLOCAL_STORAGE (sizeof(HLOCAL) * 2)
-
static inline struct mem_entry *unsafe_mem_from_HLOCAL( HLOCAL handle )
{
struct mem_entry *mem = CONTAINING_RECORD( *(volatile HANDLE *)&handle, struct mem_entry, ptr );
@@ -872,10 +865,9 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalAlloc( UINT flags, SIZE_T size )
if (!size) mem->flags |= MEM_FLAG_DISCARDED;
else
{
- if (!(ptr = HeapAlloc( heap, heap_flags, size + HLOCAL_STORAGE ))) goto failed;
+ if (!(ptr = HeapAlloc( heap, heap_flags, size ))) goto failed;
RtlSetUserValueHeap( heap, heap_flags, ptr, handle );
- *(HLOCAL *)ptr = handle;
- mem->ptr = (char *)ptr + HLOCAL_STORAGE;
+ mem->ptr = ptr;
}
TRACE_(globalmem)( "return handle %p, ptr %p\n", handle, mem->ptr );
@@ -907,7 +899,7 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalFree( HLOCAL handle )
}
else if ((mem = unsafe_mem_from_HLOCAL( handle )))
{
- if (!mem->ptr || HeapFree( heap, HEAP_NO_SERIALIZE, (char *)mem->ptr - HLOCAL_STORAGE )) ret = 0;
+ if (HeapFree( heap, HEAP_NO_SERIALIZE, mem->ptr )) ret = 0;
mem->ptr = NULL;
mem->next_free = next_free_mem;
next_free_mem = mem;
@@ -1026,25 +1018,24 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalReAlloc( HLOCAL handle, SIZE_T size, UINT f
/* reallocate a moveable block */
if (size != 0)
{
- if (size <= INT_MAX - HLOCAL_STORAGE)
+ if (size <= INT_MAX)
{
if (mem->ptr)
{
- if ((ptr = HeapReAlloc( GetProcessHeap(), heap_flags, (char *)mem->ptr - HLOCAL_STORAGE,
- size + HLOCAL_STORAGE )))
+ if ((ptr = HeapReAlloc( GetProcessHeap(), heap_flags, mem->ptr, size )))
{
RtlSetUserValueHeap( GetProcessHeap(), heap_flags, ptr, handle );
- mem->ptr = (char *)ptr + HLOCAL_STORAGE;
+ mem->ptr = ptr;
ret = handle;
}
}
else
{
- if ((ptr = HeapAlloc( GetProcessHeap(), heap_flags, size + HLOCAL_STORAGE )))
+ if ((ptr = HeapAlloc( GetProcessHeap(), heap_flags, size )))
{
RtlSetUserValueHeap( GetProcessHeap(), heap_flags, ptr, handle );
*(HLOCAL *)ptr = handle;
- mem->ptr = (char *)ptr + HLOCAL_STORAGE;
+ mem->ptr = ptr;
ret = handle;
}
}
@@ -1057,7 +1048,7 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalReAlloc( HLOCAL handle, SIZE_T size, UINT f
{
if (mem->ptr)
{
- HeapFree( GetProcessHeap(), 0, (char *)mem->ptr - HLOCAL_STORAGE );
+ HeapFree( GetProcessHeap(), 0, mem->ptr );
mem->ptr = NULL;
}
ret = handle;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/222
June 10, 2022
[PATCH 2/6] kernel32: Use RtlGetUserInfoHeap in GlobalHandle.
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 | 10 ++++++++--
dlls/kernel32/tests/heap.c | 8 ++++++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index df094c94257..c1074e70e2e 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -47,6 +47,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(globalmem);
static HANDLE systemHeap; /* globally shared heap */
+BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE handle, ULONG flags, void *ptr, void **user_value, ULONG *user_flags );
/***********************************************************************
* HEAP_CreateSystemHeap
@@ -171,7 +172,6 @@ C_ASSERT(sizeof(struct mem_entry) == 2 * sizeof(void *));
struct kernelbase_global_data *kernelbase_global_data;
-#define POINTER_TO_HANDLE( p ) (*(((const HGLOBAL *)( p )) - 2))
/* align the storage needed for the HLOCAL on an 8-byte boundary thus
* LocalAlloc/LocalReAlloc'ing with LMEM_MOVEABLE of memory with
* size = 8*k, where k=1,2,3,... allocs exactly the given size.
@@ -255,6 +255,7 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
struct mem_entry *mem;
HGLOBAL handle;
LPCVOID test;
+ ULONG flags;
TRACE_(globalmem)( "ptr %p\n", ptr );
@@ -279,7 +280,12 @@ HGLOBAL WINAPI GlobalHandle( const void *ptr )
handle = (HGLOBAL)ptr; /* valid fixed block */
break;
}
- handle = POINTER_TO_HANDLE( ptr );
+ if (!RtlGetUserInfoHeap( GetProcessHeap(), HEAP_NO_SERIALIZE, (char *)ptr - HLOCAL_STORAGE, &handle, &flags ))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ handle = 0;
+ }
+ break;
}
else handle = (HGLOBAL)ptr;
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 339921b83c3..ec2fe7479ca 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -1494,6 +1494,8 @@ static void test_GlobalAlloc(void)
ptr = GlobalLock( mem );
ok( !!ptr, "GlobalLock failed, error %lu\n", GetLastError() );
ok( ptr != mem, "got unexpected ptr %p\n", ptr );
+ tmp_mem = GlobalHandle( ptr );
+ ok( tmp_mem == mem, "GlobalHandle returned unexpected handle\n" );
flags = GlobalFlags( mem );
ok( flags == 1, "GlobalFlags returned %#x, error %lu\n", flags, GetLastError() );
tmp_ptr = GlobalLock( mem );
@@ -1698,6 +1700,8 @@ static void test_GlobalAlloc(void)
ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() );
ret = GlobalUnlock( mem );
ok( ret, "GlobalUnlock failed, error %lu\n", GetLastError() );
+ tmp_mem = GlobalHandle( mem );
+ ok( tmp_mem == mem, "GlobalHandle returned unexpected handle\n" );
mem = GlobalFree( mem );
ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
@@ -1867,6 +1871,8 @@ static void test_LocalAlloc(void)
ptr = LocalLock( mem );
ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() );
ok( ptr != mem, "got unexpected ptr %p\n", ptr );
+ tmp_mem = LocalHandle( ptr );
+ ok( tmp_mem == mem, "LocalHandle returned unexpected handle\n" );
flags = LocalFlags( mem );
ok( flags == 1, "LocalFlags returned %#x, error %lu\n", flags, GetLastError() );
tmp_ptr = LocalLock( mem );
@@ -2030,6 +2036,8 @@ static void test_LocalAlloc(void)
ret = LocalUnlock( mem );
ok( !ret, "LocalUnlock succeeded\n" );
ok( GetLastError() == ERROR_NOT_LOCKED, "got error %lu\n", GetLastError() );
+ tmp_mem = LocalHandle( mem );
+ ok( tmp_mem == mem, "LocalHandle returned unexpected handle\n" );
mem = LocalFree( mem );
ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/222
June 10, 2022