- Delete all the remnants of Win32CsrValidateBuffer calls, which were replaced by standard CsrValidateMessageBuffer calls, and therefore delete the unused server.c file.
- Adapt WriteConsole API to use CSR waits. This replaces the old event-based waiting.

TODO: Dereference all the waits in Console->WriteWaitQueue.

svn path=/branches/ros-csrss/; revision=57819
This commit is contained in:
Hermès Bélusca-Maïto 2012-12-08 16:13:16 +00:00
parent 0da8c7abf0
commit ca2cc847d2
9 changed files with 133 additions and 238 deletions

View file

@ -135,7 +135,6 @@ typedef struct
BOOL Unicode;
ULONG NrCharactersToWrite;
ULONG NrCharactersWritten;
// HANDLE UnpauseEvent;
ULONG BufferSize;
PVOID Buffer;

View file

@ -15,7 +15,6 @@ list(APPEND SOURCE
handle.c
init.c
lineinput.c
server.c
tuiconsole.c
consrv.rc
${CMAKE_CURRENT_BINARY_DIR}/consrv.def)

View file

@ -438,15 +438,6 @@ CSR_API(SrvGetConsoleAlias)
return STATUS_BUFFER_TOO_SMALL;
}
/*
if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process, lpTarget,
ConsoleAlias->TargetLength, 1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
*/
wcscpy(lpTarget, Entry->lpTarget);
ConsoleAlias->TargetLength = Length;
ConioUnlockConsole(Console);
@ -496,17 +487,6 @@ CSR_API(SrvGetConsoleAliases)
return STATUS_BUFFER_OVERFLOW;
}
/*
if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process,
GetAllConsoleAliases->AliasesBuffer,
GetAllConsoleAliases->AliasesBufferLength,
1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
*/
BytesWritten = IntGetAllConsoleAliases(Header,
GetAllConsoleAliases->AliasesBuffer,
GetAllConsoleAliases->AliasesBufferLength);
@ -592,17 +572,6 @@ CSR_API(SrvGetConsoleAliasExes)
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process,
GetConsoleAliasesExes->ExeNames,
GetConsoleAliasesExes->Length,
1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
*/
BytesWritten = IntGetConsoleAliasesExes(Console->Aliases,
GetConsoleAliasesExes->ExeNames,
GetConsoleAliasesExes->Length);

View file

@ -52,8 +52,8 @@ typedef struct tagCSRSS_CONSOLE
LONG ReferenceCount;
CRITICAL_SECTION Lock;
struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
HANDLE ActiveEvent;
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
LIST_ENTRY InputEvents; /* List head for input event queue */
@ -83,8 +83,10 @@ typedef struct tagCSRSS_CONSOLE
LIST_ENTRY ProcessList;
struct tagALIAS_HEADER *Aliases;
CONSOLE_SELECTION_INFO Selection;
BYTE PauseFlags;
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
} CSRSS_CONSOLE, *PCSRSS_CONSOLE;
typedef struct tagCSRSS_CONSOLE_VTBL

View file

@ -131,22 +131,6 @@ ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
for (i = 0; i < Length; i++)
{
if (Console->UnpauseEvent)
{
/** FIXME: Added in 47359 for pausing
Status = NtDuplicateObject(NtCurrentProcess(),
Console->UnpauseEvent,
Process->ProcessHandle,
&WriteConsoleRequest->UnpauseEvent,
SYNCHRONIZE, 0, 0);
ConioUnlockScreenBuffer(Buff);
return (NT_SUCCESS(Status) ? STATUS_PENDING : Status);
**/
/* Wait on the console unpause event till it becomes signaled */
WaitForSingleObject(Console->UnpauseEvent, INFINITE);
}
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
{
/* --- LF --- */
@ -446,6 +430,122 @@ ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale)
return Size;
}
static NTSTATUS
DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
IN PCSR_THREAD ClientThread,
IN BOOL CreateWaitBlock OPTIONAL);
// Wait function CSR_WAIT_FUNCTION
static BOOLEAN
WriteConsoleThread(IN PLIST_ENTRY WaitList,
IN PCSR_THREAD WaitThread,
IN PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags)
{
NTSTATUS Status;
Status = DoWriteConsole(WaitApiMessage,
WaitThread,
FALSE);
if (Status != STATUS_PENDING)
{
WaitApiMessage->Status = Status;
}
return (Status == STATUS_PENDING ? FALSE : TRUE);
}
static NTSTATUS
DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
IN PCSR_THREAD ClientThread,
IN BOOL CreateWaitBlock OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
PCSRSS_WRITE_CONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
PCHAR Buffer;
DWORD Written = 0;
ULONG Length;
Status = ConioLockScreenBuffer(ConsoleGetPerProcessData(ClientThread->Process), WriteConsoleRequest->ConsoleHandle, &Buff, GENERIC_WRITE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
// if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
if (Console->PauseFlags && Console->UnpauseEvent != NULL)
{
if (CreateWaitBlock)
{
if (!CsrCreateWait(&Console->WriteWaitQueue,
WriteConsoleThread,
ClientThread,
ApiMessage,
NULL,
NULL))
{
ConioUnlockScreenBuffer(Buff);
return STATUS_NO_MEMORY;
}
}
/* Wait until we un-pause the console */
ConioUnlockScreenBuffer(Buff);
return STATUS_PENDING;
}
if(WriteConsoleRequest->Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
NULL, 0, NULL, NULL);
Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (Buffer)
{
WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
Buffer, Length, NULL, NULL);
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
Buffer = (PCHAR)WriteConsoleRequest->Buffer;
}
if (Buffer)
{
if (NT_SUCCESS(Status))
{
Status = ConioWriteConsole(Console, Buff, Buffer,
WriteConsoleRequest->NrCharactersToWrite, TRUE);
if (NT_SUCCESS(Status))
{
Written = WriteConsoleRequest->NrCharactersToWrite;
}
}
if (WriteConsoleRequest->Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
}
}
WriteConsoleRequest->NrCharactersWritten = Written;
ConioUnlockScreenBuffer(Buff);
return Status;
}
/* PUBLIC APIS ****************************************************************/
@ -485,15 +585,6 @@ CSR_API(SrvReadConsoleOutput)
Status = ConioLockScreenBuffer(ProcessData, ReadConsoleOutputRequest->ConsoleHandle, &Buff, GENERIC_READ);
if (!NT_SUCCESS(Status)) return Status;
/*
if (!Win32CsrValidateBuffer(ProcessData->Process, CharInfo,
BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
{
ConioUnlockScreenBuffer(Buff);
return STATUS_ACCESS_VIOLATION;
}
*/
/* FIXME: Is this correct? */
CodePage = ProcessData->Console->OutputCodePage;
@ -546,13 +637,6 @@ CSR_API(SrvWriteConsole)
{
NTSTATUS Status;
PCSRSS_WRITE_CONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
PCHAR Buffer;
PCSRSS_SCREEN_BUFFER Buff;
// PCSR_PROCESS Process = CsrGetClientThread()->Process;
PCSRSS_CONSOLE Console;
DWORD Written = 0;
ULONG Length;
// ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
DPRINT("SrvWriteConsole\n");
@ -564,68 +648,12 @@ CSR_API(SrvWriteConsole)
return STATUS_INVALID_PARAMETER;
}
Status = ConioLockScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), WriteConsoleRequest->ConsoleHandle, &Buff, GENERIC_WRITE);
if (!NT_SUCCESS(Status)) return Status;
Status = DoWriteConsole(ApiMessage,
CsrGetClientThread(),
TRUE);
Console = Buff->Header.Console;
/** FIXME: Added in 47359 for pausing
if (Console->UnpauseEvent)
{
Status = NtDuplicateObject(NtCurrentProcess(),
Console->UnpauseEvent,
Process->ProcessHandle,
&WriteConsoleRequest->UnpauseEvent,
SYNCHRONIZE, 0, 0);
ConioUnlockScreenBuffer(Buff);
return (NT_SUCCESS(Status) ? STATUS_PENDING : Status);
}
**/
if(WriteConsoleRequest->Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
NULL, 0, NULL, NULL);
Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length);
if (Buffer)
{
WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
Buffer, Length, NULL, NULL);
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
Buffer = (PCHAR)WriteConsoleRequest->Buffer;
}
if (Buffer)
{
if (NT_SUCCESS(Status))
{
Status = ConioWriteConsole(Console, Buff, Buffer,
WriteConsoleRequest->NrCharactersToWrite, TRUE);
if (NT_SUCCESS(Status))
{
Written = WriteConsoleRequest->NrCharactersToWrite;
}
}
if (WriteConsoleRequest->Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
}
}
ConioUnlockScreenBuffer(Buff);
WriteConsoleRequest->NrCharactersWritten = Written;
if (Status == STATUS_PENDING)
*ReplyCode = CsrReplyPending;
return Status;
}
@ -668,15 +696,6 @@ CSR_API(SrvWriteConsoleOutput)
Console = Buff->Header.Console;
/*
if (!Win32CsrValidateBuffer(ProcessData->Process, CharInfo,
BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO)))
{
ConioUnlockScreenBuffer(Buff);
return STATUS_ACCESS_VIOLATION;
}
*/
WriteRegion = WriteConsoleOutputRequest->WriteRegion;
SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion));

