-/* $Id: console.c,v 1.81 2004/09/14 22:30:56 hbirr Exp $
+/* $Id: console.c,v 1.82 2004/11/02 20:42:05 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
#define NDEBUG
#include "../include/debug.h"
-#define _NOACHS(__X) (sizeof(__X) / sizeof((__X)[0]))
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
extern CRITICAL_SECTION ConsoleLock;
LPSTR Target,
LPSTR ExeName)
{
+ DPRINT1("AddConsoleAliasA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
LPWSTR Target,
LPWSTR ExeName)
{
+ DPRINT1("AddConsoleAliasW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+
+ DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ DPRINT1("GetConsoleAliasA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasExesW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ DPRINT1("GetConsoleAliasExesA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasExesLengthA() UNIMPLEMENTED!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasExesLengthW() UNIMPLEMENTED!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasesW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasesA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasesLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleAliasesLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* STATUS: Undocumented
*/
{
+ DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
GetConsoleFontSize(HANDLE hConsoleOutput,
DWORD nFont)
{
+ DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetConsoleInputWaitHandle() UNIMPLEMENTED!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
BOOL bMaximumWindow,
PCONSOLE_FONT_INFO lpConsoleCurrentFont)
{
+ DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
* Undocumented
*/
{
+ DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 1; /* FIXME: call csrss.exe */
}
* Undocumented
*/
{
+ DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
PHANDLE phConsole = NULL;
NTSTATUS Status = STATUS_SUCCESS;
-
if(0 == _wcsicmp(wsName, L"CONIN$"))
{
Request.Type = CSRSS_GET_INPUT_HANDLE;
* Undocumented
*/
{
+ DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* lpdwOldMode - Address of a variable that receives the old mode.
*/
{
+ DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
* Undocumented
*/
{
+ DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
DWORD Unknown2,
DWORD Unknown3)
{
+ DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
DWORD Unknown2,
DWORD Unknown3)
{
+ DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
}
+static BOOL
+IntWriteConsole(HANDLE hConsoleOutput,
+ PVOID lpBuffer,
+ DWORD nNumberOfCharsToWrite,
+ LPDWORD lpNumberOfCharsWritten,
+ LPVOID lpReserved,
+ BOOL bUnicode)
+{
+ PCSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+ USHORT nChars;
+ ULONG MessageSize, BufferSize, SizeBytes, CharSize;
+ DWORD Written = 0;
+
+ CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ BufferSize = sizeof(CSRSS_API_REQUEST) + min(nNumberOfCharsToWrite * CharSize, CSRSS_MAX_WRITE_CONSOLE_REQUEST);
+ Request = RtlAllocateHeap(GetProcessHeap(), 0, BufferSize);
+ if(Request == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ Request->Type = CSRSS_WRITE_CONSOLE;
+ Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
+ Request->Data.WriteConsoleRequest.Unicode = bUnicode;
+
+ while(nNumberOfCharsToWrite > 0)
+ {
+ nChars = min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE_REQUEST / CharSize);
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
+
+ SizeBytes = nChars * CharSize;
+
+ memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
+
+ MessageSize = CSRSS_REQUEST_HEADER_SIZE + sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + SizeBytes;
+ Status = CsrClientCallServer(Request,
+ &Reply,
+ MessageSize,
+ sizeof(CSRSS_API_REPLY));
+
+ if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+ {
+ RtlFreeHeap(GetProcessHeap(), 0, Request);
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ nNumberOfCharsToWrite -= nChars;
+ lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
+ Written += Reply.Data.WriteConsoleReply.NrCharactersWritten;
+ }
+
+ RtlFreeHeap(GetProcessHeap(), 0, Request);
+
+ if(lpNumberOfCharsWritten != NULL)
+ {
+ *lpNumberOfCharsWritten = Written;
+ }
+
+ return TRUE;
+}
+
+
/*--------------------------------------------------------------
* WriteConsoleA
*
LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved)
{
- PCSRSS_API_REQUEST Request;
- CSRSS_API_REPLY Reply;
- NTSTATUS Status;
- USHORT Size;
- ULONG MessageSize;
+ return IntWriteConsole(hConsoleOutput,
+ (PVOID)lpBuffer,
+ nNumberOfCharsToWrite,
+ lpNumberOfCharsWritten,
+ lpReserved,
+ FALSE);
+}
- Request = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REQUEST) +
- min(nNumberOfCharsToWrite,
- CSRSS_MAX_WRITE_CONSOLE_REQUEST));
- if (Request == NULL)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return(FALSE);
- }
- Request->Type = CSRSS_WRITE_CONSOLE;
- Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
- if (lpNumberOfCharsWritten != NULL)
- *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
- while (nNumberOfCharsToWrite)
- {
- if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
- {
- Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
- }
- else
- {
- Size = nNumberOfCharsToWrite;
- }
- Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
+/*--------------------------------------------------------------
+ * WriteConsoleW
+ *
+ * @implemented
+ */
+BOOL STDCALL
+WriteConsoleW(
+ HANDLE hConsoleOutput,
+ CONST VOID *lpBuffer,
+ DWORD nNumberOfCharsToWrite,
+ LPDWORD lpNumberOfCharsWritten,
+ LPVOID lpReserved
+ )
+{
+ return IntWriteConsole(hConsoleOutput,
+ (PVOID)lpBuffer,
+ nNumberOfCharsToWrite,
+ lpNumberOfCharsWritten,
+ lpReserved,
+ TRUE);
+}
- memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
- MessageSize = CSRSS_REQUEST_HEADER_SIZE +
- sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
- Status = CsrClientCallServer(Request,
- &Reply,
- MessageSize,
- sizeof(CSRSS_API_REPLY));
+static BOOL
+IntReadConsole(HANDLE hConsoleInput,
+ PVOID lpBuffer,
+ DWORD nNumberOfCharsToRead,
+ LPDWORD lpNumberOfCharsRead,
+ LPVOID lpReserved,
+ BOOL bUnicode)
+{
+ CSRSS_API_REQUEST Request;
+ PCSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+ ULONG BufferSize, CharSize, CharsRead = 0;
+
+ CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ BufferSize = sizeof(CSRSS_API_REQUEST) + min(nNumberOfCharsToRead * CharSize, CSRSS_MAX_READ_CONSOLE_REQUEST);
+ Reply = RtlAllocateHeap(GetProcessHeap(), 0, BufferSize);
+ if(Reply == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ Reply->Status = STATUS_SUCCESS;
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
- {
- RtlFreeHeap(GetProcessHeap(), 0, Request);
- SetLastErrorByStatus(Status);
- return(FALSE);
- }
- nNumberOfCharsToWrite -= Size;
- lpBuffer += Size;
+ do
+ {
+ if(Reply->Status == STATUS_PENDING)
+ {
+ Status = NtWaitForSingleObject(Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Wait for console input failed!\n");
+ break;
+ }
}
+
+ Request.Type = CSRSS_READ_CONSOLE;
+ Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
+ Request.Data.ReadConsoleRequest.Unicode = bUnicode;
+ Request.Data.ReadConsoleRequest.NrCharactersToRead = min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE_REQUEST / CharSize);
+ Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
+ Status = CsrClientCallServer(&Request,
+ Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY) + (Request.Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
+
+ if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply->Status))
+ {
+ DPRINT1("CSR returned error in ReadConsole\n");
+ SetLastErrorByStatus(Status);
+ RtlFreeHeap(GetProcessHeap(), 0, Reply);
+ return FALSE;
+ }
+
+ nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
+ memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
+ Reply->Data.ReadConsoleReply.Buffer,
+ Reply->Data.ReadConsoleReply.NrCharactersRead);
+ CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
+
+ if(Reply->Status == STATUS_NOTIFY_CLEANUP)
+ {
+ if(CharsRead > 0)
+ {
+ CharsRead--;
+ nNumberOfCharsToRead++;
+ }
+ Reply->Status = STATUS_PENDING;
+ }
+ } while(Reply->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
+
+ if(lpNumberOfCharsRead != NULL)
+ {
+ *lpNumberOfCharsRead = CharsRead;
+ }
+
+ return (nNumberOfCharsToRead == 0);
+}
- RtlFreeHeap(GetProcessHeap(), 0, Request);
- return TRUE;
+/*--------------------------------------------------------------
+ * ReadConsoleA
+ *
+ * @implemented
+ */
+BOOL STDCALL
+ReadConsoleA(HANDLE hConsoleInput,
+ LPVOID lpBuffer,
+ DWORD nNumberOfCharsToRead,
+ LPDWORD lpNumberOfCharsRead,
+ LPVOID lpReserved)
+{
+ return IntReadConsole(hConsoleInput,
+ lpBuffer,
+ nNumberOfCharsToRead,
+ lpNumberOfCharsRead,
+ lpReserved,
+ FALSE);
}
/*--------------------------------------------------------------
- * ReadConsoleA
+ * ReadConsoleW
*
* @implemented
*/
-BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
- LPVOID lpBuffer,
- DWORD nNumberOfCharsToRead,
- LPDWORD lpNumberOfCharsRead,
- LPVOID lpReserved)
+BOOL STDCALL
+ReadConsoleW(HANDLE hConsoleInput,
+ LPVOID lpBuffer,
+ DWORD nNumberOfCharsToRead,
+ LPDWORD lpNumberOfCharsRead,
+ LPVOID lpReserved)
{
- CSRSS_API_REQUEST Request;
- PCSRSS_API_REPLY Reply;
- NTSTATUS Status;
- ULONG CharsRead = 0;
-
- Reply = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
- if (Reply == NULL)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return(FALSE);
- }
-
- Request.Type = CSRSS_READ_CONSOLE;
- Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
- Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
- Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
- Status = CsrClientCallServer(&Request,
- Reply,
- sizeof(CSRSS_API_REQUEST),
- sizeof(CSRSS_API_REPLY) +
- Request.Data.ReadConsoleRequest.NrCharactersToRead);
- if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
- {
- DbgPrint( "CSR returned error in ReadConsole\n" );
- SetLastErrorByStatus ( Status );
- RtlFreeHeap( GetProcessHeap(), 0, Reply );
- return(FALSE);
- }
- if( Reply->Status == STATUS_NOTIFY_CLEANUP )
- Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
- /* There may not be any chars or lines to read yet, so wait */
- while( Reply->Status == STATUS_PENDING )
- {
- /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
- nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
- /* don't overflow caller's buffer, even if you still don't have a complete line */
- if( !nNumberOfCharsToRead )
- break;
- Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
- /* copy any chars already read to buffer */
- memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
- CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
- /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
- Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "Wait for console input failed!\n" );
- RtlFreeHeap( GetProcessHeap(), 0, Reply );
- return FALSE;
- }
- Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
- Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
- if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
- {
- SetLastErrorByStatus ( Status );
- RtlFreeHeap( GetProcessHeap(), 0, Reply );
- return FALSE;
- }
- if( Reply->Status == STATUS_NOTIFY_CLEANUP )
- {
- // delete last char
- if( CharsRead )
- {
- CharsRead--;
- nNumberOfCharsToRead++;
- }
- Reply->Status = STATUS_PENDING; // retry
- }
- }
- /* copy data to buffer, count total returned, and return */
- memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
- CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
- if (lpNumberOfCharsRead != NULL)
- *lpNumberOfCharsRead = CharsRead;
- RtlFreeHeap(GetProcessHeap(),
- 0,
- Reply);
-
- return(TRUE);
+ return IntReadConsole(hConsoleInput,
+ lpBuffer,
+ nNumberOfCharsToRead,
+ lpNumberOfCharsRead,
+ lpReserved,
+ TRUE);
}
}
+static BOOL
+IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
+ PVOID cCharacter,
+ DWORD nLength,
+ COORD dwWriteCoord,
+ LPDWORD lpNumberOfCharsWritten,
+ BOOL bUnicode)
+{
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
+ Request.Type = CSRSS_FILL_OUTPUT;
+ Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
+ Request.Data.FillOutputRequest.Unicode = bUnicode;
+ if(bUnicode)
+ Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
+ else
+ Request.Data.FillOutputRequest.Char.AsciiChar = *((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 = Reply.Data.FillOutputReply.NrCharactersWritten;
+ }
+
+ return TRUE;
+}
+
/*--------------------------------------------------------------
* FillConsoleOutputCharacterA
*
LPDWORD lpNumberOfCharsWritten
)
{
- 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);
- }
- if (lpNumberOfCharsWritten != NULL)
- *lpNumberOfCharsWritten = nLength;
- return(TRUE);
+ return IntFillConsoleOutputCharacter(hConsoleOutput,
+ &cCharacter,
+ nLength,
+ dwWriteCoord,
+ lpNumberOfCharsWritten,
+ FALSE);
}
/*--------------------------------------------------------------
* FillConsoleOutputCharacterW
*
- * @unimplemented
+ * @implemented
*/
BOOL
STDCALL
LPDWORD lpNumberOfCharsWritten
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ return IntFillConsoleOutputCharacter(hConsoleOutput,
+ &cCharacter,
+ nLength,
+ dwWriteCoord,
+ lpNumberOfCharsWritten,
+ TRUE);
}
-/*--------------------------------------------------------------
- * IntPeekConsoleInput
- *
- * INTERNAL
- */
-BOOL
-WINAPI
-IntPeekConsoleInput(
- HANDLE hConsoleInput,
- PINPUT_RECORD lpBuffer,
- DWORD nLength,
- LPDWORD lpNumberOfEventsRead,
- BOOL bUnicode
- )
+static BOOL
+IntPeekConsoleInput(HANDLE hConsoleInput,
+ PINPUT_RECORD lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsRead,
+ BOOL bUnicode)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
PVOID BufferBase;
PVOID BufferTargetBase;
- DWORD Size;
+ ULONG Size;
if(lpBuffer == NULL)
{
if(Request == NULL)
{
CsrReleaseParameterBuffer(BufferBase);
- SetLastError(ERROR_OUTOFMEMORY);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
Request->Data.PeekConsoleInputRequest.Length = nLength;
Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
- 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))
{
memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
+ RtlFreeHeap(GetProcessHeap(), 0, Request);
+ CsrReleaseParameterBuffer(BufferBase);
+
if(lpNumberOfEventsRead != NULL)
+ {
*lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
-
- RtlFreeHeap(GetProcessHeap(), 0, Request);
- CsrReleaseParameterBuffer(BufferBase);
+ }
return TRUE;
}
}
-/*--------------------------------------------------------------
- * IntReadConsoleInput
- *
- * INTERNAL
- */
-BOOL WINAPI
+static BOOL
IntReadConsoleInput(HANDLE hConsoleInput,
PINPUT_RECORD lpBuffer,
DWORD nLength,
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
- DWORD NumEventsRead;
+ ULONG Read;
NTSTATUS Status;
-
+
Request.Type = CSRSS_READ_INPUT;
Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
- Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
- sizeof(CSRSS_API_REPLY));
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+ Request.Data.ReadInputRequest.Unicode = bUnicode;
+
+ Read = 0;
+ while(nLength > 0)
+ {
+ 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(Read == 0)
+ {
+ /* we couldn't read a single record, fail */
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+ else
+ {
+ /* FIXME - fail gracefully in case we already read at least one record? */
+ break;
+ }
}
-
- while (Status == STATUS_PENDING)
+ else if(Status == STATUS_PENDING)
{
- Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE,
- 0);
- if(!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return FALSE;
- }
-
- Request.Type = CSRSS_READ_INPUT;
- Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
- Request.Data.ReadInputRequest.Unicode = bUnicode;
- 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(Read == 0)
+ {
+ Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE, 0);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ break;
+ }
+ }
+ else
+ {
+ /* nothing more to read (waiting for more input??), let's just bail */
+ break;
+ }
}
-
- NumEventsRead = 1;
- *lpBuffer = Reply.Data.ReadInputReply.Input;
- lpBuffer++;
-
- while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
+ else
{
- 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 (Status == STATUS_PENDING)
- {
- break;
- }
-
- *lpBuffer = Reply.Data.ReadInputReply.Input;
- lpBuffer++;
- NumEventsRead++;
-
+ lpBuffer[Read++] = Reply.Data.ReadInputReply.Input;
+ nLength--;
+
+ if(!Reply.Data.ReadInputReply.MoreEvents)
+ {
+ /* nothing more to read, bail */
+ break;
+ }
}
- *lpNumberOfEventsRead = NumEventsRead;
+ }
- return TRUE;
+ if(lpNumberOfEventsRead != NULL)
+ {
+ *lpNumberOfEventsRead = Read;
+ }
+
+ return (Read > 0);
}
}
-/*--------------------------------------------------------------
- * WriteConsoleInputA
- *
- * @implemented
- */
-BOOL
-WINAPI
-WriteConsoleInputA(
- HANDLE hConsoleInput,
- CONST INPUT_RECORD *lpBuffer,
- DWORD nLength,
- LPDWORD lpNumberOfEventsWritten
- )
+static BOOL
+IntWriteConsoleInput(HANDLE hConsoleInput,
+ PINPUT_RECORD lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsWritten,
+ BOOL bUnicode)
{
- PCSRSS_API_REQUEST Request;
+ CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
PVOID BufferBase, BufferTargetBase;
NTSTATUS Status;
DWORD Size;
-
+
if(lpBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
-
+
Size = nLength * sizeof(INPUT_RECORD);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
SetLastErrorByStatus(Status);
return FALSE;
}
-
- Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
- if(Request == NULL)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- CsrReleaseParameterBuffer(BufferBase);
- return FALSE;
- }
- Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
- Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
- Request->Data.WriteConsoleInputRequest.Length = nLength;
- Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
+ Request.Type = CSRSS_WRITE_CONSOLE_INPUT;
+ Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
+ Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
+ Request.Data.WriteConsoleInputRequest.Length = nLength;
+ Request.Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
+
+ Status = CsrClientCallServer(&Request, &Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY));
+
+ CsrReleaseParameterBuffer(BufferBase);
- Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
- RtlFreeHeap(GetProcessHeap(), 0, Request);
- CsrReleaseParameterBuffer(BufferBase);
+ SetLastErrorByStatus(Status);
return FALSE;
}
if(lpNumberOfEventsWritten != NULL)
+ {
*lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
-
- RtlFreeHeap(GetProcessHeap(), 0, Request);
- CsrReleaseParameterBuffer(BufferBase);
-
+ }
+
return TRUE;
}
/*--------------------------------------------------------------
- * WriteConsoleInputW
+ * WriteConsoleInputA
*
- * @unimplemented
+ * @implemented
*/
BOOL
WINAPI
-WriteConsoleInputW(
+WriteConsoleInputA(
HANDLE hConsoleInput,
CONST INPUT_RECORD *lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsWritten
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ return IntWriteConsoleInput(hConsoleInput,
+ (PINPUT_RECORD)lpBuffer,
+ nLength,
+ lpNumberOfEventsWritten,
+ FALSE);
}
/*--------------------------------------------------------------
- * IntReadConsoleOutput
+ * WriteConsoleInputW
*
- * INTERNAL
+ * @implemented
*/
BOOL
WINAPI
-IntReadConsoleOutput(
- HANDLE hConsoleOutput,
- PCHAR_INFO lpBuffer,
- COORD dwBufferSize,
- COORD dwBufferCoord,
- PSMALL_RECT lpReadRegion,
- BOOL bUnicode
+WriteConsoleInputW(
+ HANDLE hConsoleInput,
+ CONST INPUT_RECORD *lpBuffer,
+ DWORD nLength,
+ LPDWORD lpNumberOfEventsWritten
)
+{
+ return IntWriteConsoleInput(hConsoleInput,
+ (PINPUT_RECORD)lpBuffer,
+ nLength,
+ lpNumberOfEventsWritten,
+ TRUE);
+}
+
+
+static BOOL
+IntReadConsoleOutput(HANDLE hConsoleOutput,
+ PCHAR_INFO lpBuffer,
+ COORD dwBufferSize,
+ COORD dwBufferCoord,
+ PSMALL_RECT lpReadRegion,
+ BOOL bUnicode)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
if(Request == NULL)
{
- SetLastError(ERROR_OUTOFMEMORY);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
- 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))
{
SetLastErrorByStatus(Status);
SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
- *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
+ *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
+
return TRUE;
}
}
-/*--------------------------------------------------------------
- * IntWriteConsoleOutput
- *
- * INTERNAL
- */
-BOOL WINAPI
-IntWriteConsoleOutput(HANDLE hConsoleOutput,
+static BOOL
+IntWriteConsoleOutput(HANDLE hConsoleOutput,
CONST CHAR_INFO *lpBuffer,
- COORD dwBufferSize,
- COORD dwBufferCoord,
- PSMALL_RECT lpWriteRegion,
- BOOL bUnicode)
+ COORD dwBufferSize,
+ COORD dwBufferCoord,
+ PSMALL_RECT lpWriteRegion,
+ BOOL bUnicode)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
if (Request == NULL)
{
CsrReleaseParameterBuffer(BufferBase);
- SetLastError(ERROR_OUTOFMEMORY);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
Status = CsrClientCallServer(Request, &Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
+
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
- *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
+
+ *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
+
return(TRUE);
}
}
-/*--------------------------------------------------------------
- * ReadConsoleOutputCharacterA
- *
- * @implemented
- */
-BOOL
-WINAPI
-ReadConsoleOutputCharacterA(
- HANDLE hConsoleOutput,
- LPSTR lpCharacter,
- DWORD nLength,
- COORD dwReadCoord,
- LPDWORD lpNumberOfCharsRead
- )
+static BOOL
+IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
+ PVOID lpCharacter,
+ DWORD nLength,
+ COORD dwReadCoord,
+ LPDWORD lpNumberOfCharsRead,
+ BOOL bUnicode)
{
CSRSS_API_REQUEST Request;
PCSRSS_API_REPLY Reply;
NTSTATUS Status;
- DWORD Size;
+ ULONG nChars, SizeBytes, CharSize;
+ DWORD CharsRead = 0;
+
+ CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize);
+ SizeBytes = nChars * CharSize;
Reply = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REPLY) +
- min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR));
- if (Reply == NULL)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return(FALSE);
- }
+ sizeof(CSRSS_API_REPLY) + SizeBytes);
+ if(Reply == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
- if (lpNumberOfCharsRead != NULL)
- *lpNumberOfCharsRead = nLength;
Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+ Request.Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
- while (nLength != 0)
+ while(nLength > 0)
+ {
+ DWORD BytesRead;
+
+ Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
+
+ Status = CsrClientCallServer(&Request,
+ Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY) + SizeBytes);
+ if(!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
{
- if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
- Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
- else
- Size = nLength;
+ SetLastErrorByStatus(Status);
+ break;
+ }
- Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
+ BytesRead = Reply->Data.ReadConsoleOutputCharReply.CharsRead * CharSize;
+ memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], BytesRead);
+ lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
+ CharsRead += Reply->Data.ReadConsoleOutputCharReply.CharsRead;
+ nLength -= Reply->Data.ReadConsoleOutputCharReply.CharsRead;
+
+ Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
+ }
- 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);
- }
+ RtlFreeHeap(GetProcessHeap(), 0, Reply);
+
+ if(lpNumberOfCharsRead != NULL)
+ {
+ *lpNumberOfCharsRead = CharsRead;
+ }
- memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
- lpCharacter += Size;
- nLength -= Size;
- Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
- }
+ return TRUE;
+}
- RtlFreeHeap(GetProcessHeap(), 0, Reply);
- return(TRUE);
+/*--------------------------------------------------------------
+ * ReadConsoleOutputCharacterA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+ReadConsoleOutputCharacterA(
+ HANDLE hConsoleOutput,
+ LPSTR lpCharacter,
+ DWORD nLength,
+ COORD dwReadCoord,
+ LPDWORD lpNumberOfCharsRead
+ )
+{
+ return IntReadConsoleOutputCharacter(hConsoleOutput,
+ (PVOID)lpCharacter,
+ nLength,
+ dwReadCoord,
+ lpNumberOfCharsRead,
+ FALSE);
}
/*--------------------------------------------------------------
* ReadConsoleOutputCharacterW
*
- * @unimplemented
+ * @implemented
*/
BOOL
WINAPI
LPDWORD lpNumberOfCharsRead
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ return IntReadConsoleOutputCharacter(hConsoleOutput,
+ (PVOID)lpCharacter,
+ nLength,
+ dwReadCoord,
+ lpNumberOfCharsRead,
+ TRUE);
}
DWORD Size, i;
Reply = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REPLY) +
- min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
+ sizeof(CSRSS_API_REPLY) + min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
if (Reply == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
}
-/*--------------------------------------------------------------
- * WriteConsoleOutputCharacterA
- *
- * @implemented
- */
-BOOL WINAPI
-WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
- LPCSTR lpCharacter,
- DWORD nLength,
- COORD dwWriteCoord,
- LPDWORD lpNumberOfCharsWritten)
+static BOOL
+IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
+ PVOID lpCharacter,
+ DWORD nLength,
+ COORD dwWriteCoord,
+ LPDWORD lpNumberOfCharsWritten,
+ BOOL bUnicode)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
- WORD Size;
+ ULONG SizeBytes, CharSize, nChars;
+ DWORD Written = 0;
+
+ CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_REQUEST / CharSize);
+ SizeBytes = nChars * CharSize;
Request = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REQUEST) +
- min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
- if( !Request )
- {
- SetLastError( ERROR_OUTOFMEMORY );
- return FALSE;
- }
+ sizeof(CSRSS_API_REQUEST) + (nChars * CharSize));
+ if(Request == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
+ Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
- if( lpNumberOfCharsWritten )
- *lpNumberOfCharsWritten = nLength;
- while( nLength )
+
+ while(nLength > 0)
+ {
+ DWORD BytesWrite;
+
+ Request->Data.WriteConsoleOutputCharRequest.Length = min(nLength, nChars);
+ BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
+
+ memcpy(&Request->Data.WriteConsoleOutputCharRequest.String[0], lpCharacter, BytesWrite);
+
+ Status = CsrClientCallServer(Request, &Reply,
+ sizeof(CSRSS_API_REQUEST) + BytesWrite,
+ sizeof(CSRSS_API_REPLY));
+
+ if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
- Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
- Request->Data.WriteConsoleOutputCharRequest.Length = Size;
- memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
- lpCharacter,
- Size );
- Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
- if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
- {
- RtlFreeHeap( GetProcessHeap(), 0, Request );
- SetLastErrorByStatus ( Status );
- return FALSE;
- }
- nLength -= Size;
- lpCharacter += Size;
- Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+ RtlFreeHeap(GetProcessHeap(), 0, Request);
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
+
+ nLength -= Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten;
+ lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten * CharSize));
+ Written += Reply.Data.WriteConsoleOutputCharReply.NrCharactersWritten;
+
+ Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
+ }
+
+ RtlFreeHeap(GetProcessHeap(), 0, Request);
- RtlFreeHeap( GetProcessHeap(), 0, Request );
+ if(lpNumberOfCharsWritten != NULL)
+ {
+ *lpNumberOfCharsWritten = Written;
+ }
+
return TRUE;
}
+/*--------------------------------------------------------------
+ * WriteConsoleOutputCharacterA
+ *
+ * @implemented
+ */
+BOOL WINAPI
+WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
+ LPCSTR lpCharacter,
+ DWORD nLength,
+ COORD dwWriteCoord,
+ LPDWORD lpNumberOfCharsWritten)
+{
+ return IntWriteConsoleOutputCharacter(hConsoleOutput,
+ (PVOID)lpCharacter,
+ nLength,
+ dwWriteCoord,
+ lpNumberOfCharsWritten,
+ FALSE);
+}
+
+
/*--------------------------------------------------------------
* WriteConsoleOutputCharacterW
*
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
- PCSRSS_API_REQUEST Request;
- CSRSS_API_REPLY Reply;
- NTSTATUS Status;
- WORD Size;
-
- Request = RtlAllocateHeap(GetProcessHeap(), 0,
- sizeof(CSRSS_API_REQUEST) +
- min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
- if( !Request )
- {
- SetLastError( ERROR_OUTOFMEMORY );
- return FALSE;
- }
- Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
- Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
- Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
- if( lpNumberOfCharsWritten )
- *lpNumberOfCharsWritten = nLength;
- while( nLength )
- {
- Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
- Request->Data.WriteConsoleOutputCharRequest.Length = Size;
- Status = RtlUnicodeToOemN (&Request->Data.WriteConsoleOutputCharRequest.String[0],
- Size,
- NULL,
- (PWCHAR)lpCharacter,
- Size * sizeof(WCHAR));
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap (GetProcessHeap(), 0, Request);
- SetLastErrorByStatus (Status);
- return FALSE;
- }
-
- Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
- if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
- {
- RtlFreeHeap( GetProcessHeap(), 0, Request );
- SetLastErrorByStatus ( Status );
- return FALSE;
- }
- nLength -= Size;
- lpCharacter += Size;
- Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
- }
-
- RtlFreeHeap( GetProcessHeap(), 0, Request );
- return TRUE;
+ return IntWriteConsoleOutputCharacter(hConsoleOutput,
+ (PVOID)lpCharacter,
+ nLength,
+ dwWriteCoord,
+ lpNumberOfCharsWritten,
+ TRUE);
}
HANDLE hConsoleOutput
)
{
-#if 1 /* FIXME: */
- COORD Coord = {80,25};
-
-/* TO DO */
- return Coord;
-#endif
+ COORD Coord = {80,25};
+ DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return Coord;
}
LPDWORD lpNumberOfMouseButtons
)
{
-/* TO DO */
- return FALSE;
+ DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
COORD dwSize
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
/*--------------------------------------------------------------
}
-/*--------------------------------------------------------------
- * ScrollConsoleScreenBufferA
- *
- * @implemented
- */
-BOOL
-WINAPI
-ScrollConsoleScreenBufferA(
- HANDLE hConsoleOutput,
- CONST SMALL_RECT *lpScrollRectangle,
- CONST SMALL_RECT *lpClipRectangle,
- COORD dwDestinationOrigin,
- CONST CHAR_INFO *lpFill
- )
+static BOOL
+IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
+ PSMALL_RECT lpScrollRectangle,
+ PSMALL_RECT lpClipRectangle,
+ COORD dwDestinationOrigin,
+ PCHAR_INFO lpFill,
+ BOOL bUnicode)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
+ Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
- if (lpClipRectangle != NULL)
- {
- Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
- Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
- }
+ if(lpClipRectangle != NULL)
+ {
+ Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
+ Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
+ }
else
- {
- Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
- }
+ {
+ Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
+ }
Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
- 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))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
- if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
- {
- SetLastErrorByStatus ( Status );
- return FALSE;
- }
return TRUE;
}
+/*--------------------------------------------------------------
+ * ScrollConsoleScreenBufferA
+ *
+ * @implemented
+ */
+BOOL
+WINAPI
+ScrollConsoleScreenBufferA(
+ HANDLE hConsoleOutput,
+ CONST SMALL_RECT *lpScrollRectangle,
+ CONST SMALL_RECT *lpClipRectangle,
+ COORD dwDestinationOrigin,
+ CONST CHAR_INFO *lpFill
+ )
+{
+ return IntScrollConsoleScreenBuffer(hConsoleOutput,
+ (PSMALL_RECT)lpScrollRectangle,
+ (PSMALL_RECT)lpClipRectangle,
+ dwDestinationOrigin,
+ (PCHAR_INFO)lpFill,
+ FALSE);
+}
+
+
/*--------------------------------------------------------------
* ScrollConsoleScreenBufferW
*
- * @unimplemented
+ * @implemented
*/
BOOL
WINAPI
CONST CHAR_INFO *lpFill
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ return IntScrollConsoleScreenBuffer(hConsoleOutput,
+ (PSMALL_RECT)lpScrollRectangle,
+ (PSMALL_RECT)lpClipRectangle,
+ dwDestinationOrigin,
+ (PCHAR_INFO)lpFill,
+ TRUE);
}
CONST SMALL_RECT *lpConsoleWindow
)
{
-/* TO DO */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
+ DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
DWORD dwProcessGroupId
)
{
- /* TO DO */
+ DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
}
-/*--------------------------------------------------------------
- * ReadConsoleW
- *
- * @unimplemented
- */
-BOOL
-WINAPI
-ReadConsoleW(
- HANDLE hConsoleInput,
- LPVOID lpBuffer,
- DWORD nNumberOfCharsToRead,
- LPDWORD lpNumberOfCharsRead,
- LPVOID lpReserved
- )
-{
-/* --- TO DO --- */
- DbgPrint("%s unimplemented\n", __FUNCTION__);
- return FALSE;
-}
-
-
-/*--------------------------------------------------------------
- * WriteConsoleW
- *
- * @unimplemented
- */
-BOOL
-WINAPI
-WriteConsoleW(
- HANDLE hConsoleOutput,
- CONST VOID *lpBuffer,
- DWORD nNumberOfCharsToWrite,
- LPDWORD lpNumberOfCharsWritten,
- LPVOID lpReserved
- )
-{
- DbgPrint("%s unimplemented\n", __FUNCTION__);
-#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)
- {
- 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));
-
- Status = CsrClientCallServer(Request,
- &Reply,
- sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
- sizeof(CSRSS_API_REPLY));
-
- RtlFreeHeap(GetProcessHeap(),
- 0,
- Request);
-
- if (!NT_SUCCESS(Status))
- {
- return(FALSE);
- }
-
- if (lpNumberOfCharsWritten != NULL)
- {
- *lpNumberOfCharsWritten =
- Reply.Data.WriteConsoleReply.NrCharactersWritten;
- }
-
- return(TRUE);
-#endif
- return(FALSE);
-}
-
-
/*--------------------------------------------------------------
* CreateConsoleScreenBuffer
*
GetConsoleProcessList(LPDWORD lpdwProcessList,
DWORD dwProcessCount)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ DPRINT1("GetConsoleProcessList(0x%x, 0x%x) UNIMPLEMENTED!\n", lpdwProcessList, dwProcessCount);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
}
BOOL STDCALL
GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
BOOL STDCALL
AttachConsole(DWORD dwProcessId)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
/*--------------------------------------------------------------
-/* $Id: conio.c,v 1.15 2004/09/10 22:14:52 gvg Exp $
+/* $Id: conio.c,v 1.16 2004/11/02 20:42:06 weiden Exp $
*
* reactos/subsys/csrss/win32csr/conio.c
*
#define ConioIsRectEmpty(Rect) \
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
+#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+
+#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
+ MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
+
+#define ConsoleUnicodeToAnsiN(Console, dChar, sWChar, nChars) \
+ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), (nChars), (dChar), (nChars) * sizeof(WCHAR), NULL, NULL)
+
/* FUNCTIONS *****************************************************************/
STATIC NTSTATUS FASTCALL
PLIST_ENTRY CurrentEntry;
ConsoleInput *Input;
PCHAR Buffer;
+ PWCHAR UnicodeBuffer;
int i;
- ULONG nNumberOfCharsToRead;
+ ULONG nNumberOfCharsToRead, CharSize;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrReadConsole\n");
+
+ CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
/* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
- nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : Request->Data.ReadConsoleRequest.NrCharactersToRead;
+ nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE_REQUEST / CharSize);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
Buffer = Reply->Data.ReadConsoleReply.Buffer;
+ UnicodeBuffer = (PWCHAR)Buffer;
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
&Console);
if (! NT_SUCCESS(Status))
/* only pay attention to valid ascii chars, on key down */
if (KEY_EVENT == Input->InputEvent.EventType
&& Input->InputEvent.Event.KeyEvent.bKeyDown
- && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+ && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0')
{
/* backspace handling */
if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
&& (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted))
{
ConioWriteConsole(Console, Console->ActiveBuffer,
- &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
+ &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
}
if (0 != i)
{
}
else
{ /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
- Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
- Reply->Status = STATUS_NOTIFY_CLEANUP;
Console->WaitingChars--;
- HeapFree(Win32CsrApiHeap, 0, Input);
ConioUnlockConsole(Console);
+ HeapFree(Win32CsrApiHeap, 0, Input);
+ Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
+ Reply->Status = STATUS_NOTIFY_CLEANUP;
return STATUS_NOTIFY_CLEANUP;
}
Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
/* do not copy backspace to buffer */
else
{
- Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
+ if(Request->Data.ReadConsoleRequest.Unicode)
+ UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
+ else
+ Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
}
/* echo to screen if enabled and we did not already echo the char */
if (0 != (Console->Mode & ENABLE_ECHO_INPUT)
}
else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
{
- if (0 == Console->WaitingLines || '\n' != Buffer[i - 1])
+ if (0 == Console->WaitingLines ||
+ (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
{
Reply->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
}
{
Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */
}
- Reply->Header.MessageSize += i;
+ Reply->Header.MessageSize += i * CharSize;
ConioUnlockConsole(Console);
return Reply->Status;
}
STATIC VOID FASTCALL
-ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ConioFillRegion(PCSRSS_CONSOLE Console,
+ PCSRSS_SCREEN_BUFFER ScreenBuffer,
RECT *Region,
- CHAR_INFO CharInfo)
+ CHAR_INFO *CharInfo,
+ BOOL bUnicode)
{
SHORT X, Y;
DWORD Offset;
DWORD Delta;
ULONG i;
+ CHAR Char;
+
+ if(bUnicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &Char, &CharInfo->Char.UnicodeChar);
+ else
+ Char = CharInfo->Char.AsciiChar;
Y = (Region->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
Offset = (Y * ScreenBuffer->MaxX + Region->left + ScreenBuffer->ShowX) * 2;
{
for (X = Region->left; X <= Region->right; X++)
{
- SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
+ SET_CELL_BUFFER(ScreenBuffer, Offset, Char, CharInfo->Attributes);
}
if (++Y == ScreenBuffer->MaxY)
{
{
if (InputEvent->EventType == KEY_EVENT)
{
- WideCharToMultiByte(Console->CodePage, 0,
- &InputEvent->Event.KeyEvent.uChar.UnicodeChar, 1,
- &InputEvent->Event.KeyEvent.uChar.AsciiChar, 1,
- NULL, NULL);
+ ConsoleUnicodeCharToAnsiChar(Console,
+ &InputEvent->Event.KeyEvent.uChar.AsciiChar,
+ &InputEvent->Event.KeyEvent.uChar.UnicodeChar);
}
}
BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
PCSRSS_SCREEN_BUFFER Buff;
PCSRSS_CONSOLE Console;
+ ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
DPRINT("CsrWriteConsole\n");
if (Request->Header.DataSize
< sizeof(CSRSS_WRITE_CONSOLE_REQUEST) - 1
- + Request->Data.WriteConsoleRequest.NrCharactersToWrite)
+ + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
{
DPRINT1("Invalid request size\n");
return Reply->Status = STATUS_INVALID_PARAMETER;
return Reply->Status = Status;
}
+ if(Request->Data.WriteConsoleRequest.Unicode)
+ {
+ ConsoleUnicodeToAnsiN(Console, Buffer, (PWCHAR)Buffer, Request->Data.WriteConsoleRequest.NrCharactersToWrite);
+ }
+
Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
{
return Reply->Status = Status;
}
- ConioWriteConsole(Console, Buff, Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+ Reply->Status = ConioWriteConsole(Console, Buff, Buffer,
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
ConioUnlockScreenBuffer(Buff);
if (NULL != Console)
{
ConioUnlockConsole(Console);
}
+ if(NT_SUCCESS(Reply->Status))
+ {
+ Reply->Data.WriteConsoleReply.NrCharactersWritten = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
+ }
+ else
+ {
+ Reply->Data.WriteConsoleReply.NrCharactersWritten = 0; /* FIXME - return the actual number of characters written! */
+ }
+
return Reply->Status = STATUS_SUCCESS;
}
STATIC VOID FASTCALL
ConioProcessChar(PCSRSS_CONSOLE Console,
- ConsoleInput *KeyEventRecord)
+ ConsoleInput *KeyEventRecord)
{
BOOL updown;
BOOL bClientWake = FALSE;
{
ConioWriteConsole(Console, Console->ActiveBuffer,
&KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
- 1, TRUE);
+ 1, TRUE);
}
HeapFree(Win32CsrApiHeap, 0, TempInput);
RemoveEntryList(&KeyEventRecord->ListEntry);
if (! ConInRec->Fake || ! ConInRec->NotChar)
{
+ /* FIXME - convert to ascii */
ConioProcessChar(Console, ConInRec);
}
else
PBYTE Buffer;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length;
+ DWORD X, Y, Length, CharSize, Written = 0;
RECT UpdateRect;
DPRINT("CsrWriteConsoleOutputChar\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+
+ CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
if (Request->Header.DataSize
< sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST) - 1
- + Request->Data.WriteConsoleOutputCharRequest.Length)
+ + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
{
DPRINT1("Invalid request size\n");
return Reply->Status = STATUS_INVALID_PARAMETER;
return Reply->Status = Status;
}
+ if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
+ {
+ ConsoleUnicodeToAnsiN(Console, String, (PWCHAR)String, Request->Data.WriteConsoleOutputCharRequest.Length);
+ }
+
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
&Buff);
while (Length--)
{
*Buffer = *String++;
+ Written++;
Buffer += 2;
if (++X == Buff->MaxX)
{
ConioUnlockConsole(Console);
}
+ Reply->Data.WriteConsoleOutputCharReply.NrCharactersWritten = Written;
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length;
+ DWORD X, Y, Length, Written = 0;
BYTE Char;
PBYTE Buffer;
RECT UpdateRect;
X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
- Char = Request->Data.FillOutputRequest.Char;
+ if(Request->Data.FillOutputRequest.Unicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
+ else
+ Char = Request->Data.FillOutputRequest.Char.AsciiChar;
Length = Request->Data.FillOutputRequest.Length;
while (Length--)
{
*Buffer = Char;
Buffer += 2;
+ Written++;
if (++X == Buff->MaxX)
{
if (++Y == Buff->MaxY)
ConioUnlockConsole(Console);
}
+ Reply->Data.FillOutputReply.NrCharactersWritten = Written;
return Reply->Status;
}
if (Request->Data.ReadInputRequest.Unicode == FALSE)
{
- ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input);
+ ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input); /* FIXME */
}
if (Input->InputEvent.EventType == KEY_EVENT)
if (Request->Data.WriteConsoleOutputRequest.Unicode)
{
CHAR AsciiChar;
- WideCharToMultiByte(Console->OutputCodePage, 0,
- &CurCharInfo->Char.UnicodeChar, 1,
- &AsciiChar, 1, NULL, NULL);
+ ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
SET_CELL_BUFFER(Buff, Offset, AsciiChar, CurCharInfo->Attributes);
}
else
/* FIXME: The subtracted rectangle is off by one line */
FillRegion.top += 1;
- ConioFillRegion(Buff, &FillRegion, Fill);
+ ConioFillRegion(Console, Buff, &FillRegion, &Fill, Request->Data.ScrollConsoleScreenBufferRequest.Unicode);
DoFill = TRUE;
}
CSR_API(CsrReadConsoleOutputChar)
{
NTSTATUS Status;
+ PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
DWORD Xpos, Ypos;
BYTE* ReadBuffer;
DWORD i;
+ ULONG CharSize;
+ CHAR Char;
DPRINT("CsrReadConsoleOutputChar\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
ReadBuffer = Reply->Data.ReadConsoleOutputCharReply.String;
+
+ CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
{
- *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+ Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+
+ if(Request->Data.ReadConsoleOutputCharRequest.Unicode)
+ {
+ ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
+ ReadBuffer += sizeof(WCHAR);
+ }
+ else
+ *(ReadBuffer++) = Char;
- ReadBuffer++;
Xpos++;
if (Xpos == Buff->MaxX)
Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
ConioUnlockScreenBuffer(Buff);
+ if (NULL != Console)
+ {
+ ConioUnlockConsole(Console);
+ }
+
+ Reply->Data.ReadConsoleOutputCharReply.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Reply->Data.ReadConsoleOutputCharReply.String) / CharSize;
return Reply->Status;
}
Record->InputEvent = *InputRecord++;
if (KEY_EVENT == Record->InputEvent.EventType)
{
+ /* FIXME - convert from unicode to ascii!! */
ConioProcessChar(Console, Record);
}
}