https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d49004352fd3927e94db4…
commit d49004352fd3927e94db440ea0a61185f45eab4e
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sat Jan 13 21:32:48 2018 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Mon Apr 9 19:36:09 2018 +0200
[NTDLL] Check the process manifest at startup for a compatibility section.
---
dll/appcompat/apphelp/hsdb.c | 12 +++--
dll/ntdll/ldr/ldrinit.c | 86 +++++++++++++++++++++++++++++++++-
sdk/include/reactos/compat_undoc.h | 43 +++++++++++++++++
sdk/include/reactos/compatguid_undoc.h | 12 +++++
sdk/lib/uuid/undoc.c | 1 +
5 files changed, 149 insertions(+), 5 deletions(-)
diff --git a/dll/appcompat/apphelp/hsdb.c b/dll/appcompat/apphelp/hsdb.c
index 903968d0d6..6c23ec6fa3 100644
--- a/dll/appcompat/apphelp/hsdb.c
+++ b/dll/appcompat/apphelp/hsdb.c
@@ -12,7 +12,7 @@
#include "ntndk.h"
#include "strsafe.h"
#include "apphelp.h"
-
+#include "compat_undoc.h"
#define MAX_LAYER_LENGTH 256
#define GPLK_USER 1
@@ -25,12 +25,18 @@ typedef struct _ShimData
DWORD dwMagic;
SDBQUERYRESULT Query;
WCHAR szLayer[MAX_LAYER_LENGTH];
- DWORD unknown; // 0x14c
+ DWORD dwRosProcessCompatVersion; // ReactOS specific
} ShimData;
#define SHIMDATA_MAGIC 0xAC0DEDAB
+C_ASSERT(SHIMDATA_MAGIC == REACTOS_SHIMDATA_MAGIC);
+C_ASSERT(sizeof(ShimData) == sizeof(ReactOS_ShimData));
+C_ASSERT(offsetof(ShimData, dwMagic) == offsetof(ReactOS_ShimData, dwMagic));
+C_ASSERT(offsetof(ShimData, dwRosProcessCompatVersion) == offsetof(ReactOS_ShimData,
dwRosProcessCompatVersion));
+
+
static BOOL WINAPI SdbpFileExists(LPCWSTR path)
{
DWORD attr = GetFileAttributesW(path);
@@ -706,7 +712,7 @@ BOOL WINAPI SdbPackAppCompatData(HSDB hsdb, PSDBQUERYRESULT
pQueryResult, PVOID*
pData->dwSize = sizeof(*pData);
pData->dwMagic = SHIMDATA_MAGIC;
pData->Query = *pQueryResult;
- pData->unknown = 0;
+ pData->dwRosProcessCompatVersion = 0;
pData->szLayer[0] = UNICODE_NULL; /* TODO */
SHIM_INFO("\ndwFlags 0x%x\ndwMagic 0x%x\ntrExe 0x%x\ntrLayer
0x%x\n",
diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c
index f62b93ef65..b35321e8c6 100644
--- a/dll/ntdll/ldr/ldrinit.c
+++ b/dll/ntdll/ldr/ldrinit.c
@@ -10,6 +10,8 @@
/* INCLUDES *****************************************************************/
#include <ntdll.h>
+#include <compat_undoc.h>
+#include <compatguid_undoc.h>
#define NDEBUG
#include <debug.h>
@@ -1455,6 +1457,83 @@ LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
UNIMPLEMENTED;
}
+VOID
+NTAPI
+LdrpInitializeProcessCompat(PVOID* pOldShimData)
+{
+ static const GUID* GuidOrder[] = { &COMPAT_GUID_WIN10, &COMPAT_GUID_WIN81,
&COMPAT_GUID_WIN8,
+ &COMPAT_GUID_WIN7, &COMPAT_GUID_VISTA };
+ static const DWORD GuidVersions[] = { WINVER_WIN10, WINVER_WIN81, WINVER_WIN8,
WINVER_WIN7, WINVER_VISTA };
+
+ ULONG Buffer[(sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 10 +
sizeof(ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION)) / sizeof(ULONG)];
+ ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION* ContextCompatInfo;
+ SIZE_T SizeRequired;
+ NTSTATUS Status;
+ DWORD n, cur;
+
+ C_ASSERT(RTL_NUMBER_OF(GuidOrder) == RTL_NUMBER_OF(GuidVersions));
+
+ SizeRequired = sizeof(Buffer);
+ Status =
RtlQueryInformationActivationContext(RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF,
+ NULL,
+ NULL,
+
CompatibilityInformationInActivationContext,
+ Buffer,
+ sizeof(Buffer),
+ &SizeRequired);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("LdrpInitializeProcessCompat: Unable to query process actctx with
status %x\n", Status);
+ return;
+ }
+
+ ContextCompatInfo = (ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION*)Buffer;
+ /* No Compatibility elements present, bail out */
+ if (ContextCompatInfo->ElementCount == 0)
+ return;
+
+ /* Search for known GUID's, starting from newest to oldest. */
+ for (cur = 0; cur < RTL_NUMBER_OF(GuidOrder); ++cur)
+ {
+ for (n = 0; n < ContextCompatInfo->ElementCount; ++n)
+ {
+ if (ContextCompatInfo->Elements[n].Type ==
ACTCX_COMPATIBILITY_ELEMENT_TYPE_OS &&
+ RtlCompareMemory(&ContextCompatInfo->Elements[n].Id,
GuidOrder[cur], sizeof(GUID)) == sizeof(GUID))
+ {
+ ReactOS_ShimData* pShimData = *pOldShimData;
+
+ /* If this process did not need shim data before, allocate and store it
*/
+ if (pShimData == NULL)
+ {
+ PPEB Peb = NtCurrentPeb();
+
+ ASSERT(Peb->pShimData == NULL);
+ pShimData = RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY,
sizeof(*pShimData));
+
+ if (!pShimData)
+ {
+ DPRINT1("LdrpInitializeProcessCompat: Unable to allocated %u
bytes\n", sizeof(*pShimData));
+ return;
+ }
+
+ pShimData->dwSize = sizeof(*pShimData);
+ pShimData->dwMagic = REACTOS_SHIMDATA_MAGIC;
+
+ Peb->pShimData = pShimData;
+ *pOldShimData = pShimData;
+ }
+
+ /* Store the highest found version, and bail out. */
+ pShimData->dwRosProcessCompatVersion = GuidVersions[cur];
+ DPRINT1("LdrpInitializeProcessCompat: Found guid for winver
0x%x\n", GuidVersions[cur]);
+ return;
+ }
+ }
+ }
+}
+
+
NTSTATUS
NTAPI
LdrpInitializeProcess(IN PCONTEXT Context,
@@ -1542,8 +1621,8 @@ LdrpInitializeProcess(IN PCONTEXT Context,
/* Save the old Shim Data */
OldShimData = Peb->pShimData;
- /* Clear it */
- Peb->pShimData = NULL;
+ /* ReactOS specific: do not clear it. (Windows starts doing the same in later
versions) */
+ //Peb->pShimData = NULL;
/* Save the number of processors and CS Timeout */
LdrpNumberOfProcessors = Peb->NumberOfProcessors;
@@ -1934,6 +2013,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
/* Initialize Wine's active context implementation for the current process */
actctx_init();
+ /* ReactOS specific */
+ LdrpInitializeProcessCompat(&OldShimData);
+
/* Set the current directory */
Status = RtlSetCurrentDirectory_U(&CurrentDirectory);
if (!NT_SUCCESS(Status))
diff --git a/sdk/include/reactos/compat_undoc.h b/sdk/include/reactos/compat_undoc.h
new file mode 100644
index 0000000000..fc6a04794d
--- /dev/null
+++ b/sdk/include/reactos/compat_undoc.h
@@ -0,0 +1,43 @@
+#ifndef COMPAT_UNDOC_H
+#define COMPAT_UNDOC_H
+
+
+typedef struct _ReactOS_ShimData
+{
+ DWORD dwReserved1[130];
+ DWORD dwSize;
+ DWORD dwMagic;
+ DWORD dwReserved2[242];
+ DWORD dwRosProcessCompatVersion;
+} ReactOS_ShimData;
+
+
+#define REACTOS_SHIMDATA_MAGIC 0xAC0DEDAB
+
+#ifndef WINVER_VISTA
+#define WINVER_VISTA 0x0600
+#define WINVER_WIN7 0x0601
+#define WINVER_WIN8 0x0602
+#define WINVER_WIN81 0x0603
+#define WINVER_WIN10 0x0a00
+#endif
+
+static
+inline
+DWORD RosGetProcessCompatVersion(VOID)
+{
+ static DWORD g_CompatVersion = 0xffffffff;
+ if (g_CompatVersion == 0xffffffff)
+ {
+ ReactOS_ShimData* pShimData = (ReactOS_ShimData*)NtCurrentPeb()->pShimData;
+ if (pShimData && pShimData->dwMagic == REACTOS_SHIMDATA_MAGIC
&&
+ pShimData->dwSize == sizeof(ReactOS_ShimData))
+ {
+ g_CompatVersion = pShimData->dwRosProcessCompatVersion;
+ }
+ }
+ return g_CompatVersion != 0xffffffff ? g_CompatVersion : 0;
+}
+
+
+#endif // COMPAT_UNDOC_H
diff --git a/sdk/include/reactos/compatguid_undoc.h
b/sdk/include/reactos/compatguid_undoc.h
new file mode 100644
index 0000000000..be4206aa94
--- /dev/null
+++ b/sdk/include/reactos/compatguid_undoc.h
@@ -0,0 +1,12 @@
+#ifndef COMPATGUID_UNDOC_H
+#define COMPATGUID_UNDOC_H
+
+
+DEFINE_GUID(COMPAT_GUID_VISTA, 0xe2011457, 0x1546, 0x43c5, 0xa5, 0xfe, 0x00, 0x8d, 0xee,
0xe3, 0xd3, 0xf0);
+DEFINE_GUID(COMPAT_GUID_WIN7, 0x35138b9a, 0x5d96, 0x4fbd, 0x8e, 0x2d, 0xa2, 0x44, 0x02,
0x25, 0xf9, 0x3a);
+DEFINE_GUID(COMPAT_GUID_WIN8, 0x4a2f28e3, 0x53b9, 0x4441, 0xba, 0x9c, 0xd6, 0x9d, 0x4a,
0x4a, 0x6e, 0x38);
+DEFINE_GUID(COMPAT_GUID_WIN81, 0x1f676c76, 0x80e1, 0x4239, 0x95, 0xbb, 0x83, 0xd0, 0xf6,
0xd0, 0xda, 0x78);
+DEFINE_GUID(COMPAT_GUID_WIN10, 0x8e0f7a12, 0xbfb3, 0x4fe8, 0xb9, 0xa5, 0x48, 0xfd, 0x50,
0xa1, 0x5a, 0x9a);
+
+
+#endif // COMPATGUID_UNDOC_H
diff --git a/sdk/lib/uuid/undoc.c b/sdk/lib/uuid/undoc.c
index 5e3fab4653..8768a3a2ff 100644
--- a/sdk/lib/uuid/undoc.c
+++ b/sdk/lib/uuid/undoc.c
@@ -5,4 +5,5 @@
#include <guiddef.h>
#include <shlguid_undoc.h>
+#include <compatguid_undoc.h>