[APPHELP] Implement SdbQueryData[Ex][TagID]
authorMark Jansen <mark.jansen@reactos.org>
Tue, 10 Apr 2018 20:42:03 +0000 (22:42 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 12 Apr 2018 16:49:25 +0000 (18:49 +0200)
dll/appcompat/apphelp/apphelp.h
dll/appcompat/apphelp/apphelp.spec
dll/appcompat/apphelp/hsdb.c
dll/appcompat/apphelp/sdbapi.c
dll/appcompat/apphelp/sdbread.c

index f2af2b0..5d7e4c3 100644 (file)
@@ -90,6 +90,8 @@ BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid);
 HRESULT WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size);
 LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid);
 TAGID WINAPI SdbFindFirstNamedTag(PDB pdb, TAGID root, TAGID find, TAGID nametag, LPCWSTR find_name);
+DWORD WINAPI SdbQueryDataExTagID(PDB pdb, TAGID tiExe, LPCWSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize, TAGID *ptiData);
+
 
 /* sdbread.c */
 BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num);
@@ -101,6 +103,9 @@ DWORD WINAPI SdbReadDWORDTag(PDB pdb, TAGID tagid, DWORD ret);
 QWORD WINAPI SdbReadQWORDTag(PDB pdb, TAGID tagid, QWORD ret);
 TAGID WINAPI SdbGetFirstChild(PDB pdb, TAGID parent);
 TAGID WINAPI SdbGetNextChild(PDB pdb, TAGID parent, TAGID prev_child);
+DWORD WINAPI SdbGetTagDataSize(PDB pdb, TAGID tagid);
+LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size);
+
 
 /* sdbfileattr.c*/
 BOOL WINAPI SdbGetFileAttributes(LPCWSTR path, PATTRINFO *attr_info_ret, LPDWORD attr_count);
@@ -116,6 +121,7 @@ BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name, LPCW
 BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF* ptrWhich);
 BOOL WINAPI SdbTagRefToTagID(HSDB hsdb, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich);
 BOOL WINAPI SdbUnpackAppCompatData(HSDB hsdb, LPCWSTR pszImageName, PVOID pData, PSDBQUERYRESULT pQueryResult);
+DWORD WINAPI SdbQueryData(HSDB hsdb, TAGREF trWhich, LPCWSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize);
 
 #define ATTRIBUTE_AVAILABLE 0x1
 #define ATTRIBUTE_FAILED 0x2
index d2def1a..9509e6e 100644 (file)
 @ stub SdbQueryApphelpInformation
 @ stub SdbQueryBlockUpgrade
 @ stub SdbQueryContext
-@ stub SdbQueryData
-@ stub SdbQueryDataEx
-@ stub SdbQueryDataExTagID
+@ stdcall SdbQueryData(ptr long wstr ptr ptr ptr)
+@ stdcall SdbQueryDataEx(ptr long wstr ptr ptr ptr ptr)
+@ stdcall SdbQueryDataExTagID(ptr long wstr ptr ptr ptr ptr)
 @ stub SdbQueryFlagInfo
 @ stub SdbQueryName
 @ stub SdbQueryReinstallUpgrade
index 6c23ec6..ddc501b 100644 (file)
@@ -753,7 +753,57 @@ DWORD WINAPI SdbGetAppCompatDataSize(ShimData* pData)
     if (!pData || pData->dwMagic != SHIMDATA_MAGIC)
         return 0;
 
-
     return pData->dwSize;
 }
 
