[ros-diffs] [jmorlan] 47318: [WIN32CSR] Delete even the active screen buffer when all handles are closed. Fixes a winetest.

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Sun May 23 08:04:15 CEST 2010


Author: jmorlan
Date: Sun May 23 08:04:15 2010
New Revision: 47318

URL: http://svn.reactos.org/svn/reactos?rev=47318&view=rev
Log:
[WIN32CSR] Delete even the active screen buffer when all handles are closed. Fixes a winetest.

Modified:
    trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
    trunk/reactos/subsystems/win32/csrss/win32csr/conio.h
    trunk/reactos/subsystems/win32/csrss/win32csr/handle.c

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=47318&r1=47317&r2=47318&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] Sun May 23 08:04:15 2010
@@ -137,6 +137,7 @@
   Buffer->CurrentX = 0;
   Buffer->CurrentY = 0;
 
+  InsertHeadList(&Console->BufferList, &Buffer->ListEntry);
   return STATUS_SUCCESS;
 }
 
@@ -162,6 +163,7 @@
   Console->Header.Console = Console;
   Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
   Console->EarlyReturn = FALSE;
+  InitializeListHead(&Console->BufferList);
   Console->ActiveBuffer = NULL;
   InitializeListHead(&Console->InputEvents);
   Console->CodePage = GetOEMCP();
@@ -893,11 +895,24 @@
 }
 
 VOID WINAPI
-ConioDeleteScreenBuffer(Object_t *Object)
-{
-  PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
-  HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
-  HeapFree(Win32CsrApiHeap, 0, Buffer);
+ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
+{
+    PCSRSS_CONSOLE Console = Buffer->Header.Console;
+
+    RemoveEntryList(&Buffer->ListEntry);
+    if (Buffer == Console->ActiveBuffer)
+    {
+        /* Deleted active buffer; switch to most recently created */
+        Console->ActiveBuffer = NULL;
+        if (!IsListEmpty(&Console->BufferList))
+        {
+            Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry);
+            ConioDrawConsole(Console);
+        }
+    }
+
+    HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
+    HeapFree(Win32CsrApiHeap, 0, Buffer);
 }
 
 VOID FASTCALL
@@ -929,9 +944,11 @@
     }
 
   ConioCleanupConsole(Console);
-  ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
-
-  Console->ActiveBuffer = NULL;
+  ConioDeleteScreenBuffer(Console->ActiveBuffer);
+  if (!IsListEmpty(&Console->BufferList))
+    {
+      DPRINT1("BUG: screen buffer list not empty\n");
+    }
 
   CloseHandle(Console->ActiveEvent);
   DeleteCriticalSection(&Console->Lock);
@@ -1998,7 +2015,7 @@
   /* If old buffer has no handles, it's now unreferenced */
   if (Console->ActiveBuffer->Header.HandleCount == 0)
     {
-      ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+      ConioDeleteScreenBuffer(Console->ActiveBuffer);
     }
   /* tie console to new buffer */
   Console->ActiveBuffer = Buff;

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/conio.h?rev=47318&r1=47317&r2=47318&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] Sun May 23 08:04:15 2010
@@ -46,6 +46,7 @@
   USHORT VirtualY;                 /* top row of buffer being displayed, reported to callers */
   CONSOLE_CURSOR_INFO CursorInfo;
   USHORT Mode;
+  LIST_ENTRY ListEntry;            /* entry in console's list of buffers */
 } CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
 
 typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
@@ -76,6 +77,7 @@
   LIST_ENTRY InputEvents;               /* List head for input event queue */
   WORD WaitingChars;
   WORD WaitingLines;                    /* number of chars and lines in input queue */
+  LIST_ENTRY BufferList;                /* List of all screen buffers for this console */
   PCSRSS_SCREEN_BUFFER ActiveBuffer;    /* Pointer to currently active screen buffer */
   WORD Mode;                            /* Console mode flags */
   WORD EchoCount;                       /* count of chars to echo, in line buffered mode */
@@ -103,7 +105,7 @@
 
 NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console);
 VOID WINAPI ConioDeleteConsole(Object_t *Object);
-VOID WINAPI ConioDeleteScreenBuffer(Object_t *Buffer);
+VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer);
 VOID WINAPI CsrInitConsoleSupport(VOID);
 void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode);
 PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y);

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/handle.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/handle.c?rev=47318&r1=47317&r2=47318&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] Sun May 23 08:04:15 2010
@@ -49,11 +49,13 @@
             && Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
         {
             PCSRSS_CONSOLE Console = Object->Console;
+            PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object;
             EnterCriticalSection(&Console->Lock);
-            /* TODO: Should delete even the active buffer, but we're not yet ready
-             * to deal with the case where this results in no buffers left. */
-            if (Object != &Console->ActiveBuffer->Header)
-                ConioDeleteScreenBuffer(Object);
+            /* ...unless it's the only buffer left. Windows allows deletion
+             * even of the last buffer, but having to deal with a lack of
+             * any active buffer might be error-prone. */
+            if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
+                ConioDeleteScreenBuffer(Buffer);
             LeaveCriticalSection(&Console->Lock);
         }
     }




More information about the Ros-diffs mailing list