View file

@ -115,6 +115,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL;
InitializeListHead(&Console->ReadWaitQueue);
InitializeListHead(&Console->WriteWaitQueue);
InitializeListHead(&Console->InputEvents);
InitializeListHead(&Console->HistoryBuffers);
Console->CodePage = GetOEMCP();
@ -426,6 +427,7 @@ ConioDeleteConsole(Object_t *Object)
DPRINT("ConioDeleteConsole\n");
/* TODO: Dereference all the waits in Console->ReadWaitQueue */
/* TODO: Dereference all the waits in Console->WriteWaitQueue */
/* Drain input event queue */
while (Console->InputEvents.Flink != &Console->InputEvents)
@ -476,11 +478,18 @@ VOID FASTCALL
ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
{
Console->PauseFlags &= ~Flags;
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
if (Console->PauseFlags == 0 && Console->UnpauseEvent)
{
SetEvent(Console->UnpauseEvent);
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
CsrNotifyWait(&Console->WriteWaitQueue,
WaitAll,
NULL,
NULL);
}
}
@ -569,13 +578,6 @@ CSR_API(SrvSetConsoleTitle)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
TitleRequest->Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
if(NT_SUCCESS(Status))
@ -626,13 +628,6 @@ CSR_API(SrvGetConsoleTitle)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
TitleRequest->Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
if (!NT_SUCCESS(Status))
@ -846,11 +841,6 @@ CSR_API(SrvGetConsoleProcessList)
Buffer = GetProcessListRequest->pProcessIds;
/*
if (!Win32CsrValidateBuffer(ProcessData, Buffer, GetProcessListRequest->nMaxIds, sizeof(DWORD)))
return STATUS_ACCESS_VIOLATION;
*/
Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
if (!NT_SUCCESS(Status)) return Status;

View file

@ -140,14 +140,6 @@ CSR_API(SrvSetConsoleNumberOfCommands);
CSR_API(SrvGetConsoleHistory);
CSR_API(SrvSetConsoleHistory);
/* server.c */
#if 0
BOOL FASTCALL Win32CsrValidateBuffer(PCSR_PROCESS ProcessData,
PVOID Buffer,
SIZE_T NumElements,
SIZE_T ElementSize);
#endif
#endif // __CONSRV_H__
/* EOF */

View file

@ -166,14 +166,6 @@ CSR_API(SrvGetConsoleCommandHistoryLength)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(ProcessData->Process,
GetCommandHistoryLength->ExeName.Buffer,
GetCommandHistoryLength->ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
@ -212,15 +204,6 @@ CSR_API(SrvGetConsoleCommandHistory)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(ProcessData->Process, Buffer, BufferSize, 1) ||
!Win32CsrValidateBuffer(ProcessData->Process,
GetCommandHistory->ExeName.Buffer,
GetCommandHistory->ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
@ -262,14 +245,6 @@ CSR_API(SrvExpungeConsoleCommandHistory)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(ProcessData->Process,
ExpungeCommandHistory->ExeName.Buffer,
ExpungeCommandHistory->ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
@ -298,14 +273,6 @@ CSR_API(SrvSetConsoleNumberOfCommands)
{
return STATUS_INVALID_PARAMETER;
}
/*
if (!Win32CsrValidateBuffer(ProcessData->Process,
SetHistoryNumberCommands->ExeName.Buffer,
SetHistoryNumberCommands->ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
*/
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))

View file

@ -1,42 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/init.c
* PURPOSE: Server APIs
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
#include "consrv.h"
#define NDEBUG
#include <debug.h>
#if 0
/* Ensure that a captured buffer is safe to access */
BOOL FASTCALL
Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
SIZE_T NumElements, SIZE_T ElementSize)
{
/* Check that the following conditions are true:
* 1. The start of the buffer is somewhere within the process's
* shared memory section view.
* 2. The remaining space in the view is at least as large as the buffer.
* (NB: Please don't try to "optimize" this by using multiplication
* instead of division; remember that 2147483648 * 2 = 0.)
* 3. The buffer is DWORD-aligned.
*/
ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase;
if (Offset >= ProcessData->ClientViewBounds
|| NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize
|| (Offset & (sizeof(DWORD) - 1)) != 0)
{
DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n",
Buffer, NumElements, ElementSize,
ProcessData->ClientViewBase, ProcessData->ClientViewBounds);
return FALSE;
}
return TRUE;
}
#endif
/* EOF */