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 /* NOTES ******************************************************************/
20 * [[character][attribute]][[character][attribute]]....
24 /* TYPEDEFS ***************************************************************/
26 typedef struct _DEVICE_EXTENSION
28 PUCHAR VideoMemory
; /* Pointer to video memory */
33 UCHAR ScanLines
; /* Height of a text line */
34 USHORT Rows
; /* Number of rows */
35 USHORT Columns
; /* Number of columns */
36 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
38 typedef struct _VGA_REGISTERS
45 } VGA_REGISTERS
, *PVGA_REGISTERS
;
47 static const VGA_REGISTERS VidpMode3Regs
=
49 /* CRT Controller Registers */
50 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
51 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
52 /* Attribute Controller Registers */
53 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
54 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
55 /* Graphics Controller Registers */
56 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
57 /* Sequencer Registers */
58 {0x03, 0x00, 0x03, 0x00, 0x02},
59 /* Misc Output Register */
63 static const UCHAR DefaultPalette
[] =
83 /* FUNCTIONS **************************************************************/
86 ScrSetRegisters(const VGA_REGISTERS
*Registers
)
90 /* Update misc output register */
91 WRITE_PORT_UCHAR(MISC
, Registers
->Misc
);
93 /* Synchronous reset on */
94 WRITE_PORT_UCHAR(SEQ
, 0x00);
95 WRITE_PORT_UCHAR(SEQDATA
, 0x01);
97 /* Write sequencer registers */
98 for (i
= 1; i
< sizeof(Registers
->Sequencer
); i
++)
100 WRITE_PORT_UCHAR(SEQ
, i
);
101 WRITE_PORT_UCHAR(SEQDATA
, Registers
->Sequencer
[i
]);
104 /* Synchronous reset off */
105 WRITE_PORT_UCHAR(SEQ
, 0x00);
106 WRITE_PORT_UCHAR(SEQDATA
, 0x03);
108 /* Deprotect CRT registers 0-7 */
109 WRITE_PORT_UCHAR(CRTC
, 0x11);
110 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[0x11] & 0x7f);
112 /* Write CRT registers */
113 for (i
= 0; i
< sizeof(Registers
->CRT
); i
++)
115 WRITE_PORT_UCHAR(CRTC
, i
);
116 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[i
]);
119 /* Write graphics controller registers */
120 for (i
= 0; i
< sizeof(Registers
->Graphics
); i
++)
122 WRITE_PORT_UCHAR(GRAPHICS
, i
);
123 WRITE_PORT_UCHAR(GRAPHICSDATA
, Registers
->Graphics
[i
]);
126 /* Write attribute controller registers */
127 for (i
= 0; i
< sizeof(Registers
->Attribute
); i
++)
129 READ_PORT_UCHAR(STATUS
);
130 WRITE_PORT_UCHAR(ATTRIB
, i
);
131 WRITE_PORT_UCHAR(ATTRIB
, Registers
->Attribute
[i
]);
134 /* Set the PEL mask. */
135 WRITE_PORT_UCHAR(PELMASK
, 0xff);
139 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension
)
145 ScrSetRegisters(&VidpMode3Regs
);
147 /* Disable screen and enable palette access. */
148 READ_PORT_UCHAR(STATUS
);
149 WRITE_PORT_UCHAR(ATTRIB
, 0x00);
151 for (Index
= 0; Index
< sizeof(DefaultPalette
) / 3; Index
++)
153 WRITE_PORT_UCHAR(PELINDEX
, Index
);
154 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3] >> 2);
155 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 1] >> 2);
156 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 2] >> 2);
159 /* Enable screen and disable palette access. */
160 READ_PORT_UCHAR(STATUS
);
161 WRITE_PORT_UCHAR(ATTRIB
, 0x20);
163 /* get current output position */
164 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
165 offset
= READ_PORT_UCHAR (CRTC_DATA
);
166 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
167 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
169 /* switch blinking characters off */
170 READ_PORT_UCHAR (ATTRC_INPST1
);
171 value
= READ_PORT_UCHAR (ATTRC_WRITEREG
);
172 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, 0x10);
173 data
= READ_PORT_UCHAR (ATTRC_READREG
);
175 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, data
);
176 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, value
);
177 READ_PORT_UCHAR (ATTRC_INPST1
);
179 /* read screen information from crt controller */
180 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_COLUMNS
);
181 DeviceExtension
->Columns
= READ_PORT_UCHAR (CRTC_DATA
) + 1;
182 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_ROWS
);
183 DeviceExtension
->Rows
= READ_PORT_UCHAR (CRTC_DATA
);
184 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_OVERFLOW
);
185 data
= READ_PORT_UCHAR (CRTC_DATA
);
186 DeviceExtension
->Rows
|= (((data
& 0x02) << 7) | ((data
& 0x40) << 3));
187 DeviceExtension
->Rows
++;
188 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_SCANLINES
);
189 DeviceExtension
->ScanLines
= (READ_PORT_UCHAR (CRTC_DATA
) & 0x1F) + 1;
191 /* show blinking cursor */
192 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
193 WRITE_PORT_UCHAR (CRTC_DATA
, (DeviceExtension
->ScanLines
- 1) & 0x1F);
194 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
195 data
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
196 WRITE_PORT_UCHAR (CRTC_DATA
,
197 data
| ((DeviceExtension
->ScanLines
- 1) & 0x1F));
199 /* calculate number of text rows */
200 DeviceExtension
->Rows
=
201 DeviceExtension
->Rows
/ DeviceExtension
->ScanLines
;
203 DeviceExtension
->Rows
= 30;
206 /* Upload a default font for the default codepage 437 */
207 ScrLoadFontTable(437);
209 DPRINT ("%d Columns %d Rows %d Scanlines\n",
210 DeviceExtension
->Columns
,
211 DeviceExtension
->Rows
,
212 DeviceExtension
->ScanLines
);
216 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
218 static DRIVER_DISPATCH ScrCreate
;
219 static NTSTATUS NTAPI
220 ScrCreate(PDEVICE_OBJECT DeviceObject
,
223 PDEVICE_EXTENSION DeviceExtension
;
224 PHYSICAL_ADDRESS BaseAddress
;
227 DeviceExtension
= DeviceObject
->DeviceExtension
;
229 if (!InbvCheckDisplayOwnership())
231 ScrAcquireOwnership(DeviceExtension
);
233 /* get pointer to video memory */
234 BaseAddress
.QuadPart
= VIDMEM_BASE
;
235 DeviceExtension
->VideoMemory
=
236 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
240 /* store dummy values here */
241 DeviceExtension
->Columns
= 1;
242 DeviceExtension
->Rows
= 1;
243 DeviceExtension
->ScanLines
= 1;
246 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
247 DeviceExtension
->CursorVisible
= TRUE
;
249 /* more initialization */
250 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
251 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
252 ENABLE_WRAP_AT_EOL_OUTPUT
;
254 Status
= STATUS_SUCCESS
;
256 Irp
->IoStatus
.Status
= Status
;
257 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
262 static DRIVER_DISPATCH ScrWrite
;
263 static NTSTATUS NTAPI
264 ScrWrite(PDEVICE_OBJECT DeviceObject
,
267 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
268 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
270 char *pch
= Irp
->UserBuffer
;
274 int cursorx
, cursory
;
276 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
278 if (InbvCheckDisplayOwnership())
280 /* Display is in graphics mode, we're not allowed to touch it */
281 Status
= STATUS_SUCCESS
;
283 Irp
->IoStatus
.Status
= Status
;
284 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
289 vidmem
= DeviceExtension
->VideoMemory
;
290 rows
= DeviceExtension
->Rows
;
291 columns
= DeviceExtension
->Columns
;
294 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
295 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
296 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
297 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
300 cursory
= offset
/ columns
;
301 cursorx
= offset
% columns
;
304 /* raw output mode */
305 // FIXME: Does the buffer only contains chars? or chars + attributes?
306 // FIXME2: Fix buffer overflow.
307 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
308 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
311 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
320 else if (cursory
> 0)
322 cursorx
= columns
- 1;
325 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
326 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
339 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
340 for (j
= 0; j
< offset
; j
++)
342 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
345 if (cursorx
>= columns
)
354 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
355 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
357 if (cursorx
>= columns
)
365 /* Scroll up the contents of the screen if we are at the end */
368 unsigned short *LinePtr
;
371 &vidmem
[columns
* 2],
372 columns
* (rows
- 1) * 2);
374 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
376 for (j
= 0; j
< columns
; j
++)
378 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
381 for (j
= 0; j
< columns
; j
++)
383 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
384 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
389 /* Set the cursor position */
390 offset
= (cursory
* columns
) + cursorx
;
393 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
394 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
395 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
397 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
400 Status
= STATUS_SUCCESS
;
402 Irp
->IoStatus
.Status
= Status
;
403 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
408 static DRIVER_DISPATCH ScrIoControl
;
409 static NTSTATUS NTAPI
410 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
413 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
414 PDEVICE_EXTENSION DeviceExtension
;
417 DeviceExtension
= DeviceObject
->DeviceExtension
;
418 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
420 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
422 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
423 int rows
= DeviceExtension
->Rows
;
424 int columns
= DeviceExtension
->Columns
;
427 if (!InbvCheckDisplayOwnership())
429 /* read cursor position from crtc */
431 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
432 offset
= READ_PORT_UCHAR (CRTC_DATA
);
433 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
434 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
442 pcsbi
->dwSize
.X
= columns
;
443 pcsbi
->dwSize
.Y
= rows
;
445 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
446 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
448 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
450 pcsbi
->srWindow
.Left
= 0;
451 pcsbi
->srWindow
.Right
= columns
- 1;
452 pcsbi
->srWindow
.Top
= 0;
453 pcsbi
->srWindow
.Bottom
= rows
- 1;
455 pcsbi
->dwMaximumWindowSize
.X
= columns
;
456 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
458 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
459 Status
= STATUS_SUCCESS
;
463 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
465 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
468 if ( pcsbi
->dwCursorPosition
.X
< 0 || pcsbi
->dwCursorPosition
.X
>= DeviceExtension
->Columns
||
469 pcsbi
->dwCursorPosition
.Y
< 0 || pcsbi
->dwCursorPosition
.Y
>= DeviceExtension
->Rows
)
471 Irp
->IoStatus
.Information
= 0;
472 Status
= STATUS_INVALID_PARAMETER
;
476 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
477 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
478 pcsbi
->dwCursorPosition
.X
;
480 if (!InbvCheckDisplayOwnership())
483 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
484 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
485 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
486 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
490 Irp
->IoStatus
.Information
= 0;
491 Status
= STATUS_SUCCESS
;
495 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
497 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
499 pcci
->dwSize
= DeviceExtension
->CursorSize
;
500 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
502 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
503 Status
= STATUS_SUCCESS
;
507 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
509 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
513 DeviceExtension
->CursorSize
= pcci
->dwSize
;
514 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
516 if (!InbvCheckDisplayOwnership())
518 height
= DeviceExtension
->ScanLines
;
519 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
521 size
= (pcci
->dwSize
* height
) / 100;
527 data
|= (UCHAR
)(height
- size
);
530 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
531 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
532 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
533 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
534 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
539 Irp
->IoStatus
.Information
= 0;
540 Status
= STATUS_SUCCESS
;
544 case IOCTL_CONSOLE_GET_MODE
:
546 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
548 pcm
->dwMode
= DeviceExtension
->Mode
;
550 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
551 Status
= STATUS_SUCCESS
;
555 case IOCTL_CONSOLE_SET_MODE
:
557 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
559 DeviceExtension
->Mode
= pcm
->dwMode
;
561 Irp
->IoStatus
.Information
= 0;
562 Status
= STATUS_SUCCESS
;
566 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
568 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
572 ULONG nMaxLength
= Buf
->nLength
;
574 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
575 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
577 Buf
->dwTransfered
= 0;
578 Irp
->IoStatus
.Information
= 0;
579 Status
= STATUS_SUCCESS
;
583 if (!InbvCheckDisplayOwnership())
585 vidmem
= DeviceExtension
->VideoMemory
;
586 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
587 (Buf
->dwCoord
.X
* 2) + 1;
589 nMaxLength
= min(nMaxLength
,
590 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
591 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
593 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++)
595 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
599 Buf
->dwTransfered
= nMaxLength
;
601 Irp
->IoStatus
.Information
= 0;
602 Status
= STATUS_SUCCESS
;
606 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
608 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
609 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
615 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
616 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
618 Buf
->dwTransfered
= 0;
619 Irp
->IoStatus
.Information
= 0;
620 Status
= STATUS_SUCCESS
;
624 if (!InbvCheckDisplayOwnership())
626 vidmem
= DeviceExtension
->VideoMemory
;
627 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
628 (Buf
->dwCoord
.X
* 2) + 1;
630 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
,
631 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
632 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
634 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pAttr
++)
636 *((char *)pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
639 Buf
->dwTransfered
= dwCount
;
643 Buf
->dwTransfered
= 0;
646 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
647 Status
= STATUS_SUCCESS
;
651 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
653 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
654 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
660 if ( pCoord
->X
< 0 || pCoord
->X
>= DeviceExtension
->Columns
||
661 pCoord
->Y
< 0 || pCoord
->Y
>= DeviceExtension
->Rows
)
663 Irp
->IoStatus
.Information
= 0;
664 Status
= STATUS_SUCCESS
;
668 if (!InbvCheckDisplayOwnership())
670 vidmem
= DeviceExtension
->VideoMemory
;
671 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
674 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof(COORD
),
675 (DeviceExtension
->Rows
- pCoord
->Y
)
676 * DeviceExtension
->Columns
- pCoord
->X
);
678 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pAttr
++)
680 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
684 Irp
->IoStatus
.Information
= 0;
685 Status
= STATUS_SUCCESS
;
689 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
690 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
691 Irp
->IoStatus
.Information
= 0;
692 Status
= STATUS_SUCCESS
;
695 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
697 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
701 ULONG nMaxLength
= Buf
->nLength
;
703 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
704 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
706 Buf
->dwTransfered
= 0;
707 Irp
->IoStatus
.Information
= 0;
708 Status
= STATUS_SUCCESS
;
712 if (!InbvCheckDisplayOwnership())
714 vidmem
= DeviceExtension
->VideoMemory
;
715 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
716 (Buf
->dwCoord
.X
* 2);
718 nMaxLength
= min(nMaxLength
,
719 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
720 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
722 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++)
724 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
728 Buf
->dwTransfered
= nMaxLength
;
730 Irp
->IoStatus
.Information
= 0;
731 Status
= STATUS_SUCCESS
;
735 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
737 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
738 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
744 if ( Buf
->dwCoord
.X
< 0 || Buf
->dwCoord
.X
>= DeviceExtension
->Columns
||
745 Buf
->dwCoord
.Y
< 0 || Buf
->dwCoord
.Y
>= DeviceExtension
->Rows
)
747 Buf
->dwTransfered
= 0;
748 Irp
->IoStatus
.Information
= 0;
749 Status
= STATUS_SUCCESS
;
753 if (!InbvCheckDisplayOwnership())
755 vidmem
= DeviceExtension
->VideoMemory
;
756 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
757 (Buf
->dwCoord
.X
* 2);
759 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
,
760 (DeviceExtension
->Rows
- Buf
->dwCoord
.Y
)
761 * DeviceExtension
->Columns
- Buf
->dwCoord
.X
);
763 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pChar
++)
765 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
768 Buf
->dwTransfered
= dwCount
;
772 Buf
->dwTransfered
= 0;
775 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
776 Status
= STATUS_SUCCESS
;
780 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
782 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
783 LPSTR pChar
= (CHAR
*)(pCoord
+ 1);
789 if ( pCoord
->X
< 0 || pCoord
->X
>= DeviceExtension
->Columns
||
790 pCoord
->Y
< 0 || pCoord
->Y
>= DeviceExtension
->Rows
)
792 Irp
->IoStatus
.Information
= 0;
793 Status
= STATUS_SUCCESS
;
797 if (!InbvCheckDisplayOwnership())
799 vidmem
= DeviceExtension
->VideoMemory
;
800 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
803 nMaxLength
= min(stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof(COORD
),
804 (DeviceExtension
->Rows
- pCoord
->Y
)
805 * DeviceExtension
->Columns
- pCoord
->X
);
807 for (dwCount
= 0; dwCount
< nMaxLength
; dwCount
++, pChar
++)
809 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
813 Irp
->IoStatus
.Information
= 0;
814 Status
= STATUS_SUCCESS
;
818 case IOCTL_CONSOLE_DRAW
:
820 PCONSOLE_DRAW ConsoleDraw
;
822 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
824 if (!InbvCheckDisplayOwnership())
826 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
827 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
828 SrcDelta
= ConsoleDraw
->SizeX
* 2;
829 Dest
= DeviceExtension
->VideoMemory
+
830 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
831 DestDelta
= DeviceExtension
->Columns
* 2;
833 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
835 RtlCopyMemory(Dest
, Src
, SrcDelta
);
840 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
841 ConsoleDraw
->CursorX
;
844 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
845 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
846 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
847 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
851 Irp
->IoStatus
.Information
= 0;
852 Status
= STATUS_SUCCESS
;
856 case IOCTL_CONSOLE_LOADFONT
:
858 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
860 if (!InbvCheckDisplayOwnership())
862 /* Upload a font for the codepage if needed */
863 ScrLoadFontTable(CodePage
);
866 Irp
->IoStatus
.Information
= 0;
867 Status
= STATUS_SUCCESS
;
872 Status
= STATUS_NOT_IMPLEMENTED
;
875 Irp
->IoStatus
.Status
= Status
;
876 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
881 static DRIVER_DISPATCH ScrDispatch
;
882 static NTSTATUS NTAPI
883 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
886 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
889 switch (stk
->MajorFunction
)
892 Status
= STATUS_SUCCESS
;
896 Status
= STATUS_NOT_IMPLEMENTED
;
901 Irp
->IoStatus
.Status
= Status
;
902 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
912 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
914 PDEVICE_OBJECT DeviceObject
;
916 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
917 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
919 DPRINT ("Screen Driver 0.0.6\n");
921 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
922 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
923 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
924 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
925 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
927 Status
= IoCreateDevice (DriverObject
,
928 sizeof(DEVICE_EXTENSION
),
931 FILE_DEVICE_SECURE_OPEN
,
935 if (!NT_SUCCESS(Status
))
940 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
941 if (NT_SUCCESS(Status
))
942 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
944 IoDeleteDevice (DeviceObject
);