[BLUE] Improve initialization and interfacing with INBV.

CORE-15901

This fixes display reset transition when an external module acquired
INBV ownership and then released it, similarly to what was done in
commit 0ad65796 for VIDEOPRT.

For this a backup screenbuffer is used to store the contents of the
screen just before an INBV screen acquire transition, and these contents
are restored when it is detected that INBV ownership has been released.
Also, the active text font associated with the active console code-page
is restored, as well as the cursor state and shape.

In addition, any user of BLUE.SYS is now required to explicitly issue
a new IOCTL_CONSOLE_RESET_SCREEN to either enable or disable the screen.
This allows avoiding nasty unwanted screen mode switches when a handle
to the \Device\BlueScreen device is opened but no screen mode switch was
actually wanted - This "fixes" this annoyance on ReactOS and Windows,
when these are running witha VGA-compatible video driver and one wants
to look at properties of the \Device\BlueScreen device using
Sysinternals' WinObj.

Following this, we don't need to check anymore for explicit INBV
ownership by issuing calls to InbvCheckDisplayOwnership(), but instead
we check whether the screen has beeen manually enabled using the
aforementioned IOCTL. This partly supersedes commit 8b553a4b, and allows
fixing the second bug, namely that if we start ReactOS without the
/NOGUIBOOT option (and thus, INBV is active during boot), USETUP would
not show up anything because BLUE.SYS wouldn't display anything on screen.
See CORE-15901.

[USETUP][CONSRV] Call IOCTL_CONSOLE_RESET_SCREEN to tell BlueScreen device to enable the screen.
This commit is contained in:
Hermès Bélusca-Maïto 2019-12-15 03:37:52 +01:00
parent 67c9e81cb0
commit bfd8a84865
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 604 additions and 193 deletions

View file

@ -47,11 +47,12 @@ BOOL
WINAPI
AllocConsole(VOID)
{
NTSTATUS Status;
UNICODE_STRING ScreenName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ULONG Enable;
/* Open the screen */
InitializeObjectAttributes(&ObjectAttributes,
@ -68,6 +69,24 @@ AllocConsole(VOID)
if (!NT_SUCCESS(Status))
return FALSE;
/* Enable it */
Enable = TRUE;
Status = NtDeviceIoControlFile(StdOutput,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_CONSOLE_RESET_SCREEN,
&Enable,
sizeof(Enable),
NULL,
0);
if (!NT_SUCCESS(Status))
{
NtClose(StdOutput);
return FALSE;
}
/* Open the keyboard */
InitializeObjectAttributes(&ObjectAttributes,
&KeyboardName,
@ -81,7 +100,10 @@ AllocConsole(VOID)
FILE_OPEN,
0);
if (!NT_SUCCESS(Status))
{
NtClose(StdOutput);
return FALSE;
}
/* Reset the queue state */
InputQueueEmpty = TRUE;

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,8 @@
#ifndef _NTDDBLUE_H_INCLUDED_
#define _NTDDBLUE_H_INCLUDED_
#define IOCTL_CONSOLE_RESET_SCREEN CTL_CODE(FILE_DEVICE_SCREEN, 0x800, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_SCREEN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_SCREEN, 0x802, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_CONSOLE_GET_CURSOR_INFO CTL_CODE(FILE_DEVICE_SCREEN, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS)

View file

@ -375,7 +375,7 @@ TuiConsoleThread(PVOID Param)
static BOOL
TuiInit(DWORD OemCP)
{
BOOL Ret = FALSE;
BOOL Success;
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned;
WNDCLASSEXW wc;
@ -388,6 +388,7 @@ TuiInit(DWORD OemCP)
/*
* Initialize the TUI front-end:
* - load the console driver,
* - open BlueScreen device and enable it,
* - set default screen attributes,
* - grab the console size.
*/
@ -404,6 +405,16 @@ TuiInit(DWORD OemCP)
return FALSE;
}
Success = TRUE;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_RESET_SCREEN,
&Success, sizeof(Success), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to enable the screen.\n");
CloseHandle(ConsoleDeviceHandle);
return FALSE;
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
&OemCP, sizeof(OemCP), NULL, 0,
&BytesReturned, NULL))
@ -416,7 +427,7 @@ TuiInit(DWORD OemCP)
&TextAttribute, sizeof(TextAttribute), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to set text attribute\n");
DPRINT1("Failed to set text attribute.\n");
}
ActiveConsole = NULL;
@ -426,8 +437,8 @@ TuiInit(DWORD OemCP)
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
{
DPRINT1("Failed to get console info\n");
Ret = FALSE;
DPRINT1("Failed to get console info.\n");
Success = FALSE;
goto Quit;
}
PhysicalConsoleSize = ScrInfo.dwSize;
@ -443,23 +454,23 @@ TuiInit(DWORD OemCP)
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
{
DPRINT1("Failed to register TUI console wndproc\n");
Ret = FALSE;
DPRINT1("Failed to register TUI console wndproc.\n");
Success = FALSE;
}
else
{
Ret = TRUE;
Success = TRUE;
}
Quit:
if (!Ret)
if (!Success)
{
DeleteCriticalSection(&ActiveVirtConsLock);
CloseHandle(ConsoleDeviceHandle);
}
ConsInitialized = Ret;
return Ret;
ConsInitialized = Success;
return Success;
}