Author: janderwald
Date: Mon Sep  3 05:58:43 2007
New Revision: 28794
URL: 
http://svn.reactos.org/svn/reactos?rev=28794&view=rev
Log:
- add hActiveBuffer member to struct to ensure that modifying the screenbuffer is secured
- fix a bugs in the screen buffer resize code
- resizing now "works" (unfortunately a few drawing bugs show up)
Modified:
    trunk/reactos/subsystems/win32/csrss/include/conio.h
    trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
    trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
    trunk/reactos/subsystems/win32/csrss/win32csr/w32csr.h
Modified: trunk/reactos/subsystems/win32/csrss/include/conio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/include/conio.h (original)
+++ trunk/reactos/subsystems/win32/csrss/include/conio.h Mon Sep  3 05:58:43 2007
@@ -70,6 +70,7 @@
   WORD WaitingChars;
   WORD WaitingLines;                    /* number of chars and lines in input queue */
   PCSRSS_SCREEN_BUFFER ActiveBuffer;    /* Pointer to currently active screen buffer */
+  HANDLE hActiveBuffer;
   WORD Mode;                            /* Console mode flags */
   WORD EchoCount;                       /* count of chars to echo, in line buffered mode
*/
   UNICODE_STRING Title;                 /* Title of console */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c Mon Sep  3 05:58:43 2007
@@ -153,6 +153,7 @@
   Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT |
ENABLE_MOUSE_INPUT;
   Console->EarlyReturn = FALSE;
   Console->ActiveBuffer = NULL;
+  Console->hActiveBuffer = INVALID_HANDLE_VALUE;
   InitializeListHead(&Console->InputEvents);
   Console->CodePage = GetOEMCP();
   Console->OutputCodePage = GetOEMCP();
@@ -174,20 +175,22 @@
   /* allocate console screen buffer */
   NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
+  if (NULL == NewBuffer)
+    {
+      RtlFreeUnicodeString(&Console->Title);
+      DeleteCriticalSection(&Console->Header.Lock);
+      CloseHandle(Console->ActiveEvent);
+      return STATUS_INSUFFICIENT_RESOURCES;
+    }
   /* init screen buffer with defaults */
   NewBuffer->CursorInfo.bVisible = TRUE;
   NewBuffer->CursorInfo.dwSize = 5;
   /* make console active, and insert into console list */
   Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
+  Console->hActiveBuffer = INVALID_HANDLE_VALUE;
   /* add a reference count because the buffer is tied to the console */
   InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
-  if (NULL == NewBuffer)
-    {
-      RtlFreeUnicodeString(&Console->Title);
-      DeleteCriticalSection(&Console->Header.Lock);
-      CloseHandle(Console->ActiveEvent);
-      return STATUS_INSUFFICIENT_RESOURCES;
-    }
+
   if (! GuiMode)
     {
@@ -332,6 +335,7 @@
             ProcessData->Console = 0;
             return Request->Status = Status;
         }
+        Console->hActiveBuffer = Request->Data.AllocConsoleRequest.OutputHandle;
     }
     /* Duplicate the Event */
@@ -1065,6 +1069,7 @@
 #endif
   Console->ActiveBuffer = NULL;
+  Console->hActiveBuffer = INVALID_HANDLE_VALUE;
   ConioCleanupConsole(Console);
   CloseHandle(Console->ActiveEvent);
@@ -2272,6 +2277,7 @@
     }
   /* tie console to new buffer */
   Console->ActiveBuffer = Buff;
+  Console->hActiveBuffer = Request->Data.SetScreenBufferRequest.OutputHandle;
   /* inc ref count on new buffer */
   InterlockedIncrement(&Buff->Header.ReferenceCount);
   /* Redraw the console */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c Mon Sep  3 05:58:43 2007
@@ -1614,7 +1614,15 @@
 {
   DWORD windx, windy;
   RECT rect;
-
+  PCSRSS_SCREEN_BUFFER ActiveBuffer;
+  PCSRSS_PROCESS_DATA ProcessData = NULL;
+
+  if (Console->ProcessList.Flink != &Console->ProcessList)
+    {
+      ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA,
ProcessEntry);
+      ConioLockScreenBuffer(ProcessData, Console->hActiveBuffer, (Object_t
**)&ActiveBuffer);
+    }
+
   /* apply text / background color */
   GuiData->ScreenText = pConInfo->ScreenText;
   GuiData->ScreenBackground = pConInfo->ScreenBackground;
@@ -1625,38 +1633,51 @@
   windx = LOWORD(pConInfo->ScreenBuffer);
   windy = HIWORD(pConInfo->ScreenBuffer);
-  if (windx != Console->ActiveBuffer->MaxX || windy !=
Console->ActiveBuffer->MaxY)
+  if (windx != ActiveBuffer->MaxX || windy != ActiveBuffer->MaxY)
   {
      BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2);
