https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bfd8a84865b7571e5e6c9…
commit bfd8a84865b7571e5e6c949b654830373651da59
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Dec 15 03:37:52 2019 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Dec 15 03:37:52 2019 +0100
[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.
---
base/setup/usetup/console.c | 24 +-
drivers/setup/blue/blue.c | 720 ++++++++++++++++-----
sdk/include/reactos/drivers/blue/ntddblue.h | 2 +
win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c | 31 +-
4 files changed, 594 insertions(+), 183 deletions(-)
diff --git a/base/setup/usetup/console.c b/base/setup/usetup/console.c
index ec73f382216..6e647d8bfde 100644
--- a/base/setup/usetup/console.c
+++ b/base/setup/usetup/console.c
@@ -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;
diff --git a/drivers/setup/blue/blue.c b/drivers/setup/blue/blue.c
index 56a115fffd4..e9accab60e8 100644
--- a/drivers/setup/blue/blue.c
+++ b/drivers/setup/blue/blue.c
@@ -5,6 +5,7 @@
* COPYRIGHT: Copyright 1999 Boudewijn Dekker
* Copyright 1999-2019 Eric Kohl
* Copyright 2006 Filip Navara
+ * Copyright 2019 Hermes Belusca-Maito
*/
/* INCLUDES ******************************************************************/
@@ -25,6 +26,10 @@
typedef struct _DEVICE_EXTENSION
{
PUCHAR VideoMemory; /* Pointer to video memory */
+ SIZE_T VideoMemorySize;
+ BOOLEAN Enabled;
+ PUCHAR ScreenBuffer; /* Pointer to screenbuffer */
+ SIZE_T ScreenBufferSize;
ULONG CursorSize;
INT CursorVisible;
USHORT CharAttribute;
@@ -32,6 +37,8 @@ typedef struct _DEVICE_EXTENSION
UCHAR ScanLines; /* Height of a text line */
USHORT Rows; /* Number of rows */
USHORT Columns; /* Number of columns */
+ USHORT CursorX, CursorY; /* Cursor position */
+ ULONG CodePage; /* Specifies the font associated to this code page */
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _VGA_REGISTERS
@@ -79,6 +86,218 @@ static const UCHAR DefaultPalette[] =
0xFF, 0xFF, 0xFF
};
+/* INBV MANAGEMENT FUNCTIONS **************************************************/
+
+static BOOLEAN
+ScrResetScreen(
+ _In_ PDEVICE_EXTENSION DeviceExtension,
+ _In_ BOOLEAN FullReset,
+ _In_ BOOLEAN Enable);
+
+static PDEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
+static HANDLE InbvThreadHandle = NULL;
+static BOOLEAN InbvMonitoring = FALSE;
+
+/*
+ * Reinitialize the display to base VGA mode.
+ *
+ * Returns TRUE if it completely resets the adapter to the given character mode.
+ * Returns FALSE otherwise, indicating that the HAL should perform the VGA mode
+ * reset itself after HwVidResetHw() returns control.
+ *
+ * This callback has been registered with InbvNotifyDisplayOwnershipLost()
+ * and is called by InbvAcquireDisplayOwnership(), typically when the bugcheck
+ * code regains display access. Therefore this routine can be called at any
+ * IRQL, and in particular at IRQL = HIGH_LEVEL. This routine must also reside
+ * completely in non-paged pool, and cannot perform the following actions:
+ * Allocate memory, access pageable memory, use any synchronization mechanisms
+ * or call any routine that must execute at IRQL = DISPATCH_LEVEL or below.
+ */
+static BOOLEAN
+NTAPI
+ScrResetDisplayParametersEx(
+ _In_ ULONG Columns,
+ _In_ ULONG Rows,
+ _In_ BOOLEAN CalledByInbv)
+{
+ PDEVICE_EXTENSION DeviceExtension;
+
+ /* Bail out early if we don't have any resettable adapter */
+ if (!ResetDisplayParametersDeviceExtension)
+ return FALSE; // No adapter found: request HAL to perform a full reset.
+
+ /*
+ * If we have been unexpectedly called via a callback from
+ * InbvAcquireDisplayOwnership(), start monitoring INBV.
+ */
+ if (CalledByInbv)
+ InbvMonitoring = TRUE;
+
+ DeviceExtension = ResetDisplayParametersDeviceExtension;
+ ASSERT(DeviceExtension);
+
+ /* Disable the screen but don't reset all screen settings (OK at high IRQL) */
+ return ScrResetScreen(DeviceExtension, FALSE, FALSE);
+}
+
+/* This callback is registered with InbvNotifyDisplayOwnershipLost() */
+static BOOLEAN
+NTAPI
+ScrResetDisplayParameters(
+ _In_ ULONG Columns,
+ _In_ ULONG Rows)
+{
+ /* Call the extended function, specifying we were called by INBV */
+ return ScrResetDisplayParametersEx(Columns, Rows, TRUE);
+}
+
+/*
+ * (Adapted for ReactOS/Win2k3 from an original comment
+ * by Gé van Geldorp, June 2003, r4937)
+ *
+ * DISPLAY OWNERSHIP
+ *
+ * So, who owns the physical display and is allowed to write to it?
+ *
+ * In NT 5.x (Win2k/Win2k3), upon boot INBV/BootVid owns the display, unless
+ * /NOGUIBOOT has been specified in the boot command line. Later in the boot
+ * sequence, WIN32K.SYS opens the DISPLAY device. This open call ends up in
+ * VIDEOPRT.SYS. This component takes ownership of the display by calling
+ * InbvNotifyDisplayOwnershipLost() -- effectively telling INBV to release
+ * ownership of the display it previously had. From that moment on, the display
+ * is owned by that component and can be switched to graphics mode. The display
+ * is not supposed to return to text mode, except in case of a bugcheck.
+ * The bugcheck code calls InbvAcquireDisplayOwnership() so as to make INBV
+ * re-take display ownership, and calls back the function previously registered
+ * by VIDEOPRT.SYS with InbvNotifyDisplayOwnershipLost(). After the bugcheck,
+ * execution is halted. So, under NT, the only possible sequence of display
+ * modes is text mode -> graphics mode -> text mode (the latter hopefully
+ * happening very infrequently).
+ *
+ * In ReactOS things are a little bit different. We want to have a functional
+ * interactive text mode. We should be able to switch back and forth from
+ * text mode to graphics mode when a GUI app is started and then finished.
+ * Also, when the system bugchecks in graphics mode we want to switch back to
+ * text mode and show the bugcheck information. Last but not least, when using
+ * KDBG in /DEBUGPORT=SCREEN mode, breaking into the debugger would trigger a
+ * switch to text mode, and the user would expect that by continuing execution
+ * a switch back to graphics mode is done.
+ */
+static VOID
+NTAPI
+InbvMonitorThread(
+ _In_ PVOID Context)
+{
+ LARGE_INTEGER Delay;
+ USHORT i;
+
+ KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
+
+ while (TRUE)
+ {
+ /*
+ * During one second, check the INBV status each 100 milliseconds,
+ * then revert to 1 second delay.
+ */
+ i = 10;
+ Delay.QuadPart = (LONGLONG)-100*1000*10; // 100 millisecond delay
+ while (!InbvMonitoring)
+ {
+ KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+
+ if ((i > 0) && (--i == 0))
+ Delay.QuadPart = (LONGLONG)-1*1000*1000*10; // 1 second delay
+ }
+
+ /*
+ * Loop while the display is owned by INBV. We cannot do anything else
+ * than polling since INBV does not offer a proper notification system.
+ *
+ * During one second, check the INBV status each 100 milliseconds,
+ * then revert to 1 second delay.
+ */
+ i = 10;
+ Delay.QuadPart = (LONGLONG)-100*1000*10; // 100 millisecond delay
+ while (InbvCheckDisplayOwnership())
+ {
+ KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+
+ if ((i > 0) && (--i == 0))
+ Delay.QuadPart = (LONGLONG)-1*1000*1000*10; // 1 second delay
+ }
+
+ /* Reset the monitoring */
+ InbvMonitoring = FALSE;
+
+ /*
+ * Somebody released INBV display ownership, usually by invoking
+ * InbvNotifyDisplayOwnershipLost(). However the caller of this
+ * function certainly specified a different callback than ours.
+ * As we are going to be the only owner of the active display,
+ * we need to re-register our own display reset callback.
+ */
+ InbvNotifyDisplayOwnershipLost(ScrResetDisplayParameters);
+
+ /* Re-enable the screen, keeping the original screen settings */
+ if (ResetDisplayParametersDeviceExtension)
+ ScrResetScreen(ResetDisplayParametersDeviceExtension, FALSE, TRUE);
+ }
+
+ // FIXME: See ScrInbvCleanup().
+ // PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+static NTSTATUS
+ScrInbvInitialize(VOID)
+{
+ /* Create the INBV monitoring thread if needed */
+ if (!InbvThreadHandle)
+ {
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(NULL,
OBJ_KERNEL_HANDLE);
+
+ Status = PsCreateSystemThread(&InbvThreadHandle,
+ 0,
+ &ObjectAttributes,
+ NULL,
+ NULL,
+ InbvMonitorThread,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ InbvThreadHandle = NULL;
+ }
+
+ /* Re-register the display reset callback with INBV */
+ InbvNotifyDisplayOwnershipLost(ScrResetDisplayParameters);
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+ScrInbvCleanup(VOID)
+{
+ // HANDLE ThreadHandle;
+
+ // ResetDisplayParametersDeviceExtension = NULL;
+ InbvNotifyDisplayOwnershipLost(NULL);
+ ScrResetDisplayParametersEx(80, 50, FALSE);
+ // or InbvAcquireDisplayOwnership(); ?
+
+#if 0
+ // TODO: Find the best way to communicate the request.
+ /* Signal the INBV monitoring thread and wait for it to terminate */
+ ThreadHandle = InterlockedExchangePointer((PVOID*)&InbvThreadHandle, NULL);
+ if (ThreadHandle)
+ {
+ KeWaitForSingleObject(&ThreadHandle, Executive, KernelMode, FALSE, NULL);
+ /* Close its handle */
+ ObCloseHandle(ThreadHandle, KernelMode);
+ }
+#endif
+
+ return STATUS_SUCCESS;
+}
+
/* FUNCTIONS **************************************************************/
static VOID
@@ -135,15 +354,66 @@ ScrSetRegisters(const VGA_REGISTERS *Registers)
WRITE_PORT_UCHAR(PELMASK, 0xff);
}
+static VOID
+FASTCALL
+ScrSetCursor(
+ _In_ PDEVICE_EXTENSION DeviceExtension)
+{
+ ULONG Offset;
+
+ if (!DeviceExtension->VideoMemory)
+ return;
+
+ Offset = (DeviceExtension->CursorY * DeviceExtension->Columns) +
DeviceExtension->CursorX;
+
+ _disable();
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
+ WRITE_PORT_UCHAR(CRTC_DATA, Offset);
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
+ WRITE_PORT_UCHAR(CRTC_DATA, Offset >> 8);
+ _enable();
+}
+
+static VOID
+FASTCALL
+ScrSetCursorShape(
+ _In_ PDEVICE_EXTENSION DeviceExtension)
+{
+ ULONG size, height;
+ UCHAR data, value;
+
+ if (!DeviceExtension->VideoMemory)
+ return;
+
+ height = DeviceExtension->ScanLines;
+ data = (DeviceExtension->CursorVisible) ? 0x00 : 0x20;
+
+ size = (DeviceExtension->CursorSize * height) / 100;
+ if (size < 1)
+ size = 1;
+
+ data |= (UCHAR)(height - size);
+
+ _disable();
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORSTART);
+ WRITE_PORT_UCHAR(CRTC_DATA, data);
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSOREND);
+ value = READ_PORT_UCHAR(CRTC_DATA) & 0xE0;
+ WRITE_PORT_UCHAR(CRTC_DATA, value | (height - 1));
+ _enable();
+}
+
static VOID
FASTCALL
ScrAcquireOwnership(
_In_ PDEVICE_EXTENSION DeviceExtension)
{
- ULONG offset;
UCHAR data, value;
+ ULONG offset;
ULONG Index;
+ _disable();
+
ScrSetRegisters(&VidpMode3Regs);
/* Disable screen and enable palette access */
@@ -162,12 +432,6 @@ ScrAcquireOwnership(
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
- /* Get current output position */
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- offset = READ_PORT_UCHAR(CRTC_DATA);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- offset += (READ_PORT_UCHAR(CRTC_DATA) << 8);
-
/* Switch blinking characters off */
READ_PORT_UCHAR(ATTRC_INPST1);
value = READ_PORT_UCHAR(ATTRC_WRITEREG);
@@ -190,7 +454,14 @@ ScrAcquireOwnership(
WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_SCANLINES);
DeviceExtension->ScanLines = (READ_PORT_UCHAR(CRTC_DATA) & 0x1F) + 1;
+ /* Retrieve the current output cursor position */
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
+ offset = READ_PORT_UCHAR(CRTC_DATA);
+ WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
+ offset += (READ_PORT_UCHAR(CRTC_DATA) << 8);
+
/* Show blinking cursor */
+ // FIXME: cursor block? Call ScrSetCursorShape() instead?
WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORSTART);
WRITE_PORT_UCHAR(CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSOREND);
@@ -198,15 +469,19 @@ ScrAcquireOwnership(
WRITE_PORT_UCHAR(CRTC_DATA,
data | ((DeviceExtension->ScanLines - 1) & 0x1F));
+ _enable();
+
/* Calculate number of text rows */
- DeviceExtension->Rows =
- DeviceExtension->Rows / DeviceExtension->ScanLines;
-#ifdef BOCHS_30ROWS
- DeviceExtension->Rows = 30;
-#endif
+ DeviceExtension->Rows = DeviceExtension->Rows / DeviceExtension->ScanLines;
- /* Upload a default font for the default codepage 437 */
- ScrLoadFontTable(437);
+ /* Set the cursor position, clipping it to the screen */
+ DeviceExtension->CursorX = (USHORT)(offset % DeviceExtension->Columns);
+ DeviceExtension->CursorY = (USHORT)(offset / DeviceExtension->Columns);
+ // DeviceExtension->CursorX = min(max(DeviceExtension->CursorX, 0),
DeviceExtension->Columns - 1);
+ DeviceExtension->CursorY = min(max(DeviceExtension->CursorY, 0),
DeviceExtension->Rows - 1);
+
+ /* Upload a default font for the current codepage */
+ ScrLoadFontTable(DeviceExtension->CodePage);
DPRINT("%d Columns %d Rows %d Scanlines\n",
DeviceExtension->Columns,
@@ -214,51 +489,183 @@ ScrAcquireOwnership(
DeviceExtension->ScanLines);
}
-static DRIVER_DISPATCH ScrCreate;
-static NTSTATUS
-NTAPI
-ScrCreate(
- _In_ PDEVICE_OBJECT DeviceObject,
- _In_ PIRP Irp)
+static BOOLEAN
+ScrResetScreen(
+ _In_ PDEVICE_EXTENSION DeviceExtension,
+ _In_ BOOLEAN FullReset,
+ _In_ BOOLEAN Enable)
{
#define FOREGROUND_LIGHTGRAY (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
- PDEVICE_EXTENSION DeviceExtension;
PHYSICAL_ADDRESS BaseAddress;
- NTSTATUS Status;
- DeviceExtension = DeviceObject->DeviceExtension;
+ /* Allow resets to the same state only for full resets */
+ if (!FullReset && (Enable == DeviceExtension->Enabled))
+ return FALSE; // STATUS_INVALID_PARAMETER; STATUS_INVALID_DEVICE_REQUEST;
+
+ if (FullReset)
+ {
+ DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
+ DeviceExtension->CursorVisible = TRUE;
+
+ /* More initialization */
+ DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
+ DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
+ ENABLE_WRAP_AT_EOL_OUTPUT;
+ DeviceExtension->CodePage = 437; /* Use default codepage */
+ }
- if (!InbvCheckDisplayOwnership())
+ if (Enable)
{
ScrAcquireOwnership(DeviceExtension);
- /* Get a pointer to the video memory */
- BaseAddress.QuadPart = VIDMEM_BASE;
- DeviceExtension->VideoMemory =
- (PUCHAR)MmMapIoSpace(BaseAddress, DeviceExtension->Rows *
DeviceExtension->Columns * 2, MmNonCached);
+ if (FullReset)
+ {
+ /*
+ * Fully reset the screen and all its settings.
+ */
+
+ /* Unmap any previously mapped video memory */
+ if (DeviceExtension->VideoMemory)
+ {
+ ASSERT(DeviceExtension->VideoMemorySize != 0);
+ MmUnmapIoSpace(DeviceExtension->VideoMemory,
DeviceExtension->VideoMemorySize);
+ }
+ DeviceExtension->VideoMemory = NULL;
+ DeviceExtension->VideoMemorySize = 0;
+
+ /* Free any previously allocated backup screenbuffer */
+ if (DeviceExtension->ScreenBuffer)
+ {
+ ASSERT(DeviceExtension->ScreenBufferSize != 0);
+ ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
+ }
+ DeviceExtension->ScreenBuffer = NULL;
+ DeviceExtension->ScreenBufferSize = 0;
+
+ /* Get a pointer to the video memory */
+ DeviceExtension->VideoMemorySize = DeviceExtension->Rows *
DeviceExtension->Columns * 2;
+ if (DeviceExtension->VideoMemorySize == 0)
+ return FALSE; // STATUS_INVALID_VIEW_SIZE; STATUS_MAPPED_FILE_SIZE_ZERO;
+
+ /* Map the video memory */
+ BaseAddress.QuadPart = VIDMEM_BASE;
+ DeviceExtension->VideoMemory =
+ (PUCHAR)MmMapIoSpace(BaseAddress, DeviceExtension->VideoMemorySize,
MmNonCached);
+ if (!DeviceExtension->VideoMemory)
+ {
+ DeviceExtension->VideoMemorySize = 0;
+ return FALSE; // STATUS_NONE_MAPPED; STATUS_NOT_MAPPED_VIEW;
STATUS_CONFLICTING_ADDRESSES;
+ }
+
+ /* Initialize the backup screenbuffer in non-paged pool (must be accessible
at high IRQL) */
+ DeviceExtension->ScreenBufferSize = DeviceExtension->VideoMemorySize;
+ DeviceExtension->ScreenBuffer =
+ (PUCHAR)ExAllocatePoolWithTag(NonPagedPool,
DeviceExtension->ScreenBufferSize, TAG_BLUE);
+ if (!DeviceExtension->ScreenBuffer)
+ {
+ DPRINT1("Could not allocate screenbuffer, ignore...\n");
+ DeviceExtension->ScreenBufferSize = 0;
+ }
+
+ /* (Re-)initialize INBV */
+ ScrInbvInitialize();
+ }
+ else
+ {
+ /*
+ * Restore the previously disabled screen.
+ */
+
+ /* Restore the snapshot of the video memory from the backup screenbuffer */
+ if (DeviceExtension->ScreenBuffer)
+ {
+ ASSERT(DeviceExtension->VideoMemory);
+ ASSERT(DeviceExtension->ScreenBuffer);
+ ASSERT(DeviceExtension->ScreenBufferSize != 0);
+ ASSERT(DeviceExtension->VideoMemorySize ==
DeviceExtension->ScreenBufferSize);
+
+ RtlCopyMemory(DeviceExtension->VideoMemory,
+ DeviceExtension->ScreenBuffer,
+ DeviceExtension->VideoMemorySize);
+ }
+
+ /* Restore the cursor state */
+ ScrSetCursor(DeviceExtension);
+ ScrSetCursorShape(DeviceExtension);
+ }
+ DeviceExtension->Enabled = TRUE;
}
else
{
- /* Store dummy values */
- DeviceExtension->Columns = 1;
- DeviceExtension->Rows = 1;
- DeviceExtension->ScanLines = 1;
- }
+ DeviceExtension->Enabled = FALSE;
+ if (FullReset)
+ {
+ /*
+ * Fully disable the screen and reset all its settings.
+ */
- DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
- DeviceExtension->CursorVisible = TRUE;
+ /* Clean INBV up */
+ ScrInbvCleanup();
- /* More initialization */
- DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
- DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
- ENABLE_WRAP_AT_EOL_OUTPUT;
+ /* Unmap any previously mapped video memory */
+ if (DeviceExtension->VideoMemory)
+ {
+ ASSERT(DeviceExtension->VideoMemorySize != 0);
+ MmUnmapIoSpace(DeviceExtension->VideoMemory,
DeviceExtension->VideoMemorySize);
+ }
+ DeviceExtension->VideoMemory = NULL;
+ DeviceExtension->VideoMemorySize = 0;
- Status = STATUS_SUCCESS;
+ /* Free any previously allocated backup screenbuffer */
+ if (DeviceExtension->ScreenBuffer)
+ {
+ ASSERT(DeviceExtension->ScreenBufferSize != 0);
+ ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
+ }
+ DeviceExtension->ScreenBuffer = NULL;
+ DeviceExtension->ScreenBufferSize = 0;
- Irp->IoStatus.Status = Status;
+ /* Store dummy values */
+ DeviceExtension->Columns = 1;
+ DeviceExtension->Rows = 1;
+ DeviceExtension->ScanLines = 1;
+ }
+ else
+ {
+ /*
+ * Partially disable the screen such that it can be restored later.
+ */
+
+ /* Take a snapshot of the video memory into the backup screenbuffer */
+ if (DeviceExtension->ScreenBuffer)
+ {
+ ASSERT(DeviceExtension->VideoMemory);
+ ASSERT(DeviceExtension->ScreenBuffer);
+ ASSERT(DeviceExtension->ScreenBufferSize != 0);
+ ASSERT(DeviceExtension->VideoMemorySize ==
DeviceExtension->ScreenBufferSize);
+
+ RtlCopyMemory(DeviceExtension->ScreenBuffer,
+ DeviceExtension->VideoMemory,
+ DeviceExtension->VideoMemorySize);
+ }
+ }
+ }
+
+ return TRUE; // STATUS_SUCCESS;
+}
+
+static DRIVER_DISPATCH ScrCreate;
+static NTSTATUS
+NTAPI
+ScrCreate(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp)
+{
+ // Irp->IoStatus.Information = FILE_OPENED;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ return STATUS_SUCCESS;
}
static DRIVER_DISPATCH ScrWrite;
@@ -268,9 +675,9 @@ ScrWrite(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp)
{
+ NTSTATUS Status;
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- NTSTATUS Status;
PCHAR pch = Irp->UserBuffer;
PUCHAR vidmem;
ULONG i;
@@ -279,9 +686,9 @@ ScrWrite(
USHORT rows, columns;
BOOLEAN processed = !!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT);
- if (InbvCheckDisplayOwnership())
+ if (!DeviceExtension->Enabled || !DeviceExtension->VideoMemory)
{
- /* Display is in graphics mode, we're not allowed to touch it */
+ /* Display is not enabled, we're not allowed to touch it */
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
@@ -293,24 +700,26 @@ ScrWrite(
vidmem = DeviceExtension->VideoMemory;
rows = DeviceExtension->Rows;
columns = DeviceExtension->Columns;
+ cursorx = DeviceExtension->CursorX;
+ cursory = DeviceExtension->CursorY;
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- offset = READ_PORT_UCHAR(CRTC_DATA)<<8;
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- offset += READ_PORT_UCHAR(CRTC_DATA);
- _enable();
-
- cursory = (USHORT)(offset / columns);
- cursorx = (USHORT)(offset % columns);
if (!processed)
{
/* Raw output mode */
+
+ /* Calculate the offset from the cursor position */
+ offset = cursorx + cursory * columns;
+
// FIXME: Does the buffer only contains chars? or chars + attributes?
// FIXME2: Fix buffer overflow.
- RtlCopyMemory(&vidmem[(cursorx * 2) + (cursory * columns * 2)],
- pch, stk->Parameters.Write.Length);
+ RtlCopyMemory(&vidmem[offset * 2], pch, stk->Parameters.Write.Length);
offset += (stk->Parameters.Write.Length / 2);
+
+ /* Set the cursor position, clipping it to the screen */
+ cursorx = (USHORT)(offset % columns);
+ cursory = (USHORT)(offset / columns);
+ // cursorx = min(max(cursorx, 0), columns - 1);
+ cursory = min(max(cursory, 0), rows - 1);
}
else
{
@@ -327,19 +736,18 @@ ScrWrite(
}
else if (cursory > 0)
{
- cursorx = columns - 1;
cursory--;
+ cursorx = columns - 1;
}
- vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
- vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] =
(char)DeviceExtension->CharAttribute;
+ offset = cursorx + cursory * columns;
+ vidmem[offset * 2] = ' ';
+ vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
break;
}
case '\n':
cursory++;
- cursorx = 0;
- break;
-
+ /* Fall back */
case '\r':
cursorx = 0;
break;
@@ -347,15 +755,16 @@ ScrWrite(
case '\t':
{
offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
- for (j = 0; j < offset; j++)
+ while (offset--)
{
- vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
+ vidmem[(cursorx + cursory * columns) * 2] = ' ';
cursorx++;
-
if (cursorx >= columns)
{
- cursory++;
cursorx = 0;
+ cursory++;
+ /* We jumped to the next line, stop there */
+ break;
}
}
break;
@@ -363,13 +772,14 @@ ScrWrite(
default:
{
- vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
- vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] =
(char)DeviceExtension->CharAttribute;
+ offset = cursorx + cursory * columns;
+ vidmem[offset * 2] = *pch;
+ vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
cursorx++;
if (cursorx >= columns)
{
- cursory++;
cursorx = 0;
+ cursory++;
}
break;
}
@@ -393,22 +803,20 @@ ScrWrite(
cursory = rows - 1;
for (j = 0; j < columns; j++)
{
- vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
- vidmem[(j * 2) + (cursory * columns * 2) + 1] =
(char)DeviceExtension->CharAttribute;
+ offset = j + cursory * columns;
+ vidmem[offset * 2] = ' ';
+ vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
}
}
}
-
- /* Set the cursor position */
- offset = (cursory * columns) + cursorx;
}
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- WRITE_PORT_UCHAR(CRTC_DATA, offset);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- offset >>= 8;
- WRITE_PORT_UCHAR(CRTC_DATA, offset);
- _enable();
+
+ /* Set the cursor position */
+ ASSERT((0 <= cursorx) && (cursorx < DeviceExtension->Columns));
+ ASSERT((0 <= cursory) && (cursory < DeviceExtension->Rows));
+ DeviceExtension->CursorX = cursorx;
+ DeviceExtension->CursorY = cursory;
+ ScrSetCursor(DeviceExtension);
Status = STATUS_SUCCESS;
@@ -432,33 +840,29 @@ ScrIoControl(
DeviceExtension = DeviceObject->DeviceExtension;
switch (stk->Parameters.DeviceIoControl.IoControlCode)
{
+ case IOCTL_CONSOLE_RESET_SCREEN:
+ {
+ BOOLEAN Enable = !!*(PULONG)Irp->AssociatedIrp.SystemBuffer;
+
+ /* Fully enable or disable the screen */
+ Status = (ScrResetScreen(DeviceExtension, TRUE, Enable)
+ ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
{
PCONSOLE_SCREEN_BUFFER_INFO pcsbi =
(PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
USHORT rows = DeviceExtension->Rows;
USHORT columns = DeviceExtension->Columns;
- ULONG offset;
-
- if (!InbvCheckDisplayOwnership())
- {
- /* read cursor position from crtc */
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- offset = READ_PORT_UCHAR(CRTC_DATA);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- offset += (READ_PORT_UCHAR(CRTC_DATA) << 8);
- _enable();
- }
- else
- {
- offset = 0;
- }
pcsbi->dwSize.X = columns;
pcsbi->dwSize.Y = rows;
- pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
- pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
+ pcsbi->dwCursorPosition.X = DeviceExtension->CursorX;
+ pcsbi->dwCursorPosition.Y = DeviceExtension->CursorY;
pcsbi->wAttributes = DeviceExtension->CharAttribute;
@@ -478,7 +882,6 @@ ScrIoControl(
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
{
PCONSOLE_SCREEN_BUFFER_INFO pcsbi =
(PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
- ULONG Offset;
if ( pcsbi->dwCursorPosition.X < 0 || pcsbi->dwCursorPosition.X
>= DeviceExtension->Columns ||
pcsbi->dwCursorPosition.Y < 0 || pcsbi->dwCursorPosition.Y
>= DeviceExtension->Rows )
@@ -490,18 +893,13 @@ ScrIoControl(
DeviceExtension->CharAttribute = pcsbi->wAttributes;
- Offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
- pcsbi->dwCursorPosition.X;
-
- if (!InbvCheckDisplayOwnership())
- {
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- WRITE_PORT_UCHAR(CRTC_DATA, Offset);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- WRITE_PORT_UCHAR(CRTC_DATA, Offset >> 8);
- _enable();
- }
+ /* Set the cursor position */
+ ASSERT((0 <= pcsbi->dwCursorPosition.X) &&
(pcsbi->dwCursorPosition.X < DeviceExtension->Columns));
+ ASSERT((0 <= pcsbi->dwCursorPosition.Y) &&
(pcsbi->dwCursorPosition.Y < DeviceExtension->Rows));
+ DeviceExtension->CursorX = pcsbi->dwCursorPosition.X;
+ DeviceExtension->CursorY = pcsbi->dwCursorPosition.Y;
+ if (DeviceExtension->Enabled)
+ ScrSetCursor(DeviceExtension);
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
@@ -523,31 +921,11 @@ ScrIoControl(
case IOCTL_CONSOLE_SET_CURSOR_INFO:
{
PCONSOLE_CURSOR_INFO pcci =
(PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
- UCHAR data, value;
- ULONG size, height;
DeviceExtension->CursorSize = pcci->dwSize;
DeviceExtension->CursorVisible = pcci->bVisible;
-
- if (!InbvCheckDisplayOwnership())
- {
- height = DeviceExtension->ScanLines;
- data = (pcci->bVisible) ? 0x00 : 0x20;
-
- size = (pcci->dwSize * height) / 100;
- if (size < 1)
- size = 1;
-
- data |= (UCHAR)(height - size);
-
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORSTART);
- WRITE_PORT_UCHAR(CRTC_DATA, data);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSOREND);
- value = READ_PORT_UCHAR(CRTC_DATA) & 0xE0;
- WRITE_PORT_UCHAR(CRTC_DATA, value | (height - 1));
- _enable();
- }
+ if (DeviceExtension->Enabled)
+ ScrSetCursorShape(DeviceExtension);
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
@@ -580,7 +958,7 @@ ScrIoControl(
{
POUTPUT_ATTRIBUTE Buf =
(POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength = Buf->nLength;
@@ -593,11 +971,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
- (Buf->dwCoord.X * 2) + 1;
+ offset = (Buf->dwCoord.X + Buf->dwCoord.Y *
DeviceExtension->Columns) * 2 + 1;
nMaxLength = min(nMaxLength,
(DeviceExtension->Rows - Buf->dwCoord.Y)
@@ -621,7 +998,7 @@ ScrIoControl(
POUTPUT_ATTRIBUTE Buf =
(POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
PUSHORT pAttr = (PUSHORT)MmGetSystemAddressForMdl(Irp->MdlAddress);
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength;
@@ -634,11 +1011,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
- (Buf->dwCoord.X * 2) + 1;
+ offset = (Buf->dwCoord.X + Buf->dwCoord.Y *
DeviceExtension->Columns) * 2 + 1;
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
(DeviceExtension->Rows - Buf->dwCoord.Y)
@@ -666,7 +1042,7 @@ ScrIoControl(
PCOORD pCoord = (PCOORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
PCHAR pAttr = (PCHAR)(pCoord + 1);
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength;
@@ -678,11 +1054,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (pCoord->Y * DeviceExtension->Columns * 2) +
- (pCoord->X * 2) + 1;
+ offset = (pCoord->X + pCoord->Y * DeviceExtension->Columns) * 2
+ 1;
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength -
sizeof(COORD),
(DeviceExtension->Rows - pCoord->Y)
@@ -709,7 +1084,7 @@ ScrIoControl(
{
POUTPUT_CHARACTER Buf =
(POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength = Buf->nLength;
@@ -722,11 +1097,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
- (Buf->dwCoord.X * 2);
+ offset = (Buf->dwCoord.X + Buf->dwCoord.Y *
DeviceExtension->Columns) * 2;
nMaxLength = min(nMaxLength,
(DeviceExtension->Rows - Buf->dwCoord.Y)
@@ -750,7 +1124,7 @@ ScrIoControl(
POUTPUT_CHARACTER Buf =
(POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
PCHAR pChar = (PCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength;
@@ -763,11 +1137,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
- (Buf->dwCoord.X * 2);
+ offset = (Buf->dwCoord.X + Buf->dwCoord.Y *
DeviceExtension->Columns) * 2;
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
(DeviceExtension->Rows - Buf->dwCoord.Y)
@@ -795,7 +1168,7 @@ ScrIoControl(
PCOORD pCoord = (PCOORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
PCHAR pChar = (PCHAR)(pCoord + 1);
PUCHAR vidmem;
- int offset;
+ ULONG offset;
ULONG dwCount;
ULONG nMaxLength;
@@ -807,11 +1180,10 @@ ScrIoControl(
break;
}
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
vidmem = DeviceExtension->VideoMemory;
- offset = (pCoord->Y * DeviceExtension->Columns * 2) +
- (pCoord->X * 2);
+ offset = (pCoord->X + pCoord->Y * DeviceExtension->Columns) *
2;
nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength -
sizeof(COORD),
(DeviceExtension->Rows - pCoord->Y)
@@ -832,15 +1204,15 @@ ScrIoControl(
{
PCONSOLE_DRAW ConsoleDraw;
PUCHAR Src, Dest;
- UINT32 SrcDelta, DestDelta, i, Offset;
+ UINT32 SrcDelta, DestDelta, i;
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
ConsoleDraw = (PCONSOLE_DRAW)
MmGetSystemAddressForMdl(Irp->MdlAddress);
Src = (PUCHAR) (ConsoleDraw + 1);
SrcDelta = ConsoleDraw->SizeX * 2;
Dest = DeviceExtension->VideoMemory +
- (ConsoleDraw->Y * DeviceExtension->Columns +
ConsoleDraw->X) * 2;
+ (ConsoleDraw->X + ConsoleDraw->Y *
DeviceExtension->Columns) * 2;
DestDelta = DeviceExtension->Columns * 2;
for (i = 0; i < ConsoleDraw->SizeY; i++)
@@ -849,18 +1221,14 @@ ScrIoControl(
Src += SrcDelta;
Dest += DestDelta;
}
-
- Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
- ConsoleDraw->CursorX;
-
- _disable();
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSLO);
- WRITE_PORT_UCHAR(CRTC_DATA, Offset);
- WRITE_PORT_UCHAR(CRTC_COMMAND, CRTC_CURSORPOSHI);
- WRITE_PORT_UCHAR(CRTC_DATA, Offset >> 8);
- _enable();
}
+ /* Set the cursor position, clipping it to the screen */
+ DeviceExtension->CursorX = min(max(ConsoleDraw->CursorX, 0),
DeviceExtension->Columns - 1);
+ DeviceExtension->CursorY = min(max(ConsoleDraw->CursorY, 0),
DeviceExtension->Rows - 1);
+ if (DeviceExtension->Enabled)
+ ScrSetCursor(DeviceExtension);
+
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
@@ -869,8 +1237,9 @@ ScrIoControl(
case IOCTL_CONSOLE_LOADFONT:
{
ULONG CodePage = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
+ DeviceExtension->CodePage = CodePage;
- if (!InbvCheckDisplayOwnership())
+ if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
{
/* Upload a font for the codepage if needed */
ScrLoadFontTable(CodePage);
@@ -953,9 +1322,16 @@ DriverEntry(
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
if (NT_SUCCESS(Status))
+ {
+ /* By default disable the screen */
+ ResetDisplayParametersDeviceExtension = DeviceObject->DeviceExtension;
+ ScrResetScreen(DeviceObject->DeviceExtension, TRUE, FALSE);
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
else
+ {
IoDeleteDevice(DeviceObject);
+ }
return Status;
}
diff --git a/sdk/include/reactos/drivers/blue/ntddblue.h
b/sdk/include/reactos/drivers/blue/ntddblue.h
index 50ef34d2365..5c6df7bfff7 100644
--- a/sdk/include/reactos/drivers/blue/ntddblue.h
+++ b/sdk/include/reactos/drivers/blue/ntddblue.h
@@ -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)
diff --git a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
index e66203ad7b8..e4874b10df6 100644
--- a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
+++ b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
@@ -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;
}