2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: services/dd/blue/blue.c
5 * PURPOSE: Console (blue screen) device driver
6 * PROGRAMMER: Eric Kohl
11 /* INCLUDES ******************************************************************/
18 // ROS Internal. Please deprecate.
22 HalQueryDisplayOwnership(
26 /* NOTES ******************************************************************/
28 * [[character][attribute]][[character][attribute]]....
32 /* TYPEDEFS ***************************************************************/
34 typedef struct _DEVICE_EXTENSION
36 PUCHAR VideoMemory
; /* Pointer to video memory */
41 UCHAR ScanLines
; /* Height of a text line */
42 USHORT Rows
; /* Number of rows */
43 USHORT Columns
; /* Number of columns */
44 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
46 typedef struct _VGA_REGISTERS
53 } VGA_REGISTERS
, *PVGA_REGISTERS
;
55 static const VGA_REGISTERS VidpMode3Regs
=
57 /* CRT Controller Registers */
58 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
59 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
60 /* Attribute Controller Registers */
61 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
62 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
63 /* Graphics Controller Registers */
64 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
65 /* Sequencer Registers */
66 {0x03, 0x00, 0x03, 0x00, 0x02},
67 /* Misc Output Register */
71 static const UCHAR DefaultPalette
[] =
91 static FAST_IO_DISPATCH ScrFastIoDispatch
;
93 /* FUNCTIONS **************************************************************/
96 ScrSetRegisters(const VGA_REGISTERS
*Registers
)
100 /* Update misc output register */
101 WRITE_PORT_UCHAR(MISC
, Registers
->Misc
);
103 /* Synchronous reset on */
104 WRITE_PORT_UCHAR(SEQ
, 0x00);
105 WRITE_PORT_UCHAR(SEQDATA
, 0x01);
107 /* Write sequencer registers */
108 for (i
= 1; i
< sizeof(Registers
->Sequencer
); i
++)
110 WRITE_PORT_UCHAR(SEQ
, i
);
111 WRITE_PORT_UCHAR(SEQDATA
, Registers
->Sequencer
[i
]);
114 /* Synchronous reset off */
115 WRITE_PORT_UCHAR(SEQ
, 0x00);
116 WRITE_PORT_UCHAR(SEQDATA
, 0x03);
118 /* Deprotect CRT registers 0-7 */
119 WRITE_PORT_UCHAR(CRTC
, 0x11);
120 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[0x11] & 0x7f);
122 /* Write CRT registers */
123 for (i
= 0; i
< sizeof(Registers
->CRT
); i
++)
125 WRITE_PORT_UCHAR(CRTC
, i
);
126 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[i
]);
129 /* Write graphics controller registers */
130 for (i
= 0; i
< sizeof(Registers
->Graphics
); i
++)
132 WRITE_PORT_UCHAR(GRAPHICS
, i
);
133 WRITE_PORT_UCHAR(GRAPHICSDATA
, Registers
->Graphics
[i
]);
136 /* Write attribute controller registers */
137 for (i
= 0; i
< sizeof(Registers
->Attribute
); i
++)
139 READ_PORT_UCHAR(STATUS
);
140 WRITE_PORT_UCHAR(ATTRIB
, i
);
141 WRITE_PORT_UCHAR(ATTRIB
, Registers
->Attribute
[i
]);
144 /* Set the PEL mask. */
145 WRITE_PORT_UCHAR(PELMASK
, 0xff);
149 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension
)
155 ScrSetRegisters(&VidpMode3Regs
);
157 /* Disable screen and enable palette access. */
158 READ_PORT_UCHAR(STATUS
);
159 WRITE_PORT_UCHAR(ATTRIB
, 0x00);
161 for (Index
= 0; Index
< sizeof(DefaultPalette
) / 3; Index
++)
163 WRITE_PORT_UCHAR(PELINDEX
, Index
);
164 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3] >> 2);
165 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 1] >> 2);
166 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 2] >> 2);
169 /* Enable screen and disable palette access. */
170 READ_PORT_UCHAR(STATUS
);
171 WRITE_PORT_UCHAR(ATTRIB
, 0x20);
173 /* get current output position */
174 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
175 offset
= READ_PORT_UCHAR (CRTC_DATA
);
176 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
177 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
179 /* switch blinking characters off */
180 READ_PORT_UCHAR (ATTRC_INPST1
);
181 value
= READ_PORT_UCHAR (ATTRC_WRITEREG
);
182 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, 0x10);
183 data
= READ_PORT_UCHAR (ATTRC_READREG
);
185 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, data
);
186 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, value
);
187 READ_PORT_UCHAR (ATTRC_INPST1
);
189 /* read screen information from crt controller */
190 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_COLUMNS
);
191 DeviceExtension
->Columns
= READ_PORT_UCHAR (CRTC_DATA
) + 1;
192 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_ROWS
);
193 DeviceExtension
->Rows
= READ_PORT_UCHAR (CRTC_DATA
);
194 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_OVERFLOW
);
195 data
= READ_PORT_UCHAR (CRTC_DATA
);
196 DeviceExtension
->Rows
|= (((data
& 0x02) << 7) | ((data
& 0x40) << 3));
197 DeviceExtension
->Rows
++;
198 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_SCANLINES
);
199 DeviceExtension
->ScanLines
= (READ_PORT_UCHAR (CRTC_DATA
) & 0x1F) + 1;
201 /* show blinking cursor */
202 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
203 WRITE_PORT_UCHAR (CRTC_DATA
, (DeviceExtension
->ScanLines
- 1) & 0x1F);
204 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
205 data
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
206 WRITE_PORT_UCHAR (CRTC_DATA
,
207 data
| ((DeviceExtension
->ScanLines
- 1) & 0x1F));
209 /* calculate number of text rows */
210 DeviceExtension
->Rows
=
211 DeviceExtension
->Rows
/ DeviceExtension
->ScanLines
;
213 DeviceExtension
->Rows
= 30;
216 DPRINT ("%d Columns %d Rows %d Scanlines\n",
217 DeviceExtension
->Columns
,
218 DeviceExtension
->Rows
,
219 DeviceExtension
->ScanLines
);
223 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
225 static DRIVER_DISPATCH ScrCreate
;
226 static NTSTATUS NTAPI
227 ScrCreate(PDEVICE_OBJECT DeviceObject
,
230 PDEVICE_EXTENSION DeviceExtension
;
231 PHYSICAL_ADDRESS BaseAddress
;
234 DeviceExtension
= DeviceObject
->DeviceExtension
;
236 if (!InbvCheckDisplayOwnership())
238 ScrAcquireOwnership(DeviceExtension
);
240 /* get pointer to video memory */
241 BaseAddress
.QuadPart
= VIDMEM_BASE
;
242 DeviceExtension
->VideoMemory
=
243 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
247 /* store dummy values here */
248 DeviceExtension
->Columns
= 1;
249 DeviceExtension
->Rows
= 1;
250 DeviceExtension
->ScanLines
= 1;
253 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
254 DeviceExtension
->CursorVisible
= TRUE
;
256 /* more initialization */
257 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
258 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
259 ENABLE_WRAP_AT_EOL_OUTPUT
;
261 Status
= STATUS_SUCCESS
;
263 Irp
->IoStatus
.Status
= Status
;
264 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
269 static DRIVER_DISPATCH ScrWrite
;
270 static NTSTATUS NTAPI
271 ScrWrite(PDEVICE_OBJECT DeviceObject
,
274 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
275 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
277 char *pch
= Irp
->UserBuffer
;
281 int cursorx
, cursory
;
283 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
285 if (InbvCheckDisplayOwnership())
287 /* Display is in graphics mode, we're not allowed to touch it */
288 Status
= STATUS_SUCCESS
;
290 Irp
->IoStatus
.Status
= Status
;
291 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
296 vidmem
= DeviceExtension
->VideoMemory
;
297 rows
= DeviceExtension
->Rows
;
298 columns
= DeviceExtension
->Columns
;
301 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
302 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
303 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
304 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
307 cursory
= offset
/ columns
;
308 cursorx
= offset
% columns
;
311 /* raw output mode */
312 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
313 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
316 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
325 else if (cursory
> 0)
327 cursorx
= columns
- 1;
330 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
331 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
344 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
345 for (j
= 0; j
< offset
; j
++)
347 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
350 if (cursorx
>= columns
)
359 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
360 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
362 if (cursorx
>= columns
)
371 unsigned short *LinePtr
;
374 &vidmem
[columns
* 2],
375 columns
* (rows
- 1) * 2);
377 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
379 for (j
= 0; j
< columns
; j
++)
381 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
384 for (j
= 0; j
< columns
; j
++)
386 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
387 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
392 /* Set the cursor position */
393 offset
= (cursory
* columns
) + cursorx
;
396 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
397 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
398 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
400 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
403 Status
= STATUS_SUCCESS
;
405 Irp
->IoStatus
.Status
= Status
;
406 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
411 static DRIVER_DISPATCH ScrIoControl
;
412 static NTSTATUS NTAPI
413 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
416 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
417 PDEVICE_EXTENSION DeviceExtension
;
420 DeviceExtension
= DeviceObject
->DeviceExtension
;
421 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
423 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
425 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
426 int rows
= DeviceExtension
->Rows
;
427 int columns
= DeviceExtension
->Columns
;
430 if (!InbvCheckDisplayOwnership())
432 /* read cursor position from crtc */
434 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
435 offset
= READ_PORT_UCHAR (CRTC_DATA
);
436 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
437 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
445 pcsbi
->dwSize
.X
= columns
;
446 pcsbi
->dwSize
.Y
= rows
;
448 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
449 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
451 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
453 pcsbi
->srWindow
.Left
= 0;
454 pcsbi
->srWindow
.Right
= columns
- 1;
455 pcsbi
->srWindow
.Top
= 0;
456 pcsbi
->srWindow
.Bottom
= rows
- 1;
458 pcsbi
->dwMaximumWindowSize
.X
= columns
;
459 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
461 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
462 Status
= STATUS_SUCCESS
;
466 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
468 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
471 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
472 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
473 pcsbi
->dwCursorPosition
.X
;
475 if (!InbvCheckDisplayOwnership())
478 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
479 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
480 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
481 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
485 Irp
->IoStatus
.Information
= 0;
486 Status
= STATUS_SUCCESS
;
490 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
492 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
494 pcci
->dwSize
= DeviceExtension
->CursorSize
;
495 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
497 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
498 Status
= STATUS_SUCCESS
;
502 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
504 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
508 DeviceExtension
->CursorSize
= pcci
->dwSize
;
509 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
511 if (!InbvCheckDisplayOwnership())
513 height
= DeviceExtension
->ScanLines
;
514 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
516 size
= (pcci
->dwSize
* height
) / 100;
522 data
|= (UCHAR
)(height
- size
);
525 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
526 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
527 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
528 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
529 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
534 Irp
->IoStatus
.Information
= 0;
535 Status
= STATUS_SUCCESS
;
539 case IOCTL_CONSOLE_GET_MODE
:
541 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
543 pcm
->dwMode
= DeviceExtension
->Mode
;
545 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
546 Status
= STATUS_SUCCESS
;
550 case IOCTL_CONSOLE_SET_MODE
:
552 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
554 DeviceExtension
->Mode
= pcm
->dwMode
;
556 Irp
->IoStatus
.Information
= 0;
557 Status
= STATUS_SUCCESS
;
561 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
563 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
568 if (!InbvCheckDisplayOwnership())
570 vidmem
= DeviceExtension
->VideoMemory
;
571 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
572 (Buf
->dwCoord
.X
* 2) + 1;
574 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
576 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
580 Buf
->dwTransfered
= Buf
->nLength
;
582 Irp
->IoStatus
.Information
= 0;
583 Status
= STATUS_SUCCESS
;
587 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
589 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
590 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
595 if (!InbvCheckDisplayOwnership())
597 vidmem
= DeviceExtension
->VideoMemory
;
598 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
599 (Buf
->dwCoord
.X
* 2) + 1;
601 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pAttr
++)
603 *((char *) pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
606 Buf
->dwTransfered
= dwCount
;
610 Buf
->dwTransfered
= 0;
613 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
614 Status
= STATUS_SUCCESS
;
618 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
620 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
621 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
626 if (!InbvCheckDisplayOwnership())
628 vidmem
= DeviceExtension
->VideoMemory
;
629 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
632 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pAttr
++)
634 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
638 Irp
->IoStatus
.Information
= 0;
639 Status
= STATUS_SUCCESS
;
643 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
644 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
645 Irp
->IoStatus
.Information
= 0;
646 Status
= STATUS_SUCCESS
;
649 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
651 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
656 if (!InbvCheckDisplayOwnership())
658 vidmem
= DeviceExtension
->VideoMemory
;
659 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
660 (Buf
->dwCoord
.X
* 2);
663 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
665 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
669 Buf
->dwTransfered
= Buf
->nLength
;
671 Irp
->IoStatus
.Information
= 0;
672 Status
= STATUS_SUCCESS
;
676 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
678 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
679 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
684 if (!InbvCheckDisplayOwnership())
686 vidmem
= DeviceExtension
->VideoMemory
;
687 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
688 (Buf
->dwCoord
.X
* 2);
690 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pChar
++)
692 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
695 Buf
->dwTransfered
= dwCount
;
699 Buf
->dwTransfered
= 0;
702 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
703 Status
= STATUS_SUCCESS
;
707 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
715 if (!InbvCheckDisplayOwnership())
717 pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
718 pChar
= (CHAR
*)(pCoord
+ 1);
719 vidmem
= DeviceExtension
->VideoMemory
;
720 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
723 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pChar
++)
725 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
729 Irp
->IoStatus
.Information
= 0;
730 Status
= STATUS_SUCCESS
;
734 case IOCTL_CONSOLE_DRAW
:
736 PCONSOLE_DRAW ConsoleDraw
;
738 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
740 if (!InbvCheckDisplayOwnership())
742 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
743 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
744 SrcDelta
= ConsoleDraw
->SizeX
* 2;
745 Dest
= DeviceExtension
->VideoMemory
+
746 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
747 DestDelta
= DeviceExtension
->Columns
* 2;
749 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
751 RtlCopyMemory(Dest
, Src
, SrcDelta
);
756 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
757 ConsoleDraw
->CursorX
;
760 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
761 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
762 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
763 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
767 Irp
->IoStatus
.Information
= 0;
768 Status
= STATUS_SUCCESS
;
772 case IOCTL_CONSOLE_LOADFONT
:
774 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
776 if (!InbvCheckDisplayOwnership())
778 // Upload a font for the codepage if needed
779 ScrLoadFontTable(CodePage
);
782 Irp
->IoStatus
.Information
= 0;
783 Status
= STATUS_SUCCESS
;
788 Status
= STATUS_NOT_IMPLEMENTED
;
791 Irp
->IoStatus
.Status
= Status
;
792 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
797 static DRIVER_DISPATCH ScrDispatch
;
798 static NTSTATUS NTAPI
799 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
802 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
805 switch (stk
->MajorFunction
)
808 Status
= STATUS_SUCCESS
;
812 Status
= STATUS_NOT_IMPLEMENTED
;
817 Irp
->IoStatus
.Status
= Status
;
818 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
823 static FAST_IO_READ ScrFastIoRead
;
828 _In_ PFILE_OBJECT FileObject
,
829 _In_ PLARGE_INTEGER FileOffset
,
834 _Out_ PIO_STATUS_BLOCK IoStatus
,
835 _In_ PDEVICE_OBJECT DeviceObject
)
837 DBG_UNREFERENCED_PARAMETER(FileObject
);
838 DBG_UNREFERENCED_PARAMETER(FileOffset
);
839 DBG_UNREFERENCED_PARAMETER(Length
);
840 DBG_UNREFERENCED_PARAMETER(Wait
);
841 DBG_UNREFERENCED_PARAMETER(LockKey
);
842 DBG_UNREFERENCED_PARAMETER(Buffer
);
843 DBG_UNREFERENCED_PARAMETER(IoStatus
);
844 DBG_UNREFERENCED_PARAMETER(DeviceObject
);
848 static FAST_IO_WRITE ScrFastIoWrite
;
853 _In_ PFILE_OBJECT FileObject
,
854 _In_ PLARGE_INTEGER FileOffset
,
859 _Out_ PIO_STATUS_BLOCK IoStatus
,
860 _In_ PDEVICE_OBJECT DeviceObject
)
862 DBG_UNREFERENCED_PARAMETER(FileObject
);
863 DBG_UNREFERENCED_PARAMETER(FileOffset
);
864 DBG_UNREFERENCED_PARAMETER(Length
);
865 DBG_UNREFERENCED_PARAMETER(Wait
);
866 DBG_UNREFERENCED_PARAMETER(LockKey
);
867 DBG_UNREFERENCED_PARAMETER(Buffer
);
868 DBG_UNREFERENCED_PARAMETER(IoStatus
);
869 DBG_UNREFERENCED_PARAMETER(DeviceObject
);
877 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
879 PDEVICE_OBJECT DeviceObject
;
881 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
882 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
884 DPRINT ("Screen Driver 0.0.6\n");
886 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
887 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
888 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
889 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
890 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
892 ScrFastIoDispatch
.FastIoRead
= ScrFastIoRead
;
893 ScrFastIoDispatch
.FastIoWrite
= ScrFastIoWrite
;
894 DriverObject
->FastIoDispatch
= &ScrFastIoDispatch
;
896 Status
= IoCreateDevice (DriverObject
,
897 sizeof(DEVICE_EXTENSION
),
900 FILE_DEVICE_SECURE_OPEN
,
904 if (!NT_SUCCESS(Status
))
909 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
910 if (NT_SUCCESS(Status
))
911 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
913 IoDeleteDevice (DeviceObject
);