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 DPRINT ("%d Columns %d Rows %d Scanlines\n",
215 DeviceExtension
->Columns
,
216 DeviceExtension
->Rows
,
217 DeviceExtension
->ScanLines
);
221 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
);
223 static DRIVER_DISPATCH ScrCreate
;
224 static NTSTATUS NTAPI
225 ScrCreate(PDEVICE_OBJECT DeviceObject
,
228 PDEVICE_EXTENSION DeviceExtension
;
229 PHYSICAL_ADDRESS BaseAddress
;
232 DeviceExtension
= DeviceObject
->DeviceExtension
;
234 if (!InbvCheckDisplayOwnership())
236 ScrAcquireOwnership(DeviceExtension
);
238 /* get pointer to video memory */
239 BaseAddress
.QuadPart
= VIDMEM_BASE
;
240 DeviceExtension
->VideoMemory
=
241 (PUCHAR
)MmMapIoSpace (BaseAddress
, DeviceExtension
->Rows
* DeviceExtension
->Columns
* 2, MmNonCached
);
245 /* store dummy values here */
246 DeviceExtension
->Columns
= 1;
247 DeviceExtension
->Rows
= 1;
248 DeviceExtension
->ScanLines
= 1;
251 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
252 DeviceExtension
->CursorVisible
= TRUE
;
254 /* more initialization */
255 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
256 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
257 ENABLE_WRAP_AT_EOL_OUTPUT
;
259 Status
= STATUS_SUCCESS
;
261 Irp
->IoStatus
.Status
= Status
;
262 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
267 static DRIVER_DISPATCH ScrWrite
;
268 static NTSTATUS NTAPI
269 ScrWrite(PDEVICE_OBJECT DeviceObject
,
272 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
273 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
275 char *pch
= Irp
->UserBuffer
;
279 int cursorx
, cursory
;
281 int processed
= DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
;
283 if (InbvCheckDisplayOwnership())
285 /* Display is in graphics mode, we're not allowed to touch it */
286 Status
= STATUS_SUCCESS
;
288 Irp
->IoStatus
.Status
= Status
;
289 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
294 vidmem
= DeviceExtension
->VideoMemory
;
295 rows
= DeviceExtension
->Rows
;
296 columns
= DeviceExtension
->Columns
;
299 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
300 offset
= READ_PORT_UCHAR (CRTC_DATA
)<<8;
301 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
302 offset
+= READ_PORT_UCHAR (CRTC_DATA
);
305 cursory
= offset
/ columns
;
306 cursorx
= offset
% columns
;
309 /* raw output mode */
310 memcpy( &vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)], pch
, stk
->Parameters
.Write
.Length
);
311 offset
+= (stk
->Parameters
.Write
.Length
/ 2);
314 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
323 else if (cursory
> 0)
325 cursorx
= columns
- 1;
328 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
329 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
342 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
343 for (j
= 0; j
< offset
; j
++)
345 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = ' ';
348 if (cursorx
>= columns
)
357 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2)] = *pch
;
358 vidmem
[(cursorx
* 2) + (cursory
* columns
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
360 if (cursorx
>= columns
)
369 unsigned short *LinePtr
;
372 &vidmem
[columns
* 2],
373 columns
* (rows
- 1) * 2);
375 LinePtr
= (unsigned short *) &vidmem
[columns
* (rows
- 1) * 2];
377 for (j
= 0; j
< columns
; j
++)
379 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
382 for (j
= 0; j
< columns
; j
++)
384 vidmem
[(j
* 2) + (cursory
* columns
* 2)] = ' ';
385 vidmem
[(j
* 2) + (cursory
* columns
* 2) + 1] = (char)DeviceExtension
->CharAttribute
;
390 /* Set the cursor position */
391 offset
= (cursory
* columns
) + cursorx
;
394 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
395 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
396 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
398 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
401 Status
= STATUS_SUCCESS
;
403 Irp
->IoStatus
.Status
= Status
;
404 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
409 static DRIVER_DISPATCH ScrIoControl
;
410 static NTSTATUS NTAPI
411 ScrIoControl(PDEVICE_OBJECT DeviceObject
,
414 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
415 PDEVICE_EXTENSION DeviceExtension
;
418 DeviceExtension
= DeviceObject
->DeviceExtension
;
419 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
421 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
423 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
424 int rows
= DeviceExtension
->Rows
;
425 int columns
= DeviceExtension
->Columns
;
428 if (!InbvCheckDisplayOwnership())
430 /* read cursor position from crtc */
432 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
433 offset
= READ_PORT_UCHAR (CRTC_DATA
);
434 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
435 offset
+= (READ_PORT_UCHAR (CRTC_DATA
) << 8);
443 pcsbi
->dwSize
.X
= columns
;
444 pcsbi
->dwSize
.Y
= rows
;
446 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% columns
);
447 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ columns
);
449 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
451 pcsbi
->srWindow
.Left
= 0;
452 pcsbi
->srWindow
.Right
= columns
- 1;
453 pcsbi
->srWindow
.Top
= 0;
454 pcsbi
->srWindow
.Bottom
= rows
- 1;
456 pcsbi
->dwMaximumWindowSize
.X
= columns
;
457 pcsbi
->dwMaximumWindowSize
.Y
= rows
;
459 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
460 Status
= STATUS_SUCCESS
;
464 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
466 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
469 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
470 offset
= (pcsbi
->dwCursorPosition
.Y
* DeviceExtension
->Columns
) +
471 pcsbi
->dwCursorPosition
.X
;
473 if (!InbvCheckDisplayOwnership())
476 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
477 WRITE_PORT_UCHAR (CRTC_DATA
, offset
);
478 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
479 WRITE_PORT_UCHAR (CRTC_DATA
, offset
>>8);
483 Irp
->IoStatus
.Information
= 0;
484 Status
= STATUS_SUCCESS
;
488 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
490 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
492 pcci
->dwSize
= DeviceExtension
->CursorSize
;
493 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
495 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
496 Status
= STATUS_SUCCESS
;
500 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
502 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
506 DeviceExtension
->CursorSize
= pcci
->dwSize
;
507 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
509 if (!InbvCheckDisplayOwnership())
511 height
= DeviceExtension
->ScanLines
;
512 data
= (pcci
->bVisible
) ? 0x00 : 0x20;
514 size
= (pcci
->dwSize
* height
) / 100;
520 data
|= (UCHAR
)(height
- size
);
523 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORSTART
);
524 WRITE_PORT_UCHAR (CRTC_DATA
, data
);
525 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSOREND
);
526 value
= READ_PORT_UCHAR (CRTC_DATA
) & 0xE0;
527 WRITE_PORT_UCHAR (CRTC_DATA
, value
| (height
- 1));
532 Irp
->IoStatus
.Information
= 0;
533 Status
= STATUS_SUCCESS
;
537 case IOCTL_CONSOLE_GET_MODE
:
539 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
541 pcm
->dwMode
= DeviceExtension
->Mode
;
543 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
544 Status
= STATUS_SUCCESS
;
548 case IOCTL_CONSOLE_SET_MODE
:
550 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
552 DeviceExtension
->Mode
= pcm
->dwMode
;
554 Irp
->IoStatus
.Information
= 0;
555 Status
= STATUS_SUCCESS
;
559 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
561 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
566 if (!InbvCheckDisplayOwnership())
568 vidmem
= DeviceExtension
->VideoMemory
;
569 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
570 (Buf
->dwCoord
.X
* 2) + 1;
572 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
574 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
578 Buf
->dwTransfered
= Buf
->nLength
;
580 Irp
->IoStatus
.Information
= 0;
581 Status
= STATUS_SUCCESS
;
585 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
587 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
588 PUSHORT pAttr
= (PUSHORT
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
593 if (!InbvCheckDisplayOwnership())
595 vidmem
= DeviceExtension
->VideoMemory
;
596 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
597 (Buf
->dwCoord
.X
* 2) + 1;
599 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pAttr
++)
601 *((char *) pAttr
) = vidmem
[offset
+ (dwCount
* 2)];
604 Buf
->dwTransfered
= dwCount
;
608 Buf
->dwTransfered
= 0;
611 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
612 Status
= STATUS_SUCCESS
;
616 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
618 COORD
*pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
619 CHAR
*pAttr
= (CHAR
*)(pCoord
+ 1);
624 if (!InbvCheckDisplayOwnership())
626 vidmem
= DeviceExtension
->VideoMemory
;
627 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
630 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pAttr
++)
632 vidmem
[offset
+ (dwCount
* 2)] = *pAttr
;
636 Irp
->IoStatus
.Information
= 0;
637 Status
= STATUS_SUCCESS
;
641 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
642 DeviceExtension
->CharAttribute
= (USHORT
)*(PUSHORT
)Irp
->AssociatedIrp
.SystemBuffer
;
643 Irp
->IoStatus
.Information
= 0;
644 Status
= STATUS_SUCCESS
;
647 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
649 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
654 if (!InbvCheckDisplayOwnership())
656 vidmem
= DeviceExtension
->VideoMemory
;
657 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
658 (Buf
->dwCoord
.X
* 2);
661 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
663 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
667 Buf
->dwTransfered
= Buf
->nLength
;
669 Irp
->IoStatus
.Information
= 0;
670 Status
= STATUS_SUCCESS
;
674 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
676 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
677 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
682 if (!InbvCheckDisplayOwnership())
684 vidmem
= DeviceExtension
->VideoMemory
;
685 offset
= (Buf
->dwCoord
.Y
* DeviceExtension
->Columns
* 2) +
686 (Buf
->dwCoord
.X
* 2);
688 for (dwCount
= 0; dwCount
< stk
->Parameters
.DeviceIoControl
.OutputBufferLength
; dwCount
++, pChar
++)
690 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
693 Buf
->dwTransfered
= dwCount
;
697 Buf
->dwTransfered
= 0;
700 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
701 Status
= STATUS_SUCCESS
;
705 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
713 if (!InbvCheckDisplayOwnership())
715 pCoord
= (COORD
*)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
716 pChar
= (CHAR
*)(pCoord
+ 1);
717 vidmem
= DeviceExtension
->VideoMemory
;
718 offset
= (pCoord
->Y
* DeviceExtension
->Columns
* 2) +
721 for (dwCount
= 0; dwCount
< (stk
->Parameters
.DeviceIoControl
.OutputBufferLength
- sizeof( COORD
)); dwCount
++, pChar
++)
723 vidmem
[offset
+ (dwCount
* 2)] = *pChar
;
727 Irp
->IoStatus
.Information
= 0;
728 Status
= STATUS_SUCCESS
;
732 case IOCTL_CONSOLE_DRAW
:
734 PCONSOLE_DRAW ConsoleDraw
;
736 UINT32 SrcDelta
, DestDelta
, i
, Offset
;
738 if (!InbvCheckDisplayOwnership())
740 ConsoleDraw
= (PCONSOLE_DRAW
) MmGetSystemAddressForMdl(Irp
->MdlAddress
);
741 Src
= (PUCHAR
) (ConsoleDraw
+ 1);
742 SrcDelta
= ConsoleDraw
->SizeX
* 2;
743 Dest
= DeviceExtension
->VideoMemory
+
744 (ConsoleDraw
->Y
* DeviceExtension
->Columns
+ ConsoleDraw
->X
) * 2;
745 DestDelta
= DeviceExtension
->Columns
* 2;
747 for (i
= 0; i
< ConsoleDraw
->SizeY
; i
++)
749 RtlCopyMemory(Dest
, Src
, SrcDelta
);
754 Offset
= (ConsoleDraw
->CursorY
* DeviceExtension
->Columns
) +
755 ConsoleDraw
->CursorX
;
758 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
759 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
);
760 WRITE_PORT_UCHAR (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
761 WRITE_PORT_UCHAR (CRTC_DATA
, Offset
>> 8);
765 Irp
->IoStatus
.Information
= 0;
766 Status
= STATUS_SUCCESS
;
770 case IOCTL_CONSOLE_LOADFONT
:
772 UINT32 CodePage
= (UINT32
)*(PULONG
)Irp
->AssociatedIrp
.SystemBuffer
;
774 if (!InbvCheckDisplayOwnership())
776 // Upload a font for the codepage if needed
777 ScrLoadFontTable(CodePage
);
780 Irp
->IoStatus
.Information
= 0;
781 Status
= STATUS_SUCCESS
;
786 Status
= STATUS_NOT_IMPLEMENTED
;
789 Irp
->IoStatus
.Status
= Status
;
790 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
795 static DRIVER_DISPATCH ScrDispatch
;
796 static NTSTATUS NTAPI
797 ScrDispatch(PDEVICE_OBJECT DeviceObject
,
800 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
803 switch (stk
->MajorFunction
)
806 Status
= STATUS_SUCCESS
;
810 Status
= STATUS_NOT_IMPLEMENTED
;
815 Irp
->IoStatus
.Status
= Status
;
816 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
826 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
828 PDEVICE_OBJECT DeviceObject
;
830 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
831 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
833 DPRINT ("Screen Driver 0.0.6\n");
835 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
836 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
837 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
838 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
839 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
841 Status
= IoCreateDevice (DriverObject
,
842 sizeof(DEVICE_EXTENSION
),
845 FILE_DEVICE_SECURE_OPEN
,
849 if (!NT_SUCCESS(Status
))
854 Status
= IoCreateSymbolicLink (&SymlinkName
, &DeviceName
);
855 if (NT_SUCCESS(Status
))
856 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
858 IoDeleteDevice (DeviceObject
);