mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 15:10:53 +00:00
- 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
This commit is contained in:
parent
81f092736f
commit
9b81b3ab92
4 changed files with 91 additions and 22 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <win32csr.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <wchar.h>
|
||||
#include <cpl.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
|
Loading…
Reference in a new issue