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 ******************************************************************/
19 // ROS Internal. Please deprecate.
23 HalQueryDisplayOwnership(
27 /* NOTES ******************************************************************/
29 * [[character][attribute]][[character][attribute]]....
33 /* TYPEDEFS ***************************************************************/
35 typedef struct _DEVICE_EXTENSION
37 PUCHAR VideoMemory
; /* Pointer to video memory */
42 UCHAR ScanLines
; /* Height of a text line */
43 USHORT Rows
; /* Number of rows */
44 USHORT Columns
; /* Number of columns */
45 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
47 typedef struct _VGA_REGISTERS
54 } VGA_REGISTERS
, *PVGA_REGISTERS
;
56 static const VGA_REGISTERS VidpMode3Regs
=
58 /* CRT Controller Registers */
59 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
60 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
61 /* Attribute Controller Registers */
62 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
63 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
64 /* Graphics Controller Registers */
65 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
66 /* Sequencer Registers */
67 {0x03, 0x00, 0x03, 0x00, 0x02},
68 /* Misc Output Register */
72 static const UCHAR DefaultPalette
[] =
92 /* FUNCTIONS **************************************************************/
95 ScrSetRegisters(const VGA_REGISTERS
*Registers
)
99 /* Update misc output register */
100 WRITE_PORT_UCHAR(MISC
, Registers
->Misc
);
102 /* Synchronous reset on */
103 WRITE_PORT_UCHAR(SEQ
, 0x00);
104 WRITE_PORT_UCHAR(SEQDATA
, 0x01);
106 /* Write sequencer registers */
107 for (i
= 1; i
< sizeof(Registers
->Sequencer
); i
++)
109 WRITE_PORT_UCHAR(SEQ
, i
);
110 WRITE_PORT_UCHAR(SEQDATA
, Registers
->Sequencer
[i
]);
113 /* Synchronous reset off */
114 WRITE_PORT_UCHAR(SEQ
, 0x00);
115 WRITE_PORT_UCHAR(SEQDATA
, 0x03);
117 /* Deprotect CRT registers 0-7 */
118 WRITE_PORT_UCHAR(CRTC
, 0x11);
119 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[0x11] & 0x7f);
121 /* Write CRT registers */
122 for (i
= 0; i
< sizeof(Registers
->CRT
); i
++)
124 WRITE_PORT_UCHAR(CRTC
, i
);
125 WRITE_PORT_UCHAR(CRTCDATA
, Registers
->CRT
[i
]);
128 /* Write graphics controller registers */
129 for (i
= 0; i
< sizeof(Registers
->Graphics
); i
++)
131 WRITE_PORT_UCHAR(GRAPHICS
, i
);
132 WRITE_PORT_UCHAR(GRAPHICSDATA
, Registers
->Graphics
[i
]);
135 /* Write attribute controller registers */
136 for (i
= 0; i
< sizeof(Registers
->Attribute
); i
++)
138 READ_PORT_UCHAR(STATUS
);
139 WRITE_PORT_UCHAR(ATTRIB
, i
);
140 WRITE_PORT_UCHAR(ATTRIB
, Registers
->Attribute
[i
]);
143 /* Set the PEL mask. */
144 WRITE_PORT_UCHAR(PELMASK
, 0xff);
148 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension
)
154 ScrSetRegisters(&VidpMode3Regs
);
156 /* Disable screen and enable palette access. */
157 READ_PORT_UCHAR(STATUS
);
158 WRITE_PORT_UCHAR(ATTRIB
, 0x00);
160 for (Index
= 0; Index
< sizeof(DefaultPalette
) / 3; Index
++)
162 WRITE_PORT_UCHAR(PELINDEX
, Index
);
163 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3] >> 2);
164 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 1] >> 2);
165 WRITE_PORT_UCHAR(PELDATA
, DefaultPalette
[Index
* 3 + 2] >> 2);
168 /* Enable screen and disable palette access. */
169 READ_PORT_UCHAR(STATUS
);
170 WRITE_PORT_UCHAR(ATTRIB
, 0x20);
172 /* get current output position */
173 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
174 offset
= READ_PORT_UCHAR (CRTC_DATA
);
175 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
176 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
178 /* switch blinking characters off */
179 READ_PORT_UCHAR (ATTRC_INPST1
);
180 value
= READ_PORT_UCHAR (ATTRC_WRITEREG
);
181 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, 0x10);
182 data
= READ_PORT_UCHAR (ATTRC_READREG
);
184 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, data
);
185 WRITE_PORT_UCHAR (ATTRC_WRITEREG
, value
);
186 READ_PORT_UCHAR (ATTRC_INPST1
);
188 /* read screen information from crt controller */
189 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_COLUMNS
);
190 DeviceExtension
->Columns
= READ_PORT_UCHAR (CRTC_DATA
) + 1;
191 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_ROWS
);
192 DeviceExtension
->Rows
= READ_PORT_UCHAR (CRTC_DATA
);
193 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_OVERFLOW
);
194 data
= READ_PORT_UCHAR (CRTC_DATA
);
195 DeviceExtension
->Rows
|= (((data
& 0x02) << 7) | ((data
& 0x40) << 3));
196 DeviceExtension
->Rows
++;
197 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_SCANLINES
);
198 DeviceExtension
->ScanLines
= (READ_PORT_UCHAR (CRTC_DATA
) & 0x1F) + 1;
200 /* show blinking cursor */
201 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
202 WRITE_PORT_UCHAR (CRTC_DATA
, (DeviceExtension
->ScanLines
- 1) & 0x1F);
203 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
204 data
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
205 WRITE_PORT_UCHAR (CRTC_DATA
,
206 data
| ((DeviceExtension
->ScanLines
- 1) & 0x1F));
208 /* calculate number of text rows */
209 DeviceExtension
->Rows
=
210 DeviceExtension
->Rows
/ DeviceExtension
->ScanLines
;
212 DeviceExtension
->Rows
= 30;
215 DPRINT ("%d Columns %d Rows %d Scanlines\n",
216 DeviceExtension
->Columns
,
217 DeviceExtension
->Rows
,
218 DeviceExtension
->ScanLines
);
222 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
224 static DRIVER_DISPATCH ScrCreate
;
225 static NTSTATUS NTAPI
226 ScrCreate(PDEVICE_OBJECT DeviceObject
,
229 PDEVICE_EXTENSION DeviceExtension
;
230 PHYSICAL_ADDRESS BaseAddress
;
233 DeviceExtension
= DeviceObject
->DeviceExtension
;
235 ScrAcquireOwnership(DeviceExtension
);
237 /* get pointer to video memory */
238 BaseAddress
.QuadPart
= VIDMEM_BASE
;
239 DeviceExtension
->VideoMemory
=
240 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
242 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
243 DeviceExtension
->CursorVisible
= TRUE
;
245 /* more initialization */
246 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
247 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
248 ENABLE_WRAP_AT_EOL_OUTPUT
;
250 Status
= STATUS_SUCCESS
;
252 Irp
->IoStatus
.Status
= Status
;
253 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
258 static DRIVER_DISPATCH ScrWrite
;
259 static NTSTATUS NTAPI
260 ScrWrite(PDEVICE_OBJECT DeviceObject
,
263 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
264 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
266 char *pch
= Irp
->UserBuffer
;
270 int cursorx
, cursory
;
272 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
274 if (0 && InbvCheckDisplayOwnership())
276 /* Display is in graphics mode, we're not allowed to touch it */
277 Status
= STATUS_SUCCESS
;
279 Irp
->IoStatus
.Status
= Status
;
280 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
285 vidmem
= DeviceExtension
->VideoMemory
;
286 rows
= DeviceExtension
->Rows
;
287 columns
= DeviceExtension
->Columns
;
290 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
291 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
292 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
293 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
296 cursory
= offset
/ columns
;
297 cursorx
= offset
% columns
;
300 /* raw output mode */
301 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
302 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
305 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
314 else if (cursory
> 0)
316 cursorx
= columns
- 1;
319 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
320 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
333 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
334 for (j
= 0; j
< offset
; j
++)
336 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
339 if (cursorx
>= columns
)
348 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
349 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
351 if (cursorx
>= columns
)
360 unsigned short *LinePtr
;
363 &vidmem
[columns
* 2],
364 columns
* (rows
- 1) * 2);
366 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
368 for (j
= 0; j
< columns
; j
++)
370 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
373 for (j
= 0; j
< columns
; j
++)
375 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
376 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
381 /* Set the cursor position */
382 offset
= (cursory
* columns
) + cursorx
;
385 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
386 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
387 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
389 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
392 Status
= STATUS_SUCCESS
;
394 Irp
->IoStatus
.Status
= Status
;
395 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
400 static DRIVER_DISPATCH ScrIoControl
;
401 static NTSTATUS NTAPI
402 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
405 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
406 PDEVICE_EXTENSION DeviceExtension
;
409 DeviceExtension
= DeviceObject
->DeviceExtension
;
410 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
412 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
414 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
415 int rows
= DeviceExtension
->Rows
;
416 int columns
= DeviceExtension
->Columns
;
419 /* read cursor position from crtc */
421 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
422 offset
= READ_PORT_UCHAR (CRTC_DATA
);
423 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
424 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
427 pcsbi
->dwSize
.X
= columns
;
428 pcsbi
->dwSize
.Y
= rows
;
430 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
431 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
433 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
435 pcsbi
->srWindow
.Left
= 0;
436 pcsbi
->srWindow
.Right
= columns
- 1;
437 pcsbi
->srWindow
.Top
= 0;
438 pcsbi
->srWindow
.Bottom
= rows
- 1;
440 pcsbi
->dwMaximumWindowSize
.X
= columns
;
441 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
443 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
444 Status
= STATUS_SUCCESS
;
448 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
450 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
453 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
454 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
455 pcsbi
->dwCursorPosition
.X
;
458 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
459 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
460 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
461 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
464 Irp
->IoStatus
.Information
= 0;
465 Status
= STATUS_SUCCESS
;
469 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
471 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
473 pcci
->dwSize
= DeviceExtension
->CursorSize
;
474 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
476 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
477 Status
= STATUS_SUCCESS
;
481 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
483 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
487 DeviceExtension
->CursorSize
= pcci
->dwSize
;
488 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
489 height
= DeviceExtension
->ScanLines
;
490 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
492 size
= (pcci
->dwSize
* height
) / 100;
498 data
|= (UCHAR
)(height
- size
);
501 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
502 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
503 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
504 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
505 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
509 Irp
->IoStatus
.Information
= 0;
510 Status
= STATUS_SUCCESS
;
514 case IOCTL_CONSOLE_GET_MODE
:
516 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
518 pcm
->dwMode
= DeviceExtension
->Mode
;
520 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
521 Status
= STATUS_SUCCESS
;
525 case IOCTL_CONSOLE_SET_MODE
:
527 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
529 DeviceExtension
->Mode
= pcm
->dwMode
;
531 Irp
->IoStatus
.Information
= 0;
532 Status
= STATUS_SUCCESS
;
536 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
538 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
543 vidmem
= DeviceExtension
->VideoMemory
;
544 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
545 (Buf
->dwCoord
.X
* 2) + 1;
547 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
549 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
552 Buf
->dwTransfered
= Buf
->nLength
;
554 Irp
->IoStatus
.Information
= 0;
555 Status
= STATUS_SUCCESS
;
559 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
561 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
562 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
567 vidmem
= DeviceExtension
->VideoMemory
;
568 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
569 (Buf
->dwCoord
.X
* 2) + 1;
571 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pAttr
++)
573 *((char *) pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
576 Buf
->dwTransfered
= dwCount
;
578 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
579 Status
= STATUS_SUCCESS
;
583 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
585 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
586 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
591 vidmem
= DeviceExtension
->VideoMemory
;
592 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
595 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pAttr
++)
597 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
599 Irp
->IoStatus
.Information
= 0;
600 Status
= STATUS_SUCCESS
;
604 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
605 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
606 Irp
->IoStatus
.Information
= 0;
607 Status
= STATUS_SUCCESS
;
610 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
612 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
617 vidmem
= DeviceExtension
->VideoMemory
;
618 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
619 (Buf
->dwCoord
.X
* 2);
622 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
624 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
627 Buf
->dwTransfered
= Buf
->nLength
;
629 Irp
->IoStatus
.Information
= 0;
630 Status
= STATUS_SUCCESS
;
634 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
636 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
637 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
642 vidmem
= DeviceExtension
->VideoMemory
;
643 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
644 (Buf
->dwCoord
.X
* 2);
646 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pChar
++)
648 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
651 Buf
->dwTransfered
= dwCount
;
653 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
654 Status
= STATUS_SUCCESS
;
658 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
666 pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
667 pChar
= (CHAR
*)(pCoord
+ 1);
668 vidmem
= DeviceExtension
->VideoMemory
;
669 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
672 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pChar
++)
674 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
677 Irp
->IoStatus
.Information
= 0;
678 Status
= STATUS_SUCCESS
;
682 case IOCTL_CONSOLE_DRAW
:
684 PCONSOLE_DRAW ConsoleDraw
;
686 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
688 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
689 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
690 SrcDelta
= ConsoleDraw
->SizeX
* 2;
691 Dest
= DeviceExtension
->VideoMemory
+
692 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
693 DestDelta
= DeviceExtension
->Columns
* 2;
695 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
697 RtlCopyMemory(Dest
, Src
, SrcDelta
);
702 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
703 ConsoleDraw
->CursorX
;
706 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
707 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
708 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
709 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
712 Irp
->IoStatus
.Information
= 0;
713 Status
= STATUS_SUCCESS
;
717 case IOCTL_CONSOLE_LOADFONT
:
719 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
721 // Upload a font for the codepage if needed
722 ScrLoadFontTable(CodePage
);
724 Irp
->IoStatus
.Information
= 0;
725 Status
= STATUS_SUCCESS
;
730 Status
= STATUS_NOT_IMPLEMENTED
;
733 Irp
->IoStatus
.Status
= Status
;
734 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
739 static DRIVER_DISPATCH ScrDispatch
;
740 static NTSTATUS NTAPI
741 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
744 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
747 switch (stk
->MajorFunction
)
750 Status
= STATUS_SUCCESS
;
754 Status
= STATUS_NOT_IMPLEMENTED
;
759 Irp
->IoStatus
.Status
= Status
;
760 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
770 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
772 PDEVICE_OBJECT DeviceObject
;
774 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
775 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
777 DPRINT ("Screen Driver 0.0.6\n");
779 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
780 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
781 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
782 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
783 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
785 Status
= IoCreateDevice (DriverObject
,
786 sizeof(DEVICE_EXTENSION
),
789 FILE_DEVICE_SECURE_OPEN
,
793 if (!NT_SUCCESS(Status
))
798 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
799 if (NT_SUCCESS(Status
))
800 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
802 IoDeleteDevice (DeviceObject
);