[ros-diffs] [jmorlan] 47165: [KERNEL32] [WIN32CSR] Implement SetConsoleScreenBufferSize. FAR Manager now works again.

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Wed May 12 05:34:02 CEST 2010


Author: jmorlan
Date: Wed May 12 05:34:02 2010
New Revision: 47165

URL: http://svn.reactos.org/svn/reactos?rev=47165&view=rev
Log:
[KERNEL32] [WIN32CSR] Implement SetConsoleScreenBufferSize. FAR Manager now works again.

Modified:
    trunk/reactos/dll/win32/kernel32/misc/console.c
    trunk/reactos/include/reactos/subsys/csrss/csrss.h
    trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
    trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c
    trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
    trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c

Modified: trunk/reactos/dll/win32/kernel32/misc/console.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/console.c?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Wed May 12 05:34:02 2010
@@ -3086,16 +3086,29 @@
 /*--------------------------------------------------------------
  *     SetConsoleScreenBufferSize
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
                            COORD dwSize)
 {
-    DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    CSR_API_MESSAGE Request;
+    ULONG CsrRequest;
+    NTSTATUS Status;
+
+    CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE);
+    Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
+    Request.Data.SetScreenBufferSize.Size = dwSize;
+
+    Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 /*--------------------------------------------------------------

Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csrss/csrss.h?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Wed May 12 05:34:02 2010
@@ -472,6 +472,11 @@
   DWORD ProcessGroup;
 } CSRSS_GENERATE_CTRL_EVENT, *PCSRSS_GENERATE_CTRL_EVENT;
 
+typedef struct
+{
+  HANDLE OutputHandle;
+  COORD Size;
+} CSRSS_SET_SCREEN_BUFFER_SIZE, *PCSRSS_SET_SCREEN_BUFFER_SIZE;
 
 
 #define CSR_API_MESSAGE_HEADER_SIZE(Type)       (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type))
@@ -551,6 +556,7 @@
 #define GET_CONSOLE_ALIASES_EXES_LENGTH (0x3D)
 #define GENERATE_CTRL_EVENT           (0x3E)
 #define CREATE_THREAD                 (0x3F)
+#define SET_SCREEN_BUFFER_SIZE        (0x40)
 
 /* Keep in sync with definition below. */
 #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
@@ -624,6 +630,7 @@
         CSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes;
         CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength;
         CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent;
+        CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize;
     } Data;
 } CSR_API_MESSAGE, *PCSR_API_MESSAGE;
 

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/conio.c?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] Wed May 12 05:34:02 2010
@@ -3118,4 +3118,33 @@
   return Status;
 }
 
+CSR_API(CsrSetScreenBufferSize)
+{
+    NTSTATUS Status;
+    PCSRSS_CONSOLE Console;
+    PCSRSS_SCREEN_BUFFER Buff;
+
+    Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+    Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+    Status = ConioConsoleFromProcessData(ProcessData, &Console);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        ConioUnlockConsole(Console);
+        return Status;
+    }
+
+    Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size);
+    ConioUnlockScreenBuffer(Buff);
+    ConioUnlockConsole(Console);
+
+    return Status;
+}
+
 /* EOF */

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Wed May 12 05:34:02 2010
@@ -74,6 +74,7 @@
     CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES,        CsrGetConsoleAliasesExes),
     CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
     CSRSS_DEFINE_API(GENERATE_CTRL_EVENT,          CsrGenerateCtrlEvent),
+    CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE,       CsrSetScreenBufferSize),
     { 0, 0, NULL }
   };
 

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] Wed May 12 05:34:02 2010
@@ -1708,11 +1708,105 @@
 
 }
 
+static NTSTATUS WINAPI
+GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
+{
+    BYTE * Buffer;
+    DWORD Offset = 0;
+    BYTE * OldPtr;
+    USHORT CurrentY;
+    BYTE * OldBuffer;
+#if HAVE_WMEMSET
+    USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib);
+#endif
+    DWORD diff;
+    DWORD i;
+
+    /* Buffer size is not allowed to be smaller than window size */
+    if (Size.X < Console->Size.X || Size.Y < Console->Size.Y)
+        return STATUS_INVALID_PARAMETER;
+
+    if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY)
+        return STATUS_SUCCESS;
+
+    Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2);
+    if (!Buffer)
+        return STATUS_NO_MEMORY;
+
+    DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y);
+    OldBuffer = ScreenBuffer->Buffer;
+
+    for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++)
+    {
+        OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
+        if (Size.X <= ScreenBuffer->MaxX)
+        {
+            /* reduce size */
+            RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
+            Offset += (Size.X * 2);
+        }
+        else
+        {
+            /* enlarge size */
+            RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2);
+            Offset += (ScreenBuffer->MaxX * 2);
+
+            diff = Size.X - ScreenBuffer->MaxX;
+            /* zero new part of it */
+#if HAVE_WMEMSET
+            wmemset((WCHAR*)&Buffer[Offset], value, diff);
+#else
+            for (i = 0; i < diff; i++)
+            {
+                Buffer[Offset++] = ' ';
+                Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
+            }
+#endif
+        }
+    }
+
+    if (Size.Y > ScreenBuffer->MaxY)
+    {
+        diff = Size.X * (Size.Y - ScreenBuffer->MaxY);
+#if HAVE_WMEMSET
+        wmemset((WCHAR*)&Buffer[Offset], value, diff);
+#else
+        for (i = 0; i < diff; i++)
+        {
+            Buffer[Offset++] = ' ';
+            Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
+        }
+#endif
+    }
+
+    (void)InterlockedExchangePointer((PVOID volatile  *)&ScreenBuffer->Buffer, Buffer);
+    HeapFree(Win32CsrApiHeap, 0, OldBuffer);
+    ScreenBuffer->MaxX = Size.X;
+    ScreenBuffer->MaxY = Size.Y;
+    ScreenBuffer->VirtualY = 0;
+
+    /* Ensure cursor and window are within buffer */
+    if (ScreenBuffer->CurrentX >= Size.X)
+        ScreenBuffer->CurrentX = Size.X - 1;
+    if (ScreenBuffer->CurrentY >= Size.Y)
+        ScreenBuffer->CurrentY = Size.Y - 1;
+    if (ScreenBuffer->ShowX > Size.X - Console->Size.X)
+        ScreenBuffer->ShowX = Size.X - Console->Size.X;
+    if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y)
+        ScreenBuffer->ShowY = Size.Y - Console->Size.Y;
+
+    /* TODO: Should update scrollbar, but can't use anything that
+     * calls SendMessage or it could cause deadlock */
+
+    return STATUS_SUCCESS;
+}
+
 static VOID FASTCALL
 GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
 {
   DWORD windx, windy;
   PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
+  COORD BufSize;
   BOOL SizeChanged = FALSE;
 
   EnterCriticalSection(&ActiveBuffer->Header.Lock);
@@ -1723,85 +1817,6 @@
 
   /* apply cursor size */
   ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100);