+
+/**
+* Retrieve a Data entry
+*
+* @param [in]  hsdb                    The multi-database.
+* @param [in]  trExe                   The tagRef to start at
+* @param [in,opt]  lpszDataName        The name of the Data entry to find, or NULL to return all.
+* @param [out,opt]  lpdwDataType       Any of REG_SZ, REG_QWORD, REG_DWORD, ...
+* @param [out]  lpBuffer               The output buffer
+* @param [in,out,opt]  lpcbBufferSize  The size of lpBuffer in bytes
+* @param [out,opt]  ptrData            The tagRef of the data
+*
+* @return  ERROR_SUCCESS
+*/
+DWORD WINAPI SdbQueryDataEx(HSDB hsdb, TAGREF trWhich, LPCWSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize, TAGREF *ptrData)
+{
+    PDB pdb;
+    TAGID tiWhich, tiData;
+    DWORD dwResult;
+
+    if (!SdbTagRefToTagID(hsdb, trWhich, &pdb, &tiWhich))
+    {
+        SHIM_WARN("Unable to translate trWhich=0x%x\n", trWhich);
+        return ERROR_NOT_FOUND;
+    }
+
+    dwResult = SdbQueryDataExTagID(pdb, tiWhich, lpszDataName, lpdwDataType, lpBuffer, lpcbBufferSize, &tiData);
+
+    if (dwResult == ERROR_SUCCESS && ptrData)
+        SdbTagIDToTagRef(hsdb, pdb, tiData, ptrData);
+
+    return dwResult;
+}
+
+
+/**
+* Retrieve a Data entry
+*
+* @param [in]  hsdb                    The multi-database.
+* @param [in]  trExe                   The tagRef to start at
+* @param [in,opt]  lpszDataName        The name of the Data entry to find, or NULL to return all.
+* @param [out,opt]  lpdwDataType       Any of REG_SZ, REG_QWORD, REG_DWORD, ...
+* @param [out]  lpBuffer               The output buffer
+* @param [in,out,opt]  lpcbBufferSize  The size of lpBuffer in bytes
+*
+* @return  ERROR_SUCCESS
+*/
+DWORD WINAPI SdbQueryData(HSDB hsdb, TAGREF trWhich, LPCWSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize)
+{
+    return SdbQueryDataEx(hsdb, trWhich, lpszDataName, lpdwDataType, lpBuffer, lpcbBufferSize, NULL);
+}
index ba60048..0f380d0 100644 (file)
@@ -4,7 +4,7 @@
  * PURPOSE:     Sdb low level glue layer
  * COPYRIGHT:   Copyright 2011 André Hentschel
  *              Copyright 2013 Mislav Blaževic
- *              Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
+ *              Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
  */
 
 #include "ntndk.h"
