-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; CHAR_INFO Fill;
} CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST, *PCSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST; } 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 \ #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \
(MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_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_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? // FIXME: it should be 80. Is this a limit due to LPC msg size?
#define CSRSS_MAX_TITLE_LENGTH 50 #define CSRSS_MAX_TITLE_LENGTH 50
@ -287,6 +302,8 @@ typedef struct
#define CSRSS_WRITE_CONSOLE_OUTPUT (0x17) #define CSRSS_WRITE_CONSOLE_OUTPUT (0x17)
#define CSRSS_FLUSH_INPUT_BUFFER (0x18) #define CSRSS_FLUSH_INPUT_BUFFER (0x18)
#define CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER (0x19) #define CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER (0x19)
#define CSRSS_READ_CONSOLE_OUTPUT_CHAR (0x1A)
/* Keep in sync with definition below. */ /* Keep in sync with definition below. */
#define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE_HEADER) + sizeof(ULONG)) #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE_HEADER) + sizeof(ULONG))
@ -321,6 +338,7 @@ typedef struct
CSRSS_FLUSH_INPUT_BUFFER_REQUEST FlushInputBufferRequest; CSRSS_FLUSH_INPUT_BUFFER_REQUEST FlushInputBufferRequest;
CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST
ScrollConsoleScreenBufferRequest; ScrollConsoleScreenBufferRequest;
CSRSS_READ_CONSOLE_OUTPUT_CHAR_REQUEST ReadConsoleOutputCharRequest;
} Data; } Data;
} CSRSS_API_REQUEST, *PCSRSS_API_REQUEST; } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
@ -344,6 +362,7 @@ typedef struct
CSRSS_CREATE_SCREEN_BUFFER_REPLY CreateScreenBufferReply; CSRSS_CREATE_SCREEN_BUFFER_REPLY CreateScreenBufferReply;
CSRSS_GET_TITLE_REPLY GetTitleReply; CSRSS_GET_TITLE_REPLY GetTitleReply;
CSRSS_WRITE_CONSOLE_OUTPUT_REPLY WriteConsoleOutputReply; CSRSS_WRITE_CONSOLE_OUTPUT_REPLY WriteConsoleOutputReply;
CSRSS_READ_CONSOLE_OUTPUT_CHAR_REPLY ReadConsoleOutputCharReply;
} Data; } Data;
} CSRSS_API_REPLY, *PCSRSS_API_REPLY; } CSRSS_API_REPLY, *PCSRSS_API_REPLY;

View file