+
      if (Buffer)
      {
         DWORD Offset = 0;
         DWORD BufferOffset = 0;
         USHORT CurrentY;
         BYTE * OldBuffer;
+        USHORT value;
         DWORD diff;
-        DWORD value = ((((DWORD)Console->ActiveBuffer->DefaultAttrib) << 16)
| 0x20);
-
-        OldBuffer = Console->ActiveBuffer->Buffer;
-
-        for (CurrentY = 0; CurrentY < min(Console->ActiveBuffer->MaxY, windy);
CurrentY++)
-        {
-            if (windx < Console->ActiveBuffer->MaxX)
+        DWORD i;
+
+        value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib);
+
+        DPRINT("MaxX %d MaxY %d windx %d windy %d value %04x DefaultAttrib
%d\n",ActiveBuffer->MaxX, ActiveBuffer->MaxY, windx, windy, value,
ActiveBuffer->DefaultAttrib);
+        OldBuffer = ActiveBuffer->Buffer;
+
+        for (CurrentY = 0; CurrentY < min(ActiveBuffer->MaxY, windy); CurrentY++)
+        {
+            if (windx <= ActiveBuffer->MaxX)
             {
                 /* reduce size */
                 RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset], windx *
2);
                 Offset += (windx * 2);
-                BufferOffset += (Console->ActiveBuffer->MaxX * 2);
+                BufferOffset += (ActiveBuffer->MaxX * 2);
             }
             else
             {
                 /* enlarge size */
-                diff = windx - Console->ActiveBuffer->MaxX;
-
-                RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset],
Console->ActiveBuffer->MaxX * 2);
-                Offset += (Console->ActiveBuffer->MaxX * 2);
+                RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset],
ActiveBuffer->MaxX * 2);
+                Offset += (ActiveBuffer->MaxX * 2);
+
+                diff = windx - ActiveBuffer->MaxX;
                 /* zero new part of it */
-                memset(&Buffer[Offset], value, (diff * 2));
+#if HAVE_WMEMSET
+                wmemset((WCHAR*)&Buffer[Offset], value, diff);
+#else
+                for (i = 0; i < diff * 2; i++)
+                {
+                    Buffer[Offset * 2] = ' ';
+                    Buffer[Offset * 2 + 1] = ActiveBuffer->DefaultAttrib;
+                }
+#endif
                 Offset += (diff * 2);
                 BufferOffset += (Console->ActiveBuffer->MaxX * 2);
             }
@@ -1665,17 +1686,54 @@
         if (windy > Console->ActiveBuffer->MaxY)
         {
             diff = windy - Console->ActiveBuffer->MaxX;
-            memset(&Buffer[Offset], value, diff * 2 * windx);
-        }
-        (void)InterlockedExchangePointer((PVOID volatile
*)Console->ActiveBuffer->Buffer, Buffer);
+#if HAVE_WMEMSET
+                wmemset((WCHAR*)&Buffer[Offset], value, diff * windx);
+#else
+                for (i = 0; i < diff * 2; i++)
+                {
+                    Buffer[Offset * 2] = ' ';
+                    Buffer[Offset * 2 + 1] = ActiveBuffer->DefaultAttrib;
+                }
+#endif
+        }
+
+        (void)InterlockedExchangePointer((PVOID volatile
*)&Console->ActiveBuffer->Buffer, Buffer);
         HeapFree(Win32CsrApiHeap, 0, OldBuffer);
         Console->ActiveBuffer->MaxX = windx;
         Console->ActiveBuffer->MaxY = windy;
+        InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
+     }
+     else
+     {
+        if (ProcessData)
+        {
+            ConioUnlockScreenBuffer(ActiveBuffer);
+        }
+        return;
      }
   }
   windx = LOWORD(pConInfo->WindowSize);
   windy = HIWORD(pConInfo->WindowSize);
+
+  if (windx > Console->Size.X)
+  {
+      PWCHAR LineBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, windx *
sizeof(WCHAR));
+      if (LineBuffer)
+      {
+          HeapFree(Win32CsrApiHeap, 0, GuiData->LineBuffer);
+          GuiData->LineBuffer = LineBuffer;
+      }
+      else
+      {
+          if (ProcessData)
+          {
+              ConioUnlockScreenBuffer(ActiveBuffer);
+          }
+          return;
+      }
+  }
+
   if (windx != Console->Size.X || windy != Console->Size.Y)
   {
@@ -1701,7 +1759,10 @@
           //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE);
       }
   }
-  /* repaint window */
+  if (ProcessData)
+  {
+      ConioUnlockScreenBuffer(ActiveBuffer);
+  }
   InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
 }
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/w32csr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/w32csr.h (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/w32csr.h Mon Sep  3 05:58:43 2007
@@ -23,6 +23,7 @@
 #include <win32csr.h>
 #include <tchar.h>
+#include <wchar.h>
 #include <cpl.h>
 #include "resource.h"