https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c01fa8e9c13de66f4b167…
commit c01fa8e9c13de66f4b167e024fe4837a02cb5a67
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Mon Feb 11 22:45:48 2019 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Mon Feb 25 20:00:35 2019 +0100
[APPHELP] Implement SdbRegisterDatabase[Ex]
CORE-11301
---
dll/appcompat/apphelp/apphelp.c | 195 +++++++++++++++++++++++++++++++++++-----
dll/appcompat/apphelp/layer.c | 6 +-
2 files changed, 174 insertions(+), 27 deletions(-)
diff --git a/dll/appcompat/apphelp/apphelp.c b/dll/appcompat/apphelp/apphelp.c
index ceb71a8e16..e05c1fd9eb 100644
--- a/dll/appcompat/apphelp/apphelp.c
+++ b/dll/appcompat/apphelp/apphelp.c
@@ -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;
+
+ 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;
- return FALSE;
+ 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;
+
+ 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);
- return FALSE;
+ NtClose(DbKey);
+ return NT_SUCCESS(Status);
}
diff --git a/dll/appcompat/apphelp/layer.c b/dll/appcompat/apphelp/layer.c
index 36f9e86ae8..9c35c3f19f 100644
--- a/dll/appcompat/apphelp/layer.c
+++ b/dll/appcompat/apphelp/layer.c
@@ -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(a)reactos.org)
+ * COPYRIGHT: Copyright 2015-2019 Mark Jansen (mark.jansen(a)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);