-
-  windx = LOWORD(pConInfo->ScreenBuffer);
-  windy = HIWORD(pConInfo->ScreenBuffer);
-
-  if (windx != ActiveBuffer->MaxX || windy != ActiveBuffer->MaxY)
-  {
-     BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2);
-
-     if (Buffer)
-     {
-        DWORD Offset = 0;
-        BYTE * OldPtr;
-        USHORT CurrentY;
-        BYTE * OldBuffer;
-        USHORT value;
-        DWORD diff;
-        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++)
-        {
-            OldPtr = ConioCoordToPointer(ActiveBuffer, 0, CurrentY);
-            if (windx <= ActiveBuffer->MaxX)
-            {
-                /* reduce size */
-                RtlCopyMemory(&Buffer[Offset], OldPtr, windx * 2);
-                Offset += (windx * 2);
-            }
-            else
-            {
-                /* enlarge size */
-                RtlCopyMemory(&Buffer[Offset], OldPtr, ActiveBuffer->MaxX * 2);
-                Offset += (ActiveBuffer->MaxX * 2);
-
-                diff = windx - ActiveBuffer->MaxX;
-                /* zero new part of it */
-#if HAVE_WMEMSET
-                wmemset((WCHAR*)&Buffer[Offset], value, diff);
-#else
-                for (i = 0; i < diff; i++)
-                {
-                    Buffer[Offset++] = ' ';
-                    Buffer[Offset++] = ActiveBuffer->DefaultAttrib;
-                }
-#endif
-            }
-        }
-
-        if (windy > ActiveBuffer->MaxY)
-        {
-            diff = windy - ActiveBuffer->MaxY;
-#if HAVE_WMEMSET
-                wmemset((WCHAR*)&Buffer[Offset], value, diff * windx);
-#else
-                for (i = 0; i < diff * windx; i++)
-                {
-                    Buffer[Offset++] = ' ';
-                    Buffer[Offset++] = ActiveBuffer->DefaultAttrib;
-                }
-#endif
-        }
-
-        (void)InterlockedExchangePointer((PVOID volatile  *)&ActiveBuffer->Buffer, Buffer);
-        HeapFree(Win32CsrApiHeap, 0, OldBuffer);
-        ActiveBuffer->MaxX = windx;
-        ActiveBuffer->MaxY = windy;
-        ActiveBuffer->VirtualY = 0;
-        SizeChanged = TRUE;
-     }
-     else
-     {
-        LeaveCriticalSection(&ActiveBuffer->Header.Lock);
-        return;
-     }
-  }
 
   windx = LOWORD(pConInfo->WindowSize);
   windy = HIWORD(pConInfo->WindowSize);
@@ -1812,6 +1827,14 @@
       Console->Size.X = windx;
       Console->Size.Y = windy;
       SizeChanged = TRUE;
+  }
+
+  BufSize.X = LOWORD(pConInfo->ScreenBuffer);
+  BufSize.Y = HIWORD(pConInfo->ScreenBuffer);
+  if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY)
+  {
+      if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize)))
+          SizeChanged = TRUE;
   }
 
   if (SizeChanged)
@@ -2222,7 +2245,8 @@
   GuiUpdateScreenInfo,
   GuiChangeTitle,
   GuiCleanupConsole,
-  GuiChangeIcon
+  GuiChangeIcon,
+  GuiResizeBuffer,
 };
 
 NTSTATUS FASTCALL

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c?rev=47165&r1=47164&r2=47165&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/tuiconsole.c [iso-8859-1] Wed May 12 05:34:02 2010
@@ -288,6 +288,19 @@
     {
       ConioDrawConsole(ActiveConsole);
     }
+}
+
+static BOOL WINAPI
+TuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
+{
+  return TRUE;
+}
+
+static NTSTATUS WINAPI
+TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
+{
+  UNIMPLEMENTED;
+  return STATUS_NOT_IMPLEMENTED;
 }
 
 DWORD WINAPI
@@ -340,7 +353,8 @@
   TuiUpdateScreenInfo,
   TuiChangeTitle,
   TuiCleanupConsole,
-  NULL  // ChangeIcon
+  TuiChangeIcon,
+  TuiResizeBuffer,
 };
 
 NTSTATUS FASTCALL




More information about the Ros-diffs mailing list