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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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); } }