2010-05-31 06:28:55 +00:00
|
|
|
/*
|
2012-10-25 20:40:41 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Console Server DLL
|
|
|
|
* FILE: win32ss/user/consrv/conoutput.c
|
2013-05-29 00:29:07 +00:00
|
|
|
* PURPOSE: General Console Output Functions
|
2013-04-10 20:22:30 +00:00
|
|
|
* PROGRAMMERS: Jeffrey Morlan
|
|
|
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
2010-05-31 06:28:55 +00:00
|
|
|
*/
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
/* INCLUDES *******************************************************************/
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-10-23 22:31:36 +00:00
|
|
|
#include "consrv.h"
|
2013-04-07 23:18:59 +00:00
|
|
|
#include "console.h"
|
|
|
|
#include "include/conio.h"
|
2012-10-23 22:31:36 +00:00
|
|
|
#include "conio.h"
|
2013-04-07 23:18:59 +00:00
|
|
|
#include "conoutput.h"
|
|
|
|
#include "handle.h"
|
2012-10-23 22:31:36 +00:00
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
NTSTATUS
|
|
|
|
TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|
|
|
IN OUT PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_BUFFER_INFO TextModeInfo);
|
|
|
|
NTSTATUS
|
|
|
|
GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|
|
|
IN OUT PCONSOLE Console,
|
|
|
|
IN PGRAPHICS_BUFFER_INFO GraphicsInfo);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
|
|
|
|
VOID
|
|
|
|
GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|
|
|
IN OUT PCONSOLE Console,
|
|
|
|
IN SIZE_T Size)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
if (Buffer == NULL || Console == NULL)
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
*Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, max(sizeof(CONSOLE_SCREEN_BUFFER), Size));
|
|
|
|
if (*Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Initialize the header with the default type */
|
2013-05-12 00:20:15 +00:00
|
|
|
ConSrvInitObject(&(*Buffer)->Header, SCREEN_BUFFER, Console);
|
2013-05-29 00:29:07 +00:00
|
|
|
(*Buffer)->Vtbl = NULL;
|
2010-05-31 06:28:55 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
VOID
|
|
|
|
CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
if (Buffer->Header.Type == TEXTMODE_BUFFER)
|
|
|
|
TEXTMODE_BUFFER_Destroy(Buffer);
|
|
|
|
else if (Buffer->Header.Type == GRAPHICS_BUFFER)
|
|
|
|
GRAPHICS_BUFFER_Destroy(Buffer);
|
|
|
|
else if (Buffer->Header.Type == SCREEN_BUFFER)
|
|
|
|
ConsoleFreeHeap(Buffer);
|
|
|
|
// else
|
|
|
|
// do_nothing;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
2013-05-29 00:29:07 +00:00
|
|
|
ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|
|
|
IN OUT PCONSOLE Console,
|
|
|
|
IN ULONG BufferType,
|
|
|
|
IN PVOID ScreenBufferInfo)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if ( Console == NULL || Buffer == NULL ||
|
|
|
|
(BufferType != CONSOLE_TEXTMODE_BUFFER && BufferType != CONSOLE_GRAPHICS_BUFFER) )
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-04-11 23:37:09 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (BufferType == CONSOLE_TEXTMODE_BUFFER)
|
2013-04-11 23:37:09 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = TEXTMODE_BUFFER_Initialize(Buffer,
|
|
|
|
Console,
|
|
|
|
(PTEXTMODE_BUFFER_INFO)ScreenBufferInfo);
|
2013-04-11 23:37:09 +00:00
|
|
|
}
|
2013-05-29 00:29:07 +00:00
|
|
|
else if (BufferType == CONSOLE_GRAPHICS_BUFFER)
|
2013-04-11 23:37:09 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = GRAPHICS_BUFFER_Initialize(Buffer,
|
|
|
|
Console,
|
|
|
|
(PGRAPHICS_BUFFER_INFO)ScreenBufferInfo);
|
2013-04-11 23:37:09 +00:00
|
|
|
}
|
2013-05-29 00:29:07 +00:00
|
|
|
else
|
2013-04-11 23:37:09 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Never ever go there!! */
|
|
|
|
ASSERT(FALSE);
|
2013-04-11 23:37:09 +00:00
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Insert the newly created screen buffer into the list, if succeeded */
|
|
|
|
if (NT_SUCCESS(Status)) InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry);
|
2013-04-11 23:37:09 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
return Status;
|
2013-04-11 23:37:09 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
VOID WINAPI
|
2013-01-05 23:37:04 +00:00
|
|
|
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
2012-11-17 15:41:31 +00:00
|
|
|
{
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console = Buffer->Header.Console;
|
2013-05-29 00:29:07 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
2012-11-17 15:41:31 +00:00
|
|
|
|
|
|
|
RemoveEntryList(&Buffer->ListEntry);
|
|
|
|
if (Buffer == Console->ActiveBuffer)
|
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Delete active buffer; switch to most recently created */
|
2012-11-17 15:41:31 +00:00
|
|
|
Console->ActiveBuffer = NULL;
|
|
|
|
if (!IsListEmpty(&Console->BufferList))
|
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
NewBuffer = CONTAINING_RECORD(Console->BufferList.Flink,
|
|
|
|
CONSOLE_SCREEN_BUFFER,
|
|
|
|
ListEntry);
|
|
|
|
ConioSetActiveScreenBuffer(NewBuffer);
|
2012-11-17 15:41:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
CONSOLE_SCREEN_BUFFER_Destroy(Buffer);
|
2012-11-17 15:41:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID FASTCALL
|
2013-01-05 23:37:04 +00:00
|
|
|
ConioDrawConsole(PCONSOLE Console)
|
2012-11-17 15:41:31 +00:00
|
|
|
{
|
|
|
|
SMALL_RECT Region;
|
2013-05-29 00:29:07 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
|
2012-11-17 15:41:31 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (ActiveBuffer)
|
2012-11-17 15:41:31 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
ConioInitRect(&Region, 0, 0, ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1);
|
|
|
|
ConioDrawRegion(Console, &Region);
|
2012-11-17 15:41:31 +00:00
|
|
|
}
|
2012-12-08 16:13:16 +00:00
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
2012-12-08 16:13:16 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
PCONSOLE Console = Buffer->Header.Console;
|
|
|
|
Console->ActiveBuffer = Buffer;
|
|
|
|
ConioResizeTerminal(Console);
|
|
|
|
// ConioDrawConsole(Console);
|
2012-12-08 16:13:16 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER
|
|
|
|
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console)
|
|
|
|
{
|
|
|
|
return (Console ? Console->ActiveBuffer : NULL);
|
|
|
|
}
|
2012-11-17 15:41:31 +00:00
|
|
|
|
2013-03-19 22:05:38 +00:00
|
|
|
/* PUBLIC SERVER APIS *********************************************************/
|
2012-11-17 15:41:31 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
CSR_API(SrvInvalidateBitMapRect)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2013-05-29 00:29:07 +00:00
|
|
|
PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.InvalidateDIBitsRequest;
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
DPRINT("SrvInvalidateBitMapRect\n");
|
2012-11-18 13:54:32 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), InvalidateDIBitsRequest->OutputHandle, &Buff, GENERIC_READ, TRUE);
|
2012-11-18 13:54:32 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
Console = Buff->Header.Console;
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* If the output buffer is the current one, redraw the correct portion of the screen */
|
2010-05-31 06:28:55 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2013-05-29 00:29:07 +00:00
|
|
|
ConioDrawRegion(Console, &InvalidateDIBitsRequest->Region);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
CSR_API(SrvGetConsoleCursorInfo)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest;
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
DPRINT("SrvGetConsoleCursorInfo\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), CursorInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible;
|
2013-05-29 00:29:07 +00:00
|
|
|
CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-04-11 23:37:09 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
CSR_API(SrvSetConsoleCursorInfo)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2012-11-17 23:29:53 +00:00
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest;
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2010-05-31 06:28:55 +00:00
|
|
|
DWORD Size;
|
2013-05-29 00:29:07 +00:00
|
|
|
BOOL Visible, Success = TRUE;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
DPRINT("SrvSetConsoleCursorInfo\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), CursorInfoRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
Console = Buff->Header.Console;
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Size = CursorInfoRequest->Info.dwSize;
|
2012-11-17 23:29:53 +00:00
|
|
|
Visible = CursorInfoRequest->Info.bVisible;
|
2013-05-29 00:29:07 +00:00
|
|
|
if (Size < 1) Size = 1;
|
|
|
|
if (100 < Size) Size = 100;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if ( (Size != Buff->CursorInfo.dwSize) ||
|
|
|
|
(Visible && !Buff->CursorInfo.bVisible) ||
|
|
|
|
(!Visible && Buff->CursorInfo.bVisible) )
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
Buff->CursorInfo.dwSize = Size;
|
2010-05-31 06:28:55 +00:00
|
|
|
Buff->CursorInfo.bVisible = Visible;
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Success = ConioSetCursorInfo(Console, Buff);
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
2013-05-29 00:29:07 +00:00
|
|
|
return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
CSR_API(SrvSetConsoleCursorPosition)
|
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorPositionRequest;
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2013-04-14 16:04:46 +00:00
|
|
|
SHORT OldCursorX, OldCursorY;
|
|
|
|
SHORT NewCursorX, NewCursorY;
|
2012-11-17 15:41:31 +00:00
|
|
|
|
|
|
|
DPRINT("SrvSetConsoleCursorPosition\n");
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetCursorPositionRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
Console = Buff->Header.Console;
|
|
|
|
|
2012-11-17 23:29:53 +00:00
|
|
|
NewCursorX = SetCursorPositionRequest->Position.X;
|
|
|
|
NewCursorY = SetCursorPositionRequest->Position.Y;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
if ( NewCursorX < 0 || NewCursorX >= Buff->ScreenBufferSize.X ||
|
|
|
|
NewCursorY < 0 || NewCursorY >= Buff->ScreenBufferSize.Y )
|
2012-11-17 15:41:31 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quit;
|
2012-11-17 15:41:31 +00:00
|
|
|
}
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
OldCursorX = Buff->CursorPosition.X;
|
|
|
|
OldCursorY = Buff->CursorPosition.Y;
|
|
|
|
Buff->CursorPosition.X = NewCursorX;
|
|
|
|
Buff->CursorPosition.Y = NewCursorY;
|
2012-11-17 15:41:31 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
|
|
|
{
|
2013-01-22 23:28:51 +00:00
|
|
|
if (!ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
|
2012-11-17 15:41:31 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto Quit;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Quit:
|
2013-01-24 22:41:33 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
2013-05-29 00:29:07 +00:00
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
CSR_API(SrvCreateConsoleScreenBuffer)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CreateScreenBufferRequest;
|
2012-11-18 14:21:21 +00:00
|
|
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
PVOID ScreenBufferInfo = NULL;
|
|
|
|
TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25},
|
|
|
|
DEFAULT_SCREEN_ATTRIB,
|
|
|
|
DEFAULT_POPUP_ATTRIB ,
|
|
|
|
TRUE,
|
|
|
|
CSR_DEFAULT_CURSOR_SIZE};
|
|
|
|
GRAPHICS_BUFFER_INFO GraphicsInfo;
|
|
|
|
GraphicsInfo.Info = CreateScreenBufferRequest->GraphicsBufferInfo; // HACK for MSVC
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
2012-10-22 23:55:51 +00:00
|
|
|
DPRINT("SrvCreateConsoleScreenBuffer\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
|
2013-04-07 23:18:59 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2013-03-30 18:44:56 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_TEXTMODE_BUFFER)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
ScreenBufferInfo = &TextModeInfo;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/*
|
|
|
|
if (Console->ActiveBuffer)
|
|
|
|
{
|
|
|
|
TextModeInfo.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
|
|
|
|
if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 80;
|
|
|
|
if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 25;
|
2013-03-09 01:39:49 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
TextModeInfo.ScreenAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.ScreenDefaultAttrib;
|
|
|
|
TextModeInfo.PopupAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.PopupDefaultAttrib;
|
2013-03-30 18:44:56 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
TextModeInfo.IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
|
|
|
|
TextModeInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
|
|
|
|
}
|
|
|
|
*/
|
2013-03-30 18:44:56 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/*
|
|
|
|
* This is Windows' behaviour
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Use the current console size. Regularize it if needed. */
|
|
|
|
TextModeInfo.ScreenBufferSize = Console->ConsoleSize;
|
|
|
|
if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1;
|
|
|
|
if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1;
|
|
|
|
|
|
|
|
/* If we have an active screen buffer, use its attributes as the new ones */
|
|
|
|
if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
2013-03-30 18:44:56 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer;
|
|
|
|
|
|
|
|
TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib;
|
|
|
|
TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib;
|
2013-03-30 18:44:56 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible;
|
|
|
|
TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize;
|
2013-03-30 18:44:56 +00:00
|
|
|
}
|
|
|
|
}
|
2013-05-29 00:29:07 +00:00
|
|
|
else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Get infos from the graphics buffer information structure */
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
(PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo,
|
|
|
|
1,
|
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength))
|
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
|
|
|
|
ScreenBufferInfo = &GraphicsInfo;
|
2013-04-07 23:18:59 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Initialize shared variables */
|
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE;
|
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = GraphicsInfo.Info.lpBitMap = NULL;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* A graphics screen buffer is never inheritable */
|
|
|
|
CreateScreenBufferRequest->Inheritable = FALSE;
|
2013-04-07 23:18:59 +00:00
|
|
|
}
|
2012-11-18 14:21:21 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvCreateScreenBuffer(&Buff,
|
|
|
|
Console,
|
|
|
|
CreateScreenBufferRequest->ScreenBufferType,
|
|
|
|
ScreenBufferInfo);
|
|
|
|
if (!NT_SUCCESS(Status)) goto Quit;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
/* Insert the new handle inside the process handles table */
|
|
|
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Status = ConSrvInsertObject(ProcessData,
|
|
|
|
&CreateScreenBufferRequest->OutputHandle,
|
|
|
|
&Buff->Header,
|
|
|
|
CreateScreenBufferRequest->Access,
|
|
|
|
CreateScreenBufferRequest->Inheritable,
|
|
|
|
CreateScreenBufferRequest->ShareMode);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
2012-11-18 14:17:47 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto Quit;
|
2012-11-19 23:26:36 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
|
|
|
|
{
|
|
|
|
PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)Buff;
|
|
|
|
/*
|
|
|
|
* Initialize the graphics buffer information structure
|
|
|
|
* and give it back to the client.
|
|
|
|
*/
|
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = Buffer->ClientMutex;
|
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = Buffer->ClientBitMap;
|
|
|
|
}
|
2012-11-19 23:26:36 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Quit:
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
CSR_API(SrvSetConsoleActiveScreenBuffer)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2012-11-17 15:41:31 +00:00
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferRequest;
|
2013-01-05 23:37:04 +00:00
|
|
|
PCONSOLE Console;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buff;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
DPRINT("SrvSetConsoleActiveScreenBuffer\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetScreenBufferRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
|
2012-11-18 14:17:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
Console = Buff->Header.Console;
|
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
if (Buff == Console->ActiveBuffer) goto Quit;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-11-17 15:41:31 +00:00
|
|
|
/* If old buffer has no handles, it's now unreferenced */
|
|
|
|
if (Console->ActiveBuffer->Header.HandleCount == 0)
|
2010-05-31 06:28:55 +00:00
|
|
|
{
|
2012-11-17 15:41:31 +00:00
|
|
|
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
2012-11-18 14:17:47 +00:00
|
|
|
|
|
|
|
/* Tie console to new buffer */
|
2013-05-29 00:29:07 +00:00
|
|
|
ConioSetActiveScreenBuffer(Buff);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-05-29 00:29:07 +00:00
|
|
|
Quit:
|
2013-01-24 22:41:33 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|