ReactOS  0.4.14-dev-1332-g6db3d88
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 
26 typedef 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  ULONG CodePage; /* Specifies the font associated to this code page */
43 
44 typedef struct _VGA_REGISTERS
45 {
46  UCHAR CRT[24];
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 
69 static 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 
91 static 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  */
116 static BOOLEAN
117 NTAPI
120  _In_ ULONG Rows,
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 
136  DeviceExtension = ResetDisplayParametersDeviceExtension;
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() */
144 static BOOLEAN
145 NTAPI
148  _In_ ULONG Rows)
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  */
186 static VOID
187 NTAPI
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
221  while (InbvCheckDisplayOwnership())
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 
250 static 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 
276 static 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 
306 static VOID
307 FASTCALL
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);
317  WRITE_PORT_UCHAR(SEQDATA, 0x01);
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);
328  WRITE_PORT_UCHAR(SEQDATA, 0x03);
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  {
345  WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]);
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 */
357  WRITE_PORT_UCHAR(PELMASK, 0xff);
358 }
359 
360 static VOID
361 FASTCALL
363  _In_ PDEVICE_EXTENSION DeviceExtension)
364 {
365  ULONG Offset;
366 
367  if (!DeviceExtension->VideoMemory)
368  return;
369 
370  Offset = (DeviceExtension->CursorY * DeviceExtension->Columns) + DeviceExtension->CursorX;
371 
372  _disable();
377  _enable();
378 }
379 
380 static VOID
381 FASTCALL
383  _In_ PDEVICE_EXTENSION DeviceExtension)
384 {
385  ULONG size, height;
386  UCHAR data, value;
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();
404  value = READ_PORT_UCHAR(CRTC_DATA) & 0xE0;
406  _enable();
407 }
408 
409 static VOID
410 FASTCALL
412  _In_ PDEVICE_EXTENSION DeviceExtension)
413 {
414  UCHAR data, value;
415  ULONG offset;
416  ULONG Index;
417 
418  _disable();
419 
421 
422  /* Disable screen and enable palette access */
424  WRITE_PORT_UCHAR(ATTRIB, 0x00);
425 
426  for (Index = 0; Index < sizeof(DefaultPalette) / 3; Index++)
427  {
432  }
433 
434  /* Enable screen and disable palette access */
436  WRITE_PORT_UCHAR(ATTRIB, 0x20);
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 */
464  offset += (READ_PORT_UCHAR(CRTC_DATA) << 8);
465 
466  /* Show blinking cursor */
467  // FIXME: cursor block? Call ScrSetCursorShape() instead?
469  WRITE_PORT_UCHAR(CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
471  data = READ_PORT_UCHAR(CRTC_DATA) & 0xE0;
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  /* Upload a default font for the current codepage */
487  ScrLoadFontTable(DeviceExtension->CodePage);
488 
489  DPRINT("%d Columns %d Rows %d Scanlines\n",
490  DeviceExtension->Columns,
491  DeviceExtension->Rows,
492  DeviceExtension->ScanLines);
493 }
494 
495 static BOOLEAN
497  _In_ PDEVICE_EXTENSION DeviceExtension,
498  _In_ BOOLEAN FullReset,
500 {
501 #define FOREGROUND_LIGHTGRAY (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
502 
504 
505  /* Allow resets to the same state only for full resets */
506  if (!FullReset && (Enable == DeviceExtension->Enabled))
507  return FALSE; // STATUS_INVALID_PARAMETER; STATUS_INVALID_DEVICE_REQUEST;
508 
509  if (FullReset)
510  {
511  DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
512  DeviceExtension->CursorVisible = TRUE;
513 
514  /* More initialization */
515  DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
516  DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
518  DeviceExtension->CodePage = 437; /* Use default codepage */
519  }
520 
521  if (Enable)
522  {
523  ScrAcquireOwnership(DeviceExtension);
524 
525  if (FullReset)
526  {
527  /*
528  * Fully reset the screen and all its settings.
529  */
530 
531  /* Unmap any previously mapped video memory */
532  if (DeviceExtension->VideoMemory)
533  {
534  ASSERT(DeviceExtension->VideoMemorySize != 0);
535  MmUnmapIoSpace(DeviceExtension->VideoMemory, DeviceExtension->VideoMemorySize);
536  }
537  DeviceExtension->VideoMemory = NULL;
538  DeviceExtension->VideoMemorySize = 0;
539 
540  /* Free any previously allocated backup screenbuffer */
541  if (DeviceExtension->ScreenBuffer)
542  {
543  ASSERT(DeviceExtension->ScreenBufferSize != 0);
544  ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
545  }
546  DeviceExtension->ScreenBuffer = NULL;
547  DeviceExtension->ScreenBufferSize = 0;
548 
549  /* Get a pointer to the video memory */
550  DeviceExtension->VideoMemorySize = DeviceExtension->Rows * DeviceExtension->Columns * 2;
551  if (DeviceExtension->VideoMemorySize == 0)
552  return FALSE; // STATUS_INVALID_VIEW_SIZE; STATUS_MAPPED_FILE_SIZE_ZERO;
553 
554  /* Map the video memory */
555  BaseAddress.QuadPart = VIDMEM_BASE;
556  DeviceExtension->VideoMemory =
557  (PUCHAR)MmMapIoSpace(BaseAddress, DeviceExtension->VideoMemorySize, MmNonCached);
558  if (!DeviceExtension->VideoMemory)
559  {
560  DeviceExtension->VideoMemorySize = 0;
561  return FALSE; // STATUS_NONE_MAPPED; STATUS_NOT_MAPPED_VIEW; STATUS_CONFLICTING_ADDRESSES;
562  }
563 
564  /* Initialize the backup screenbuffer in non-paged pool (must be accessible at high IRQL) */
565  DeviceExtension->ScreenBufferSize = DeviceExtension->VideoMemorySize;
566  DeviceExtension->ScreenBuffer =
567  (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, DeviceExtension->ScreenBufferSize, TAG_BLUE);
568  if (!DeviceExtension->ScreenBuffer)
569  {
570  DPRINT1("Could not allocate screenbuffer, ignore...\n");
571  DeviceExtension->ScreenBufferSize = 0;
572  }
573 
574  /* (Re-)initialize INBV */
576  }
577  else
578  {
579  /*
580  * Restore the previously disabled screen.
581  */
582 
583  /* Restore the snapshot of the video memory from the backup screenbuffer */
584  if (DeviceExtension->ScreenBuffer)
585  {
586  ASSERT(DeviceExtension->VideoMemory);
587  ASSERT(DeviceExtension->ScreenBuffer);
588  ASSERT(DeviceExtension->ScreenBufferSize != 0);
589  ASSERT(DeviceExtension->VideoMemorySize == DeviceExtension->ScreenBufferSize);
590 
591  RtlCopyMemory(DeviceExtension->VideoMemory,
592  DeviceExtension->ScreenBuffer,
593  DeviceExtension->VideoMemorySize);
594  }
595 
596  /* Restore the cursor state */
597  ScrSetCursor(DeviceExtension);
598  ScrSetCursorShape(DeviceExtension);
599  }
600  DeviceExtension->Enabled = TRUE;
601  }
602  else
603  {
604  DeviceExtension->Enabled = FALSE;
605  if (FullReset)
606  {
607  /*
608  * Fully disable the screen and reset all its settings.
609  */
610 
611  /* Clean INBV up */
612  ScrInbvCleanup();
613 
614  /* Unmap any previously mapped video memory */
615  if (DeviceExtension->VideoMemory)
616  {
617  ASSERT(DeviceExtension->VideoMemorySize != 0);
618  MmUnmapIoSpace(DeviceExtension->VideoMemory, DeviceExtension->VideoMemorySize);
619  }
620  DeviceExtension->VideoMemory = NULL;
621  DeviceExtension->VideoMemorySize = 0;
622 
623  /* Free any previously allocated backup screenbuffer */
624  if (DeviceExtension->ScreenBuffer)
625  {
626  ASSERT(DeviceExtension->ScreenBufferSize != 0);
627  ExFreePoolWithTag(DeviceExtension->ScreenBuffer, TAG_BLUE);
628  }
629  DeviceExtension->ScreenBuffer = NULL;
630  DeviceExtension->ScreenBufferSize = 0;
631 
632  /* Store dummy values */
633  DeviceExtension->Columns = 1;
634  DeviceExtension->Rows = 1;
635  DeviceExtension->ScanLines = 1;
636  }
637  else
638  {
639  /*
640  * Partially disable the screen such that it can be restored later.
641  */
642 
643  /* Take a snapshot of the video memory into the backup screenbuffer */
644  if (DeviceExtension->ScreenBuffer)
645  {
646  ASSERT(DeviceExtension->VideoMemory);
647  ASSERT(DeviceExtension->ScreenBuffer);
648  ASSERT(DeviceExtension->ScreenBufferSize != 0);
649  ASSERT(DeviceExtension->VideoMemorySize == DeviceExtension->ScreenBufferSize);
650 
651  RtlCopyMemory(DeviceExtension->ScreenBuffer,
652  DeviceExtension->VideoMemory,
653  DeviceExtension->VideoMemorySize);
654  }
655  }
656  }
657 
658  return TRUE; // STATUS_SUCCESS;
659 }
660 
662 static NTSTATUS
663 NTAPI
666  _In_ PIRP Irp)
667 {
669 
671 
672  if (stk->MajorFunction == IRP_MJ_CREATE)
673  Irp->IoStatus.Information = FILE_OPENED;
674  // else: IRP_MJ_CLOSE
675 
676  Irp->IoStatus.Status = STATUS_SUCCESS;
678  return STATUS_SUCCESS;
679 }
680 
682 static NTSTATUS
683 NTAPI
686  _In_ PIRP Irp)
687 {
691  PCHAR pch = Irp->UserBuffer;
692  PUCHAR vidmem;
693  ULONG i;
694  ULONG j, offset;
695  USHORT cursorx, cursory;
696  USHORT rows, columns;
697  BOOLEAN processed = !!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT);
698 
699  if (!DeviceExtension->Enabled || !DeviceExtension->VideoMemory)
700  {
701  /* Display is not enabled, we're not allowed to touch it */
703 
704  Irp->IoStatus.Status = Status;
706 
707  return Status;
708  }
709 
710  vidmem = DeviceExtension->VideoMemory;
711  rows = DeviceExtension->Rows;
712  columns = DeviceExtension->Columns;
713  cursorx = DeviceExtension->CursorX;
714  cursory = DeviceExtension->CursorY;
715 
716  if (!processed)
717  {
718  /* Raw output mode */
719 
720  /* Calculate the offset from the cursor position */
721  offset = cursorx + cursory * columns;
722 
723  // FIXME: Does the buffer only contains chars? or chars + attributes?
724  // FIXME2: Fix buffer overflow.
725  RtlCopyMemory(&vidmem[offset * 2], pch, stk->Parameters.Write.Length);
726  offset += (stk->Parameters.Write.Length / 2);
727 
728  /* Set the cursor position, clipping it to the screen */
729  cursorx = (USHORT)(offset % columns);
730  cursory = (USHORT)(offset / columns);
731  // cursorx = min(max(cursorx, 0), columns - 1);
732  cursory = min(max(cursory, 0), rows - 1);
733  }
734  else
735  {
736  /* Cooked output mode */
737  for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
738  {
739  switch (*pch)
740  {
741  case '\b':
742  {
743  if (cursorx > 0)
744  {
745  cursorx--;
746  }
747  else if (cursory > 0)
748  {
749  cursory--;
750  cursorx = columns - 1;
751  }
752  offset = cursorx + cursory * columns;
753  vidmem[offset * 2] = ' ';
754  vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
755  break;
756  }
757 
758  case '\n':
759  cursory++;
760  /* Fall back */
761  case '\r':
762  cursorx = 0;
763  break;
764 
765  case '\t':
766  {
767  offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
768  while (offset--)
769  {
770  vidmem[(cursorx + cursory * columns) * 2] = ' ';
771  cursorx++;
772  if (cursorx >= columns)
773  {
774  cursorx = 0;
775  cursory++;
776  /* We jumped to the next line, stop there */
777  break;
778  }
779  }
780  break;
781  }
782 
783  default:
784  {
785  offset = cursorx + cursory * columns;
786  vidmem[offset * 2] = *pch;
787  vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
788  cursorx++;
789  if (cursorx >= columns)
790  {
791  cursorx = 0;
792  cursory++;
793  }
794  break;
795  }
796  }
797 
798  /* Scroll up the contents of the screen if we are at the end */
799  if (cursory >= rows)
800  {
802 
804  &vidmem[columns * 2],
805  columns * (rows - 1) * 2);
806 
807  LinePtr = (PUSHORT)&vidmem[columns * (rows - 1) * 2];
808 
809  for (j = 0; j < columns; j++)
810  {
811  LinePtr[j] = DeviceExtension->CharAttribute << 8;
812  }
813  cursory = rows - 1;
814  for (j = 0; j < columns; j++)
815  {
816  offset = j + cursory * columns;
817  vidmem[offset * 2] = ' ';
818  vidmem[offset * 2 + 1] = (char)DeviceExtension->CharAttribute;
819  }
820  }
821  }
822  }
823 
824  /* Set the cursor position */
825  ASSERT((0 <= cursorx) && (cursorx < DeviceExtension->Columns));
826  ASSERT((0 <= cursory) && (cursory < DeviceExtension->Rows));
827  DeviceExtension->CursorX = cursorx;
828  DeviceExtension->CursorY = cursory;
829  ScrSetCursor(DeviceExtension);
830 
832 
833  Irp->IoStatus.Status = Status;
835 
836  return Status;
837 }
838 
840 static NTSTATUS
841 NTAPI
844  _In_ PIRP Irp)
845 {
849 
850  switch (stk->Parameters.DeviceIoControl.IoControlCode)
851  {
853  {
854  BOOLEAN Enable;
855 
856  /* Validate input buffer */
857  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
858  {
860  break;
861  }
862  ASSERT(Irp->AssociatedIrp.SystemBuffer);
863 
864  Enable = !!*(PULONG)Irp->AssociatedIrp.SystemBuffer;
865 
866  /* Fully enable or disable the screen */
867  Status = (ScrResetScreen(DeviceExtension, TRUE, Enable)
869  Irp->IoStatus.Information = 0;
870  break;
871  }
872 
874  {
876  USHORT rows = DeviceExtension->Rows;
877  USHORT columns = DeviceExtension->Columns;
878 
879  /* Validate output buffer */
880  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
881  {
883  break;
884  }
885  ASSERT(Irp->AssociatedIrp.SystemBuffer);
886 
887  pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
889 
890  pcsbi->dwSize.X = columns;
891  pcsbi->dwSize.Y = rows;
892 
893  pcsbi->dwCursorPosition.X = DeviceExtension->CursorX;
894  pcsbi->dwCursorPosition.Y = DeviceExtension->CursorY;
895 
896  pcsbi->wAttributes = DeviceExtension->CharAttribute;
897 
898  pcsbi->srWindow.Left = 0;
899  pcsbi->srWindow.Right = columns - 1;
900  pcsbi->srWindow.Top = 0;
901  pcsbi->srWindow.Bottom = rows - 1;
902 
903  pcsbi->dwMaximumWindowSize.X = columns;
904  pcsbi->dwMaximumWindowSize.Y = rows;
905 
906  Irp->IoStatus.Information = sizeof(CONSOLE_SCREEN_BUFFER_INFO);
908  break;
909  }
910 
912  {
914 
915  /* Validate input buffer */
916  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_SCREEN_BUFFER_INFO))
917  {
919  break;
920  }
921  ASSERT(Irp->AssociatedIrp.SystemBuffer);
922 
923  pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
924 
925  if ( pcsbi->dwCursorPosition.X < 0 || pcsbi->dwCursorPosition.X >= DeviceExtension->Columns ||
926  pcsbi->dwCursorPosition.Y < 0 || pcsbi->dwCursorPosition.Y >= DeviceExtension->Rows )
927  {
928  Irp->IoStatus.Information = 0;
930  break;
931  }
932 
933  DeviceExtension->CharAttribute = pcsbi->wAttributes;
934 
935  /* Set the cursor position */
936  ASSERT((0 <= pcsbi->dwCursorPosition.X) && (pcsbi->dwCursorPosition.X < DeviceExtension->Columns));
937  ASSERT((0 <= pcsbi->dwCursorPosition.Y) && (pcsbi->dwCursorPosition.Y < DeviceExtension->Rows));
938  DeviceExtension->CursorX = pcsbi->dwCursorPosition.X;
939  DeviceExtension->CursorY = pcsbi->dwCursorPosition.Y;
940  if (DeviceExtension->Enabled)
941  ScrSetCursor(DeviceExtension);
942 
943  Irp->IoStatus.Information = 0;
945  break;
946  }
947 
949  {
951 
952  /* Validate output buffer */
953  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
954  {
956  break;
957  }
958  ASSERT(Irp->AssociatedIrp.SystemBuffer);
959 
960  pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
961  RtlZeroMemory(pcci, sizeof(CONSOLE_CURSOR_INFO));
962 
963  pcci->dwSize = DeviceExtension->CursorSize;
964  pcci->bVisible = DeviceExtension->CursorVisible;
965 
966  Irp->IoStatus.Information = sizeof(CONSOLE_CURSOR_INFO);
968  break;
969  }
970 
972  {
974 
975  /* Validate input buffer */
976  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_CURSOR_INFO))
977  {
979  break;
980  }
981  ASSERT(Irp->AssociatedIrp.SystemBuffer);
982 
983  pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
984 
985  DeviceExtension->CursorSize = pcci->dwSize;
986  DeviceExtension->CursorVisible = pcci->bVisible;
987  if (DeviceExtension->Enabled)
988  ScrSetCursorShape(DeviceExtension);
989 
990  Irp->IoStatus.Information = 0;
992  break;
993  }
994 
996  {
997  PCONSOLE_MODE pcm;
998 
999  /* Validate output buffer */
1000  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_MODE))
1001  {
1003  break;
1004  }
1005  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1006 
1007  pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
1008  RtlZeroMemory(pcm, sizeof(CONSOLE_MODE));
1009 
1010  pcm->dwMode = DeviceExtension->Mode;
1011 
1012  Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
1014  break;
1015  }
1016 
1018  {
1019  PCONSOLE_MODE pcm;
1020 
1021  /* Validate input buffer */
1022  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONSOLE_MODE))
1023  {
1025  break;
1026  }
1027  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1028 
1029  pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
1030  DeviceExtension->Mode = pcm->dwMode;
1031 
1032  Irp->IoStatus.Information = 0;
1034  break;
1035  }
1036 
1038  {
1039  POUTPUT_ATTRIBUTE Buf;
1040  PUCHAR vidmem;
1041  ULONG offset;
1042  ULONG dwCount;
1043  ULONG nMaxLength;
1044 
1045  /* Validate input and output buffers */
1046  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE) ||
1047  stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
1048  {
1050  break;
1051  }
1052  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1053 
1054  Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
1055  nMaxLength = Buf->nLength;
1056 
1057  Buf->dwTransfered = 0;
1058  Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
1059 
1060  if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1061  Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
1062  nMaxLength == 0 )
1063  {
1065  break;
1066  }
1067 
1068  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1069  {
1070  vidmem = DeviceExtension->VideoMemory;
1071  offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1072 
1073  nMaxLength = min(nMaxLength,
1074  (DeviceExtension->Rows - Buf->dwCoord.Y)
1075  * DeviceExtension->Columns - Buf->dwCoord.X);
1076 
1077  for (dwCount = 0; dwCount < nMaxLength; dwCount++)
1078  {
1079  vidmem[offset + (dwCount * 2)] = (char)Buf->wAttribute;
1080  }
1081  Buf->dwTransfered = dwCount;
1082  }
1083 
1085  break;
1086  }
1087 
1089  {
1090  POUTPUT_ATTRIBUTE Buf;
1091  PUSHORT pAttr;
1092  PUCHAR vidmem;
1093  ULONG offset;
1094  ULONG dwCount;
1095  ULONG nMaxLength;
1096 
1097  /* Validate input buffer */
1098  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_ATTRIBUTE))
1099  {
1101  break;
1102  }
1103  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1104 
1105  Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
1106  Irp->IoStatus.Information = 0;
1107 
1108  /* Validate output buffer */
1109  if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
1110  {
1112  break;
1113  }
1114  ASSERT(Irp->MdlAddress);
1115  pAttr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1116  if (pAttr == NULL)
1117  {
1119  break;
1120  }
1121 
1122  if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1123  Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
1124  {
1126  break;
1127  }
1128 
1129  nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
1130  nMaxLength /= sizeof(USHORT);
1131 
1132  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1133  {
1134  vidmem = DeviceExtension->VideoMemory;
1135  offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1136 
1137  nMaxLength = min(nMaxLength,
1138  (DeviceExtension->Rows - Buf->dwCoord.Y)
1139  * DeviceExtension->Columns - Buf->dwCoord.X);
1140 
1141  for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
1142  {
1143  *((PCHAR)pAttr) = vidmem[offset + (dwCount * 2)];
1144  }
1145  Irp->IoStatus.Information = dwCount * sizeof(USHORT);
1146  }
1147 
1149  break;
1150  }
1151 
1153  {
1154  COORD dwCoord;
1155  PCOORD pCoord;
1156  PUSHORT pAttr;
1157  PUCHAR vidmem;
1158  ULONG offset;
1159  ULONG dwCount;
1160  ULONG nMaxLength;
1161 
1162  //
1163  // NOTE: For whatever reason no OUTPUT_ATTRIBUTE structure
1164  // is used for this IOCTL.
1165  //
1166 
1167  /* Validate output buffer */
1168  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
1169  {
1171  break;
1172  }
1173  ASSERT(Irp->MdlAddress);
1174  pCoord = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1175  if (pCoord == NULL)
1176  {
1178  break;
1179  }
1180  /* Capture the input info data */
1181  dwCoord = *pCoord;
1182 
1183  nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
1184  nMaxLength /= sizeof(USHORT);
1185 
1186  Irp->IoStatus.Information = 0;
1187 
1188  if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
1189  dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
1190  nMaxLength == 0 )
1191  {
1193  break;
1194  }
1195 
1196  pAttr = (PUSHORT)(pCoord + 1);
1197 
1198  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1199  {
1200  vidmem = DeviceExtension->VideoMemory;
1201  offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2 + 1;
1202 
1203  nMaxLength = min(nMaxLength,
1204  (DeviceExtension->Rows - dwCoord.Y)
1205  * DeviceExtension->Columns - dwCoord.X);
1206 
1207  for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
1208  {
1209  vidmem[offset + (dwCount * 2)] = *((PCHAR)pAttr);
1210  }
1211  Irp->IoStatus.Information = dwCount * sizeof(USHORT);
1212  }
1213 
1215  break;
1216  }
1217 
1219  {
1220  /* Validate input buffer */
1221  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(USHORT))
1222  {
1224  break;
1225  }
1226  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1227 
1228  DeviceExtension->CharAttribute = *(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
1229 
1230  Irp->IoStatus.Information = 0;
1232  break;
1233  }
1234 
1236  {
1237  POUTPUT_CHARACTER Buf;
1238  PUCHAR vidmem;
1239  ULONG offset;
1240  ULONG dwCount;
1241  ULONG nMaxLength;
1242 
1243  /* Validate input and output buffers */
1244  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER) ||
1245  stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OUTPUT_CHARACTER))
1246  {
1248  break;
1249  }
1250  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1251 
1252  Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
1253  nMaxLength = Buf->nLength;
1254 
1255  Buf->dwTransfered = 0;
1256  Irp->IoStatus.Information = sizeof(OUTPUT_CHARACTER);
1257 
1258  if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1259  Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows ||
1260  nMaxLength == 0 )
1261  {
1263  break;
1264  }
1265 
1266  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1267  {
1268  vidmem = DeviceExtension->VideoMemory;
1269  offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2;
1270 
1271  nMaxLength = min(nMaxLength,
1272  (DeviceExtension->Rows - Buf->dwCoord.Y)
1273  * DeviceExtension->Columns - Buf->dwCoord.X);
1274 
1275  for (dwCount = 0; dwCount < nMaxLength; dwCount++)
1276  {
1277  vidmem[offset + (dwCount * 2)] = (char)Buf->cCharacter;
1278  }
1279  Buf->dwTransfered = dwCount;
1280  }
1281 
1283  break;
1284  }
1285 
1287  {
1288  POUTPUT_CHARACTER Buf;
1289  PCHAR pChar;
1290  PUCHAR vidmem;
1291  ULONG offset;
1292  ULONG dwCount;
1293  ULONG nMaxLength;
1294 
1295  /* Validate input buffer */
1296  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(OUTPUT_CHARACTER))
1297  {
1299  break;
1300  }
1301  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1302 
1303  Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
1304  Irp->IoStatus.Information = 0;
1305 
1306  /* Validate output buffer */
1307  if (stk->Parameters.DeviceIoControl.OutputBufferLength == 0)
1308  {
1310  break;
1311  }
1312  ASSERT(Irp->MdlAddress);
1313  pChar = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1314  if (pChar == NULL)
1315  {
1317  break;
1318  }
1319 
1320  if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
1321  Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
1322  {
1324  break;
1325  }
1326 
1327  nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength;
1328 
1329  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1330  {
1331  vidmem = DeviceExtension->VideoMemory;
1332  offset = (Buf->dwCoord.X + Buf->dwCoord.Y * DeviceExtension->Columns) * 2;
1333 
1334  nMaxLength = min(nMaxLength,
1335  (DeviceExtension->Rows - Buf->dwCoord.Y)
1336  * DeviceExtension->Columns - Buf->dwCoord.X);
1337 
1338  for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
1339  {
1340  *pChar = vidmem[offset + (dwCount * 2)];
1341  }
1342  Irp->IoStatus.Information = dwCount * sizeof(CHAR);
1343  }
1344 
1346  break;
1347  }
1348 
1350  {
1351  COORD dwCoord;
1352  PCOORD pCoord;
1353  PCHAR pChar;
1354  PUCHAR vidmem;
1355  ULONG offset;
1356  ULONG dwCount;
1357  ULONG nMaxLength;
1358 
1359  //
1360  // NOTE: For whatever reason no OUTPUT_CHARACTER structure
1361  // is used for this IOCTL.
1362  //
1363 
1364  /* Validate output buffer */
1365  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(COORD))
1366  {
1368  break;
1369  }
1370  ASSERT(Irp->MdlAddress);
1371  pCoord = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1372  if (pCoord == NULL)
1373  {
1375  break;
1376  }
1377  /* Capture the input info data */
1378  dwCoord = *pCoord;
1379 
1380  nMaxLength = stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD);
1381  Irp->IoStatus.Information = 0;
1382 
1383  if ( dwCoord.X < 0 || dwCoord.X >= DeviceExtension->Columns ||
1384  dwCoord.Y < 0 || dwCoord.Y >= DeviceExtension->Rows ||
1385  nMaxLength == 0 )
1386  {
1388  break;
1389  }
1390 
1391  pChar = (PCHAR)(pCoord + 1);
1392 
1393  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1394  {
1395  vidmem = DeviceExtension->VideoMemory;
1396  offset = (dwCoord.X + dwCoord.Y * DeviceExtension->Columns) * 2;
1397 
1398  nMaxLength = min(nMaxLength,
1399  (DeviceExtension->Rows - dwCoord.Y)
1400  * DeviceExtension->Columns - dwCoord.X);
1401 
1402  for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
1403  {
1404  vidmem[offset + (dwCount * 2)] = *pChar;
1405  }
1406  Irp->IoStatus.Information = dwCount * sizeof(CHAR);
1407  }
1408 
1410  break;
1411  }
1412 
1413  case IOCTL_CONSOLE_DRAW:
1414  {
1415  CONSOLE_DRAW ConsoleDraw;
1416  PCONSOLE_DRAW pConsoleDraw;
1417  PUCHAR Src, Dest;
1418  UINT32 SrcDelta, DestDelta, i;
1419 
1420  /* Validate output buffer */
1421  if (stk->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CONSOLE_DRAW))
1422  {
1424  break;
1425  }
1426  ASSERT(Irp->MdlAddress);
1427  pConsoleDraw = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
1428  if (pConsoleDraw == NULL)
1429  {
1431  break;
1432  }
1433  /* Capture the input info data */
1434  ConsoleDraw = *pConsoleDraw;
1435 
1436  /* Check whether we have the size for the header plus the data area */
1437  if ((stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(CONSOLE_DRAW)) / 2
1438  < ((ULONG)ConsoleDraw.SizeX * (ULONG)ConsoleDraw.SizeY))
1439  {
1441  break;
1442  }
1443 
1444  // TODO: For the moment if the ConsoleDraw rectangle has borders
1445  // out of the screen-buffer we just bail out. Would it be better
1446  // to actually clip the rectangle within its borders instead?
1447  if ( ConsoleDraw.X < 0 || ConsoleDraw.X >= DeviceExtension->Columns ||
1448  ConsoleDraw.Y < 0 || ConsoleDraw.Y >= DeviceExtension->Rows )
1449  {
1451  break;
1452  }
1453  if ( ConsoleDraw.SizeX >= DeviceExtension->Columns - ConsoleDraw.X ||
1454  ConsoleDraw.SizeY >= DeviceExtension->Rows - ConsoleDraw.Y )
1455  {
1457  break;
1458  }
1459 
1460  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1461  {
1462  Src = (PUCHAR)(pConsoleDraw + 1);
1463  SrcDelta = ConsoleDraw.SizeX * 2;
1464  Dest = DeviceExtension->VideoMemory +
1465  (ConsoleDraw.X + ConsoleDraw.Y * DeviceExtension->Columns) * 2;
1466  DestDelta = DeviceExtension->Columns * 2;
1467  /* 2 == sizeof(CHAR) + sizeof(BYTE) */
1468 
1469  /* Copy each line */
1470  for (i = 0; i < ConsoleDraw.SizeY; i++)
1471  {
1472  RtlCopyMemory(Dest, Src, SrcDelta);
1473  Src += SrcDelta;
1474  Dest += DestDelta;
1475  }
1476  }
1477 
1478  /* Set the cursor position, clipping it to the screen */
1479  DeviceExtension->CursorX = min(max(ConsoleDraw.CursorX, 0), DeviceExtension->Columns - 1);
1480  DeviceExtension->CursorY = min(max(ConsoleDraw.CursorY, 0), DeviceExtension->Rows - 1);
1481  if (DeviceExtension->Enabled)
1482  ScrSetCursor(DeviceExtension);
1483 
1484  Irp->IoStatus.Information = 0;
1486  break;
1487  }
1488 
1490  {
1491  /* Validate input buffer */
1492  if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
1493  {
1495  break;
1496  }
1497  ASSERT(Irp->AssociatedIrp.SystemBuffer);
1498 
1499  DeviceExtension->CodePage = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
1500 
1501  /* Upload a font for the codepage if needed */
1502  if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
1503  ScrLoadFontTable(DeviceExtension->CodePage);
1504 
1505  Irp->IoStatus.Information = 0;
1507  break;
1508  }
1509 
1510  default:
1512  }
1513 
1514  Irp->IoStatus.Status = Status;
1516 
1517  return Status;
1518 }
1519 
1521 static NTSTATUS
1522 NTAPI
1525  _In_ PIRP Irp)
1526 {
1528 
1530 
1531  DPRINT1("ScrDispatch(0x%p): stk->MajorFunction = %lu UNIMPLEMENTED\n",
1532  DeviceObject, stk->MajorFunction);
1533 
1534  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1536  return STATUS_NOT_IMPLEMENTED;
1537 }
1538 
1539 /*
1540  * Module entry point
1541  */
1542 NTSTATUS
1543 NTAPI
1547 {
1548  NTSTATUS Status;
1550  UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen");
1551  UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
1552 
1553  DPRINT("Screen Driver 0.0.6\n");
1554 
1560 
1562  sizeof(DEVICE_EXTENSION),
1563  &DeviceName,
1566  TRUE,
1567  &DeviceObject);
1568  if (!NT_SUCCESS(Status))
1569  {
1570  return Status;
1571  }
1572 
1573  Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
1574  if (NT_SUCCESS(Status))
1575  {
1576  /* By default disable the screen (but don't touch INBV: ResetDisplayParametersDeviceExtension is still NULL) */
1578  /* Now set ResetDisplayParametersDeviceExtension to enable synchronizing with INBV */
1581  }
1582  else
1583  {
1585  }
1586  return Status;
1587 }
1588 
1589 /* EOF */
#define CRTC_SCANLINES
Definition: blue.h:108
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
struct tagCONSOLE_CURSOR_INFO * PCONSOLE_CURSOR_INFO
#define CRTCDATA
Definition: blue.h:138
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
VOID NTAPI InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback)
Definition: inbv.c:641
#define GRAPHICSDATA
Definition: blue.h:140
#define max(a, b)
Definition: svc.c:63
PBYTE vidmem
Definition: vgavideo.c:18
static VOID FASTCALL ScrSetCursorShape(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:382
#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:15
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
Definition: ntddblue.h:7
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT SizeX
Definition: ntddblue.h:53
#define FILE_DEVICE_SCREEN
Definition: winioctl.h:133
USHORT CursorX
Definition: blue.c:40
#define IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
Definition: ntddblue.h:16
static VOID FASTCALL ScrSetCursor(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:362
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct _DEVICE_EXTENSION DEVICE_EXTENSION
static const VGA_REGISTERS VidpMode3Regs
Definition: blue.c:53
UCHAR Sequencer[5]
Definition: blue.c:49
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct tagOUTPUT_CHARACTER OUTPUT_CHARACTER
unsigned char * PUCHAR
Definition: retypes.h:3
static BOOLEAN InbvMonitoring
Definition: blue.c:99
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
void __cdecl _enable(void)
Definition: intrin_arm.h:373
LONG NTSTATUS
Definition: precomp.h:26
struct tagCONSOLE_SCREEN_BUFFER_INFO CONSOLE_SCREEN_BUFFER_INFO
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
GLintptr offset
Definition: glext.h:5920
#define FILE_OPENED
Definition: nt_native.h:769
static DRIVER_DISPATCH ScrDispatch
Definition: blue.c:1520
PUCHAR ScreenBuffer
Definition: blue.c:31
ULONG CursorSize
Definition: blue.c:33
#define CRTC_CURSORPOSHI
Definition: blue.h:111
#define LOW_REALTIME_PRIORITY
struct tagCONSOLE_MODE * PCONSOLE_MODE
#define ATTRIB
Definition: blue.h:141
struct Line * LinePtr
Definition: ncftp.h:78
#define IOCTL_CONSOLE_SET_CURSOR_INFO
Definition: ntddblue.h:9
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define MISC
Definition: blue.h:134
static BOOLEAN ScrResetScreen(_In_ PDEVICE_EXTENSION DeviceExtension, _In_ BOOLEAN FullReset, _In_ BOOLEAN Enable)
Definition: blue.c:496
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define PELMASK
Definition: blue.h:143
#define FASTCALL
Definition: nt_native.h:50
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
int32_t INT
Definition: typedefs.h:57
#define pch(ap)
Definition: match.c:418
#define CRTC_ROWS
Definition: blue.h:107
#define IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
Definition: ntddblue.h:18
PUCHAR VideoMemory
Definition: blue.c:28
#define ENABLE_WRAP_AT_EOL_OUTPUT
Definition: blue.h:54
static const UCHAR DefaultPalette[]
Definition: blue.c:69
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
static DRIVER_DISPATCH ScrCreateClose
Definition: blue.c:661
#define CRTC_COLUMNS
Definition: blue.h:105
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned int UINT32
static DRIVER_DISPATCH ScrWrite
Definition: blue.c:681
#define CRTC_DATA
Definition: blue.h:103
#define VIDMEM_BASE
Definition: blue.h:99
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
struct _VGA_REGISTERS * PVGA_REGISTERS
#define ATTRC_INPST1
Definition: blue.h:132
USHORT CursorY
Definition: blue.c:40
#define IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:13
UCHAR Misc
Definition: blue.c:50
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
_In_ ULONG Rows
Definition: haltypes.h:7
USHORT Rows
Definition: blue.c:38
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define IOCTL_CONSOLE_GET_CURSOR_INFO
Definition: ntddblue.h:8
void DPRINT(...)
Definition: polytest.cpp:61
UCHAR Graphics[9]
Definition: blue.c:48
#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
Definition: ntddblue.h:14
static VOID FASTCALL ScrAcquireOwnership(_In_ PDEVICE_EXTENSION DeviceExtension)
Definition: blue.c:411
static BOOLEAN NTAPI ScrResetDisplayParametersEx(_In_ ULONG Columns, _In_ ULONG Rows, _In_ BOOLEAN CalledByInbv)
Definition: blue.c:118
#define ATTRC_WRITEREG
Definition: blue.h:130
struct _VGA_REGISTERS VGA_REGISTERS
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 PCHAR
Definition: match.c:90
SHORT Left
Definition: blue.h:32
ULONG X
Definition: bl.h:1340
#define SEQ
Definition: blue.h:135
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
#define TAG_BLUE
Definition: blue.h:14
struct _COORD COORD
int64_t LONGLONG
Definition: typedefs.h:67
#define PELINDEX
Definition: blue.h:144
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
USHORT CursorX
Definition: ntddblue.h:55
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
GLsizeiptr size
Definition: glext.h:5919
SHORT Bottom
Definition: blue.h:35
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG CodePage
Definition: blue.c:41
#define IOCTL_CONSOLE_GET_MODE
Definition: ntddblue.h:10
static const UCHAR Index[8]
Definition: usbohci.c:18
#define STATUS
Definition: blue.h:142
#define CRTC_CURSOREND
Definition: blue.h:110
SHORT Top
Definition: blue.h:33
UCHAR CRT[24]
Definition: blue.c:46
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Definition: ncftp.h:79
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IO_VIDEO_INCREMENT
Definition: iotypes.h:577
static NTSTATUS ScrInbvInitialize(VOID)
Definition: blue.c:251
unsigned char UCHAR
Definition: xmlstorage.h:181
static BOOLEAN NTAPI ScrResetDisplayParameters(_In_ ULONG Columns, _In_ ULONG Rows)
Definition: blue.c:146
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
#define CRTC_CURSORPOSLO
Definition: blue.h:112
UCHAR Attribute[21]
Definition: blue.c:47
USHORT CursorY
Definition: ntddblue.h:56
static DRIVER_DISPATCH ScrIoControl
Definition: blue.c:839
#define CRTC
Definition: blue.h:137
#define IOCTL_CONSOLE_RESET_SCREEN
Definition: ntddblue.h:4
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define CRTC_OVERFLOW
Definition: blue.h:106
GLsizei const GLfloat * value
Definition: glext.h:6069
Definition: bl.h:1338
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
static VOID NTAPI InbvMonitorThread(_In_ PVOID Context)
Definition: blue.c:188
#define IOCTL_CONSOLE_DRAW
Definition: ntddblue.h:22
Status
Definition: gdiplustypes.h:24
#define ENABLE_PROCESSED_OUTPUT
Definition: blue.h:53
SIZE_T VideoMemorySize
Definition: blue.c:29
#define SEQDATA
Definition: blue.h:136
static HANDLE InbvThreadHandle
Definition: blue.c:98
#define _In_
Definition: no_sal2.h:204
ULONG dwMode
Definition: ntddblue.h:30
#define FOREGROUND_LIGHTGRAY
USHORT CharAttribute
Definition: blue.c:35
SIZE_T ScreenBufferSize
Definition: blue.c:32
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct tagOUTPUT_CHARACTER * POUTPUT_CHARACTER
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:79
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
static NTSTATUS ScrInbvCleanup(VOID)
Definition: blue.c:277
static const COLUMN_LIST Columns[]
Definition: listview.c:19
USHORT SizeY
Definition: ntddblue.h:54
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
unsigned short USHORT
Definition: pedump.c:61
#define TAB_WIDTH
Definition: blue.h:16
#define IOCTL_CONSOLE_SET_MODE
Definition: ntddblue.h:11
struct tagCONSOLE_MODE CONSOLE_MODE
BOOLEAN Enabled
Definition: blue.c:30
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
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 IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
Definition: ntddblue.h:19
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define CRTC_COMMAND
Definition: blue.h:102
struct tagOUTPUT_ATTRIBUTE * POUTPUT_ATTRIBUTE
#define IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
Definition: ntddblue.h:6
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
ULONG Mode
Definition: blue.c:36
#define IOCTL_CONSOLE_LOADFONT
Definition: ntddblue.h:24
#define GRAPHICS
Definition: blue.h:139
#define PELDATA
Definition: blue.h:145
struct _DEVICE_EXTENSION * PDEVICE_EXTENSION
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
static int processed(const type_t *type)
Definition: typegen.c:2236
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define BACKGROUND_BLUE
Definition: blue.h:65
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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 WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
USHORT Columns
Definition: blue.c:39
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:28
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
Definition: ntddblue.h:20
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
SHORT Right
Definition: blue.h:34
BOOLEAN NTAPI InbvCheckDisplayOwnership(VOID)
Definition: inbv.c:556
#define KeGetCurrentThread
Definition: hal.h:44
struct tagCONSOLE_SCREEN_BUFFER_INFO * PCONSOLE_SCREEN_BUFFER_INFO
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
static VOID FASTCALL ScrSetRegisters(const VGA_REGISTERS *Registers)
Definition: blue.c:308
static PDEVICE_EXTENSION ResetDisplayParametersDeviceExtension
Definition: blue.c:97
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG Y
Definition: bl.h:1341
INT CursorVisible
Definition: blue.c:34
#define CHAR(Char)
struct tagCONSOLE_CURSOR_INFO CONSOLE_CURSOR_INFO
#define ATTRC_READREG
Definition: blue.h:131
struct tagOUTPUT_ATTRIBUTE OUTPUT_ATTRIBUTE
unsigned short * PUSHORT
Definition: retypes.h:2
#define CRTC_CURSORSTART
Definition: blue.h:109
VOID ScrLoadFontTable(_In_ ULONG CodePage)
Definition: font.c:26
LONGLONG QuadPart
Definition: typedefs.h:113
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
NTSTATUS NTAPI DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
Definition: blue.c:1544
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
UCHAR ScanLines
Definition: blue.c:37