- Get beep and blue to compile/link on MSVC.
[reactos.git] / reactos / drivers / dd / blue / blue.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/dd/blue/blue.c
6 * PURPOSE: Console (blue screen) device driver
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
8 * UPDATE HISTORY:
9 * ??? Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ntddk.h>
15
16 /* FIXME: W32API NEEDS TO BE FIXED */
17 #ifdef _MSC_VER
18 /*
19 * Wincon.h can't be included due to missing user-mode types,
20 * so we'll define them here
21 */
22 typedef ULONG DWORD, *LPDWORD;
23 typedef USHORT UINT, *LPWORD;
24 typedef USHORT WORD;
25 typedef UCHAR BYTE;
26 typedef INT BOOL;
27 typedef PVOID HWND;
28 typedef PVOID LPVOID;
29 #define WINAPI NTAPI
30 #define APIENTRY WINAPI
31 #define WINBASEAPI
32 typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
33 #endif
34
35 #include <wincon.h>
36 #include <blue/ntddblue.h>
37 #include <ndk/halfuncs.h>
38
39 #define NDEBUG
40 #include <debug.h>
41
42 /* DEFINITIONS ***************************************************************/
43
44 #define VIDMEM_BASE 0xb8000
45
46 #define CRTC_COMMAND ((PUCHAR)0x3d4)
47 #define CRTC_DATA ((PUCHAR)0x3d5)
48
49 #define CRTC_COLUMNS 0x01
50 #define CRTC_OVERFLOW 0x07
51 #define CRTC_ROWS 0x12
52 #define CRTC_SCANLINES 0x09
53 #define CRTC_CURSORSTART 0x0a
54 #define CRTC_CURSOREND 0x0b
55 #define CRTC_CURSORPOSHI 0x0e
56 #define CRTC_CURSORPOSLO 0x0f
57
58 #define ATTRC_WRITEREG ((PUCHAR)0x3c0)
59 #define ATTRC_READREG ((PUCHAR)0x3c1)
60 #define ATTRC_INPST1 ((PUCHAR)0x3da)
61
62 #define TAB_WIDTH 8
63
64
65 /* NOTES ******************************************************************/
66 /*
67 * [[character][attribute]][[character][attribute]]....
68 */
69
70
71 /* TYPEDEFS ***************************************************************/
72
73 typedef struct _DEVICE_EXTENSION
74 {
75 PUCHAR VideoMemory; /* Pointer to video memory */
76 ULONG CursorSize;
77 INT CursorVisible;
78 USHORT CharAttribute;
79 ULONG Mode;
80 UCHAR ScanLines; /* Height of a text line */
81 USHORT Rows; /* Number of rows */
82 USHORT Columns; /* Number of columns */
83 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
84
85
86 /* FUNCTIONS **************************************************************/
87
88 NTSTATUS STDCALL
89 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
90
91 static NTSTATUS STDCALL
92 ScrCreate(PDEVICE_OBJECT DeviceObject,
93 PIRP Irp)
94 {
95 PDEVICE_EXTENSION DeviceExtension;
96 PHYSICAL_ADDRESS BaseAddress;
97 NTSTATUS Status;
98 unsigned int offset;
99 UCHAR data, value;
100
101 DeviceExtension = DeviceObject->DeviceExtension;
102
103 /* disable interrupts */
104 _disable();
105
106 /* get current output position */
107 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
108 offset = READ_PORT_UCHAR (CRTC_DATA);
109 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
110 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
111
112 /* switch blinking characters off */
113 READ_PORT_UCHAR (ATTRC_INPST1);
114 value = READ_PORT_UCHAR (ATTRC_WRITEREG);
115 WRITE_PORT_UCHAR (ATTRC_WRITEREG, 0x10);
116 data = READ_PORT_UCHAR (ATTRC_READREG);
117 data = data & ~0x08;
118 WRITE_PORT_UCHAR (ATTRC_WRITEREG, data);
119 WRITE_PORT_UCHAR (ATTRC_WRITEREG, value);
120 READ_PORT_UCHAR (ATTRC_INPST1);
121
122 /* read screen information from crt controller */
123 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_COLUMNS);
124 DeviceExtension->Columns = READ_PORT_UCHAR (CRTC_DATA) + 1;
125 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_ROWS);
126 DeviceExtension->Rows = READ_PORT_UCHAR (CRTC_DATA);
127 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_OVERFLOW);
128 data = READ_PORT_UCHAR (CRTC_DATA);
129 DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3));
130 DeviceExtension->Rows++;
131 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES);
132 DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1;
133
134 /* enable interrupts */
135 _enable();
136
137 /* calculate number of text rows */
138 DeviceExtension->Rows =
139 DeviceExtension->Rows / DeviceExtension->ScanLines;
140 #ifdef BOCHS_30ROWS
141 DeviceExtension->Rows = 30;
142 #endif
143
144 DPRINT ("%d Columns %d Rows %d Scanlines\n",
145 DeviceExtension->Columns,
146 DeviceExtension->Rows,
147 DeviceExtension->ScanLines);
148
149 /* get pointer to video memory */
150 BaseAddress.QuadPart = VIDMEM_BASE;
151 DeviceExtension->VideoMemory =
152 (PUCHAR)MmMapIoSpace (BaseAddress, DeviceExtension->Rows * DeviceExtension->Columns * 2, MmNonCached);
153
154 DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
155 DeviceExtension->CursorVisible = TRUE;
156
157 /* more initialization */
158 DeviceExtension->CharAttribute = 0x17; /* light grey on blue */
159 DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
160 ENABLE_WRAP_AT_EOL_OUTPUT;
161
162 /* show blinking cursor */
163 _disable();
164 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
165 WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
166 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
167 data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
168 WRITE_PORT_UCHAR (CRTC_DATA,
169 data | ((DeviceExtension->ScanLines - 1) & 0x1F));
170 _enable();
171
172 Status = STATUS_SUCCESS;
173
174 Irp->IoStatus.Status = Status;
175 IoCompleteRequest (Irp, IO_NO_INCREMENT);
176
177 return (Status);
178 }
179
180
181 static NTSTATUS STDCALL
182 ScrWrite(PDEVICE_OBJECT DeviceObject,
183 PIRP Irp)
184 {
185 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
186 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
187 NTSTATUS Status;
188 char *pch = Irp->UserBuffer;
189 PUCHAR vidmem;
190 unsigned int i;
191 int j, offset;
192 int cursorx, cursory;
193 int rows, columns;
194 int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT;
195
196 if (HalQueryDisplayOwnership())
197 {
198 /* Display is in graphics mode, we're not allowed to touch it */
199 Status = STATUS_SUCCESS;
200
201 Irp->IoStatus.Status = Status;
202 IoCompleteRequest (Irp, IO_NO_INCREMENT);
203
204 return Status;
205 }
206
207 vidmem = DeviceExtension->VideoMemory;
208 rows = DeviceExtension->Rows;
209 columns = DeviceExtension->Columns;
210
211 _disable();
212 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
213 offset = READ_PORT_UCHAR (CRTC_DATA)<<8;
214 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
215 offset += READ_PORT_UCHAR (CRTC_DATA);
216 _enable();
217
218 cursory = offset / columns;
219 cursorx = offset % columns;
220 if( processed == 0 )
221 {
222 /* raw output mode */
223 memcpy( &vidmem[(cursorx * 2) + (cursory * columns * 2)], pch, stk->Parameters.Write.Length );
224 offset += (stk->Parameters.Write.Length / 2);
225 }
226 else {
227 for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
228 {
229 switch (*pch)
230 {
231 case '\b':
232 if (cursorx > 0)
233 {
234 cursorx--;
235 }
236 else if (cursory > 0)
237 {
238 cursorx = columns - 1;
239 cursory--;
240 }
241 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
242 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
243 break;
244
245 case '\n':
246 cursory++;
247 cursorx = 0;
248 break;
249
250 case '\r':
251 cursorx = 0;
252 break;
253
254 case '\t':
255 offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
256 for (j = 0; j < offset; j++)
257 {
258 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
259 cursorx++;
260
261 if (cursorx >= columns)
262 {
263 cursory++;
264 cursorx = 0;
265 }
266 }
267 break;
268
269 default:
270 vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
271 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
272 cursorx++;
273 if (cursorx >= columns)
274 {
275 cursory++;
276 cursorx = 0;
277 }
278 break;
279 }
280 if (cursory >= rows)
281 {
282 unsigned short *LinePtr;
283
284 memcpy (vidmem,
285 &vidmem[columns * 2],
286 columns * (rows - 1) * 2);
287
288 LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
289
290 for (j = 0; j < columns; j++)
291 {
292 LinePtr[j] = DeviceExtension->CharAttribute << 8;
293 }
294 cursory = rows - 1;
295 for (j = 0; j < columns; j++)
296 {
297 vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
298 vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
299 }
300 }
301 }
302
303 /* Set the cursor position */
304 offset = (cursory * columns) + cursorx;
305 }
306 _disable();
307 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
308 WRITE_PORT_UCHAR (CRTC_DATA, offset);
309 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
310 offset >>= 8;
311 WRITE_PORT_UCHAR (CRTC_DATA, offset);
312 _enable();
313
314 Status = STATUS_SUCCESS;
315
316 Irp->IoStatus.Status = Status;
317 IoCompleteRequest (Irp, IO_NO_INCREMENT);
318
319 return (Status);
320 }
321
322
323 static NTSTATUS STDCALL
324 ScrIoControl(PDEVICE_OBJECT DeviceObject,
325 PIRP Irp)
326 {
327 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
328 PDEVICE_EXTENSION DeviceExtension;
329 NTSTATUS Status;
330
331 DeviceExtension = DeviceObject->DeviceExtension;
332 switch (stk->Parameters.DeviceIoControl.IoControlCode)
333 {
334 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
335 {
336 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
337 int rows = DeviceExtension->Rows;
338 int columns = DeviceExtension->Columns;
339 unsigned int offset;
340
341 /* read cursor position from crtc */
342 _disable();
343 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
344 offset = READ_PORT_UCHAR (CRTC_DATA);
345 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
346 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
347 _enable();
348
349 pcsbi->dwSize.X = columns;
350 pcsbi->dwSize.Y = rows;
351
352 pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
353 pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
354
355 pcsbi->wAttributes = DeviceExtension->CharAttribute;
356
357 pcsbi->srWindow.Left = 0;
358 pcsbi->srWindow.Right = columns - 1;
359 pcsbi->srWindow.Top = 0;
360 pcsbi->srWindow.Bottom = rows - 1;
361
362 pcsbi->dwMaximumWindowSize.X = columns;
363 pcsbi->dwMaximumWindowSize.Y = rows;
364
365 Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
366 Status = STATUS_SUCCESS;
367 }
368 break;
369
370 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
371 {
372 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
373 unsigned int offset;
374
375 DeviceExtension->CharAttribute = pcsbi->wAttributes;
376 offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
377 pcsbi->dwCursorPosition.X;
378
379 _disable();
380 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
381 WRITE_PORT_UCHAR (CRTC_DATA, offset);
382 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
383 WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
384 _enable();
385
386 Irp->IoStatus.Information = 0;
387 Status = STATUS_SUCCESS;
388 }
389 break;
390
391 case IOCTL_CONSOLE_GET_CURSOR_INFO:
392 {
393 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
394
395 pcci->dwSize = DeviceExtension->CursorSize;
396 pcci->bVisible = DeviceExtension->CursorVisible;
397
398 Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
399 Status = STATUS_SUCCESS;
400 }
401 break;
402
403 case IOCTL_CONSOLE_SET_CURSOR_INFO:
404 {
405 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
406 UCHAR data, value;
407 ULONG size, height;
408
409 DeviceExtension->CursorSize = pcci->dwSize;
410 DeviceExtension->CursorVisible = pcci->bVisible;
411 height = DeviceExtension->ScanLines;
412 data = (pcci->bVisible) ? 0x00 : 0x20;
413
414 size = (pcci->dwSize * height) / 100;
415 if (size < 1)
416 {
417 size = 1;
418 }
419
420 data |= (UCHAR)(height - size);
421
422 _disable();
423 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
424 WRITE_PORT_UCHAR (CRTC_DATA, data);
425 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
426 value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
427 WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
428
429 _enable();
430
431 Irp->IoStatus.Information = 0;
432 Status = STATUS_SUCCESS;
433 }
434 break;
435
436 case IOCTL_CONSOLE_GET_MODE:
437 {
438 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
439
440 pcm->dwMode = DeviceExtension->Mode;
441
442 Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
443 Status = STATUS_SUCCESS;
444 }
445 break;
446
447 case IOCTL_CONSOLE_SET_MODE:
448 {
449 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
450
451 DeviceExtension->Mode = pcm->dwMode;
452
453 Irp->IoStatus.Information = 0;
454 Status = STATUS_SUCCESS;
455 }
456 break;
457
458 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
459 {
460 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
461 PUCHAR vidmem;
462 int offset;
463 ULONG dwCount;
464
465 vidmem = DeviceExtension->VideoMemory;
466 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
467 (Buf->dwCoord.X * 2) + 1;
468
469 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
470 {
471 vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
472 }
473
474 Buf->dwTransfered = Buf->nLength;
475
476 Irp->IoStatus.Information = 0;
477 Status = STATUS_SUCCESS;
478 }
479 break;
480
481 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
482 {
483 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
484 PUSHORT pAttr = (PUSHORT)MmGetSystemAddressForMdl(Irp->MdlAddress);
485 PUCHAR vidmem;
486 int offset;
487 ULONG dwCount;
488
489 vidmem = DeviceExtension->VideoMemory;
490 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
491 (Buf->dwCoord.X * 2) + 1;
492
493 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
494 {
495 *((char *) pAttr) = vidmem[offset + (dwCount * 2)];
496 }
497
498 Buf->dwTransfered = dwCount;
499
500 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
501 Status = STATUS_SUCCESS;
502 }
503 break;
504
505 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
506 {
507 COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
508 CHAR *pAttr = (CHAR *)(pCoord + 1);
509 PUCHAR vidmem;
510 int offset;
511 ULONG dwCount;
512
513 vidmem = DeviceExtension->VideoMemory;
514 offset = (pCoord->Y * DeviceExtension->Columns * 2) +
515 (pCoord->X * 2) + 1;
516
517 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pAttr++)
518 {
519 vidmem[offset + (dwCount * 2)] = *pAttr;
520 }
521 Irp->IoStatus.Information = 0;
522 Status = STATUS_SUCCESS;
523 }
524 break;
525
526 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
527 DeviceExtension->CharAttribute = (USHORT)*(PUSHORT)Irp->AssociatedIrp.SystemBuffer;
528 Irp->IoStatus.Information = 0;
529 Status = STATUS_SUCCESS;
530 break;
531
532 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
533 {
534 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
535 PUCHAR vidmem;
536 int offset;
537 ULONG dwCount;
538
539 vidmem = DeviceExtension->VideoMemory;
540 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
541 (Buf->dwCoord.X * 2);
542
543 CHECKPOINT
544
545 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
546 {
547 vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
548 }
549
550 Buf->dwTransfered = Buf->nLength;
551
552 Irp->IoStatus.Information = 0;
553 Status = STATUS_SUCCESS;
554 }
555 break;
556
557 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
558 {
559 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
560 LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
561 PUCHAR vidmem;
562 int offset;
563 ULONG dwCount;
564
565 vidmem = DeviceExtension->VideoMemory;
566 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
567 (Buf->dwCoord.X * 2);
568
569 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++)
570 {
571 *pChar = vidmem[offset + (dwCount * 2)];
572 }
573
574 Buf->dwTransfered = dwCount;
575
576 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
577 Status = STATUS_SUCCESS;
578 }
579 break;
580
581 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
582 {
583 COORD *pCoord;
584 LPSTR pChar;
585 PUCHAR vidmem;
586 int offset;
587 ULONG dwCount;
588
589 pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
590 pChar = (CHAR *)(pCoord + 1);
591 vidmem = DeviceExtension->VideoMemory;
592 offset = (pCoord->Y * DeviceExtension->Columns * 2) +
593 (pCoord->X * 2);
594
595 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pChar++)
596 {
597 vidmem[offset + (dwCount * 2)] = *pChar;
598 }
599
600 Irp->IoStatus.Information = 0;
601 Status = STATUS_SUCCESS;
602 }
603 break;
604
605 case IOCTL_CONSOLE_DRAW:
606 {
607 PCONSOLE_DRAW ConsoleDraw;
608 PUCHAR Src, Dest;
609 UINT SrcDelta, DestDelta, i, Offset;
610
611 ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
612 Src = (PUCHAR) (ConsoleDraw + 1);
613 SrcDelta = ConsoleDraw->SizeX * 2;
614 Dest = DeviceExtension->VideoMemory +
615 (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2;
616 DestDelta = DeviceExtension->Columns * 2;
617
618 for (i = 0; i < ConsoleDraw->SizeY; i++)
619 {
620 RtlCopyMemory(Dest, Src, SrcDelta);
621 Src += SrcDelta;
622 Dest += DestDelta;
623 }
624
625 Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
626 ConsoleDraw->CursorX;
627
628 _disable();
629 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
630 WRITE_PORT_UCHAR (CRTC_DATA, Offset);
631 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
632 WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8);
633 _enable();
634
635 Irp->IoStatus.Information = 0;
636 Status = STATUS_SUCCESS;
637 }
638 break;
639
640 default:
641 Status = STATUS_NOT_IMPLEMENTED;
642 }
643
644 Irp->IoStatus.Status = Status;
645 IoCompleteRequest (Irp, IO_NO_INCREMENT);
646
647 return Status;
648 }
649
650
651 static NTSTATUS STDCALL
652 ScrDispatch(PDEVICE_OBJECT DeviceObject,
653 PIRP Irp)
654 {
655 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
656 NTSTATUS Status;
657
658 switch (stk->MajorFunction)
659 {
660 case IRP_MJ_CLOSE:
661 Status = STATUS_SUCCESS;
662 break;
663
664 default:
665 Status = STATUS_NOT_IMPLEMENTED;
666 break;
667 }
668
669
670 Irp->IoStatus.Status = Status;
671 IoCompleteRequest (Irp, IO_NO_INCREMENT);
672
673 return (Status);
674 }
675
676
677 /*
678 * Module entry point
679 */
680 NTSTATUS STDCALL
681 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
682 {
683 PDEVICE_OBJECT DeviceObject;
684 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen");
685 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
686
687 DPRINT ("Screen Driver 0.0.6\n");
688
689 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
690 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
691 DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
692 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
693 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
694
695 IoCreateDevice (DriverObject,
696 sizeof(DEVICE_EXTENSION),
697 &DeviceName,
698 FILE_DEVICE_SCREEN,
699 0,
700 TRUE,
701 &DeviceObject);
702
703 IoCreateSymbolicLink (&SymlinkName, &DeviceName);
704
705 return (STATUS_SUCCESS);
706 }
707
708 /* EOF */