Make LocalNext() return correct handles, addresses, flags and lock values for moveable blocks. Previous implementation just returned the arena block pointer and flags for fixed blocks. Needed for applications that use toolhelp to find their own memory blocks.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48523 Signed-off-by: Dirk Niggemann <dirk.niggemann(a)gmail.com> --- dlls/toolhelp.dll16/toolhelp.c | 55 ++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/dlls/toolhelp.dll16/toolhelp.c b/dlls/toolhelp.dll16/toolhelp.c index f2b520b6a1..5fe5afe988 100644 --- a/dlls/toolhelp.dll16/toolhelp.c +++ b/dlls/toolhelp.dll16/toolhelp.c @@ -90,6 +90,30 @@ typedef struct #define LOCAL_ARENA_HEADER( handle) ((handle) - LOCAL_ARENA_HEADER_SIZE) #define LOCAL_ARENA_PTR(ptr,arena) ((LOCALARENA *)((char *)(ptr)+(arena))) +#ifdef ALLOW_UNALIGNED_ACCESS +# define MOVEABLE_PREFIX sizeof(HLOCAL16) +#else +# define MOVEABLE_PREFIX sizeof(int) +#endif + +/* Layout of a handle entry table + * + * WORD count of entries + * LOCALHANDLEENTRY[count] entries + * WORD near ptr to next table + */ +typedef struct +{ + WORD addr; /* Address of the MOVEABLE block */ + BYTE flags; /* Flags for this block */ + BYTE lock; /* Lock count */ +} LOCALHANDLEENTRY; + + +#define HANDLE_FIXED(handle) (((handle) & 3) == 0) +#define HANDLE_MOVEABLE(handle) (((handle) & 3) == 2) + + typedef struct { WORD null; /* Always 0 */ @@ -349,15 +373,36 @@ BOOL16 WINAPI LocalNext16( LOCALENTRY *pLocalEntry ) WORD ds = GlobalHandleToSel16( pLocalEntry->hHeap ); char *ptr = MapSL( MAKESEGPTR( ds, 0 ) ); LOCALARENA *pArena; + WORD table, lhandle; + LOCALHEAPINFO *pInfo = get_local_heap( ds ); - if (!get_local_heap( ds )) return FALSE; - if (!pLocalEntry->wNext) return FALSE; + if ( !pInfo ) return FALSE; + if ( !pLocalEntry->wNext ) return FALSE; + table = pInfo->htable; pArena = LOCAL_ARENA_PTR( ptr, pLocalEntry->wNext ); - - pLocalEntry->hHandle = pLocalEntry->wNext + LOCAL_ARENA_HEADER_SIZE; - pLocalEntry->wAddress = pLocalEntry->hHandle; + pLocalEntry->wAddress = pLocalEntry->wNext + LOCAL_ARENA_HEADER_SIZE; + lhandle = pLocalEntry->wAddress; pLocalEntry->wFlags = (pArena->prev & 3) + 1; pLocalEntry->wcLock = 0; + /* Find the address in the entry tables */ + while (table) + { + WORD count = *(WORD *)(ptr + table); + LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY*)(ptr+table+sizeof(WORD)); + for (; count > 0; count--, pEntry++) + if (pEntry->addr == lhandle + MOVEABLE_PREFIX) + { + lhandle = (HLOCAL16)((char *)pEntry - ptr); + table = 0; + pLocalEntry->wAddress = pEntry->addr; + pLocalEntry->wFlags = pEntry->flags; + pLocalEntry->wcLock = pEntry->lock; + TRACE("moveable handle %04x\n", lhandle); + break; + } + if ( table ) table = *(WORD *)pEntry; + } + pLocalEntry->hHandle = lhandle; pLocalEntry->wType = LT_NORMAL; if (pArena->next != pLocalEntry->wNext) /* last one? */ pLocalEntry->wNext = pArena->next; -- 2.17.2 (Apple Git-113)
participants (1)
-
Dirk Niggemann