reactos/reactos/lib/kernel32/misc/console.c
Gé van Geldorp 4e366db69f CSRSS code reshuffle
svn path=/trunk/; revision=6845
2003-12-02 11:38:47 +00:00

3198 lines
70 KiB
C

/* $Id: console.c,v 1.70 2003/12/02 11:38:46 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/misc/console.c
* PURPOSE: Win32 server console functions
* PROGRAMMER: James Tabor
* <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
* UPDATE HISTORY:
* 199901?? ?? Created
* 19990204 EA SetConsoleTitleA
* 19990306 EA Stubs
*/
/* INCLUDES ******************************************************************/
#include <k32.h>
#define NDEBUG
#include <kernel32/kernel32.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;
extern BOOL WINAPI IsDebuggerPresent(VOID);
/* GLOBALS *******************************************************************/
static BOOL IgnoreCtrlEvents = FALSE;
static PHANDLER_ROUTINE* CtrlHandlers = NULL;
static ULONG NrCtrlHandlers = 0;
/* Default Console Control Handler *******************************************/
BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
{
switch(Event)
{
case CTRL_C_EVENT:
DPRINT("Ctrl-C Event\n");
ExitProcess(0);
break;
case CTRL_BREAK_EVENT:
DPRINT("Ctrl-Break Event\n");
ExitProcess(0);
break;
case CTRL_SHUTDOWN_EVENT:
DPRINT("Ctrl Shutdown Event\n");
break;
case CTRL_CLOSE_EVENT:
DPRINT("Ctrl Close Event\n");
break;
case CTRL_LOGOFF_EVENT:
DPRINT("Ctrl Logoff Event\n");
break;
}
// ExitProcess((UINT)&ExitCode);
return TRUE;
}
__declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag)
{
DWORD nExitCode = 0;
DWORD nCode = CodeAndFlag & MAXLONG;
UINT i;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
switch(nCode)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
{
if(IsDebuggerPresent())
{
EXCEPTION_RECORD erException;
erException.ExceptionCode =
(nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
erException.ExceptionFlags = 0;
erException.ExceptionRecord = NULL;
erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
erException.NumberParameters = 0;
RtlRaiseException(&erException);
}
RtlEnterCriticalSection(&ConsoleLock);
if(!(nCode == CTRL_C_EVENT &&
NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
{
for(i = NrCtrlHandlers; i > 0; -- i)
if(CtrlHandlers[i - 1](nCode)) break;
}
RtlLeaveCriticalSection(&ConsoleLock);
ExitThread(0);
}
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
break;
default: ExitThread(0);
}
RtlEnterCriticalSection(&ConsoleLock);
if(!(nCode == CTRL_C_EVENT &&
NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
{
i = NrCtrlHandlers;
while(i > 0)
{
if (i == 1 && (CodeAndFlag & MINLONG) &&
(nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
break;
if(CtrlHandlers[i - 1](nCode))
{
switch(nCode)
{
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
nExitCode = CodeAndFlag;
}
break;
}
--i;
}
}
RtlLeaveCriticalSection(&ConsoleLock);
ExitThread(nExitCode);
}
/* FUNCTIONS *****************************************************************/
/*
* @unimplemented
*/
BOOL STDCALL
AddConsoleAliasA (LPSTR Source,
LPSTR Target,
LPSTR ExeName)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL STDCALL
AddConsoleAliasW (LPWSTR Source,
LPWSTR Target,
LPWSTR ExeName)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL STDCALL
ConsoleMenuControl (HANDLE hConsole,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @implemented
*/
HANDLE STDCALL
DuplicateConsoleHandle (HANDLE hConsole,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
if (IsConsoleHandle (hConsole) == FALSE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
Request.Type = CSRSS_DUPLICATE_HANDLE;
Request.Data.DuplicateHandleRequest.Handle = hConsole;
Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
Status = CsrClientCallServer(&Request,
&Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
return Reply.Data.DuplicateHandleReply.Handle;
}
/*
* @unimplemented
*/
DWORD STDCALL
ExpungeConsoleCommandHistoryW (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
ExpungeConsoleCommandHistoryA (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasW (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasA (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasExesW (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasExesA (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasExesLengthA (VOID)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasExesLengthW (VOID)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasesW (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasesA (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasesLengthW (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleAliasesLengthA (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleCommandHistoryW (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleCommandHistoryA (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleCommandHistoryLengthW (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleCommandHistoryLengthA (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleDisplayMode (LPDWORD lpdwMode)
/*
* FUNCTION: Get the console display mode
* ARGUMENTS:
* lpdwMode - Address of variable that receives the current value
* of display mode
* STATUS: Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleFontInfo (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleFontSize(HANDLE hConsoleOutput,
DWORD nFont)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @implemented
*/
DWORD STDCALL
GetConsoleHardwareState (HANDLE hConsole,
DWORD Flags,
PDWORD State)
/*
* Undocumented
*/
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
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;
}
*State = Reply.Data.ConsoleHardwareStateReply.State;
return TRUE;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetConsoleInputWaitHandle (VOID)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
DWORD STDCALL
GetCurrentConsoleFont(HANDLE hConsoleOutput,
BOOL bMaximumWindow,
PCONSOLE_FONT_INFO lpConsoleCurrentFont)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
ULONG STDCALL
GetNumberOfConsoleFonts (VOID)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 1; /* FIXME: call csrss.exe */
}
/*
* @unimplemented
*/
DWORD STDCALL
InvalidateConsoleDIBits (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
HANDLE STDCALL
OpenConsoleW (LPWSTR wsName,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwCreationDistribution)
/*
* Undocumented
*/
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
PHANDLE phConsole = NULL;
NTSTATUS Status = STATUS_SUCCESS;
if(0 == _wcsicmp(wsName, L"CONIN$"))
{
Request.Type = CSRSS_GET_INPUT_HANDLE;
phConsole = & Reply.Data.GetInputHandleReply.InputHandle;
}
else if (0 == _wcsicmp(wsName, L"CONOUT$"))
{
Request.Type = CSRSS_GET_OUTPUT_HANDLE;
phConsole = & Reply.Data.GetOutputHandleReply.OutputHandle;
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess)
{
SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
if (OPEN_EXISTING != dwCreationDistribution)
{
SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
Status = CsrClientCallServer(& Request,
& Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
return(*phConsole);
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleCommandHistoryMode (DWORD dwMode)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleCursor (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleDisplayMode (HANDLE hOut,
DWORD dwNewMode,
LPDWORD lpdwOldMode)
/*
* FUNCTION: Set the console display mode.
* ARGUMENTS:
* hOut - Standard output handle.
* dwNewMode - New mode.
* lpdwOldMode - Address of a variable that receives the old mode.
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleFont (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @implemented
*/
WINBOOL STDCALL
SetConsoleHardwareState (HANDLE hConsole,
DWORD Flags,
DWORD State)
/*
* Undocumented
*/
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
Request.Data.ConsoleHardwareStateRequest.State = State;
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;
}
return TRUE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleKeyShortcuts (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleMaximumWindowSize (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleMenuClose (DWORD Unknown0)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleNumberOfCommandsA (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsoleNumberOfCommandsW (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetConsolePalette (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
WINBOOL STDCALL
SetLastConsoleEventActive (VOID)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
DWORD STDCALL
ShowConsoleCursor (DWORD Unknown0,
DWORD Unknown1)
/*
* Undocumented
*/
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* FUNCTION: Checks whether the given handle is a valid console handle.
* ARGUMENTS:
* Handle - Handle to be checked
* RETURNS:
* TRUE: Handle is a valid console handle
* FALSE: Handle is not a valid console handle.
* STATUS: Officially undocumented
*
* @implemented
*/
BOOL STDCALL
VerifyConsoleIoHandle(HANDLE Handle)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_VERIFY_HANDLE;
Request.Data.VerifyHandleRequest.Handle = Handle;
Status = CsrClientCallServer(&Request,
&Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return (BOOL)NT_SUCCESS(Reply.Status);
}
/*
* @unimplemented
*/
DWORD STDCALL
WriteConsoleInputVDMA (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
DWORD STDCALL
WriteConsoleInputVDMW (DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @implemented
*/
WINBOOL STDCALL
CloseConsoleHandle(HANDLE Handle)
/*
* Undocumented
*/
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
if (IsConsoleHandle (Handle) == FALSE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
Request.Type = CSRSS_CLOSE_HANDLE;
Request.Data.CloseHandleRequest.Handle = Handle;
Status = CsrClientCallServer(&Request,
&Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOLEAN STDCALL
IsConsoleHandle(HANDLE Handle)
{
if ((((ULONG)Handle) & 0x10000003) == 0x3)
{
return(TRUE);
}
return(FALSE);
}
/*
* @implemented
*/
HANDLE STDCALL
GetStdHandle(DWORD nStdHandle)
/*
* FUNCTION: Get a handle for the standard input, standard output
* and a standard error device.
* ARGUMENTS:
* nStdHandle - Specifies the device for which to return the handle.
* RETURNS: If the function succeeds, the return value is the handle
* of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
Ppb = NtCurrentPeb()->ProcessParameters;
switch (nStdHandle)
{
case STD_INPUT_HANDLE:
return Ppb->hStdInput;
case STD_OUTPUT_HANDLE:
return Ppb->hStdOutput;
case STD_ERROR_HANDLE:
return Ppb->hStdError;
}
SetLastError (ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
/*
* @implemented
*/
WINBASEAPI BOOL WINAPI
SetStdHandle(DWORD nStdHandle,
HANDLE hHandle)
/*
* FUNCTION: Set the handle for the standard input, standard output or
* the standard error device.
* ARGUMENTS:
* nStdHandle - Specifies the handle to be set.
* hHandle - The handle to set.
* RETURNS: TRUE if the function succeeds, FALSE otherwise.
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
Ppb = NtCurrentPeb()->ProcessParameters;
/* More checking needed? */
if (hHandle == INVALID_HANDLE_VALUE)
{
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
SetLastError(ERROR_SUCCESS); /* OK */
switch (nStdHandle)
{
case STD_INPUT_HANDLE:
Ppb->hStdInput = hHandle;
return TRUE;
case STD_OUTPUT_HANDLE:
Ppb->hStdOutput = hHandle;
return TRUE;
case STD_ERROR_HANDLE:
Ppb->hStdError = hHandle;
return TRUE;
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
/*--------------------------------------------------------------
* WriteConsoleA
*
* @implemented
*/
WINBOOL STDCALL
WriteConsoleA(HANDLE hConsoleOutput,
CONST VOID *lpBuffer,
DWORD nNumberOfCharsToWrite,
LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
USHORT Size;
ULONG MessageSize;
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) +
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;
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));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
RtlFreeHeap(GetProcessHeap(), 0, Request);
SetLastErrorByStatus(Status);
return(FALSE);
}
nNumberOfCharsToWrite -= Size;
lpBuffer += Size;
}
RtlFreeHeap(GetProcessHeap(), 0, Request);
return TRUE;
}
/*--------------------------------------------------------------
* ReadConsoleA
*
* @implemented
*/
WINBOOL STDCALL ReadConsoleA(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(),
HEAP_ZERO_MEMORY,
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);
}
/*--------------------------------------------------------------
* AllocConsole
*
* @implemented
*/
WINBOOL STDCALL AllocConsole(VOID)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
HANDLE hStdError;
if(NtCurrentPeb()->ProcessParameters->hConsole)
{
DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
SetLastErrorByStatus (STATUS_OBJECT_EXISTS);
return FALSE;
}
Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher;
Request.Type = CSRSS_ALLOC_CONSOLE;
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;
}
SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
SetStdHandle( STD_ERROR_HANDLE, hStdError );
return TRUE;
}
/*--------------------------------------------------------------
* FreeConsole
*
* @implemented
*/
WINBOOL STDCALL FreeConsole(VOID)
{
// AG: I'm not sure if this is correct (what happens to std handles?)
// but I just tried to reverse what AllocConsole() does...
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_FREE_CONSOLE;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* GetConsoleScreenBufferInfo
*
* @implemented
*/
WINBOOL
STDCALL
GetConsoleScreenBufferInfo(
HANDLE hConsoleOutput,
PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SCREEN_BUFFER_INFO;
Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
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;
}
*lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
return TRUE;
}
/*--------------------------------------------------------------
* SetConsoleCursorPosition
*
* @implemented
*/
WINBOOL
STDCALL
SetConsoleCursorPosition(
HANDLE hConsoleOutput,
COORD dwCursorPosition
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_CURSOR;
Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
Request.Data.SetCursorRequest.Position = dwCursorPosition;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* FillConsoleOutputCharacterA
*
* @implemented
*/
WINBOOL STDCALL
FillConsoleOutputCharacterA(
HANDLE hConsoleOutput,
CHAR cCharacter,
DWORD nLength,
COORD dwWriteCoord,
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);
}
/*--------------------------------------------------------------
* FillConsoleOutputCharacterW
*
* @unimplemented
*/
WINBOOL
STDCALL
FillConsoleOutputCharacterW(
HANDLE hConsoleOutput,
WCHAR cCharacter,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* PeekConsoleInputA
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
PeekConsoleInputA(
HANDLE hConsoleInput,
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsRead
)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
PVOID BufferBase;
PVOID BufferTargetBase;
DWORD Size;
if(lpBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = nLength * sizeof(INPUT_RECORD);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
if(Request == NULL)
{
CsrReleaseParameterBuffer(BufferBase);
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
Request->Data.PeekConsoleInputRequest.Length = nLength;
Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
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);
return FALSE;
}
memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
if(lpNumberOfEventsRead != NULL)
*lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return TRUE;
}
/*--------------------------------------------------------------
* PeekConsoleInputW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
PeekConsoleInputW(
HANDLE hConsoleInput,
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsRead
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* ReadConsoleInputA
*
* @implemented
*/
WINBASEAPI BOOL WINAPI
ReadConsoleInputA(HANDLE hConsoleInput,
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsRead)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
DWORD NumEventsRead;
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))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
while (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;
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);
}
}
NumEventsRead = 0;
*lpBuffer = Reply.Data.ReadInputReply.Input;
lpBuffer++;
NumEventsRead++;
while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
{
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++;
}
*lpNumberOfEventsRead = NumEventsRead;
return TRUE;
}
/*--------------------------------------------------------------
* ReadConsoleInputW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleInputW(
HANDLE hConsoleInput,
PINPUT_RECORD lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsRead
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* WriteConsoleInputA
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
WriteConsoleInputA(
HANDLE hConsoleInput,
CONST INPUT_RECORD *lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsWritten
)
{
PCSRSS_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);
if(!NT_SUCCESS(Status))
{
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;
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);
return FALSE;
}
if(lpNumberOfEventsWritten != NULL)
*lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return TRUE;
}
/*--------------------------------------------------------------
* WriteConsoleInputW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
WriteConsoleInputW(
HANDLE hConsoleInput,
CONST INPUT_RECORD *lpBuffer,
DWORD nLength,
LPDWORD lpNumberOfEventsWritten
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* ReadConsoleOutputA
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleOutputA(
HANDLE hConsoleOutput,
PCHAR_INFO lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
PSMALL_RECT lpReadRegion
)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
PVOID BufferBase;
PVOID BufferTargetBase;
NTSTATUS Status;
DWORD Size, SizeX, SizeY;
if(lpBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
if(!NT_SUCCESS(Status))
{
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_READ_CONSOLE_OUTPUT;
Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus(Status);
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return FALSE;
}
SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
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);
return TRUE;
}
/*--------------------------------------------------------------
* ReadConsoleOutputW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleOutputW(
HANDLE hConsoleOutput,
PCHAR_INFO lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
PSMALL_RECT lpReadRegion
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* WriteConsoleOutputA
*
* @implemented
*/
WINBASEAPI BOOL WINAPI
WriteConsoleOutputA(HANDLE hConsoleOutput,
CONST CHAR_INFO *lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
PSMALL_RECT lpWriteRegion)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
ULONG Size;
PVOID BufferBase;
PVOID BufferTargetBase;
Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
Size,
&BufferBase,
&BufferTargetBase);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return(FALSE);
}
Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST));
if (Request == NULL)
{
CsrReleaseParameterBuffer(BufferBase);
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
Request->Data.WriteConsoleOutputRequest.CharInfo =
(CHAR_INFO*)BufferTargetBase;
Status = CsrClientCallServer(Request, &Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
CsrReleaseParameterBuffer(BufferBase);
RtlFreeHeap(GetProcessHeap(), 0, Request);
SetLastErrorByStatus(Status);
return FALSE;
}
*lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
RtlFreeHeap(GetProcessHeap(), 0, Request);
CsrReleaseParameterBuffer(BufferBase);
return(TRUE);
}
/*--------------------------------------------------------------
* WriteConsoleOutputW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
WriteConsoleOutputW(
HANDLE hConsoleOutput,
CONST CHAR_INFO *lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
PSMALL_RECT lpWriteRegion
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* ReadConsoleOutputCharacterA
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleOutputCharacterA(
HANDLE hConsoleOutput,
LPSTR lpCharacter,
DWORD nLength,
COORD dwReadCoord,
LPDWORD lpNumberOfCharsRead
)
{
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 = nLength;
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);
}
/*--------------------------------------------------------------
* ReadConsoleOutputCharacterW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleOutputCharacterW(
HANDLE hConsoleOutput,
LPWSTR lpCharacter,
DWORD nLength,
COORD dwReadCoord,
LPDWORD lpNumberOfCharsRead
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* ReadConsoleOutputAttribute
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleOutputAttribute(
HANDLE hConsoleOutput,
LPWORD lpAttribute,
DWORD nLength,
COORD dwReadCoord,
LPDWORD lpNumberOfAttrsRead
)
{
CSRSS_API_REQUEST Request;
PCSRSS_API_REPLY Reply;
NTSTATUS Status;
DWORD Size, i;
Reply = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
if (Reply == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
if (lpNumberOfAttrsRead != NULL)
*lpNumberOfAttrsRead = nLength;
Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
while (nLength != 0)
{
if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
else
Size = nLength;
Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = 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);
}
// Convert CHARs to WORDs
for(i = 0; i < Size; ++i)
*lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
nLength -= Size;
Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
}
RtlFreeHeap(GetProcessHeap(), 0, Reply);
return(TRUE);
}
/*--------------------------------------------------------------
* WriteConsoleOutputCharacterA
*
* @implemented
*/
WINBASEAPI BOOL WINAPI
WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
LPCSTR lpCharacter,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
WORD Size;
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + 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;
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 );
return TRUE;
}
/*--------------------------------------------------------------
* WriteConsoleOutputCharacterW
*
* @implemented
*/
WINBASEAPI BOOL WINAPI
WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
LPCWSTR lpCharacter,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
WORD Size;
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + 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;
}
/*--------------------------------------------------------------
* WriteConsoleOutputAttribute
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
WriteConsoleOutputAttribute(
HANDLE hConsoleOutput,
CONST WORD *lpAttribute,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfAttrsWritten
)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
WORD Size;
int c;
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
if( !Request )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
if( lpNumberOfAttrsWritten )
*lpNumberOfAttrsWritten = nLength;
while( nLength )
{
Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
for( c = 0; c < ( Size * 2 ); c++ )
Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
RtlFreeHeap( GetProcessHeap(), 0, Request );
SetLastErrorByStatus ( Status );
return FALSE;
}
nLength -= Size;
lpAttribute += Size;
Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
}
RtlFreeHeap( GetProcessHeap(), 0, Request );
return TRUE;
}
/*--------------------------------------------------------------
* FillConsoleOutputAttribute
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
FillConsoleOutputAttribute(
HANDLE hConsoleOutput,
WORD wAttribute,
DWORD nLength,
COORD dwWriteCoord,
LPDWORD lpNumberOfAttrsWritten
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
Request.Data.FillOutputAttribRequest.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( lpNumberOfAttrsWritten )
*lpNumberOfAttrsWritten = nLength;
return TRUE;
}
/*--------------------------------------------------------------
* GetConsoleMode
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
GetConsoleMode(
HANDLE hConsoleHandle,
LPDWORD lpMode
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_GET_CONSOLE_MODE;
Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
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;
}
*lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
return TRUE;
}
/*--------------------------------------------------------------
* GetNumberOfConsoleInputEvents
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
GetNumberOfConsoleInputEvents(
HANDLE hConsoleInput,
LPDWORD lpNumberOfEvents
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
if(lpNumberOfEvents == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
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;
}
*lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
return TRUE;
}
/*--------------------------------------------------------------
* GetLargestConsoleWindowSize
*
* @unimplemented
*/
WINBASEAPI
COORD
WINAPI
GetLargestConsoleWindowSize(
HANDLE hConsoleOutput
)
{
#if 1 /* FIXME: */
COORD Coord = {80,25};
/* TO DO */
return Coord;
#endif
}
/*--------------------------------------------------------------
* GetConsoleCursorInfo
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
GetConsoleCursorInfo(
HANDLE hConsoleOutput,
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_GET_CURSOR_INFO;
Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
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;
}
*lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
return TRUE;
}
/*--------------------------------------------------------------
* GetNumberOfConsoleMouseButtons
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
GetNumberOfConsoleMouseButtons(
LPDWORD lpNumberOfMouseButtons
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* SetConsoleMode
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleMode(
HANDLE hConsoleHandle,
DWORD dwMode
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_CONSOLE_MODE;
Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
Request.Data.SetConsoleModeRequest.Mode = dwMode;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* SetConsoleActiveScreenBuffer
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleActiveScreenBuffer(
HANDLE hConsoleOutput
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_SCREEN_BUFFER;
Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* FlushConsoleInputBuffer
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
FlushConsoleInputBuffer(
HANDLE hConsoleInput
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* SetConsoleScreenBufferSize
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleScreenBufferSize(
HANDLE hConsoleOutput,
COORD dwSize
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* SetConsoleCursorInfo
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleCursorInfo(
HANDLE hConsoleOutput,
CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_CURSOR_INFO;
Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
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;
}
return TRUE;
}
/*--------------------------------------------------------------
* ScrollConsoleScreenBufferA
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
ScrollConsoleScreenBufferA(
HANDLE hConsoleOutput,
CONST SMALL_RECT *lpScrollRectangle,
CONST SMALL_RECT *lpClipRectangle,
COORD dwDestinationOrigin,
CONST CHAR_INFO *lpFill
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
if (lpClipRectangle != NULL)
{
Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
}
else
{
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 ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
SetLastErrorByStatus ( Status );
return FALSE;
}
return TRUE;
}
/*--------------------------------------------------------------
* ScrollConsoleScreenBufferW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
ScrollConsoleScreenBufferW(
HANDLE hConsoleOutput,
CONST SMALL_RECT *lpScrollRectangle,
CONST SMALL_RECT *lpClipRectangle,
COORD dwDestinationOrigin,
CONST CHAR_INFO *lpFill
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* SetConsoleWindowInfo
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleWindowInfo(
HANDLE hConsoleOutput,
BOOL bAbsolute,
CONST SMALL_RECT *lpConsoleWindow
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* SetConsoleTextAttribute
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleTextAttribute(
HANDLE hConsoleOutput,
WORD wAttributes
)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_ATTRIB;
Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
Request.Data.SetAttribRequest.Attrib = wAttributes;
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;
}
return TRUE;
}
BOOL STATIC
AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
{
if (HandlerRoutine == NULL)
{
IgnoreCtrlEvents = TRUE;
return(TRUE);
}
else
{
NrCtrlHandlers++;
CtrlHandlers =
RtlReAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
(PVOID)CtrlHandlers,
NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
if (CtrlHandlers == NULL)
{
NrCtrlHandlers = 0;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(FALSE);
}
CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
return(TRUE);
}
}
BOOL STATIC
RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
{
ULONG i;
if (HandlerRoutine == NULL)
{
IgnoreCtrlEvents = FALSE;
return(TRUE);
}
else
{
for (i = 0; i < NrCtrlHandlers; i++)
{
if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
{
NrCtrlHandlers--;
memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
(NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
CtrlHandlers =
RtlReAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
(PVOID)CtrlHandlers,
NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
return(TRUE);
}
}
}
return(FALSE);
}
/*
* @implemented
*/
WINBASEAPI BOOL WINAPI
SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
BOOL Add)
{
BOOLEAN Ret;
RtlEnterCriticalSection(&DllLock);
if (Add)
{
Ret = AddConsoleCtrlHandler(HandlerRoutine);
}
else
{
Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
}
RtlLeaveCriticalSection(&DllLock);
return(Ret);
}
/*--------------------------------------------------------------
* GenerateConsoleCtrlEvent
*
* @unimplemented
*/
WINBASEAPI BOOL WINAPI
GenerateConsoleCtrlEvent(
DWORD dwCtrlEvent,
DWORD dwProcessGroupId
)
{
/* TO DO */
return FALSE;
}
/*--------------------------------------------------------------
* GetConsoleTitleW
*
* @implemented
*/
WINBASEAPI
DWORD
WINAPI
GetConsoleTitleW(
LPWSTR lpConsoleTitle,
DWORD nSize
)
{
CSRSS_API_REQUEST Request;
PCSRSS_API_REPLY Reply;
NTSTATUS Status;
HANDLE hConsole;
hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hConsole == INVALID_HANDLE_VALUE)
{
return 0;
}
Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
if(Reply == NULL)
{
CloseHandle(hConsole);
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
Request.Type = CSRSS_GET_TITLE;
Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
CloseHandle(hConsole);
if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
{
SetLastErrorByStatus(Status);
RtlFreeHeap(GetProcessHeap(), 0, Reply);
return 0;
}
if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
{
wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
lpConsoleTitle[nSize--] = L'\0';
}
else
{
nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
lpConsoleTitle[nSize] = L'\0';
}
RtlFreeHeap(GetProcessHeap(), 0, Reply);
return nSize;
}
/*--------------------------------------------------------------
* GetConsoleTitleA
*
* 19990306 EA
*
* @implemented
*/
WINBASEAPI
DWORD
WINAPI
GetConsoleTitleA(
LPSTR lpConsoleTitle,
DWORD nSize
)
{
wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
DWORD nWideTitle = sizeof WideTitle;
DWORD nWritten;
if (!lpConsoleTitle || !nSize) return 0;
nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
if (!nWideTitle) return 0;
if ( (nWritten = WideCharToMultiByte(
CP_ACP, // ANSI code page
0, // performance and mapping flags
(LPWSTR) WideTitle, // address of wide-character string
nWideTitle, // number of characters in string
lpConsoleTitle, // address of buffer for new string
nSize, // size of buffer
NULL, // FAST
NULL // FAST
)))
{
lpConsoleTitle[nWritten] = '\0';
return nWritten;
}
return 0;
}
/*--------------------------------------------------------------
* SetConsoleTitleW
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleTitleW(
LPCWSTR lpConsoleTitle
)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
unsigned int c;
HANDLE hConsole;
hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hConsole == INVALID_HANDLE_VALUE)
{
return FALSE;
}
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL)
{
CloseHandle(hConsole);
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
Request->Type = CSRSS_SET_TITLE;
Request->Data.SetTitleRequest.Console = hConsole;
for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
// add null
Request->Data.SetTitleRequest.Title[c] = 0;
Request->Data.SetTitleRequest.Length = c;
Status = CsrClientCallServer(Request,
&Reply,
sizeof(CSRSS_API_REQUEST) +
c * sizeof(WCHAR),
sizeof(CSRSS_API_REPLY));
CloseHandle(hConsole);
if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
{
RtlFreeHeap( GetProcessHeap(), 0, Request );
SetLastErrorByStatus (Status);
return(FALSE);
}
RtlFreeHeap( GetProcessHeap(), 0, Request );
return TRUE;
}
/*--------------------------------------------------------------
* SetConsoleTitleA
*
* 19990204 EA Added
*
* @implemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleTitleA(
LPCSTR lpConsoleTitle
)
{
PCSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
unsigned int c;
HANDLE hConsole;
hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hConsole == INVALID_HANDLE_VALUE)
{
return FALSE;
}
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL)
{
CloseHandle(hConsole);
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
Request->Type = CSRSS_SET_TITLE;
Request->Data.SetTitleRequest.Console = hConsole;
for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
// add null
Request->Data.SetTitleRequest.Title[c] = 0;
Request->Data.SetTitleRequest.Length = c;
Status = CsrClientCallServer(Request,
&Reply,
sizeof(CSRSS_API_REQUEST) +
c * sizeof(WCHAR),
sizeof(CSRSS_API_REPLY));
CloseHandle(hConsole);
if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
{
RtlFreeHeap( GetProcessHeap(), 0, Request );
SetLastErrorByStatus (Status);
return(FALSE);
}
RtlFreeHeap( GetProcessHeap(), 0, Request );
return TRUE;
}
/*--------------------------------------------------------------
* ReadConsoleW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
ReadConsoleW(
HANDLE hConsoleInput,
LPVOID lpBuffer,
DWORD nNumberOfCharsToRead,
LPDWORD lpNumberOfCharsRead,
LPVOID lpReserved
)
{
/* --- TO DO --- */
return FALSE;
}
/*--------------------------------------------------------------
* WriteConsoleW
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
WriteConsoleW(
HANDLE hConsoleOutput,
CONST VOID *lpBuffer,
DWORD nNumberOfCharsToWrite,
LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved
)
{
#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
*
* @implemented
*/
WINBASEAPI
HANDLE
WINAPI
CreateConsoleScreenBuffer(
DWORD dwDesiredAccess,
DWORD dwShareMode,
CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
DWORD dwFlags,
LPVOID lpScreenBufferData
)
{
// FIXME: don't ignore access, share mode, and security
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
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;
}
return Reply.Data.CreateScreenBufferReply.OutputHandle;
}
/*--------------------------------------------------------------
* GetConsoleCP
*
* @unimplemented
*/
WINBASEAPI
UINT
WINAPI
GetConsoleCP( VOID )
{
/* --- TO DO --- */
return CP_OEMCP; /* FIXME */
}
/*--------------------------------------------------------------
* SetConsoleCP
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleCP(
UINT wCodePageID
)
{
/* --- TO DO --- */
return FALSE;
}
/*--------------------------------------------------------------
* GetConsoleOutputCP
*
* @unimplemented
*/
WINBASEAPI
UINT
WINAPI
GetConsoleOutputCP( VOID )
{
/* --- TO DO --- */
return 0; /* FIXME */
}
/*--------------------------------------------------------------
* SetConsoleOutputCP
*
* @unimplemented
*/
WINBASEAPI
BOOL
WINAPI
SetConsoleOutputCP(
UINT wCodePageID
)
{
/* --- TO DO --- */
return FALSE;
}
/*--------------------------------------------------------------
* GetConsoleProcessList
*
* @unimplemented
*/
DWORD STDCALL
GetConsoleProcessList(LPDWORD lpdwProcessList,
DWORD dwProcessCount)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*--------------------------------------------------------------
* GetConsoleSelectionInfo
*
* @unimplemented
*/
BOOL STDCALL
GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*--------------------------------------------------------------
* AttachConsole
*
* @unimplemented
*/
BOOL STDCALL
AttachConsole(DWORD dwProcessId)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*--------------------------------------------------------------
* GetConsoleWindow/0
*
* @implemented
*/
HWND STDCALL
GetConsoleWindow (VOID)
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Data.ConsoleWindowRequest.ConsoleHandle =
OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
if (INVALID_HANDLE_VALUE == Request.Data.ConsoleWindowRequest.ConsoleHandle)
{
return (HWND) NULL;
}
Request.Type = CSRSS_GET_CONSOLE_WINDOW;
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus (Status);
return (HWND) NULL;
}
return Reply.Data.ConsoleWindowReply.WindowHandle;
}
/* EOF */