NTSTATUS FASTCALL
ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console)
{
- PCSRSS_CONSOLE ProcessConsole = ProcessData->Console;
+ PCSRSS_CONSOLE ProcessConsole;
+
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ ProcessConsole = ProcessData->Console;
if (!ProcessConsole)
{
*Console = NULL;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
- InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
- EnterCriticalSection(&(ProcessConsole->Header.Lock));
+ InterlockedIncrement(&ProcessConsole->ReferenceCount);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ EnterCriticalSection(&(ProcessConsole->Lock));
*Console = ProcessConsole;
return STATUS_SUCCESS;
DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
- Buffer->Header.ReferenceCount = 0;
+ Buffer->Header.Console = Console;
+ Buffer->Header.HandleCount = 0;
Buffer->ShowX = 0;
Buffer->ShowY = 0;
Buffer->VirtualY = 0;
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- InitializeCriticalSection(&Buffer->Header.Lock);
ConioInitScreenBuffer(Console, Buffer);
/* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
Buffer->CurrentX = 0;
Buffer->CurrentY = 0;
+ InsertHeadList(&Console->BufferList, &Buffer->ListEntry);
return STATUS_SUCCESS;
}
static NTSTATUS WINAPI
-CsrInitConsole(PCSRSS_CONSOLE Console)
+CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible)
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
//FIXME
RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
- Console->Header.ReferenceCount = 0;
+ Console->ReferenceCount = 0;
Console->WaitingChars = 0;
Console->WaitingLines = 0;
Console->EchoCount = 0;
Console->Header.Type = CONIO_CONSOLE_MAGIC;
+ Console->Header.Console = Console;
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
Console->EarlyReturn = FALSE;
+ InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL;
InitializeListHead(&Console->InputEvents);
Console->CodePage = GetOEMCP();
return STATUS_UNSUCCESSFUL;
}
Console->PrivateData = NULL;
- InitializeCriticalSection(&Console->Header.Lock);
+ InitializeCriticalSection(&Console->Lock);
GuiMode = DtbgIsDesktopVisible();
if (NULL == NewBuffer)
{
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
return STATUS_INSUFFICIENT_RESOURCES;
}
}
if (GuiMode)
{
- Status = GuiInitConsole(Console);
+ Status = GuiInitConsole(Console, Visible);
if (! NT_SUCCESS(Status))
{
HeapFree(Win32CsrApiHeap,0, NewBuffer);
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
DPRINT1("GuiInitConsole: failed\n");
return Status;
{
ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
return Status;
}
- /* add a reference count because the buffer is tied to the console */
- InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
-
/* copy buffer contents to screen */
ConioDrawConsole(Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console)
{
DPRINT1("Process already has a console\n");
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
{
DPRINT("No console needed\n");
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
if (NULL == Console)
{
DPRINT1("Not enough memory for console\n");
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_NO_MEMORY;
}
/* initialize list head */
/* insert process data required for GUI initialization */
InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry);
/* Initialize the Console */
- Status = CsrInitConsole(Console);
+ Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console init failed\n");
HeapFree(Win32CsrApiHeap, 0, Console);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
}
Request->Data.AllocConsoleRequest.Console = Console;
/* Add a reference count because the process is tied to the console */
- Console->Header.ReferenceCount++;
+ _InterlockedIncrement(&Console->ReferenceCount);
if (NewConsole || !ProcessData->bInheritHandles)
{
&Request->Data.AllocConsoleRequest.InputHandle,
&Console->Header,
GENERIC_READ | GENERIC_WRITE,
- TRUE);
+ TRUE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
ConioDeleteConsole((Object_t *) Console);
ProcessData->Console = 0;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
&Request->Data.AllocConsoleRequest.OutputHandle,
&Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
- TRUE);
+ TRUE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
Win32CsrReleaseObject(ProcessData,
Request->Data.AllocConsoleRequest.InputHandle);
ProcessData->Console = 0;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
}
Request->Data.AllocConsoleRequest.InputHandle);
}
ProcessData->Console = 0;
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
}
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
CSR_API(CsrFreeConsole)
{
- PCSRSS_CONSOLE Console;
-
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if (ProcessData->Console == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Console = ProcessData->Console;
- ProcessData->Console = NULL;
- RemoveEntryList(&ProcessData->ProcessEntry);
- if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
- {
- ConioDeleteConsole((Object_t *) Console);
- }
- return STATUS_SUCCESS;
+ return Win32CsrReleaseConsole(ProcessData);
}
static VOID FASTCALL
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Status;
}
+ Console = Buff->Header.Console;
if(Request->Data.WriteConsoleRequest.Unicode)
{
if (Buffer)
{
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
Status = ConioWriteConsole(Console, Buff, Buffer,
{
Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
}
- ConioUnlockScreenBuffer(Buff);
}
if (Request->Data.WriteConsoleRequest.Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
}
}
- ConioUnlockConsole(Console);
+ ConioUnlockScreenBuffer(Buff);
Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
}
VOID WINAPI
-ConioDeleteScreenBuffer(Object_t *Object)
+ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer)
{
- PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
- DeleteCriticalSection(&Buffer->Header.Lock);
- HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
- HeapFree(Win32CsrApiHeap, 0, Buffer);
+ PCSRSS_CONSOLE Console = Buffer->Header.Console;
+
+ RemoveEntryList(&Buffer->ListEntry);
+ if (Buffer == Console->ActiveBuffer)
+ {
+ /* Deleted active buffer; switch to most recently created */
+ Console->ActiveBuffer = NULL;
+ if (!IsListEmpty(&Console->BufferList))
+ {
+ Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry);
+ ConioDrawConsole(Console);
+ }
+ }
+
+ HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
+ HeapFree(Win32CsrApiHeap, 0, Buffer);
}
VOID FASTCALL
}
ConioCleanupConsole(Console);
- if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+ ConioDeleteScreenBuffer(Console->ActiveBuffer);
+ if (!IsListEmpty(&Console->BufferList))
{
- ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+ DPRINT1("BUG: screen buffer list not empty\n");
}
- Console->ActiveBuffer = NULL;
-
CloseHandle(Console->ActiveEvent);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
HeapFree(Win32CsrApiHeap, 0, Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
pInfo->dwSize.X = Buff->MaxX;
pInfo->dwSize.Y = Buff->MaxY;
pInfo->dwMaximumWindowSize.X = Buff->MaxX;
pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
DPRINT("CsrSetCursor\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
NewCursorX = Request->Data.SetCursorRequest.Position.X;
NewCursorY = Request->Data.SetCursorRequest.Position.Y;
NewCursorY < 0 || NewCursorY >= Buff->MaxY)
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
OldCursorX = Buff->CurrentX;
if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ Status = ConioLockScreenBuffer(ProcessData,
+ Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+ &Buff,
+ GENERIC_WRITE);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
if (NT_SUCCESS(Status))
{
+ Console = Buff->Header.Console;
if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
if (String)
{
- Status = ConioLockScreenBuffer(ProcessData,
- Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
- ConioUnlockScreenBuffer(Buff);
}
if (Request->Data.WriteConsoleRequest.Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, tmpString);
}
}
- ConioUnlockConsole(Console);
+ ConioUnlockScreenBuffer(Buff);
}
Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
return Status;
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
X = Request->Data.FillOutputRequest.Position.X;
Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY;
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Length = Request->Data.FillOutputRequest.Length;
Request->Data.FillOutputRequest.NrCharactersWritten = Length;
return STATUS_SUCCESS;
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
ConioDrawRegion(Console, &UpdateRect);
}
- ConioUnlockConsole(Console);
-
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
DPRINT("CsrFillOutputAttrib\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
X = Request->Data.FillOutputAttribRequest.Coord.X;
Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY;
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
if (! ConioSetCursorInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
DPRINT("CsrSetTextAttrib\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
if (Buff == Console->ActiveBuffer)
if (! ConioUpdateScreenInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = Win32CsrGetObject(ProcessData,
- Request->Data.SetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_WRITE);
+ Status = Win32CsrLockObject(ProcessData,
+ Request->Data.SetConsoleModeRequest.ConsoleHandle,
+ (Object_t **) &Console, GENERIC_WRITE, 0);
if (! NT_SUCCESS(Status))
{
return Status;
Status = STATUS_INVALID_HANDLE;
}
- Win32CsrReleaseObjectByPointer((Object_t *)Console);
+ Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_READ);
+ Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
+ (Object_t **) &Console, GENERIC_READ, 0);
if (! NT_SUCCESS(Status))
{
return Status;
Status = STATUS_INVALID_HANDLE;
}
- Win32CsrReleaseObjectByPointer((Object_t *)Console);
+ Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
DPRINT("CsrCreateScreenBuffer\n");
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
&Request->Data.CreateScreenBufferRequest.OutputHandle,
&Buff->Header,
Request->Data.CreateScreenBufferRequest.Access,
- Request->Data.CreateScreenBufferRequest.Inheritable);
+ Request->Data.CreateScreenBufferRequest.Inheritable,
+ Request->Data.CreateScreenBufferRequest.ShareMode);
}
}
else
}
ConioUnlockConsole(Console);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
DPRINT("CsrSetScreenBuffer\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
if (Buff == Console->ActiveBuffer)
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
- /* drop reference to old buffer, maybe delete */
- if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+ /* If old buffer has no handles, it's now unreferenced */
+ if (Console->ActiveBuffer->Header.HandleCount == 0)
{
- ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
+ ConioDeleteScreenBuffer(Console->ActiveBuffer);
}
/* tie console to new buffer */
Console->ActiveBuffer = Buff;
- /* inc ref count on new buffer */
- InterlockedIncrement(&Buff->Header.ReferenceCount);
/* Redraw the console */
ConioDrawConsole(Console);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
DPRINT("CsrWriteConsoleOutput\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
/* It is okay to have a WriteRegion completely outside the screen buffer.
No data is written then. */
ConioDrawRegion(Console, &WriteRegion);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1;
Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1;
DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer))
{
- ConioUnlockConsole(Console);
ConioUnlockScreenBuffer(Buff);
return STATUS_SUCCESS;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
CSR_API(CsrGetProcessList)
{
- PHANDLE Buffer;
+ PDWORD Buffer;
PCSRSS_CONSOLE Console;
PCSRSS_PROCESS_DATA current;
PLIST_ENTRY current_entry;
- ULONG nItems, nCopied, Length;
+ ULONG nItems = 0;
NTSTATUS Status;
+ ULONG_PTR Offset;
DPRINT("CsrGetProcessList\n");
- Buffer = Request->Data.GetProcessListRequest.ProcessId;
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- nItems = nCopied = 0;
- Request->Data.GetProcessListRequest.nProcessIdsCopied = 0;
- Request->Data.GetProcessListRequest.nProcessIdsTotal = 0;
+ Buffer = Request->Data.GetProcessListRequest.ProcessId;
+ Offset = (PBYTE)Buffer - (PBYTE)ProcessData->CsrSectionViewBase;
+ if (Offset >= ProcessData->CsrSectionViewSize
+ || (Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)) > (ProcessData->CsrSectionViewSize - Offset)
+ || Offset & (sizeof(DWORD) - 1))
+ {
+ return STATUS_ACCESS_VIOLATION;
+ }
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
return Status;
}
- DPRINT1("Console_Api Ctrl-C\n");
-
for(current_entry = Console->ProcessList.Flink;
current_entry != &Console->ProcessList;
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
- if(++nItems < Request->Data.GetProcessListRequest.nMaxIds)
+ if(++nItems <= Request->Data.GetProcessListRequest.nMaxIds)
{
- *(Buffer++) = current->ProcessId;
- nCopied++;
+ *Buffer++ = (DWORD)current->ProcessId;
}
}
ConioUnlockConsole(Console);
- Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied;
Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
-
- Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE);
- if (Length > sizeof(CSR_API_MESSAGE))
- {
- Request->Header.u1.s1.TotalLength = Length;
- Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE);
- }
return STATUS_SUCCESS;
}
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
if (!NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return Status;
}