[BASESRV]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Thu, 27 Feb 2014 22:44:56 +0000 (22:44 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Thu, 27 Feb 2014 22:44:56 +0000 (22:44 +0000)
Implement BaseSrvIsVdmAllowed.

svn path=/branches/ntvdm/; revision=62349

subsystems/win/basesrv/basesrv.h
subsystems/win/basesrv/vdm.c
subsystems/win/basesrv/vdm.h

index 66e4efc..881156d 100644 (file)
@@ -22,6 +22,7 @@
 #include <ndk/psfuncs.h>
 #include <ndk/exfuncs.h>
 #include <ndk/umfuncs.h>
+#include <ndk/cmfuncs.h>
 
 /* PSEH for SEH Support */
 #include <pseh/pseh2.h>
index d9cab1c..3760cfc 100644 (file)
@@ -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,
index 5467841..f12be84 100644 (file)
@@ -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;