[PATCH 9/11] apphelp: Implement SdbGetNextChild.

Mislav Blazevic krofnica996 at gmail.com
Wed Jul 31 17:59:07 CDT 2013


---
 dlls/apphelp/apphelp.c    | 85 +++++++++++++++++++++++++++++++++++++++++++++++
 dlls/apphelp/apphelp.spec |  2 +-
 include/appcompatapi.h    |  1 +
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/dlls/apphelp/apphelp.c b/dlls/apphelp/apphelp.c
index 5822266..32dface 100644
--- a/dlls/apphelp/apphelp.c
+++ b/dlls/apphelp/apphelp.c
@@ -619,3 +619,88 @@ QWORD WINAPI SdbReadQWORDTag(PDB db, TAGID tagid,
QWORD ret)

     return ret;
 }
+
+static DWORD WINAPI SdbGetTagSize(PDB db, TAGID tagid)
+{
+    /* sizes of data types with fixed size + sizeof(TAG) */
+    static const SIZE_T sizes[6] = {
+        0 + 2, 1 + 2,
+        2 + 2, 4 + 2,
+        8 + 2, 4 + 2
+    };
+    WORD type;
+    DWORD size;
+
+    type = SdbGetTagFromTagID(db, tagid) & TAG_TYPE_MASK;
+
+    if (type == TAG_NULL)
+    {
+        TRACE("Invalid tagid\n");
+        return 0;
+    }
+
+    if (type <= TAG_TYPE_STRINGREF)
+        return sizes[(type >> 12) - 1];
+
+    /* tag with dynamic size (e.g. list): must read size */
+    if (!SdbReadData(db, &size, parent + 2, 4))
+    {
+        TRACE("Failed to read size of tag!\n");
+        return 0;
+    }
+
+    /* add 4 because of size DWORD */
+    return size + 2 + 4;
+}
+
+/**************************************************************************
+ *        SdbGetNextChild                [APPHELP.@]
+ *
+ * Searches shim database for next child of specified parent tag
+ *
+ * PARAMS
+ *  db          [I] Handle to the shim database
+ *  parent      [I] TAGID of parent
+ *  prev_child  [I] TAGID of previous child
+ *
+ * RETURNS
+ *  Success: TAGID associated with next child tag
+ *  Failure: TAGID_NULL
+ */
+TAGID WINAPI SdbGetNextChild(PDB db, TAGID parent, TAGID prev_child)
+{
+    TAGID next_child;
+    DWORD prev_child_size, parent_size;
+
+    prev_child_size = SdbGetTagSize(db, prev_child);
+    if (prev_child_size == 0)
+    {
+        TRACE("Failed to read child tag size\n");
+        return TAGID_NULL;
+    }
+
+    next_child = prev_child + prev_child_size;
+    if (next_child >= db->size)
+    {
+        TRACE("Next child is beyond end of database, overflow!\n");
+        return TAGID_NULL;
+    }
+
+    if (parent == TAGID_ROOT)
+        return next_child;
+
+    parent_size = SdbGetTagSize(db, parent);
+    if (parent_size == 0)
+    {
+        TRACE("Failed to read parent tag size\n");
+        return TAGID_NULL;
+    }
+
+    if (next_child >= parent + parent_size + 6)
+    {
+        TRACE("You are not the father!\n");
+        return TAGID_NULL;
+    }
+
+    return next_child;
+}
diff --git a/dlls/apphelp/apphelp.spec b/dlls/apphelp/apphelp.spec
index 4308d80..a564653 100644
--- a/dlls/apphelp/apphelp.spec
+++ b/dlls/apphelp/apphelp.spec
@@ -71,7 +71,7 @@
 @ stub SdbGetMatchingExe
 @ stub SdbGetMsiPackageInformation
 @ stub SdbGetNamedLayer
-@ stub SdbGetNextChild
+@ stdcall SdbGetNextChild(ptr long long)
 @ stub SdbGetNthUserSdb
 @ stub SdbGetPermLayerKeys
 @ stub SdbGetShowDebugInfoOption
diff --git a/include/appcompatapi.h b/include/appcompatapi.h
index 87768b8..d7bbbf5 100644
--- a/include/appcompatapi.h
+++ b/include/appcompatapi.h
@@ -32,6 +32,7 @@ TAG WINAPI SdbGetTagFromTagID(PDB, TAGID);
 TAGID WINAPI SdbGetFirstChild(PDB, TAGID);
 DWORD WINAPI SdbReadDWORDTag(PDB, TAGID, DWORD);
 QWORD WINAPI SdbReadQWORDTag(PDB, TAGID, QWORD);
+TAGID WINAPI SdbGetNextChild(PDB, TAGID, TAGID);

 typedef enum _PATH_TYPE {
     DOS_PATH,
-- 
1.8.3.4



More information about the wine-patches mailing list