[BLUE] Initialize the console with a default font for codepage 437.
[reactos.git] / drivers / setup / blue / blue.c
index 5d9105d..1403c19 100644 (file)
@@ -10,7 +10,6 @@
 
 /* INCLUDES ******************************************************************/
 
-//#include <intrin.h>
 #include "blue.h"
 
 #define NDEBUG
@@ -212,6 +211,9 @@ ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension)
     DeviceExtension->Rows = 30;
 #endif
 
+    /* Upload a default font for the default codepage 437 */
+    ScrLoadFontTable(437);
+
     DPRINT ("%d Columns  %d Rows %d Scanlines\n",
             DeviceExtension->Columns,
             DeviceExtension->Rows,
@@ -308,13 +310,15 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
     if( processed == 0 )
        {
       /* raw output mode */
+      // FIXME: Does the buffer only contains chars? or chars + attributes?
+      // FIXME2: Fix buffer overflow.
       memcpy( &vidmem[(cursorx * 2) + (cursory * columns * 2)], pch, stk->Parameters.Write.Length );
       offset += (stk->Parameters.Write.Length / 2);
        }
     else {
-       for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
+      for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
       {
-         switch (*pch)
+        switch (*pch)
         {
         case '\b':
            if (cursorx > 0)
@@ -365,7 +369,9 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
               }
            break;
         }
-         if (cursory >= rows)
+
+        /* Scroll up the contents of the screen if we are at the end */
+        if (cursory >= rows)
         {
            unsigned short *LinePtr;
 
@@ -404,7 +410,7 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
     Irp->IoStatus.Status = Status;
     IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-    return (Status);
+    return Status;
 }
 
 static DRIVER_DISPATCH ScrIoControl;
@@ -467,6 +473,14 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
           unsigned int offset;
 
+          if ( pcsbi->dwCursorPosition.X < 0 || pcsbi->dwCursorPosition.X >= DeviceExtension->Columns ||
+               pcsbi->dwCursorPosition.Y < 0 || pcsbi->dwCursorPosition.Y >= DeviceExtension->Rows )
+          {
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_INVALID_PARAMETER;
+              break;
+          }
+
           DeviceExtension->CharAttribute = pcsbi->wAttributes;
           offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
                     pcsbi->dwCursorPosition.X;
@@ -563,20 +577,34 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength = Buf->nLength;
+
+          if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
+               Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
+          {
+              Buf->dwTransfered = 0;
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
             vidmem = DeviceExtension->VideoMemory;
             offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                        (Buf->dwCoord.X * 2) + 1;
+                     (Buf->dwCoord.X * 2) + 1;
+
+            nMaxLength = min(nMaxLength,
+                             (DeviceExtension->Rows - Buf->dwCoord.Y)
+                                * DeviceExtension->Columns - Buf->dwCoord.X);
 
-            for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++)
             {
               vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
             }
           }
 
-          Buf->dwTransfered = Buf->nLength;
+          Buf->dwTransfered = nMaxLength;
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -590,6 +618,16 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
+
+          if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
+               Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
+          {
+              Buf->dwTransfered = 0;
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
@@ -597,9 +635,13 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
             offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
                      (Buf->dwCoord.X * 2) + 1;
 
-            for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
+            nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
+                             (DeviceExtension->Rows - Buf->dwCoord.Y)
+                                * DeviceExtension->Columns - Buf->dwCoord.X);
+
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
             {
-              *((char *) pAttr) = vidmem[offset + (dwCount * 2)];
+              *((char *)pAttr) = vidmem[offset + (dwCount * 2)];
             }
 
             Buf->dwTransfered = dwCount;
@@ -621,14 +663,27 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
+
+          if ( pCoord->X < 0 || pCoord->X >= DeviceExtension->Columns ||
+               pCoord->Y < 0 || pCoord->Y >= DeviceExtension->Rows )
+          {
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
             vidmem = DeviceExtension->VideoMemory;
             offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                    (pCoord->X * 2) + 1;
+                     (pCoord->X * 2) + 1;
+
+            nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD),
+                             (DeviceExtension->Rows - pCoord->Y)
+                                * DeviceExtension->Columns - pCoord->X);
 
-            for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pAttr++)
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++, pAttr++)
             {
               vidmem[offset + (dwCount * 2)] = *pAttr;
             }
@@ -651,21 +706,34 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength = Buf->nLength;
+
+          if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
+               Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
+          {
+              Buf->dwTransfered = 0;
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
             vidmem = DeviceExtension->VideoMemory;
             offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                    (Buf->dwCoord.X * 2);
+                     (Buf->dwCoord.X * 2);
 
+            nMaxLength = min(nMaxLength,
+                             (DeviceExtension->Rows - Buf->dwCoord.Y)
+                                * DeviceExtension->Columns - Buf->dwCoord.X);
 
-            for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++)
             {
               vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
             }
           }
 
-          Buf->dwTransfered = Buf->nLength;
+          Buf->dwTransfered = nMaxLength;
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -679,14 +747,28 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
+
+          if ( Buf->dwCoord.X < 0 || Buf->dwCoord.X >= DeviceExtension->Columns ||
+               Buf->dwCoord.Y < 0 || Buf->dwCoord.Y >= DeviceExtension->Rows )
+          {
+              Buf->dwTransfered = 0;
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
             vidmem = DeviceExtension->VideoMemory;
             offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                    (Buf->dwCoord.X * 2);
+                     (Buf->dwCoord.X * 2);
+
+            nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength,
+                             (DeviceExtension->Rows - Buf->dwCoord.Y)
+                                * DeviceExtension->Columns - Buf->dwCoord.X);
 
-            for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++)
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
             {
               *pChar = vidmem[offset + (dwCount * 2)];
             }
@@ -705,21 +787,32 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
 
       case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
         {
-          COORD *pCoord;
-          LPSTR pChar;
+          COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
+          LPSTR pChar = (CHAR *)(pCoord + 1);
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
+
+          if ( pCoord->X < 0 || pCoord->X >= DeviceExtension->Columns ||
+               pCoord->Y < 0 || pCoord->Y >= DeviceExtension->Rows )
+          {
+              Irp->IoStatus.Information = 0;
+              Status = STATUS_SUCCESS;
+              break;
+          }
 
           if (!InbvCheckDisplayOwnership())
           {
-            pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
-            pChar = (CHAR *)(pCoord + 1);
             vidmem = DeviceExtension->VideoMemory;
             offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                    (pCoord->X * 2);
+                     (pCoord->X * 2);
+
+            nMaxLength = min(stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof(COORD),
+                             (DeviceExtension->Rows - pCoord->Y)
+                                * DeviceExtension->Columns - pCoord->X);
 
-            for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pChar++)
+            for (dwCount = 0; dwCount < nMaxLength; dwCount++, pChar++)
             {
               vidmem[offset + (dwCount * 2)] = *pChar;
             }
@@ -753,7 +846,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
             }
 
             Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
-                    ConsoleDraw->CursorX;
+                      ConsoleDraw->CursorX;
 
             _disable();
             WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
@@ -774,7 +867,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
 
               if (!InbvCheckDisplayOwnership())
               {
-                // Upload a font for the codepage if needed
+                /* Upload a font for the codepage if needed */
                 ScrLoadFontTable(CodePage);
               }
 
@@ -816,7 +909,7 @@ ScrDispatch(PDEVICE_OBJECT DeviceObject,
     Irp->IoStatus.Status = Status;
     IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-    return (Status);
+    return Status;
 }