mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[APPHELP] Implement SdbpMatchExe, allowing to match applications / files based on properties. CORE-13284
svn path=/trunk/; revision=75238
This commit is contained in:
parent
2fc232f21e
commit
af96013370
3 changed files with 132 additions and 22 deletions
|
@ -90,6 +90,7 @@ PWSTR SdbpStrDup(LPCWSTR string);
|
|||
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 SdbFindFirstTag(PDB db, TAGID parent, TAG tag);
|
|||
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 */
|
||||
|
|
|
@ -49,31 +49,132 @@ static BOOL WINAPI SdbpFileExists(LPCWSTR path)
|
|||
return (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
static BOOL WINAPI SdbpMatchExe(PDB db, TAGID exe, WCHAR* dir)
|
||||
static BOOL SdbpMatchFileAttributes(PDB pdb, TAGID matching_file, PATTRINFO attribs, DWORD attr_count)
|
||||
{
|
||||
static const WCHAR fmt[] = {'%','s','%','s',0};
|
||||
WCHAR buffer[256]; /* FIXME: rewrite using a buffer that can grow if needed, f.e. RtlInitBuffer stuff! */
|
||||
TAGID matching_file;
|
||||
TAGID child;
|
||||
|
||||
/* 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))
|
||||
for (child = SdbGetFirstChild(pdb, matching_file);
|
||||
child != TAGID_NULL; child = SdbGetNextChild(pdb, matching_file, child))
|
||||
{
|
||||
TAGID tagName = SdbFindFirstTag(db, matching_file, TAG_NAME);
|
||||
LPWSTR name = SdbGetStringTagPtr(db, tagName);
|
||||
TAG tag = SdbGetTagFromTagID(pdb, child);
|
||||
DWORD n;
|
||||
|
||||
if (!wcscmp(name, L"*"))
|
||||
/* 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)
|
||||
{
|
||||
// if attributes dont match main file, return FALSE!
|
||||
SHIM_WARN("Unimplemented TAG_UPTO_XXXXX\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintfW(buffer, _countof(buffer), fmt, dir, name);
|
||||
if (!SdbpFileExists(buffer))
|
||||
return FALSE;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
IsMatch = TRUE;
|
||||
|
||||
Cleanup:
|
||||
RtlFreeBuffer(&FullPathName.ByteBuffer);
|
||||
if (attribs)
|
||||
SdbFreeFileAttributes(attribs);
|
||||
|
||||
return IsMatch;
|
||||
}
|
||||
|
||||
static void SdbpAddDatabaseGuid(PDB db, PSDBQUERYRESULT result)
|
||||
|
@ -331,7 +432,7 @@ BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
|
|||
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 @@ BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
|
|||
/* 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 @@ BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
|
|||
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);
|
||||
|
|
|
@ -86,7 +86,7 @@ static WCHAR* WINAPI SdbpGetStringAttr(LPWSTR translation, LPCWSTR attr, PVOID f
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue