diff --git a/dll/appcompat/apphelp/apphelp.h b/dll/appcompat/apphelp/apphelp.h index f2af2b0afc4..5d7e4c3b7f8 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 d2def1a93f9..9509e6e9759 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 6c23ec6fa33..ddc501b5392 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 ba60048ca5d..0f380d0c1e4 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 4b4845c2905..08bc5f49dc2 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]);