NTSTATUS NTAPI ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console, IN PCONSOLE_SCREEN_BUFFER Buffer) { if (Console == NULL || Buffer == NULL) return STATUS_INVALID_PARAMETER; /* Validity check */ ASSERT(Console == Buffer->Header.Console); if (Buffer == Console->ActiveBuffer) return STATUS_SUCCESS; /* If old buffer has no handles, it's now unreferenced */ if (Console->ActiveBuffer->Header.HandleCount == 0) { ConioDeleteScreenBuffer(Console->ActiveBuffer); } /* Tie console to new buffer */ ConioSetActiveScreenBuffer(Buffer); return STATUS_SUCCESS; }
static VOID ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry) { PCONSOLE_IO_OBJECT Object = Entry->Object; if (Object != NULL) { /// LOCK /// PCONSOLE Console = Object->Console; /// LOCK /// EnterCriticalSection(&Console->Lock); /* * If this is a input handle, notify and dereference * all the waits related to this handle. */ if (Object->Type == INPUT_BUFFER) { PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; /* * Wake up all the writing waiters related to this handle for this * input buffer, if any, then dereference them and purge them all * from the list. * To select them amongst all the waiters for this input buffer, * pass the handle pointer to the waiters, then they will check * whether or not they are related to this handle and if so, they * return. */ CsrNotifyWait(&InputBuffer->ReadWaitQueue, TRUE, NULL, (PVOID)Entry); if (!IsListEmpty(&InputBuffer->ReadWaitQueue)) { CsrDereferenceWait(&InputBuffer->ReadWaitQueue); } } /* If the last handle to a screen buffer is closed, delete it... */ if (AdjustHandleCounts(Entry, -1) == 0) { if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER) { PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; /* ...unless it's the only buffer left. Windows allows deletion * even of the last buffer, but having to deal with a lack of * any active buffer might be error-prone. */ if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) ConioDeleteScreenBuffer(Buffer); } else if (Object->Type == INPUT_BUFFER) { DPRINT("Closing the input buffer\n"); } else { DPRINT1("Invalid object type %d\n", Object->Type); } } /// LOCK /// LeaveCriticalSection(&Console->Lock); /* Invalidate (zero-out) this handle entry */ // Entry->Object = NULL; // RtlZeroMemory(Entry, sizeof(*Entry)); } RtlZeroMemory(Entry, sizeof(*Entry)); // Be sure the whole entry is invalidated. }