@@ -476,7 +476,7 @@ BOOL WINAPI SdbGetDatabaseVersion(LPCWSTR database, PDWORD VersionHi, PDWORD Ver
 /**
  * Find the first named child tag.
  *
- * @param [in]  database    The database.
+ * @param [in]  pdb         The database.
  * @param [in]  root        The tag to start at
  * @param [in]  find        The tag type to find
  * @param [in]  nametag     The child of 'find' that contains the name
@@ -534,6 +534,116 @@ TAGREF WINAPI SdbGetLayerTagRef(HSDB hsdb, LPCWSTR layerName)
 }
 
 
+#ifndef REG_SZ
+#define REG_SZ 1
+#define REG_DWORD 4
+#define REG_QWORD 11
+#endif
+
+
+/**
+ * Retrieve a Data entry
+ *
+ * @param [in]  pdb                     The database.
+ * @param [in]  tiExe                   The tagID to start at
+ * @param [in,opt]  lpszDataName        The name of the Data entry to find, or NULL to return all.
+ * @param [out,opt]  lpdwDataType       Any of REG_SZ, REG_QWORD, REG_DWORD, ...
+ * @param [out]  lpBuffer               The output buffer
+ * @param [in,out,opt]  lpcbBufferSize  The size of lpBuffer in bytes
+ * @param [out,opt]  ptiData            The tagID of the data
+ *
+ * @return  ERROR_SUCCESS
+ */
+DWORD WINAPI SdbQueryDataExTagID(PDB pdb, TAGID tiExe, LPCWSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize, TAGID *ptiData)
+{
+    TAGID tiData, tiValueType, tiValue;
+    DWORD dwDataType, dwSizeRequired, dwInputSize;
+    LPCWSTR lpStringData;
+    /* Not supported yet */
+    if (!lpszDataName)
+        return ERROR_INVALID_PARAMETER;
+
+    tiData = SdbFindFirstNamedTag(pdb, tiExe, TAG_DATA, TAG_NAME, lpszDataName);
+    if (tiData == TAGID_NULL)
+    {
+        SHIM_INFO("No data tag found\n");
+        return ERROR_NOT_FOUND;
+    }
+
+    if (ptiData)
+        *ptiData = tiData;
+
+    tiValueType = SdbFindFirstTag(pdb, tiData, TAG_DATA_VALUETYPE);
+    if (tiValueType == TAGID_NULL)
+    {
+        SHIM_WARN("Data tag (0x%x) without valuetype\n", tiData);
+        return ERROR_INTERNAL_DB_CORRUPTION;
+    }
+
+    dwDataType = SdbReadDWORDTag(pdb, tiValueType, 0);
+    switch (dwDataType)
+    {
+    case REG_SZ:
+        tiValue = SdbFindFirstTag(pdb, tiData, TAG_DATA_STRING);
+        break;
+    case REG_DWORD:
+        tiValue = SdbFindFirstTag(pdb, tiData, TAG_DATA_DWORD);
+        break;
+    case REG_QWORD:
+        tiValue = SdbFindFirstTag(pdb, tiData, TAG_DATA_QWORD);
+        break;
+    default:
+        /* Not supported (yet) */
+        SHIM_WARN("Unsupported dwDataType=0x%x\n", dwDataType);
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    if (lpdwDataType)
+        *lpdwDataType = dwDataType;
+
+    if (tiValue == TAGID_NULL)
+    {
+        SHIM_WARN("Data tag (0x%x) without data\n", tiData);
+        return ERROR_INTERNAL_DB_CORRUPTION;
+    }
+
+    if (dwDataType != REG_SZ)
+    {
+        dwSizeRequired = SdbGetTagDataSize(pdb, tiValue);
+    }
+    else
+    {
+        lpStringData = SdbpGetString(pdb, tiValue, &dwSizeRequired);
+        if (lpStringData == NULL)
+        {
+            return ERROR_INTERNAL_DB_CORRUPTION;
+        }
+    }
+    if (!lpcbBufferSize)
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    dwInputSize = *lpcbBufferSize;
+    *lpcbBufferSize = dwSizeRequired;
+
+    if (dwInputSize < dwSizeRequired || lpBuffer == NULL)
+    {
+        SHIM_WARN("dwInputSize %u not sufficient to hold %u bytes\n", dwInputSize, dwSizeRequired);
+        return ERROR_INSUFFICIENT_BUFFER;
+    }
+
+    if (dwDataType != REG_SZ)
+    {
+        SdbpReadData(pdb, lpBuffer, tiValue + sizeof(TAG), dwSizeRequired);
+    }
+    else
+    {
+        StringCbCopyNW(lpBuffer, dwInputSize, lpStringData, dwSizeRequired);
+    }
+
+    return ERROR_SUCCESS;
+}
+
+
 /**
  * Converts the specified string to an index key.
  *
index 4b4845c..08bc5f4 100644 (file)
@@ -4,16 +4,13 @@
  * PURPOSE:     Shim database query functions
  * COPYRIGHT:   Copyright 2011 André Hentschel
  *              Copyright 2013 Mislav Blaževic
- *              Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
+ *              Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
  */
 
 #include "windef.h"
 #include "apphelp.h"
 
 
-DWORD WINAPI SdbGetTagDataSize(PDB pdb, TAGID tagid);
-
-
 BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num)
 {
     DWORD size = offset + num;
@@ -47,7 +44,7 @@ static DWORD WINAPI SdbpGetTagSize(PDB pdb, TAGID tagid)
     return size;
 }
 
-static LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size)
+LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size)
 {
     TAG tag;
     TAGID offset;
@@ -79,7 +76,7 @@ static LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size)
     }
 
     /* Optionally read string size */
-    if (size && !SdbpReadData(pdb, size, tagid + sizeof(TAG), sizeof(*size)))
+    if (size && !SdbpReadData(pdb, size, offset - sizeof(TAGID), sizeof(*size)))
         return FALSE;
 
     return (LPWSTR)(&pdb->data[offset]);