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
|
2013-07-13 04:54:49 +00:00
|
|
|
* FILE: win32ss/user/winsrv/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"
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2013-03-19 22:05:38 +00:00
|
|
|
/* PUBLIC SERVER APIS *********************************************************/
|
2012-11-17 15:41:31 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
|
|
|
|
IN PCONSOLE_SCREEN_BUFFER Buffer,
|
|
|
|
IN PSMALL_RECT Region);
|
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-06-23 12:13:21 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER Buffer;
|
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-06-23 12:13:21 +00:00
|
|
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
InvalidateDIBitsRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
2012-11-18 13:54:32 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvInvalidateBitMapRect(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
&InvalidateDIBitsRequest->Region);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2013-08-12 16:12:58 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsolePalette(IN PCONSOLE Console,
|
2013-10-12 15:37:50 +00:00
|
|
|
// IN PGRAPHICS_SCREEN_BUFFER Buffer,
|
|
|
|
IN PCONSOLE_SCREEN_BUFFER Buffer,
|
2013-08-12 16:12:58 +00:00
|
|
|
IN HPALETTE PaletteHandle,
|
2013-10-12 15:37:50 +00:00
|
|
|
IN UINT PaletteUsage);
|
2013-08-12 16:12:58 +00:00
|
|
|
CSR_API(SrvSetConsolePalette)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_SETPALETTE SetPaletteRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetPaletteRequest;
|
2013-10-12 15:37:50 +00:00
|
|
|
// PGRAPHICS_SCREEN_BUFFER Buffer;
|
|
|
|
PCONSOLE_SCREEN_BUFFER Buffer;
|
2013-08-12 16:12:58 +00:00
|
|
|
|
2013-10-20 22:35:15 +00:00
|
|
|
DPRINT("SrvSetConsolePalette\n");
|
2013-08-12 16:12:58 +00:00
|
|
|
|
|
|
|
// NOTE: Tests show that this function is used only for graphics screen buffers
|
2013-10-12 15:37:50 +00:00
|
|
|
// and otherwise it returns FALSE + sets last error to invalid handle.
|
|
|
|
// I think it's ridiculous, because if you are in text mode, simulating
|
|
|
|
// a change of VGA palette via DAC registers (done by a call to SetConsolePalette)
|
|
|
|
// cannot be done... So I allow it in ReactOS !
|
|
|
|
/*
|
2013-08-12 16:12:58 +00:00
|
|
|
Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetPaletteRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-10-12 15:37:50 +00:00
|
|
|
*/
|
|
|
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetPaletteRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-08-12 16:12:58 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-10-20 22:35:15 +00:00
|
|
|
/*
|
|
|
|
* Make the palette handle public, so that it can be
|
|
|
|
* used by other threads calling GDI functions on it.
|
|
|
|
* Indeed, the palette handle comes from a console app
|
|
|
|
* calling ourselves, running in CSRSS.
|
|
|
|
*/
|
|
|
|
NtUserConsoleControl(ConsoleMakePalettePublic,
|
|
|
|
&SetPaletteRequest->PaletteHandle,
|
|
|
|
sizeof(SetPaletteRequest->PaletteHandle));
|
2013-10-12 15:37:50 +00:00
|
|
|
|
2013-08-12 16:12:58 +00:00
|
|
|
Status = ConDrvSetConsolePalette(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
SetPaletteRequest->PaletteHandle,
|
|
|
|
SetPaletteRequest->Usage);
|
|
|
|
|
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvGetConsoleCursorInfo(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
OUT PCONSOLE_CURSOR_INFO CursorInfo);
|
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-06-23 12:13:21 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
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-06-23 12:13:21 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
CursorInfoRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvGetConsoleCursorInfo(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
&CursorInfoRequest->Info);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleCursorInfo(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN PCONSOLE_CURSOR_INFO CursorInfo);
|
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-06-23 12:13:21 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
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-06-23 12:13:21 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
CursorInfoRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvSetConsoleCursorInfo(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
&CursorInfoRequest->Info);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleCursorPosition(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN PCOORD Position);
|
2012-11-17 15:41:31 +00:00
|
|
|
CSR_API(SrvSetConsoleCursorPosition)
|
|
|
|
{
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorPositionRequest;
|
2013-06-23 12:13:21 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2012-11-17 15:41:31 +00:00
|
|
|
|
|
|
|
DPRINT("SrvSetConsoleCursorPosition\n");
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetCursorPositionRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2012-11-17 23:29:53 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvSetConsoleCursorPosition(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
&SetCursorPositionRequest->Position);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, 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,
|
2014-04-20 22:40:39 +00:00
|
|
|
CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength,
|
|
|
|
sizeof(BYTE)))
|
2013-05-29 00:29:07 +00:00
|
|
|
{
|
|
|
|
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 */
|
2014-04-20 22:40:39 +00:00
|
|
|
// CreateScreenBufferRequest->GraphicsBufferInfo.hMutex
|
|
|
|
CreateScreenBufferRequest->hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE;
|
|
|
|
// CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap
|
|
|
|
CreateScreenBufferRequest->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 */
|
2014-04-20 22:40:39 +00:00
|
|
|
CreateScreenBufferRequest->InheritHandle = FALSE;
|
2013-04-07 23:18:59 +00:00
|
|
|
}
|
2012-11-18 14:21:21 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvCreateScreenBuffer(&Buff,
|
2013-05-29 00:29:07 +00:00
|
|
|
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,
|
2014-04-20 22:40:39 +00:00
|
|
|
CreateScreenBufferRequest->DesiredAccess,
|
|
|
|
CreateScreenBufferRequest->InheritHandle,
|
2013-05-29 00:29:07 +00:00
|
|
|
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.
|
|
|
|
*/
|
2014-04-20 22:40:39 +00:00
|
|
|
// CreateScreenBufferRequest->GraphicsBufferInfo.hMutex
|
|
|
|
CreateScreenBufferRequest->hMutex = Buffer->ClientMutex;
|
|
|
|
// CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap
|
|
|
|
CreateScreenBufferRequest->lpBitMap = Buffer->ClientBitMap;
|
2013-05-29 00:29:07 +00:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console,
|
|
|
|
IN PCONSOLE_SCREEN_BUFFER Buffer);
|
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-06-23 12:13:21 +00:00
|
|
|
PCONSOLE_SCREEN_BUFFER Buffer;
|
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-06-23 12:13:21 +00:00
|
|
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetScreenBufferRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2012-11-18 14:17:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
Status = ConDrvSetConsoleActiveScreenBuffer(Buffer->Header.Console,
|
|
|
|
Buffer);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
|
|
|
}
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2012-11-18 14:17:47 +00:00
|
|
|
|
2013-06-23 14:51:08 +00:00
|
|
|
/* CSR THREADS FOR WriteConsole ***********************************************/
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
|
|
|
|
IN PCSR_THREAD ClientThread,
|
2013-11-10 20:20:57 +00:00
|
|
|
IN BOOLEAN CreateWaitBlock OPTIONAL);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
// Wait function CSR_WAIT_FUNCTION
|
|
|
|
static BOOLEAN
|
2013-10-05 23:34:25 +00:00
|
|
|
NTAPI
|
2013-06-23 14:51:08 +00:00
|
|
|
WriteConsoleThread(IN PLIST_ENTRY WaitList,
|
|
|
|
IN PCSR_THREAD WaitThread,
|
|
|
|
IN PCSR_API_MESSAGE WaitApiMessage,
|
|
|
|
IN PVOID WaitContext,
|
|
|
|
IN PVOID WaitArgument1,
|
|
|
|
IN PVOID WaitArgument2,
|
|
|
|
IN ULONG WaitFlags)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we are notified of the process termination via a call
|
|
|
|
* to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
|
|
|
|
* CsrDestroyThread, just return.
|
|
|
|
*/
|
|
|
|
if (WaitFlags & CsrProcessTerminating)
|
|
|
|
{
|
|
|
|
Status = STATUS_THREAD_IS_TERMINATING;
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
|
2013-11-10 20:20:57 +00:00
|
|
|
Status = DoWriteConsole(WaitApiMessage, WaitThread, FALSE);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
Quit:
|
|
|
|
if (Status != STATUS_PENDING)
|
|
|
|
{
|
|
|
|
WaitApiMessage->Status = Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (Status == STATUS_PENDING ? FALSE : TRUE);
|
|
|
|
}
|
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvWriteConsole(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
|
|
|
IN BOOLEAN Unicode,
|
|
|
|
IN PVOID StringBuffer,
|
|
|
|
IN ULONG NumCharsToWrite,
|
|
|
|
OUT PULONG NumCharsWritten OPTIONAL);
|
2013-06-23 14:51:08 +00:00
|
|
|
static NTSTATUS
|
|
|
|
DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
|
|
|
|
IN PCSR_THREAD ClientThread,
|
2013-11-10 20:20:57 +00:00
|
|
|
IN BOOLEAN CreateWaitBlock OPTIONAL)
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
2013-06-27 00:20:58 +00:00
|
|
|
NTSTATUS Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
|
2013-06-27 00:20:58 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
|
|
|
|
WriteConsoleRequest->OutputHandle,
|
|
|
|
&ScreenBuffer, GENERIC_WRITE, FALSE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
|
|
|
|
ScreenBuffer,
|
|
|
|
WriteConsoleRequest->Unicode,
|
|
|
|
WriteConsoleRequest->Buffer,
|
|
|
|
WriteConsoleRequest->NrCharactersToWrite,
|
|
|
|
&WriteConsoleRequest->NrCharactersWritten);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
if (Status == STATUS_PENDING)
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
|
|
|
if (CreateWaitBlock)
|
|
|
|
{
|
2013-06-27 00:20:58 +00:00
|
|
|
if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue,
|
2013-06-23 14:51:08 +00:00
|
|
|
WriteConsoleThread,
|
|
|
|
ClientThread,
|
|
|
|
ApiMessage,
|
|
|
|
NULL))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
Status = STATUS_NO_MEMORY;
|
2013-06-27 00:20:58 +00:00
|
|
|
goto Quit;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
/* Wait until we un-pause the console */
|
|
|
|
// Status = STATUS_PENDING;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
Quit:
|
|
|
|
ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
|
2013-06-23 14:51:08 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-23 12:13:21 +00:00
|
|
|
/* TEXT OUTPUT APIS ***********************************************************/
|
2010-05-31 06:28:55 +00:00
|
|
|
|
2013-06-23 14:51:08 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvReadConsoleOutput(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
2013-06-23 23:19:42 +00:00
|
|
|
IN BOOLEAN Unicode,
|
2013-06-23 14:51:08 +00:00
|
|
|
OUT PCHAR_INFO CharInfo/*Buffer*/,
|
|
|
|
IN PCOORD BufferSize,
|
|
|
|
IN PCOORD BufferCoord,
|
|
|
|
IN OUT PSMALL_RECT ReadRegion);
|
|
|
|
CSR_API(SrvReadConsoleOutput)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
|
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
|
|
|
|
|
|
|
DPRINT("SrvReadConsoleOutput\n");
|
|
|
|
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
(PVOID*)&ReadOutputRequest->CharInfo,
|
|
|
|
ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y,
|
|
|
|
sizeof(CHAR_INFO)))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
ReadOutputRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
Status = ConDrvReadConsoleOutput(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
ReadOutputRequest->Unicode,
|
|
|
|
ReadOutputRequest->CharInfo,
|
|
|
|
&ReadOutputRequest->BufferSize,
|
|
|
|
&ReadOutputRequest->BufferCoord,
|
|
|
|
&ReadOutputRequest->ReadRegion);
|
|
|
|
|
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvWriteConsoleOutput(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
2013-06-23 23:19:42 +00:00
|
|
|
IN BOOLEAN Unicode,
|
2013-06-23 14:51:08 +00:00
|
|
|
IN PCHAR_INFO CharInfo/*Buffer*/,
|
|
|
|
IN PCOORD BufferSize,
|
|
|
|
IN PCOORD BufferCoord,
|
|
|
|
IN OUT PSMALL_RECT WriteRegion);
|
|
|
|
CSR_API(SrvWriteConsoleOutput)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
|
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
|
|
|
|
|
|
|
DPRINT("SrvWriteConsoleOutput\n");
|
|
|
|
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
(PVOID*)&WriteOutputRequest->CharInfo,
|
|
|
|
WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y,
|
|
|
|
sizeof(CHAR_INFO)))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
WriteOutputRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
WriteOutputRequest->Unicode,
|
|
|
|
WriteOutputRequest->CharInfo,
|
|
|
|
&WriteOutputRequest->BufferSize,
|
|
|
|
&WriteOutputRequest->BufferCoord,
|
|
|
|
&WriteOutputRequest->WriteRegion);
|
|
|
|
|
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(SrvWriteConsole)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
|
|
|
|
|
|
|
|
DPRINT("SrvWriteConsole\n");
|
|
|
|
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
(PVOID)&WriteConsoleRequest->Buffer,
|
|
|
|
WriteConsoleRequest->BufferSize,
|
|
|
|
sizeof(BYTE)))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2013-11-10 20:20:57 +00:00
|
|
|
Status = DoWriteConsole(ApiMessage, CsrGetClientThread(), TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-27 00:20:58 +00:00
|
|
|
if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvReadConsoleOutputString(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN CODE_TYPE CodeType,
|
|
|
|
OUT PVOID StringBuffer,
|
|
|
|
IN ULONG NumCodesToRead,
|
|
|
|
IN PCOORD ReadCoord,
|
2014-07-29 00:00:21 +00:00
|
|
|
// OUT PCOORD EndCoord,
|
2014-07-29 14:00:46 +00:00
|
|
|
OUT PULONG NumCodesRead OPTIONAL);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvReadConsoleOutputString)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
|
2013-06-23 17:19:08 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
ULONG CodeSize;
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
PVOID pCode;
|
|
|
|
|
2013-06-23 14:51:08 +00:00
|
|
|
DPRINT("SrvReadConsoleOutputString\n");
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
switch (ReadOutputCodeRequest->CodeType)
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
|
|
|
case CODE_ASCII:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CODE_UNICODE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CODE_ATTRIBUTE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* For optimization purposes, Windows (and hence ReactOS, too, for
|
|
|
|
* compatibility reasons) uses a static buffer if no more than eighty
|
|
|
|
* bytes are read. Otherwise a new buffer is used.
|
|
|
|
* The client-side expects that we know this behaviour.
|
|
|
|
*/
|
|
|
|
if (ReadOutputCodeRequest->NumCodes * CodeSize <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* Adjust the internal pointer, because its old value points to
|
|
|
|
* the static buffer in the original ApiMessage structure.
|
|
|
|
*/
|
2014-07-29 13:49:03 +00:00
|
|
|
// ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
|
2014-07-29 00:00:21 +00:00
|
|
|
pCode = ReadOutputCodeRequest->CodeStaticBuffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
2014-07-29 13:49:03 +00:00
|
|
|
(PVOID*)&ReadOutputCodeRequest->pCode,
|
2014-07-29 00:00:21 +00:00
|
|
|
ReadOutputCodeRequest->NumCodes,
|
|
|
|
CodeSize))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2014-07-29 13:49:03 +00:00
|
|
|
pCode = ReadOutputCodeRequest->pCode;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
ReadOutputCodeRequest->OutputHandle,
|
2013-06-23 17:19:08 +00:00
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
ReadOutputCodeRequest->CodeType,
|
2014-07-29 00:00:21 +00:00
|
|
|
pCode,
|
|
|
|
ReadOutputCodeRequest->NumCodes,
|
|
|
|
&ReadOutputCodeRequest->Coord,
|
|
|
|
// &ReadOutputCodeRequest->EndCoord,
|
|
|
|
&ReadOutputCodeRequest->NumCodes);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN CODE_TYPE CodeType,
|
|
|
|
IN PVOID StringBuffer,
|
|
|
|
IN ULONG NumCodesToWrite,
|
2014-07-29 14:00:46 +00:00
|
|
|
IN PCOORD WriteCoord,
|
|
|
|
// OUT PCOORD EndCoord,
|
|
|
|
OUT PULONG NumCodesWritten OPTIONAL);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvWriteConsoleOutputString)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest;
|
2013-06-23 17:19:08 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
ULONG CodeSize;
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
PVOID pCode;
|
|
|
|
|
2013-06-23 14:51:08 +00:00
|
|
|
DPRINT("SrvWriteConsoleOutputString\n");
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
switch (WriteOutputCodeRequest->CodeType)
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
|
|
|
case CODE_ASCII:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CODE_UNICODE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CODE_ATTRIBUTE:
|
2014-07-29 13:49:03 +00:00
|
|
|
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
|
2013-06-23 14:51:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* For optimization purposes, Windows (and hence ReactOS, too, for
|
|
|
|
* compatibility reasons) uses a static buffer if no more than eighty
|
|
|
|
* bytes are written. Otherwise a new buffer is used.
|
|
|
|
* The client-side expects that we know this behaviour.
|
|
|
|
*/
|
|
|
|
if (WriteOutputCodeRequest->NumCodes * CodeSize <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
|
2013-06-23 14:51:08 +00:00
|
|
|
{
|
2014-07-29 00:00:21 +00:00
|
|
|
/*
|
|
|
|
* Adjust the internal pointer, because its old value points to
|
|
|
|
* the static buffer in the original ApiMessage structure.
|
|
|
|
*/
|
2014-07-29 13:49:03 +00:00
|
|
|
// WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
|
2014-07-29 00:00:21 +00:00
|
|
|
pCode = WriteOutputCodeRequest->CodeStaticBuffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
2014-07-29 13:49:03 +00:00
|
|
|
(PVOID*)&WriteOutputCodeRequest->pCode,
|
2014-07-29 00:00:21 +00:00
|
|
|
WriteOutputCodeRequest->NumCodes,
|
|
|
|
CodeSize))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2014-07-29 13:49:03 +00:00
|
|
|
pCode = WriteOutputCodeRequest->pCode;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
WriteOutputCodeRequest->OutputHandle,
|
2013-06-23 17:19:08 +00:00
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
WriteOutputCodeRequest->CodeType,
|
2014-07-29 00:00:21 +00:00
|
|
|
pCode,
|
|
|
|
WriteOutputCodeRequest->NumCodes,
|
2014-07-29 14:00:46 +00:00
|
|
|
&WriteOutputCodeRequest->Coord,
|
|
|
|
// &WriteOutputCodeRequest->EndCoord,
|
|
|
|
&WriteOutputCodeRequest->NumCodes);
|
2013-06-23 17:19:08 +00:00
|
|
|
|
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvFillConsoleOutput(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN CODE_TYPE CodeType,
|
2014-07-29 13:18:59 +00:00
|
|
|
IN CODE_ELEMENT Code,
|
2013-06-23 17:19:08 +00:00
|
|
|
IN ULONG NumCodesToWrite,
|
2014-07-29 14:00:46 +00:00
|
|
|
IN PCOORD WriteCoord,
|
|
|
|
OUT PULONG NumCodesWritten OPTIONAL);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvFillConsoleOutput)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
|
2013-06-23 17:19:08 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2014-07-29 13:18:59 +00:00
|
|
|
CODE_TYPE CodeType = FillOutputRequest->CodeType;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
DPRINT("SrvFillConsoleOutput\n");
|
|
|
|
|
|
|
|
if ( (CodeType != CODE_ASCII ) &&
|
|
|
|
(CodeType != CODE_UNICODE ) &&
|
|
|
|
(CodeType != CODE_ATTRIBUTE) )
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
FillOutputRequest->OutputHandle,
|
2013-06-23 17:19:08 +00:00
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
CodeType,
|
2014-07-29 13:18:59 +00:00
|
|
|
FillOutputRequest->Code,
|
2014-07-29 00:00:21 +00:00
|
|
|
FillOutputRequest->NumCodes,
|
2014-07-29 14:00:46 +00:00
|
|
|
&FillOutputRequest->WriteCoord,
|
|
|
|
&FillOutputRequest->NumCodes);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 17:19:08 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
NTSTATUS NTAPI
|
2014-03-08 15:31:05 +00:00
|
|
|
ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
OUT PCOORD ScreenBufferSize,
|
|
|
|
OUT PCOORD CursorPosition,
|
|
|
|
OUT PCOORD ViewOrigin,
|
|
|
|
OUT PCOORD ViewSize,
|
|
|
|
OUT PCOORD MaximumViewSize,
|
|
|
|
OUT PWORD Attributes);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvGetConsoleScreenBufferInfo)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
|
2013-06-23 18:20:39 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
DPRINT("SrvGetConsoleScreenBufferInfo\n");
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
ScreenBufferInfoRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConDrvGetConsoleScreenBufferInfo(Buffer->Header.Console,
|
|
|
|
Buffer,
|
2014-03-08 15:31:05 +00:00
|
|
|
&ScreenBufferInfoRequest->ScreenBufferSize,
|
|
|
|
&ScreenBufferInfoRequest->CursorPosition,
|
|
|
|
&ScreenBufferInfoRequest->ViewOrigin,
|
|
|
|
&ScreenBufferInfoRequest->ViewSize,
|
|
|
|
&ScreenBufferInfoRequest->MaximumViewSize,
|
|
|
|
&ScreenBufferInfoRequest->Attributes);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleTextAttribute(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
2014-04-20 11:25:38 +00:00
|
|
|
IN WORD Attributes);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvSetConsoleTextAttribute)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest;
|
2013-06-23 18:20:39 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
DPRINT("SrvSetConsoleTextAttribute\n");
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetTextAttribRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConDrvSetConsoleTextAttribute(Buffer->Header.Console,
|
|
|
|
Buffer,
|
2014-04-20 11:25:38 +00:00
|
|
|
SetTextAttribRequest->Attributes);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN PCOORD Size);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvSetConsoleScreenBufferSize)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest;
|
2013-06-23 18:20:39 +00:00
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
DPRINT("SrvSetConsoleScreenBufferSize\n");
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetScreenBufferSizeRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConDrvSetConsoleScreenBufferSize(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
&SetScreenBufferSizeRequest->Size);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
2013-06-23 23:19:42 +00:00
|
|
|
IN BOOLEAN Unicode,
|
2013-06-23 18:20:39 +00:00
|
|
|
IN PSMALL_RECT ScrollRectangle,
|
2013-06-23 23:19:42 +00:00
|
|
|
IN BOOLEAN UseClipRectangle,
|
2013-06-23 18:20:39 +00:00
|
|
|
IN PSMALL_RECT ClipRectangle OPTIONAL,
|
|
|
|
IN PCOORD DestinationOrigin,
|
|
|
|
IN CHAR_INFO FillChar);
|
2013-06-23 14:51:08 +00:00
|
|
|
CSR_API(SrvScrollConsoleScreenBuffer)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2013-06-23 18:20:39 +00:00
|
|
|
PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest;
|
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-06-23 14:51:08 +00:00
|
|
|
|
|
|
|
DPRINT("SrvScrollConsoleScreenBuffer\n");
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
ScrollScreenBufferRequest->OutputHandle,
|
|
|
|
&Buffer, GENERIC_WRITE, TRUE);
|
2013-06-23 14:51:08 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
Status = ConDrvScrollConsoleScreenBuffer(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
ScrollScreenBufferRequest->Unicode,
|
|
|
|
&ScrollScreenBufferRequest->ScrollRectangle,
|
|
|
|
ScrollScreenBufferRequest->UseClipRectangle,
|
|
|
|
&ScrollScreenBufferRequest->ClipRectangle,
|
|
|
|
&ScrollScreenBufferRequest->DestinationOrigin,
|
|
|
|
ScrollScreenBufferRequest->Fill);
|
2013-06-23 14:51:08 +00:00
|
|
|
|
2013-06-23 18:20:39 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-06-23 14:51:08 +00:00
|
|
|
}
|
|
|
|
|
2013-07-06 15:59:28 +00:00
|
|
|
NTSTATUS NTAPI
|
|
|
|
ConDrvSetConsoleWindowInfo(IN PCONSOLE Console,
|
|
|
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
|
|
|
IN BOOLEAN Absolute,
|
|
|
|
IN PSMALL_RECT WindowRect);
|
2013-07-03 22:40:58 +00:00
|
|
|
CSR_API(SrvSetConsoleWindowInfo)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest;
|
2013-07-06 15:59:28 +00:00
|
|
|
// PCONSOLE_SCREEN_BUFFER Buffer;
|
|
|
|
PTEXTMODE_SCREEN_BUFFER Buffer;
|
2013-07-03 22:40:58 +00:00
|
|
|
|
2013-07-06 15:59:28 +00:00
|
|
|
DPRINT1("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
|
2013-07-03 22:40:58 +00:00
|
|
|
SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
|
2013-07-06 15:59:28 +00:00
|
|
|
SetWindowInfoRequest->WindowRect.Left ,
|
|
|
|
SetWindowInfoRequest->WindowRect.Top ,
|
|
|
|
SetWindowInfoRequest->WindowRect.Right,
|
|
|
|
SetWindowInfoRequest->WindowRect.Bottom);
|
2013-07-03 22:40:58 +00:00
|
|
|
|
2013-07-06 15:59:28 +00:00
|
|
|
// ConSrvGetScreenBuffer
|
2013-07-03 22:40:58 +00:00
|
|
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
|
|
|
SetWindowInfoRequest->OutputHandle,
|
2013-07-06 15:59:28 +00:00
|
|
|
&Buffer, GENERIC_READ, TRUE);
|
2013-07-03 22:40:58 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2013-07-06 15:59:28 +00:00
|
|
|
Status = ConDrvSetConsoleWindowInfo(Buffer->Header.Console,
|
|
|
|
Buffer,
|
|
|
|
SetWindowInfoRequest->Absolute,
|
|
|
|
&SetWindowInfoRequest->WindowRect);
|
2013-07-03 22:40:58 +00:00
|
|
|
|
2013-07-06 15:59:28 +00:00
|
|
|
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
|
|
|
return Status;
|
2013-07-03 22:40:58 +00:00
|
|
|
}
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
/* EOF */
|