https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d74a3fecad67e8504a5170...
commit d74a3fecad67e8504a51706851436d7ae423dcfa Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Tue Apr 10 22:42:03 2018 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Thu Apr 12 18:49:25 2018 +0200
[APPHELP] Implement SdbQueryData[Ex][TagID] --- dll/appcompat/apphelp/apphelp.h | 6 ++ dll/appcompat/apphelp/apphelp.spec | 6 +- dll/appcompat/apphelp/hsdb.c | 52 ++++++++++++++++- dll/appcompat/apphelp/sdbapi.c | 114 ++++++++++++++++++++++++++++++++++++- dll/appcompat/apphelp/sdbread.c | 9 +-- 5 files changed, 175 insertions(+), 12 deletions(-)
diff --git a/dll/appcompat/apphelp/apphelp.h b/dll/appcompat/apphelp/apphelp.h index f2af2b0afc..5d7e4c3b7f 100644 --- a/dll/appcompat/apphelp/apphelp.h +++ b/dll/appcompat/apphelp/apphelp.h @@ -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 diff --git a/dll/appcompat/apphelp/apphelp.spec b/dll/appcompat/apphelp/apphelp.spec index d2def1a93f..9509e6e975 100644 --- a/dll/appcompat/apphelp/apphelp.spec +++ b/dll/appcompat/apphelp/apphelp.spec @@ -108,9 +108,9 @@ @ 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 diff --git a/dll/appcompat/apphelp/hsdb.c b/dll/appcompat/apphelp/hsdb.c index 6c23ec6fa3..ddc501b539 100644 --- a/dll/appcompat/apphelp/hsdb.c +++ b/dll/appcompat/apphelp/hsdb.c @@ -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); +} diff --git a/dll/appcompat/apphelp/sdbapi.c b/dll/appcompat/apphelp/sdbapi.c index ba60048ca5..0f380d0c1e 100644 --- a/dll/appcompat/apphelp/sdbapi.c +++ b/dll/appcompat/apphelp/sdbapi.c @@ -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. * diff --git a/dll/appcompat/apphelp/sdbread.c b/dll/appcompat/apphelp/sdbread.c index 4b4845c290..08bc5f49dc 100644 --- a/dll/appcompat/apphelp/sdbread.c +++ b/dll/appcompat/apphelp/sdbread.c @@ -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]);