mirror of
https://github.com/reactos/reactos.git
synced 2025-06-24 14:19:43 +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 WaitingChars;
|
||||||
WORD WaitingLines; /* number of chars and lines in input queue */
|
WORD WaitingLines; /* number of chars and lines in input queue */
|
||||||
PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
|
PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
|
||||||
|
HANDLE hActiveBuffer;
|
||||||
WORD Mode; /* Console mode flags */
|
WORD Mode; /* Console mode flags */
|
||||||
WORD EchoCount; /* count of chars to echo, in line buffered mode */
|
WORD EchoCount; /* count of chars to echo, in line buffered mode */
|
||||||
UNICODE_STRING Title; /* Title of console */
|
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->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
|
||||||
Console->EarlyReturn = FALSE;
|
Console->EarlyReturn = FALSE;
|
||||||
Console->ActiveBuffer = NULL;
|
Console->ActiveBuffer = NULL;
|
||||||
|
Console->hActiveBuffer = INVALID_HANDLE_VALUE;
|
||||||
InitializeListHead(&Console->InputEvents);
|
InitializeListHead(&Console->InputEvents);
|
||||||
Console->CodePage = GetOEMCP();
|
Console->CodePage = GetOEMCP();
|
||||||
Console->OutputCodePage = GetOEMCP();
|
Console->OutputCodePage = GetOEMCP();
|
||||||
|
@ -174,13 +175,6 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
||||||
|
|
||||||
/* allocate console screen buffer */
|
/* allocate console screen buffer */
|
||||||
NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_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)
|
if (NULL == NewBuffer)
|
||||||
{
|
{
|
||||||
RtlFreeUnicodeString(&Console->Title);
|
RtlFreeUnicodeString(&Console->Title);
|
||||||
|
@ -188,6 +182,15 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
||||||
CloseHandle(Console->ActiveEvent);
|
CloseHandle(Console->ActiveEvent);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
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)
|
if (! GuiMode)
|
||||||
{
|
{
|
||||||
|
@ -332,6 +335,7 @@ CSR_API(CsrAllocConsole)
|
||||||
ProcessData->Console = 0;
|
ProcessData->Console = 0;
|
||||||
return Request->Status = Status;
|
return Request->Status = Status;
|
||||||
}
|
}
|
||||||
|
Console->hActiveBuffer = Request->Data.AllocConsoleRequest.OutputHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the Event */
|
/* Duplicate the Event */
|
||||||
|
@ -1065,6 +1069,7 @@ ConioDeleteConsole(Object_t *Object)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Console->ActiveBuffer = NULL;
|
Console->ActiveBuffer = NULL;
|
||||||
|
Console->hActiveBuffer = INVALID_HANDLE_VALUE;
|
||||||
ConioCleanupConsole(Console);
|
ConioCleanupConsole(Console);
|
||||||
|
|
||||||
CloseHandle(Console->ActiveEvent);
|
CloseHandle(Console->ActiveEvent);
|
||||||
|
@ -2272,6 +2277,7 @@ CSR_API(CsrSetScreenBuffer)
|
||||||
}
|
}
|
||||||
/* tie console to new buffer */
|
/* tie console to new buffer */
|
||||||
Console->ActiveBuffer = Buff;
|
Console->ActiveBuffer = Buff;
|
||||||
|
Console->hActiveBuffer = Request->Data.SetScreenBufferRequest.OutputHandle;
|
||||||
/* inc ref count on new buffer */
|
/* inc ref count on new buffer */
|
||||||
InterlockedIncrement(&Buff->Header.ReferenceCount);
|
InterlockedIncrement(&Buff->Header.ReferenceCount);
|
||||||
/* Redraw the console */
|
/* Redraw the console */
|
||||||
|
|
|
@ -1614,6 +1614,14 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole
|
||||||
{
|
{
|
||||||
DWORD windx, windy;
|
DWORD windx, windy;
|
||||||
RECT rect;
|
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 */
|
/* apply text / background color */
|
||||||
GuiData->ScreenText = pConInfo->ScreenText;
|
GuiData->ScreenText = pConInfo->ScreenText;
|
||||||
|
@ -1625,38 +1633,51 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole
|
||||||
windx = LOWORD(pConInfo->ScreenBuffer);
|
windx = LOWORD(pConInfo->ScreenBuffer);
|
||||||
windy = HIWORD(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);
|
BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2);
|
||||||
|
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
DWORD Offset = 0;
|
DWORD Offset = 0;
|
||||||
DWORD BufferOffset = 0;
|
DWORD BufferOffset = 0;
|
||||||
USHORT CurrentY;
|
USHORT CurrentY;
|
||||||
BYTE * OldBuffer;
|
BYTE * OldBuffer;
|
||||||
|
USHORT value;
|
||||||
DWORD diff;
|
DWORD diff;
|
||||||
DWORD value = ((((DWORD)Console->ActiveBuffer->DefaultAttrib) << 16) | 0x20);
|
DWORD i;
|
||||||
|
|
||||||
OldBuffer = Console->ActiveBuffer->Buffer;
|
value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib);
|
||||||
|
|
||||||
for (CurrentY = 0; CurrentY < min(Console->ActiveBuffer->MaxY, windy); CurrentY++)
|
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(ActiveBuffer->MaxY, windy); CurrentY++)
|
||||||
{
|
{
|
||||||
if (windx < Console->ActiveBuffer->MaxX)
|
if (windx <= ActiveBuffer->MaxX)
|
||||||
{
|
{
|
||||||
/* reduce size */
|
/* reduce size */
|
||||||
RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset], windx * 2);
|
RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset], windx * 2);
|
||||||
Offset += (windx * 2);
|
Offset += (windx * 2);
|
||||||
BufferOffset += (Console->ActiveBuffer->MaxX * 2);
|
BufferOffset += (ActiveBuffer->MaxX * 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* enlarge size */
|
/* enlarge size */
|
||||||
diff = windx - Console->ActiveBuffer->MaxX;
|
RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset], ActiveBuffer->MaxX * 2);
|
||||||
|
Offset += (ActiveBuffer->MaxX * 2);
|
||||||
|
|
||||||
RtlCopyMemory(&Buffer[Offset], &OldBuffer[BufferOffset], Console->ActiveBuffer->MaxX * 2);
|
diff = windx - ActiveBuffer->MaxX;
|
||||||
Offset += (Console->ActiveBuffer->MaxX * 2);
|
|
||||||
/* zero new part of it */
|
/* 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);
|
Offset += (diff * 2);
|
||||||
BufferOffset += (Console->ActiveBuffer->MaxX * 2);
|
BufferOffset += (Console->ActiveBuffer->MaxX * 2);
|
||||||
}
|
}
|
||||||
|
@ -1665,18 +1686,55 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole
|
||||||
if (windy > Console->ActiveBuffer->MaxY)
|
if (windy > Console->ActiveBuffer->MaxY)
|
||||||
{
|
{
|
||||||
diff = windy - Console->ActiveBuffer->MaxX;
|
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;
|
||||||
}
|
}
|
||||||
(void)InterlockedExchangePointer((PVOID volatile *)Console->ActiveBuffer->Buffer, Buffer);
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)InterlockedExchangePointer((PVOID volatile *)&Console->ActiveBuffer->Buffer, Buffer);
|
||||||
HeapFree(Win32CsrApiHeap, 0, OldBuffer);
|
HeapFree(Win32CsrApiHeap, 0, OldBuffer);
|
||||||
Console->ActiveBuffer->MaxX = windx;
|
Console->ActiveBuffer->MaxX = windx;
|
||||||
Console->ActiveBuffer->MaxY = windy;
|
Console->ActiveBuffer->MaxY = windy;
|
||||||
|
InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ProcessData)
|
||||||
|
{
|
||||||
|
ConioUnlockScreenBuffer(ActiveBuffer);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
windx = LOWORD(pConInfo->WindowSize);
|
windx = LOWORD(pConInfo->WindowSize);
|
||||||
windy = HIWORD(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)
|
if (windx != Console->Size.X || windy != Console->Size.Y)
|
||||||
{
|
{
|
||||||
/* resize window */
|
/* resize window */
|
||||||
|
@ -1701,7 +1759,10 @@ GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsole
|
||||||
//ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE);
|
//ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* repaint window */
|
if (ProcessData)
|
||||||
|
{
|
||||||
|
ConioUnlockScreenBuffer(ActiveBuffer);
|
||||||
|
}
|
||||||
InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
|
InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <win32csr.h>
|
#include <win32csr.h>
|
||||||
|
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
#include <wchar.h>
|
||||||
#include <cpl.h>
|
#include <cpl.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue