diff --git a/reactos/drivers/dd/blue/blue.c b/reactos/drivers/dd/blue/blue.c index 5568c5e86e5..25f99f64b3f 100644 --- a/reactos/drivers/dd/blue/blue.c +++ b/reactos/drivers/dd/blue/blue.c @@ -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; } diff --git a/reactos/include/csrss/csrss.h b/reactos/include/csrss/csrss.h index 03d20c3fb5c..0d6345f45c4 100644 --- a/reactos/include/csrss/csrss.h +++ b/reactos/include/csrss/csrss.h @@ -2,6 +2,7 @@ #define __INCLUDE_CSRSS_CSRSS_H #include +#include #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 */ + diff --git a/reactos/subsys/csrss/api.h b/reactos/subsys/csrss/api.h index 81f86def72b..71a57bf137c 100644 --- a/reactos/subsys/csrss/api.h +++ b/reactos/subsys/csrss/api.h @@ -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 ); diff --git a/reactos/subsys/csrss/api/conio.c b/reactos/subsys/csrss/api/conio.c index ffb64edccdd..b66234365a7 100644 --- a/reactos/subsys/csrss/api/conio.c +++ b/reactos/subsys/csrss/api/conio.c @@ -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; iInputEvents.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; +} + + + diff --git a/reactos/subsys/csrss/api/handle.c b/reactos/subsys/csrss/api/handle.c index 0eca26a1b9b..b89331ff7ca 100644 --- a/reactos/subsys/csrss/api/handle.c +++ b/reactos/subsys/csrss/api/handle.c @@ -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; } diff --git a/reactos/subsys/csrss/api/process.c b/reactos/subsys/csrss/api/process.c index 8c760da2b92..020037fa10a 100644 --- a/reactos/subsys/csrss/api/process.c +++ b/reactos/subsys/csrss/api/process.c @@ -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; iProcessId == 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; diff --git a/reactos/subsys/csrss/api/wapi.c b/reactos/subsys/csrss/api/wapi.c index 49fac5f3f5d..b586bcffb69 100644 --- a/reactos/subsys/csrss/api/wapi.c +++ b/reactos/subsys/csrss/api/wapi.c @@ -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 ); } } diff --git a/reactos/subsys/csrss/csrss.c b/reactos/subsys/csrss/csrss.c index e99abd3d20e..709253ca9b4 100644 --- a/reactos/subsys/csrss/csrss.c +++ b/reactos/subsys/csrss/csrss.c @@ -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" ); diff --git a/reactos/subsys/csrss/init.c b/reactos/subsys/csrss/init.c index 58bd906360f..3976128aa2b 100644 --- a/reactos/subsys/csrss/init.c +++ b/reactos/subsys/csrss/init.c @@ -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') */