2005-01-06 15:57:38 +00:00
|
|
|
/*
|
2003-12-02 11:38:47 +00:00
|
|
|
* reactos/subsys/csrss/win32csr/conio.c
|
1999-12-22 14:48:30 +00:00
|
|
|
*
|
|
|
|
* Console I/O functions
|
|
|
|
*
|
|
|
|
* ReactOS Operating System
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
#define NDEBUG
|
2009-01-28 16:30:19 +00:00
|
|
|
#include "w32csr.h"
|
2000-07-07 01:16:50 +00:00
|
|
|
#include <debug.h>
|
1999-12-22 14:48:30 +00:00
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
#define ConioInitRect(Rect, Top, Left, Bottom, Right) \
|
|
|
|
((Rect)->top) = Top; \
|
|
|
|
((Rect)->left) = Left; \
|
|
|
|
((Rect)->bottom) = Bottom; \
|
|
|
|
((Rect)->right) = Right
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
#define ConioIsRectEmpty(Rect) \
|
|
|
|
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
|
1999-12-22 14:48:30 +00:00
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
2004-11-02 20:42:06 +00:00
|
|
|
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
|
|
|
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
|
2008-06-27 12:34:08 +00:00
|
|
|
MultiByteToWideChar((Console)->OutputCodePage, 0, (dChar), 1, (sWChar), 1)
|
2004-11-02 20:42:06 +00:00
|
|
|
|
|
|
|
|
1999-12-22 14:48:30 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2008-07-27 00:41:45 +00:00
|
|
|
NTSTATUS FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2007-06-14 16:41:55 +00:00
|
|
|
PCSRSS_CONSOLE ProcessConsole = ProcessData->Console;
|
|
|
|
|
|
|
|
if (!ProcessConsole)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
*Console = NULL;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
return STATUS_INVALID_HANDLE;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2008-07-22 00:33:42 +00:00
|
|
|
InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
|
2007-06-14 16:41:55 +00:00
|
|
|
EnterCriticalSection(&(ProcessConsole->Header.Lock));
|
|
|
|
*Console = ProcessConsole;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:14:52 +00:00
|
|
|
VOID FASTCALL
|
2005-12-01 22:29:57 +00:00
|
|
|
ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2005-04-03 13:04:10 +00:00
|
|
|
HANDLE Thread;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2006-07-16 17:00:39 +00:00
|
|
|
DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId);
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (ProcessData->CtrlDispatcher)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
|
|
|
|
2005-04-03 13:04:10 +00:00
|
|
|
Thread = CreateRemoteThread(ProcessData->Process, NULL, 0,
|
2004-01-11 17:31:16 +00:00
|
|
|
(LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
|
2009-06-20 12:40:11 +00:00
|
|
|
UlongToPtr(Event), 0, NULL);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (NULL == Thread)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2005-03-21 08:32:22 +00:00
|
|
|
DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
|
2004-01-11 17:31:16 +00:00
|
|
|
return;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2005-12-01 22:29:57 +00:00
|
|
|
WaitForSingleObject(Thread, Timeout);
|
2004-01-11 17:31:16 +00:00
|
|
|
CloseHandle(Thread);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-01 22:29:57 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
|
|
|
|
{
|
2008-07-20 19:34:18 +00:00
|
|
|
ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
|
2005-12-01 22:29:57 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 20:08:18 +00:00
|
|
|
PBYTE FASTCALL
|
|
|
|
ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)];
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
}
|
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
static VOID FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY);
|
2004-01-11 17:31:16 +00:00
|
|
|
UINT Pos;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
for (Pos = 0; Pos < Buff->MaxX; Pos++)
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
/* Fill the cell */
|
|
|
|
*Ptr++ = ' ';
|
|
|
|
*Ptr++ = Buff->DefaultAttrib;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static NTSTATUS FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
|
|
|
|
PCSRSS_SCREEN_BUFFER Buffer)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2006-07-12 21:06:21 +00:00
|
|
|
DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
|
|
|
|
Buffer->Header.ReferenceCount = 0;
|
|
|
|
Buffer->ShowX = 0;
|
|
|
|
Buffer->ShowY = 0;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Buffer->VirtualY = 0;
|
2006-11-30 16:48:13 +00:00
|
|
|
Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (NULL == Buffer->Buffer)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2005-01-03 23:02:15 +00:00
|
|
|
InitializeCriticalSection(&Buffer->Header.Lock);
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioInitScreenBuffer(Console, Buffer);
|
|
|
|
/* initialize buffer to be empty with default attributes */
|
|
|
|
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ClearLineBuffer(Buffer);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
|
|
|
|
Buffer->CurrentX = 0;
|
|
|
|
Buffer->CurrentY = 0;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
static NTSTATUS WINAPI
|
2004-01-11 17:31:16 +00:00
|
|
|
CsrInitConsole(PCSRSS_CONSOLE Console)
|
2003-08-18 07:20:37 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
|
|
|
PCSRSS_SCREEN_BUFFER NewBuffer;
|
|
|
|
BOOL GuiMode;
|
2003-08-18 10:58:49 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Console->Title.MaximumLength = Console->Title.Length = 0;
|
|
|
|
Console->Title.Buffer = NULL;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2006-07-12 16:48:58 +00:00
|
|
|
//FIXME
|
2004-01-11 17:31:16 +00:00
|
|
|
RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Console->Header.ReferenceCount = 0;
|
|
|
|
Console->WaitingChars = 0;
|
|
|
|
Console->WaitingLines = 0;
|
|
|
|
Console->EchoCount = 0;
|
|
|
|
Console->Header.Type = CONIO_CONSOLE_MAGIC;
|
|
|
|
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
|
|
|
|
Console->EarlyReturn = FALSE;
|
|
|
|
Console->ActiveBuffer = NULL;
|
|
|
|
InitializeListHead(&Console->InputEvents);
|
2004-08-24 17:25:17 +00:00
|
|
|
Console->CodePage = GetOEMCP();
|
|
|
|
Console->OutputCodePage = GetOEMCP();
|
2004-08-22 20:52:28 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
|
|
SecurityAttributes.lpSecurityDescriptor = NULL;
|
|
|
|
SecurityAttributes.bInheritHandle = TRUE;
|
2003-08-18 07:20:37 +00:00
|
|
|
|
2004-11-14 18:47:10 +00:00
|
|
|
Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (NULL == Console->ActiveEvent)
|
|
|
|
{
|
2004-02-27 17:35:42 +00:00
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
Console->PrivateData = NULL;
|
2005-01-03 23:02:15 +00:00
|
|
|
InitializeCriticalSection(&Console->Header.Lock);
|
2006-07-12 21:06:21 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
GuiMode = DtbgIsDesktopVisible();
|
2006-07-12 21:06:21 +00:00
|
|
|
|
|
|
|
/* allocate console screen buffer */
|
|
|
|
NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
|
|
|
|
if (NULL == NewBuffer)
|
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
|
|
|
DeleteCriticalSection(&Console->Header.Lock);
|
|
|
|
CloseHandle(Console->ActiveEvent);
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
2007-09-03 01:58:43 +00:00
|
|
|
/* init screen buffer with defaults */
|
|
|
|
NewBuffer->CursorInfo.bVisible = TRUE;
|
2009-02-11 16:39:33 +00:00
|
|
|
NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
|
2007-09-03 01:58:43 +00:00
|
|
|
/* make console active, and insert into console list */
|
|
|
|
Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! GuiMode)
|
|
|
|
{
|
|
|
|
Status = TuiInitConsole(Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
|
|
|
|
GuiMode = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (GuiMode)
|
|
|
|
{
|
|
|
|
Status = GuiInitConsole(Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2006-07-12 21:06:21 +00:00
|
|
|
HeapFree(Win32CsrApiHeap,0, NewBuffer);
|
2004-02-27 17:35:42 +00:00
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
2006-07-12 21:06:21 +00:00
|
|
|
DeleteCriticalSection(&Console->Header.Lock);
|
2004-01-11 17:31:16 +00:00
|
|
|
CloseHandle(Console->ActiveEvent);
|
2006-07-12 21:06:21 +00:00
|
|
|
DPRINT1("GuiInitConsole: failed\n");
|
2004-01-11 17:31:16 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2003-08-18 07:20:37 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2004-12-18 19:23:05 +00:00
|
|
|
ConioCleanupConsole(Console);
|
2004-02-27 17:35:42 +00:00
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
2005-01-03 23:02:15 +00:00
|
|
|
DeleteCriticalSection(&Console->Header.Lock);
|
2004-01-11 17:31:16 +00:00
|
|
|
CloseHandle(Console->ActiveEvent);
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
|
2006-07-16 17:00:39 +00:00
|
|
|
DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
|
2004-01-11 17:31:16 +00:00
|
|
|
return Status;
|
2003-08-18 10:58:49 +00:00
|
|
|
}
|
2006-07-12 21:06:21 +00:00
|
|
|
|
2008-07-16 00:24:54 +00:00
|
|
|
/* add a reference count because the buffer is tied to the console */
|
|
|
|
InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
/* copy buffer contents to screen */
|
|
|
|
ConioDrawConsole(Console);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2003-08-18 07:20:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrAllocConsole)
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
2005-07-28 04:12:43 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2005-07-31 23:39:05 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-07-31 21:23:40 +00:00
|
|
|
BOOLEAN NewConsole = FALSE;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-07-31 06:22:05 +00:00
|
|
|
DPRINT("CsrAllocConsole\n");
|
2000-04-23 17:44:53 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
if (ProcessData->Console)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-07-28 04:12:43 +00:00
|
|
|
DPRINT1("Process already has a console\n");
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
/* If we don't need a console, then get out of here */
|
2005-07-28 11:48:58 +00:00
|
|
|
if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-07-31 06:22:05 +00:00
|
|
|
DPRINT("No console needed\n");
|
2005-07-28 04:12:43 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we already have one, then don't create a new one... */
|
2005-07-31 21:23:40 +00:00
|
|
|
if (!Request->Data.AllocConsoleRequest.Console ||
|
|
|
|
Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
|
2005-07-28 04:12:43 +00:00
|
|
|
{
|
|
|
|
/* Allocate a console structure */
|
2005-07-31 21:23:40 +00:00
|
|
|
NewConsole = TRUE;
|
2006-09-06 19:37:53 +00:00
|
|
|
Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
|
2005-07-28 04:12:43 +00:00
|
|
|
if (NULL == Console)
|
|
|
|
{
|
|
|
|
DPRINT1("Not enough memory for console\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
2006-09-06 19:37:53 +00:00
|
|
|
/* initialize list head */
|
|
|
|
InitializeListHead(&Console->ProcessList);
|
|
|
|
/* insert process data required for GUI initialization */
|
|
|
|
InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry);
|
2005-07-28 04:12:43 +00:00
|
|
|
/* Initialize the Console */
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = CsrInitConsole(Console);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2005-07-28 04:12:43 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Console init failed\n");
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2005-07-28 04:12:43 +00:00
|
|
|
}
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2005-07-28 04:12:43 +00:00
|
|
|
else
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-07-28 04:12:43 +00:00
|
|
|
/* Reuse our current console */
|
|
|
|
Console = Request->Data.AllocConsoleRequest.Console;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2003-08-18 07:20:37 +00:00
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
/* Set the Process Console */
|
|
|
|
ProcessData->Console = Console;
|
|
|
|
|
|
|
|
/* Return it to the caller */
|
|
|
|
Request->Data.AllocConsoleRequest.Console = Console;
|
|
|
|
|
|
|
|
/* Add a reference count because the process is tied to the console */
|
|
|
|
Console->Header.ReferenceCount++;
|
|
|
|
|
2005-07-31 21:23:40 +00:00
|
|
|
if (NewConsole || !ProcessData->bInheritHandles)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-07-31 21:23:40 +00:00
|
|
|
/* Insert the Objects */
|
2008-07-16 23:16:40 +00:00
|
|
|
Status = Win32CsrInsertObject(ProcessData,
|
|
|
|
&Request->Data.AllocConsoleRequest.InputHandle,
|
2008-07-22 17:37:13 +00:00
|
|
|
&Console->Header,
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
TRUE);
|
2005-07-31 21:23:40 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to insert object\n");
|
|
|
|
ConioDeleteConsole((Object_t *) Console);
|
|
|
|
ProcessData->Console = 0;
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2005-07-31 21:23:40 +00:00
|
|
|
}
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2008-07-16 23:16:40 +00:00
|
|
|
Status = Win32CsrInsertObject(ProcessData,
|
|
|
|
&Request->Data.AllocConsoleRequest.OutputHandle,
|
2008-07-22 17:37:13 +00:00
|
|
|
&Console->ActiveBuffer->Header,
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
TRUE);
|
2005-07-31 21:23:40 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to insert object\n");
|
|
|
|
ConioDeleteConsole((Object_t *) Console);
|
2006-07-16 17:00:39 +00:00
|
|
|
Win32CsrReleaseObject(ProcessData,
|
2005-07-31 21:23:40 +00:00
|
|
|
Request->Data.AllocConsoleRequest.InputHandle);
|
|
|
|
ProcessData->Console = 0;
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2005-07-31 21:23:40 +00:00
|
|
|
}
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
/* Duplicate the Event */
|
2006-07-16 17:00:39 +00:00
|
|
|
if (!DuplicateHandle(GetCurrentProcess(),
|
2005-07-28 04:12:43 +00:00
|
|
|
ProcessData->Console->ActiveEvent,
|
2006-07-16 17:00:39 +00:00
|
|
|
ProcessData->Process,
|
|
|
|
&ProcessData->ConsoleEvent,
|
|
|
|
EVENT_ALL_ACCESS,
|
|
|
|
FALSE,
|
2005-07-28 04:12:43 +00:00
|
|
|
0))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-07-28 04:12:43 +00:00
|
|
|
DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
|
2005-07-31 21:23:40 +00:00
|
|
|
ConioDeleteConsole((Object_t *) Console);
|
|
|
|
if (NewConsole || !ProcessData->bInheritHandles)
|
|
|
|
{
|
|
|
|
Win32CsrReleaseObject(ProcessData,
|
|
|
|
Request->Data.AllocConsoleRequest.OutputHandle);
|
|
|
|
Win32CsrReleaseObject(ProcessData,
|
|
|
|
Request->Data.AllocConsoleRequest.InputHandle);
|
|
|
|
}
|
2005-07-28 04:12:43 +00:00
|
|
|
ProcessData->Console = 0;
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2003-08-18 10:58:49 +00:00
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
/* Set the Ctrl Dispatcher */
|
|
|
|
ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
|
2005-07-31 06:22:05 +00:00
|
|
|
DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
2005-07-28 04:12:43 +00:00
|
|
|
|
2006-09-06 19:37:53 +00:00
|
|
|
if (!NewConsole)
|
|
|
|
{
|
|
|
|
/* Insert into the list if it has not been added */
|
|
|
|
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
|
|
|
|
}
|
|
|
|
|
2005-07-28 04:12:43 +00:00
|
|
|
return STATUS_SUCCESS;
|
1999-12-30 01:51:42 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrFreeConsole)
|
1999-12-30 01:51:42 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2001-07-30 11:56:54 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
if (ProcessData->Console == NULL)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Console = ProcessData->Console;
|
|
|
|
ProcessData->Console = NULL;
|
2008-07-23 16:21:46 +00:00
|
|
|
RemoveEntryList(&ProcessData->ProcessEntry);
|
2005-07-31 21:23:40 +00:00
|
|
|
if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioDeleteConsole((Object_t *) Console);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-07-30 11:56:54 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static VOID FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines)
|
2000-03-22 18:36:00 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
/* If we hit bottom, slide the viewable screen */
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (++Buff->CurrentY == Buff->MaxY)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Buff->CurrentY--;
|
|
|
|
if (++Buff->VirtualY == Buff->MaxY)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Buff->VirtualY = 0;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
(*ScrolledLines)++;
|
2008-06-27 12:34:08 +00:00
|
|
|
ClearLineBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (UpdateRect->top != 0)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
UpdateRect->top--;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
UpdateRect->left = 0;
|
|
|
|
UpdateRect->right = Buff->MaxX - 1;
|
2004-01-11 17:31:16 +00:00
|
|
|
UpdateRect->bottom = Buff->CurrentY;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static NTSTATUS FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
|
|
|
|
CHAR *Buffer, DWORD Length, BOOL Attrib)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2005-07-05 22:35:29 +00:00
|
|
|
UINT i;
|
2008-07-27 20:08:18 +00:00
|
|
|
PBYTE Ptr;
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT UpdateRect;
|
|
|
|
LONG CursorStartX, CursorStartY;
|
|
|
|
UINT ScrolledLines;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
CursorStartX = Buff->CurrentX;
|
|
|
|
CursorStartY = Buff->CurrentY;
|
2004-01-11 17:31:16 +00:00
|
|
|
UpdateRect.left = Buff->MaxX;
|
|
|
|
UpdateRect.top = Buff->CurrentY;
|
|
|
|
UpdateRect.right = -1;
|
|
|
|
UpdateRect.bottom = Buff->CurrentY;
|
|
|
|
ScrolledLines = 0;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
for (i = 0; i < Length; i++)
|
|
|
|
{
|
2004-08-24 17:25:17 +00:00
|
|
|
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
|
|
|
/* --- LF --- */
|
2004-08-24 17:25:17 +00:00
|
|
|
if (Buffer[i] == '\n')
|
|
|
|
{
|
|
|
|
Buff->CurrentX = 0;
|
|
|
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
|
|
continue;
|
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
/* --- BS --- */
|
2004-08-25 10:37:14 +00:00
|
|
|
else if (Buffer[i] == '\b')
|
2004-08-24 17:25:17 +00:00
|
|
|
{
|
|
|
|
/* Only handle BS if we're not on the first pos of the first line */
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (0 != Buff->CurrentX || 0 != Buff->CurrentY)
|
2004-08-24 17:25:17 +00:00
|
|
|
{
|
|
|
|
if (0 == Buff->CurrentX)
|
|
|
|
{
|
|
|
|
/* slide virtual position up */
|
|
|
|
Buff->CurrentX = Buff->MaxX - 1;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Buff->CurrentY--;
|
|
|
|
UpdateRect.top = min(UpdateRect.top, (LONG)Buff->CurrentY);
|
2004-08-24 17:25:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Buff->CurrentX--;
|
2004-08-24 17:25:17 +00:00
|
|
|
}
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
|
|
|
|
Ptr[0] = ' ';
|
|
|
|
Ptr[1] = Buff->DefaultAttrib;
|
2005-07-05 22:35:29 +00:00
|
|
|
UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
|
2005-07-01 01:54:55 +00:00
|
|
|
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
2004-08-24 17:25:17 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
/* --- CR --- */
|
2004-08-24 17:25:17 +00:00
|
|
|
else if (Buffer[i] == '\r')
|
|
|
|
{
|
|
|
|
Buff->CurrentX = 0;
|
2005-07-05 22:35:29 +00:00
|
|
|
UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX);
|
2005-07-01 01:54:55 +00:00
|
|
|
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
2004-08-24 17:25:17 +00:00
|
|
|
continue;
|
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
/* --- TAB --- */
|
2004-08-24 17:25:17 +00:00
|
|
|
else if (Buffer[i] == '\t')
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
UINT EndX;
|
|
|
|
|
2005-07-05 22:35:29 +00:00
|
|
|
UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
|
2004-08-24 17:25:17 +00:00
|
|
|
EndX = (Buff->CurrentX + 8) & ~7;
|
|
|
|
if (EndX > Buff->MaxX)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
EndX = Buff->MaxX;
|
|
|
|
}
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
|
2004-01-11 17:31:16 +00:00
|
|
|
while (Buff->CurrentX < EndX)
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
*Ptr++ = ' ';
|
|
|
|
*Ptr++ = Buff->DefaultAttrib;
|
2004-01-11 17:31:16 +00:00
|
|
|
Buff->CurrentX++;
|
|
|
|
}
|
2005-07-01 01:54:55 +00:00
|
|
|
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Buff->CurrentX == Buff->MaxX)
|
|
|
|
{
|
2004-08-24 17:25:17 +00:00
|
|
|
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
|
|
|
{
|
|
|
|
Buff->CurrentX = 0;
|
|
|
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Buff->CurrentX--;
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2004-08-24 17:25:17 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2005-07-05 22:35:29 +00:00
|
|
|
UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX);
|
2005-07-01 01:54:55 +00:00
|
|
|
UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX);
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
|
|
|
|
Ptr[0] = Buffer[i];
|
2004-08-24 17:25:17 +00:00
|
|
|
if (Attrib)
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr[1] = Buff->DefaultAttrib;
|
2004-08-24 17:25:17 +00:00
|
|
|
}
|
|
|
|
Buff->CurrentX++;
|
|
|
|
if (Buff->CurrentX == Buff->MaxX)
|
|
|
|
{
|
|
|
|
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
|
|
|
{
|
|
|
|
Buff->CurrentX = 0;
|
|
|
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Buff->CurrentX = CursorStartX;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines,
|
|
|
|
Buffer, Length);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
CSR_API(CsrReadConsole)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
ConsoleInput *Input;
|
2004-12-25 11:22:37 +00:00
|
|
|
PUCHAR Buffer;
|
2004-11-02 20:42:06 +00:00
|
|
|
PWCHAR UnicodeBuffer;
|
2005-07-05 22:35:29 +00:00
|
|
|
ULONG i;
|
2004-11-02 20:42:06 +00:00
|
|
|
ULONG nNumberOfCharsToRead, CharSize;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrReadConsole\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
/* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-28 12:03:25 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2001-09-01 15:36:45 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Buffer = Request->Data.ReadConsoleRequest.Buffer;
|
2004-11-02 20:42:06 +00:00
|
|
|
UnicodeBuffer = (PWCHAR)Buffer;
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Console, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
|
2004-01-11 17:31:16 +00:00
|
|
|
for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
/* remove input event from queue */
|
|
|
|
CurrentEntry = RemoveHeadList(&Console->InputEvents);
|
2004-11-14 18:47:10 +00:00
|
|
|
if (IsListEmpty(&Console->InputEvents))
|
|
|
|
{
|
|
|
|
ResetEvent(Console->ActiveEvent);
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
|
|
|
|
|
|
|
/* only pay attention to valid ascii chars, on key down */
|
|
|
|
if (KEY_EVENT == Input->InputEvent.EventType
|
|
|
|
&& Input->InputEvent.Event.KeyEvent.bKeyDown
|
2004-11-02 20:42:06 +00:00
|
|
|
&& Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0')
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2006-07-22 05:16:26 +00:00
|
|
|
/*
|
|
|
|
* backspace handling - if we are in charge of echoing it then we handle it here
|
2007-10-19 23:21:45 +00:00
|
|
|
* otherwise we treat it like a normal char.
|
2006-07-22 05:16:26 +00:00
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0
|
2006-07-22 05:16:26 +00:00
|
|
|
!= (Console->Mode & ENABLE_ECHO_INPUT))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
/* echo if it has not already been done, and either we or the client has chars to be deleted */
|
|
|
|
if (! Input->Echoed
|
|
|
|
&& (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted))
|
|
|
|
{
|
|
|
|
ConioWriteConsole(Console, Console->ActiveBuffer,
|
2004-11-02 20:42:06 +00:00
|
|
|
&Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
if (0 != i)
|
|
|
|
{
|
|
|
|
i -= 2; /* if we already have something to return, just back it up by 2 */
|
|
|
|
}
|
|
|
|
else
|
2006-07-22 05:16:26 +00:00
|
|
|
{ /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
|
2004-01-11 17:31:16 +00:00
|
|
|
Console->WaitingChars--;
|
|
|
|
ConioUnlockConsole(Console);
|
2004-11-02 20:42:06 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, Input);
|
2006-07-22 05:16:26 +00:00
|
|
|
Request->Data.ReadConsoleRequest.NrCharactersRead = 0;
|
|
|
|
return STATUS_NOTIFY_CLEANUP;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
|
|
|
|
Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */
|
|
|
|
}
|
|
|
|
/* do not copy backspace to buffer */
|
|
|
|
else
|
|
|
|
{
|
2004-11-02 20:42:06 +00:00
|
|
|
if(Request->Data.ReadConsoleRequest.Unicode)
|
|
|
|
UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
|
|
|
|
else
|
|
|
|
Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
/* echo to screen if enabled and we did not already echo the char */
|
|
|
|
if (0 != (Console->Mode & ENABLE_ECHO_INPUT)
|
|
|
|
&& ! Input->Echoed
|
|
|
|
&& '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
|
|
|
|
{
|
|
|
|
ConioWriteConsole(Console, Console->ActiveBuffer,
|
|
|
|
&Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
|
|
|
|
}
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
Console->WaitingChars--;
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, Input);
|
|
|
|
}
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadConsoleRequest.NrCharactersRead = i;
|
2004-01-11 17:31:16 +00:00
|
|
|
if (0 == i)
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_PENDING; /* we didn't read anything */
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
|
|
|
|
{
|
2004-11-02 20:42:06 +00:00
|
|
|
if (0 == Console->WaitingLines ||
|
|
|
|
(Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Console->WaitingLines--;
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_SUCCESS; /* line buffered, did get a complete line */
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_SUCCESS; /* not line buffered, did read something */
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
if (Status == STATUS_PENDING)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Console->EchoCount = nNumberOfCharsToRead - i;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
2005-08-28 12:03:25 +00:00
|
|
|
|
|
|
|
if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE))
|
|
|
|
{
|
|
|
|
Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize;
|
|
|
|
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
|
|
|
}
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-12-03 17:36:23 +00:00
|
|
|
__inline BOOLEAN ConioGetIntersection(
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT *Intersection,
|
|
|
|
RECT *Rect1,
|
|
|
|
RECT *Rect2)
|
|
|
|
{
|
|
|
|
if (ConioIsRectEmpty(Rect1) ||
|
|
|
|
(ConioIsRectEmpty(Rect2)) ||
|
|
|
|
(Rect1->top > Rect2->bottom) ||
|
|
|
|
(Rect1->left > Rect2->right) ||
|
|
|
|
(Rect1->bottom < Rect2->top) ||
|
|
|
|
(Rect1->right < Rect2->left))
|
|
|
|
{
|
|
|
|
/* The rectangles do not intersect */
|
|
|
|
ConioInitRect(Intersection, 0, -1, 0, -1);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioInitRect(Intersection,
|
2005-07-01 01:54:55 +00:00
|
|
|
max(Rect1->top, Rect2->top),
|
|
|
|
max(Rect1->left, Rect2->left),
|
|
|
|
min(Rect1->bottom, Rect2->bottom),
|
|
|
|
min(Rect1->right, Rect2->right));
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2008-12-03 17:36:23 +00:00
|
|
|
__inline BOOLEAN ConioGetUnion(
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT *Union,
|
|
|
|
RECT *Rect1,
|
|
|
|
RECT *Rect2)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
if (ConioIsRectEmpty(Rect1))
|
|
|
|
{
|
|
|
|
if (ConioIsRectEmpty(Rect2))
|
|
|
|
{
|
|
|
|
ConioInitRect(Union, 0, -1, 0, -1);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*Union = *Rect2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ConioIsRectEmpty(Rect2))
|
|
|
|
{
|
|
|
|
*Union = *Rect1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ConioInitRect(Union,
|
2005-07-01 01:54:55 +00:00
|
|
|
min(Rect1->top, Rect2->top),
|
|
|
|
min(Rect1->left, Rect2->left),
|
|
|
|
max(Rect1->bottom, Rect2->bottom),
|
|
|
|
max(Rect1->right, Rect2->right));
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2001-09-01 15:36:45 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
/* Move from one rectangle to another. We must be careful about the order that
|
|
|
|
* this is done, to avoid overwriting parts of the source before they are moved. */
|
|
|
|
static VOID FASTCALL
|
|
|
|
ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
|
|
|
|
RECT *SrcRegion,
|
|
|
|
RECT *DstRegion,
|
|
|
|
RECT *ClipRegion,
|
|
|
|
WORD Fill)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
int Width = ConioRectWidth(SrcRegion);
|
|
|
|
int Height = ConioRectHeight(SrcRegion);
|
|
|
|
int SX, SY;
|
|
|
|
int DX, DY;
|
|
|
|
int XDelta, YDelta;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
SY = SrcRegion->top;
|
|
|
|
DY = DstRegion->top;
|
|
|
|
YDelta = 1;
|
|
|
|
if (SY < DY)
|
|
|
|
{
|
|
|
|
/* Moving down: work from bottom up */
|
|
|
|
SY = SrcRegion->bottom;
|
|
|
|
DY = DstRegion->bottom;
|
|
|
|
YDelta = -1;
|
|
|
|
}
|
|
|
|
for (i = 0; i < Height; i++)
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
|
|
|
|
PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
|
2008-06-27 12:34:08 +00:00
|
|
|
|
|
|
|
SX = SrcRegion->left;
|
|
|
|
DX = DstRegion->left;
|
|
|
|
XDelta = 1;
|
|
|
|
if (SX < DX)
|
|
|
|
{
|
|
|
|
/* Moving right: work from right to left */
|
|
|
|
SX = SrcRegion->right;
|
|
|
|
DX = DstRegion->right;
|
|
|
|
XDelta = -1;
|
|
|
|
}
|
|
|
|
for (j = 0; j < Width; j++)
|
|
|
|
{
|
|
|
|
WORD Cell = SRow[SX];
|
|
|
|
if (SX >= ClipRegion->left && SX <= ClipRegion->right
|
|
|
|
&& SY >= ClipRegion->top && SY <= ClipRegion->bottom)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
SRow[SX] = Fill;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-06-27 12:34:08 +00:00
|
|
|
if (DX >= ClipRegion->left && DX <= ClipRegion->right
|
|
|
|
&& DY >= ClipRegion->top && DY <= ClipRegion->bottom)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
DRow[DX] = Cell;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-06-27 12:34:08 +00:00
|
|
|
SX += XDelta;
|
|
|
|
DX += XDelta;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-06-27 12:34:08 +00:00
|
|
|
SY += YDelta;
|
|
|
|
DY += YDelta;
|
2003-03-09 21:40:19 +00:00
|
|
|
}
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static VOID FASTCALL
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
|
|
|
|
{
|
|
|
|
if (InputEvent->EventType == KEY_EVENT)
|
|
|
|
{
|
2005-08-07 08:06:56 +00:00
|
|
|
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
|
|
|
|
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
|
2008-06-27 12:34:08 +00:00
|
|
|
ConsoleInputUnicodeCharToAnsiChar(Console,
|
|
|
|
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
|
|
|
|
&UnicodeChar);
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrWriteConsole)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
2005-08-07 08:06:56 +00:00
|
|
|
PCHAR Buffer;
|
2003-12-02 11:38:47 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2005-08-07 08:06:56 +00:00
|
|
|
DWORD Written = 0;
|
|
|
|
ULONG Length;
|
2004-11-02 20:42:06 +00:00
|
|
|
ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
DPRINT("CsrWriteConsole\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Request->Header.u1.s1.TotalLength
|
2006-07-16 17:00:39 +00:00
|
|
|
< CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)
|
2004-11-02 20:42:06 +00:00
|
|
|
+ (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Invalid request size\n");
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
if(Request->Data.WriteConsoleRequest.Unicode)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
|
2006-07-16 17:00:39 +00:00
|
|
|
(PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
|
|
|
|
Request->Data.WriteConsoleRequest.NrCharactersToWrite,
|
2005-08-07 08:06:56 +00:00
|
|
|
NULL, 0, NULL, NULL);
|
|
|
|
Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
|
|
|
|
if (Buffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
WideCharToMultiByte(Console->OutputCodePage, 0,
|
2006-07-16 17:00:39 +00:00
|
|
|
(PWCHAR)Request->Data.WriteConsoleRequest.Buffer,
|
|
|
|
Request->Data.WriteConsoleRequest.NrCharactersToWrite,
|
2005-08-07 08:06:56 +00:00
|
|
|
Buffer, Length, NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
|
|
|
|
}
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2005-08-07 08:06:56 +00:00
|
|
|
if (Buffer)
|
|
|
|
{
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2005-08-07 08:06:56 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = ConioWriteConsole(Console, Buff, Buffer,
|
|
|
|
Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
|
2005-08-07 08:06:56 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
|
|
|
|
}
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
}
|
|
|
|
if (Request->Data.WriteConsoleRequest.Unicode)
|
|
|
|
{
|
|
|
|
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-07 08:06:56 +00:00
|
|
|
Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
|
2004-11-02 20:42:06 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2001-01-21 00:11:54 +00:00
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
VOID WINAPI
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioDeleteScreenBuffer(Object_t *Object)
|
2001-01-21 00:11:54 +00:00
|
|
|
{
|
2003-12-02 11:38:47 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
|
2005-01-03 23:02:15 +00:00
|
|
|
DeleteCriticalSection(&Buffer->Header.Lock);
|
2004-01-11 17:31:16 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, Buffer);
|
2000-04-23 17:44:53 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
ConioDrawConsole(PCSRSS_CONSOLE Console)
|
2000-04-23 17:44:53 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT Region;
|
2000-04-23 17:44:53 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioDrawRegion(Console, &Region);
|
2000-04-23 17:44:53 +00:00
|
|
|
}
|
|
|
|
|
2000-10-09 00:12:01 +00:00
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
VOID WINAPI
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioDeleteConsole(Object_t *Object)
|
2000-04-23 17:44:53 +00:00
|
|
|
{
|
2003-12-02 11:38:47 +00:00
|
|
|
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
|
|
|
|
ConsoleInput *Event;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
DPRINT("ConioDeleteConsole\n");
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
/* Drain input event queue */
|
|
|
|
while (Console->InputEvents.Flink != &Console->InputEvents)
|
|
|
|
{
|
|
|
|
Event = (ConsoleInput *) Console->InputEvents.Flink;
|
|
|
|
Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
|
|
|
|
Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
|
2004-01-11 17:31:16 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, Event);
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
2008-07-16 23:16:40 +00:00
|
|
|
ConioCleanupConsole(Console);
|
2005-07-31 21:23:40 +00:00
|
|
|
if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
Console->ActiveBuffer = NULL;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
CloseHandle(Console->ActiveEvent);
|
2005-01-03 23:02:15 +00:00
|
|
|
DeleteCriticalSection(&Console->Header.Lock);
|
2003-12-02 11:38:47 +00:00
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
2008-07-27 00:41:45 +00:00
|
|
|
IntDeleteAllAliases(Console->Aliases);
|
2004-01-11 17:31:16 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, Console);
|
1999-12-22 14:48:30 +00:00
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
VOID WINAPI
|
2004-01-11 17:31:16 +00:00
|
|
|
CsrInitConsoleSupport(VOID)
|
2000-03-22 18:36:00 +00:00
|
|
|
{
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CSR: CsrInitConsoleSupport()\n");
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
/* Should call LoadKeyboardLayout */
|
2000-04-23 17:44:53 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static VOID FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioProcessChar(PCSRSS_CONSOLE Console,
|
2004-11-02 20:42:06 +00:00
|
|
|
ConsoleInput *KeyEventRecord)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2003-10-09 06:13:05 +00:00
|
|
|
BOOL updown;
|
2001-01-21 00:11:54 +00:00
|
|
|
ConsoleInput *TempInput;
|
2000-07-07 01:16:50 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)))
|
|
|
|
{
|
|
|
|
switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
|
|
|
|
{
|
|
|
|
case '\r':
|
|
|
|
/* first add the \r */
|
|
|
|
KeyEventRecord->InputEvent.EventType = KEY_EVENT;
|
|
|
|
updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown;
|
|
|
|
KeyEventRecord->Echoed = FALSE;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r';
|
|
|
|
InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry);
|
|
|
|
Console->WaitingChars++;
|
|
|
|
KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
|
|
|
|
if (NULL == KeyEventRecord)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to allocate KeyEventRecord\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
KeyEventRecord->InputEvent.EventType = KEY_EVENT;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0;
|
|
|
|
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n';
|
|
|
|
KeyEventRecord->Fake = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* add event to the queue */
|
2003-10-09 06:13:05 +00:00
|
|
|
InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry);
|
|
|
|
Console->WaitingChars++;
|
2004-01-11 17:31:16 +00:00
|
|
|
/* if line input mode is enabled, only wake the client on enter key down */
|
|
|
|
if (0 == (Console->Mode & ENABLE_LINE_INPUT)
|
|
|
|
|| Console->EarlyReturn
|
|
|
|
|| ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
|
2005-01-06 15:57:38 +00:00
|
|
|
&& KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
|
|
|
|
{
|
|
|
|
Console->WaitingLines++;
|
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
}
|
|
|
|
KeyEventRecord->Echoed = FALSE;
|
2004-01-11 17:31:16 +00:00
|
|
|
if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))
|
|
|
|
&& '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
|
|
|
|
&& KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)
|
|
|
|
{
|
|
|
|
/* walk the input queue looking for a char to backspace */
|
|
|
|
for (TempInput = (ConsoleInput *) Console->InputEvents.Blink;
|
2006-07-16 17:00:39 +00:00
|
|
|
TempInput != (ConsoleInput *) &Console->InputEvents
|
2004-01-11 17:31:16 +00:00
|
|
|
&& (KEY_EVENT == TempInput->InputEvent.EventType
|
|
|
|
|| ! TempInput->InputEvent.Event.KeyEvent.bKeyDown
|
|
|
|
|| '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar);
|
2006-07-16 17:00:39 +00:00
|
|
|
TempInput = (ConsoleInput *) TempInput->ListEntry.Blink)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
/* NOP */;
|
|
|
|
}
|
|
|
|
/* if we found one, delete it, otherwise, wake the client */
|
|
|
|
if (TempInput != (ConsoleInput *) &Console->InputEvents)
|
2006-07-16 17:00:39 +00:00
|
|
|
{
|
|
|
|
/* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
|
|
|
|
RemoveEntryList(&TempInput->ListEntry);
|
|
|
|
if (TempInput->Echoed)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioWriteConsole(Console, Console->ActiveBuffer,
|
|
|
|
&KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
|
2004-11-02 20:42:06 +00:00
|
|
|
1, TRUE);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, TempInput);
|
2006-07-16 17:00:39 +00:00
|
|
|
RemoveEntryList(&KeyEventRecord->ListEntry);
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
|
|
|
|
Console->WaitingChars -= 2;
|
2008-08-20 20:55:39 +00:00
|
|
|
return;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* echo chars if we are supposed to and client is waiting for some */
|
|
|
|
if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount
|
|
|
|
&& KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
|
|
|
|
&& KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown
|
|
|
|
&& '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
|
|
|
|
{
|
|
|
|
/* mark the char as already echoed */
|
|
|
|
ConioWriteConsole(Console, Console->ActiveBuffer,
|
|
|
|
&KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
|
|
|
|
1, TRUE);
|
|
|
|
Console->EchoCount--;
|
|
|
|
KeyEventRecord->Echoed = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-09 06:13:05 +00:00
|
|
|
/* Console->WaitingChars++; */
|
2008-08-20 20:55:39 +00:00
|
|
|
SetEvent(Console->ActiveEvent);
|
2003-10-09 06:13:05 +00:00
|
|
|
}
|
2003-08-18 07:20:37 +00:00
|
|
|
|
2005-11-22 03:18:13 +00:00
|
|
|
static DWORD FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioGetShiftState(PBYTE KeyState)
|
|
|
|
{
|
2003-10-09 06:13:05 +00:00
|
|
|
DWORD ssOut = 0;
|
|
|
|
|
2004-07-04 17:22:33 +00:00
|
|
|
if (KeyState[VK_CAPITAL] & 1)
|
|
|
|
ssOut |= CAPSLOCK_ON;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2004-07-04 17:22:33 +00:00
|
|
|
if (KeyState[VK_NUMLOCK] & 1)
|
|
|
|
ssOut |= NUMLOCK_ON;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2004-07-04 17:22:33 +00:00
|
|
|
if (KeyState[VK_SCROLL] & 1)
|
|
|
|
ssOut |= SCROLLLOCK_ON;
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2004-07-04 17:22:33 +00:00
|
|
|
if (KeyState[VK_SHIFT] & 0x80)
|
2004-02-19 06:59:50 +00:00
|
|
|
ssOut |= SHIFT_PRESSED;
|
|
|
|
|
|
|
|
if (KeyState[VK_LCONTROL] & 0x80)
|
|
|
|
ssOut |= LEFT_CTRL_PRESSED;
|
2004-03-07 20:03:43 +00:00
|
|
|
if (KeyState[VK_RCONTROL] & 0x80)
|
|
|
|
ssOut |= RIGHT_CTRL_PRESSED;
|
2004-02-19 06:59:50 +00:00
|
|
|
|
|
|
|
if (KeyState[VK_LMENU] & 0x80)
|
|
|
|
ssOut |= LEFT_ALT_PRESSED;
|
2004-03-07 20:03:43 +00:00
|
|
|
if (KeyState[VK_RMENU] & 0x80)
|
|
|
|
ssOut |= RIGHT_ALT_PRESSED;
|
2004-02-19 06:59:50 +00:00
|
|
|
|
2003-10-09 06:13:05 +00:00
|
|
|
return ssOut;
|
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
VOID WINAPI
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
|
2003-10-09 06:13:05 +00:00
|
|
|
{
|
2003-10-20 18:02:04 +00:00
|
|
|
static BYTE KeyState[256] = { 0 };
|
2003-11-24 00:22:53 +00:00
|
|
|
/* MSDN mentions that you should use the last virtual key code received
|
|
|
|
* when putting a virtual key identity to a WM_CHAR message since multiple
|
|
|
|
* or translated keys may be involved. */
|
|
|
|
static UINT LastVirtualKey = 0;
|
|
|
|
DWORD ShiftState;
|
2003-10-09 06:13:05 +00:00
|
|
|
ConsoleInput *ConInRec;
|
|
|
|
UINT RepeatCount;
|
2003-11-24 00:22:53 +00:00
|
|
|
CHAR AsciiChar;
|
2003-10-09 06:13:05 +00:00
|
|
|
WCHAR UnicodeChar;
|
|
|
|
UINT VirtualKeyCode;
|
|
|
|
UINT VirtualScanCode;
|
|
|
|
BOOL Down = FALSE;
|
|
|
|
INPUT_RECORD er;
|
2003-11-24 00:22:53 +00:00
|
|
|
ULONG ResultSize = 0;
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
RepeatCount = 1;
|
|
|
|
VirtualScanCode = (msg->lParam >> 16) & 0xff;
|
2005-05-08 04:07:56 +00:00
|
|
|
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
|
2003-11-24 00:22:53 +00:00
|
|
|
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
GetKeyboardState(KeyState);
|
2004-01-11 17:31:16 +00:00
|
|
|
ShiftState = ConioGetShiftState(KeyState);
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2003-11-24 00:22:53 +00:00
|
|
|
if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2003-11-24 00:22:53 +00:00
|
|
|
VirtualKeyCode = LastVirtualKey;
|
|
|
|
UnicodeChar = msg->wParam;
|
2005-05-08 04:07:56 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
else
|
2005-05-08 04:07:56 +00:00
|
|
|
{
|
2003-11-24 00:22:53 +00:00
|
|
|
WCHAR Chars[2];
|
|
|
|
INT RetChars = 0;
|
|
|
|
|
|
|
|
VirtualKeyCode = msg->wParam;
|
2003-12-02 11:38:47 +00:00
|
|
|
RetChars = ToUnicodeEx(VirtualKeyCode,
|
|
|
|
VirtualScanCode,
|
|
|
|
KeyState,
|
|
|
|
Chars,
|
|
|
|
2,
|
|
|
|
0,
|
|
|
|
0);
|
2003-11-24 00:22:53 +00:00
|
|
|
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
2003-10-09 06:13:05 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (0 == ResultSize)
|
|
|
|
{
|
|
|
|
AsciiChar = 0;
|
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
er.EventType = KEY_EVENT;
|
|
|
|
er.Event.KeyEvent.bKeyDown = Down;
|
|
|
|
er.Event.KeyEvent.wRepeatCount = RepeatCount;
|
2004-08-22 20:52:28 +00:00
|
|
|
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
2003-10-20 18:02:04 +00:00
|
|
|
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
|
|
|
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
|
|
|
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
if (TextMode)
|
2005-05-08 04:07:56 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
|
|
|
|
&& VK_TAB == VirtualKeyCode)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Down)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (VK_MENU == VirtualKeyCode && ! Down)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
if (TuiSwapConsole(0))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2005-05-08 04:07:56 +00:00
|
|
|
if (NULL == Console)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2008-07-26 15:20:21 +00:00
|
|
|
DPRINT1("No Active Console!\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
|
2003-10-20 18:02:04 +00:00
|
|
|
|
|
|
|
if (NULL == ConInRec)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
ConInRec->InputEvent = er;
|
2005-05-08 04:07:56 +00:00
|
|
|
ConInRec->Fake = UnicodeChar &&
|
2003-11-24 00:22:53 +00:00
|
|
|
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
|
|
|
|
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
|
|
|
|
ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
|
2003-10-20 18:02:04 +00:00
|
|
|
ConInRec->Echoed = FALSE;
|
2003-11-24 00:22:53 +00:00
|
|
|
if (ConInRec->NotChar)
|
|
|
|
LastVirtualKey = msg->wParam;
|
|
|
|
|
2004-02-19 06:59:50 +00:00
|
|
|
DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n",
|
2006-07-16 17:00:39 +00:00
|
|
|
Down ? "down" : "up ",
|
|
|
|
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
|
|
|
|
"char" : "key ",
|
|
|
|
ConInRec->Fake ? "fake" : "real",
|
|
|
|
ConInRec->NotChar ? "notc" : "char",
|
|
|
|
VirtualScanCode,
|
|
|
|
VirtualKeyCode,
|
|
|
|
(AsciiChar >= ' ') ? AsciiChar : '.',
|
|
|
|
ShiftState);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-26 15:20:21 +00:00
|
|
|
if (ConInRec->Fake && ConInRec->NotChar)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-07-26 15:20:21 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, ConInRec);
|
|
|
|
return;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-07-26 15:20:21 +00:00
|
|
|
|
|
|
|
/* process Ctrl-C and Ctrl-Break */
|
|
|
|
if (Console->Mode & ENABLE_PROCESSED_INPUT &&
|
|
|
|
er.Event.KeyEvent.bKeyDown &&
|
|
|
|
((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
|
|
|
|
(er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
|
|
|
|
(er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
|
|
|
|
{
|
|
|
|
PCSRSS_PROCESS_DATA current;
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
DPRINT1("Console_Api Ctrl-C\n");
|
|
|
|
current_entry = Console->ProcessList.Flink;
|
|
|
|
while (current_entry != &Console->ProcessList)
|
|
|
|
{
|
|
|
|
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
|
|
|
|
current_entry = current_entry->Flink;
|
|
|
|
ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
|
|
|
|
}
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, ConInRec);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0 != (er.Event.KeyEvent.dwControlKeyState
|
|
|
|
& (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
|
|
|
|
&& (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
|
|
|
|
|| VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-07-26 15:20:21 +00:00
|
|
|
if (er.Event.KeyEvent.bKeyDown)
|
|
|
|
{
|
|
|
|
/* scroll up or down */
|
|
|
|
if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
|
|
|
|
{
|
|
|
|
/* only scroll up if there is room to scroll up into */
|
|
|
|
if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
|
|
|
|
{
|
|
|
|
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
|
|
|
Console->ActiveBuffer->MaxY - 1) %
|
|
|
|
Console->ActiveBuffer->MaxY;
|
|
|
|
Console->ActiveBuffer->CurrentY++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* only scroll down if there is room to scroll down into */
|
|
|
|
if (Console->ActiveBuffer->CurrentY != 0)
|
|
|
|
{
|
|
|
|
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
|
|
|
|
Console->ActiveBuffer->MaxY;
|
|
|
|
Console->ActiveBuffer->CurrentY--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ConioDrawConsole(Console);
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, ConInRec);
|
2008-07-26 15:20:21 +00:00
|
|
|
return;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-07-26 15:20:21 +00:00
|
|
|
/* FIXME - convert to ascii */
|
|
|
|
ConioProcessChar(Console, ConInRec);
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrGetScreenBufferInfo)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
2008-07-29 16:10:38 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
PCONSOLE_SCREEN_BUFFER_INFO pInfo;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrGetScreenBufferInfo\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-07-29 16:10:38 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2008-07-29 16:10:38 +00:00
|
|
|
}
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-07-29 16:10:38 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
|
2004-01-11 17:31:16 +00:00
|
|
|
pInfo->dwSize.X = Buff->MaxX;
|
|
|
|
pInfo->dwSize.Y = Buff->MaxY;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
pInfo->dwCursorPosition.X = Buff->CurrentX;
|
|
|
|
pInfo->dwCursorPosition.Y = Buff->CurrentY;
|
2004-01-11 17:31:16 +00:00
|
|
|
pInfo->wAttributes = Buff->DefaultAttrib;
|
2008-07-29 16:10:38 +00:00
|
|
|
pInfo->srWindow.Left = Buff->ShowX;
|
|
|
|
pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1;
|
|
|
|
pInfo->srWindow.Top = Buff->ShowY;
|
|
|
|
pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1;
|
2004-01-11 17:31:16 +00:00
|
|
|
pInfo->dwMaximumWindowSize.X = Buff->MaxX;
|
|
|
|
pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2008-07-29 16:10:38 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetCursor)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2003-10-20 18:02:04 +00:00
|
|
|
NTSTATUS Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2003-10-20 18:02:04 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-01-11 17:31:16 +00:00
|
|
|
LONG OldCursorX, OldCursorY;
|
2004-08-24 17:25:17 +00:00
|
|
|
LONG NewCursorX, NewCursorY;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrSetCursor\n");
|
2000-05-26 05:43:33 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2004-08-24 17:25:17 +00:00
|
|
|
NewCursorX = Request->Data.SetCursorRequest.Position.X;
|
|
|
|
NewCursorY = Request->Data.SetCursorRequest.Position.Y;
|
|
|
|
if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
|
|
|
|
NewCursorY < 0 || NewCursorY >= Buff->MaxY)
|
|
|
|
{
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-08-24 17:25:17 +00:00
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
OldCursorX = Buff->CurrentX;
|
|
|
|
OldCursorY = Buff->CurrentY;
|
|
|
|
Buff->CurrentX = NewCursorX;
|
|
|
|
Buff->CurrentY = NewCursorY;
|
|
|
|
if (Buff == Console->ActiveBuffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2006-11-30 16:48:13 +00:00
|
|
|
static VOID FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length)
|
|
|
|
{
|
|
|
|
if (Buff->MaxX <= Start->X + Length)
|
|
|
|
{
|
|
|
|
UpdateRect->left = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UpdateRect->left = Start->X;
|
|
|
|
}
|
|
|
|
if (Buff->MaxX <= Start->X + Length)
|
|
|
|
{
|
|
|
|
UpdateRect->right = Buff->MaxX - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UpdateRect->right = Start->X + Length - 1;
|
|
|
|
}
|
|
|
|
UpdateRect->top = Start->Y;
|
|
|
|
UpdateRect->bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
|
|
|
|
if (Buff->MaxY <= UpdateRect->bottom)
|
|
|
|
{
|
|
|
|
UpdateRect->bottom = Buff->MaxY - 1;
|
|
|
|
}
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrWriteConsoleOutputChar)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
2005-08-07 23:37:59 +00:00
|
|
|
PCHAR String, tmpString = NULL;
|
2003-12-02 11:38:47 +00:00
|
|
|
PBYTE Buffer;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2003-12-02 11:38:47 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-11-02 20:42:06 +00:00
|
|
|
DWORD X, Y, Length, CharSize, Written = 0;
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT UpdateRect;
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
DPRINT("CsrWriteConsoleOutputChar\n");
|
2003-03-21 20:17:55 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
|
2003-03-21 20:17:55 +00:00
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Request->Header.u1.s1.TotalLength
|
2006-07-16 17:00:39 +00:00
|
|
|
< CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
|
2004-11-02 20:42:06 +00:00
|
|
|
+ (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Invalid request size\n");
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-08-07 08:06:56 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2005-08-07 08:06:56 +00:00
|
|
|
if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
|
2006-07-16 17:00:39 +00:00
|
|
|
(PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Length,
|
2005-08-07 08:06:56 +00:00
|
|
|
NULL, 0, NULL, NULL);
|
2005-08-07 23:37:59 +00:00
|
|
|
tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length);
|
2005-08-07 08:06:56 +00:00
|
|
|
if (String)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
WideCharToMultiByte(Console->OutputCodePage, 0,
|
2006-07-16 17:00:39 +00:00
|
|
|
(PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String,
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Length,
|
2005-08-07 08:06:56 +00:00
|
|
|
String, Length, NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
2005-08-07 08:06:56 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
|
|
|
|
}
|
2006-07-16 17:00:39 +00:00
|
|
|
|
2005-08-07 08:06:56 +00:00
|
|
|
if (String)
|
|
|
|
{
|
|
|
|
Status = ConioLockScreenBuffer(ProcessData,
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Buff,
|
|
|
|
GENERIC_WRITE);
|
2005-08-07 08:06:56 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
|
|
|
|
Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
|
2005-08-07 08:06:56 +00:00
|
|
|
Length = Request->Data.WriteConsoleOutputCharRequest.Length;
|
|
|
|
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
|
|
|
|
while (Length--)
|
|
|
|
{
|
|
|
|
*Buffer = *String++;
|
|
|
|
Written++;
|
|
|
|
Buffer += 2;
|
|
|
|
if (++X == Buff->MaxX)
|
|
|
|
{
|
|
|
|
if (++Y == Buff->MaxY)
|
|
|
|
{
|
|
|
|
Y = 0;
|
|
|
|
Buffer = Buff->Buffer;
|
|
|
|
}
|
|
|
|
X = 0;
|
|
|
|
}
|
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2005-08-07 08:06:56 +00:00
|
|
|
{
|
|
|
|
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord,
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.Length);
|
|
|
|
ConioDrawRegion(Console, &UpdateRect);
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
|
|
|
|
Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2005-08-07 08:06:56 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
}
|
|
|
|
if (Request->Data.WriteConsoleRequest.Unicode)
|
|
|
|
{
|
2005-08-07 23:37:59 +00:00
|
|
|
RtlFreeHeap(GetProcessHeap(), 0, tmpString);
|
2005-08-07 08:06:56 +00:00
|
|
|
}
|
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrFillOutputChar)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-11-02 20:42:06 +00:00
|
|
|
DWORD X, Y, Length, Written = 0;
|
2004-12-25 11:22:37 +00:00
|
|
|
CHAR Char;
|
2004-01-11 17:31:16 +00:00
|
|
|
PBYTE Buffer;
|
|
|
|
RECT UpdateRect;
|
|
|
|
|
|
|
|
DPRINT("CsrFillOutputChar\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
X = Request->Data.FillOutputRequest.Position.X;
|
|
|
|
Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY;
|
2004-01-11 17:31:16 +00:00
|
|
|
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
|
2004-11-02 20:42:06 +00:00
|
|
|
if(Request->Data.FillOutputRequest.Unicode)
|
|
|
|
ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
|
|
|
|
else
|
|
|
|
Char = Request->Data.FillOutputRequest.Char.AsciiChar;
|
2004-01-11 17:31:16 +00:00
|
|
|
Length = Request->Data.FillOutputRequest.Length;
|
|
|
|
while (Length--)
|
|
|
|
{
|
2003-03-21 20:17:55 +00:00
|
|
|
*Buffer = Char;
|
|
|
|
Buffer += 2;
|
2004-11-02 20:42:06 +00:00
|
|
|
Written++;
|
2004-01-11 17:31:16 +00:00
|
|
|
if (++X == Buff->MaxX)
|
|
|
|
{
|
|
|
|
if (++Y == Buff->MaxY)
|
|
|
|
{
|
|
|
|
Y = 0;
|
|
|
|
Buffer = Buff->Buffer;
|
|
|
|
}
|
|
|
|
X = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position,
|
|
|
|
Request->Data.FillOutputRequest.Length);
|
|
|
|
ConioDrawRegion(Console, &UpdateRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2005-08-26 20:35:33 +00:00
|
|
|
Length = Request->Data.FillOutputRequest.Length;
|
|
|
|
Request->Data.FillOutputRequest.NrCharactersWritten = Length;
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrReadInputEvent)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN Done = FALSE;
|
|
|
|
ConsoleInput *Input;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrReadInputEvent\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* only get input if there is any */
|
2004-11-14 18:47:10 +00:00
|
|
|
CurrentEntry = Console->InputEvents.Flink;
|
|
|
|
while (CurrentEntry != &Console->InputEvents)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
2004-11-14 18:47:10 +00:00
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2004-11-14 18:47:10 +00:00
|
|
|
if (Done && !Input->Fake)
|
2004-08-22 20:52:28 +00:00
|
|
|
{
|
2006-07-16 17:00:39 +00:00
|
|
|
Request->Data.ReadInputRequest.MoreEvents = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-14 18:47:10 +00:00
|
|
|
RemoveEntryList(&Input->ListEntry);
|
|
|
|
|
|
|
|
if (!Done && !Input->Fake)
|
|
|
|
{
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadInputRequest.Input = Input->InputEvent;
|
2004-11-14 18:47:10 +00:00
|
|
|
if (Request->Data.ReadInputRequest.Unicode == FALSE)
|
|
|
|
{
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
|
2004-11-14 18:47:10 +00:00
|
|
|
}
|
2006-07-16 17:00:39 +00:00
|
|
|
Done = TRUE;
|
|
|
|
}
|
2004-08-22 20:52:28 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Input->InputEvent.EventType == KEY_EVENT)
|
|
|
|
{
|
|
|
|
if (0 != (Console->Mode & ENABLE_LINE_INPUT)
|
2006-07-16 17:00:39 +00:00
|
|
|
&& Input->InputEvent.Event.KeyEvent.bKeyDown
|
|
|
|
&& '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Console->WaitingLines--;
|
|
|
|
}
|
|
|
|
Console->WaitingChars--;
|
|
|
|
}
|
|
|
|
HeapFree(Win32CsrApiHeap, 0, Input);
|
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-14 18:47:10 +00:00
|
|
|
if (Done)
|
|
|
|
{
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
Console->EarlyReturn = FALSE;
|
|
|
|
}
|
|
|
|
else
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Status = STATUS_PENDING;
|
|
|
|
Console->EarlyReturn = TRUE; /* mark for early return */
|
|
|
|
}
|
|
|
|
|
2004-11-14 18:47:10 +00:00
|
|
|
if (IsListEmpty(&Console->InputEvents))
|
|
|
|
{
|
|
|
|
ResetEvent(Console->ActiveEvent);
|
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrWriteConsoleOutputAttrib)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2003-12-02 11:38:47 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2005-08-26 20:35:33 +00:00
|
|
|
PUCHAR Buffer;
|
|
|
|
PWORD Attribute;
|
2003-12-02 11:38:47 +00:00
|
|
|
int X, Y, Length;
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
RECT UpdateRect;
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
DPRINT("CsrWriteConsoleOutputAttrib\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Request->Header.u1.s1.TotalLength
|
|
|
|
< CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
|
|
|
|
+ Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Invalid request size\n");
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status = ConioLockScreenBuffer(ProcessData,
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Buff,
|
|
|
|
GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
|
|
|
|
Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
|
2003-12-02 11:38:47 +00:00
|
|
|
Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
|
|
|
|
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
|
2005-08-26 20:35:33 +00:00
|
|
|
Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute;
|
2003-12-02 11:38:47 +00:00
|
|
|
while (Length--)
|
|
|
|
{
|
2005-08-26 20:35:33 +00:00
|
|
|
*Buffer = (UCHAR)(*Attribute++);
|
2003-03-21 20:17:55 +00:00
|
|
|
Buffer += 2;
|
2004-01-11 17:31:16 +00:00
|
|
|
if (++X == Buff->MaxX)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
if (++Y == Buff->MaxY)
|
|
|
|
{
|
|
|
|
Y = 0;
|
|
|
|
Buffer = Buff->Buffer + 1;
|
|
|
|
}
|
|
|
|
X = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord,
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.Length);
|
|
|
|
ConioDrawRegion(Console, &UpdateRect);
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-12-02 11:38:47 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
|
|
|
|
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrFillOutputAttrib)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-12-25 11:22:37 +00:00
|
|
|
PUCHAR Buffer;
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
int X, Y, Length;
|
|
|
|
UCHAR Attr;
|
|
|
|
RECT UpdateRect;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
|
|
|
|
DPRINT("CsrFillOutputAttrib\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
X = Request->Data.FillOutputAttribRequest.Coord.X;
|
|
|
|
Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
|
2004-01-11 17:31:16 +00:00
|
|
|
Length = Request->Data.FillOutputAttribRequest.Length;
|
|
|
|
Attr = Request->Data.FillOutputAttribRequest.Attribute;
|
|
|
|
Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1];
|
|
|
|
while (Length--)
|
|
|
|
{
|
2003-03-21 20:17:55 +00:00
|
|
|
*Buffer = Attr;
|
|
|
|
Buffer += 2;
|
2004-01-11 17:31:16 +00:00
|
|
|
if (++X == Buff->MaxX)
|
|
|
|
{
|
|
|
|
if (++Y == Buff->MaxY)
|
|
|
|
{
|
|
|
|
Y = 0;
|
|
|
|
Buffer = Buff->Buffer + 1;
|
|
|
|
}
|
|
|
|
X = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord,
|
|
|
|
Request->Data.FillOutputAttribRequest.Length);
|
|
|
|
ConioDrawRegion(Console, &UpdateRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrGetCursorInfo)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
NTSTATUS Status;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrGetCursorInfo\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2006-09-06 19:37:53 +00:00
|
|
|
Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible;
|
|
|
|
Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize;
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetCursorInfo)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2003-10-20 18:02:04 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-01-11 17:31:16 +00:00
|
|
|
DWORD Size;
|
|
|
|
BOOL Visible;
|
2003-10-20 18:02:04 +00:00
|
|
|
NTSTATUS Status;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrSetCursorInfo\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
|
|
|
|
Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
|
|
|
|
if (Size < 1)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
Size = 1;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
if (100 < Size)
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
Size = 100;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
if (Size != Buff->CursorInfo.dwSize
|
|
|
|
|| (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
Buff->CursorInfo.dwSize = Size;
|
|
|
|
Buff->CursorInfo.bVisible = Visible;
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (! ConioSetCursorInfo(Console, Buff))
|
2003-10-20 18:02:04 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2003-10-20 18:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetTextAttrib)
|
2000-05-26 05:43:33 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrSetTextAttrib\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2007-10-20 22:26:58 +00:00
|
|
|
if (! ConioUpdateScreenInfo(Console, Buff))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-05-26 05:43:33 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetConsoleMode)
|
2000-07-11 04:09:25 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
|
|
|
|
DPRINT("CsrSetConsoleMode\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = Win32CsrGetObject(ProcessData,
|
|
|
|
Request->Data.SetConsoleModeRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
(Object_t **) &Console, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Buff = (PCSRSS_SCREEN_BUFFER)Console;
|
|
|
|
if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
|
|
|
|
{
|
2001-01-21 00:11:54 +00:00
|
|
|
Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
|
|
|
|
{
|
2001-01-21 00:11:54 +00:00
|
|
|
Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-22 00:33:42 +00:00
|
|
|
Status = STATUS_INVALID_HANDLE;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-07-22 00:33:42 +00:00
|
|
|
Win32CsrReleaseObjectByPointer((Object_t *)Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2000-07-11 04:09:25 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrGetConsoleMode)
|
2000-07-11 04:09:25 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */
|
|
|
|
|
|
|
|
DPRINT("CsrGetConsoleMode\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
(Object_t **) &Console, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
Buff = (PCSRSS_SCREEN_BUFFER) Console;
|
|
|
|
if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
|
|
|
|
{
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
|
|
|
|
{
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_INVALID_HANDLE;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-07-22 00:33:42 +00:00
|
|
|
Win32CsrReleaseObjectByPointer((Object_t *)Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2000-07-11 04:09:25 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrCreateScreenBuffer)
|
2001-01-21 00:11:54 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
NTSTATUS Status;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrCreateScreenBuffer\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2003-03-09 21:40:19 +00:00
|
|
|
|
2006-07-12 21:06:21 +00:00
|
|
|
Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2006-07-12 21:06:21 +00:00
|
|
|
if (Buff != NULL)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2006-07-12 21:06:21 +00:00
|
|
|
if (Console->ActiveBuffer)
|
|
|
|
{
|
|
|
|
Buff->MaxX = Console->ActiveBuffer->MaxX;
|
2006-07-16 17:00:39 +00:00
|
|
|
Buff->MaxY = Console->ActiveBuffer->MaxY;
|
2006-09-06 19:37:53 +00:00
|
|
|
Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible;
|
|
|
|
Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Buff->CursorInfo.bVisible = TRUE;
|
2009-02-11 16:39:33 +00:00
|
|
|
Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
|
2006-07-12 21:06:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Buff->MaxX == 0)
|
2006-09-06 19:37:53 +00:00
|
|
|
{
|
|
|
|
Buff->MaxX = 80;
|
|
|
|
}
|
2006-07-12 21:06:21 +00:00
|
|
|
|
|
|
|
if (Buff->MaxY == 0)
|
2006-09-06 19:37:53 +00:00
|
|
|
{
|
|
|
|
Buff->MaxY = 25;
|
|
|
|
}
|
2006-07-12 21:06:21 +00:00
|
|
|
|
|
|
|
Status = CsrInitConsoleScreenBuffer(Console, Buff);
|
2008-08-02 22:09:22 +00:00
|
|
|
if(NT_SUCCESS(Status))
|
2006-07-12 21:06:21 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = Win32CsrInsertObject(ProcessData,
|
2008-07-22 17:37:13 +00:00
|
|
|
&Request->Data.CreateScreenBufferRequest.OutputHandle,
|
|
|
|
&Buff->Header,
|
|
|
|
Request->Data.CreateScreenBufferRequest.Access,
|
|
|
|
Request->Data.CreateScreenBufferRequest.Inheritable);
|
2006-07-12 21:06:21 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2001-01-21 00:11:54 +00:00
|
|
|
}
|
2000-07-11 04:09:25 +00:00
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetScreenBuffer)
|
2001-01-21 00:11:54 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrSetScreenBuffer\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Buff == Console->ActiveBuffer)
|
|
|
|
{
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* drop reference to old buffer, maybe delete */
|
|
|
|
if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
|
|
|
|
{
|
|
|
|
ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
|
|
|
|
}
|
|
|
|
/* tie console to new buffer */
|
|
|
|
Console->ActiveBuffer = Buff;
|
|
|
|
/* inc ref count on new buffer */
|
|
|
|
InterlockedIncrement(&Buff->Header.ReferenceCount);
|
|
|
|
/* Redraw the console */
|
|
|
|
ConioDrawConsole(Console);
|
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-01-21 00:11:54 +00:00
|
|
|
}
|
2001-06-22 02:11:44 +00:00
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
CSR_API(CsrSetTitle)
|
2001-06-22 02:11:44 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
2005-08-28 12:03:25 +00:00
|
|
|
PWCHAR Buffer;
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrSetTitle\n");
|
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Request->Header.u1.s1.TotalLength
|
|
|
|
< CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE)
|
2004-01-11 17:31:16 +00:00
|
|
|
+ Request->Data.SetTitleRequest.Length)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid request size\n");
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-08-02 22:09:22 +00:00
|
|
|
if(NT_SUCCESS(Status))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2005-08-28 12:03:25 +00:00
|
|
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
|
|
|
|
if (Buffer)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2005-08-28 12:03:25 +00:00
|
|
|
/* copy title to console */
|
|
|
|
RtlFreeUnicodeString(&Console->Title);
|
|
|
|
Console->Title.Buffer = Buffer;
|
|
|
|
Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
|
|
|
|
memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
|
|
|
|
if (! ConioChangeTitle(Console))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
2005-08-28 12:03:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
2005-08-28 12:03:25 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_NO_MEMORY;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrGetTitle)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
2005-08-28 12:03:25 +00:00
|
|
|
DWORD Length;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrGetTitle\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Can't get console\n");
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
/* Copy title of the console to the user title buffer */
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE));
|
|
|
|
Request->Data.GetTitleRequest.Length = Console->Title.Length;
|
2005-09-09 12:22:01 +00:00
|
|
|
memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer,
|
|
|
|
Console->Title.Length);
|
2005-08-28 12:03:25 +00:00
|
|
|
Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Length > sizeof(CSR_API_MESSAGE))
|
|
|
|
{
|
|
|
|
Request->Header.u1.s1.TotalLength = Length;
|
|
|
|
Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
|
|
|
|
}
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrWriteConsoleOutput)
|
|
|
|
{
|
|
|
|
SHORT i, X, Y, SizeX, SizeY;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
RECT ScreenBuffer;
|
|
|
|
CHAR_INFO* CurCharInfo;
|
|
|
|
RECT WriteRegion;
|
|
|
|
CHAR_INFO* CharInfo;
|
|
|
|
COORD BufferCoord;
|
|
|
|
COORD BufferSize;
|
|
|
|
NTSTATUS Status;
|
2008-07-27 20:08:18 +00:00
|
|
|
PBYTE Ptr;
|
2004-01-11 17:31:16 +00:00
|
|
|
DWORD PSize;
|
|
|
|
|
|
|
|
DPRINT("CsrWriteConsoleOutput\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData,
|
|
|
|
Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Buff,
|
|
|
|
GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
|
|
|
|
PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
|
|
|
|
BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
|
|
|
|
CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo;
|
|
|
|
if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) ||
|
2005-07-05 00:57:47 +00:00
|
|
|
(((ULONG_PTR)CharInfo + PSize) >
|
|
|
|
((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
|
|
|
|
WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top;
|
|
|
|
WriteRegion.right = Request->Data.WriteConsoleOutputRequest.WriteRegion.Right;
|
|
|
|
WriteRegion.bottom = Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom;
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2005-07-01 01:54:55 +00:00
|
|
|
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));
|
|
|
|
SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion));
|
2004-01-11 17:31:16 +00:00
|
|
|
WriteRegion.bottom = WriteRegion.top + SizeY - 1;
|
|
|
|
WriteRegion.right = WriteRegion.left + SizeX - 1;
|
|
|
|
|
|
|
|
/* Make sure WriteRegion is inside the screen buffer */
|
|
|
|
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
|
|
|
|
if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
|
|
|
/* It is okay to have a WriteRegion completely outside the screen buffer.
|
|
|
|
No data is written then. */
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
|
|
|
|
for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr = ConioCoordToPointer(Buff, WriteRegion.left, Y);
|
2004-01-11 17:31:16 +00:00
|
|
|
for (X = WriteRegion.left; X <= WriteRegion.right; X++)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
CHAR AsciiChar;
|
2004-08-22 20:52:28 +00:00
|
|
|
if (Request->Data.WriteConsoleOutputRequest.Unicode)
|
|
|
|
{
|
2004-11-02 20:42:06 +00:00
|
|
|
ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
AsciiChar = CurCharInfo->Char.AsciiChar;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2008-07-27 20:08:18 +00:00
|
|
|
*Ptr++ = AsciiChar;
|
|
|
|
*Ptr++ = CurCharInfo->Attributes;
|
2004-01-11 17:31:16 +00:00
|
|
|
CurCharInfo++;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioDrawRegion(Console, &WriteRegion);
|
2001-06-22 02:11:44 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
|
|
|
ConioUnlockConsole(Console);
|
2001-08-14 12:57:16 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1;
|
|
|
|
Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
|
|
|
|
Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left;
|
|
|
|
Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrFlushInputBuffer)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
ConsoleInput* Input;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrFlushInputBuffer\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioLockConsole(ProcessData,
|
|
|
|
Request->Data.FlushInputBufferRequest.ConsoleInput,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Console,
|
|
|
|
GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if(! NT_SUCCESS(Status))
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Discard all entries in the input event queue */
|
2003-02-24 23:17:32 +00:00
|
|
|
while (!IsListEmpty(&Console->InputEvents))
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2003-02-24 23:17:32 +00:00
|
|
|
CurrentEntry = RemoveHeadList(&Console->InputEvents);
|
|
|
|
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
|
|
|
/* Destroy the event */
|
2004-01-11 17:31:16 +00:00
|
|
|
HeapFree(Win32CsrApiHeap, 0, Input);
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
2004-11-14 18:47:10 +00:00
|
|
|
ResetEvent(Console->ActiveEvent);
|
2003-02-24 23:17:32 +00:00
|
|
|
Console->WaitingChars=0;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrScrollConsoleScreenBuffer)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2001-09-01 15:36:45 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT ScreenBuffer;
|
|
|
|
RECT SrcRegion;
|
|
|
|
RECT DstRegion;
|
2008-06-27 12:34:08 +00:00
|
|
|
RECT UpdateRegion;
|
2004-01-11 17:31:16 +00:00
|
|
|
RECT ScrollRectangle;
|
|
|
|
RECT ClipRectangle;
|
2001-09-01 15:36:45 +00:00
|
|
|
NTSTATUS Status;
|
2006-11-30 16:48:13 +00:00
|
|
|
HANDLE ConsoleHandle;
|
|
|
|
BOOLEAN UseClipRectangle;
|
|
|
|
COORD DestinationOrigin;
|
|
|
|
CHAR_INFO Fill;
|
2008-06-27 12:34:08 +00:00
|
|
|
CHAR FillChar;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrScrollConsoleScreenBuffer\n");
|
|
|
|
|
2006-11-30 16:48:13 +00:00
|
|
|
ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle;
|
|
|
|
UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle;
|
|
|
|
DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
|
|
|
|
Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
|
|
|
|
ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
|
|
|
|
ScrollRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right;
|
|
|
|
ScrollRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
|
|
|
/* Make sure source rectangle is inside the screen buffer */
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
|
|
|
|
if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
/* If the source was clipped on the left or top, adjust the destination accordingly */
|
|
|
|
if (ScrollRectangle.left < 0)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
DestinationOrigin.X -= ScrollRectangle.left;
|
|
|
|
}
|
|
|
|
if (ScrollRectangle.top < 0)
|
|
|
|
{
|
|
|
|
DestinationOrigin.Y -= ScrollRectangle.top;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
if (UseClipRectangle)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
ClipRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left;
|
|
|
|
ClipRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top;
|
|
|
|
ClipRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right;
|
|
|
|
ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
|
|
|
|
if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
|
2007-06-16 08:27:02 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-06-27 12:34:08 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2008-06-27 12:34:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ClipRectangle = ScreenBuffer;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
ConioInitRect(&DstRegion,
|
|
|
|
DestinationOrigin.Y,
|
|
|
|
DestinationOrigin.X,
|
|
|
|
DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
|
|
|
|
DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode)
|
|
|
|
ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
|
|
|
|
else
|
|
|
|
FillChar = Fill.Char.AsciiChar;
|
2001-09-01 15:36:45 +00:00
|
|
|
|
2008-06-27 12:34:08 +00:00
|
|
|
ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar);
|
2001-09-01 15:36:45 +00:00
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
if (Buff == Console->ActiveBuffer)
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion);
|
|
|
|
if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle))
|
2001-09-01 15:36:45 +00:00
|
|
|
{
|
2008-06-27 12:34:08 +00:00
|
|
|
/* Draw update region */
|
|
|
|
ConioDrawRegion(Console, &UpdateRegion);
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2002-08-22 15:21:57 +00:00
|
|
|
|
|
|
|
CSR_API(CsrReadConsoleOutputChar)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2004-11-02 20:42:06 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2002-08-22 15:21:57 +00:00
|
|
|
DWORD Xpos, Ypos;
|
2004-12-25 11:22:37 +00:00
|
|
|
PCHAR ReadBuffer;
|
2002-08-22 15:21:57 +00:00
|
|
|
DWORD i;
|
2004-11-02 20:42:06 +00:00
|
|
|
ULONG CharSize;
|
|
|
|
CHAR Char;
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrReadConsoleOutputChar\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-11-02 20:42:06 +00:00
|
|
|
}
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2002-08-22 15:21:57 +00:00
|
|
|
{
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2002-08-22 15:21:57 +00:00
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
|
|
|
|
Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
|
2002-08-22 15:21:57 +00:00
|
|
|
|
|
|
|
for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
|
|
|
|
{
|
2004-11-02 20:42:06 +00:00
|
|
|
Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-11-02 20:42:06 +00:00
|
|
|
if(Request->Data.ReadConsoleOutputCharRequest.Unicode)
|
|
|
|
{
|
|
|
|
ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
|
|
|
|
ReadBuffer += sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*(ReadBuffer++) = Char;
|
2002-08-22 15:21:57 +00:00
|
|
|
|
|
|
|
Xpos++;
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Xpos == Buff->MaxX)
|
2006-07-16 17:00:39 +00:00
|
|
|
{
|
|
|
|
Xpos = 0;
|
|
|
|
Ypos++;
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2006-07-16 17:00:39 +00:00
|
|
|
if (Ypos == Buff->MaxY)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Ypos = 0;
|
|
|
|
}
|
2006-07-16 17:00:39 +00:00
|
|
|
}
|
2002-08-22 15:21:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*ReadBuffer = 0;
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos;
|
|
|
|
Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
|
2005-08-28 12:03:25 +00:00
|
|
|
if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
|
|
|
|
{
|
|
|
|
Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR);
|
|
|
|
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
|
|
|
}
|
2002-08-22 15:21:57 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-09-01 15:36:45 +00:00
|
|
|
}
|
|
|
|
|
2002-10-20 00:34:40 +00:00
|
|
|
|
|
|
|
CSR_API(CsrReadConsoleOutputAttrib)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
2002-10-20 00:34:40 +00:00
|
|
|
DWORD Xpos, Ypos;
|
2005-08-26 20:35:33 +00:00
|
|
|
PWORD ReadBuffer;
|
2002-10-20 00:34:40 +00:00
|
|
|
DWORD i;
|
2005-08-28 12:03:25 +00:00
|
|
|
DWORD CurrentLength;
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrReadConsoleOutputAttrib\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
2005-08-26 20:35:33 +00:00
|
|
|
ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute;
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2002-10-20 00:34:40 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2002-10-20 00:34:40 +00:00
|
|
|
}
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X;
|
|
|
|
Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
|
2002-10-20 00:34:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
*ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1];
|
2002-10-20 00:34:40 +00:00
|
|
|
|
|
|
|
ReadBuffer++;
|
|
|
|
Xpos++;
|
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Xpos == Buff->MaxX)
|
|
|
|
{
|
|
|
|
Xpos = 0;
|
|
|
|
Ypos++;
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (Ypos == Buff->MaxY)
|
|
|
|
{
|
|
|
|
Ypos = 0;
|
|
|
|
}
|
|
|
|
}
|
2002-10-20 00:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*ReadBuffer = 0;
|
|
|
|
|
Clean up console code a bit:
- Get/SetConsoleTitle: Get rid of unnecessary handle creation; instead, just have csrss get the console from the ProcessData.
- Instead of using ShowX/ShowY to store the origin of the buffer, use the VirtualX member that was put there for this purpose. Rename it to VirtualY, though, since it's a row number. ShowX/ShowY should hold the position of the visible window, once that's implemented.
- From the CSRSS_CONSOLE structure: remove hActiveBuffer (redundant), CodePageId (unused), and hWindowIcon (only used as a temporary)
- Make cursor coordinates be "logical", not "physical". This simplifies various things.
- ConioConsoleFromProcessData: If process has no console, return STATUS_INVALID_HANDLE; don't pretend to succeed (causing many functions to access memory around address 0, which is probably not a good thing). Remove various Console != NULL checks which are now unnecessary.
svn path=/trunk/; revision=34568
2008-07-17 21:53:39 +00:00
|
|
|
Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos;
|
|
|
|
Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
|
|
|
|
+ Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD);
|
|
|
|
if (CurrentLength > sizeof(CSR_API_MESSAGE))
|
|
|
|
{
|
|
|
|
Request->Header.u1.s1.TotalLength = CurrentLength;
|
|
|
|
Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE);
|
|
|
|
}
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-10-20 00:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CSR_API(CsrGetNumberOfConsoleInputEvents)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PLIST_ENTRY CurrentItem;
|
|
|
|
DWORD NumEvents;
|
2004-02-27 17:35:42 +00:00
|
|
|
ConsoleInput *Input;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2003-10-20 18:02:04 +00:00
|
|
|
DPRINT("CsrGetNumberOfConsoleInputEvents\n");
|
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
2002-10-20 00:34:40 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2002-10-20 00:34:40 +00:00
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2002-10-20 00:34:40 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-02-27 17:35:42 +00:00
|
|
|
CurrentItem = Console->InputEvents.Flink;
|
2002-10-20 00:34:40 +00:00
|
|
|
NumEvents = 0;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
/* If there are any events ... */
|
2004-02-27 17:35:42 +00:00
|
|
|
while (CurrentItem != &Console->InputEvents)
|
2002-10-20 00:34:40 +00:00
|
|
|
{
|
2004-02-27 17:35:42 +00:00
|
|
|
Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
|
|
|
|
CurrentItem = CurrentItem->Flink;
|
|
|
|
if (!Input->Fake)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2004-02-27 17:35:42 +00:00
|
|
|
NumEvents++;
|
2006-07-16 17:00:39 +00:00
|
|
|
}
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-10-20 00:34:40 +00:00
|
|
|
}
|
|
|
|
|
2002-10-29 03:49:32 +00:00
|
|
|
|
|
|
|
CSR_API(CsrPeekConsoleInput)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
DWORD Size;
|
|
|
|
DWORD Length;
|
|
|
|
PLIST_ENTRY CurrentItem;
|
|
|
|
PINPUT_RECORD InputRecord;
|
|
|
|
ConsoleInput* Item;
|
|
|
|
UINT NumItems;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrPeekConsoleInput\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if(! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
|
|
|
|
Length = Request->Data.PeekConsoleInputRequest.Length;
|
|
|
|
Size = Length * sizeof(INPUT_RECORD);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
|
2005-07-05 00:57:47 +00:00
|
|
|
|| (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
NumItems = 0;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! IsListEmpty(&Console->InputEvents))
|
|
|
|
{
|
2004-08-22 20:52:28 +00:00
|
|
|
CurrentItem = Console->InputEvents.Flink;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
while (CurrentItem != &Console->InputEvents && NumItems < Length)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
|
2004-08-22 20:52:28 +00:00
|
|
|
|
|
|
|
if (Item->Fake)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2004-08-22 20:52:28 +00:00
|
|
|
CurrentItem = CurrentItem->Flink;
|
|
|
|
continue;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
++NumItems;
|
|
|
|
*InputRecord = Item->InputEvent;
|
|
|
|
|
|
|
|
if (Request->Data.ReadInputRequest.Unicode == FALSE)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioInputEventToAnsi(Console, InputRecord);
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
InputRecord++;
|
|
|
|
CurrentItem = CurrentItem->Flink;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
}
|
2002-10-29 03:49:32 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.PeekConsoleInputRequest.Length = NumItems;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-10-29 03:49:32 +00:00
|
|
|
}
|
|
|
|
|
2002-11-12 00:48:26 +00:00
|
|
|
|
|
|
|
CSR_API(CsrReadConsoleOutput)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCHAR_INFO CharInfo;
|
|
|
|
PCHAR_INFO CurCharInfo;
|
|
|
|
PCSRSS_SCREEN_BUFFER Buff;
|
|
|
|
DWORD Size;
|
|
|
|
DWORD Length;
|
|
|
|
DWORD SizeX, SizeY;
|
|
|
|
NTSTATUS Status;
|
|
|
|
COORD BufferSize;
|
|
|
|
COORD BufferCoord;
|
|
|
|
RECT ReadRegion;
|
|
|
|
RECT ScreenRect;
|
2008-07-27 20:08:18 +00:00
|
|
|
DWORD i;
|
|
|
|
PBYTE Ptr;
|
2005-07-05 22:35:29 +00:00
|
|
|
LONG X, Y;
|
2004-08-22 20:52:28 +00:00
|
|
|
UINT CodePage;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrReadConsoleOutput\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo;
|
|
|
|
ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left;
|
|
|
|
ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top;
|
|
|
|
ReadRegion.right = Request->Data.ReadConsoleOutputRequest.ReadRegion.Right;
|
|
|
|
ReadRegion.bottom = Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom;
|
|
|
|
BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize;
|
|
|
|
BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
|
|
|
|
Length = BufferSize.X * BufferSize.Y;
|
|
|
|
Size = Length * sizeof(CHAR_INFO);
|
2004-08-22 20:52:28 +00:00
|
|
|
|
|
|
|
/* FIXME: Is this correct? */
|
|
|
|
CodePage = ProcessData->Console->OutputCodePage;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
|
2005-07-05 00:57:47 +00:00
|
|
|
|| (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-07-01 01:54:55 +00:00
|
|
|
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion));
|
|
|
|
SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion));
|
2004-01-11 17:31:16 +00:00
|
|
|
ReadRegion.bottom = ReadRegion.top + SizeY;
|
|
|
|
ReadRegion.right = ReadRegion.left + SizeX;
|
|
|
|
|
|
|
|
ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
|
|
|
|
if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
|
|
|
|
{
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y)
|
|
|
|
{
|
|
|
|
CurCharInfo = CharInfo + (i * BufferSize.X);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-27 20:08:18 +00:00
|
|
|
Ptr = ConioCoordToPointer(Buff, ReadRegion.left, Y);
|
2004-01-11 17:31:16 +00:00
|
|
|
for (X = ReadRegion.left; X < ReadRegion.right; ++X)
|
|
|
|
{
|
2004-08-22 20:52:28 +00:00
|
|
|
if (Request->Data.ReadConsoleOutputRequest.Unicode)
|
|
|
|
{
|
|
|
|
MultiByteToWideChar(CodePage, 0,
|
2008-07-27 20:08:18 +00:00
|
|
|
(PCHAR)Ptr++, 1,
|
2004-08-22 20:52:28 +00:00
|
|
|
&CurCharInfo->Char.UnicodeChar, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-27 20:08:18 +00:00
|
|
|
CurCharInfo->Char.AsciiChar = *Ptr++;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2008-07-27 20:08:18 +00:00
|
|
|
CurCharInfo->Attributes = *Ptr++;
|
2004-01-11 17:31:16 +00:00
|
|
|
++CurCharInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockScreenBuffer(Buff);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1;
|
|
|
|
Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1;
|
|
|
|
Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left;
|
|
|
|
Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-11-12 00:48:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CSR_API(CsrWriteConsoleInput)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PINPUT_RECORD InputRecord;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
DWORD Length;
|
|
|
|
DWORD Size;
|
|
|
|
DWORD i;
|
|
|
|
ConsoleInput* Record;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrWriteConsoleInput\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2008-07-23 16:21:46 +00:00
|
|
|
Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
|
|
|
|
Length = Request->Data.WriteConsoleInputRequest.Length;
|
|
|
|
Size = Length * sizeof(INPUT_RECORD);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase)
|
2005-07-05 00:57:47 +00:00
|
|
|
|| (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_ACCESS_VIOLATION;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
for (i = 0; i < Length; i++)
|
|
|
|
{
|
|
|
|
Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
|
|
|
|
if (NULL == Record)
|
|
|
|
{
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-10-09 06:13:05 +00:00
|
|
|
|
|
|
|
Record->Echoed = FALSE;
|
|
|
|
Record->Fake = FALSE;
|
2006-07-16 17:00:39 +00:00
|
|
|
//Record->InputEvent = *InputRecord++;
|
|
|
|
memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD));
|
2004-01-11 17:31:16 +00:00
|
|
|
if (KEY_EVENT == Record->InputEvent.EventType)
|
|
|
|
{
|
2004-11-02 20:42:06 +00:00
|
|
|
/* FIXME - convert from unicode to ascii!! */
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioProcessChar(Console, Record);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.WriteConsoleInputRequest.Length = i;
|
2004-01-11 17:31:16 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-11-12 00:48:26 +00:00
|
|
|
}
|
|
|
|
|
2003-06-19 19:38:26 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* HardwareStateProperty
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* Set/Get the value of the HardwareState and switch
|
|
|
|
* between direct video buffer ouput and GDI windowed
|
|
|
|
* output.
|
|
|
|
* ARGUMENTS
|
|
|
|
* Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
* object. We use the same object to Request.
|
2003-06-19 19:38:26 +00:00
|
|
|
* NOTE
|
|
|
|
* ConsoleHwState has the correct size to be compatible
|
|
|
|
* with NT's, but values are not.
|
|
|
|
*/
|
2005-11-22 03:18:13 +00:00
|
|
|
static NTSTATUS FASTCALL
|
2004-01-11 17:31:16 +00:00
|
|
|
SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
|
2003-06-19 19:38:26 +00:00
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
|
2003-07-29 23:03:01 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
|
2003-06-19 19:38:26 +00:00
|
|
|
||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
2003-06-19 19:38:26 +00:00
|
|
|
if (Console->HardwareState != ConsoleHwState)
|
2004-01-11 17:31:16 +00:00
|
|
|
{
|
|
|
|
/* TODO: implement switching from full screen to windowed mode */
|
|
|
|
/* TODO: or back; now simply store the hardware state */
|
|
|
|
Console->HardwareState = ConsoleHwState;
|
|
|
|
}
|
|
|
|
|
2005-05-08 04:07:56 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
|
2003-06-19 19:38:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrHardwareStateProperty)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrHardwareStateProperty\n");
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
Status = ConioLockConsole(ProcessData,
|
|
|
|
Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
|
2008-07-23 16:21:46 +00:00
|
|
|
&Console,
|
|
|
|
GENERIC_READ);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
|
|
|
|
{
|
|
|
|
case CONSOLE_HARDWARE_STATE_GET:
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState;
|
2004-01-11 17:31:16 +00:00
|
|
|
break;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
case CONSOLE_HARDWARE_STATE_SET:
|
|
|
|
DPRINT("Setting console hardware state.\n");
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
|
2004-01-11 17:31:16 +00:00
|
|
|
break;
|
2003-06-19 19:38:26 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
default:
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
|
2004-01-11 17:31:16 +00:00
|
|
|
break;
|
|
|
|
}
|
2003-06-19 19:38:26 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-06-19 19:38:26 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2003-06-19 19:38:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrGetConsoleWindow)
|
|
|
|
{
|
2004-01-11 17:31:16 +00:00
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
2003-10-20 18:02:04 +00:00
|
|
|
|
2004-01-11 17:31:16 +00:00
|
|
|
DPRINT("CsrGetConsoleWindow\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2004-01-11 17:31:16 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-01-11 17:31:16 +00:00
|
|
|
}
|
2003-06-19 19:38:26 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
|
2004-01-11 17:31:16 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2003-06-19 19:38:26 +00:00
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2003-06-19 19:38:26 +00:00
|
|
|
}
|
|
|
|
|
2004-03-14 17:53:27 +00:00
|
|
|
CSR_API(CsrSetConsoleIcon)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrSetConsoleIcon\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
2004-03-14 17:53:27 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-03-14 17:53:27 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
|
|
|
|
? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
2004-03-14 17:53:27 +00:00
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-03-14 17:53:27 +00:00
|
|
|
}
|
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
CSR_API(CsrGetConsoleCodePage)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrGetConsoleCodePage\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrSetConsoleCodePage)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrSetConsoleCodePage\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2009-04-13 17:13:35 +00:00
|
|
|
|
|
|
|
if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
|
2004-08-22 20:52:28 +00:00
|
|
|
{
|
|
|
|
Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2009-04-13 17:13:35 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2009-04-13 17:13:35 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrGetConsoleOutputCodePage)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrGetConsoleOutputCodePage\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSR_API(CsrSetConsoleOutputCodePage)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrSetConsoleOutputCodePage\n");
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-16 23:05:33 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2009-04-13 17:13:35 +00:00
|
|
|
|
|
|
|
if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
|
2004-08-22 20:52:28 +00:00
|
|
|
{
|
|
|
|
Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
|
|
|
|
ConioUnlockConsole(Console);
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
2009-04-13 17:13:35 +00:00
|
|
|
|
2004-08-22 20:52:28 +00:00
|
|
|
ConioUnlockConsole(Console);
|
2009-04-13 17:13:35 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2004-08-22 20:52:28 +00:00
|
|
|
}
|
|
|
|
|
2005-02-05 01:44:05 +00:00
|
|
|
CSR_API(CsrGetProcessList)
|
|
|
|
{
|
|
|
|
PHANDLE Buffer;
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_PROCESS_DATA current;
|
|
|
|
PLIST_ENTRY current_entry;
|
2005-08-28 12:03:25 +00:00
|
|
|
ULONG nItems, nCopied, Length;
|
2005-02-05 01:44:05 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("CsrGetProcessList\n");
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Buffer = Request->Data.GetProcessListRequest.ProcessId;
|
2005-08-11 02:58:54 +00:00
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
2005-08-28 12:03:25 +00:00
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-02-05 01:44:05 +00:00
|
|
|
nItems = nCopied = 0;
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetProcessListRequest.nProcessIdsCopied = 0;
|
|
|
|
Request->Data.GetProcessListRequest.nProcessIdsTotal = 0;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-02-05 01:44:05 +00:00
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2005-02-05 01:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT1("Console_Api Ctrl-C\n");
|
|
|
|
|
|
|
|
for(current_entry = Console->ProcessList.Flink;
|
|
|
|
current_entry != &Console->ProcessList;
|
|
|
|
current_entry = current_entry->Flink)
|
|
|
|
{
|
|
|
|
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
|
2006-09-06 19:37:53 +00:00
|
|
|
if(++nItems < Request->Data.GetProcessListRequest.nMaxIds)
|
2005-02-05 01:44:05 +00:00
|
|
|
{
|
|
|
|
*(Buffer++) = current->ProcessId;
|
|
|
|
nCopied++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied;
|
|
|
|
Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-08-28 12:03:25 +00:00
|
|
|
Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE);
|
|
|
|
if (Length > sizeof(CSR_API_MESSAGE))
|
|
|
|
{
|
|
|
|
Request->Header.u1.s1.TotalLength = Length;
|
|
|
|
Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
|
|
|
|
}
|
2008-08-02 22:09:22 +00:00
|
|
|
return STATUS_SUCCESS;
|
2005-02-05 01:44:05 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 17:01:22 +00:00
|
|
|
CSR_API(CsrGenerateCtrlEvent)
|
|
|
|
{
|
|
|
|
PCSRSS_CONSOLE Console;
|
|
|
|
PCSRSS_PROCESS_DATA current;
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
DWORD Group;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
|
|
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
|
|
|
|
|
|
|
Status = ConioConsoleFromProcessData(ProcessData, &Console);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2008-08-02 17:01:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
for (current_entry = Console->ProcessList.Flink;
|
|
|
|
current_entry != &Console->ProcessList;
|
|
|
|
current_entry = current_entry->Flink)
|
|
|
|
{
|
|
|
|
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
|
|
|
|
if (Group == 0 || current->ProcessGroup == Group)
|
|
|
|
{
|
|
|
|
ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConioUnlockConsole(Console);
|
|
|
|
|
2008-08-02 22:09:22 +00:00
|
|
|
return Status;
|
2008-08-02 17:01:22 +00:00
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
/* EOF */
|