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 /* FUNCTIONS **************************************************************/
94 ScrSetRegisters(const VGA_REGISTERS
*Registers
)
98 /* Update misc output register */
99 WRITE_PORT_UCHAR(MISC
, Registers
->Misc
);
101 /* Synchronous reset on */
102 WRITE_PORT_UCHAR(SEQ
, 0x00);
103 WRITE_PORT_UCHAR(SEQDATA
, 0x01);
105 /* Write sequencer registers */
106 for (i
= 1; i
< sizeof(Registers
->Sequencer
); i
++)
108 WRITE_PORT_UCHAR(SEQ
, i
);
109 WRITE_PORT_UCHAR(SEQDATA
, Registers
->Sequencer
[i
]);
112 /* Synchronous reset off */
113 WRITE_PORT_UCHAR(SEQ
, 0x00);
114 WRITE_PORT_UCHAR(SEQDATA
, 0x03);
116 /* Deprotect CRT registers 0-7 */
117 WRITE_PORT_UCHAR(CRTC
, 0x11);
118 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[0x11] & 0x7f);
120 /* Write CRT registers */
121 for (i
= 0; i
< sizeof(Registers
->CRT
); i
++)
123 WRITE_PORT_UCHAR(CRTC
, i
);
124 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[i
]);
127 /* Write graphics controller registers */
128 for (i
= 0; i
< sizeof(Registers
->Graphics
); i
++)
130 WRITE_PORT_UCHAR(GRAPHICS
, i
);
131 WRITE_PORT_UCHAR(GRAPHICSDATA
, Registers
->Graphics
[i
]);
134 /* Write attribute controller registers */
135 for (i
= 0; i
< sizeof(Registers
->Attribute
); i
++)
137 READ_PORT_UCHAR(STATUS
);
138 WRITE_PORT_UCHAR(ATTRIB
, i
);
139 WRITE_PORT_UCHAR(ATTRIB
, Registers
->Attribute
[i
]);
142 /* Set the PEL mask. */
143 WRITE_PORT_UCHAR(PELMASK
, 0xff);
147 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension
)
153 ScrSetRegisters(&VidpMode3Regs
);
155 /* Disable screen and enable palette access. */
156 READ_PORT_UCHAR(STATUS
);
157 WRITE_PORT_UCHAR(ATTRIB
, 0x00);
159 for (Index
= 0; Index
< sizeof(DefaultPalette
) / 3; Index
++)
161 WRITE_PORT_UCHAR(PELINDEX
, Index
);
162 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3] >> 2);
163 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 1] >> 2);
164 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 2] >> 2);
167 /* Enable screen and disable palette access. */
168 READ_PORT_UCHAR(STATUS
);
169 WRITE_PORT_UCHAR(ATTRIB
, 0x20);
171 /* get current output position */
172 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
173 offset
= READ_PORT_UCHAR (CRTC_DATA
);
174 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
175 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
177 /* switch blinking characters off */
178 READ_PORT_UCHAR (ATTRC_INPST1
);
179 value
= READ_PORT_UCHAR (ATTRC_WRITEREG
);
180 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, 0x10);
181 data
= READ_PORT_UCHAR (ATTRC_READREG
);
183 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, data
);
184 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, value
);
185 READ_PORT_UCHAR (ATTRC_INPST1
);
187 /* read screen information from crt controller */
188 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_COLUMNS
);
189 DeviceExtension
->Columns
= READ_PORT_UCHAR (CRTC_DATA
) + 1;
190 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_ROWS
);
191 DeviceExtension
->Rows
= READ_PORT_UCHAR (CRTC_DATA
);
192 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_OVERFLOW
);
193 data
= READ_PORT_UCHAR (CRTC_DATA
);
194 DeviceExtension
->Rows
|= (((data
& 0x02) << 7) | ((data
& 0x40) << 3));
195 DeviceExtension
->Rows
++;
196 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_SCANLINES
);
197 DeviceExtension
->ScanLines
= (READ_PORT_UCHAR (CRTC_DATA
) & 0x1F) + 1;
199 /* show blinking cursor */
200 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
201 WRITE_PORT_UCHAR (CRTC_DATA
, (DeviceExtension
->ScanLines
- 1) & 0x1F);
202 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
203 data
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
204 WRITE_PORT_UCHAR (CRTC_DATA
,
205 data
| ((DeviceExtension
->ScanLines
- 1) & 0x1F));
207 /* calculate number of text rows */
208 DeviceExtension
->Rows
=
209 DeviceExtension
->Rows
/ DeviceExtension
->ScanLines
;
211 DeviceExtension
->Rows
= 30;
214 /* Upload a default font for the default codepage 437 */
215 ScrLoadFontTable(437);
217 DPRINT ("%d Columns %d Rows %d Scanlines\n",
218 DeviceExtension
->Columns
,
219 DeviceExtension
->Rows
,
220 DeviceExtension
->ScanLines
);
224 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
226 static DRIVER_DISPATCH ScrCreate
;
227 static NTSTATUS NTAPI
228 ScrCreate(PDEVICE_OBJECT DeviceObject
,
231 PDEVICE_EXTENSION DeviceExtension
;
232 PHYSICAL_ADDRESS BaseAddress
;
235 DeviceExtension
= DeviceObject
->DeviceExtension
;
237 if (!InbvCheckDisplayOwnership())
239 ScrAcquireOwnership(DeviceExtension
);
241 /* get pointer to video memory */
242 BaseAddress
.QuadPart
= VIDMEM_BASE
;
243 DeviceExtension
->VideoMemory
=
244 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
248 /* store dummy values here */
249 DeviceExtension
->Columns
= 1;
250 DeviceExtension
->Rows
= 1;
251 DeviceExtension
->ScanLines
= 1;
254 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
255 DeviceExtension
->CursorVisible
= TRUE
;
257 /* more initialization */
258 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
259 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
260 ENABLE_WRAP_AT_EOL_OUTPUT
;
262 Status
= STATUS_SUCCESS
;
264 Irp
->IoStatus
.Status
= Status
;
265 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
270 static DRIVER_DISPATCH ScrWrite
;
271 static NTSTATUS NTAPI
272 ScrWrite(PDEVICE_OBJECT DeviceObject
,
275 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
276 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
278 char *pch
= Irp
->UserBuffer
;
282 int cursorx
, cursory
;
284 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
286 if (InbvCheckDisplayOwnership())
288 /* Display is in graphics mode, we're not allowed to touch it */
289 Status
= STATUS_SUCCESS
;
291 Irp
->IoStatus
.Status
= Status
;
292 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
297 vidmem
= DeviceExtension
->VideoMemory
;
298 rows
= DeviceExtension
->Rows
;
299 columns
= DeviceExtension
->Columns
;
302 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
303 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
304 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
305 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
308 cursory
= offset
/ columns
;
309 cursorx
= offset
% columns
;
312 /* raw output mode */
313 // FIXME: Does the buffer only contains chars? or chars + attributes?
314 // FIXME2: Fix buffer overflow.
315 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
316 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
319 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
328 else if (cursory
> 0)
330 cursorx
= columns
- 1;
333 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
334 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
347 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
348 for (j
= 0; j
< offset
; j
++)
350 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
353 if (cursorx
>= columns
)
362 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
363 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
365 if (cursorx
>= columns
)
373 /* Scroll up the contents of the screen if we are at the end */
376 unsigned short *LinePtr
;
379 &vidmem
[columns
* 2],
380 columns
* (rows
- 1) * 2);
382 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
384 for (j
= 0; j
< columns
; j
++)
386 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
389 for (j
= 0; j
< columns
; j
++)
391 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
392 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
397 /* Set the cursor position */
398 offset
= (cursory
* columns
) + cursorx
;
401 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
402 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
403 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
405 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
408 Status
= STATUS_SUCCESS
;
410 Irp
->IoStatus
.Status
= Status
;
411 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
416 static DRIVER_DISPATCH ScrIoControl
;
417 static NTSTATUS NTAPI
418 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
421 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
422 PDEVICE_EXTENSION DeviceExtension
;
425 DeviceExtension
= DeviceObject
->DeviceExtension
;
426 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
428 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
430 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
431 int rows
= DeviceExtension
->Rows
;
432 int columns
= DeviceExtension
->Columns
;
435 if (!InbvCheckDisplayOwnership())
437 /* read cursor position from crtc */
439 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
440 offset
= READ_PORT_UCHAR (CRTC_DATA
);
441 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
442 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
450 pcsbi
->dwSize
.X
= columns
;
451 pcsbi
->dwSize
.Y
= rows
;
453 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
454 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
456 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
458 pcsbi
->srWindow
.Left
= 0;
459 pcsbi
->srWindow
.Right
= columns
- 1;
460 pcsbi
->srWindow
.Top
= 0;
461 pcsbi
->srWindow
.Bottom
= rows
- 1;
463 pcsbi
->dwMaximumWindowSize
.X
= columns
;
464 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
466 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
467 Status
= STATUS_SUCCESS
;
471 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
473 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
476 if ( pcsbi
->dwCursorPosition
.X
< 0 || pcsbi
->dwCursorPosition
.X
>= DeviceExtension
->Columns
||
477 pcsbi
->dwCursorPosition
.Y
< 0 || pcsbi
->dwCursorPosition
.Y
>= DeviceExtension
->Rows
)
479 Irp
->IoStatus
.Information
= 0;
480 Status
= STATUS_INVALID_PARAMETER
;
484 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
485 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
486 pcsbi
->dwCursorPosition
.X
;
488 if (!InbvCheckDisplayOwnership())
491 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
492 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
493 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
494 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
498 Irp
->IoStatus
.Information
= 0;
499 Status
= STATUS_SUCCESS
;
503 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
505 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
507 pcci
->dwSize
= DeviceExtension
->CursorSize
;
508 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
510 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
511 Status
= STATUS_SUCCESS
;
515 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
517 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
521 DeviceExtension
->CursorSize
= pcci
->dwSize
;
522 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
524 if (!InbvCheckDisplayOwnership())
526 height
= DeviceExtension
->ScanLines
;
527 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
529 size
= (pcci
->dwSize
* height
) / 100;
535 data
|= (UCHAR
)(height
- size
);
538 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
539 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
540 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
541 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
542 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
547 Irp
->IoStatus
.Information
= 0;
548 Status
= STATUS_SUCCESS
;
552 case IOCTL_CONSOLE_GET_MODE
:
554 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
556 pcm
->dwMode
= DeviceExtension
->Mode
;
558 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
559 Status
= STATUS_SUCCESS
;
563 case IOCTL_CONSOLE_SET_MODE
:
565 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
567 DeviceExtension
->Mode
= pcm
->dwMode
;
569 Irp
->IoStatus
.Information
= 0;
570 Status
= STATUS_SUCCESS
;
574 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
576 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
580 ULONG nMaxLength
= Buf
->nLength
;
582 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
583 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
585 Buf
->dwTransfered
= 0;
586 Irp
->IoStatus
.Information
= 0;
587 Status
= STATUS_SUCCESS
;
591 if (!InbvCheckDisplayOwnership())
593 vidmem
= DeviceExtension
->VideoMemory
;
594 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
595 (Buf
->dwCoord
.X
* 2) + 1;
597 nMaxLength
= min(nMaxLength
,
598 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
599 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
601 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++)
603 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
607 Buf
->dwTransfered
= nMaxLength
;
609 Irp
->IoStatus
.Information
= 0;
610 Status
= STATUS_SUCCESS
;
614 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
616 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
617 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
623 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
624 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
626 Buf
->dwTransfered
= 0;
627 Irp
->IoStatus
.Information
= 0;
628 Status
= STATUS_SUCCESS
;
632 if (!InbvCheckDisplayOwnership())
634 vidmem
= DeviceExtension
->VideoMemory
;
635 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
636 (Buf
->dwCoord
.X
* 2) + 1;
638 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
,
639 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
640 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
642 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pAttr
++)
644 *((char *)pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
647 Buf
->dwTransfered
= dwCount
;
651 Buf
->dwTransfered
= 0;
654 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
655 Status
= STATUS_SUCCESS
;
659 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
661 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
662 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
668 if ( pCoord
->X
< 0 || pCoord
->X
>= DeviceExtension
->Columns
||
669 pCoord
->Y
< 0 || pCoord
->Y
>= DeviceExtension
->Rows
)
671 Irp
->IoStatus
.Information
= 0;
672 Status
= STATUS_SUCCESS
;
676 if (!InbvCheckDisplayOwnership())
678 vidmem
= DeviceExtension
->VideoMemory
;
679 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
682 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof(COORD
),
683 (DeviceExtension
->Rows
- pCoord
->Y
)
684 * DeviceExtension
->Columns
- pCoord
->X
);
686 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pAttr
++)
688 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
692 Irp
->IoStatus
.Information
= 0;
693 Status
= STATUS_SUCCESS
;
697 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
698 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
699 Irp
->IoStatus
.Information
= 0;
700 Status
= STATUS_SUCCESS
;
703 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
705 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
709 ULONG nMaxLength
= Buf
->nLength
;
711 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
712 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
714 Buf
->dwTransfered
= 0;
715 Irp
->IoStatus
.Information
= 0;
716 Status
= STATUS_SUCCESS
;
720 if (!InbvCheckDisplayOwnership())
722 vidmem
= DeviceExtension
->VideoMemory
;
723 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
724 (Buf
->dwCoord
.X
* 2);
726 nMaxLength
= min(nMaxLength
,
727 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
728 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
730 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++)
732 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
736 Buf
->dwTransfered
= nMaxLength
;
738 Irp
->IoStatus
.Information
= 0;
739 Status
= STATUS_SUCCESS
;
743 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
745 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
746 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
752 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
753 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
755 Buf
->dwTransfered
= 0;
756 Irp
->IoStatus
.Information
= 0;
757 Status
= STATUS_SUCCESS
;
761 if (!InbvCheckDisplayOwnership())
763 vidmem
= DeviceExtension
->VideoMemory
;
764 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
765 (Buf
->dwCoord
.X
* 2);
767 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
,
768 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
769 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
771 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pChar
++)
773 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
776 Buf
->dwTransfered
= dwCount
;
780 Buf
->dwTransfered
= 0;
783 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
784 Status
= STATUS_SUCCESS
;
788 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
790 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
791 LPSTR pChar
= (CHAR
*)(pCoord
+ 1);
797 if ( pCoord
->X
< 0 || pCoord
->X
>= DeviceExtension
->Columns
||
798 pCoord
->Y
< 0 || pCoord
->Y
>= DeviceExtension
->Rows
)
800 Irp
->IoStatus
.Information
= 0;
801 Status
= STATUS_SUCCESS
;
805 if (!InbvCheckDisplayOwnership())
807 vidmem
= DeviceExtension
->VideoMemory
;
808 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
811 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof(COORD
),
812 (DeviceExtension
->Rows
- pCoord
->Y
)
813 * DeviceExtension
->Columns
- pCoord
->X
);
815 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pChar
++)
817 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
821 Irp
->IoStatus
.Information
= 0;
822 Status
= STATUS_SUCCESS
;
826 case IOCTL_CONSOLE_DRAW
:
828 PCONSOLE_DRAW ConsoleDraw
;
830 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
832 if (!InbvCheckDisplayOwnership())
834 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
835 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
836 SrcDelta
= ConsoleDraw
->SizeX
* 2;
837 Dest
= DeviceExtension
->VideoMemory
+
838 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
839 DestDelta
= DeviceExtension
->Columns
* 2;
841 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
843 RtlCopyMemory(Dest
, Src
, SrcDelta
);
848 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
849 ConsoleDraw
->CursorX
;
852 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
853 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
854 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
855 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
859 Irp
->IoStatus
.Information
= 0;
860 Status
= STATUS_SUCCESS
;
864 case IOCTL_CONSOLE_LOADFONT
:
866 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
868 if (!InbvCheckDisplayOwnership())
870 /* Upload a font for the codepage if needed */
871 ScrLoadFontTable(CodePage
);
874 Irp
->IoStatus
.Information
= 0;
875 Status
= STATUS_SUCCESS
;
880 Status
= STATUS_NOT_IMPLEMENTED
;
883 Irp
->IoStatus
.Status
= Status
;
884 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
889 static DRIVER_DISPATCH ScrDispatch
;
890 static NTSTATUS NTAPI
891 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
894 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
897 switch (stk
->MajorFunction
)
900 Status
= STATUS_SUCCESS
;
904 Status
= STATUS_NOT_IMPLEMENTED
;
909 Irp
->IoStatus
.Status
= Status
;
910 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
920 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
922 PDEVICE_OBJECT DeviceObject
;
924 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
925 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
927 DPRINT ("Screen Driver 0.0.6\n");
929 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
930 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
931 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
932 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
933 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
935 Status
= IoCreateDevice (DriverObject
,
936 sizeof(DEVICE_EXTENSION
),
939 FILE_DEVICE_SECURE_OPEN
,
943 if (!NT_SUCCESS(Status
))
948 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
949 if (NT_SUCCESS(Status
))
950 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
952 IoDeleteDevice (DeviceObject
);