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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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);
}
}