ReactOS 0.4.16-dev-306-g647d351
blue.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Console Text-Mode Device Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Driver Management Functions.
5 * COPYRIGHT: Copyright 1999 Boudewijn Dekker
6 * Copyright 1999-2019 Eric Kohl
7 * Copyright 2006 Filip Navara
8 * Copyright 2019 Hermes Belusca-Maito
9 */
10
11/* INCLUDES ******************************************************************/
12
13#include "blue.h"
14#include <ndk/inbvfuncs.h>
15
16#define NDEBUG
17#include <debug.h>
18
19/* NOTES ******************************************************************/
20/*
21 * [[character][attribute]][[character][attribute]]....
22 */
23
24/* TYPEDEFS ***************************************************************/
25
26typedef struct _DEVICE_EXTENSION
27{
28 PUCHAR VideoMemory; /* Pointer to video memory */
31 PUCHAR ScreenBuffer; /* Pointer to screenbuffer */
37 UCHAR ScanLines; /* Height of a text line */
38 USHORT Rows; /* Number of rows */
39 USHORT Columns; /* Number of columns */
40 USHORT CursorX, CursorY; /* Cursor position */
41 PUCHAR FontBitfield; /* Specifies the font */
43
44typedef struct _VGA_REGISTERS
45{
52
54{
55 /* CRT Controller Registers */
56 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
57 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
58 /* Attribute Controller Registers */
59 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
60 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
61 /* Graphics Controller Registers */
62 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
63 /* Sequencer Registers */
64 {0x03, 0x00, 0x03, 0x00, 0x02},
65 /* Misc Output Register */
66 0x67
67};
68
69static const UCHAR DefaultPalette[] =
70{
71 0, 0, 0,
72 0, 0, 0xC0,
73 0, 0xC0, 0,
74 0, 0xC0, 0xC0,
75 0xC0, 0, 0,
76 0xC0, 0, 0xC0,
77 0xC0, 0xC0, 0,
78 0xC0, 0xC0, 0xC0,
79 0x80, 0x80, 0x80,
80 0, 0, 0xFF,
81 0, 0xFF, 0,
82 0, 0xFF, 0xFF,
83 0xFF, 0, 0,
84 0xFF, 0, 0xFF,
85 0xFF, 0xFF, 0,
86 0xFF, 0xFF, 0xFF
87};
88
89/* INBV MANAGEMENT FUNCTIONS **************************************************/
90
91static BOOLEAN
93 _In_ PDEVICE_EXTENSION DeviceExtension,
94 _In_ BOOLEAN FullReset,
96
100
101/*
102 * Reinitialize the display to base VGA mode.
103 *
104 * Returns TRUE if it completely resets the adapter to the given character mode.
105 * Returns FALSE otherwise, indicating that the HAL should perform the VGA mode
106 * reset itself after HwVidResetHw() returns control.
107 *
108 * This callback has been registered with InbvNotifyDisplayOwnershipLost()
109 * and is called by InbvAcquireDisplayOwnership(), typically when the bugcheck
110 * code regains display access. Therefore this routine can be called at any
111 * IRQL, and in particular at IRQL = HIGH_LEVEL. This routine must also reside
112 * completely in non-paged pool, and cannot perform the following actions:
113 * Allocate memory, access pageable memory, use any synchronization mechanisms
114 * or call any routine that must execute at IRQL = DISPATCH_LEVEL or below.
115 */
116static BOOLEAN
117NTAPI
121 _In_ BOOLEAN CalledByInbv)
122{
123 PDEVICE_EXTENSION DeviceExtension;
124
125 /* Bail out early if we don't have any resettable adapter */
127 return FALSE; // No adapter found: request HAL to perform a full reset.
128
129 /*
130 * If we have been unexpectedly called via a callback from
131 * InbvAcquireDisplayOwnership(), start monitoring INBV.
132 */
133 if (CalledByInbv)
135
137 ASSERT(DeviceExtension);
138
139 /* Disable the screen but don't reset all screen settings (OK at high IRQL) */
140 return ScrResetScreen(DeviceExtension, FALSE, FALSE);
141}
142
143/* This callback is registered with InbvNotifyDisplayOwnershipLost() */
144static BOOLEAN
145NTAPI
149{
150 /* Call the extended function, specifying we were called by INBV */
152}
153
154/*
155 * (Adapted for ReactOS/Win2k3 from an original comment
156 * by Gé van Geldorp, June 2003, r4937)
157 *
158 * DISPLAY OWNERSHIP
159 *
160 * So, who owns the physical display and is allowed to write to it?
161 *
162 * In NT 5.x (Win2k/Win2k3), upon boot INBV/BootVid owns the display, unless
163 * /NOGUIBOOT has been specified in the boot command line. Later in the boot
164 * sequence, WIN32K.SYS opens the DISPLAY device. This open call ends up in
165 * VIDEOPRT.SYS. This component takes ownership of the display by calling
166 * InbvNotifyDisplayOwnershipLost() -- effectively telling INBV to release
167 * ownership of the display it previously had. From that moment on, the display
168 * is owned by that component and can be switched to graphics mode. The display
169 * is not supposed to return to text mode, except in case of a bugcheck.
170 * The bugcheck code calls InbvAcquireDisplayOwnership() so as to make INBV
171 * re-take display ownership, and calls back the function previously registered
172 * by VIDEOPRT.SYS with InbvNotifyDisplayOwnershipLost(). After the bugcheck,
173 * execution is halted. So, under NT, the only possible sequence of display
174 * modes is text mode -> graphics mode -> text mode (the latter hopefully
175 * happening very infrequently).
176 *
177 * In ReactOS things are a little bit different. We want to have a functional
178 * interactive text mode. We should be able to switch back and forth from
179 * text mode to graphics mode when a GUI app is started and then finished.
180 * Also, when the system bugchecks in graphics mode we want to switch back to
181 * text mode and show the bugcheck information. Last but not least, when using
182 * KDBG in /DEBUGPORT=SCREEN mode, breaking into the debugger would trigger a
183 * switch to text mode, and the user would expect that by continuing execution
184 * a switch back to graphics mode is done.
185 */
186static VOID
187NTAPI
190{
191 LARGE_INTEGER Delay;
192 USHORT i;
193
195
196 while (TRUE)
197 {
198 /*
199 * During one second, check the INBV status each 100 milliseconds,
200 * then revert to 1 second delay.
201 */
202 i = 10;
203 Delay.QuadPart = (LONGLONG)-100*1000*10; // 100 millisecond delay
204 while (!InbvMonitoring)
205 {
207
208 if ((i > 0) && (--i == 0))
209 Delay.QuadPart = (LONGLONG)-1*1000*1000*10; // 1 second delay
210 }
211
212 /*
213 * Loop while the display is owned by INBV. We cannot do anything else
214 * than polling since INBV does not offer a proper notification system.
215 *
216 * During one second, check the INBV status each 100 milliseconds,
217 * then revert to 1 second delay.
218 */
219 i = 10;
220 Delay.QuadPart = (LONGLONG)-100*1000*10; // 100 millisecond delay
222 {
224
225 if ((i > 0) && (--i == 0))
226 Delay.QuadPart = (LONGLONG)-1*1000*1000*10; // 1 second delay
227 }
228
229 /* Reset the monitoring */
231
232 /*
233 * Somebody released INBV display ownership, usually by invoking
234 * InbvNotifyDisplayOwnershipLost(). However the caller of this
235 * function certainly specified a different callback than ours.
236 * As we are going to be the only owner of the active display,
237 * we need to re-register our own display reset callback.
238 */
240
241 /* Re-enable the screen, keeping the original screen settings */
244 }
245
246 // FIXME: See ScrInbvCleanup().
247 // PsTerminateSystemThread(STATUS_SUCCESS);
248}
249
250static NTSTATUS
252{
253 /* Create the INBV monitoring thread if needed */
254 if (!InbvThreadHandle)
255 {
258
260 0,
262 NULL,
263 NULL,
265 NULL);
266 if (!NT_SUCCESS(Status))
268 }
269
270 /* Re-register the display reset callback with INBV */
272
273 return STATUS_SUCCESS;
274}
275
276static NTSTATUS
278{
279 // HANDLE ThreadHandle;
280
281 // ResetDisplayParametersDeviceExtension = NULL;
283 {
286 // or InbvAcquireDisplayOwnership(); ?
287 }
288
289#if 0
290 // TODO: Find the best way to communicate the request.
291 /* Signal the INBV monitoring thread and wait for it to terminate */
293 if (ThreadHandle)
294 {
295 ZwWaitForSingleObject(ThreadHandle, Executive, KernelMode, FALSE, NULL);
296 /* Close its handle */
297 ObCloseHandle(ThreadHandle, KernelMode);
298 }
299#endif
300
301 return STATUS_SUCCESS;
302}
303
304/* FUNCTIONS **************************************************************/
305
306static VOID
309{
310 UINT32 i;
311
312 /* Update misc output register */
313 WRITE_PORT_UCHAR(MISC, Registers->Misc);
314
315 /* Synchronous reset on */
316 WRITE_PORT_UCHAR(SEQ, 0x00);
318
319 /* Write sequencer registers */
320 for (i = 1; i < sizeof(Registers->Sequencer); i++)
321 {
323 WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]);
324 }
325
326 /* Synchronous reset off */
327 WRITE_PORT_UCHAR(SEQ, 0x00);
329
330 /* Deprotect CRT registers 0-7 */
331 WRITE_PORT_UCHAR(CRTC, 0x11);
332 WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f);
333
334 /* Write CRT registers */
335 for (i = 0; i < sizeof(Registers->CRT); i++)
336 {
338 WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]);
339 }
340
341 /* Write graphics controller registers */
342 for (i = 0; i < sizeof(Registers->Graphics); i++)
343 {
346 }
347
348 /* Write attribute controller registers */
349 for (i = 0; i < sizeof(Registers->Attribute); i++)
350 {
353 WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]);
354 }
355
356 /* Set the PEL mask */
358}
359
360static VOID
363 _In_ PDEVICE_EXTENSION DeviceExtension)
364{
366
367 if (!DeviceExtension->VideoMemory)
368 return;
369
370 Offset = (DeviceExtension->CursorY * DeviceExtension->Columns) + DeviceExtension->CursorX;
371
372 _disable();
377 _enable();
378}
379
380static VOID
383 _In_ PDEVICE_EXTENSION DeviceExtension)
384{
387
388 if (!DeviceExtension->VideoMemory)
389 return;
390
391 height = DeviceExtension->ScanLines;
392 data = (DeviceExtension->CursorVisible) ? 0x00 : 0x20;
393
394 size = (DeviceExtension->CursorSize * height) / 100;
395 if (size < 1)
396 size = 1;
397
398 data |= (UCHAR)(height - size);
399
400 _disable();
406 _enable();
407}
408
409static VOID
412 _In_ PDEVICE_EXTENSION DeviceExtension)
413{
416 ULONG Index;
417
418 _disable();
419
421
422 /* Disable screen and enable palette access */
425
426 for (Index = 0; Index < sizeof(DefaultPalette) / 3; Index++)
427 {
432 }
433
434 /* Enable screen and disable palette access */
437
438 /* Switch blinking characters off */
443 data = data & ~0x08;
447
448 /* Read screen information from CRT controller */
450 DeviceExtension->Columns = READ_PORT_UCHAR(CRTC_DATA) + 1;
452 DeviceExtension->Rows = READ_PORT_UCHAR(CRTC_DATA);
455 DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3));
456 DeviceExtension->Rows++;
458 DeviceExtension->ScanLines = (READ_PORT_UCHAR(CRTC_DATA) & 0x1F) + 1;
459
460 /* Retrieve the current output cursor position */
465
466 /* Show blinking cursor */
467 // FIXME: cursor block? Call ScrSetCursorShape() instead?
469 WRITE_PORT_UCHAR(CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
473 data | ((DeviceExtension->ScanLines - 1) & 0x1F));
474
475 _enable();
476
477 /* Calculate number of text rows */
478 DeviceExtension->Rows = DeviceExtension->Rows / DeviceExtension->ScanLines;
479
480 /* Set the cursor position, clipping it to the screen */
481 DeviceExtension->CursorX = (USHORT)(offset % DeviceExtension->Columns);
482 DeviceExtension->CursorY = (USHORT)(offset / DeviceExtension->Columns);
483 // DeviceExtension->CursorX = min(max(DeviceExtension->CursorX, 0), DeviceExtension->Columns - 1);
484 DeviceExtension->CursorY = min(max(DeviceExtension->CursorY, 0), DeviceExtension->Rows - 1);
485
486 /* Set the font */
487 if (DeviceExtension->FontBitfield)
488 ScrSetFont(DeviceExtension->FontBitfield);
489
490 DPRINT("%d Columns %d Rows %d Scanlines\n",
491 DeviceExtension->Columns,
492 DeviceExtension->Rows,
493 DeviceExtension->ScanLines);
494}
495
496static BOOLEAN
498 _In_ PDEVICE_EXTENSION DeviceExtension,
499 _In_ BOOLEAN FullReset,
501{
502#define FOREGROUND_LIGHTGRAY (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
503
505
506 /* Allow resets to the same state only for full resets */
507 if (!FullReset && (Enable == DeviceExtension->Enabled))
508 return FALSE; // STATUS_INVALID_PARAMETER; STATUS_INVALID_DEVICE_REQUEST;
509
510 if (FullReset)
511 {
512 DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
513 DeviceExtension->CursorVisible = TRUE;
514
515 if (DeviceExtension->FontBitfield)
516 {
517 ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
518 DeviceExtension->FontBitfield = NULL;
519 }
520
521 /* More initialization */
522 DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
523 DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
525 }
526
527 if (Enable)
528 {
529 ScrAcquireOwnership(DeviceExtension);
530
531 if (FullReset)
532 {
533 /*
534 * Fully reset the screen and all its settings.
535 */
536
537 /* Unmap any previously mapped video memory */
538 if (DeviceExtension->VideoMemory)
539 {
540 ASSERT(DeviceExtension->VideoMemorySize != 0);
541 MmUnmapIoSpace(DeviceExtension->VideoMemory, DeviceExtension->VideoMemorySize);
542 }
543 DeviceExtension->VideoMemory = NULL;
544 DeviceExtension->VideoMemorySize = 0;
545
546 /* Free any previously allocated backup screenbuffer */
547 if (DeviceExtension->ScreenBuffer)
548 {
549 ASSERT(DeviceExtension->ScreenBufferSize != 0);
550 ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
551 }
552 DeviceExtension->ScreenBuffer = NULL;
553 DeviceExtension->ScreenBufferSize = 0;
554
555 /* Get a pointer to the video memory */
556 DeviceExtension->VideoMemorySize = DeviceExtension->Rows * DeviceExtension->Columns * 2;
557 if (DeviceExtension->VideoMemorySize == 0)
558 return FALSE; // STATUS_INVALID_VIEW_SIZE; STATUS_MAPPED_FILE_SIZE_ZERO;
559
560 /* Map the video memory */
561 BaseAddress.QuadPart = VIDMEM_BASE;
562 DeviceExtension->VideoMemory =
563 (PUCHAR)MmMapIoSpace(BaseAddress, DeviceExtension->VideoMemorySize, MmNonCached);
564 if (!DeviceExtension->VideoMemory)
565 {
566 DeviceExtension->VideoMemorySize = 0;
567 return FALSE; // STATUS_NONE_MAPPED; STATUS_NOT_MAPPED_VIEW; STATUS_CONFLICTING_ADDRESSES;
568 }
569
570 /* Initialize the backup screenbuffer in non-paged pool (must be accessible at high IRQL) */
571 DeviceExtension->ScreenBufferSize = DeviceExtension->VideoMemorySize;
572 DeviceExtension->ScreenBuffer =
573 (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->ScreenBufferSize, TAG_BLUE);
574 if (!DeviceExtension->ScreenBuffer)
575 {
576 DPRINT1("Could not allocate screenbuffer, ignore...\n");
577 DeviceExtension->ScreenBufferSize = 0;
578 }
579
580 /* (Re-)initialize INBV */
582 }
583 else
584 {
585 /*
586 * Restore the previously disabled screen.
587 */
588
589 /* Restore the snapshot of the video memory from the backup screenbuffer */
590 if (DeviceExtension->ScreenBuffer)
591 {
592 ASSERT(DeviceExtension->VideoMemory);
593 ASSERT(DeviceExtension->ScreenBuffer);
594 ASSERT(DeviceExtension->ScreenBufferSize != 0);
595 ASSERT(DeviceExtension->VideoMemorySize == DeviceExtension->ScreenBufferSize);
596
597 RtlCopyMemory(DeviceExtension->VideoMemory,
598 DeviceExtension->ScreenBuffer,
599 DeviceExtension->VideoMemorySize);
600 }
601
602 /* Restore the cursor state */
603 ScrSetCursor(DeviceExtension);
604 ScrSetCursorShape(DeviceExtension);
605 }
606 DeviceExtension->Enabled = TRUE;
607 }
608 else
609 {
610 DeviceExtension->Enabled = FALSE;
611 if (FullReset)
612 {
613 /*
614 * Fully disable the screen and reset all its settings.
615 */
616
617 /* Clean INBV up */
619
620 /* Unmap any previously mapped video memory */
621 if (DeviceExtension->VideoMemory)
622 {
623 ASSERT(DeviceExtension->VideoMemorySize != 0);
624 MmUnmapIoSpace(DeviceExtension->VideoMemory, DeviceExtension->VideoMemorySize);
625 }
626 DeviceExtension->VideoMemory = NULL;
627 DeviceExtension->VideoMemorySize = 0;
628
629 /* Free any previously allocated backup screenbuffer */
630 if (DeviceExtension->ScreenBuffer)
631 {
632 ASSERT(DeviceExtension->ScreenBufferSize != 0);
633 ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
634 }
635 DeviceExtension->ScreenBuffer = NULL;
636 DeviceExtension->ScreenBufferSize = 0;
637
638 /* Store dummy values */
639 DeviceExtension->Columns = 1;
640 DeviceExtension->Rows = 1;
641 DeviceExtension->ScanLines = 1;
642 }
643 else
644 {
645 /*
646 * Partially disable the screen such that it can be restored later.
647 */
648
649 /* Take a snapshot of the video memory into the backup screenbuffer */
650 if (DeviceExtension->ScreenBuffer)
651 {
652 ASSERT(DeviceExtension->VideoMemory);
653 ASSERT(DeviceExtension->ScreenBuffer);
654 ASSERT(DeviceExtension->ScreenBufferSize != 0);
655 ASSERT(DeviceExtension->VideoMemorySize == DeviceExtension->ScreenBufferSize);
656
657 RtlCopyMemory(DeviceExtension->ScreenBuffer,
658 DeviceExtension->VideoMemory,
659 DeviceExtension->VideoMemorySize);
660 }
661 }
662 }
663
664 return TRUE; // STATUS_SUCCESS;
665}
666
668static NTSTATUS
669NTAPI
672 _In_ PIRP Irp)
673{
675
677
678 if (stk->MajorFunction == IRP_MJ_CREATE)
679 Irp->IoStatus.Information = FILE_OPENED;
680 // else: IRP_MJ_CLOSE
681
682 Irp->IoStatus.Status = STATUS_SUCCESS;
684 return STATUS_SUCCESS;
685}
686
688static NTSTATUS
689NTAPI
692 _In_ PIRP Irp)
693{
696 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
697 PCHAR pch = Irp->UserBuffer;
699 ULONG i;
700 ULONG j, offset;
701 USHORT cursorx, cursory;
702 USHORT rows, columns;
703 BOOLEAN processed = !!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT);
704
705 if (!DeviceExtension->Enabled || !DeviceExtension->VideoMemory)
706 {
707 /* Display is not enabled, we're not allowed to touch it */
709
710 Irp->IoStatus.Status = Status;
712
713 return Status;
714 }
715
716 vidmem = DeviceExtension->VideoMemory;
717 rows = DeviceExtension->Rows;
718 columns = DeviceExtension->Columns;
719 cursorx = DeviceExtension->CursorX;
720 cursory = DeviceExtension->CursorY;
721
722 if (!processed)
723 {
724 /* Raw output mode */
725
726 /* Calculate the offset from the cursor position */
727 offset = cursorx + cursory * columns;
728
729 // FIXME: Does the buffer only contains chars? or chars + attributes?
730 // FIXME2: Fix buffer overflow.
731 RtlCopyMemory(&vidmem[offset * 2], pch, stk->Parameters.Write.Length);
732 offset += (stk->Parameters.Write.Length / 2);
733
734 /* Set the cursor position, clipping it to the screen */
735 cursorx = (USHORT)(offset % columns);
736 cursory = (USHORT)(offset / columns);
737 // cursorx = min(max(cursorx, 0), columns - 1);
738 cursory = min(max(cursory, 0), rows - 1);
739 }
740 else
741 {
742 /* Cooked output mode */
743 for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
744 {
745 switch (*pch)
746 {
747 case '\b':
748 {
749 if (cursorx > 0)
750 {
751 cursorx--;
752 }
753 else if (cursory > 0)
754 {
755 cursory--;
756 cursorx = columns - 1;
757 }
758 offset = cursorx + cursory * columns;
759 vidmem[offset * 2] = ' ';
760 vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
761 break;
762 }
763
764 case '\n':
765 cursory++;
766 /* Fall back */
767 case '\r':
768 cursorx = 0;
769 break;
770
771 case '\t':
772 {
773 offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
774 while (offset--)
775 {
776 vidmem[(cursorx + cursory * columns) * 2] = ' ';
777 cursorx++;
778 if (cursorx >= columns)
779 {
780 cursorx = 0;
781 cursory++;
782 /* We jumped to the next line, stop there */
783 break;
784 }
785 }
786 break;
787 }
788
789 default:
790 {
791 offset = cursorx + cursory * columns;
792 vidmem[offset * 2] = *pch;
793 vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
794 cursorx++;
795 if (cursorx >= columns)
796 {
797 cursorx = 0;
798 cursory++;
799 }
800 break;
801 }
802 }
803
804 /* Scroll up the contents of the screen if we are at the end */
805 if (cursory >= rows)
806 {
808
810 &vidmem[columns * 2],
811 columns * (rows - 1) * 2);
812
813 LinePtr = (PUSHORT)&vidmem[columns * (rows - 1) * 2];
814
815 for (j = 0; j < columns; j++)
816 {
817 LinePtr[j] = DeviceExtension->CharAttribute << 8;
818 }
819 cursory = rows - 1;
820 for (j = 0; j < columns; j++)
821 {
822 offset = j + cursory * columns;
823 vidmem[offset * 2] = ' ';
824 vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
825 }
826 }
827 }
828 }
829
830 /* Set the cursor position */
831 ASSERT((0 <= cursorx) && (cursorx < DeviceExtension->Columns));
832 ASSERT((0 <= cursory) && (cursory < DeviceExtension->Rows));
833 DeviceExtension->CursorX = cursorx;
834 DeviceExtension->CursorY = cursory;
835 ScrSetCursor(DeviceExtension);
836
838
839 Irp->IoStatus.Status = Status;
841
842 return Status;
843}
844
846static NTSTATUS
847NTAPI
850 _In_ PIRP Irp)
851{
854 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
855
856 switch (stk->Parameters.DeviceIoControl.IoControlCode)
857 {
859 {
861
862 /* Validate input buffer */
863 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
864 {
866 break;
867 }
868 ASSERT(Irp->AssociatedIrp.SystemBuffer);
869
870 Enable = !!*(PULONG)Irp->AssociatedIrp.SystemBuffer;
871
872 /* Fully enable or disable the screen */
873 Status = (ScrResetScreen(DeviceExtension, TRUE, Enable)
875 Irp->IoStatus.Information = 0;
876 break;
877 }
878
880 {
882 USHORT rows = DeviceExtension->Rows;
883 USHORT columns = DeviceExtension->Columns;
884
885 /* Validate output buffer */
886 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
887 {
889 break;
890 }
891 ASSERT(Irp->AssociatedIrp.SystemBuffer);
892
893 pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
895
896 pcsbi->dwSize.X = columns;
897 pcsbi->dwSize.Y = rows;
898
899 pcsbi->dwCursorPosition.X = DeviceExtension->CursorX;
900 pcsbi->dwCursorPosition.Y = DeviceExtension->CursorY;
901
902 pcsbi->wAttributes = DeviceExtension->CharAttribute;
903
904 pcsbi->srWindow.Left = 0;
905 pcsbi->srWindow.Right = columns - 1;
906 pcsbi->srWindow.Top = 0;
907 pcsbi->srWindow.Bottom = rows - 1;
908
909 pcsbi->dwMaximumWindowSize.X = columns;
910 pcsbi->dwMaximumWindowSize.Y = rows;
911
912 Irp->IoStatus.Information = sizeof(CONSOLE_SCREEN_BUFFER_INFO);
914 break;
915 }
916
918 {
920
921 /* Validate input buffer */
922 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
923 {
925 break;
926 }
927 ASSERT(Irp->AssociatedIrp.SystemBuffer);
928
929 pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
930
931 if ( pcsbi->dwCursorPosition.X < 0 || pcsbi->dwCursorPosition.X >= DeviceExtension->Columns ||
932 pcsbi->dwCursorPosition.Y < 0 || pcsbi->dwCursorPosition.Y >= DeviceExtension->Rows )
933 {
934 Irp->IoStatus.Information = 0;
936 break;
937 }
938
939 DeviceExtension->CharAttribute = pcsbi->wAttributes;
940
941 /* Set the cursor position */
942 ASSERT((0 <= pcsbi->dwCursorPosition.X) && (pcsbi->dwCursorPosition.X < DeviceExtension->Columns));
943 ASSERT((0 <= pcsbi->dwCursorPosition.Y) && (pcsbi->dwCursorPosition.Y < DeviceExtension->Rows));
944 DeviceExtension->CursorX = pcsbi->dwCursorPosition.X;
945 DeviceExtension->CursorY = pcsbi->dwCursorPosition.Y;
946 if (DeviceExtension->Enabled)
947 ScrSetCursor(DeviceExtension);
948
949 Irp->IoStatus.Information = 0;
951 break;
952 }
953
955 {
957
958 /* Validate output buffer */
959 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
960 {
962 break;
963 }
964 ASSERT(Irp->AssociatedIrp.SystemBuffer);
965
966 pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
967 RtlZeroMemory(pcci, sizeof(CONSOLE_CURSOR_INFO));
968
969 pcci->dwSize = DeviceExtension->CursorSize;
970 pcci->bVisible = DeviceExtension->CursorVisible;
971
972 Irp->IoStatus.Information = sizeof(CONSOLE_CURSOR_INFO);
974 break;
975 }
976
978 {
980
981 /* Validate input buffer */
982 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
983 {
985 break;
986 }
987 ASSERT(Irp->AssociatedIrp.SystemBuffer);
988
989 pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
990
991 DeviceExtension->CursorSize = pcci->dwSize;
992 DeviceExtension->CursorVisible = pcci->bVisible;
993 if (DeviceExtension->Enabled)
994 ScrSetCursorShape(DeviceExtension);
995
996 Irp->IoStatus.Information = 0;
998 break;
999 }
1000
1002 {
1003 PCONSOLE_MODE pcm;
1004
1005 /* Validate output buffer */
1006 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_MODE))
1007 {
1009 break;
1010 }
1011 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1012
1013 pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
1014 RtlZeroMemory(pcm, sizeof(CONSOLE_MODE));
1015
1016 pcm->dwMode = DeviceExtension->Mode;
1017
1018 Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
1020 break;
1021 }
1022
1024 {
1025 PCONSOLE_MODE pcm;
1026
1027 /* Validate input buffer */
1028 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_MODE))
1029 {
1031 break;
1032 }
1033 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1034
1035 pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
1036 DeviceExtension->Mode = pcm->dwMode;
1037
1038 Irp->IoStatus.Information = 0;
1040 break;
1041 }
1042
1044 {
1046 PUCHAR vidmem;
1047 ULONG offset;
1048 ULONG dwCount;
1049 ULONG nMaxLength;
1050
1051 /* Validate input and output buffers */
1052 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE) ||
1053 stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
1054 {
1056 break;
1057 }
1058 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1059
1060 Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
1061 nMaxLength = Buf->nLength;
1062
1063 Buf->dwTransfered = 0;
1064 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
1065
1066 if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1067 Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
1068 nMaxLength == 0 )
1069 {
1071 break;
1072 }
1073
1074 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1075 {
1076 UCHAR attr = Buf->wAttribute;
1077
1078 vidmem = DeviceExtension->VideoMemory;
1079 offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1080
1081 nMaxLength = min(nMaxLength,
1082 (DeviceExtension->Rows - Buf->dwCoord.Y)
1083 * DeviceExtension->Columns - Buf->dwCoord.X);
1084
1085 for (dwCount = 0; dwCount < nMaxLength; dwCount++)
1086 {
1087 vidmem[offset + (dwCount * 2)] = attr;
1088 }
1089 Buf->dwTransfered = dwCount;
1090 }
1091
1093 break;
1094 }
1095
1097 {
1099 PUSHORT pAttr;
1100 PUCHAR vidmem;
1101 ULONG offset;
1102 ULONG dwCount;
1103 ULONG nMaxLength;
1104
1105 /* Validate input buffer */
1106 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
1107 {
1109 break;
1110 }
1111 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1112
1113 Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
1114 Irp->IoStatus.Information = 0;
1115
1116 /* Validate output buffer */
1117 if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
1118 {
1120 break;
1121 }
1122 ASSERT(Irp->MdlAddress);
1124 if (pAttr == NULL)
1125 {
1127 break;
1128 }
1129
1130 if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1131 Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
1132 {
1134 break;
1135 }
1136
1137 nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
1138 nMaxLength /= sizeof(USHORT);
1139
1140 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1141 {
1142 vidmem = DeviceExtension->VideoMemory;
1143 offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1144
1145 nMaxLength = min(nMaxLength,
1146 (DeviceExtension->Rows - Buf->dwCoord.Y)
1147 * DeviceExtension->Columns - Buf->dwCoord.X);
1148
1149 for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
1150 {
1151 *((PCHAR)pAttr) = vidmem[offset + (dwCount * 2)];
1152 }
1153 Irp->IoStatus.Information = dwCount * sizeof(USHORT);
1154 }
1155
1157 break;
1158 }
1159
1161 {
1162 COORD dwCoord;
1163 PCOORD pCoord;
1164 PUSHORT pAttr;
1165 PUCHAR vidmem;
1166 ULONG offset;
1167 ULONG dwCount;
1168 ULONG nMaxLength;
1169
1170 //
1171 // NOTE: For whatever reason no OUTPUT_ATTRIBUTE structure
1172 // is used for this IOCTL.
1173 //
1174
1175 /* Validate output buffer */
1176 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
1177 {
1179 break;
1180 }
1181 ASSERT(Irp->MdlAddress);
1183 if (pCoord == NULL)
1184 {
1186 break;
1187 }
1188 /* Capture the input info data */
1189 dwCoord = *pCoord;
1190
1191 nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
1192 nMaxLength /= sizeof(USHORT);
1193
1194 Irp->IoStatus.Information = 0;
1195
1196 if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
1197 dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
1198 nMaxLength == 0 )
1199 {
1201 break;
1202 }
1203
1204 pAttr = (PUSHORT)(pCoord + 1);
1205
1206 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1207 {
1208 vidmem = DeviceExtension->VideoMemory;
1209 offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1210
1211 nMaxLength = min(nMaxLength,
1212 (DeviceExtension->Rows - dwCoord.Y)
1213 * DeviceExtension->Columns - dwCoord.X);
1214
1215 for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
1216 {
1217 vidmem[offset + (dwCount * 2)] = *((PCHAR)pAttr);
1218 }
1219 Irp->IoStatus.Information = dwCount * sizeof(USHORT);
1220 }
1221
1223 break;
1224 }
1225
1227 {
1228 /* Validate input buffer */
1229 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(USHORT))
1230 {
1232 break;
1233 }
1234 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1235
1236 DeviceExtension->CharAttribute = *(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
1237
1238 Irp->IoStatus.Information = 0;
1240 break;
1241 }
1242
1244 {
1246 PUCHAR vidmem;
1247 ULONG offset;
1248 ULONG dwCount;
1249 ULONG nMaxLength;
1250
1251 /* Validate input and output buffers */
1252 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER) ||
1253 stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_CHARACTER))
1254 {
1256 break;
1257 }
1258 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1259
1260 Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
1261 nMaxLength = Buf->nLength;
1262
1263 Buf->dwTransfered = 0;
1264 Irp->IoStatus.Information = sizeof(OUTPUT_CHARACTER);
1265
1266 if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1267 Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
1268 nMaxLength == 0 )
1269 {
1271 break;
1272 }
1273
1274 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1275 {
1276 UCHAR ch = Buf->cCharacter;
1277
1278 vidmem = DeviceExtension->VideoMemory;
1279 offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2;
1280
1281 nMaxLength = min(nMaxLength,
1282 (DeviceExtension->Rows - Buf->dwCoord.Y)
1283 * DeviceExtension->Columns - Buf->dwCoord.X);
1284
1285 for (dwCount = 0; dwCount < nMaxLength; dwCount++)
1286 {
1287 vidmem[offset + (dwCount * 2)] = ch;
1288 }
1289 Buf->dwTransfered = dwCount;
1290 }
1291
1293 break;
1294 }
1295
1297 {
1299 PCHAR pChar;
1300 PUCHAR vidmem;
1301 ULONG offset;
1302 ULONG dwCount;
1303 ULONG nMaxLength;
1304
1305 /* Validate input buffer */
1306 if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER))
1307 {
1309 break;
1310 }
1311 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1312
1313 Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
1314 Irp->IoStatus.Information = 0;
1315
1316 /* Validate output buffer */
1317 if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
1318 {
1320 break;
1321 }
1322 ASSERT(Irp->MdlAddress);
1324 if (pChar == NULL)
1325 {
1327 break;
1328 }
1329
1330 if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1331 Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
1332 {
1334 break;
1335 }
1336
1337 nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
1338
1339 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1340 {
1341 vidmem = DeviceExtension->VideoMemory;
1342 offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2;
1343
1344 nMaxLength = min(nMaxLength,
1345 (DeviceExtension->Rows - Buf->dwCoord.Y)
1346 * DeviceExtension->Columns - Buf->dwCoord.X);
1347
1348 for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
1349 {
1350 *pChar = vidmem[offset + (dwCount * 2)];
1351 }
1352 Irp->IoStatus.Information = dwCount * sizeof(CHAR);
1353 }
1354
1356 break;
1357 }
1358
1360 {
1361 COORD dwCoord;
1362 PCOORD pCoord;
1363 PCHAR pChar;
1364 PUCHAR vidmem;
1365 ULONG offset;
1366 ULONG dwCount;
1367 ULONG nMaxLength;
1368
1369 //
1370 // NOTE: For whatever reason no OUTPUT_CHARACTER structure
1371 // is used for this IOCTL.
1372 //
1373
1374 /* Validate output buffer */
1375 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
1376 {
1378 break;
1379 }
1380 ASSERT(Irp->MdlAddress);
1382 if (pCoord == NULL)
1383 {
1385 break;
1386 }
1387 /* Capture the input info data */
1388 dwCoord = *pCoord;
1389
1390 nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
1391 Irp->IoStatus.Information = 0;
1392
1393 if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
1394 dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
1395 nMaxLength == 0 )
1396 {
1398 break;
1399 }
1400
1401 pChar = (PCHAR)(pCoord + 1);
1402
1403 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1404 {
1405 vidmem = DeviceExtension->VideoMemory;
1406 offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2;
1407
1408 nMaxLength = min(nMaxLength,
1409 (DeviceExtension->Rows - dwCoord.Y)
1410 * DeviceExtension->Columns - dwCoord.X);
1411
1412 for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
1413 {
1414 vidmem[offset + (dwCount * 2)] = *pChar;
1415 }
1416 Irp->IoStatus.Information = dwCount * sizeof(CHAR);
1417 }
1418
1420 break;
1421 }
1422
1423 case IOCTL_CONSOLE_DRAW:
1424 {
1425 CONSOLE_DRAW ConsoleDraw;
1426 PCONSOLE_DRAW pConsoleDraw;
1427 PUCHAR Src, Dest;
1428 UINT32 SrcDelta, DestDelta, i;
1429
1430 /* Validate output buffer */
1431 if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_DRAW))
1432 {
1434 break;
1435 }
1436 ASSERT(Irp->MdlAddress);
1437 pConsoleDraw = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1438 if (pConsoleDraw == NULL)
1439 {
1441 break;
1442 }
1443 /* Capture the input info data */
1444 ConsoleDraw = *pConsoleDraw;
1445
1446 /* Check whether we have the size for the header plus the data area */
1447 if ((stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(CONSOLE_DRAW)) / 2
1448 < ((ULONG)ConsoleDraw.SizeX * (ULONG)ConsoleDraw.SizeY))
1449 {
1451 break;
1452 }
1453
1454 Irp->IoStatus.Information = 0;
1455
1456 /* Set the cursor position, clipping it to the screen */
1457 DeviceExtension->CursorX = min(max(ConsoleDraw.CursorX, 0), DeviceExtension->Columns - 1);
1458 DeviceExtension->CursorY = min(max(ConsoleDraw.CursorY, 0), DeviceExtension->Rows - 1);
1459 if (DeviceExtension->Enabled)
1460 ScrSetCursor(DeviceExtension);
1461
1462 // TODO: For the moment if the ConsoleDraw rectangle has borders
1463 // out of the screen-buffer we just bail out. Would it be better
1464 // to actually clip the rectangle within its borders instead?
1465 if ( ConsoleDraw.X < 0 || ConsoleDraw.X >= DeviceExtension->Columns ||
1466 ConsoleDraw.Y < 0 || ConsoleDraw.Y >= DeviceExtension->Rows )
1467 {
1469 break;
1470 }
1471 if ( ConsoleDraw.SizeX > DeviceExtension->Columns - ConsoleDraw.X ||
1472 ConsoleDraw.SizeY > DeviceExtension->Rows - ConsoleDraw.Y )
1473 {
1475 break;
1476 }
1477
1478 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1479 {
1480 Src = (PUCHAR)(pConsoleDraw + 1);
1481 SrcDelta = ConsoleDraw.SizeX * 2;
1482 Dest = DeviceExtension->VideoMemory +
1483 (ConsoleDraw.X + ConsoleDraw.Y * DeviceExtension->Columns) * 2;
1484 DestDelta = DeviceExtension->Columns * 2;
1485 /* 2 == sizeof(CHAR) + sizeof(BYTE) */
1486
1487 /* Copy each line */
1488 for (i = 0; i < ConsoleDraw.SizeY; i++)
1489 {
1490 RtlCopyMemory(Dest, Src, SrcDelta);
1491 Src += SrcDelta;
1492 Dest += DestDelta;
1493 }
1494 }
1495
1497 break;
1498 }
1499
1501 {
1502 //
1503 // FIXME: For the moment we support only a fixed 256-char 8-bit font.
1504 //
1505
1506 /* Validate input buffer */
1507 if (stk->Parameters.DeviceIoControl.InputBufferLength < 256 * 8)
1508 {
1510 break;
1511 }
1512 ASSERT(Irp->AssociatedIrp.SystemBuffer);
1513
1514 if (DeviceExtension->FontBitfield)
1515 ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
1516 DeviceExtension->FontBitfield = ExAllocatePoolWithTag(NonPagedPool, 256 * 8, TAG_BLUE);
1517 if (!DeviceExtension->FontBitfield)
1518 {
1520 break;
1521 }
1522 RtlCopyMemory(DeviceExtension->FontBitfield, Irp->AssociatedIrp.SystemBuffer, 256 * 8);
1523
1524 /* Set the font if needed */
1525 if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1526 ScrSetFont(DeviceExtension->FontBitfield);
1527
1528 Irp->IoStatus.Information = 0;
1530 break;
1531 }
1532
1533 default:
1535 }
1536
1537 Irp->IoStatus.Status = Status;
1539
1540 return Status;
1541}
1542
1544static NTSTATUS
1545NTAPI
1548 _In_ PIRP Irp)
1549{
1551
1553
1554 DPRINT1("ScrDispatch(0x%p): stk->MajorFunction = %lu UNIMPLEMENTED\n",
1556
1557 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1560}
1561
1562/*
1563 * Module entry point
1564 */
1566NTAPI
1570{
1573 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen");
1574 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
1575
1576 DPRINT("Screen Driver 0.0.6\n");
1577
1578 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreateClose;
1579 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrCreateClose;
1580 DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
1581 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
1583
1585 sizeof(DEVICE_EXTENSION),
1586 &DeviceName,
1589 TRUE,
1590 &DeviceObject);
1591 if (!NT_SUCCESS(Status))
1592 {
1593 return Status;
1594 }
1595
1596 Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
1597 if (NT_SUCCESS(Status))
1598 {
1599 /* By default disable the screen (but don't touch INBV: ResetDisplayParametersDeviceExtension is still NULL) */
1600 ScrResetScreen(DeviceObject->DeviceExtension, TRUE, FALSE);
1601 /* Now set ResetDisplayParametersDeviceExtension to enable synchronizing with INBV */
1603 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1604 }
1605 else
1606 {
1608 }
1609 return Status;
1610}
1611
1612/* EOF */
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
unsigned int UINT32
#define TAB_WIDTH
Definition: text.h:125
LONG NTSTATUS
Definition: precomp.h:26
static const COLUMN_LIST Columns[]
Definition: listview.c:19
#define DPRINT1
Definition: precomp.h:8
#define CHAR(Char)
struct _COORD COORD
static VOID FASTCALL ScrSetCursorShape(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:382
static DRIVER_DISPATCH ScrDispatch
Definition: blue.c:1543
static BOOLEAN InbvMonitoring
Definition: blue.c:99
static NTSTATUS ScrInbvCleanup(VOID)
Definition: blue.c:277
static DRIVER_DISPATCH ScrWrite
Definition: blue.c:687
struct _DEVICE_EXTENSION DEVICE_EXTENSION
static DRIVER_DISPATCH ScrCreateClose
Definition: blue.c:667
static PDEVICE_EXTENSION ResetDisplayParametersDeviceExtension
Definition: blue.c:97
static VOID FASTCALL ScrAcquireOwnership(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:411
static const UCHAR DefaultPalette[]
Definition: blue.c:69
struct _VGA_REGISTERS VGA_REGISTERS
static BOOLEAN NTAPI ScrResetDisplayParameters(_In_ ULONG Columns, _In_ ULONG Rows)
Definition: blue.c:146
static VOID FASTCALL ScrSetRegisters(const VGA_REGISTERS *Registers)
Definition: blue.c:308
static BOOLEAN ScrResetScreen(_In_ PDEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FullReset, _In_ BOOLEAN Enable)
Definition: blue.c:497
static VOID FASTCALL ScrSetCursor(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:362
static const VGA_REGISTERS VidpMode3Regs
Definition: blue.c:53
struct _VGA_REGISTERS * PVGA_REGISTERS
static VOID NTAPI InbvMonitorThread(_In_ PVOID Context)
Definition: blue.c:188
#define FOREGROUND_LIGHTGRAY
static NTSTATUS ScrInbvInitialize(VOID)
Definition: blue.c:251
struct _DEVICE_EXTENSION * PDEVICE_EXTENSION
static HANDLE InbvThreadHandle
Definition: blue.c:98
static DRIVER_DISPATCH ScrIoControl
Definition: blue.c:845
static BOOLEAN NTAPI ScrResetDisplayParametersEx(_In_ ULONG Columns, _In_ ULONG Rows, _In_ BOOLEAN CalledByInbv)
Definition: blue.c:118
#define ATTRC_WRITEREG
Definition: blue.h:104
#define ENABLE_WRAP_AT_EOL_OUTPUT
Definition: blue.h:54
#define SEQDATA
Definition: blue.h:110
#define GRAPHICSDATA
Definition: blue.h:114
VOID ScrSetFont(_In_ PUCHAR FontBitfield)
Definition: font.c:25
#define CRTC_CURSOREND
Definition: blue.h:84
#define PELMASK
Definition: blue.h:117
#define GRAPHICS
Definition: blue.h:113
#define CRTC_COMMAND
Definition: blue.h:76
#define VIDMEM_BASE
Definition: blue.h:73
#define ENABLE_PROCESSED_OUTPUT
Definition: blue.h:53
#define STATUS
Definition: blue.h:116
#define CRTC_ROWS
Definition: blue.h:81
#define CRTC
Definition: blue.h:111
#define CRTC_CURSORSTART
Definition: blue.h:83
#define CRTC_CURSORPOSHI
Definition: blue.h:85
#define CRTC_OVERFLOW
Definition: blue.h:80
struct tagCONSOLE_SCREEN_BUFFER_INFO CONSOLE_SCREEN_BUFFER_INFO
#define ATTRIB
Definition: blue.h:115
#define PELDATA
Definition: blue.h:119
struct tagCONSOLE_CURSOR_INFO CONSOLE_CURSOR_INFO
#define ATTRC_INPST1
Definition: blue.h:106
#define BACKGROUND_BLUE
Definition: blue.h:65
#define SEQ
Definition: blue.h:109
#define CRTC_CURSORPOSLO
Definition: blue.h:86
#define CRTC_COLUMNS
Definition: blue.h:79
#define CRTC_DATA
Definition: blue.h:77
struct tagCONSOLE_CURSOR_INFO * PCONSOLE_CURSOR_INFO
#define ATTRC_READREG
Definition: blue.h:105
#define CRTCDATA
Definition: blue.h:112
#define MISC
Definition: blue.h:108
#define TAG_BLUE
Definition: blue.h:14
struct tagCONSOLE_SCREEN_BUFFER_INFO * PCONSOLE_SCREEN_BUFFER_INFO
#define PELINDEX
Definition: blue.h:118
#define CRTC_SCANLINES
Definition: blue.h:82
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
unsigned char
Definition: typeof.h:29
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
Status
Definition: gdiplustypes.h:25
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define KeGetCurrentThread
Definition: hal.h:55
VOID NTAPI InbvNotifyDisplayOwnershipLost(_In_ INBV_RESET_DISPLAY_PARAMETERS Callback)
Definition: inbv.c:404
BOOLEAN NTAPI InbvCheckDisplayOwnership(VOID)
Definition: inbv.c:316
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define LOW_REALTIME_PRIORITY
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
if(dx< 0)
Definition: linetemp.h:194
#define pch(ap)
Definition: match.c:418
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ NormalPagePriority
Definition: imports.h:54
#define min(a, b)
Definition: monoChain.cc:55
struct Line * LinePtr
Definition: ncftp.h:78
#define KernelMode
Definition: asm.h:34
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define _In_
Definition: no_sal2.h:158
#define FASTCALL
Definition: nt_native.h:50
#define FILE_OPENED
Definition: nt_native.h:769
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define IOCTL_CONSOLE_DRAW
Definition: ntddblue.h:22
struct tagOUTPUT_ATTRIBUTE * POUTPUT_ATTRIBUTE
#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:14
#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
Definition: ntddblue.h:20
struct tagOUTPUT_ATTRIBUTE OUTPUT_ATTRIBUTE
struct tagOUTPUT_CHARACTER * POUTPUT_CHARACTER
struct tagOUTPUT_CHARACTER OUTPUT_CHARACTER
#define IOCTL_CONSOLE_GET_MODE
Definition: ntddblue.h:10
#define IOCTL_CONSOLE_LOADFONT
Definition: ntddblue.h:24
#define IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
Definition: ntddblue.h:18
#define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
Definition: ntddblue.h:19
#define IOCTL_CONSOLE_SET_MODE
Definition: ntddblue.h:11
#define IOCTL_CONSOLE_RESET_SCREEN
Definition: ntddblue.h:4
#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:15
struct tagCONSOLE_MODE CONSOLE_MODE
#define IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
Definition: ntddblue.h:16
struct tagCONSOLE_MODE * PCONSOLE_MODE
#define IOCTL_CONSOLE_GET_CURSOR_INFO
Definition: ntddblue.h:8
#define IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
Definition: ntddblue.h:7
#define IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
Definition: ntddblue.h:6
#define IOCTL_CONSOLE_SET_CURSOR_INFO
Definition: ntddblue.h:9
#define IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:13
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_SCREEN
Definition: winioctl.h:73
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: ncftp.h:79
Definition: bl.h:1338
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
USHORT CursorY
Definition: blue.c:40
PUCHAR VideoMemory
Definition: blue.c:28
USHORT CharAttribute
Definition: blue.c:35
USHORT Rows
Definition: blue.c:38
PUCHAR ScreenBuffer
Definition: blue.c:31
INT CursorVisible
Definition: blue.c:34
ULONG Mode
Definition: blue.c:36
SIZE_T ScreenBufferSize
Definition: blue.c:32
USHORT Columns
Definition: blue.c:39
PUCHAR FontBitfield
Definition: blue.c:41
UCHAR ScanLines
Definition: blue.c:37
USHORT CursorX
Definition: blue.c:40
SIZE_T VideoMemorySize
Definition: blue.c:29
ULONG CursorSize
Definition: blue.c:33
BOOLEAN Enabled
Definition: blue.c:30
struct _IO_STACK_LOCATION::@3979::@3984 Write
struct _IO_STACK_LOCATION::@1580::@1581 DeviceIoControl
union _IO_STACK_LOCATION::@1580 Parameters
UCHAR CRT[24]
Definition: blue.c:46
UCHAR Attribute[21]
Definition: blue.c:47
UCHAR Sequencer[5]
Definition: blue.c:49
UCHAR Misc
Definition: blue.c:50
UCHAR Graphics[9]
Definition: blue.c:48
Definition: cookie.c:202
USHORT CursorY
Definition: ntddblue.h:56
USHORT SizeX
Definition: ntddblue.h:53
USHORT SizeY
Definition: ntddblue.h:54
USHORT CursorX
Definition: ntddblue.h:55
ULONG dwMode
Definition: ntddblue.h:30
SHORT Y
Definition: blue.h:27
SHORT X
Definition: blue.h:26
SHORT Right
Definition: blue.h:34
SHORT Left
Definition: blue.h:32
SHORT Top
Definition: blue.h:33
SHORT Bottom
Definition: blue.h:35
#define max(a, b)
Definition: svc.c:63
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
static int processed(const type_t *type)
Definition: typegen.c:2254
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:94
PBYTE vidmem
Definition: vgavideo.c:18
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ ULONG Rows
Definition: haltypes.h:7
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_VIDEO_INCREMENT
Definition: iotypes.h:609
@ Executive
Definition: ketypes.h:415
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
@ MmNonCached
Definition: mmtypes.h:129
unsigned char UCHAR
Definition: xmlstorage.h:181