Author: mjansen
Date: Thu Jun 29 17:32:03 2017
New Revision: 75238
URL:
http://svn.reactos.org/svn/reactos?rev=75238&view=rev
Log:
[APPHELP] Implement SdbpMatchExe, allowing to match applications / files based on
properties. CORE-13284
Modified:
trunk/reactos/dll/appcompat/apphelp/apphelp.h
trunk/reactos/dll/appcompat/apphelp/hsdb.c
trunk/reactos/dll/appcompat/apphelp/sdbfileattr.c
Modified: trunk/reactos/dll/appcompat/apphelp/apphelp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/apph…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/apphelp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/apphelp.h [iso-8859-1] Thu Jun 29 17:32:03 2017
@@ -90,6 +90,7 @@
HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR);
void WINAPI SdbReleaseDatabase(HSDB);
BOOL WINAPI SdbGUIDToString(CONST GUID *Guid, PWSTR GuidString, SIZE_T Length);
+LPCWSTR WINAPI SdbTagToString(TAG tag);
PDB WINAPI SdbOpenDatabase(LPCWSTR path, PATH_TYPE type);
void WINAPI SdbCloseDatabase(PDB);
@@ -105,8 +106,12 @@
TAGID WINAPI SdbFindNextTag(PDB db, TAGID parent, TAGID prev_child);
BOOL WINAPI SdbGetDatabaseID(PDB db, GUID* Guid);
DWORD WINAPI SdbReadDWORDTag(PDB db, TAGID tagid, DWORD ret);
+QWORD WINAPI SdbReadQWORDTag(PDB db, TAGID tagid, QWORD ret);
+TAGID WINAPI SdbGetFirstChild(PDB db, TAGID parent);
+TAGID WINAPI SdbGetNextChild(PDB db, TAGID parent, TAGID prev_child);
/* sdbfileattr.c*/
+BOOL WINAPI SdbGetFileAttributes(LPCWSTR path, PATTRINFO *attr_info_ret, LPDWORD
attr_count);
BOOL WINAPI SdbFreeFileAttributes(PATTRINFO attr_info);
/* layer.c */
Modified: trunk/reactos/dll/appcompat/apphelp/hsdb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/hsdb…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/hsdb.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/hsdb.c [iso-8859-1] Thu Jun 29 17:32:03 2017
@@ -49,31 +49,132 @@
return (attr != INVALID_FILE_ATTRIBUTES && !(attr &
FILE_ATTRIBUTE_DIRECTORY));
}
-static BOOL WINAPI SdbpMatchExe(PDB db, TAGID exe, WCHAR* dir)
-{
- static const WCHAR fmt[] = {'%','s','%','s',0};
- WCHAR buffer[256]; /* FIXME: rewrite using a buffer that can grow if needed, f.e.
RtlInitBuffer stuff! */
+static BOOL SdbpMatchFileAttributes(PDB pdb, TAGID matching_file, PATTRINFO attribs,
DWORD attr_count)
+{
+ TAGID child;
+
+ for (child = SdbGetFirstChild(pdb, matching_file);
+ child != TAGID_NULL; child = SdbGetNextChild(pdb, matching_file, child))
+ {
+ TAG tag = SdbGetTagFromTagID(pdb, child);
+ DWORD n;
+
+ /* Already handled! */
+ if (tag == TAG_NAME)
+ continue;
+
+ if (tag == TAG_UPTO_BIN_FILE_VERSION ||
+ tag == TAG_UPTO_BIN_PRODUCT_VERSION ||
+ tag == TAG_UPTO_LINK_DATE)
+ {
+ SHIM_WARN("Unimplemented TAG_UPTO_XXXXX\n");
+ continue;
+ }
+
+ for (n = 0; n < attr_count; ++n)
+ {
+ PATTRINFO attr = attribs + n;
+ if (attr->flags == ATTRIBUTE_AVAILABLE && attr->type == tag)
+ {
+ DWORD dwval;
+ WCHAR* lpval;
+ QWORD qwval;
+ switch (tag & TAG_TYPE_MASK)
+ {
+ case TAG_TYPE_DWORD:
+ dwval = SdbReadDWORDTag(pdb, child, 0);
+ if (dwval != attr->dwattr)
+ return FALSE;
+ break;
+ case TAG_TYPE_STRINGREF:
+ lpval = SdbGetStringTagPtr(pdb, child);
+ if (!lpval || wcsicmp(attr->lpattr, lpval))
+ return FALSE;
+ break;
+ case TAG_TYPE_QWORD:
+ qwval = SdbReadQWORDTag(pdb, child, 0);
+ if (qwval != attr->qwattr)
+ return FALSE;
+ break;
+ default:
+ SHIM_WARN("Unhandled type 0x%x MATCHING_FILE\n", (tag &
TAG_TYPE_MASK));
+ return FALSE;
+ }
+ }
+ }
+ if (n == attr_count)
+ SHIM_WARN("Unhandled tag %ws in MACHING_FILE\n",
SdbTagToString(tag));
+ }
+ return TRUE;
+}
+
+static BOOL WINAPI SdbpMatchExe(PDB pdb, TAGID exe, const WCHAR* dir, PATTRINFO
main_attribs, DWORD main_attr_count)
+{
+ RTL_UNICODE_STRING_BUFFER FullPathName = { { 0 } };
+ WCHAR FullPathBuffer[MAX_PATH];
+ UNICODE_STRING UnicodeDir;
TAGID matching_file;
-
- /* TODO: check size/checksum from the main exe as well as from the extra files */
- for (matching_file = SdbFindFirstTag(db, exe, TAG_MATCHING_FILE);
- matching_file != TAGID_NULL; matching_file = SdbFindNextTag(db, exe,
matching_file))
- {
- TAGID tagName = SdbFindFirstTag(db, matching_file, TAG_NAME);
- LPWSTR name = SdbGetStringTagPtr(db, tagName);
-
- if (!wcscmp(name, L"*"))
- {
- // if attributes dont match main file, return FALSE!
+ PATTRINFO attribs = NULL;
+ DWORD attr_count;
+ BOOL IsMatch = FALSE;
+
+ RtlInitUnicodeString(&UnicodeDir, dir);
+ RtlInitBuffer(&FullPathName.ByteBuffer, (PUCHAR)FullPathBuffer,
sizeof(FullPathBuffer));
+
+ for (matching_file = SdbFindFirstTag(pdb, exe, TAG_MATCHING_FILE);
+ matching_file != TAGID_NULL; matching_file = SdbFindNextTag(pdb, exe,
matching_file))
+ {
+ TAGID tagName = SdbFindFirstTag(pdb, matching_file, TAG_NAME);
+ UNICODE_STRING Name;
+ USHORT Len;
+
+ RtlInitUnicodeString(&Name, SdbGetStringTagPtr(pdb, tagName));
+
+ if (!Name.Buffer)
+ goto Cleanup;
+
+ if (!wcscmp(Name.Buffer, L"*"))
+ {
+ if (!SdbpMatchFileAttributes(pdb, matching_file, main_attribs,
main_attr_count))
+ goto Cleanup;
continue;
}
- snprintfW(buffer, _countof(buffer), fmt, dir, name);
- if (!SdbpFileExists(buffer))
- return FALSE;
- }
-
- return TRUE;
+ /* Technically, one UNICODE_NULL and one path separator. */
+ Len = UnicodeDir.Length + Name.Length + sizeof(UNICODE_NULL) +
sizeof(UNICODE_NULL);
+ if (!NT_SUCCESS(RtlEnsureBufferSize(RTL_SKIP_BUFFER_COPY,
&FullPathName.ByteBuffer, Len)))
+ goto Cleanup;
+
+ if (Len > FullPathName.ByteBuffer.Size)
+ goto Cleanup;
+
+ RtlInitEmptyUnicodeString(&FullPathName.String,
(PWCHAR)FullPathName.ByteBuffer.Buffer, FullPathName.ByteBuffer.Size);
+
+ RtlCopyUnicodeString(&FullPathName.String, &UnicodeDir);
+ RtlAppendUnicodeToString(&FullPathName.String, L"\\");
+ RtlAppendUnicodeStringToString(&FullPathName.String, &Name);
+
+ if (!SdbpFileExists(FullPathName.String.Buffer))
+ goto Cleanup;
+
+ if (attribs)
+ SdbFreeFileAttributes(attribs);
+
+ if (!SdbGetFileAttributes(FullPathName.String.Buffer, &attribs,
&attr_count))
+ goto Cleanup;
+
+ if (!SdbpMatchFileAttributes(pdb, matching_file, attribs, attr_count))
+ goto Cleanup;
+ }
+
+ IsMatch = TRUE;
+
+Cleanup:
+ RtlFreeBuffer(&FullPathName.ByteBuffer);
+ if (attribs)
+ SdbFreeFileAttributes(attribs);
+
+ return IsMatch;
}
static void SdbpAddDatabaseGuid(PDB db, PSDBQUERYRESULT result)
@@ -331,7 +432,7 @@
BOOL ret = FALSE;
TAGID database, iter, name;
PATTRINFO attribs = NULL;
- /*DWORD attr_count;*/
+ DWORD attr_count;
RTL_UNICODE_STRING_BUFFER DosApplicationName = { { 0 } };
WCHAR DosPathBuffer[MAX_PATH];
ULONG PathType = 0;
@@ -390,10 +491,6 @@
/* We will use the buffer for exe name and directory. */
*(file_name++) = UNICODE_NULL;
- /* Get information about executable required to match it with database entry */
- /*if (!SdbGetFileAttributes(path, &attribs, &attr_count))
- return FALSE;*/
-
/* DATABASE is list TAG which contains all executables */
database = SdbFindFirstTag(db, TAGID_ROOT, TAG_DATABASE);
if (database == TAGID_NULL)
@@ -414,8 +511,16 @@
foundName = SdbGetStringTagPtr(db, name);
if (foundName && !lstrcmpiW(foundName, file_name))
{
+ /* Get information about executable required to match it with database entry
*/
+ if (!attribs)
+ {
+ if (!SdbGetFileAttributes(path, &attribs, &attr_count))
+ goto Cleanup;
+ }
+
+
/* We have a null terminator before the application name, so
DosApplicationName only contains the path. */
- if (SdbpMatchExe(db, iter, DosApplicationName.String.Buffer))
+ if (SdbpMatchExe(db, iter, DosApplicationName.String.Buffer, attribs,
attr_count))
{
ret = TRUE;
SdbpAddExeMatch(hsdb, db, iter, result);
Modified: trunk/reactos/dll/appcompat/apphelp/sdbfileattr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbf…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbfileattr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/sdbfileattr.c [iso-8859-1] Thu Jun 29 17:32:03
2017
@@ -86,7 +86,7 @@
return NULL;
}
-static void WINAPI SdbpSetStringAttrFromAnsiString(PATTRINFO attr, TAG tag, PBYTE string,
BYTE len)
+static void WINAPI SdbpSetStringAttrFromAnsiString(PATTRINFO attr, TAG tag, PBYTE string,
size_t len)
{
WCHAR* dest;
if (!string)