From bde24e0bb45085a5d5110c0333eeaeb15b2ed0e3 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Thu, 27 Feb 2014 22:44:56 +0000 Subject: [PATCH] [BASESRV] Implement BaseSrvIsVdmAllowed. svn path=/branches/ntvdm/; revision=62349 --- subsystems/win/basesrv/basesrv.h | 1 + subsystems/win/basesrv/vdm.c | 100 +++++++++++++++++++++++++++++++ subsystems/win/basesrv/vdm.h | 3 + 3 files changed, 104 insertions(+) diff --git a/subsystems/win/basesrv/basesrv.h b/subsystems/win/basesrv/basesrv.h index 66e4efcdcf4..881156d2a30 100644 --- a/subsystems/win/basesrv/basesrv.h +++ b/subsystems/win/basesrv/basesrv.h @@ -22,6 +22,7 @@ #include #include #include +#include /* PSEH for SEH Support */ #include diff --git a/subsystems/win/basesrv/vdm.c b/subsystems/win/basesrv/vdm.c index d9cab1ccfae..3760cfcf889 100644 --- a/subsystems/win/basesrv/vdm.c +++ b/subsystems/win/basesrv/vdm.c @@ -69,6 +69,103 @@ ULONG NTAPI GetNextDosSesId(VOID) return SessionId; } +BOOLEAN NTAPI BaseSrvIsVdmAllowed(VOID) +{ + NTSTATUS Status; + BOOLEAN VdmAllowed = TRUE; + HANDLE RootKey, KeyHandle; + UNICODE_STRING KeyName, ValueName, MachineKeyName; + OBJECT_ATTRIBUTES Attributes; + UCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)]; + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; + ULONG ActualSize; + + /* Initialize the unicode strings */ + RtlInitUnicodeString(&MachineKeyName, L"\\Registry\\Machine"); + RtlInitUnicodeString(&KeyName, VDM_POLICY_KEY_NAME); + RtlInitUnicodeString(&ValueName, VDM_DISALLOWED_VALUE_NAME); + + InitializeObjectAttributes(&Attributes, + &MachineKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the local machine key */ + Status = NtOpenKey(&RootKey, KEY_READ, &Attributes); + if (!NT_SUCCESS(Status)) return FALSE; + + InitializeObjectAttributes(&Attributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKey, + NULL); + + /* Open the policy key in the local machine hive, if it exists */ + if (NT_SUCCESS(NtOpenKey(&KeyHandle, KEY_READ, &Attributes))) + { + /* Read the value, if it's set */ + if (NT_SUCCESS(NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + ValueInfo, + sizeof(ValueBuffer), + &ActualSize))) + { + if (*((PULONG)ValueInfo->Data)) + { + /* The VDM has been disabled in the registry */ + VdmAllowed = FALSE; + } + } + + NtClose(KeyHandle); + } + + /* Close the local machine key */ + NtClose(RootKey); + + /* If it's disabled system-wide, there's no need to check the user key */ + if (!VdmAllowed) return FALSE; + + /* Open the current user key of the client */ + if (!CsrImpersonateClient(NULL)) return VdmAllowed; + Status = RtlOpenCurrentUser(KEY_READ, &RootKey); + CsrRevertToSelf(); + + /* If that fails, return the system-wide setting */ + if (!NT_SUCCESS(Status)) return VdmAllowed; + + InitializeObjectAttributes(&Attributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKey, + NULL); + + /* Open the policy key in the current user hive, if it exists */ + if (NT_SUCCESS(NtOpenKey(&KeyHandle, KEY_READ, &Attributes))) + { + /* Read the value, if it's set */ + if (NT_SUCCESS(NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + ValueInfo, + sizeof(ValueBuffer), + &ActualSize))) + { + if (*((PULONG)ValueInfo->Data)) + { + /* The VDM has been disabled in the registry */ + VdmAllowed = FALSE; + } + } + + NtClose(KeyHandle); + } + + return VdmAllowed; +} + VOID NTAPI BaseInitializeVDM(VOID) { /* Initialize the list head */ @@ -88,6 +185,9 @@ CSR_API(BaseSrvCheckVDM) PRTL_CRITICAL_SECTION CriticalSection = NULL; PVDM_CONSOLE_RECORD ConsoleRecord = NULL; + /* Don't do anything if the VDM has been disabled in the registry */ + if (!BaseSrvIsVdmAllowed()) return STATUS_ACCESS_DENIED; + /* Validate the message buffers */ if (!CsrValidateMessageBuffer(ApiMessage, (PVOID*)&CheckVdmRequest->CmdLine, diff --git a/subsystems/win/basesrv/vdm.h b/subsystems/win/basesrv/vdm.h index 5467841dd7e..f12be8458ea 100644 --- a/subsystems/win/basesrv/vdm.h +++ b/subsystems/win/basesrv/vdm.h @@ -13,6 +13,9 @@ /* DEFINITIONS ****************************************************************/ +#define VDM_POLICY_KEY_NAME L"Software\\Policies\\Microsoft\\Windows\\AppCompat" +#define VDM_DISALLOWED_VALUE_NAME L"VDMDisallowed" + typedef struct _VDM_CONSOLE_RECORD { LIST_ENTRY Entry; -- 2.17.1