New console client support

svn path=/trunk/; revision=1550
This commit is contained in:
Phillip Susi 2001-01-21 00:07:03 +00:00
parent b360ee177d
commit 5c0fb84170
2 changed files with 71 additions and 37 deletions

View file

@ -1,4 +1,4 @@
/* $Id: console.c,v 1.25 2000/07/11 04:06:42 phreak Exp $ /* $Id: console.c,v 1.26 2001/01/21 00:07:03 phreak Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -62,13 +62,7 @@ HANDLE STDCALL GetStdHandle(DWORD nStdHandle)
{ {
PRTL_USER_PROCESS_PARAMETERS Ppb; PRTL_USER_PROCESS_PARAMETERS Ppb;
// DbgPrint("GetStdHandle(nStdHandle %d)\n",nStdHandle);
SetLastError(ERROR_SUCCESS); /* OK */
// DbgPrint("NtCurrentPeb() %x\n", NtCurrentPeb());
Ppb = NtCurrentPeb()->ProcessParameters; Ppb = NtCurrentPeb()->ProcessParameters;
// DbgPrint("Ppb %x\n", Ppb);
// DbgPrint("Ppb->OutputHandle %x\n", Ppb->OutputHandle);
switch (nStdHandle) switch (nStdHandle)
{ {
case STD_INPUT_HANDLE: return Ppb->InputHandle; case STD_INPUT_HANDLE: return Ppb->InputHandle;
@ -184,6 +178,7 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
CSRSS_API_REQUEST Request; CSRSS_API_REQUEST Request;
PCSRSS_API_REPLY Reply; PCSRSS_API_REPLY Reply;
NTSTATUS Status; NTSTATUS Status;
ULONG CharsRead = 0;
Reply = HeapAlloc(GetProcessHeap(), Reply = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
@ -196,13 +191,12 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
Request.Type = CSRSS_READ_CONSOLE; Request.Type = CSRSS_READ_CONSOLE;
Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead; Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
Status = CsrClientCallServer(&Request, Status = CsrClientCallServer(&Request,
Reply, Reply,
sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY) + sizeof(CSRSS_API_REPLY) +
nNumberOfCharsToRead); Request.Data.ReadConsoleRequest.NrCharactersToRead);
// DbgPrint( "Csrss Returned\n" );
if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status )) if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
{ {
DbgPrint( "CSR returned error in ReadConsole\n" ); DbgPrint( "CSR returned error in ReadConsole\n" );
@ -210,9 +204,21 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
HeapFree( GetProcessHeap(), 0, Reply ); HeapFree( GetProcessHeap(), 0, Reply );
return(FALSE); 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 ) while( Reply->Status == STATUS_PENDING )
{ {
//DbgPrint( "Read pending, waiting on object %x\n", Reply->Data.ReadConsoleReply.EventHandle ); /* 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 ); Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
if( !NT_SUCCESS( Status ) ) if( !NT_SUCCESS( Status ) )
{ {
@ -220,19 +226,30 @@ WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
HeapFree( GetProcessHeap(), 0, Reply ); HeapFree( GetProcessHeap(), 0, Reply );
return FALSE; return FALSE;
} }
Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + nNumberOfCharsToRead ); 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 ) ) if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
{ {
SetLastErrorByStatus ( Status ); SetLastErrorByStatus ( Status );
HeapFree( GetProcessHeap(), 0, Reply ); HeapFree( GetProcessHeap(), 0, Reply );
return FALSE; 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) if (lpNumberOfCharsRead != NULL)
*lpNumberOfCharsRead = Reply->Data.ReadConsoleReply.NrCharactersRead; *lpNumberOfCharsRead = CharsRead;
memcpy(lpBuffer,
Reply->Data.ReadConsoleReply.Buffer,
Reply->Data.ReadConsoleReply.NrCharactersRead);
HeapFree(GetProcessHeap(), HeapFree(GetProcessHeap(),
0, 0,
Reply); Reply);
@ -257,9 +274,9 @@ WINBOOL STDCALL AllocConsole(VOID)
SetLastErrorByStatus ( Status ); SetLastErrorByStatus ( Status );
return FALSE; return FALSE;
} }
SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.ConsoleHandle ); SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.ConsoleHandle ); SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.ConsoleHandle ); SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
return TRUE; return TRUE;
} }
@ -934,9 +951,20 @@ SetConsoleActiveScreenBuffer(
HANDLE hConsoleOutput HANDLE hConsoleOutput
) )
{ {
/* TO DO */ CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
Request.Type = CSRSS_SET_SCREEN_BUFFER;
Request.Data.SetActiveScreenBufferRequest.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 FALSE;
} }
return TRUE;
}
/*-------------------------------------------------------------- /*--------------------------------------------------------------
@ -1327,9 +1355,20 @@ CreateConsoleScreenBuffer(
LPVOID lpScreenBufferData LPVOID lpScreenBufferData
) )
{ {
/* --- TO DO --- */ // 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 FALSE;
} }
return Reply.Data.CreateScreenBufferReply.OutputHandle;
}
/*-------------------------------------------------------------- /*--------------------------------------------------------------

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.31 2000/12/05 18:08:24 ekohl Exp $ /* $Id: create.c,v 1.32 2001/01/21 00:07:03 phreak Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -390,7 +390,6 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
UNICODE_STRING CommandLine_U; UNICODE_STRING CommandLine_U;
CSRSS_API_REQUEST CsrRequest; CSRSS_API_REQUEST CsrRequest;
CSRSS_API_REPLY CsrReply; CSRSS_API_REPLY CsrReply;
HANDLE ConsoleHandle;
CHAR ImageFileName[8]; CHAR ImageFileName[8];
PWCHAR s; PWCHAR s;
PWCHAR e; PWCHAR e;
@ -515,19 +514,15 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
{ {
DbgPrint("Failed to tell csrss about new process. Expect trouble.\n"); DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
} }
ConsoleHandle = CsrReply.Data.CreateProcessReply.ConsoleHandle;
// DbgPrint("ConsoleHandle %x\n", ConsoleHandle);
/* /*
* Create Process Environment Block * Create Process Environment Block
*/ */
DPRINT("Creating peb\n"); DPRINT("Creating peb\n");
Ppb->ConsoleHandle = ConsoleHandle; Ppb->InputHandle = CsrReply.Data.CreateProcessReply.InputHandle;
Ppb->InputHandle = ConsoleHandle; Ppb->OutputHandle = CsrReply.Data.CreateProcessReply.OutputHandle;;
Ppb->OutputHandle = ConsoleHandle; Ppb->ErrorHandle = Ppb->OutputHandle;
Ppb->ErrorHandle = ConsoleHandle;
KlInitPeb(hProcess, Ppb); KlInitPeb(hProcess, Ppb);
RtlDestroyProcessParameters (Ppb); RtlDestroyProcessParameters (Ppb);