big work on the console front

svn path=/trunk/; revision=1161
This commit is contained in:
Phillip Susi 2000-05-26 05:43:33 +00:00
parent 1410c2b0a4
commit 232a66904f
9 changed files with 698 additions and 270 deletions

View file

@ -1,4 +1,4 @@
/* $Id: blue.c,v 1.22 2000/05/08 23:25:36 ekohl Exp $
/* $Id: blue.c,v 1.23 2000/05/26 05:43:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -64,13 +64,6 @@ typedef struct _DEVICE_EXTENSION
WORD Columns; /* Number of columns */
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
#pragma pack(push,1)
typedef struct _CHAR_CELL
{
UCHAR Character;
UCHAR Attribute;
} CHAR_CELL, *PCHAR_CELL;
#pragma pack(pop)
/* FUNCTIONS **************************************************************/
@ -184,7 +177,6 @@ ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
cursory = offset / columns;
cursorx = offset % columns;
if( processed == 0 )
{
/* raw output mode */
@ -242,7 +234,6 @@ ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
}
if (cursory >= rows)
{
unsigned short *LinePtr;
@ -284,47 +275,6 @@ ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
static
NTSTATUS
BlueDraw (
PDEVICE_EXTENSION DeviceExtension,
PIRP Irp,
PIO_STACK_LOCATION Stack
)
{
PCONSOLE_DRAW DrawInfo;
PCHAR_INFO CharBuffer;
PCHAR_CELL VideoMemory;
ULONG ScreenIndex;
ULONG BufferIndex;
ULONG x;
ULONG y;
DrawInfo = (PCONSOLE_DRAW)Irp->AssociatedIrp.SystemBuffer;
CharBuffer = (PCHAR_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
VideoMemory = (PCHAR_CELL)DeviceExtension->VideoMemory;
for (y = 0; y < DeviceExtension->Rows; y++)
{
for (x = 0; x < DeviceExtension->Columns; x++)
{
ScreenIndex = y *DeviceExtension->Columns + x;
BufferIndex = (DrawInfo->Y + y) * DrawInfo->SizeX
+ DrawInfo->X + x;
VideoMemory[ScreenIndex].Character =
(CHAR)CharBuffer[BufferIndex].Char.UnicodeChar;
VideoMemory[ScreenIndex].Attribute =
(CHAR)CharBuffer[BufferIndex].Attributes;
}
}
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
NTSTATUS
ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
@ -378,7 +328,6 @@ ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
unsigned int offset;
DeviceExtension->CharAttribute = pcsbi->wAttributes;
offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
pcsbi->dwCursorPosition.X;
@ -611,10 +560,6 @@ ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
break;
case IOCTL_CONSOLE_DRAW:
Status = BlueDraw (DeviceExtension, Irp, stk);
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
}

View file

@ -2,6 +2,7 @@
#define __INCLUDE_CSRSS_CSRSS_H
#include <napi/lpc.h>
#include <ddk/ntddblue.h>
#define CSR_PRIORITY_CLASS_NORMAL (0x10)
#define CSR_PRIORITY_CLASS_IDLE (0x20)
@ -58,13 +59,122 @@ typedef struct
HANDLE ConsoleHandle;
} CSRSS_ALLOC_CONSOLE_REPLY, *PCSRSS_ALLOC_CONSOLE_REPLY;
#define CSRSS_CREATE_PROCESS (0x1)
#define CSRSS_TERMINATE_PROCESS (0x2)
#define CSRSS_WRITE_CONSOLE (0x3)
#define CSRSS_READ_CONSOLE (0x4)
#define CSRSS_ALLOC_CONSOLE (0x5)
#define CSRSS_FREE_CONSOLE (0x6)
#define CSRSS_CONNECT_PROCESS (0x7)
typedef struct
{
HANDLE ConsoleHandle;
} CSRSS_SCREEN_BUFFER_INFO_REQUEST, *PCSRSS_SCREEN_BUFFER_INFO_REQUEST;
typedef struct
{
CONSOLE_SCREEN_BUFFER_INFO Info;
} CSRSS_SCREEN_BUFFER_INFO_REPLY, *PCSRSS_SCREEN_BUFFER_INFO_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
COORD Position;
} CSRSS_SET_CURSOR_REQUEST, *PCSRSS_SET_CURSOR_REQUEST;
typedef struct
{
HANDLE ConsoleHandle;
CHAR Char;
COORD Position;
WORD Length;
} CSRSS_FILL_OUTPUT_REQUEST, *PCSRSS_FILL_OUTPUT_REQUEST;
typedef struct
{
HANDLE ConsoleHandle;
CHAR Attribute;
COORD Coord;
WORD Length;
} CSRSS_FILL_OUTPUT_ATTRIB_REQUEST, *PCSRSS_FILL_OUTPUT_ATTRIB_REQUEST;
typedef struct
{
HANDLE ConsoleHandle;
} CSRSS_READ_INPUT_REQUEST, *PCSRSS_READ_INPUT_REQUEST;
typedef struct
{
INPUT_RECORD Input;
BOOL MoreEvents;
HANDLE Event;
} CSRSS_READ_INPUT_REPLY, *PCSRSS_READ_INPUT_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
COORD Coord;
WORD Length;
CHAR String[1];
} CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST, *PCSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST;
typedef struct
{
COORD EndCoord;
} CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REPLY, *PCSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
COORD Coord;
WORD Length;
CHAR String[1];
} CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST, *PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST;
typedef struct
{
COORD EndCoord;
} CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REPLY, *PCSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
} CSRSS_GET_CURSOR_INFO_REQUEST, *PCSRSS_GET_CURSOR_INFO_REQUEST;
typedef struct
{
CONSOLE_CURSOR_INFO Info;
} CSRSS_GET_CURSOR_INFO_REPLY, *PCSRSS_GET_CURSOR_INFO_REPLY;
typedef struct
{
HANDLE ConsoleHandle;
CONSOLE_CURSOR_INFO Info;
} CSRSS_SET_CURSOR_INFO_REQUEST, *PCSRSS_SET_CURSOR_INFO_REQUEST;
typedef struct
{
HANDLE ConsoleHandle;
CHAR Attrib;
} CSRSS_SET_ATTRIB_REQUEST, *PCSRSS_SET_ATTRIB_REQUEST;
#define CSRSS_MAX_WRITE_CONSOLE_REQUEST (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_REQUEST))
#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST ))
#define CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST ))
#define CSRSS_MAX_READ_CONSOLE_REQUEST (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_READ_CONSOLE_REQUEST ))
#define CSRSS_CREATE_PROCESS (0x0)
#define CSRSS_TERMINATE_PROCESS (0x1)
#define CSRSS_WRITE_CONSOLE (0x2)
#define CSRSS_READ_CONSOLE (0x3)
#define CSRSS_ALLOC_CONSOLE (0x4)
#define CSRSS_FREE_CONSOLE (0x5)
#define CSRSS_CONNECT_PROCESS (0x6)
#define CSRSS_SCREEN_BUFFER_INFO (0x7)
#define CSRSS_SET_CURSOR (0x8)
#define CSRSS_FILL_OUTPUT (0x9)
#define CSRSS_READ_INPUT (0xA)
#define CSRSS_WRITE_CONSOLE_OUTPUT_CHAR (0xB)
#define CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB (0xC)
#define CSRSS_FILL_OUTPUT_ATTRIB (0xD)
#define CSRSS_GET_CURSOR_INFO (0xE)
#define CSRSS_SET_CURSOR_INFO (0xF)
#define CSRSS_SET_ATTRIB (0x10)
typedef struct
{
@ -76,6 +186,16 @@ typedef struct
CSRSS_CONNECT_PROCESS_REQUEST ConnectRequest;
CSRSS_WRITE_CONSOLE_REQUEST WriteConsoleRequest;
CSRSS_READ_CONSOLE_REQUEST ReadConsoleRequest;
CSRSS_SCREEN_BUFFER_INFO_REQUEST ScreenBufferInfoRequest;
CSRSS_SET_CURSOR_REQUEST SetCursorRequest;
CSRSS_FILL_OUTPUT_REQUEST FillOutputRequest;
CSRSS_READ_INPUT_REQUEST ReadInputRequest;
CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST WriteConsoleOutputCharRequest;
CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST WriteConsoleOutputAttribRequest;
CSRSS_FILL_OUTPUT_ATTRIB_REQUEST FillOutputAttribRequest;
CSRSS_SET_CURSOR_INFO_REQUEST SetCursorInfoRequest;
CSRSS_GET_CURSOR_INFO_REQUEST GetCursorInfoRequest;
CSRSS_SET_ATTRIB_REQUEST SetAttribRequest;
} Data;
} CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
@ -90,7 +210,13 @@ typedef struct
CSRSS_WRITE_CONSOLE_REPLY WriteConsoleReply;
CSRSS_READ_CONSOLE_REPLY ReadConsoleReply;
CSRSS_ALLOC_CONSOLE_REPLY AllocConsoleReply;
CSRSS_SCREEN_BUFFER_INFO_REPLY ScreenBufferInfoReply;
CSRSS_READ_INPUT_REPLY ReadInputReply;
CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REPLY WriteConsoleOutputCharReply;
CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REPLY WriteConsoleOutputAttribReply;
CSRSS_GET_CURSOR_INFO_REPLY GetCursorInfoReply;
} Data;
} CSRSS_API_REPLY, *PCSRSS_API_REPLY;
#endif /* __INCLUDE_CSRSS_CSRSS_H */

