-Implemented ReadConsoleOutputCharacterA and CsrReadConsoleOutputChar

-Added null pointer check to FillConsoleOutputCharacterA
-Added parameter names and removed 'undocumented' label for
GetConsoleFontSize and GetCurrentConsoleFont
-Added definition of CONSOLE_FONT_INFO struct
-Added call to SetLastError(ERROR_OUTOFMEMORY) to a number of
RtlAllocateHeap return value checks

Patch by Marty Dill

svn path=/trunk/; revision=3375
This commit is contained in:
Eric Kohl 2002-08-22 15:21:57 +00:00
parent d3991649c5
commit ed21a6af20
6 changed files with 222 additions and 87 deletions

View file

@ -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;

View file

@ -37,6 +37,11 @@ typedef struct _CONSOLE_CURSOR_INFO {
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 */

View file

@ -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;
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);
}
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
if (Request == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
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->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));
Status = CsrClientCallServer(Request,
&Reply,
sizeof(CSRSS_API_REQUEST) +
nNumberOfCharsToWrite,
sizeof(CSRSS_API_REPLY));
Status = CsrClientCallServer(Request,
&Reply,
sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
sizeof(CSRSS_API_REPLY));
RtlFreeHeap(GetProcessHeap(),
0,
Request);
RtlFreeHeap(GetProcessHeap(),
0,
Request);
if (!NT_SUCCESS(Status))
{
return(FALSE);
}
if (!NT_SUCCESS(Status))
{
return(FALSE);
}
if (lpNumberOfCharsWritten != NULL)
{
*lpNumberOfCharsWritten =
if (lpNumberOfCharsWritten != NULL)
{
*lpNumberOfCharsWritten =
Reply.Data.WriteConsoleReply.NrCharactersWritten;
}
}
return(TRUE);
return(TRUE);
#endif
return FALSE;
return(FALSE);
}

View file

@ -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);

View file

@ -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 */

View file

@ -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)