Dirk Niggemann : toolhelp: Return correct handle, address, flag and lock values in LocalNext() for moveable blocks.

Alexandre Julliard julliard at winehq.org
Mon Feb 17 15:42:16 CST 2020


Module: wine
Branch: master
Commit: 22173f708e2a6b8be851cc69e4aabbadd387732b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=22173f708e2a6b8be851cc69e4aabbadd387732b

Author: Dirk Niggemann <dirk.niggemann at gmail.com>
Date:   Thu Feb 13 19:32:14 2020 +0000

toolhelp: Return correct handle, address, flag and lock values in LocalNext() for moveable blocks.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48523
Signed-off-by: Dirk Niggemann <dirk.niggemann at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/toolhelp.dll16/toolhelp.c | 44 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/dlls/toolhelp.dll16/toolhelp.c b/dlls/toolhelp.dll16/toolhelp.c
index f2b520b6a1..578d1ae7fa 100644
--- a/dlls/toolhelp.dll16/toolhelp.c
+++ b/dlls/toolhelp.dll16/toolhelp.c
@@ -90,6 +90,22 @@ typedef struct
 #define LOCAL_ARENA_HEADER( handle) ((handle) - LOCAL_ARENA_HEADER_SIZE)
 #define LOCAL_ARENA_PTR(ptr,arena)  ((LOCALARENA *)((char *)(ptr)+(arena)))
 
+#define MOVEABLE_PREFIX sizeof(HLOCAL16)
+
+/* 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;
+
+
 typedef struct
 {
     WORD null;        /* Always 0 */
@@ -349,15 +365,35 @@ 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 (!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;
     pLocalEntry->wFlags    = (pArena->prev & 3) + 1;
     pLocalEntry->wcLock    = 0;
+    /* Find the address in the entry tables */
+    lhandle = pLocalEntry->wAddress;
+    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;
+                break;
+            }
+        if (table) table = *(WORD *)pEntry;
+    }
+    pLocalEntry->hHandle   = lhandle;
     pLocalEntry->wType     = LT_NORMAL;
     if (pArena->next != pLocalEntry->wNext)  /* last one? */
         pLocalEntry->wNext = pArena->next;




More information about the wine-cvs mailing list