From 9b81b3ab92c18a413e7c16ae237fff1e2d609f95 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 3 Sep 2007 01:58:43 +0000 Subject: [PATCH] - 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) svn path=/trunk/; revision=28794 --- .../subsystems/win32/csrss/include/conio.h | 1 + .../subsystems/win32/csrss/win32csr/conio.c | 20 ++-- .../win32/csrss/win32csr/guiconsole.c | 91 ++++++++++++++++--- .../subsystems/win32/csrss/win32csr/w32csr.h | 1 + 4 files changed, 91 insertions(+), 22 deletions(-) diff --git a/reactos/subsystems/win32/csrss/include/conio.h b/reactos/subsystems/win32/csrss/include/conio.h index f6c1b82990c..c4590307ead 100644 --- a/reactos/subsystems/win32/csrss/include/conio.h +++ b/reactos/subsystems/win32/csrss/include/conio.h @@ -70,6 +70,7 @@ typedef struct tagCSRSS_CONSOLE 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 */ diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 5019b9c22fb..7650fd1b6cf 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -153,6 +153,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console) 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,13 +175,6 @@ CsrInitConsole(PCSRSS_CONSOLE Console) /* allocate console screen buffer */ NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - /* 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; - /* add a reference count because the buffer is tied to the console */ - InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount); if (NULL == NewBuffer) { RtlFreeUnicodeString(&Console->Title); @@ -188,6 +182,15 @@ CsrInitConsole(PCSRSS_CONSOLE Console) 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 (! GuiMode) { @@ -332,6 +335,7 @@ CSR_API(CsrAllocConsole) ProcessData->Console = 0; return Request->Status = Status; } + Console->hActiveBuffer = Request->Data.AllocConsoleRequest.OutputHandle; } /* Duplicate the Event */ @@ -1065,6 +1069,7 @@ ConioDeleteConsole(Object_t *Object) #endif Console->ActiveBuffer = NULL; + Console->hActiveBuffer = INVALID_HANDLE_VALUE; ConioCleanupConsole(Console); CloseHandle(Console->ActiveEvent); @@ -2272,6 +2277,7 @@ CSR_API(CsrSetScreenBuffer) } /* 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 */ diff --git a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c index 7d004d795a0..ec59c884f8b 100644 --- a/reactos/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/reactos/subsystems/win32/csrss/win32csr/guiconsole.c @@ -1614,7 +1614,15 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole { 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 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole 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); + DWORD i; + + value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib); - OldBuffer = Console->ActiveBuffer->Buffer; + 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(Console->ActiveBuffer->MaxY, windy); CurrentY++) + for (CurrentY = 0; CurrentY < min(ActiveBuffer->MaxY, windy); CurrentY++) { - if (windx < Console->ActiveBuffer->MaxX) + 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,18 +1686,55 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole if (windy > Console->ActiveBuffer->MaxY) { diff = windy - Console->ActiveBuffer->MaxX; - memset(&Buffer[Offset], value, diff * 2 * windx); +#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); + + (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) { /* resize window */ @@ -1701,7 +1759,10 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE); } } - /* repaint window */ + if (ProcessData) + { + ConioUnlockScreenBuffer(ActiveBuffer); + } InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); } diff --git a/reactos/subsystems/win32/csrss/win32csr/w32csr.h b/reactos/subsystems/win32/csrss/win32csr/w32csr.h index 150f866ad32..f7b9aaada52 100644 --- a/reactos/subsystems/win32/csrss/win32csr/w32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/w32csr.h @@ -23,6 +23,7 @@ #include #include +#include #include #include "resource.h"