Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenblue.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: services/dd/blue/blue.c 00005 * PURPOSE: Console (blue screen) device driver 00006 * PROGRAMMER: Eric Kohl 00007 * UPDATE HISTORY: 00008 * ??? Created 00009 */ 00010 00011 /* INCLUDES ******************************************************************/ 00012 00013 //#include <intrin.h> 00014 #include "blue.h" 00015 00016 #define NDEBUG 00017 #include <debug.h> 00018 00019 // ROS Internal. Please deprecate. 00020 NTHALAPI 00021 BOOLEAN 00022 NTAPI 00023 HalQueryDisplayOwnership( 00024 VOID 00025 ); 00026 00027 /* NOTES ******************************************************************/ 00028 /* 00029 * [[character][attribute]][[character][attribute]].... 00030 */ 00031 00032 00033 /* TYPEDEFS ***************************************************************/ 00034 00035 typedef struct _DEVICE_EXTENSION 00036 { 00037 PUCHAR VideoMemory; /* Pointer to video memory */ 00038 ULONG CursorSize; 00039 INT CursorVisible; 00040 USHORT CharAttribute; 00041 ULONG Mode; 00042 UCHAR ScanLines; /* Height of a text line */ 00043 USHORT Rows; /* Number of rows */ 00044 USHORT Columns; /* Number of columns */ 00045 } DEVICE_EXTENSION, *PDEVICE_EXTENSION; 00046 00047 typedef struct _VGA_REGISTERS 00048 { 00049 UCHAR CRT[24]; 00050 UCHAR Attribute[21]; 00051 UCHAR Graphics[9]; 00052 UCHAR Sequencer[5]; 00053 UCHAR Misc; 00054 } VGA_REGISTERS, *PVGA_REGISTERS; 00055 00056 static const VGA_REGISTERS VidpMode3Regs = 00057 { 00058 /* CRT Controller Registers */ 00059 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00, 00060 0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3}, 00061 /* Attribute Controller Registers */ 00062 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 00063 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}, 00064 /* Graphics Controller Registers */ 00065 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF}, 00066 /* Sequencer Registers */ 00067 {0x03, 0x00, 0x03, 0x00, 0x02}, 00068 /* Misc Output Register */ 00069 0x67 00070 }; 00071 00072 static const UCHAR DefaultPalette[] = 00073 { 00074 0, 0, 0, 00075 0, 0, 0xC0, 00076 0, 0xC0, 0, 00077 0, 0xC0, 0xC0, 00078 0xC0, 0, 0, 00079 0xC0, 0, 0xC0, 00080 0xC0, 0xC0, 0, 00081 0xC0, 0xC0, 0xC0, 00082 0x80, 0x80, 0x80, 00083 0, 0, 0xFF, 00084 0, 0xFF, 0, 00085 0, 0xFF, 0xFF, 00086 0xFF, 0, 0, 00087 0xFF, 0, 0xFF, 00088 0xFF, 0xFF, 0, 00089 0xFF, 0xFF, 0xFF 00090 }; 00091 00092 /* FUNCTIONS **************************************************************/ 00093 00094 static VOID FASTCALL 00095 ScrSetRegisters(const VGA_REGISTERS *Registers) 00096 { 00097 UINT32 i; 00098 00099 /* Update misc output register */ 00100 WRITE_PORT_UCHAR(MISC, Registers->Misc); 00101 00102 /* Synchronous reset on */ 00103 WRITE_PORT_UCHAR(SEQ, 0x00); 00104 WRITE_PORT_UCHAR(SEQDATA, 0x01); 00105 00106 /* Write sequencer registers */ 00107 for (i = 1; i < sizeof(Registers->Sequencer); i++) 00108 { 00109 WRITE_PORT_UCHAR(SEQ, i); 00110 WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]); 00111 } 00112 00113 /* Synchronous reset off */ 00114 WRITE_PORT_UCHAR(SEQ, 0x00); 00115 WRITE_PORT_UCHAR(SEQDATA, 0x03); 00116 00117 /* Deprotect CRT registers 0-7 */ 00118 WRITE_PORT_UCHAR(CRTC, 0x11); 00119 WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f); 00120 00121 /* Write CRT registers */ 00122 for (i = 0; i < sizeof(Registers->CRT); i++) 00123 { 00124 WRITE_PORT_UCHAR(CRTC, i); 00125 WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]); 00126 } 00127 00128 /* Write graphics controller registers */ 00129 for (i = 0; i < sizeof(Registers->Graphics); i++) 00130 { 00131 WRITE_PORT_UCHAR(GRAPHICS, i); 00132 WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]); 00133 } 00134 00135 /* Write attribute controller registers */ 00136 for (i = 0; i < sizeof(Registers->Attribute); i++) 00137 { 00138 READ_PORT_UCHAR(STATUS); 00139 WRITE_PORT_UCHAR(ATTRIB, i); 00140 WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]); 00141 } 00142 00143 /* Set the PEL mask. */ 00144 WRITE_PORT_UCHAR(PELMASK, 0xff); 00145 } 00146 00147 static VOID FASTCALL 00148 ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension) 00149 { 00150 unsigned int offset; 00151 UCHAR data, value; 00152 ULONG Index; 00153 00154 ScrSetRegisters(&VidpMode3Regs); 00155 00156 /* Disable screen and enable palette access. */ 00157 READ_PORT_UCHAR(STATUS); 00158 WRITE_PORT_UCHAR(ATTRIB, 0x00); 00159 00160 for (Index = 0; Index < sizeof(DefaultPalette) / 3; Index++) 00161 { 00162 WRITE_PORT_UCHAR(PELINDEX, Index); 00163 WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3] >> 2); 00164 WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3 + 1] >> 2); 00165 WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3 + 2] >> 2); 00166 } 00167 00168 /* Enable screen and disable palette access. */ 00169 READ_PORT_UCHAR(STATUS); 00170 WRITE_PORT_UCHAR(ATTRIB, 0x20); 00171 00172 /* get current output position */ 00173 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00174 offset = READ_PORT_UCHAR (CRTC_DATA); 00175 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00176 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8); 00177 00178 /* switch blinking characters off */ 00179 READ_PORT_UCHAR (ATTRC_INPST1); 00180 value = READ_PORT_UCHAR (ATTRC_WRITEREG); 00181 WRITE_PORT_UCHAR (ATTRC_WRITEREG, 0x10); 00182 data = READ_PORT_UCHAR (ATTRC_READREG); 00183 data = data & ~0x08; 00184 WRITE_PORT_UCHAR (ATTRC_WRITEREG, data); 00185 WRITE_PORT_UCHAR (ATTRC_WRITEREG, value); 00186 READ_PORT_UCHAR (ATTRC_INPST1); 00187 00188 /* read screen information from crt controller */ 00189 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_COLUMNS); 00190 DeviceExtension->Columns = READ_PORT_UCHAR (CRTC_DATA) + 1; 00191 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_ROWS); 00192 DeviceExtension->Rows = READ_PORT_UCHAR (CRTC_DATA); 00193 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_OVERFLOW); 00194 data = READ_PORT_UCHAR (CRTC_DATA); 00195 DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3)); 00196 DeviceExtension->Rows++; 00197 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES); 00198 DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1; 00199 00200 /* show blinking cursor */ 00201 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART); 00202 WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F); 00203 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND); 00204 data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0; 00205 WRITE_PORT_UCHAR (CRTC_DATA, 00206 data | ((DeviceExtension->ScanLines - 1) & 0x1F)); 00207 00208 /* calculate number of text rows */ 00209 DeviceExtension->Rows = 00210 DeviceExtension->Rows / DeviceExtension->ScanLines; 00211 #ifdef BOCHS_30ROWS 00212 DeviceExtension->Rows = 30; 00213 #endif 00214 00215 DPRINT ("%d Columns %d Rows %d Scanlines\n", 00216 DeviceExtension->Columns, 00217 DeviceExtension->Rows, 00218 DeviceExtension->ScanLines); 00219 } 00220 00221 NTSTATUS NTAPI 00222 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); 00223 00224 static DRIVER_DISPATCH ScrCreate; 00225 static NTSTATUS NTAPI 00226 ScrCreate(PDEVICE_OBJECT DeviceObject, 00227 PIRP Irp) 00228 { 00229 PDEVICE_EXTENSION DeviceExtension; 00230 PHYSICAL_ADDRESS BaseAddress; 00231 NTSTATUS Status; 00232 00233 DeviceExtension = DeviceObject->DeviceExtension; 00234 00235 if (!InbvCheckDisplayOwnership()) 00236 { 00237 ScrAcquireOwnership(DeviceExtension); 00238 00239 /* get pointer to video memory */ 00240 BaseAddress.QuadPart = VIDMEM_BASE; 00241 DeviceExtension->VideoMemory = 00242 (PUCHAR)MmMapIoSpace (BaseAddress, DeviceExtension->Rows * DeviceExtension->Columns * 2, MmNonCached); 00243 } 00244 else 00245 { 00246 /* store dummy values here */ 00247 DeviceExtension->Columns = 1; 00248 DeviceExtension->Rows = 1; 00249 DeviceExtension->ScanLines = 1; 00250 } 00251 00252 DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */ 00253 DeviceExtension->CursorVisible = TRUE; 00254 00255 /* more initialization */ 00256 DeviceExtension->CharAttribute = 0x17; /* light grey on blue */ 00257 DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT | 00258 ENABLE_WRAP_AT_EOL_OUTPUT; 00259 00260 Status = STATUS_SUCCESS; 00261 00262 Irp->IoStatus.Status = Status; 00263 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00264 00265 return (Status); 00266 } 00267 00268 static DRIVER_DISPATCH ScrWrite; 00269 static NTSTATUS NTAPI 00270 ScrWrite(PDEVICE_OBJECT DeviceObject, 00271 PIRP Irp) 00272 { 00273 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp); 00274 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 00275 NTSTATUS Status; 00276 char *pch = Irp->UserBuffer; 00277 PUCHAR vidmem; 00278 unsigned int i; 00279 int j, offset; 00280 int cursorx, cursory; 00281 int rows, columns; 00282 int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT; 00283 00284 if (InbvCheckDisplayOwnership()) 00285 { 00286 /* Display is in graphics mode, we're not allowed to touch it */ 00287 Status = STATUS_SUCCESS; 00288 00289 Irp->IoStatus.Status = Status; 00290 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00291 00292 return Status; 00293 } 00294 00295 vidmem = DeviceExtension->VideoMemory; 00296 rows = DeviceExtension->Rows; 00297 columns = DeviceExtension->Columns; 00298 00299 _disable(); 00300 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00301 offset = READ_PORT_UCHAR (CRTC_DATA)<<8; 00302 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00303 offset += READ_PORT_UCHAR (CRTC_DATA); 00304 _enable(); 00305 00306 cursory = offset / columns; 00307 cursorx = offset % columns; 00308 if( processed == 0 ) 00309 { 00310 /* raw output mode */ 00311 memcpy( &vidmem[(cursorx * 2) + (cursory * columns * 2)], pch, stk->Parameters.Write.Length ); 00312 offset += (stk->Parameters.Write.Length / 2); 00313 } 00314 else { 00315 for (i = 0; i < stk->Parameters.Write.Length; i++, pch++) 00316 { 00317 switch (*pch) 00318 { 00319 case '\b': 00320 if (cursorx > 0) 00321 { 00322 cursorx--; 00323 } 00324 else if (cursory > 0) 00325 { 00326 cursorx = columns - 1; 00327 cursory--; 00328 } 00329 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' '; 00330 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute; 00331 break; 00332 00333 case '\n': 00334 cursory++; 00335 cursorx = 0; 00336 break; 00337 00338 case '\r': 00339 cursorx = 0; 00340 break; 00341 00342 case '\t': 00343 offset = TAB_WIDTH - (cursorx % TAB_WIDTH); 00344 for (j = 0; j < offset; j++) 00345 { 00346 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' '; 00347 cursorx++; 00348 00349 if (cursorx >= columns) 00350 { 00351 cursory++; 00352 cursorx = 0; 00353 } 00354 } 00355 break; 00356 00357 default: 00358 vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch; 00359 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute; 00360 cursorx++; 00361 if (cursorx >= columns) 00362 { 00363 cursory++; 00364 cursorx = 0; 00365 } 00366 break; 00367 } 00368 if (cursory >= rows) 00369 { 00370 unsigned short *LinePtr; 00371 00372 memcpy (vidmem, 00373 &vidmem[columns * 2], 00374 columns * (rows - 1) * 2); 00375 00376 LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2]; 00377 00378 for (j = 0; j < columns; j++) 00379 { 00380 LinePtr[j] = DeviceExtension->CharAttribute << 8; 00381 } 00382 cursory = rows - 1; 00383 for (j = 0; j < columns; j++) 00384 { 00385 vidmem[(j * 2) + (cursory * columns * 2)] = ' '; 00386 vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute; 00387 } 00388 } 00389 } 00390 00391 /* Set the cursor position */ 00392 offset = (cursory * columns) + cursorx; 00393 } 00394 _disable(); 00395 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00396 WRITE_PORT_UCHAR (CRTC_DATA, offset); 00397 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00398 offset >>= 8; 00399 WRITE_PORT_UCHAR (CRTC_DATA, offset); 00400 _enable(); 00401 00402 Status = STATUS_SUCCESS; 00403 00404 Irp->IoStatus.Status = Status; 00405 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00406 00407 return (Status); 00408 } 00409 00410 static DRIVER_DISPATCH ScrIoControl; 00411 static NTSTATUS NTAPI 00412 ScrIoControl(PDEVICE_OBJECT DeviceObject, 00413 PIRP Irp) 00414 { 00415 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp); 00416 PDEVICE_EXTENSION DeviceExtension; 00417 NTSTATUS Status; 00418 00419 DeviceExtension = DeviceObject->DeviceExtension; 00420 switch (stk->Parameters.DeviceIoControl.IoControlCode) 00421 { 00422 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO: 00423 { 00424 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer; 00425 int rows = DeviceExtension->Rows; 00426 int columns = DeviceExtension->Columns; 00427 unsigned int offset; 00428 00429 if (!InbvCheckDisplayOwnership()) 00430 { 00431 /* read cursor position from crtc */ 00432 _disable(); 00433 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00434 offset = READ_PORT_UCHAR (CRTC_DATA); 00435 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00436 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8); 00437 _enable(); 00438 } 00439 else 00440 { 00441 offset = 0; 00442 } 00443 00444 pcsbi->dwSize.X = columns; 00445 pcsbi->dwSize.Y = rows; 00446 00447 pcsbi->dwCursorPosition.X = (SHORT)(offset % columns); 00448 pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns); 00449 00450 pcsbi->wAttributes = DeviceExtension->CharAttribute; 00451 00452 pcsbi->srWindow.Left = 0; 00453 pcsbi->srWindow.Right = columns - 1; 00454 pcsbi->srWindow.Top = 0; 00455 pcsbi->srWindow.Bottom = rows - 1; 00456 00457 pcsbi->dwMaximumWindowSize.X = columns; 00458 pcsbi->dwMaximumWindowSize.Y = rows; 00459 00460 Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO); 00461 Status = STATUS_SUCCESS; 00462 } 00463 break; 00464 00465 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO: 00466 { 00467 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer; 00468 unsigned int offset; 00469 00470 DeviceExtension->CharAttribute = pcsbi->wAttributes; 00471 offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) + 00472 pcsbi->dwCursorPosition.X; 00473 00474 if (!InbvCheckDisplayOwnership()) 00475 { 00476 _disable(); 00477 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00478 WRITE_PORT_UCHAR (CRTC_DATA, offset); 00479 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00480 WRITE_PORT_UCHAR (CRTC_DATA, offset>>8); 00481 _enable(); 00482 } 00483 00484 Irp->IoStatus.Information = 0; 00485 Status = STATUS_SUCCESS; 00486 } 00487 break; 00488 00489 case IOCTL_CONSOLE_GET_CURSOR_INFO: 00490 { 00491 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer; 00492 00493 pcci->dwSize = DeviceExtension->CursorSize; 00494 pcci->bVisible = DeviceExtension->CursorVisible; 00495 00496 Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO); 00497 Status = STATUS_SUCCESS; 00498 } 00499 break; 00500 00501 case IOCTL_CONSOLE_SET_CURSOR_INFO: 00502 { 00503 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer; 00504 UCHAR data, value; 00505 ULONG size, height; 00506 00507 DeviceExtension->CursorSize = pcci->dwSize; 00508 DeviceExtension->CursorVisible = pcci->bVisible; 00509 00510 if (!InbvCheckDisplayOwnership()) 00511 { 00512 height = DeviceExtension->ScanLines; 00513 data = (pcci->bVisible) ? 0x00 : 0x20; 00514 00515 size = (pcci->dwSize * height) / 100; 00516 if (size < 1) 00517 { 00518 size = 1; 00519 } 00520 00521 data |= (UCHAR)(height - size); 00522 00523 _disable(); 00524 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART); 00525 WRITE_PORT_UCHAR (CRTC_DATA, data); 00526 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND); 00527 value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0; 00528 WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1)); 00529 00530 _enable(); 00531 } 00532 00533 Irp->IoStatus.Information = 0; 00534 Status = STATUS_SUCCESS; 00535 } 00536 break; 00537 00538 case IOCTL_CONSOLE_GET_MODE: 00539 { 00540 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; 00541 00542 pcm->dwMode = DeviceExtension->Mode; 00543 00544 Irp->IoStatus.Information = sizeof(CONSOLE_MODE); 00545 Status = STATUS_SUCCESS; 00546 } 00547 break; 00548 00549 case IOCTL_CONSOLE_SET_MODE: 00550 { 00551 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; 00552 00553 DeviceExtension->Mode = pcm->dwMode; 00554 00555 Irp->IoStatus.Information = 0; 00556 Status = STATUS_SUCCESS; 00557 } 00558 break; 00559 00560 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE: 00561 { 00562 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer; 00563 PUCHAR vidmem; 00564 int offset; 00565 ULONG dwCount; 00566 00567 if (!InbvCheckDisplayOwnership()) 00568 { 00569 vidmem = DeviceExtension->VideoMemory; 00570 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + 00571 (Buf->dwCoord.X * 2) + 1; 00572 00573 for (dwCount = 0; dwCount < Buf->nLength; dwCount++) 00574 { 00575 vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute; 00576 } 00577 } 00578 00579 Buf->dwTransfered = Buf->nLength; 00580 00581 Irp->IoStatus.Information = 0; 00582 Status = STATUS_SUCCESS; 00583 } 00584 break; 00585 00586 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE: 00587 { 00588 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer; 00589 PUSHORT pAttr = (PUSHORT)MmGetSystemAddressForMdl(Irp->MdlAddress); 00590 PUCHAR vidmem; 00591 int offset; 00592 ULONG dwCount; 00593 00594 if (!InbvCheckDisplayOwnership()) 00595 { 00596 vidmem = DeviceExtension->VideoMemory; 00597 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + 00598 (Buf->dwCoord.X * 2) + 1; 00599 00600 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++) 00601 { 00602 *((char *) pAttr) = vidmem[offset + (dwCount * 2)]; 00603 } 00604 00605 Buf->dwTransfered = dwCount; 00606 } 00607 else 00608 { 00609 Buf->dwTransfered = 0; 00610 } 00611 00612 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE); 00613 Status = STATUS_SUCCESS; 00614 } 00615 break; 00616 00617 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE: 00618 { 00619 COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress); 00620 CHAR *pAttr = (CHAR *)(pCoord + 1); 00621 PUCHAR vidmem; 00622 int offset; 00623 ULONG dwCount; 00624 00625 if (!InbvCheckDisplayOwnership()) 00626 { 00627 vidmem = DeviceExtension->VideoMemory; 00628 offset = (pCoord->Y * DeviceExtension->Columns * 2) + 00629 (pCoord->X * 2) + 1; 00630 00631 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pAttr++) 00632 { 00633 vidmem[offset + (dwCount * 2)] = *pAttr; 00634 } 00635 } 00636 00637 Irp->IoStatus.Information = 0; 00638 Status = STATUS_SUCCESS; 00639 } 00640 break; 00641 00642 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE: 00643 DeviceExtension->CharAttribute = (USHORT)*(PUSHORT)Irp->AssociatedIrp.SystemBuffer; 00644 Irp->IoStatus.Information = 0; 00645 Status = STATUS_SUCCESS; 00646 break; 00647 00648 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER: 00649 { 00650 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer; 00651 PUCHAR vidmem; 00652 int offset; 00653 ULONG dwCount; 00654 00655 if (!InbvCheckDisplayOwnership()) 00656 { 00657 vidmem = DeviceExtension->VideoMemory; 00658 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + 00659 (Buf->dwCoord.X * 2); 00660 00661 00662 for (dwCount = 0; dwCount < Buf->nLength; dwCount++) 00663 { 00664 vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter; 00665 } 00666 } 00667 00668 Buf->dwTransfered = Buf->nLength; 00669 00670 Irp->IoStatus.Information = 0; 00671 Status = STATUS_SUCCESS; 00672 } 00673 break; 00674 00675 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER: 00676 { 00677 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer; 00678 LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress); 00679 PUCHAR vidmem; 00680 int offset; 00681 ULONG dwCount; 00682 00683 if (!InbvCheckDisplayOwnership()) 00684 { 00685 vidmem = DeviceExtension->VideoMemory; 00686 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + 00687 (Buf->dwCoord.X * 2); 00688 00689 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++) 00690 { 00691 *pChar = vidmem[offset + (dwCount * 2)]; 00692 } 00693 00694 Buf->dwTransfered = dwCount; 00695 } 00696 else 00697 { 00698 Buf->dwTransfered = 0; 00699 } 00700 00701 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE); 00702 Status = STATUS_SUCCESS; 00703 } 00704 break; 00705 00706 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER: 00707 { 00708 COORD *pCoord; 00709 LPSTR pChar; 00710 PUCHAR vidmem; 00711 int offset; 00712 ULONG dwCount; 00713 00714 if (!InbvCheckDisplayOwnership()) 00715 { 00716 pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress); 00717 pChar = (CHAR *)(pCoord + 1); 00718 vidmem = DeviceExtension->VideoMemory; 00719 offset = (pCoord->Y * DeviceExtension->Columns * 2) + 00720 (pCoord->X * 2); 00721 00722 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pChar++) 00723 { 00724 vidmem[offset + (dwCount * 2)] = *pChar; 00725 } 00726 } 00727 00728 Irp->IoStatus.Information = 0; 00729 Status = STATUS_SUCCESS; 00730 } 00731 break; 00732 00733 case IOCTL_CONSOLE_DRAW: 00734 { 00735 PCONSOLE_DRAW ConsoleDraw; 00736 PUCHAR Src, Dest; 00737 UINT32 SrcDelta, DestDelta, i, Offset; 00738 00739 if (!InbvCheckDisplayOwnership()) 00740 { 00741 ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress); 00742 Src = (PUCHAR) (ConsoleDraw + 1); 00743 SrcDelta = ConsoleDraw->SizeX * 2; 00744 Dest = DeviceExtension->VideoMemory + 00745 (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2; 00746 DestDelta = DeviceExtension->Columns * 2; 00747 00748 for (i = 0; i < ConsoleDraw->SizeY; i++) 00749 { 00750 RtlCopyMemory(Dest, Src, SrcDelta); 00751 Src += SrcDelta; 00752 Dest += DestDelta; 00753 } 00754 00755 Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) + 00756 ConsoleDraw->CursorX; 00757 00758 _disable(); 00759 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); 00760 WRITE_PORT_UCHAR (CRTC_DATA, Offset); 00761 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); 00762 WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8); 00763 _enable(); 00764 } 00765 00766 Irp->IoStatus.Information = 0; 00767 Status = STATUS_SUCCESS; 00768 } 00769 break; 00770 00771 case IOCTL_CONSOLE_LOADFONT: 00772 { 00773 UINT32 CodePage = (UINT32)*(PULONG)Irp->AssociatedIrp.SystemBuffer; 00774 00775 if (!InbvCheckDisplayOwnership()) 00776 { 00777 // Upload a font for the codepage if needed 00778 ScrLoadFontTable(CodePage); 00779 } 00780 00781 Irp->IoStatus.Information = 0; 00782 Status = STATUS_SUCCESS; 00783 } 00784 break; 00785 00786 default: 00787 Status = STATUS_NOT_IMPLEMENTED; 00788 } 00789 00790 Irp->IoStatus.Status = Status; 00791 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00792 00793 return Status; 00794 } 00795 00796 static DRIVER_DISPATCH ScrDispatch; 00797 static NTSTATUS NTAPI 00798 ScrDispatch(PDEVICE_OBJECT DeviceObject, 00799 PIRP Irp) 00800 { 00801 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp); 00802 NTSTATUS Status; 00803 00804 switch (stk->MajorFunction) 00805 { 00806 case IRP_MJ_CLOSE: 00807 Status = STATUS_SUCCESS; 00808 break; 00809 00810 default: 00811 Status = STATUS_NOT_IMPLEMENTED; 00812 break; 00813 } 00814 00815 00816 Irp->IoStatus.Status = Status; 00817 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00818 00819 return (Status); 00820 } 00821 00822 00823 /* 00824 * Module entry point 00825 */ 00826 NTSTATUS NTAPI 00827 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 00828 { 00829 PDEVICE_OBJECT DeviceObject; 00830 NTSTATUS Status; 00831 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen"); 00832 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen"); 00833 00834 DPRINT ("Screen Driver 0.0.6\n"); 00835 00836 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate; 00837 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch; 00838 DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch; 00839 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite; 00840 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl; 00841 00842 Status = IoCreateDevice (DriverObject, 00843 sizeof(DEVICE_EXTENSION), 00844 &DeviceName, 00845 FILE_DEVICE_SCREEN, 00846 FILE_DEVICE_SECURE_OPEN, 00847 TRUE, 00848 &DeviceObject); 00849 00850 if (!NT_SUCCESS(Status)) 00851 { 00852 return Status; 00853 } 00854 00855 Status = IoCreateSymbolicLink (&SymlinkName, &DeviceName); 00856 if (NT_SUCCESS(Status)) 00857 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00858 else 00859 IoDeleteDevice (DeviceObject); 00860 return Status; 00861 } 00862 00863 /* EOF */ Generated on Thu May 24 2012 04:28:45 for ReactOS by
1.7.6.1
|