https://git.reactos.org/?p=reactos.git;a=commitdiff;h=18a51dc7f5f66108fc8050...
commit 18a51dc7f5f66108fc8050e604debaa53ab587cb Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Tue Dec 24 13:51:20 2019 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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);