View file

@ -12,7 +12,6 @@ typedef struct Object_tt
{
DWORD Type;
DWORD ReferenceCount;
CRITICAL_SECTION Lock;
} Object_t;
typedef struct ConsoleInput_t
@ -25,16 +24,16 @@ typedef struct CSRSS_CONSOLE_t
{
DWORD Type;
DWORD ReferenceCount; /* Inherited from Object_t */
CRITICAL_SECTION Lock;
struct CSRSS_CONSOLE_t *Prev, *Next; /* Next and Prev consoles in console wheel */
HANDLE ActiveEvent;
PCHAR_INFO Buffer;
BYTE *Buffer;
USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
USHORT ShowX, ShowY; /* beginning offset for the actual display area */
ULONG CurrentX;
ULONG CurrentY;
WORD DefaultAttrib; /* default char attribute */
BYTE DefaultAttrib; /* default char attribute */
LIST_ENTRY InputEvents; /* List head for input event queue */
CONSOLE_CURSOR_INFO CursorInfo;
} CSRSS_CONSOLE, *PCSRSS_CONSOLE;
typedef struct
@ -46,10 +45,11 @@ typedef struct
HANDLE ConsoleEvent;
} CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA;
VOID CsrInitProcessData(VOID);
NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_CREATE_PROCESS_REQUEST Request,
PCSRSS_API_REQUEST Request,
PCSRSS_API_REPLY Reply);
NTSTATUS CsrTerminateProcess(PCSRSS_PROCESS_DATA ProcessData,
@ -76,6 +76,26 @@ NTSTATUS CsrConnectProcess(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_API_REQUEST Request,
PCSRSS_API_REPLY Reply);
NTSTATUS CsrGetScreenBufferInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrSetCursor( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrFillOutputChar( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrReadInputEvent( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrWriteConsoleOutputChar( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrWriteConsoleOutputAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrFillOutputAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrGetCursorInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrSetCursorInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
NTSTATUS CsrSetTextAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply );
/* print.c */
VOID DisplayString(LPCWSTR lpwString);
VOID PrintString (char* fmt, ...);
@ -102,7 +122,6 @@ NTSTATUS CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t
BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount,
PWSTR *ArgumentArray);
NTSTATUS CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
VOID CsrUnlockObject( Object_t *Object );
VOID CsrDrawConsole( PCSRSS_CONSOLE Console );

View file

@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.6 2000/05/08 23:27:03 ekohl Exp $
/* $Id: conio.c,v 1.7 2000/05/26 05:40:20 phreak Exp $
*
* reactos/subsys/csrss/api/conio.c
*
@ -73,7 +73,7 @@ NTSTATUS CsrAllocConsole(PCSRSS_PROCESS_DATA ProcessData,
Status = NtDuplicateObject( NtCurrentProcess(), &ProcessData->Console->ActiveEvent, Process, &ProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: NtDuplicateObject() failed\n" );
DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
NtClose( Process );
Console->ReferenceCount--;
CsrReleaseObject( ProcessData, LpcReply->Data.AllocConsoleReply.ConsoleHandle );
@ -102,15 +102,14 @@ NTSTATUS CsrReadConsole(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_API_REQUEST LpcMessage,
PCSRSS_API_REPLY LpcReply)
{
PINPUT_RECORD Input;
ConsoleInput *Input;
PCHAR Buffer;
int i;
ULONG nNumberOfCharsToRead;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
nNumberOfCharsToRead =
LpcMessage->Data.ReadConsoleRequest.NrCharactersToRead;
nNumberOfCharsToRead = LpcMessage->Data.ReadConsoleRequest.NrCharactersToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : LpcMessage->Data.ReadConsoleRequest.NrCharactersToRead;
// DbgPrint("CSR: NrCharactersToRead %d\n", nNumberOfCharsToRead);
@ -127,15 +126,18 @@ NTSTATUS CsrReadConsole(PCSRSS_PROCESS_DATA ProcessData,
LpcReply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
for (i=0; i<nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++ )
{
Input = &((ConsoleInput *)Console->InputEvents.Flink)->InputEvent;
Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
Console->InputEvents.Flink->Blink = &Console->InputEvents;
Buffer[i] = Input->Event.KeyEvent.uChar.AsciiChar;
Input = (ConsoleInput *)Console->InputEvents.Flink;
Input->ListEntry.Blink->Flink = Input->ListEntry.Flink;
Input->ListEntry.Flink->Blink = Input->ListEntry.Blink;
if( Input->InputEvent.Event.KeyEvent.bKeyDown == TRUE && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar )
Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
else i--;
RtlFreeHeap( CsrssApiHeap, 0, Input );
}
CsrUnlockObject( (Object_t *)Console );
RtlLeaveCriticalSection( &ActiveConsoleLock );
LpcReply->Data.ReadConsoleReply.NrCharactersRead = i;
LpcReply->Status = i ? STATUS_SUCCESS : STATUS_PENDING;
return(Status);
@ -143,29 +145,21 @@ NTSTATUS CsrReadConsole(PCSRSS_PROCESS_DATA ProcessData,
NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_API_REQUEST Message,
PCSRSS_API_REPLY LpcReply)
NTSTATUS CsrpWriteConsole( PCSRSS_CONSOLE Console, CHAR *Buffer, DWORD Length, BOOL Attrib )
{
BYTE *Buffer = Message->Data.WriteConsoleRequest.Buffer;
PCSRSS_CONSOLE Console;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
int i;
LpcReply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
LpcReply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, Message->Data.WriteConsoleRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return LpcReply->Status = STATUS_INVALID_HANDLE;
for( i = 0; i < Message->Data.WriteConsoleRequest.NrCharactersToWrite; i++ )
for( i = 0; i < Length; i++ )
{
switch( Buffer[ i ] )
{
case L'\n': {
case '\n': {
int c;
Console->CurrentX = 0;
/* slide the viewable screen */
if( ((PhysicalConsoleSize.Y + Console->ShowY) % Console->MaxY) == (Console->CurrentY + 1) )
if( ((PhysicalConsoleSize.Y + Console->ShowY) % Console->MaxY) == (Console->CurrentY + 1) % Console->MaxY)
if( ++Console->ShowY == (Console->MaxY - 1) )
Console->ShowY = 0;
if( ++Console->CurrentY == Console->MaxY )
@ -174,28 +168,26 @@ NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
for( c = 0; c < Console->MaxX; c++ )
{
/* clear new line */
Console->Buffer[ c ].Char.UnicodeChar = L' ';
Console->Buffer[ c ].Attributes = Console->DefaultAttrib;
Console->Buffer[ c * 2 ] = ' ';
Console->Buffer[ (c * 2) + 1 ] = Console->DefaultAttrib;
}
}
else for( c = 0; c < Console->MaxX; c++ )
{
/* clear new line */
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Char.UnicodeChar = L' ';
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Attributes = Console->DefaultAttrib;
Console->Buffer[ 2 * ((Console->CurrentY * Console->MaxX) + c) ] = ' ';
Console->Buffer[ (2 * ((Console->CurrentY * Console->MaxX) + c)) + 1 ] = Console->DefaultAttrib;
}
break;
}
case L'\b': {
case '\b': {
if( Console->CurrentX == 0 )
{
/* slide viewable screen up */
if( Console->ShowY == Console->CurrentY )
{
if( Console->ShowY == 0 )
Console->ShowY = Console->MaxY;
else Console->ShowY--;
}
/* slide virtual position up */
Console->CurrentX = Console->MaxX;
if( Console->CurrentY == 0 )
@ -203,14 +195,15 @@ NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
else Console->CurrentY--;
}
else Console->CurrentX--;
Console->Buffer[ (Console->CurrentY * Console->MaxX) + Console->CurrentX ].Char.UnicodeChar = L' ';
Console->Buffer[ (Console->CurrentY * Console->MaxX) + Console->CurrentX ].Attributes = Console->DefaultAttrib;
Console->Buffer[ 2 * ((Console->CurrentY * Console->MaxX) + Console->CurrentX) ] = ' ';
Console->Buffer[ (2 * ((Console->CurrentY * Console->MaxX) + Console->CurrentX)) + 1 ] = Console->DefaultAttrib;
break;
}
default: {
int c;
Console->Buffer[ (Console->CurrentY * Console->MaxX) + Console->CurrentX ].Char.UnicodeChar = (WCHAR)Buffer[ i ];
Console->Buffer[ (Console->CurrentY * Console->MaxX) + Console->CurrentX ].Attributes = Console->DefaultAttrib;
Console->Buffer[ 2 * (((Console->CurrentY * Console->MaxX)) + Console->CurrentX) ] = Buffer[ i ];
if( Attrib )
Console->Buffer[ (2 * ((Console->CurrentY * Console->MaxX) + Console->CurrentX)) + 1 ] = Console->DefaultAttrib;
Console->CurrentX++;
if( Console->CurrentX == Console->MaxX )
{
@ -223,16 +216,16 @@ NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
/* clear new line */
for( c = 0; c < Console->MaxX; c++ )
{
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Char.UnicodeChar = L' ';
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Attributes = Console->DefaultAttrib;
Console->Buffer[ 2 * ((Console->CurrentY * Console->MaxX) + c) ] = ' ';
Console->Buffer[ (2 * ((Console->CurrentY * Console->MaxX) + c)) + 1 ] = Console->DefaultAttrib;
}
}
else {
/* clear new line */
for( c = 0; c < Console->MaxX; c += 2 )
{
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Char.UnicodeChar = L' ';
Console->Buffer[ (Console->CurrentY * Console->MaxX) + c ].Attributes = Console->DefaultAttrib;
Console->Buffer[ 2 * ((Console->CurrentY * Console->MaxX) + c) ] = ' ';
Console->Buffer[ (2 * ((Console->CurrentY * Console->MaxX) + c)) + 1 ] = Console->DefaultAttrib;
}
}
/* slide the viewable screen */
@ -243,18 +236,39 @@ NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
}
}
}
CsrUnlockObject( (Object_t *)Console );
RtlEnterCriticalSection( &ActiveConsoleLock );
if( Console == ActiveConsole )
{ /* only write to screen if Console is Active, and not scrolled up */
CsrDrawConsole ( Console );
}
RtlLeaveCriticalSection( &ActiveConsoleLock );
LpcReply->Data.WriteConsoleReply.NrCharactersWritten = i;
LpcReply->Status = STATUS_SUCCESS;
{ /* only write to screen if Console is Active, and not scrolled up */
if( Attrib )
{
Status = NtWriteFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, Buffer, Length, NULL, 0);
if (!NT_SUCCESS(Status))
DbgPrint("CSR: Write failed\n");
}
else CsrDrawConsole( Console );
}
return(STATUS_SUCCESS);
}
NTSTATUS CsrWriteConsole(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_API_REQUEST LpcMessage,
PCSRSS_API_REPLY Reply)
{
BYTE *Buffer = LpcMessage->Data.WriteConsoleRequest.Buffer;
PCSRSS_CONSOLE Console;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, LpcMessage->Data.WriteConsoleRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return Reply->Status = STATUS_INVALID_HANDLE;
RtlEnterCriticalSection( &ActiveConsoleLock );
CsrpWriteConsole( Console, Buffer, LpcMessage->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE );
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS CsrInitConsole(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_CONSOLE Console)
{
@ -268,8 +282,7 @@ NTSTATUS CsrInitConsole(PCSRSS_PROCESS_DATA ProcessData,
Console->CurrentY = 0;
Console->ReferenceCount = 0;
Console->Type = CSRSS_CONSOLE_MAGIC;
RtlInitializeCriticalSection( &Console->Lock );
Console->Buffer = RtlAllocateHeap( CsrssApiHeap, 0, Console->MaxX * Console->MaxY * sizeof(CHAR_INFO) );
Console->Buffer = RtlAllocateHeap( CsrssApiHeap, 0, Console->MaxX * Console->MaxY * 2 );
if( Console->Buffer == 0 )
return STATUS_INSUFFICIENT_RESOURCES;
Console->InputEvents.Flink = Console->InputEvents.Blink = &Console->InputEvents;
@ -285,11 +298,13 @@ NTSTATUS CsrInitConsole(PCSRSS_PROCESS_DATA ProcessData,
{
for( ; Console->CurrentX < Console->MaxX; Console->CurrentX++ )
{
Console->Buffer[ Console->CurrentX + (Console->CurrentY * Console->MaxX) ].Char.UnicodeChar = L' ';
Console->Buffer[ Console->CurrentX + (Console->CurrentY * Console->MaxX) ].Attributes = Console->DefaultAttrib;
Console->Buffer[ (Console->CurrentX * 2) + (Console->CurrentY * Console->MaxX * 2) ] = ' ';
Console->Buffer[ (Console->CurrentX * 2) + (Console->CurrentY * Console->MaxX * 2)+ 1 ] = Console->DefaultAttrib;
}
Console->CurrentX = 0;
}
Console->CursorInfo.bVisible = TRUE;
Console->CursorInfo.dwSize = 5;
/* make console active, and insert into console list */
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole )
@ -318,28 +333,15 @@ NTSTATUS CsrInitConsole(PCSRSS_PROCESS_DATA ProcessData,
**************************************************************/
VOID CsrDrawConsole( PCSRSS_CONSOLE Console )
{
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
CONSOLE_DRAW DrawInfo;
ULONG BufferSize;
NTSTATUS Status;
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
CONSOLE_MODE Mode;
int i, y;
DrawInfo.X = Console->ShowX;
DrawInfo.Y = Console->ShowY;
DrawInfo.SizeX = Console->MaxX;
DrawInfo.SizeY = Console->MaxY;
BufferSize = Console->MaxX * Console->MaxY * sizeof(CHAR_INFO);
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_DRAW, &DrawInfo, sizeof( CONSOLE_DRAW ), Console->Buffer, BufferSize);
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set console info\n" );
return;
}
ScrInfo.dwCursorPosition.X = Console->CurrentX - Console->ShowX;
ScrInfo.dwCursorPosition.Y = ((Console->CurrentY + Console->MaxY) - Console->ShowY) % Console->MaxY;
/* first set position to 0,0 */
ScrInfo.dwCursorPosition.X = 0;
ScrInfo.dwCursorPosition.Y = 0;
ScrInfo.wAttributes = Console->DefaultAttrib;
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
if( !NT_SUCCESS( Status ) )
@ -347,12 +349,54 @@ VOID CsrDrawConsole( PCSRSS_CONSOLE Console )
DbgPrint( "CSR: Failed to set console info\n" );
return;
}
Mode.dwMode = 0; /* clear ENABLE_PROCESSED_OUTPUT mode */
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set console mode\n" );
return;
}
/* blast out buffer */
for( i = 0, y = Console->ShowY; i < PhysicalConsoleSize.Y; i++ )
{
Status = NtWriteFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, &Console->Buffer[ (Console->ShowX * 2) + (y * Console->MaxX * 2) ], PhysicalConsoleSize.X * 2, 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Write to console failed\n" );
return;
}
/* wrap back around the end of the buffer */
if( ++y == Console->MaxY )
y = 0;
}
Mode.dwMode = ENABLE_PROCESSED_OUTPUT;
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set console mode\n" );
return;
}
ScrInfo.dwCursorPosition.X = Console->CurrentX - Console->ShowX;
ScrInfo.dwCursorPosition.Y = ((Console->CurrentY + Console->MaxY) - Console->ShowY) % Console->MaxY;
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set console info\n" );
return;
}
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_CURSOR_INFO, &Console->CursorInfo, sizeof( Console->CursorInfo ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set cursor info\n" );
return;
}
}
VOID CsrDeleteConsole( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE Console )
{
ConsoleInput *Event;
RtlEnterCriticalSection( &ActiveConsoleLock );
RtlFreeHeap( CsrssApiHeap, 0, Console->Buffer );
while( Console->InputEvents.Flink != &Console->InputEvents )
{
@ -361,7 +405,6 @@ VOID CsrDeleteConsole( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE Console )
Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
RtlFreeHeap( CsrssApiHeap, 0, Event );
}
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole == Console )
{
if( Console->Next != Console )
@ -376,7 +419,6 @@ VOID CsrDeleteConsole( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE Console )
CsrDrawConsole( ActiveConsole );
RtlLeaveCriticalSection( &ActiveConsoleLock );
NtClose( Console->ActiveEvent );
RtlDeleteCriticalSection( &Console->Lock );
}
VOID CsrInitConsoleSupport(VOID)
@ -455,68 +497,390 @@ VOID Console_Api( DWORD Ignored )
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: ReadFile on keyboard device failed\n" );
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
// DbgPrint( "Char: %c\n", KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar );
if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
{
if( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == 'q' )
if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED )&& KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == 'q' )
if( KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
{
/* alt-tab, swap consoles */
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole->Next != ActiveConsole )
ActiveConsole = ActiveConsole->Next;
CsrDrawConsole( ActiveConsole );
RtlLeaveCriticalSection( &ActiveConsoleLock );
continue;
}
else if( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP || KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_DOWN )
{
/* scroll up or down */
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole == 0 )
{
DbgPrint( "CSR: No Active Console!\n" );
continue;
}
RtlEnterCriticalSection( &ActiveConsole->Lock );
if( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP )
{
/* only scroll up if there is room to scroll up into */
if( ActiveConsole->ShowY != ((ActiveConsole->CurrentY + 1) % ActiveConsole->MaxY) )
ActiveConsole->ShowY = (ActiveConsole->ShowY + ActiveConsole->MaxY - 1) % ActiveConsole->MaxY;
}
else if( ActiveConsole->ShowY != ActiveConsole->CurrentY )
/* only scroll down if there is room to scroll down into */
if( ActiveConsole->ShowY % ActiveConsole->MaxY != ActiveConsole->CurrentY )
if( ((ActiveConsole->CurrentY + 1) % ActiveConsole->MaxY) != (ActiveConsole->ShowY + PhysicalConsoleSize.Y) % ActiveConsole->MaxY )
ActiveConsole->ShowY = (ActiveConsole->ShowY + 1) % ActiveConsole->MaxY;
CsrDrawConsole( ActiveConsole );
RtlLeaveCriticalSection( &ActiveConsole->Lock );
RtlLeaveCriticalSection( &ActiveConsoleLock );
/* alt-tab, swap consoles */
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole->Next != ActiveConsole )
ActiveConsole = ActiveConsole->Next;
CsrDrawConsole( ActiveConsole );
RtlLeaveCriticalSection( &ActiveConsoleLock );
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
else {
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
else if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) && (KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP || KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) )
{
if( KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
{
/* scroll up or down */
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole == 0 )
{
DbgPrint( "CSR: No Active Console!\n" );
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
if( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP )
{
/* only scroll up if there is room to scroll up into */
if( ActiveConsole->ShowY != ((ActiveConsole->CurrentY + 1) % ActiveConsole->MaxY) )
ActiveConsole->ShowY = (ActiveConsole->ShowY + ActiveConsole->MaxY - 1) % ActiveConsole->MaxY;
}
else if( ActiveConsole->ShowY != ActiveConsole->CurrentY )
/* only scroll down if there is room to scroll down into */
if( ActiveConsole->ShowY % ActiveConsole->MaxY != ActiveConsole->CurrentY )
if( ((ActiveConsole->CurrentY + 1) % ActiveConsole->MaxY) != (ActiveConsole->ShowY + PhysicalConsoleSize.Y) % ActiveConsole->MaxY )
ActiveConsole->ShowY = (ActiveConsole->ShowY + 1) % ActiveConsole->MaxY;
CsrDrawConsole( ActiveConsole );
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
if( KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
continue;
/* ignore dead keys */
if( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == 0 )
continue;
RtlEnterCriticalSection( &ActiveConsoleLock );
if( ActiveConsole == 0 )
{
DbgPrint( "CSR: No Active Console!\n" );
continue;
}
RtlEnterCriticalSection( &ActiveConsole->Lock );
{
DbgPrint( "CSR: No Active Console!\n" );
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
continue;
}
KeyEventRecord->ListEntry.Flink = &ActiveConsole->InputEvents;
KeyEventRecord->ListEntry.Blink = ActiveConsole->InputEvents.Blink;
ActiveConsole->InputEvents.Blink->Flink = &KeyEventRecord->ListEntry;
ActiveConsole->InputEvents.Blink = &KeyEventRecord->ListEntry;
NtSetEvent( ActiveConsole->ActiveEvent, 0 );
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
NTSTATUS CsrGetScreenBufferInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCONSOLE_SCREEN_BUFFER_INFO pInfo;
IO_STATUS_BLOCK Iosb;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return Reply->Status = STATUS_INVALID_HANDLE;
pInfo = &Reply->Data.ScreenBufferInfoReply.Info;
RtlEnterCriticalSection( &ActiveConsoleLock );
if( Console == ActiveConsole )
{
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, 0, 0, pInfo, sizeof( *pInfo ) );
if( !NT_SUCCESS( Status ) )
DbgPrint( "CSR: Failed to get console info, expect trouble\n" );
Reply->Status = STATUS_SUCCESS;
}
else {
pInfo->dwSize.X = PhysicalConsoleSize.X;
pInfo->dwSize.Y = PhysicalConsoleSize.Y;
pInfo->dwCursorPosition.X = Console->CurrentX - Console->ShowX;
pInfo->dwCursorPosition.Y = (Console->CurrentY + Console->MaxY - Console->ShowY) % Console->MaxY;
pInfo->wAttributes = Console->DefaultAttrib;
pInfo->srWindow.Left = 0;
pInfo->srWindow.Right = PhysicalConsoleSize.X - 1;
pInfo->srWindow.Top = 0;
pInfo->srWindow.Bottom = PhysicalConsoleSize.Y - 1;
Reply->Status = STATUS_SUCCESS;
}
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status;
}
NTSTATUS CsrSetCursor( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
CONSOLE_SCREEN_BUFFER_INFO Info;
IO_STATUS_BLOCK Iosb;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return Reply->Status = STATUS_INVALID_HANDLE;
RtlEnterCriticalSection( &ActiveConsoleLock );
Info.dwCursorPosition = Request->Data.SetCursorRequest.Position;
Info.wAttributes = Console->DefaultAttrib;
if( Console == ActiveConsole )
{
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &Info, sizeof( Info ), 0, 0 );
if( !NT_SUCCESS( Status ) )
DbgPrint( "CSR: Failed to set console info, expect trouble\n" );
}
Console->CurrentX = Info.dwCursorPosition.X + Console->ShowX;
Console->CurrentY = (Info.dwCursorPosition.Y + Console->ShowY) % Console->MaxY;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = Status;
}
NTSTATUS CsrWriteConsoleOutputChar( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
BYTE *Buffer = Request->Data.WriteConsoleOutputCharRequest.String;
PCSRSS_CONSOLE Console;
DWORD X, Y;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return Reply->Status = STATUS_INVALID_HANDLE;
RtlEnterCriticalSection( &ActiveConsoleLock );
X = Console->CurrentX;
Y = Console->CurrentY;
CsrpWriteConsole( Console, Buffer, Request->Data.WriteConsoleOutputCharRequest.Length, TRUE );
Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = Console->CurrentX - Console->ShowX;
Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Console->CurrentY + Console->MaxY - Console->ShowY) % Console->MaxY;
Console->CurrentY = Y;
Console->CurrentX = X;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS CsrFillOutputChar( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
PCSRSS_CONSOLE Console;
DWORD X, Y, i;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, (Object_t **)&Console ) ) )
return Reply->Status = STATUS_INVALID_HANDLE;
RtlEnterCriticalSection( &ActiveConsoleLock );
X = Request->Data.FillOutputRequest.Position.X + Console->ShowX;
Y = Request->Data.FillOutputRequest.Position.Y + Console->ShowY;
for( i = 0; i < 20000; i++ );
for( i = 0; i < Request->Data.FillOutputRequest.Length; i++ )
{
Console->Buffer[ (Y * 2 * Console->MaxX) + (X * 2) ] = Request->Data.FillOutputRequest.Char;
if( ++X == Console->MaxX )
{
if( ++Y == Console->MaxY )
Y = 0;
X = 0;
}
}
if( Console == ActiveConsole )
CsrDrawConsole( Console );
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
NTSTATUS CsrReadInputEvent( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
ConsoleInput *Input;
// DbgPrint("CSR: NrCharactersToRead %d\n", nNumberOfCharsToRead);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Reply->Data.ReadInputReply.Event = ProcessData->ConsoleEvent;
Status = CsrGetObject( ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
if( Console->InputEvents.Flink != &Console->InputEvents )
{
Input = (ConsoleInput *)Console->InputEvents.Flink;
Input->ListEntry.Blink->Flink = Input->ListEntry.Flink;
Input->ListEntry.Flink->Blink = Input->ListEntry.Blink;
Reply->Data.ReadInputReply.Input = Input->InputEvent;
RtlFreeHeap( CsrssApiHeap, 0, Input );
Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents) ? TRUE : FALSE;
Status = STATUS_SUCCESS;
}
else Status = STATUS_PENDING;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = Status;
}
NTSTATUS CsrWriteConsoleOutputAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
int c;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
int X, Y;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Status = CsrGetObject( ProcessData, Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
X = Console->CurrentX;
Y = Console->CurrentY;
Console->CurrentX = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Console->ShowX;
Console->CurrentY = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Console->ShowY) % Console->MaxY;
for( c = 0; c < Request->Data.WriteConsoleOutputAttribRequest.Length; c++ )
{
Console->Buffer[(Console->CurrentY * Console->MaxX * 2) + (Console->CurrentX * 2) + 1] = Request->Data.WriteConsoleOutputAttribRequest.String[c];
if( ++Console->CurrentX == Console->MaxX )
{
Console->CurrentX = 0;
if( ++Console->CurrentY == Console->MaxY )
Console->CurrentY = 0;
}
}
if( Console == ActiveConsole )
CsrDrawConsole( Console );
Reply->Data.WriteConsoleOutputAttribReply.EndCoord.X = Console->CurrentX - Console->ShowX;
Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = ( Console->CurrentY + Console->MaxY - Console->ShowY ) % Console->MaxY;
Console->CurrentX = X;
Console->CurrentY = Y;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS CsrFillOutputAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
int c;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
int X, Y;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Status = CsrGetObject( ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
X = Console->CurrentX;
Y = Console->CurrentY;
Console->CurrentX = Request->Data.FillOutputAttribRequest.Coord.X + Console->ShowX;
Console->CurrentY = Request->Data.FillOutputAttribRequest.Coord.Y + Console->ShowY;
for( c = 0; c < Request->Data.FillOutputAttribRequest.Length; c++ )
{
Console->Buffer[(Console->CurrentY * Console->MaxX * 2) + (Console->CurrentX * 2) + 1] = Request->Data.FillOutputAttribRequest.Attribute;
if( ++Console->CurrentX == Console->MaxX )
{
Console->CurrentX = 0;
if( ++Console->CurrentY == Console->MaxY )
Console->CurrentY = 0;
}
}
if( Console == ActiveConsole )
CsrDrawConsole( Console );
Console->CurrentX = X;
Console->CurrentY = Y;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
/* EOF */
NTSTATUS CsrGetCursorInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Status = CsrGetObject( ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
Reply->Data.GetCursorInfoReply.Info = Console->CursorInfo;
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS CsrSetCursorInfo( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Status = CsrGetObject( ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
Console->CursorInfo = Request->Data.SetCursorInfoRequest.Info;
if( Console == ActiveConsole )
{
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_CURSOR_INFO, &Console->CursorInfo, sizeof( Console->CursorInfo ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set cursor info\n" );
return Reply->Status = Status;
}
}
RtlLeaveCriticalSection( &ActiveConsoleLock );
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS CsrSetTextAttrib( PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply )
{
NTSTATUS Status;
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
IO_STATUS_BLOCK Iosb;
PCSRSS_CONSOLE Console;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Status = CsrGetObject( ProcessData, Request->Data.SetAttribRequest.ConsoleHandle, (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
return Status;
}
RtlEnterCriticalSection( &ActiveConsoleLock );
Console->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
if( Console == ActiveConsole )
{
ScrInfo.wAttributes = Console->DefaultAttrib;
ScrInfo.dwCursorPosition.X = Console->CurrentX - Console->ShowX;
ScrInfo.dwCursorPosition.Y = ((Console->CurrentY + Console->MaxY) - Console->ShowY) % Console->MaxY;
Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: Failed to set console info\n" );
return Reply->Status = Status;
}
}
return Reply->Status = STATUS_SUCCESS;
}

View file

@ -1,4 +1,4 @@
/* $Id: handle.c,v 1.6 2000/04/23 17:44:53 phreak Exp $
/* $Id: handle.c,v 1.7 2000/05/26 05:40:20 phreak Exp $
*
* reactos/subsys/csrss/api/handle.c
*
@ -26,15 +26,10 @@ NTSTATUS CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t
return STATUS_INVALID_HANDLE;
}
*Object = ProcessData->HandleTable[(((ULONG)Handle) >> 2) - 1];
RtlEnterCriticalSection( &(*Object)->Lock );
// DbgPrint( "CsrGetObject returning\n" );
return *Object ? STATUS_SUCCESS : STATUS_INVALID_HANDLE;
}
VOID CsrUnlockObject( Object_t *Object )
{
RtlLeaveCriticalSection( &Object->Lock );
}
NTSTATUS CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle)
@ -45,18 +40,14 @@ NTSTATUS CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
return STATUS_INVALID_HANDLE;
/* dec ref count */
Object = ProcessData->HandleTable[(((ULONG)Handle) >> 2) - 1];
RtlEnterCriticalSection( &Object->Lock );
if( --Object->ReferenceCount == 0 )
switch( Object->Type )
{
case CSRSS_CONSOLE_MAGIC: CsrDeleteConsole( ProcessData, (PCSRSS_CONSOLE) Object );
DbgPrint( "Deleting Console\n" );
break;
default: DbgPrint( "CSR: Error: releaseing unknown object type" );
}
DbgPrint( "Deleting object, refcount: %d\n", Object->ReferenceCount );
ProcessData->HandleTable[(((ULONG)Handle) >> 2) - 1] = 0;
RtlLeaveCriticalSection( &Object->Lock );
return STATUS_SUCCESS;
}

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.8 2000/04/23 17:44:53 phreak Exp $
/* $Id: process.c,v 1.9 2000/05/26 05:40:20 phreak Exp $
*
* reactos/subsys/csrss/api/process.c
*
@ -19,6 +19,8 @@
static ULONG NrProcess;
static PCSRSS_PROCESS_DATA ProcessData[256];
extern CRITICAL_SECTION ActiveConsoleLock;
CRITICAL_SECTION ProcessDataLock;
/* FUNCTIONS *****************************************************************/
@ -31,17 +33,20 @@ VOID CsrInitProcessData(VOID)
ProcessData[i] = NULL;
}
NrProcess = 256;
RtlInitializeCriticalSection( &ProcessDataLock );
}
PCSRSS_PROCESS_DATA CsrGetProcessData(ULONG ProcessId)
{
ULONG i;
RtlEnterCriticalSection( &ProcessDataLock );
for (i=0; i<NrProcess; i++)
{
if (ProcessData[i] &&
ProcessData[i]->ProcessId == ProcessId)
{
RtlLeaveCriticalSection( &ProcessDataLock );
return(ProcessData[i]);
}
}
@ -54,19 +59,23 @@ PCSRSS_PROCESS_DATA CsrGetProcessData(ULONG ProcessId)
sizeof(CSRSS_PROCESS_DATA));
if (ProcessData[i] == NULL)
{
RtlLeaveCriticalSection( &ProcessDataLock );
return(NULL);
}
ProcessData[i]->ProcessId = ProcessId;
RtlLeaveCriticalSection( &ProcessDataLock );
return(ProcessData[i]);
}
}
// DbgPrint("CSR: CsrGetProcessData() failed\n");
RtlLeaveCriticalSection( &ProcessDataLock );
return(NULL);
}
NTSTATUS CsrFreeProcessData( ULONG Pid )
{
int i;
RtlEnterCriticalSection( &ProcessDataLock );
for( i = 0; i < NrProcess; i++ )
{
if( ProcessData[i] && ProcessData[i]->ProcessId == Pid )
@ -81,25 +90,27 @@ NTSTATUS CsrFreeProcessData( ULONG Pid )
}
if( ProcessData[i]->Console )
{
RtlEnterCriticalSection( &ProcessData[i]->Console->Lock );
RtlEnterCriticalSection( &ActiveConsoleLock );
if( --ProcessData[i]->Console->ReferenceCount == 0 )
{
RtlLeaveCriticalSection( &ProcessData[i]->Console->Lock );
RtlLeaveCriticalSection( &ActiveConsoleLock );
CsrDeleteConsole( ProcessData[i], ProcessData[i]->Console );
}
RtlLeaveCriticalSection( &ProcessData[i]->Console->Lock );
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i] );
ProcessData[i] = 0;
RtlLeaveCriticalSection( &ProcessDataLock );
return STATUS_SUCCESS;
}
}
RtlLeaveCriticalSection( &ProcessDataLock );
return STATUS_INVALID_PARAMETER;
}
NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_CREATE_PROCESS_REQUEST Request,
PCSRSS_API_REQUEST Request,
PCSRSS_API_REPLY Reply)
{
PCSRSS_PROCESS_DATA NewProcessData;
@ -110,19 +121,19 @@ NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
sizeof(LPC_MESSAGE_HEADER);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
NewProcessData = CsrGetProcessData(Request->NewProcessId);
NewProcessData = CsrGetProcessData(Request->Data.CreateProcessRequest.NewProcessId);
DbgPrint( "CreateProcess\n" );
if (NewProcessData == NULL)
{
Reply->Status = STATUS_NO_MEMORY;
return(STATUS_NO_MEMORY);
}
if (Request->Flags & DETACHED_PROCESS)
if (Request->Data.CreateProcessRequest.Flags & DETACHED_PROCESS)
{
NewProcessData->Console = NULL;
}
else if (Request->Flags & CREATE_NEW_CONSOLE)
else if (Request->Data.CreateProcessRequest.Flags & CREATE_NEW_CONSOLE)
{
PCSRSS_CONSOLE Console;
@ -137,9 +148,9 @@ NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
else
{
NewProcessData->Console = ProcessData->Console;
RtlEnterCriticalSection( &ProcessData->Console->Lock );
RtlEnterCriticalSection( &ActiveConsoleLock );
ProcessData->Console->ReferenceCount++;
RtlLeaveCriticalSection( &ProcessData->Console->Lock );
RtlLeaveCriticalSection( &ActiveConsoleLock );
}
if( NewProcessData->Console )
@ -160,7 +171,7 @@ NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
Status = NtDuplicateObject( NtCurrentProcess(), &NewProcessData->Console->ActiveEvent, Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: NtDuplicateObject() failed\n" );
DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
NtClose( Process );
CsrFreeProcessData( NewProcessData->ProcessId );
Reply->Status = Status;

View file

@ -1,4 +1,4 @@
/* $Id: wapi.c,v 1.7 2000/04/23 17:44:53 phreak Exp $
/* $Id: wapi.c,v 1.8 2000/05/26 05:40:20 phreak Exp $
*
* reactos/subsys/csrss/api/wapi.c
*
@ -22,6 +22,28 @@ HANDLE CsrssApiHeap;
/* FUNCTIONS *****************************************************************/
typedef NTSTATUS (*CsrFunc)( PCSRSS_PROCESS_DATA, PCSRSS_API_REQUEST, PCSRSS_API_REPLY );
static const CsrFunc CsrFuncs[] = {
CsrCreateProcess,
CsrTerminateProcess,
CsrWriteConsole,
CsrReadConsole,
CsrAllocConsole,
CsrFreeConsole,
CsrConnectProcess,
CsrGetScreenBufferInfo,
CsrSetCursor,
CsrFillOutputChar,
CsrReadInputEvent,
CsrWriteConsoleOutputChar,
CsrWriteConsoleOutputAttrib,
CsrFillOutputAttrib,
CsrGetCursorInfo,
CsrSetCursorInfo,
CsrSetTextAttrib,
0 };
static void Thread_Api2(HANDLE ServerPort)
{
NTSTATUS Status;
@ -46,7 +68,6 @@ static void Thread_Api2(HANDLE ServerPort)
if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED)
{
DbgPrint("Client closed port\n");
CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess );
NtClose(ServerPort);
NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
@ -59,57 +80,9 @@ static void Thread_Api2(HANDLE ServerPort)
(ULONG)LpcRequest.Header.Cid.UniqueProcess);
// DisplayString(L"CSR: Received request\n");
switch (Request->Type)
{
case CSRSS_CREATE_PROCESS:
Status = CsrCreateProcess(ProcessData,
&Request->Data.CreateProcessRequest,
Reply);
break;
case CSRSS_TERMINATE_PROCESS:
Status = CsrTerminateProcess(ProcessData,
Request,
Reply);
break;
case CSRSS_WRITE_CONSOLE:
Status = CsrWriteConsole(ProcessData,
Request,
Reply);
break;
case CSRSS_READ_CONSOLE:
Status = CsrReadConsole(ProcessData,
Request,
Reply);
break;
case CSRSS_ALLOC_CONSOLE:
Status = CsrAllocConsole(ProcessData,
Request,
Reply);
break;
case CSRSS_FREE_CONSOLE:
Status = CsrFreeConsole(ProcessData,
Request,
Reply);
break;
case CSRSS_CONNECT_PROCESS:
Status = CsrConnectProcess(ProcessData,
Request,
Reply);
break;
default:
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Status = STATUS_NOT_IMPLEMENTED;
}
if( Request->Type >= (sizeof( CsrFuncs ) / sizeof( CsrFunc )) - 1 )
Reply->Status = STATUS_INVALID_SYSTEM_SERVICE;
else CsrFuncs[ Request->Type ]( ProcessData, Request, Reply );
}
}

