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 if (!InbvCheckDisplayOwnership())
237 ScrAcquireOwnership(DeviceExtension
);
239 /* get pointer to video memory */
240 BaseAddress
.QuadPart
= VIDMEM_BASE
;
241 DeviceExtension
->VideoMemory
=
242 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
246 /* store dummy values here */
247 DeviceExtension
->Columns
= 1;
248 DeviceExtension
->Rows
= 1;
249 DeviceExtension
->ScanLines
= 1;
252 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
253 DeviceExtension
->CursorVisible
= TRUE
;
255 /* more initialization */
256 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
257 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
258 ENABLE_WRAP_AT_EOL_OUTPUT
;
260 Status
= STATUS_SUCCESS
;
262 Irp
->IoStatus
.Status
= Status
;
263 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
268 static DRIVER_DISPATCH ScrWrite
;
269 static NTSTATUS NTAPI
270 ScrWrite(PDEVICE_OBJECT DeviceObject
,
273 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
274 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
276 char *pch
= Irp
->UserBuffer
;
280 int cursorx
, cursory
;
282 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
284 if (InbvCheckDisplayOwnership())
286 /* Display is in graphics mode, we're not allowed to touch it */
287 Status
= STATUS_SUCCESS
;
289 Irp
->IoStatus
.Status
= Status
;
290 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
295 vidmem
= DeviceExtension
->VideoMemory
;
296 rows
= DeviceExtension
->Rows
;
297 columns
= DeviceExtension
->Columns
;
300 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
301 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
302 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
303 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
306 cursory
= offset
/ columns
;
307 cursorx
= offset
% columns
;
310 /* raw output mode */
311 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
312 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
315 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
324 else if (cursory
> 0)
326 cursorx
= columns
- 1;
329 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
330 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
343 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
344 for (j
= 0; j
< offset
; j
++)
346 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
349 if (cursorx
>= columns
)
358 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
359 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
361 if (cursorx
>= columns
)
370 unsigned short *LinePtr
;
373 &vidmem
[columns
* 2],
374 columns
* (rows
- 1) * 2);
376 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
378 for (j
= 0; j
< columns
; j
++)
380 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
383 for (j
= 0; j
< columns
; j
++)
385 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
386 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
391 /* Set the cursor position */
392 offset
= (cursory
* columns
) + cursorx
;
395 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
396 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
397 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
399 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
402 Status
= STATUS_SUCCESS
;
404 Irp
->IoStatus
.Status
= Status
;
405 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
410 static DRIVER_DISPATCH ScrIoControl
;
411 static NTSTATUS NTAPI
412 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
415 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
416 PDEVICE_EXTENSION DeviceExtension
;
419 DeviceExtension
= DeviceObject
->DeviceExtension
;
420 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
422 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
424 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
425 int rows
= DeviceExtension
->Rows
;
426 int columns
= DeviceExtension
->Columns
;
429 if (!InbvCheckDisplayOwnership())
431 /* read cursor position from crtc */
433 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
434 offset
= READ_PORT_UCHAR (CRTC_DATA
);
435 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
436 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
444 pcsbi
->dwSize
.X
= columns
;
445 pcsbi
->dwSize
.Y
= rows
;
447 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
448 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
450 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
452 pcsbi
->srWindow
.Left
= 0;
453 pcsbi
->srWindow
.Right
= columns
- 1;
454 pcsbi
->srWindow
.Top
= 0;
455 pcsbi
->srWindow
.Bottom
= rows
- 1;
457 pcsbi
->dwMaximumWindowSize
.X
= columns
;
458 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
460 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
461 Status
= STATUS_SUCCESS
;
465 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
467 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
470 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
471 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
472 pcsbi
->dwCursorPosition
.X
;
474 if (!InbvCheckDisplayOwnership())
477 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
478 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
479 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
480 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
484 Irp
->IoStatus
.Information
= 0;
485 Status
= STATUS_SUCCESS
;
489 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
491 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
493 pcci
->dwSize
= DeviceExtension
->CursorSize
;
494 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
496 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
497 Status
= STATUS_SUCCESS
;
501 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
503 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
507 DeviceExtension
->CursorSize
= pcci
->dwSize
;
508 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
510 if (!InbvCheckDisplayOwnership())
512 height
= DeviceExtension
->ScanLines
;
513 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
515 size
= (pcci
->dwSize
* height
) / 100;
521 data
|= (UCHAR
)(height
- size
);
524 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
525 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
526 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
527 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
528 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
533 Irp
->IoStatus
.Information
= 0;
534 Status
= STATUS_SUCCESS
;
538 case IOCTL_CONSOLE_GET_MODE
:
540 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
542 pcm
->dwMode
= DeviceExtension
->Mode
;
544 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
545 Status
= STATUS_SUCCESS
;
549 case IOCTL_CONSOLE_SET_MODE
:
551 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
553 DeviceExtension
->Mode
= pcm
->dwMode
;
555 Irp
->IoStatus
.Information
= 0;
556 Status
= STATUS_SUCCESS
;
560 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
562 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
567 if (!InbvCheckDisplayOwnership())
569 vidmem
= DeviceExtension
->VideoMemory
;
570 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
571 (Buf
->dwCoord
.X
* 2) + 1;
573 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
575 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
579 Buf
->dwTransfered
= Buf
->nLength
;
581 Irp
->IoStatus
.Information
= 0;
582 Status
= STATUS_SUCCESS
;
586 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
588 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
589 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
594 if (!InbvCheckDisplayOwnership())
596 vidmem
= DeviceExtension
->VideoMemory
;
597 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
598 (Buf
->dwCoord
.X
* 2) + 1;
600 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pAttr
++)
602 *((char *) pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
605 Buf
->dwTransfered
= dwCount
;
609 Buf
->dwTransfered
= 0;
612 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
613 Status
= STATUS_SUCCESS
;
617 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
619 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
620 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
625 if (!InbvCheckDisplayOwnership())
627 vidmem
= DeviceExtension
->VideoMemory
;
628 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
631 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pAttr
++)
633 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
637 Irp
->IoStatus
.Information
= 0;
638 Status
= STATUS_SUCCESS
;
642 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
643 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
644 Irp
->IoStatus
.Information
= 0;
645 Status
= STATUS_SUCCESS
;
648 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
650 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
655 if (!InbvCheckDisplayOwnership())
657 vidmem
= DeviceExtension
->VideoMemory
;
658 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
659 (Buf
->dwCoord
.X
* 2);
662 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
664 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
668 Buf
->dwTransfered
= Buf
->nLength
;
670 Irp
->IoStatus
.Information
= 0;
671 Status
= STATUS_SUCCESS
;
675 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
677 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
678 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
683 if (!InbvCheckDisplayOwnership())
685 vidmem
= DeviceExtension
->VideoMemory
;
686 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
687 (Buf
->dwCoord
.X
* 2);
689 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pChar
++)
691 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
694 Buf
->dwTransfered
= dwCount
;
698 Buf
->dwTransfered
= 0;
701 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
702 Status
= STATUS_SUCCESS
;
706 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
714 if (!InbvCheckDisplayOwnership())
716 pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
717 pChar
= (CHAR
*)(pCoord
+ 1);
718 vidmem
= DeviceExtension
->VideoMemory
;
719 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
722 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pChar
++)
724 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
728 Irp
->IoStatus
.Information
= 0;
729 Status
= STATUS_SUCCESS
;
733 case IOCTL_CONSOLE_DRAW
:
735 PCONSOLE_DRAW ConsoleDraw
;
737 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
739 if (!InbvCheckDisplayOwnership())
741 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
742 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
743 SrcDelta
= ConsoleDraw
->SizeX
* 2;
744 Dest
= DeviceExtension
->VideoMemory
+
745 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
746 DestDelta
= DeviceExtension
->Columns
* 2;
748 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
750 RtlCopyMemory(Dest
, Src
, SrcDelta
);
755 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
756 ConsoleDraw
->CursorX
;
759 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
760 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
761 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
762 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
766 Irp
->IoStatus
.Information
= 0;
767 Status
= STATUS_SUCCESS
;
771 case IOCTL_CONSOLE_LOADFONT
:
773 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
775 if (!InbvCheckDisplayOwnership())
777 // Upload a font for the codepage if needed
778 ScrLoadFontTable(CodePage
);
781 Irp
->IoStatus
.Information
= 0;
782 Status
= STATUS_SUCCESS
;
787 Status
= STATUS_NOT_IMPLEMENTED
;
790 Irp
->IoStatus
.Status
= Status
;
791 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
796 static DRIVER_DISPATCH ScrDispatch
;
797 static NTSTATUS NTAPI
798 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
801 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
804 switch (stk
->MajorFunction
)
807 Status
= STATUS_SUCCESS
;
811 Status
= STATUS_NOT_IMPLEMENTED
;
816 Irp
->IoStatus
.Status
= Status
;
817 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
827 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
829 PDEVICE_OBJECT DeviceObject
;
831 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
832 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
834 DPRINT ("Screen Driver 0.0.6\n");
836 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
837 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
838 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
839 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
840 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
842 Status
= IoCreateDevice (DriverObject
,
843 sizeof(DEVICE_EXTENSION
),
846 FILE_DEVICE_SECURE_OPEN
,
850 if (!NT_SUCCESS(Status
))
855 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
856 if (NT_SUCCESS(Status
))
857 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
859 IoDeleteDevice (DeviceObject
);