mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 12:55:43 +00:00
[NTDLL] Check the process manifest at startup for a compatibility section.
This commit is contained in:
parent
e195199a51
commit
d49004352f
5 changed files with 149 additions and 5 deletions
|
@ -12,7 +12,7 @@
|
||||||
#include "ntndk.h"
|
#include "ntndk.h"
|
||||||
#include "strsafe.h"
|
#include "strsafe.h"
|
||||||
#include "apphelp.h"
|
#include "apphelp.h"
|
||||||
|
#include "compat_undoc.h"
|
||||||
|
|
||||||
#define MAX_LAYER_LENGTH 256
|
#define MAX_LAYER_LENGTH 256
|
||||||
#define GPLK_USER 1
|
#define GPLK_USER 1
|
||||||
|
@ -25,12 +25,18 @@ typedef struct _ShimData
|
||||||
DWORD dwMagic;
|
DWORD dwMagic;
|
||||||
SDBQUERYRESULT Query;
|
SDBQUERYRESULT Query;
|
||||||
WCHAR szLayer[MAX_LAYER_LENGTH];
|
WCHAR szLayer[MAX_LAYER_LENGTH];
|
||||||
DWORD unknown; // 0x14c
|
DWORD dwRosProcessCompatVersion; // ReactOS specific
|
||||||
} ShimData;
|
} ShimData;
|
||||||
|
|
||||||
#define SHIMDATA_MAGIC 0xAC0DEDAB
|
#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)
|
static BOOL WINAPI SdbpFileExists(LPCWSTR path)
|
||||||
{
|
{
|
||||||
DWORD attr = GetFileAttributesW(path);
|
DWORD attr = GetFileAttributesW(path);
|
||||||
|
@ -706,7 +712,7 @@ BOOL WINAPI SdbPackAppCompatData(HSDB hsdb, PSDBQUERYRESULT pQueryResult, PVOID*
|
||||||
pData->dwSize = sizeof(*pData);
|
pData->dwSize = sizeof(*pData);
|
||||||
pData->dwMagic = SHIMDATA_MAGIC;
|
pData->dwMagic = SHIMDATA_MAGIC;
|
||||||
pData->Query = *pQueryResult;
|
pData->Query = *pQueryResult;
|
||||||
pData->unknown = 0;
|
pData->dwRosProcessCompatVersion = 0;
|
||||||
pData->szLayer[0] = UNICODE_NULL; /* TODO */
|
pData->szLayer[0] = UNICODE_NULL; /* TODO */
|
||||||
|
|
||||||
SHIM_INFO("\ndwFlags 0x%x\ndwMagic 0x%x\ntrExe 0x%x\ntrLayer 0x%x\n",
|
SHIM_INFO("\ndwFlags 0x%x\ndwMagic 0x%x\ntrExe 0x%x\ntrLayer 0x%x\n",
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ntdll.h>
|
#include <ntdll.h>
|
||||||
|
#include <compat_undoc.h>
|
||||||
|
#include <compatguid_undoc.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -1455,6 +1457,83 @@ LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
|
||||||
UNIMPLEMENTED;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrpInitializeProcess(IN PCONTEXT Context,
|
LdrpInitializeProcess(IN PCONTEXT Context,
|
||||||
|
@ -1542,8 +1621,8 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||||
/* Save the old Shim Data */
|
/* Save the old Shim Data */
|
||||||
OldShimData = Peb->pShimData;
|
OldShimData = Peb->pShimData;
|
||||||
|
|
||||||
/* Clear it */
|
/* ReactOS specific: do not clear it. (Windows starts doing the same in later versions) */
|
||||||
Peb->pShimData = NULL;
|
//Peb->pShimData = NULL;
|
||||||
|
|
||||||
/* Save the number of processors and CS Timeout */
|
/* Save the number of processors and CS Timeout */
|
||||||
LdrpNumberOfProcessors = Peb->NumberOfProcessors;
|
LdrpNumberOfProcessors = Peb->NumberOfProcessors;
|
||||||
|
@ -1934,6 +2013,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||||
/* Initialize Wine's active context implementation for the current process */
|
/* Initialize Wine's active context implementation for the current process */
|
||||||
actctx_init();
|
actctx_init();
|
||||||
|
|
||||||
|
/* ReactOS specific */
|
||||||
|
LdrpInitializeProcessCompat(&OldShimData);
|
||||||
|
|
||||||
/* Set the current directory */
|
/* Set the current directory */
|
||||||
Status = RtlSetCurrentDirectory_U(&CurrentDirectory);
|
Status = RtlSetCurrentDirectory_U(&CurrentDirectory);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
43
sdk/include/reactos/compat_undoc.h
Normal file
43
sdk/include/reactos/compat_undoc.h
Normal file
|
@ -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
|
12
sdk/include/reactos/compatguid_undoc.h
Normal file
12
sdk/include/reactos/compatguid_undoc.h
Normal file
|
@ -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
|
|
@ -5,4 +5,5 @@
|
||||||
#include <guiddef.h>
|
#include <guiddef.h>
|
||||||
|
|
||||||
#include <shlguid_undoc.h>
|
#include <shlguid_undoc.h>
|
||||||
|
#include <compatguid_undoc.h>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue