diff --git a/reactos/include/csrss/csrss.h b/reactos/include/csrss/csrss.h index 3e3a1e279eb..c7264823052 100644 --- a/reactos/include/csrss/csrss.h +++ b/reactos/include/csrss/csrss.h @@ -246,6 +246,19 @@ typedef struct CHAR_INFO Fill; } CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST, *PCSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST; +typedef struct +{ + HANDLE ConsoleHandle; + DWORD NumCharsToRead; + COORD ReadCoord; +}CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST, *PCSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST; + +typedef struct +{ + COORD EndCoord; + CHAR String[1]; +}CSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY, *PCSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY; + #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \ (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST)) @@ -258,6 +271,8 @@ typedef struct #define CSRSS_MAX_READ_CONSOLE_REQUEST (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_READ_CONSOLE_REQUEST )) +#define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(HANDLE) - sizeof(DWORD) - sizeof(CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST)) + // FIXME: it should be 80. Is this a limit due to LPC msg size? #define CSRSS_MAX_TITLE_LENGTH 50 @@ -287,6 +302,8 @@ typedef struct #define CSRSS_WRITE_CONSOLE_OUTPUT (0x17) #define CSRSS_FLUSH_INPUT_BUFFER (0x18) #define CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER (0x19) +#define CSRSS_READ_CONSOLE_OUTPUT_CHAR (0x1A) + /* Keep in sync with definition below. */ #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE_HEADER) + sizeof(ULONG)) @@ -321,6 +338,7 @@ typedef struct CSRSS_FLUSH_INPUT_BUFFER_REQUEST FlushInputBufferRequest; CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST ScrollConsoleScreenBufferRequest; + CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST ReadConsoleOutputCharRequest; } Data; } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST; @@ -344,6 +362,7 @@ typedef struct CSRSS_CREATE_SCREEN_BUFFER_REPLY CreateScreenBufferReply; CSRSS_GET_TITLE_REPLY GetTitleReply; CSRSS_WRITE_CONSOLE_OUTPUT_REPLY WriteConsoleOutputReply; + CSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY ReadConsoleOutputCharReply; } Data; } CSRSS_API_REPLY, *PCSRSS_API_REPLY; diff --git a/reactos/include/ntos/console.h b/reactos/include/ntos/console.h index c1377c08db6..42a78526ea4 100644 --- a/reactos/include/ntos/console.h +++ b/reactos/include/ntos/console.h @@ -25,17 +25,22 @@ #define CONSOLE_OUTPUT_MODE_VALID (0x03) typedef struct _CONSOLE_SCREEN_BUFFER_INFO { - COORD dwSize; - COORD dwCursorPosition; - WORD wAttributes; - SMALL_RECT srWindow; - COORD dwMaximumWindowSize; -} CONSOLE_SCREEN_BUFFER_INFO, *PCONSOLE_SCREEN_BUFFER_INFO ; + COORD dwSize; + COORD dwCursorPosition; + WORD wAttributes; + SMALL_RECT srWindow; + COORD dwMaximumWindowSize; +} CONSOLE_SCREEN_BUFFER_INFO, *PCONSOLE_SCREEN_BUFFER_INFO ; typedef struct _CONSOLE_CURSOR_INFO { - DWORD dwSize; - BOOL bVisible; -} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; + DWORD dwSize; + BOOL bVisible; +} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; + +typedef struct _CONSOLE_FONT_INFO { + DWORD nFont; + COORD dwFontSize; +} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO; #endif /* __INCLUDE_CONSOLE_H */ diff --git a/reactos/lib/kernel32/misc/console.c b/reactos/lib/kernel32/misc/console.c index b7a11b597d8..f576c9b92a6 100644 --- a/reactos/lib/kernel32/misc/console.c +++ b/reactos/lib/kernel32/misc/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.40 2002/05/07 22:23:17 hbirr Exp $ +/* $Id: console.c,v 1.41 2002/08/22 15:21:06 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -293,11 +293,8 @@ GetConsoleFontInfo (DWORD Unknown0, } DWORD STDCALL -GetConsoleFontSize (DWORD Unknown0, - DWORD Unknown1) - /* - * Undocumented - */ +GetConsoleFontSize(HANDLE hConsoleOutput, + DWORD nFont) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; @@ -326,12 +323,9 @@ GetConsoleInputWaitHandle (VOID) } DWORD STDCALL -GetCurrentConsoleFont (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) - /* - * Undocumented - */ +GetCurrentConsoleFont(HANDLE hConsoleOutput, + BOOL bMaximumWindow, + PCONSOLE_FONT_INFO lpConsoleCurrentFont) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; @@ -662,6 +656,7 @@ WriteConsoleA(HANDLE hConsoleOutput, CSRSS_MAX_WRITE_CONSOLE_REQUEST); if (Request == NULL) { + SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } @@ -723,6 +718,7 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput, sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead); if (Reply == NULL) { + SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } @@ -824,7 +820,7 @@ WINBOOL STDCALL AllocConsole(VOID) */ WINBOOL STDCALL FreeConsole(VOID) { - DbgPrint("FreeConsole() is unimplemented"); + DbgPrint("FreeConsole() is unimplemented\n"); return FALSE; } @@ -886,8 +882,7 @@ SetConsoleCursorPosition( /*-------------------------------------------------------------- * FillConsoleOutputCharacterA */ -WINBOOL -STDCALL +WINBOOL STDCALL FillConsoleOutputCharacterA( HANDLE hConsoleOutput, CHAR cCharacter, @@ -896,23 +891,24 @@ FillConsoleOutputCharacterA( LPDWORD lpNumberOfCharsWritten ) { - CSRSS_API_REQUEST Request; - CSRSS_API_REPLY Reply; - NTSTATUS Status; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; - Request.Type = CSRSS_FILL_OUTPUT; - Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput; - Request.Data.FillOutputRequest.Char = cCharacter; - Request.Data.FillOutputRequest.Position = dwWriteCoord; - Request.Data.FillOutputRequest.Length = nLength; - Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); - if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) - { - SetLastErrorByStatus ( Status ); - return FALSE; - } - *lpNumberOfCharsWritten = nLength; - return TRUE; + Request.Type = CSRSS_FILL_OUTPUT; + Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput; + Request.Data.FillOutputRequest.Char = cCharacter; + Request.Data.FillOutputRequest.Position = dwWriteCoord; + Request.Data.FillOutputRequest.Length = nLength; + Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); + if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) + { + SetLastErrorByStatus(Status); + return(FALSE); + } + if (lpNumberOfCharsWritten != NULL) + *lpNumberOfCharsWritten = nLength; + return(TRUE); } @@ -1233,8 +1229,56 @@ ReadConsoleOutputCharacterA( LPDWORD lpNumberOfCharsRead ) { - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + CSRSS_API_REQUEST Request; + PCSRSS_API_REPLY Reply; + NTSTATUS Status; + DWORD Size; + + Reply = RtlAllocateHeap(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR); + if (Reply == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return(FALSE); + } + + if (lpNumberOfCharsRead != NULL) + *lpNumberOfCharsRead = Size; + + Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR; + Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput; + Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord; + + while (nLength != 0) + { + if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) + Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR; + else + Size = nLength; + + Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size; + + Status = CsrClientCallServer(&Request, + Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY) + Size); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status)) + { + RtlFreeHeap(GetProcessHeap(), 0, Reply); + SetLastErrorByStatus(Status); + return(FALSE); + } + + memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size); + lpCharacter += Size; + nLength -= Size; + Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord; + } + + RtlFreeHeap(GetProcessHeap(), 0, Reply); + + return(TRUE); } @@ -1704,8 +1748,8 @@ ScrollConsoleScreenBufferA( if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) { - SetLastErrorByStatus ( Status ); - return FALSE; + SetLastErrorByStatus ( Status ); + return FALSE; } return TRUE; } @@ -1994,6 +2038,7 @@ SetConsoleTitleW( sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); if (Request == NULL) { + SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } @@ -2046,6 +2091,7 @@ SetConsoleTitleA( sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); if (Request == NULL) { + SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } @@ -2110,52 +2156,52 @@ WriteConsoleW( ) { #if 0 - PCSRSS_API_REQUEST Request; - CSRSS_API_REPLY Reply; - NTSTATUS Status; - - Request = RtlAllocateHeap(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR)); - if (Request == NULL) - { - return(FALSE); - } + PCSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; - Request->Type = CSRSS_WRITE_CONSOLE; - Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleRequest.NrCharactersToWrite = - nNumberOfCharsToWrite; -// DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite); -// DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer); - memcpy(Request->Data.WriteConsoleRequest.Buffer, - lpBuffer, - nNumberOfCharsToWrite * sizeof(WCHAR)); + Request = RtlAllocateHeap(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR)); + if (Request == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return(FALSE); + } - Status = CsrClientCallServer(Request, - &Reply, - sizeof(CSRSS_API_REQUEST) + - nNumberOfCharsToWrite, - sizeof(CSRSS_API_REPLY)); + Request->Type = CSRSS_WRITE_CONSOLE; + Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput; + Request->Data.WriteConsoleRequest.NrCharactersToWrite = + nNumberOfCharsToWrite; +// DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite); +// DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer); + memcpy(Request->Data.WriteConsoleRequest.Buffer, + lpBuffer, + nNumberOfCharsToWrite * sizeof(WCHAR)); - RtlFreeHeap(GetProcessHeap(), - 0, - Request); + Status = CsrClientCallServer(Request, + &Reply, + sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite, + sizeof(CSRSS_API_REPLY)); - if (!NT_SUCCESS(Status)) - { - return(FALSE); - } + RtlFreeHeap(GetProcessHeap(), + 0, + Request); - if (lpNumberOfCharsWritten != NULL) - { - *lpNumberOfCharsWritten = + if (!NT_SUCCESS(Status)) + { + return(FALSE); + } + + if (lpNumberOfCharsWritten != NULL) + { + *lpNumberOfCharsWritten = Reply.Data.WriteConsoleReply.NrCharactersWritten; - } + } - return(TRUE); + return(TRUE); #endif - return FALSE; + return(FALSE); } diff --git a/reactos/subsys/csrss/api.h b/reactos/subsys/csrss/api.h index 44098bab7be..7c1836c3690 100644 --- a/reactos/subsys/csrss/api.h +++ b/reactos/subsys/csrss/api.h @@ -119,6 +119,7 @@ CSR_API(CsrGetTitle); CSR_API(CsrWriteConsoleOutput); CSR_API(CsrFlushInputBuffer); CSR_API(CsrScrollConsoleScreenBuffer); +CSR_API(CsrReadConsoleOutputChar); /* print.c */ VOID STDCALL DisplayString(LPCWSTR lpwString); diff --git a/reactos/subsys/csrss/api/conio.c b/reactos/subsys/csrss/api/conio.c index 6241bfe9371..a24f1eeb9bf 100644 --- a/reactos/subsys/csrss/api/conio.c +++ b/reactos/subsys/csrss/api/conio.c @@ -1,4 +1,4 @@ -/* $Id: conio.c,v 1.31 2002/08/20 20:37:16 hyperion Exp $ +/* $Id: conio.c,v 1.32 2002/08/22 15:21:57 ekohl Exp $ * * reactos/subsys/csrss/api/conio.c * @@ -1885,7 +1885,7 @@ CSR_API(CsrScrollConsoleScreenBuffer) DoFill = TRUE; } - if( Buff == ActiveConsole->ActiveBuffer ) + if (Buff == ActiveConsole->ActiveBuffer) { /* Draw destination region */ CsrpDrawRegion(ActiveConsole->ActiveBuffer, DstRegion); @@ -1897,8 +1897,71 @@ CSR_API(CsrScrollConsoleScreenBuffer) } } - UNLOCK; - return (Reply->Status = STATUS_SUCCESS); + UNLOCK; + return(Reply->Status = STATUS_SUCCESS); +} + + +CSR_API(CsrReadConsoleOutputChar) +{ + NTSTATUS Status; + PCSRSS_SCREEN_BUFFER ScreenBuffer; + DWORD Xpos, Ypos; + BYTE* ReadBuffer; + DWORD i; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE_HEADER); + ReadBuffer = Reply->Data.ReadConsoleOutputCharReply.String; + + LOCK; + + Status = CsrGetObject(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, (Object_t**)&ScreenBuffer); + if (!NT_SUCCESS(Status)) + { + Reply->Status = Status; + UNLOCK; + return(Reply->Status); + } + + if (ScreenBuffer->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC) + { + Reply->Status = STATUS_INVALID_HANDLE; + UNLOCK; + return(Reply->Status); + } + + Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + ScreenBuffer->ShowX; + Ypos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY; + + for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) + { + *ReadBuffer = ScreenBuffer->Buffer[(Xpos * 2) + (Ypos * 2 * ScreenBuffer->MaxX)]; + + ReadBuffer++; + Xpos++; + + if (Xpos == ScreenBuffer->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == ScreenBuffer->MaxY) + Ypos = 0; + } + } + + *ReadBuffer = 0; + + Reply->Status = STATUS_SUCCESS; + Reply->Data.ReadConsoleOutputCharReply.EndCoord.X = Xpos - ScreenBuffer->ShowX; + Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = Ypos - ScreenBuffer->ShowY; + Reply->Header.MessageSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; + Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; + + UNLOCK; + + return(Reply->Status); } /* EOF */ diff --git a/reactos/subsys/csrss/api/wapi.c b/reactos/subsys/csrss/api/wapi.c index f78796bebd0..9efe28631e0 100644 --- a/reactos/subsys/csrss/api/wapi.c +++ b/reactos/subsys/csrss/api/wapi.c @@ -1,4 +1,4 @@ -/* $Id: wapi.c,v 1.16 2001/12/02 23:34:43 dwelch Exp $ +/* $Id: wapi.c,v 1.17 2002/08/22 15:21:57 ekohl Exp $ * * reactos/subsys/csrss/api/wapi.c * @@ -53,6 +53,7 @@ static const CsrFunc CsrFuncs[] = { CsrWriteConsoleOutput, CsrFlushInputBuffer, CsrScrollConsoleScreenBuffer, + CsrReadConsoleOutputChar, 0 }; static void Thread_Api2(HANDLE ServerPort)