[APPHELP] Implement SdbRegisterDatabase[Ex]

CORE-11301
This commit is contained in:
Mark Jansen 2019-02-11 22:45:48 +01:00
parent 28a091ac12
commit c01fa8e9c1
No known key found for this signature in database
GPG Key ID: B39240EE84BEAE8B
2 changed files with 174 additions and 27 deletions

View File

@ -10,21 +10,29 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winver.h"
#include "winreg.h"
#include "strsafe.h"
#include "apphelp.h"
#include "ndk/rtlfuncs.h"
#include "ndk/kdtypes.h"
#include <ndk/rtlfuncs.h>
#include <ndk/cmfuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/kdtypes.h>
ACCESS_MASK Wow64QueryFlag(void);
const UNICODE_STRING InstalledSDBKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\InstalledSDB");
/* from dpfilter.h */
#define DPFLTR_APPCOMPAT_ID 123
#define MAX_GUID_STRING_LEN sizeof("{12345678-1234-1234-0123-456789abcdef}")
#ifndef NT_SUCCESS
#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
#endif
ULONG g_ShimDebugLevel = 0xffffffff;
ULONG g_ShimDebugLevel = ~0;
HMODULE g_hInstance;
void ApphelppInitDebugLevel(void)
@ -52,14 +60,14 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
g_hInstance = hinst;
DisableThreadLibraryCalls( hinst );
SdbpHeapInit();
break;
case DLL_PROCESS_DETACH:
SdbpHeapDeinit();
break;
case DLL_PROCESS_ATTACH:
g_hInstance = hinst;
DisableThreadLibraryCalls(hinst);
SdbpHeapInit();
break;
case DLL_PROCESS_DETACH:
SdbpHeapDeinit();
break;
}
return TRUE;
}
@ -73,8 +81,8 @@ BOOL WINAPI ApphelpCheckInstallShieldPackage(void* ptr, LPCWSTR path)
BOOL WINAPI ApphelpCheckShellObject(REFCLSID ObjectCLSID, BOOL bShimIfNecessary, ULONGLONG *pullFlags)
{
WCHAR GuidString[100];
if (!ObjectCLSID || !SdbGUIDToString(ObjectCLSID, GuidString, 100))
WCHAR GuidString[MAX_GUID_STRING_LEN];
if (!ObjectCLSID || !SdbGUIDToString(ObjectCLSID, GuidString, RTL_NUMBER_OF(GuidString)))
GuidString[0] = L'\0';
SHIM_WARN("stub: ObjectCLSID='%S', bShimIfNecessary=%d, pullFlags=%p)\n", GuidString, bShimIfNecessary, pullFlags);
@ -103,7 +111,7 @@ BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format
const char* LevelStr;
size_t Length = sizeof(Buffer);
if (g_ShimDebugLevel == 0xffffffff)
if (g_ShimDebugLevel == ~0)
ApphelppInitDebugLevel();
if (Level > g_ShimDebugLevel)
@ -251,14 +259,124 @@ ApphelpCheckRunAppEx(
* @return TRUE on success, or FALSE on failure.
*/
BOOL WINAPI SdbRegisterDatabaseEx(
_In_ LPCTSTR pszDatabasePath,
_In_ LPCWSTR pszDatabasePath,
_In_ DWORD dwDatabaseType,
_In_opt_ PULONGLONG pTimeStamp)
_In_opt_ const PULONGLONG pTimeStamp)
{
SHIM_ERR("UNIMPLEMENTED, pszDatabasePath=%ws, dwDatabaseType=0x%x, pTimeStamp=%p\n",
pszDatabasePath, dwDatabaseType, pTimeStamp);
PDB pdb;
DB_INFORMATION Information;
WCHAR GuidBuffer[MAX_GUID_STRING_LEN];
UNICODE_STRING KeyName;
ACCESS_MASK KeyAccess;
OBJECT_ATTRIBUTES ObjectKey = RTL_INIT_OBJECT_ATTRIBUTES(&KeyName, OBJ_CASE_INSENSITIVE);
NTSTATUS Status;
HANDLE InstalledSDBKey;
return FALSE;
pdb = SdbOpenDatabase(pszDatabasePath, DOS_PATH);
if (!pdb)
{
SHIM_ERR("Unable to open DB %S\n", pszDatabasePath);
return FALSE;
}
if (!SdbGetDatabaseInformation(pdb, &Information) ||
!(Information.dwFlags & DB_INFO_FLAGS_VALID_GUID))
{
SHIM_ERR("Unable to retrieve DB info\n");
SdbCloseDatabase(pdb);
return FALSE;
}
if (!SdbGUIDToString(&Information.Id, GuidBuffer, RTL_NUMBER_OF(GuidBuffer)))
{
SHIM_ERR("Unable to Convert GUID to string\n");
SdbFreeDatabaseInformation(&Information);
SdbCloseDatabase(pdb);
return FALSE;
}
KeyName = InstalledSDBKeyName;
KeyAccess = Wow64QueryFlag() | KEY_WRITE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
Status = NtCreateKey(&InstalledSDBKey, KeyAccess, &ObjectKey, 0, NULL, 0, NULL);
if (NT_SUCCESS(Status))
{
HANDLE DbKey;
RtlInitUnicodeString(&KeyName, GuidBuffer);
ObjectKey.RootDirectory = InstalledSDBKey;
Status = NtCreateKey(&DbKey, KeyAccess, &ObjectKey, 0, NULL, 0, NULL);
if (NT_SUCCESS(Status))
{
UNICODE_STRING DatabasePathKey = RTL_CONSTANT_STRING(L"DatabasePath");
UNICODE_STRING DatabaseInstallTimeStampKey = RTL_CONSTANT_STRING(L"DatabaseInstallTimeStamp");
UNICODE_STRING DatabaseTypeKey = RTL_CONSTANT_STRING(L"DatabaseType");
UNICODE_STRING DatabaseDescriptionKey = RTL_CONSTANT_STRING(L"DatabaseDescription");
Status = NtSetValueKey(DbKey, &DatabasePathKey, 0, REG_SZ,
(PVOID)pszDatabasePath, (wcslen(pszDatabasePath) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
SHIM_ERR("Unable to write %wZ\n", &DatabasePathKey);
if (NT_SUCCESS(Status))
{
ULARGE_INTEGER ulTimeStamp;
if (pTimeStamp)
{
ulTimeStamp.QuadPart = *pTimeStamp;
}
else
{
FILETIME fi;
GetSystemTimeAsFileTime(&fi);
ulTimeStamp.LowPart = fi.dwLowDateTime;
ulTimeStamp.HighPart = fi.dwHighDateTime;
}
Status = NtSetValueKey(DbKey, &DatabaseInstallTimeStampKey, 0, REG_QWORD,
&ulTimeStamp.QuadPart, sizeof(ulTimeStamp));
if (!NT_SUCCESS(Status))
SHIM_ERR("Unable to write %wZ\n", &DatabaseInstallTimeStampKey);
}
if (NT_SUCCESS(Status))
{
Status = NtSetValueKey(DbKey, &DatabaseTypeKey, 0, REG_DWORD,
&dwDatabaseType, sizeof(dwDatabaseType));
if (!NT_SUCCESS(Status))
SHIM_ERR("Unable to write %wZ\n", &DatabaseTypeKey);
}
if (NT_SUCCESS(Status) && Information.Description)
{
Status = NtSetValueKey(DbKey, &DatabaseDescriptionKey, 0, REG_SZ,
(PVOID)Information.Description, (wcslen(Information.Description) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
SHIM_ERR("Unable to write %wZ\n", &DatabaseDescriptionKey);
}
NtClose(DbKey);
if (NT_SUCCESS(Status))
{
SHIM_INFO("Installed %wS as %wZ\n", pszDatabasePath, &KeyName);
}
}
else
{
SHIM_ERR("Unable to create key %wZ\n", &KeyName);
}
NtClose(InstalledSDBKey);
}
else
{
SHIM_ERR("Unable to create key %wZ\n", &KeyName);
}
SdbFreeDatabaseInformation(&Information);
SdbCloseDatabase(pdb);
return NT_SUCCESS(Status);
}
@ -271,7 +389,7 @@ BOOL WINAPI SdbRegisterDatabaseEx(
* @return TRUE on success, or FALSE on failure.
*/
BOOL WINAPI SdbRegisterDatabase(
_In_ LPCTSTR pszDatabasePath,
_In_ LPCWSTR pszDatabasePath,
_In_ DWORD dwDatabaseType)
{
return SdbRegisterDatabaseEx(pszDatabasePath, dwDatabaseType, NULL);
@ -285,11 +403,40 @@ BOOL WINAPI SdbRegisterDatabase(
* @param pguidDB
* @return
*/
BOOL WINAPI SdbUnregisterDatabase(_In_ GUID *pguidDB)
BOOL WINAPI SdbUnregisterDatabase(_In_ const GUID *pguidDB)
{
SHIM_ERR("UNIMPLEMENTED, pguidDB = %p\n", pguidDB);
WCHAR KeyBuffer[MAX_PATH], GuidBuffer[50];
UNICODE_STRING KeyName;
ACCESS_MASK KeyAccess;
OBJECT_ATTRIBUTES ObjectKey = RTL_INIT_OBJECT_ATTRIBUTES(&KeyName, OBJ_CASE_INSENSITIVE);
NTSTATUS Status;
HANDLE DbKey;
return FALSE;
if (!SdbGUIDToString(pguidDB, GuidBuffer, RTL_NUMBER_OF(GuidBuffer)))
{
SHIM_ERR("Unable to Convert GUID to string\n");
return FALSE;
}
RtlInitEmptyUnicodeString(&KeyName, KeyBuffer, sizeof(KeyBuffer));
RtlAppendUnicodeStringToString(&KeyName, &InstalledSDBKeyName);
RtlAppendUnicodeToString(&KeyName, L"\\");
RtlAppendUnicodeToString(&KeyName, GuidBuffer);
KeyAccess = Wow64QueryFlag() | DELETE;
Status = NtCreateKey(&DbKey, KeyAccess, &ObjectKey, 0, NULL, 0, NULL);
if (!NT_SUCCESS(Status))
{
SHIM_ERR("Unable to open %wZ\n", &KeyName);
return FALSE;
}
Status = NtDeleteKey(DbKey);
if (!NT_SUCCESS(Status))
SHIM_ERR("Unable to delete %wZ\n", &KeyName);
NtClose(DbKey);
return NT_SUCCESS(Status);
}

View File

@ -2,7 +2,7 @@
* PROJECT: ReactOS Application compatibility module
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Registry layer manipulation functions
* COPYRIGHT: Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
* COPYRIGHT: Copyright 2015-2019 Mark Jansen (mark.jansen@reactos.org)
*/
#define WIN32_NO_STATUS
@ -176,7 +176,7 @@ BOOL SdbpResolvePath(PSDB_TMP_STR LongPath, PCWSTR wszPath)
}
static ACCESS_MASK g_QueryFlag = 0xffffffff;
ACCESS_MASK QueryFlag(void)
ACCESS_MASK Wow64QueryFlag(void)
{
if (g_QueryFlag == 0xffffffff)
{
@ -216,7 +216,7 @@ NTSTATUS SdbpOpenKey(PUNICODE_STRING FullPath, BOOL bMachine, ACCESS_MASK Access
RtlFreeUnicodeString(&BasePath);
RtlAppendUnicodeToString(FullPath, LayersKey);
Status = NtOpenKey(KeyHandle, Access | QueryFlag(), &ObjectLayer);
Status = NtOpenKey(KeyHandle, Access | Wow64QueryFlag(), &ObjectLayer);
if (!NT_SUCCESS(Status))
{
SHIM_ERR("Unable to open Key \"%wZ\" Status 0x%lx\n", FullPath, Status);