[BLUE] Perform size/rectangle boundary checks on read/write operations. CORE-15108
[reactos.git] / drivers / setup / blue / blue.c
index f7a71f7..7367cea 100644 (file)
@@ -10,7 +10,6 @@
 
 /* INCLUDES ******************************************************************/
 
-//#include <intrin.h>
 #include "blue.h"
 
 #define NDEBUG
@@ -224,7 +223,7 @@ DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
 static DRIVER_DISPATCH ScrCreate;
 static NTSTATUS NTAPI
 ScrCreate(PDEVICE_OBJECT DeviceObject,
-         PIRP Irp)
+      PIRP Irp)
 {
     PDEVICE_EXTENSION DeviceExtension;
     PHYSICAL_ADDRESS BaseAddress;
@@ -232,12 +231,22 @@ ScrCreate(PDEVICE_OBJECT DeviceObject,
 
     DeviceExtension = DeviceObject->DeviceExtension;
 
-    ScrAcquireOwnership(DeviceExtension);
+    if (!InbvCheckDisplayOwnership())
+    {
+        ScrAcquireOwnership(DeviceExtension);
 
-    /* get pointer to video memory */
-    BaseAddress.QuadPart = VIDMEM_BASE;
-    DeviceExtension->VideoMemory =
-        (PUCHAR)MmMapIoSpace (BaseAddress, DeviceExtension->Rows * DeviceExtension->Columns * 2, MmNonCached);
+        /* get pointer to video memory */
+        BaseAddress.QuadPart = VIDMEM_BASE;
+        DeviceExtension->VideoMemory =
+            (PUCHAR)MmMapIoSpace (BaseAddress, DeviceExtension->Rows * DeviceExtension->Columns * 2, MmNonCached);
+    }
+    else
+    {
+        /* store dummy values here */
+        DeviceExtension->Columns = 1;
+        DeviceExtension->Rows = 1;
+        DeviceExtension->ScanLines = 1;
+    }
 
     DeviceExtension->CursorSize    = 5; /* FIXME: value correct?? */
     DeviceExtension->CursorVisible = TRUE;
@@ -258,7 +267,7 @@ ScrCreate(PDEVICE_OBJECT DeviceObject,
 static DRIVER_DISPATCH ScrWrite;
 static NTSTATUS NTAPI
 ScrWrite(PDEVICE_OBJECT DeviceObject,
-        PIRP Irp)
+     PIRP Irp)
 {
     PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
     PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
@@ -271,16 +280,16 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
     int rows, columns;
     int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT;
 
-    if (0 && InbvCheckDisplayOwnership())
-       {
-         /* Display is in graphics mode, we're not allowed to touch it */
-         Status = STATUS_SUCCESS;
+    if (InbvCheckDisplayOwnership())
+    {
+        /* Display is in graphics mode, we're not allowed to touch it */
+        Status = STATUS_SUCCESS;
 
-         Irp->IoStatus.Status = Status;
-         IoCompleteRequest (Irp, IO_NO_INCREMENT);
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-         return Status;
-       }
+        return Status;
+    }
 
     vidmem  = DeviceExtension->VideoMemory;
     rows = DeviceExtension->Rows;
@@ -297,86 +306,90 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
     cursorx = offset % columns;
     if( processed == 0 )
        {
-         /* raw output mode */
-         memcpy( &vidmem[(cursorx * 2) + (cursory * columns * 2)], pch, stk->Parameters.Write.Length );
-         offset += (stk->Parameters.Write.Length / 2);
+      /* 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++)
-         {
-            switch (*pch)
-               {
-               case '\b':
-                  if (cursorx > 0)
-                     {
-                        cursorx--;
-                     }
-                  else if (cursory > 0)
-                     {
-                        cursorx = columns - 1;
-                        cursory--;
-                     }
-                  vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
-                  vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
-                  break;
-
-               case '\n':
-                  cursory++;
-                  cursorx = 0;
-                  break;
-
-               case '\r':
-                  cursorx = 0;
-                  break;
-
-               case '\t':
-                  offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
-                  for (j = 0; j < offset; j++)
-                     {
-                        vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
-                        cursorx++;
-
-                        if (cursorx >= columns)
-                           {
-                              cursory++;
-                              cursorx = 0;
-                           }
-                     }
-                  break;
-
-               default:
-                  vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
-                  vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
-                  cursorx++;
-                  if (cursorx >= columns)
-                     {
-                        cursory++;
-                        cursorx = 0;
-                     }
-                  break;
-               }
-            if (cursory >= rows)
-               {
-                  unsigned short *LinePtr;
-
-                  memcpy (vidmem,
-                          &vidmem[columns * 2],
-                          columns * (rows - 1) * 2);
-
-                  LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
-
-                  for (j = 0; j < columns; j++)
-                     {
-                        LinePtr[j] = DeviceExtension->CharAttribute << 8;
-                     }
-                  cursory = rows - 1;
-                  for (j = 0; j < columns; j++)
-                     {
-                        vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
-                        vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
-                     }
-               }
-         }
+      for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
+      {
+        switch (*pch)
+        {
+        case '\b':
+           if (cursorx > 0)
+              {
+             cursorx--;
+              }
+           else if (cursory > 0)
+              {
+             cursorx = columns - 1;
+             cursory--;
+              }
+           vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
+           vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
+           break;
+
+        case '\n':
+           cursory++;
+           cursorx = 0;
+           break;
+
+        case '\r':
+           cursorx = 0;
+           break;
+
+        case '\t':
+           offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
+           for (j = 0; j < offset; j++)
+              {
+             vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
+             cursorx++;
+
+             if (cursorx >= columns)
+                {
+                   cursory++;
+                   cursorx = 0;
+                }
+              }
+           break;
+
+        default:
+           vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
+           vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
+           cursorx++;
+           if (cursorx >= columns)
+              {
+             cursory++;
+             cursorx = 0;
+              }
+           break;
+        }
+
+        /* Scroll up the contents of the screen if we are at the end */
+        if (cursory >= rows)
+        {
+           unsigned short *LinePtr;
+
+           memcpy (vidmem,
+               &vidmem[columns * 2],
+               columns * (rows - 1) * 2);
+
+           LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
+
+           for (j = 0; j < columns; j++)
+              {
+             LinePtr[j] = DeviceExtension->CharAttribute << 8;
+              }
+           cursory = rows - 1;
+           for (j = 0; j < columns; j++)
+              {
+             vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
+             vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
+              }
+        }
+      }
 
        /* Set the cursor position */
        offset = (cursory * columns) + cursorx;
@@ -394,13 +407,13 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
     Irp->IoStatus.Status = Status;
     IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-    return (Status);
+    return Status;
 }
 
 static DRIVER_DISPATCH ScrIoControl;
 static NTSTATUS NTAPI
 ScrIoControl(PDEVICE_OBJECT DeviceObject,
-            PIRP Irp)
+         PIRP Irp)
 {
   PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
   PDEVICE_EXTENSION DeviceExtension;
@@ -416,13 +429,20 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           int columns = DeviceExtension->Columns;
           unsigned int offset;
 
-          /* read cursor position from crtc */
-          _disable();
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
-          offset = READ_PORT_UCHAR (CRTC_DATA);
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
-          offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
-          _enable();
+          if (!InbvCheckDisplayOwnership())
+          {
+            /* read cursor position from crtc */
+            _disable();
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+            offset = READ_PORT_UCHAR (CRTC_DATA);
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+            offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
+            _enable();
+          }
+          else
+          {
+            offset = 0;
+          }
 
           pcsbi->dwSize.X = columns;
           pcsbi->dwSize.Y = rows;
@@ -450,16 +470,27 @@ 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;
 
-          _disable();
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
-          WRITE_PORT_UCHAR (CRTC_DATA, offset);
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
-          WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
-          _enable();
+          if (!InbvCheckDisplayOwnership())
+          {
+            _disable();
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+            WRITE_PORT_UCHAR (CRTC_DATA, offset);
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+            WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
+            _enable();
+          }
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -486,25 +517,29 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
 
           DeviceExtension->CursorSize = pcci->dwSize;
           DeviceExtension->CursorVisible = pcci->bVisible;
-          height = DeviceExtension->ScanLines;
-          data = (pcci->bVisible) ? 0x00 : 0x20;
 
-          size = (pcci->dwSize * height) / 100;
-          if (size < 1)
+          if (!InbvCheckDisplayOwnership())
+          {
+            height = DeviceExtension->ScanLines;
+            data = (pcci->bVisible) ? 0x00 : 0x20;
+
+            size = (pcci->dwSize * height) / 100;
+            if (size < 1)
             {
               size = 1;
             }
 
-          data |= (UCHAR)(height - size);
+            data |= (UCHAR)(height - size);
 
-          _disable();
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
-          WRITE_PORT_UCHAR (CRTC_DATA, data);
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
-          value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
-          WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
+            _disable();
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
+            WRITE_PORT_UCHAR (CRTC_DATA, data);
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
+            value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
+            WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
 
-          _enable();
+            _enable();
+          }
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -539,17 +574,34 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength = Buf->nLength;
 
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                    (Buf->dwCoord.X * 2) + 1;
+          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;
+
+            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;
@@ -563,17 +615,38 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
 
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                   (Buf->dwCoord.X * 2) + 1;
+          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;
+          }
 
-          for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
+          if (!InbvCheckDisplayOwnership())
+          {
+            vidmem = DeviceExtension->VideoMemory;
+            offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
+                     (Buf->dwCoord.X * 2) + 1;
+
+            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;
+            Buf->dwTransfered = dwCount;
+          }
+          else
+          {
+            Buf->dwTransfered = 0;
+          }
 
           Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
           Status = STATUS_SUCCESS;
@@ -587,15 +660,32 @@ 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;
 
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                   (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;
             }
+          }
+
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
         }