View file

@ -1,4 +1,4 @@
/* $Id: csrss.c,v 1.7 2000/04/23 17:44:53 phreak Exp $
/* $Id: csrss.c,v 1.8 2000/05/26 05:40:20 phreak Exp $
*
* csrss.c - Client/Server Runtime subsystem
*
@ -106,7 +106,6 @@ VOID NtProcessStartup(PPEB Peb)
{
DbgPrint("CSR: Failed to open csrss notification event\n");
}
DbgPrint( "foof\n" );
if (CsrServerInitialization (argc, argv) == TRUE)
{
DisplayString( L"CSR: Subsystem initialized.\n" );

View file

@ -1,4 +1,4 @@
/* $Id: init.c,v 1.8 2000/04/23 17:44:53 phreak Exp $
/* $Id: init.c,v 1.9 2000/05/26 05:40:20 phreak Exp $
*
* reactos/subsys/csrss/init.c
*
@ -47,11 +47,11 @@ CsrParseCommandLine (
ULONG i;
DbgPrint ("Arguments: %ld\n", ArgumentCount);
/* DbgPrint ("Arguments: %ld\n", ArgumentCount);
for (i = 0; i < ArgumentCount; i++)
{
DbgPrint ("Argument %ld: %S\n", i, ArgumentArray[i]);
}
}*/
/* create object directory ('\Windows') */