@ -25,17 +25,22 @@
#define CONSOLE_OUTPUT_MODE_VALID (0x03) #define CONSOLE_OUTPUT_MODE_VALID (0x03)
typedef struct _CONSOLE_SCREEN_BUFFER_INFO { typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize; COORD dwSize;
COORD dwCursorPosition; COORD dwCursorPosition;
WORD wAttributes; WORD wAttributes;
SMALL_RECT srWindow; SMALL_RECT srWindow;
COORD dwMaximumWindowSize; COORD dwMaximumWindowSize;
} CONSOLE_SCREEN_BUFFER_INFO, *PCONSOLE_SCREEN_BUFFER_INFO ; } CONSOLE_SCREEN_BUFFER_INFO, *PCONSOLE_SCREEN_BUFFER_INFO ;
typedef struct _CONSOLE_CURSOR_INFO { typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize; DWORD dwSize;
BOOL bVisible; BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; } 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 */ #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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -293,11 +293,8 @@ GetConsoleFontInfo (DWORD Unknown0,
} }
DWORD STDCALL DWORD STDCALL
GetConsoleFontSize (DWORD Unknown0, GetConsoleFontSize(HANDLE hConsoleOutput,
DWORD Unknown1) DWORD nFont)
/*
* Undocumented
*/
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
@ -326,12 +323,9 @@ GetConsoleInputWaitHandle (VOID)
} }
DWORD STDCALL DWORD STDCALL
GetCurrentConsoleFont (DWORD Unknown0, GetCurrentConsoleFont(HANDLE hConsoleOutput,
DWORD Unknown1, BOOL bMaximumWindow,
DWORD Unknown2) PCONSOLE_FONT_INFO lpConsoleCurrentFont)
/*
* Undocumented
*/
{ {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
@ -662,6 +656,7 @@ WriteConsoleA(HANDLE hConsoleOutput,
CSRSS_MAX_WRITE_CONSOLE_REQUEST); CSRSS_MAX_WRITE_CONSOLE_REQUEST);
if (Request == NULL) if (Request == NULL)
{ {
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE); return(FALSE);
} }
@ -723,6 +718,7 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead); sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
if (Reply == NULL) if (Reply == NULL)
{ {
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE); return(FALSE);
} }
@ -824,7 +820,7 @@ WINBOOL STDCALL AllocConsole(VOID)
*/ */
WINBOOL STDCALL FreeConsole(VOID) WINBOOL STDCALL FreeConsole(VOID)
{ {
DbgPrint("FreeConsole() is unimplemented"); DbgPrint("FreeConsole() is unimplemented\n");
return FALSE; return FALSE;
} }
@ -886,8 +882,7 @@ SetConsoleCursorPosition(
/*-------------------------------------------------------------- /*--------------------------------------------------------------
* FillConsoleOutputCharacterA * FillConsoleOutputCharacterA
*/ */
WINBOOL WINBOOL STDCALL
STDCALL
FillConsoleOutputCharacterA( FillConsoleOutputCharacterA(
HANDLE hConsoleOutput, HANDLE hConsoleOutput,
CHAR cCharacter, CHAR cCharacter,
@ -896,23 +891,24 @@ FillConsoleOutputCharacterA(
LPDWORD lpNumberOfCharsWritten LPDWORD lpNumberOfCharsWritten
) )
{ {
CSRSS_API_REQUEST Request; CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply; CSRSS_API_REPLY Reply;
NTSTATUS Status; NTSTATUS Status;
Request.Type = CSRSS_FILL_OUTPUT; Request.Type = CSRSS_FILL_OUTPUT;
Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput; Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
Request.Data.FillOutputRequest.Char = cCharacter; Request.Data.FillOutputRequest.Char = cCharacter;
Request.Data.FillOutputRequest.Position = dwWriteCoord; Request.Data.FillOutputRequest.Position = dwWriteCoord;
Request.Data.FillOutputRequest.Length = nLength; Request.Data.FillOutputRequest.Length = nLength;
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{ {
SetLastErrorByStatus ( Status ); SetLastErrorByStatus(Status);
return FALSE; return(FALSE);
} }
*lpNumberOfCharsWritten = nLength; if (lpNumberOfCharsWritten != NULL)
return TRUE; *lpNumberOfCharsWritten = nLength;
return(TRUE);
} }
@ -1233,8 +1229,56 @@ ReadConsoleOutputCharacterA(
LPDWORD lpNumberOfCharsRead LPDWORD lpNumberOfCharsRead
) )
{ {
SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); CSRSS_API_REQUEST Request;
return FALSE; 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 ) ) if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{ {
SetLastErrorByStatus ( Status ); SetLastErrorByStatus ( Status );
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
@ -1994,6 +2038,7 @@ SetConsoleTitleW(
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL) if (Request == NULL)
{ {
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE); return(FALSE);
} }
@ -2046,6 +2091,7 @@ SetConsoleTitleA(
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL) if (Request == NULL)
{ {
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE); return(FALSE);
} }
@ -2110,52 +2156,52 @@ WriteConsoleW(
) )
{ {
#if 0 #if 0
PCSRSS_API_REQUEST Request; PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply; CSRSS_API_REPLY Reply;
NTSTATUS Status; NTSTATUS Status;
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
if (Request == NULL)
{
return(FALSE);
}
Request->Type = CSRSS_WRITE_CONSOLE; Request = RtlAllocateHeap(GetProcessHeap(),
Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput; HEAP_ZERO_MEMORY,
Request->Data.WriteConsoleRequest.NrCharactersToWrite = sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
nNumberOfCharsToWrite; if (Request == NULL)
// DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite); {
// DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer); SetLastError(ERROR_OUTOFMEMORY);
memcpy(Request->Data.WriteConsoleRequest.Buffer, return(FALSE);
lpBuffer, }
nNumberOfCharsToWrite * sizeof(WCHAR));
Status = CsrClientCallServer(Request, Request->Type = CSRSS_WRITE_CONSOLE;
&Reply, Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
sizeof(CSRSS_API_REQUEST) + Request->Data.WriteConsoleRequest.NrCharactersToWrite =
nNumberOfCharsToWrite, nNumberOfCharsToWrite;
sizeof(CSRSS_API_REPLY)); // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
// DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
memcpy(Request->Data.WriteConsoleRequest.Buffer,
lpBuffer,
nNumberOfCharsToWrite * sizeof(WCHAR));
RtlFreeHeap(GetProcessHeap(), Status = CsrClientCallServer(Request,
0, &Reply,
Request); sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status)) RtlFreeHeap(GetProcessHeap(),
{ 0,
return(FALSE); Request);
}
if (lpNumberOfCharsWritten != NULL) if (!NT_SUCCESS(Status))
{ {
*lpNumberOfCharsWritten = return(FALSE);
}
if (lpNumberOfCharsWritten != NULL)
{
*lpNumberOfCharsWritten =
Reply.Data.WriteConsoleReply.NrCharactersWritten; Reply.Data.WriteConsoleReply.NrCharactersWritten;
} }
return(TRUE); return(TRUE);
#endif #endif
return FALSE; return(FALSE);
} }