@@ -613,18 +703,34 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength = Buf->nLength;
 
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                   (Buf->dwCoord.X * 2);
+          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);
+
+            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;
@@ -638,17 +744,38 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR vidmem;
           int offset;
           ULONG dwCount;
+          ULONG nMaxLength;
 
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
-                   (Buf->dwCoord.X * 2);
+          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);
+
+            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)];
             }
 
-          Buf->dwTransfered = dwCount;
+            Buf->dwTransfered = dwCount;
+          }
+          else
+          {
+            Buf->dwTransfered = 0;
+          }
 
           Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
           Status = STATUS_SUCCESS;
@@ -657,22 +784,36 @@ 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;
+          }
 
-          pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
-          pChar = (CHAR *)(pCoord + 1);
-          vidmem = DeviceExtension->VideoMemory;
-          offset = (pCoord->Y * DeviceExtension->Columns * 2) +
-                   (pCoord->X * 2);
+          if (!InbvCheckDisplayOwnership())
+          {
+            vidmem = DeviceExtension->VideoMemory;
+            offset = (pCoord->Y * DeviceExtension->Columns * 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;
             }
+          }
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -685,29 +826,32 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           PUCHAR Src, Dest;
           UINT32 SrcDelta, DestDelta, i, Offset;
 
-          ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
-          Src = (PUCHAR) (ConsoleDraw + 1);
-          SrcDelta = ConsoleDraw->SizeX * 2;
-          Dest = DeviceExtension->VideoMemory +
-                 (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2;
-          DestDelta = DeviceExtension->Columns * 2;
-
-          for (i = 0; i < ConsoleDraw->SizeY; i++)
+          if (!InbvCheckDisplayOwnership())
+          {
+            ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
+            Src = (PUCHAR) (ConsoleDraw + 1);
+            SrcDelta = ConsoleDraw->SizeX * 2;
+            Dest = DeviceExtension->VideoMemory +
+                    (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2;
+            DestDelta = DeviceExtension->Columns * 2;
+
+            for (i = 0; i < ConsoleDraw->SizeY; i++)
             {
               RtlCopyMemory(Dest, Src, SrcDelta);
               Src += SrcDelta;
               Dest += DestDelta;
             }
 
-          Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
-                   ConsoleDraw->CursorX;
+            Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
+                      ConsoleDraw->CursorX;
 
-          _disable();
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
-          WRITE_PORT_UCHAR (CRTC_DATA, Offset);
-          WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
-          WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8);
-          _enable();
+            _disable();
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
+            WRITE_PORT_UCHAR (CRTC_DATA, Offset);
+            WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
+            WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8);
+            _enable();
+          }
 
           Irp->IoStatus.Information = 0;
           Status = STATUS_SUCCESS;
@@ -718,8 +862,11 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
           {
               UINT32 CodePage = (UINT32)*(PULONG)Irp->AssociatedIrp.SystemBuffer;
 
-              // Upload a font for the codepage if needed
-              ScrLoadFontTable(CodePage);
+              if (!InbvCheckDisplayOwnership())
+              {
+                // Upload a font for the codepage if needed
+                ScrLoadFontTable(CodePage);
+              }
 
               Irp->IoStatus.Information = 0;
               Status = STATUS_SUCCESS;
@@ -739,7 +886,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject,
 static DRIVER_DISPATCH ScrDispatch;
 static NTSTATUS NTAPI
 ScrDispatch(PDEVICE_OBJECT DeviceObject,
-           PIRP Irp)
+        PIRP Irp)
 {
     PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
     NTSTATUS Status;
@@ -759,7 +906,7 @@ ScrDispatch(PDEVICE_OBJECT DeviceObject,
     Irp->IoStatus.Status = Status;
     IoCompleteRequest (Irp, IO_NO_INCREMENT);
 
-    return (Status);
+    return Status;
 }