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