View file

@ -119,6 +119,7 @@ CSR_API(CsrGetTitle);
CSR_API(CsrWriteConsoleOutput); CSR_API(CsrWriteConsoleOutput);
CSR_API(CsrFlushInputBuffer); CSR_API(CsrFlushInputBuffer);
CSR_API(CsrScrollConsoleScreenBuffer); CSR_API(CsrScrollConsoleScreenBuffer);
CSR_API(CsrReadConsoleOutputChar);
/* print.c */ /* print.c */
VOID STDCALL DisplayString(LPCWSTR lpwString); 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 * reactos/subsys/csrss/api/conio.c
* *
@ -1885,7 +1885,7 @@ CSR_API(CsrScrollConsoleScreenBuffer)
DoFill = TRUE; DoFill = TRUE;
} }
if( Buff == ActiveConsole->ActiveBuffer ) if (Buff == ActiveConsole->ActiveBuffer)
{ {
/* Draw destination region */ /* Draw destination region */
CsrpDrawRegion(ActiveConsole->ActiveBuffer, DstRegion); CsrpDrawRegion(ActiveConsole->ActiveBuffer, DstRegion);
@ -1897,8 +1897,71 @@ CSR_API(CsrScrollConsoleScreenBuffer)
} }
} }
UNLOCK; UNLOCK;
return (Reply->Status = STATUS_SUCCESS); 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 */ /* 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 * reactos/subsys/csrss/api/wapi.c
* *
@ -53,6 +53,7 @@ static const CsrFunc CsrFuncs[] = {
CsrWriteConsoleOutput, CsrWriteConsoleOutput,
CsrFlushInputBuffer, CsrFlushInputBuffer,
CsrScrollConsoleScreenBuffer, CsrScrollConsoleScreenBuffer,
CsrReadConsoleOutputChar,
0 }; 0 };
static void Thread_Api2(HANDLE ServerPort) static void Thread_Api2(HANDLE ServerPort)