return STATUS_INVALID_HANDLE;
}
- InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
+ InterlockedIncrement(&ProcessConsole->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- EnterCriticalSection(&(ProcessConsole->Header.Lock));
+ 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++)
//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;
Console->ActiveBuffer = NULL;
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;
}
{
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->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->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;
ConioDeleteScreenBuffer(Object_t *Object)
{
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
- DeleteCriticalSection(&Buffer->Header.Lock);
HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
HeapFree(Win32CsrApiHeap, 0, Buffer);
}
}
ConioCleanupConsole(Console);
- if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
- {
- ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
- }
+ ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
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("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);
}
/* 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))
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;
}
/* FUNCTIONS *****************************************************************/
-static unsigned ObjectDefinitionsCount = 2;
-static CSRSS_OBJECT_DEFINITION ObjectDefinitions[] =
-{
- { CONIO_CONSOLE_MAGIC, ConioDeleteConsole },
- { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer },
-};
-
static
BOOL
CsrIsConsoleHandle(HANDLE Handle)
return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
}
-NTSTATUS
-FASTCALL
-Win32CsrGetObject(
- PCSRSS_PROCESS_DATA ProcessData,
- HANDLE Handle,
- Object_t **Object,
- DWORD Access )
+static VOID
+Win32CsrCreateHandleEntry(
+ PCSRSS_HANDLE Entry,
+ Object_t *Object,
+ DWORD Access,
+ BOOL Inheritable)
{
- ULONG_PTR h = (ULONG_PTR)Handle >> 2;
-
- DPRINT("CsrGetObject, Object: %x, %x, %x\n",
- Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
- || (*Object = ProcessData->HandleTable[h].Object) == NULL
- || ~ProcessData->HandleTable[h].Access & Access)
- {
- DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
- _InterlockedIncrement(&(*Object)->ReferenceCount);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- // DbgPrint( "CsrGetObject returning\n" );
- return STATUS_SUCCESS;
+ Entry->Object = Object;
+ Entry->Access = Access;
+ Entry->Inheritable = Inheritable;
+ _InterlockedIncrement(&Object->HandleCount);
}
-
-NTSTATUS
-FASTCALL
-Win32CsrReleaseObjectByPointer(
- Object_t *Object)
+static VOID
+Win32CsrCloseHandleEntry(
+ PCSRSS_HANDLE Entry)
{
- unsigned DefIndex;
-
- /* dec ref count */
- if (_InterlockedDecrement(&Object->ReferenceCount) == 0)
+ Object_t *Object = Entry->Object;
+ if (Object != NULL)
{
- for (DefIndex = 0; DefIndex < ObjectDefinitionsCount; DefIndex++)
+ Entry->Object = NULL;
+ /* If the last handle to a screen buffer is closed, delete it */
+ if (_InterlockedDecrement(&Object->HandleCount) == 0
+ && Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
{
- if (Object->Type == ObjectDefinitions[DefIndex].Type)
- {
- (ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object);
- return STATUS_SUCCESS;
- }
+ PCSRSS_CONSOLE Console = Object->Console;
+ EnterCriticalSection(&Console->Lock);
+ /* TODO: Should delete even the active buffer, but we're not yet ready
+ * to deal with the case where this results in no buffers left. */
+ if (Object != &Console->ActiveBuffer->Header)
+ ConioDeleteScreenBuffer(Object);
+ LeaveCriticalSection(&Console->Lock);
}
-
- DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object->Type);
}
-
- return STATUS_SUCCESS;
}
NTSTATUS
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
- ProcessData->HandleTable[h].Object = NULL;
+ Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- return Win32CsrReleaseObjectByPointer(Object);
+ return STATUS_SUCCESS;
}
NTSTATUS
DWORD Access,
LONG Type)
{
- NTSTATUS Status;
+ ULONG_PTR h = (ULONG_PTR)Handle >> 2;
- Status = Win32CsrGetObject(ProcessData, Handle, Object, Access);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
+ DPRINT("CsrGetObject, Object: %x, %x, %x\n",
+ Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
- if ((*Object)->Type != Type)
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
+ || (*Object = ProcessData->HandleTable[h].Object) == NULL
+ || ~ProcessData->HandleTable[h].Access & Access
+ || (Type != 0 && (*Object)->Type != Type))
{
- Win32CsrReleaseObjectByPointer(*Object);
+ DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
+ _InterlockedIncrement(&(*Object)->Console->ReferenceCount);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- EnterCriticalSection(&((*Object)->Lock));
-
+ EnterCriticalSection(&((*Object)->Console->Lock));
return STATUS_SUCCESS;
}
FASTCALL
Win32CsrUnlockObject(Object_t *Object)
{
- LeaveCriticalSection(&(Object->Lock));
- Win32CsrReleaseObjectByPointer(Object);
+ PCSRSS_CONSOLE Console = Object->Console;
+ LeaveCriticalSection(&Console->Lock);
+ /* dec ref count */
+ if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
+ ConioDeleteConsole(&Console->Header);
}
NTSTATUS
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
- {
- if (ProcessData->HandleTable[i].Object != NULL)
- Win32CsrReleaseObjectByPointer(ProcessData->HandleTable[i].Object);
- }
+ Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
ProcessData->HandleTableSize = 0;
RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = NULL;
Console = ProcessData->Console;
- ProcessData->Console = NULL;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
if (Console != NULL)
{
- EnterCriticalSection(&Console->Header.Lock);
+ ProcessData->Console = NULL;
+ EnterCriticalSection(&Console->Lock);
RemoveEntryList(&ProcessData->ProcessEntry);
- LeaveCriticalSection(&Console->Header.Lock);
- Win32CsrReleaseObjectByPointer(&Console->Header);
+ LeaveCriticalSection(&Console->Lock);
+ if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
+ ConioDeleteConsole(&Console->Header);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
-
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64;
}
- ProcessData->HandleTable[i].Object = Object;
- ProcessData->HandleTable[i].Access = Access;
- ProcessData->HandleTable[i].Inheritable = Inheritable;
+ Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i], Object, Access, Inheritable);
*Handle = UlongToHandle((i << 2) | 0x3);
- _InterlockedIncrement( &Object->ReferenceCount );
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_SUCCESS);
}
if (SourceProcessData->HandleTable[i].Object != NULL &&
SourceProcessData->HandleTable[i].Inheritable)
{
- TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
- _InterlockedIncrement( &SourceProcessData->HandleTable[i].Object->ReferenceCount );
+ Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i],
+ SourceProcessData->HandleTable[i].Object,
+ SourceProcessData->HandleTable[i].Access,
+ SourceProcessData->HandleTable[i].Inheritable);
}
}
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
if (NT_SUCCESS(Request->Status)
&& Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE)
{
- /* Close the original handle. This cannot drop the count to 0, since a new handle now exists */
- _InterlockedDecrement(&Entry->Object->ReferenceCount);
- Entry->Object = NULL;
+ Win32CsrCloseHandleEntry(Entry);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);