https://git.reactos.org/?p=reactos.git;a=commitdiff;h=18a51dc7f5f66108fc805…
commit 18a51dc7f5f66108fc8050e604debaa53ab587cb
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Dec 24 13:51:20 2019 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Dec 24 13:51:20 2019 +0100
[VIDEOPRT][WIN32K] Use a Windows-compatible way of communicating the
'BaseVideo' state from VIDEOPRT to WIN32K.
This is done by creating the volatile key
\Registry\Machine\System\CurrentControlSet\Control\GraphicsDrivers\BaseVideo .
Also cache during first initialization of VIDEOPRT the state of the boot
options BASEVIDEO and NOVESA, so that they can be readily retrieved later
(for example, in VideoPortIsNoVesa()).
---
win32ss/drivers/videoprt/registry.c | 3 +-
win32ss/drivers/videoprt/videoprt.c | 222 +++++++++++++++++++++---------------
win32ss/user/ntuser/display.c | 23 +---
3 files changed, 137 insertions(+), 111 deletions(-)
diff --git a/win32ss/drivers/videoprt/registry.c b/win32ss/drivers/videoprt/registry.c
index 1527fb6cc8c..362c251d21a 100644
--- a/win32ss/drivers/videoprt/registry.c
+++ b/win32ss/drivers/videoprt/registry.c
@@ -20,7 +20,6 @@
*/
#include "videoprt.h"
-
#include <ndk/obfuncs.h>
#define NDEBUG
@@ -122,7 +121,7 @@ IntCopyRegistryKey(
&ObjectAttributes,
0,
NULL,
- 0,
+ REG_OPTION_NON_VOLATILE,
NULL);
if (!NT_SUCCESS(Status))
{
diff --git a/win32ss/drivers/videoprt/videoprt.c b/win32ss/drivers/videoprt/videoprt.c
index b4207309e93..0c80c7fbfb4 100644
--- a/win32ss/drivers/videoprt/videoprt.c
+++ b/win32ss/drivers/videoprt/videoprt.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <ndk/exfuncs.h>
+#include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h>
#define NDEBUG
@@ -30,6 +31,9 @@
/* GLOBAL VARIABLES ***********************************************************/
+BOOLEAN VpBaseVideo = FALSE;
+BOOLEAN VpNoVesa = FALSE;
+
PKPROCESS CsrProcess = NULL;
ULONG VideoPortDeviceNumber = 0;
KMUTEX VideoPortInt10Mutex;
@@ -455,6 +459,125 @@ IntDetachFromCSRSS(
}
}
+VOID
+FASTCALL
+IntLoadRegistryParameters(VOID)
+{
+ NTSTATUS Status;
+ HANDLE KeyHandle;
+ UNICODE_STRING Path =
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control");
+ UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SystemStartOptions");
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+ ULONG Length, NewLength;
+
+ /* Initialize object attributes with the path we want */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Path,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Open the key */
+ Status = ZwOpenKey(&KeyHandle,
+ KEY_QUERY_VALUE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ VideoPortDebugPrint(Error, "ZwOpenKey failed (0x%x)\n", Status);
+ return;
+ }
+
+ /* Find out how large our buffer should be */
+ Status = ZwQueryValueKey(KeyHandle,
+ &ValueName,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &Length);
+ if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ VideoPortDebugPrint(Error, "ZwQueryValueKey failed (0x%x)\n", Status);
+ ObCloseHandle(KeyHandle, KernelMode);
+ return;
+ }
+
+ /* Allocate it */
+ KeyInfo = ExAllocatePoolWithTag(PagedPool, Length, TAG_VIDEO_PORT);
+ if (!KeyInfo)
+ {
+ VideoPortDebugPrint(Error, "Out of memory\n");
+ ObCloseHandle(KeyHandle, KernelMode);
+ return;
+ }
+
+ /* Now for real this time */
+ Status = ZwQueryValueKey(KeyHandle,
+ &ValueName,
+ KeyValuePartialInformation,
+ KeyInfo,
+ Length,
+ &NewLength);
+ ObCloseHandle(KeyHandle, KernelMode);
+
+ if (!NT_SUCCESS(Status))
+ {
+ VideoPortDebugPrint(Error, "ZwQueryValueKey failed (0x%x)\n", Status);
+ ExFreePoolWithTag(KeyInfo, TAG_VIDEO_PORT);
+ return;
+ }
+
+ /* Sanity check */
+ if (KeyInfo->Type != REG_SZ)
+ {
+ VideoPortDebugPrint(Error, "Invalid type for SystemStartOptions\n");
+ ExFreePoolWithTag(KeyInfo, TAG_VIDEO_PORT);
+ return;
+ }
+
+ /* Check if BASEVIDEO or NOVESA is present in the start options */
+ if (wcsstr((PWCHAR)KeyInfo->Data, L"BASEVIDEO"))
+ VpBaseVideo = TRUE;
+ if (wcsstr((PWCHAR)KeyInfo->Data, L"NOVESA"))
+ VpNoVesa = TRUE;
+
+ ExFreePoolWithTag(KeyInfo, TAG_VIDEO_PORT);
+
+ /* FIXME: Old ReactOS-compatibility... */
+ if (VpBaseVideo) VpNoVesa = TRUE;
+
+ if (VpNoVesa)
+ VideoPortDebugPrint(Info, "VESA mode disabled\n");
+ else
+ VideoPortDebugPrint(Info, "VESA mode enabled\n");
+
+ /* If we are in BASEVIDEO, create the volatile registry key for Win32k */
+ if (VpBaseVideo)
+ {
+ RtlInitUnicodeString(&Path,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\BaseVideo");
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Path,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ Status = ZwCreateKey(&KeyHandle,
+ KEY_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ if (NT_SUCCESS(Status))
+ ObCloseHandle(KeyHandle, KernelMode);
+ else
+ ERR_(VIDEOPRT, "Failed to create the BaseVideo key (0x%x)\n",
Status);
+ }
+
+ return;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
@@ -479,9 +602,10 @@ VideoPortInitialize(
if (!FirstInitialization)
{
+ FirstInitialization = TRUE;
KeInitializeMutex(&VideoPortInt10Mutex, 0);
KeInitializeSpinLock(&HwResetAdaptersLock);
- FirstInitialization = TRUE;
+ IntLoadRegistryParameters();
}
/* As a first thing do parameter checks. */
@@ -1344,7 +1468,8 @@ VideoPortAcquireDeviceLock(
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
- (void)Status;
+
+ UNREFERENCED_LOCAL_VARIABLE(Status);
TRACE_(VIDEOPRT, "VideoPortAcquireDeviceLock\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
@@ -1363,7 +1488,8 @@ VideoPortReleaseDeviceLock(
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
LONG Status;
- (void)Status;
+
+ UNREFERENCED_LOCAL_VARIABLE(Status);
TRACE_(VIDEOPRT, "VideoPortReleaseDeviceLock\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
@@ -1394,7 +1520,6 @@ VideoPortAllocateContiguousMemory(
IN PHYSICAL_ADDRESS HighestAcceptableAddress
)
{
-
return MmAllocateContiguousMemory(NumberOfBytes, HighestAcceptableAddress);
}
@@ -1405,92 +1530,5 @@ BOOLEAN
NTAPI
VideoPortIsNoVesa(VOID)
{
- NTSTATUS Status;
- HANDLE KeyHandle;
- UNICODE_STRING Path =
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control");
- UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SystemStartOptions");
- OBJECT_ATTRIBUTES ObjectAttributes;
- PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
- ULONG Length, NewLength;
-
- /* Initialize object attributes with the path we want */
- InitializeObjectAttributes(&ObjectAttributes,
- &Path,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
-
- /* Open the key */
- Status = ZwOpenKey(&KeyHandle,
- KEY_QUERY_VALUE,
- &ObjectAttributes);
-
- if (!NT_SUCCESS(Status))
- {
- VideoPortDebugPrint(Error, "ZwOpenKey failed (0x%x)\n", Status);
- return FALSE;
- }
-
- /* Find out how large our buffer should be */
- Status = ZwQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Length);
- if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL)
- {
- VideoPortDebugPrint(Error, "ZwQueryValueKey failed (0x%x)\n", Status);
- ZwClose(KeyHandle);
- return FALSE;
- }
-
- /* Allocate it */
- KeyInfo = ExAllocatePool(PagedPool, Length);
- if (!KeyInfo)
- {
- VideoPortDebugPrint(Error, "Out of memory\n");
- ZwClose(KeyHandle);
- return FALSE;
- }
-
- /* Now for real this time */
- Status = ZwQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- KeyInfo,
- Length,
- &NewLength);
-
- ZwClose(KeyHandle);
-
- if (!NT_SUCCESS(Status))
- {
- VideoPortDebugPrint(Error, "ZwQueryValueKey failed (0x%x)\n", Status);
- ExFreePool(KeyInfo);
- return FALSE;
- }
-
- /* Sanity check */
- if (KeyInfo->Type != REG_SZ)
- {
- VideoPortDebugPrint(Error, "Invalid type for SystemStartOptions\n");
- ExFreePool(KeyInfo);
- return FALSE;
- }
-
- /* Check if NOVESA or BASEVIDEO is present in the start options */
- if (wcsstr((PWCHAR)KeyInfo->Data, L"NOVESA") ||
- wcsstr((PWCHAR)KeyInfo->Data, L"BASEVIDEO"))
- {
- VideoPortDebugPrint(Info, "VESA mode disabled\n");
- ExFreePool(KeyInfo);
- return TRUE;
- }
-
- ExFreePool(KeyInfo);
-
- VideoPortDebugPrint(Info, "VESA mode enabled\n");
-
- return FALSE;
+ return VpNoVesa;
}
diff --git a/win32ss/user/ntuser/display.c b/win32ss/user/ntuser/display.c
index be0335c52da..a23d19590d3 100644
--- a/win32ss/user/ntuser/display.c
+++ b/win32ss/user/ntuser/display.c
@@ -9,7 +9,7 @@
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserDisplay);
-BOOL gbBaseVideo = 0;
+BOOL gbBaseVideo = FALSE;
static PPROCESSINFO gpFullscreen = NULL;
static const PWCHAR KEY_VIDEO =
L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
@@ -165,24 +165,13 @@ InitVideo(VOID)
TRACE("----------------------------- InitVideo()
-------------------------------\n");
- /* Open the key for the boot command line */
- Status =
RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control",
&hkey);
+ /* Check if VGA mode is requested, by finding the special volatile key created by
VIDEOPRT */
+ Status =
RegOpenKey(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\BaseVideo",
&hkey);
if (NT_SUCCESS(Status))
- {
- cbValue = sizeof(awcBuffer);
- Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer,
&cbValue);
- if (NT_SUCCESS(Status))
- {
- /* Check if VGA mode is requested. */
- if (wcsstr(awcBuffer, L"BASEVIDEO") != 0)
- {
- ERR("VGA mode requested.\n");
- gbBaseVideo = TRUE;
- }
- }
-
ZwClose(hkey);
- }
+ gbBaseVideo = NT_SUCCESS(Status);
+ if (gbBaseVideo)
+ ERR("VGA mode requested.\n");
/* Open the key for the adapters */
Status = RegOpenKey(KEY_VIDEO, &hkey);