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 ******************************************************************/
16 typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
, *PSECURITY_ATTRIBUTES
;
19 #include <blue/ntddblue.h>
20 #include <ndk/inbvfuncs.h>
27 // ROS Internal. Please deprecate.
31 HalQueryDisplayOwnership(
35 /* NOTES ******************************************************************/
37 * [[character][attribute]][[character][attribute]]....
41 /* TYPEDEFS ***************************************************************/
43 typedef struct _DEVICE_EXTENSION
45 PUCHAR VideoMemory
; /* Pointer to video memory */
50 UCHAR ScanLines
; /* Height of a text line */
51 USHORT Rows
; /* Number of rows */
52 USHORT Columns
; /* Number of columns */
53 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
55 typedef struct _VGA_REGISTERS
62 } VGA_REGISTERS
, *PVGA_REGISTERS
;
64 static const VGA_REGISTERS VidpMode3Regs
=
66 /* CRT Controller Registers */
67 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
68 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
69 /* Attribute Controller Registers */
70 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
71 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
72 /* Graphics Controller Registers */
73 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
74 /* Sequencer Registers */
75 {0x03, 0x00, 0x03, 0x00, 0x02},
76 /* Misc Output Register */
80 static const UCHAR DefaultPalette
[] =
100 /* FUNCTIONS **************************************************************/
103 ScrSetRegisters(const VGA_REGISTERS
*Registers
)
107 /* Update misc output register */
108 WRITE_PORT_UCHAR(MISC
, Registers
->Misc
);
110 /* Synchronous reset on */
111 WRITE_PORT_UCHAR(SEQ
, 0x00);
112 WRITE_PORT_UCHAR(SEQDATA
, 0x01);
114 /* Write sequencer registers */
115 for (i
= 1; i
< sizeof(Registers
->Sequencer
); i
++)
117 WRITE_PORT_UCHAR(SEQ
, i
);
118 WRITE_PORT_UCHAR(SEQDATA
, Registers
->Sequencer
[i
]);
121 /* Synchronous reset off */
122 WRITE_PORT_UCHAR(SEQ
, 0x00);
123 WRITE_PORT_UCHAR(SEQDATA
, 0x03);
125 /* Deprotect CRT registers 0-7 */
126 WRITE_PORT_UCHAR(CRTC
, 0x11);
127 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[0x11] & 0x7f);
129 /* Write CRT registers */
130 for (i
= 0; i
< sizeof(Registers
->CRT
); i
++)
132 WRITE_PORT_UCHAR(CRTC
, i
);
133 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[i
]);
136 /* Write graphics controller registers */
137 for (i
= 0; i
< sizeof(Registers
->Graphics
); i
++)
139 WRITE_PORT_UCHAR(GRAPHICS
, i
);
140 WRITE_PORT_UCHAR(GRAPHICSDATA
, Registers
->Graphics
[i
]);
143 /* Write attribute controller registers */
144 for (i
= 0; i
< sizeof(Registers
->Attribute
); i
++)
146 READ_PORT_UCHAR(STATUS
);
147 WRITE_PORT_UCHAR(ATTRIB
, i
);
148 WRITE_PORT_UCHAR(ATTRIB
, Registers
->Attribute
[i
]);
151 /* Set the PEL mask. */
152 WRITE_PORT_UCHAR(PELMASK
, 0xff);
156 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension
)
162 ScrSetRegisters(&VidpMode3Regs
);
164 /* Disable screen and enable palette access. */
165 READ_PORT_UCHAR(STATUS
);
166 WRITE_PORT_UCHAR(ATTRIB
, 0x00);
168 for (Index
= 0; Index
< sizeof(DefaultPalette
) / 3; Index
++)
170 WRITE_PORT_UCHAR(PELINDEX
, Index
);
171 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3] >> 2);
172 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 1] >> 2);
173 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 2] >> 2);
176 /* Enable screen and disable palette access. */
177 READ_PORT_UCHAR(STATUS
);
178 WRITE_PORT_UCHAR(ATTRIB
, 0x20);
180 /* get current output position */
181 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
182 offset
= READ_PORT_UCHAR (CRTC_DATA
);
183 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
184 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
186 /* switch blinking characters off */
187 READ_PORT_UCHAR (ATTRC_INPST1
);
188 value
= READ_PORT_UCHAR (ATTRC_WRITEREG
);
189 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, 0x10);
190 data
= READ_PORT_UCHAR (ATTRC_READREG
);
192 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, data
);
193 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, value
);
194 READ_PORT_UCHAR (ATTRC_INPST1
);
196 /* read screen information from crt controller */
197 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_COLUMNS
);
198 DeviceExtension
->Columns
= READ_PORT_UCHAR (CRTC_DATA
) + 1;
199 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_ROWS
);
200 DeviceExtension
->Rows
= READ_PORT_UCHAR (CRTC_DATA
);
201 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_OVERFLOW
);
202 data
= READ_PORT_UCHAR (CRTC_DATA
);
203 DeviceExtension
->Rows
|= (((data
& 0x02) << 7) | ((data
& 0x40) << 3));
204 DeviceExtension
->Rows
++;
205 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_SCANLINES
);
206 DeviceExtension
->ScanLines
= (READ_PORT_UCHAR (CRTC_DATA
) & 0x1F) + 1;
208 /* show blinking cursor */
209 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
210 WRITE_PORT_UCHAR (CRTC_DATA
, (DeviceExtension
->ScanLines
- 1) & 0x1F);
211 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
212 data
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
213 WRITE_PORT_UCHAR (CRTC_DATA
,
214 data
| ((DeviceExtension
->ScanLines
- 1) & 0x1F));
216 /* calculate number of text rows */
217 DeviceExtension
->Rows
=
218 DeviceExtension
->Rows
/ DeviceExtension
->ScanLines
;
220 DeviceExtension
->Rows
= 30;
223 DPRINT ("%d Columns %d Rows %d Scanlines\n",
224 DeviceExtension
->Columns
,
225 DeviceExtension
->Rows
,
226 DeviceExtension
->ScanLines
);
230 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
232 static DRIVER_DISPATCH ScrCreate
;
233 static NTSTATUS NTAPI
234 ScrCreate(PDEVICE_OBJECT DeviceObject
,
237 PDEVICE_EXTENSION DeviceExtension
;
238 PHYSICAL_ADDRESS BaseAddress
;
241 DeviceExtension
= DeviceObject
->DeviceExtension
;
243 ScrAcquireOwnership(DeviceExtension
);
245 /* get pointer to video memory */
246 BaseAddress
.QuadPart
= VIDMEM_BASE
;
247 DeviceExtension
->VideoMemory
=
248 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
250 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
251 DeviceExtension
->CursorVisible
= TRUE
;
253 /* more initialization */
254 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
255 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
256 ENABLE_WRAP_AT_EOL_OUTPUT
;
258 Status
= STATUS_SUCCESS
;
260 Irp
->IoStatus
.Status
= Status
;
261 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
266 static DRIVER_DISPATCH ScrWrite
;
267 static NTSTATUS NTAPI
268 ScrWrite(PDEVICE_OBJECT DeviceObject
,
271 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
272 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
274 char *pch
= Irp
->UserBuffer
;
278 int cursorx
, cursory
;
280 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
282 if (0 && InbvCheckDisplayOwnership())
284 /* Display is in graphics mode, we're not allowed to touch it */
285 Status
= STATUS_SUCCESS
;
287 Irp
->IoStatus
.Status
= Status
;
288 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
293 vidmem
= DeviceExtension
->VideoMemory
;
294 rows
= DeviceExtension
->Rows
;
295 columns
= DeviceExtension
->Columns
;
298 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
299 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
300 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
301 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
304 cursory
= offset
/ columns
;
305 cursorx
= offset
% columns
;
308 /* raw output mode */
309 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
310 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
313 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
322 else if (cursory
> 0)
324 cursorx
= columns
- 1;
327 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
328 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
341 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
342 for (j
= 0; j
< offset
; j
++)
344 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
347 if (cursorx
>= columns
)
356 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
357 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
359 if (cursorx
>= columns
)
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 /* read cursor position from crtc */
429 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
430 offset
= READ_PORT_UCHAR (CRTC_DATA
);
431 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
432 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
435 pcsbi
->dwSize
.X
= columns
;
436 pcsbi
->dwSize
.Y
= rows
;
438 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
439 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
441 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
443 pcsbi
->srWindow
.Left
= 0;
444 pcsbi
->srWindow
.Right
= columns
- 1;
445 pcsbi
->srWindow
.Top
= 0;
446 pcsbi
->srWindow
.Bottom
= rows
- 1;
448 pcsbi
->dwMaximumWindowSize
.X
= columns
;
449 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
451 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
452 Status
= STATUS_SUCCESS
;
456 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
458 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
461 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
462 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
463 pcsbi
->dwCursorPosition
.X
;
466 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
467 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
468 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
469 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
472 Irp
->IoStatus
.Information
= 0;
473 Status
= STATUS_SUCCESS
;
477 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
479 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
481 pcci
->dwSize
= DeviceExtension
->CursorSize
;
482 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
484 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
485 Status
= STATUS_SUCCESS
;
489 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
491 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
495 DeviceExtension
->CursorSize
= pcci
->dwSize
;
496 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
497 height
= DeviceExtension
->ScanLines
;
498 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
500 size
= (pcci
->dwSize
* height
) / 100;
506 data
|= (UCHAR
)(height
- size
);
509 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
510 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
511 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
512 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
513 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
517 Irp
->IoStatus
.Information
= 0;
518 Status
= STATUS_SUCCESS
;
522 case IOCTL_CONSOLE_GET_MODE
:
524 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
526 pcm
->dwMode
= DeviceExtension
->Mode
;
528 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
529 Status
= STATUS_SUCCESS
;
533 case IOCTL_CONSOLE_SET_MODE
:
535 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
537 DeviceExtension
->Mode
= pcm
->dwMode
;
539 Irp
->IoStatus
.Information
= 0;
540 Status
= STATUS_SUCCESS
;
544 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
546 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
551 vidmem
= DeviceExtension
->VideoMemory
;
552 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
553 (Buf
->dwCoord
.X
* 2) + 1;
555 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
557 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
560 Buf
->dwTransfered
= Buf
->nLength
;
562 Irp
->IoStatus
.Information
= 0;
563 Status
= STATUS_SUCCESS
;
567 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
569 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
570 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
575 vidmem
= DeviceExtension
->VideoMemory
;
576 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
577 (Buf
->dwCoord
.X
* 2) + 1;
579 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pAttr
++)
581 *((char *) pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
584 Buf
->dwTransfered
= dwCount
;
586 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
587 Status
= STATUS_SUCCESS
;
591 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
593 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
594 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
599 vidmem
= DeviceExtension
->VideoMemory
;
600 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
603 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pAttr
++)
605 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
607 Irp
->IoStatus
.Information
= 0;
608 Status
= STATUS_SUCCESS
;
612 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
613 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
614 Irp
->IoStatus
.Information
= 0;
615 Status
= STATUS_SUCCESS
;
618 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
620 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
625 vidmem
= DeviceExtension
->VideoMemory
;
626 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
627 (Buf
->dwCoord
.X
* 2);
630 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
632 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
635 Buf
->dwTransfered
= Buf
->nLength
;
637 Irp
->IoStatus
.Information
= 0;
638 Status
= STATUS_SUCCESS
;
642 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
644 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
645 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
650 vidmem
= DeviceExtension
->VideoMemory
;
651 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
652 (Buf
->dwCoord
.X
* 2);
654 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pChar
++)
656 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
659 Buf
->dwTransfered
= dwCount
;
661 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
662 Status
= STATUS_SUCCESS
;
666 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
674 pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
675 pChar
= (CHAR
*)(pCoord
+ 1);
676 vidmem
= DeviceExtension
->VideoMemory
;
677 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
680 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pChar
++)
682 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
685 Irp
->IoStatus
.Information
= 0;
686 Status
= STATUS_SUCCESS
;
690 case IOCTL_CONSOLE_DRAW
:
692 PCONSOLE_DRAW ConsoleDraw
;
694 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
696 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
697 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
698 SrcDelta
= ConsoleDraw
->SizeX
* 2;
699 Dest
= DeviceExtension
->VideoMemory
+
700 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
701 DestDelta
= DeviceExtension
->Columns
* 2;
703 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
705 RtlCopyMemory(Dest
, Src
, SrcDelta
);
710 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
711 ConsoleDraw
->CursorX
;
714 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
715 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
716 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
717 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
720 Irp
->IoStatus
.Information
= 0;
721 Status
= STATUS_SUCCESS
;
725 case IOCTL_CONSOLE_LOADFONT
:
727 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
729 // Upload a font for the codepage if needed
730 ScrLoadFontTable(CodePage
);
732 Irp
->IoStatus
.Information
= 0;
733 Status
= STATUS_SUCCESS
;
738 Status
= STATUS_NOT_IMPLEMENTED
;
741 Irp
->IoStatus
.Status
= Status
;
742 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
747 static DRIVER_DISPATCH ScrDispatch
;
748 static NTSTATUS NTAPI
749 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
752 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
755 switch (stk
->MajorFunction
)
758 Status
= STATUS_SUCCESS
;
762 Status
= STATUS_NOT_IMPLEMENTED
;
767 Irp
->IoStatus
.Status
= Status
;
768 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
778 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
780 PDEVICE_OBJECT DeviceObject
;
782 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
783 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
785 DPRINT ("Screen Driver 0.0.6\n");
787 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
788 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
789 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
790 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
791 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
793 Status
= IoCreateDevice (DriverObject
,
794 sizeof(DEVICE_EXTENSION
),
797 FILE_DEVICE_SECURE_OPEN
,
801 if (!NT_SUCCESS(Status
))
806 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
807 if (NT_SUCCESS(Status
))
808 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
810 IoDeleteDevice (DeviceObject
);