mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 03:05:40 +00:00
[CONSRV]
Start to separate better the CSR console server layer from the pure set of console functions (which will constitute a future console driver called... condrv :) ), and rework the terminal frontends interface. Now load the frontends by order : - the tui if we're in console mode - the gui, otherwise. (It's a temporary solution) More modifications to come ! svn path=/trunk/; revision=59297
This commit is contained in:
parent
f00adc9916
commit
c34686cca0
18 changed files with 2502 additions and 1762 deletions
|
@ -12,13 +12,16 @@ list(APPEND SOURCE
|
||||||
alias.c
|
alias.c
|
||||||
coninput.c
|
coninput.c
|
||||||
conoutput.c
|
conoutput.c
|
||||||
graphics.c
|
|
||||||
text.c
|
text.c
|
||||||
console.c
|
console.c
|
||||||
|
frontendctl.c
|
||||||
handle.c
|
handle.c
|
||||||
init.c
|
init.c
|
||||||
lineinput.c
|
lineinput.c
|
||||||
settings.c
|
settings.c
|
||||||
|
condrv/console.c
|
||||||
|
condrv/graphics.c
|
||||||
|
frontends/input.c
|
||||||
frontends/gui/guiterm.c
|
frontends/gui/guiterm.c
|
||||||
frontends/gui/guisettings.c
|
frontends/gui/guisettings.c
|
||||||
frontends/gui/graphics.c
|
frontends/gui/graphics.c
|
||||||
|
|
984
reactos/win32ss/user/consrv/condrv/console.c
Normal file
984
reactos/win32ss/user/consrv/condrv/console.c
Normal file
|
@ -0,0 +1,984 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/condrv/console.c
|
||||||
|
* PURPOSE: Console Management Functions
|
||||||
|
* PROGRAMMERS: Gé van Geldorp
|
||||||
|
* Jeffrey Morlan
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include "consrv.h"
|
||||||
|
#include "include/conio.h"
|
||||||
|
#include "conio.h"
|
||||||
|
#include "handle.h"
|
||||||
|
#include "procinit.h"
|
||||||
|
#include "alias.h"
|
||||||
|
#include "coninput.h"
|
||||||
|
#include "conoutput.h"
|
||||||
|
#include "lineinput.h"
|
||||||
|
#include "include/settings.h"
|
||||||
|
|
||||||
|
#include "include/console.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
// FIXME: Add this prototype to winternl.h / rtlfuncs.h / ...
|
||||||
|
NTSTATUS NTAPI RtlGetLastNtStatus(VOID);
|
||||||
|
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
static LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
||||||
|
static RTL_RESOURCE ListLock;
|
||||||
|
|
||||||
|
#define ConDrvLockConsoleListExclusive() \
|
||||||
|
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConDrvLockConsoleListShared() \
|
||||||
|
RtlAcquireResourceShared(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConDrvUnlockConsoleList() \
|
||||||
|
RtlReleaseResource(&ListLock)
|
||||||
|
|
||||||
|
// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
|
||||||
|
BOOLEAN
|
||||||
|
ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
|
||||||
|
IN PCWSTR Source)
|
||||||
|
{
|
||||||
|
SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
|
||||||
|
if (Size > MAXUSHORT) return FALSE;
|
||||||
|
|
||||||
|
UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
|
||||||
|
if (UniDest->Buffer == NULL) return FALSE;
|
||||||
|
|
||||||
|
RtlCopyMemory(UniDest->Buffer, Source, Size);
|
||||||
|
UniDest->MaximumLength = (USHORT)Size;
|
||||||
|
UniDest->Length = (USHORT)Size - sizeof(WCHAR);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431
|
||||||
|
VOID
|
||||||
|
ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
||||||
|
{
|
||||||
|
if (UnicodeString->Buffer)
|
||||||
|
{
|
||||||
|
ConsoleFreeHeap(UnicodeString->Buffer);
|
||||||
|
RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ConDrvConsoleCtrlEventTimeout(IN ULONG Event,
|
||||||
|
IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
|
IN ULONG Timeout)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
DPRINT("ConDrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
||||||
|
|
||||||
|
if (ProcessData->CtrlDispatcher)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
HANDLE Thread = NULL;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||||
|
ProcessData->CtrlDispatcher,
|
||||||
|
UlongToPtr(Event), 0, NULL);
|
||||||
|
if (NULL == Thread)
|
||||||
|
{
|
||||||
|
Status = RtlGetLastNtStatus();
|
||||||
|
DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||||
|
WaitForSingleObject(Thread, Timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
|
CloseHandle(Thread);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
DPRINT1("ConDrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ConDrvConsoleCtrlEvent(IN ULONG Event,
|
||||||
|
IN PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
|
{
|
||||||
|
return ConDrvConsoleCtrlEventTimeout(Event, ProcessData, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
ConioPause(PCONSOLE Console, UINT Flags)
|
||||||
|
{
|
||||||
|
Console->PauseFlags |= Flags;
|
||||||
|
if (!Console->UnpauseEvent)
|
||||||
|
Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
ConioUnpause(PCONSOLE 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);
|
||||||
|
if (!IsListEmpty(&Console->WriteWaitQueue))
|
||||||
|
{
|
||||||
|
CsrDereferenceWait(&Console->WriteWaitQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Console accessibility check helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
BOOLEAN NTAPI
|
||||||
|
ConDrvValidateConsolePointer(IN PCONSOLE Console)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY ConsoleEntry;
|
||||||
|
PCONSOLE CurrentConsole = NULL;
|
||||||
|
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/* The console list must be locked */
|
||||||
|
// ASSERT(Console_list_locked);
|
||||||
|
|
||||||
|
ConsoleEntry = ConsoleList.Flink;
|
||||||
|
while (ConsoleEntry != &ConsoleList)
|
||||||
|
{
|
||||||
|
CurrentConsole = CONTAINING_RECORD(ConsoleEntry, CONSOLE, Entry);
|
||||||
|
ConsoleEntry = ConsoleEntry->Flink;
|
||||||
|
if (CurrentConsole == Console) return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN NTAPI
|
||||||
|
ConDrvValidateConsoleState(IN PCONSOLE Console,
|
||||||
|
IN CONSOLE_STATE ExpectedState)
|
||||||
|
{
|
||||||
|
// if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/* The console must be locked */
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
return (Console->State == ExpectedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN NTAPI
|
||||||
|
ConDrvValidateConsoleUnsafe(IN PCONSOLE Console,
|
||||||
|
IN CONSOLE_STATE ExpectedState,
|
||||||
|
IN BOOLEAN LockConsole)
|
||||||
|
{
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock the console to forbid possible console's state changes
|
||||||
|
* (which must be done when the console is already locked).
|
||||||
|
* If we don't want to lock it, it's because the lock is already
|
||||||
|
* held. So there must be no problems.
|
||||||
|
*/
|
||||||
|
if (LockConsole) EnterCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
/* Check whether the console's state is what we expect */
|
||||||
|
if (!ConDrvValidateConsoleState(Console, ExpectedState))
|
||||||
|
{
|
||||||
|
if (LockConsole) LeaveCriticalSection(&Console->Lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN NTAPI
|
||||||
|
ConDrvValidateConsole(IN PCONSOLE Console,
|
||||||
|
IN CONSOLE_STATE ExpectedState,
|
||||||
|
IN BOOLEAN LockConsole)
|
||||||
|
{
|
||||||
|
BOOLEAN RetVal = FALSE;
|
||||||
|
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forbid creation or deletion of consoles when
|
||||||
|
* checking for the existence of a console.
|
||||||
|
*/
|
||||||
|
ConDrvLockConsoleListShared();
|
||||||
|
|
||||||
|
if (ConDrvValidateConsolePointer(Console))
|
||||||
|
{
|
||||||
|
RetVal = ConDrvValidateConsoleUnsafe(Console,
|
||||||
|
ExpectedState,
|
||||||
|
LockConsole);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGrabConsole(IN PCONSOLE Console,
|
||||||
|
IN BOOLEAN LockConsole)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
if (ConDrvValidateConsole(Console, CONSOLE_RUNNING, LockConsole))
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&Console->ReferenceCount);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvReleaseConsole(IN PCONSOLE Console,
|
||||||
|
IN BOOLEAN WasConsoleLocked)
|
||||||
|
{
|
||||||
|
LONG RefCount = 0;
|
||||||
|
|
||||||
|
if (!Console) return;
|
||||||
|
// if (Console->ReferenceCount == 0) return; // This shouldn't happen
|
||||||
|
ASSERT(Console->ReferenceCount > 0);
|
||||||
|
|
||||||
|
/* The console must be locked */
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the reference count. Save the new value too,
|
||||||
|
* because Console->ReferenceCount might be modified after
|
||||||
|
* the console gets unlocked but before we check whether we
|
||||||
|
* can destroy it.
|
||||||
|
*/
|
||||||
|
RefCount = _InterlockedDecrement(&Console->ReferenceCount);
|
||||||
|
|
||||||
|
/* Unlock the console if needed */
|
||||||
|
if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
/* Delete the console if needed */
|
||||||
|
if (RefCount <= 0) ConDrvDeleteConsole(Console);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
|
||||||
|
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvInitConsoleSupport(VOID)
|
||||||
|
{
|
||||||
|
DPRINT("CONSRV: ConDrvInitConsoleSupport()\n");
|
||||||
|
|
||||||
|
/* Initialize the console list and its lock */
|
||||||
|
InitializeListHead(&ConsoleList);
|
||||||
|
RtlInitializeResource(&ListLock);
|
||||||
|
|
||||||
|
/* Should call LoadKeyboardLayout */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
|
IN PCONSOLE_INFO ConsoleInfo,
|
||||||
|
IN ULONG ConsoleLeaderProcessId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||||
|
// CONSOLE_INFO CapturedConsoleInfo;
|
||||||
|
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
|
||||||
|
PCONSOLE Console;
|
||||||
|
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
||||||
|
// WCHAR DefaultTitle[128];
|
||||||
|
|
||||||
|
if (NewConsole == NULL || ConsoleInfo == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*NewConsole = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a console structure
|
||||||
|
*/
|
||||||
|
Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(CONSOLE));
|
||||||
|
if (NULL == Console)
|
||||||
|
{
|
||||||
|
DPRINT1("Not enough memory for console creation.\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the console settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 1. Load the default settings */
|
||||||
|
// ConSrvGetDefaultSettings(ConsoleInfo, ProcessId);
|
||||||
|
|
||||||
|
// /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
|
||||||
|
// Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
|
||||||
|
// sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
|
||||||
|
// wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
|
||||||
|
// ConsoleInfo.ConsoleTitle[Length] = L'\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 4. Load the remaining console settings via the registry.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Either we weren't created by an app launched via a shell-link,
|
||||||
|
* or we failed to load shell-link console properties.
|
||||||
|
* Therefore, load the console infos for the application from the registry.
|
||||||
|
*/
|
||||||
|
ConSrvReadUserSettings(ConsoleInfo, ProcessId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, update them with the properties the user might gave to us
|
||||||
|
* via the STARTUPINFO structure before calling CreateProcess
|
||||||
|
* (and which was transmitted via the ConsoleStartInfo structure).
|
||||||
|
* We therefore overwrite the values read in the registry.
|
||||||
|
*/
|
||||||
|
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
||||||
|
{
|
||||||
|
ConsoleInfo->ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute;
|
||||||
|
}
|
||||||
|
if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
||||||
|
{
|
||||||
|
ConsoleInfo->ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize;
|
||||||
|
}
|
||||||
|
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
||||||
|
{
|
||||||
|
// ConsoleInfo->ConsoleSize = ConsoleStartInfo->ConsoleWindowSize;
|
||||||
|
ConsoleInfo->ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx;
|
||||||
|
ConsoleInfo->ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix the screen buffer size if needed. The rule is:
|
||||||
|
* ScreenBufferSize >= ConsoleSize
|
||||||
|
*/
|
||||||
|
if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X)
|
||||||
|
ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X;
|
||||||
|
if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y)
|
||||||
|
ConsoleInfo->ScreenBufferSize.Y = ConsoleInfo->ConsoleSize.Y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the console
|
||||||
|
*/
|
||||||
|
Console->State = CONSOLE_INITIALIZING;
|
||||||
|
Console->ReferenceCount = 0;
|
||||||
|
InitializeCriticalSection(&Console->Lock);
|
||||||
|
InitializeListHead(&Console->ProcessList);
|
||||||
|
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
|
||||||
|
|
||||||
|
memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(ConsoleInfo->Colors));
|
||||||
|
Console->ConsoleSize = ConsoleInfo->ConsoleSize;
|
||||||
|
Console->FixedSize = FALSE; // Value by default; is reseted by the front-ends if needed.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the input buffer
|
||||||
|
*/
|
||||||
|
ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
|
||||||
|
|
||||||
|
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
SecurityAttributes.lpSecurityDescriptor = NULL;
|
||||||
|
SecurityAttributes.bInheritHandle = TRUE;
|
||||||
|
Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
|
||||||
|
if (NULL == Console->InputBuffer.ActiveEvent)
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(&Console->Lock);
|
||||||
|
ConsoleFreeHeap(Console);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console->InputBuffer.InputBufferSize = 0; // FIXME!
|
||||||
|
InitializeListHead(&Console->InputBuffer.InputEvents);
|
||||||
|
InitializeListHead(&Console->InputBuffer.ReadWaitQueue);
|
||||||
|
Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
|
||||||
|
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
|
||||||
|
|
||||||
|
Console->QuickEdit = ConsoleInfo->QuickEdit;
|
||||||
|
Console->InsertMode = ConsoleInfo->InsertMode;
|
||||||
|
Console->LineBuffer = NULL;
|
||||||
|
Console->LineMaxSize = Console->LineSize = Console->LinePos = 0;
|
||||||
|
Console->LineComplete = Console->LineUpPressed = Console->LineInsertToggle = FALSE;
|
||||||
|
// LineWakeupMask
|
||||||
|
|
||||||
|
// FIXME: This is terminal-specific !! VV
|
||||||
|
RtlZeroMemory(&Console->Selection, sizeof(CONSOLE_SELECTION_INFO));
|
||||||
|
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
|
||||||
|
// dwSelectionCursor
|
||||||
|
|
||||||
|
/* Set-up the code page */
|
||||||
|
Console->CodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
|
||||||
|
|
||||||
|
/* Initialize a new text-mode screen buffer with default settings */
|
||||||
|
ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
|
||||||
|
ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib;
|
||||||
|
ScreenBufferInfo.PopupAttrib = ConsoleInfo->PopupAttrib;
|
||||||
|
ScreenBufferInfo.IsCursorVisible = TRUE;
|
||||||
|
ScreenBufferInfo.CursorSize = ConsoleInfo->CursorSize;
|
||||||
|
|
||||||
|
InitializeListHead(&Console->BufferList);
|
||||||
|
Status = ConSrvCreateScreenBuffer(&NewBuffer,
|
||||||
|
Console,
|
||||||
|
CONSOLE_TEXTMODE_BUFFER,
|
||||||
|
&ScreenBufferInfo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ConSrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
|
||||||
|
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||||
|
DeleteCriticalSection(&Console->Lock);
|
||||||
|
ConsoleFreeHeap(Console);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/* Make the new screen buffer active */
|
||||||
|
Console->ActiveBuffer = NewBuffer;
|
||||||
|
InitializeListHead(&Console->WriteWaitQueue);
|
||||||
|
Console->PauseFlags = 0;
|
||||||
|
Console->UnpauseEvent = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the alias and history buffers
|
||||||
|
*/
|
||||||
|
Console->Aliases = NULL;
|
||||||
|
InitializeListHead(&Console->HistoryBuffers);
|
||||||
|
Console->HistoryBufferSize = ConsoleInfo->HistoryBufferSize;
|
||||||
|
Console->NumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers;
|
||||||
|
Console->HistoryNoDup = ConsoleInfo->HistoryNoDup;
|
||||||
|
|
||||||
|
/* Initialize the console title */
|
||||||
|
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
|
||||||
|
// if (ConsoleInfo.ConsoleTitle[0] == L'\0')
|
||||||
|
// {
|
||||||
|
// if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
|
||||||
|
// {
|
||||||
|
// ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/* Lock the console until its initialization is finished */
|
||||||
|
// EnterCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
DPRINT("Console initialized\n");
|
||||||
|
|
||||||
|
/* All went right, so add the console to the list */
|
||||||
|
ConDrvLockConsoleListExclusive();
|
||||||
|
DPRINT("Insert in the list\n");
|
||||||
|
InsertTailList(&ConsoleList, &Console->Entry);
|
||||||
|
|
||||||
|
/* The initialization is finished */
|
||||||
|
DPRINT("Change state\n");
|
||||||
|
Console->State = CONSOLE_RUNNING;
|
||||||
|
|
||||||
|
/* Unlock the console */
|
||||||
|
// LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
/* Unlock the console list */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
|
||||||
|
/* Return the newly created console to the caller and a success code too */
|
||||||
|
*NewConsole = Console;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvRegisterFrontEnd(IN PCONSOLE Console,
|
||||||
|
IN PFRONTEND FrontEnd)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (Console == NULL || FrontEnd == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* FIXME: Lock the console before ?? */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach the frontend to the console. Use now the TermIFace of the console,
|
||||||
|
* and not the user-defined temporary FrontEnd pointer.
|
||||||
|
*/
|
||||||
|
Console->TermIFace = *FrontEnd;
|
||||||
|
Console->TermIFace.Console = Console;
|
||||||
|
|
||||||
|
/* Initialize the frontend AFTER having attached it to the console */
|
||||||
|
DPRINT("Finish initialization of frontend\n");
|
||||||
|
Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("FrontEnd initialization failed, Status = 0x%08lx\n", Status);
|
||||||
|
|
||||||
|
/* We failed, detach the frontend from the console */
|
||||||
|
FrontEnd->Console = NULL; // For the caller
|
||||||
|
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy buffer contents to screen */
|
||||||
|
// FrontEnd.Draw();
|
||||||
|
// ConioDrawConsole(Console);
|
||||||
|
DPRINT("Console drawn\n");
|
||||||
|
|
||||||
|
DPRINT("Terminal FrontEnd initialization done\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvDeregisterFrontEnd(IN PCONSOLE Console)
|
||||||
|
{
|
||||||
|
if (Console == NULL) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* FIXME: Lock the console before ?? */
|
||||||
|
|
||||||
|
/* Deinitialize the frontend BEFORE detaching it from the console */
|
||||||
|
Console->TermIFace.Vtbl->DeinitFrontEnd(&Console->TermIFace/*, Console*/);
|
||||||
|
|
||||||
|
/* Detach the frontend from the console */
|
||||||
|
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
|
||||||
|
|
||||||
|
DPRINT("Terminal FrontEnd unregistered\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvDeleteConsole(IN PCONSOLE Console)
|
||||||
|
{
|
||||||
|
DPRINT("ConDrvDeleteConsole(0x%p)\n", Console);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forbid validation of any console by other threads
|
||||||
|
* during the deletion of this console.
|
||||||
|
*/
|
||||||
|
ConDrvLockConsoleListExclusive();
|
||||||
|
|
||||||
|
/* Check the existence of the console, and if it's ok, continue */
|
||||||
|
if (!ConDrvValidateConsolePointer(Console))
|
||||||
|
{
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the console is already being destroyed
|
||||||
|
* (thus not running), just return.
|
||||||
|
*/
|
||||||
|
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are about to be destroyed. Signal it to other people
|
||||||
|
* so that they can terminate what they are doing, and that
|
||||||
|
* they cannot longer validate the console.
|
||||||
|
*/
|
||||||
|
Console->State = CONSOLE_TERMINATING;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow other threads to finish their job: basically, unlock
|
||||||
|
* all other calls to EnterCriticalSection(&Console->Lock); by
|
||||||
|
* ConDrvValidateConsole(Unsafe) functions so that they just see
|
||||||
|
* that we are not in CONSOLE_RUNNING state anymore, or unlock
|
||||||
|
* other concurrent calls to ConDrvDeleteConsole so that they
|
||||||
|
* can see that we are in fact already deleting the console.
|
||||||
|
*/
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
|
||||||
|
/* FIXME: Send a terminate message to all the processes owning this console */
|
||||||
|
|
||||||
|
/* Cleanup the UI-oriented part */
|
||||||
|
DPRINT("Deregister console\n");
|
||||||
|
ConDrvDeregisterFrontEnd(Console);
|
||||||
|
DPRINT("Console deregistered\n");
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Check that the console is in terminating state before continuing
|
||||||
|
* (the cleanup code must not change the state of the console...
|
||||||
|
* ...unless to cancel console deletion ?).
|
||||||
|
***/
|
||||||
|
|
||||||
|
ConDrvLockConsoleListExclusive();
|
||||||
|
|
||||||
|
/* Re-check the existence of the console, and if it's ok, continue */
|
||||||
|
if (!ConDrvValidateConsolePointer(Console))
|
||||||
|
{
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE))
|
||||||
|
{
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are now in destruction */
|
||||||
|
Console->State = CONSOLE_IN_DESTRUCTION;
|
||||||
|
|
||||||
|
/* Remove the console from the list */
|
||||||
|
RemoveEntryList(&Console->Entry);
|
||||||
|
|
||||||
|
/* We really delete the console. Reset the count to be sure. */
|
||||||
|
Console->ReferenceCount = 0;
|
||||||
|
|
||||||
|
/* Discard all entries in the input event queue */
|
||||||
|
PurgeInputBuffer(Console);
|
||||||
|
|
||||||
|
if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
|
||||||
|
|
||||||
|
IntDeleteAllAliases(Console);
|
||||||
|
HistoryDeleteBuffers(Console);
|
||||||
|
|
||||||
|
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||||
|
if (!IsListEmpty(&Console->BufferList))
|
||||||
|
{
|
||||||
|
DPRINT1("BUG: screen buffer list not empty\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/ CloseHandle(Console->InputBuffer.ActiveEvent); /**/
|
||||||
|
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||||
|
|
||||||
|
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||||
|
ConsoleFreeUnicodeString(&Console->Title);
|
||||||
|
|
||||||
|
DPRINT("ConDrvDeleteConsole - Unlocking\n");
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
DPRINT("ConDrvDeleteConsole - Destroying lock\n");
|
||||||
|
DeleteCriticalSection(&Console->Lock);
|
||||||
|
DPRINT("ConDrvDeleteConsole - Lock destroyed ; freeing console\n");
|
||||||
|
|
||||||
|
ConsoleFreeHeap(Console);
|
||||||
|
DPRINT("ConDrvDeleteConsole - Console destroyed\n");
|
||||||
|
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConDrvUnlockConsoleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGetConsoleMode(IN PCONSOLE Console,
|
||||||
|
IN PCONSOLE_IO_OBJECT Object,
|
||||||
|
OUT PULONG ConsoleMode)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (Console == NULL || Object == NULL || ConsoleMode == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Validity check */
|
||||||
|
ASSERT(Console == Object->Console);
|
||||||
|
|
||||||
|
/*** FIXME: */ *ConsoleMode = 0; /***/
|
||||||
|
|
||||||
|
if (INPUT_BUFFER == Object->Type)
|
||||||
|
{
|
||||||
|
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
|
||||||
|
|
||||||
|
*ConsoleMode = InputBuffer->Mode;
|
||||||
|
|
||||||
|
if (Console->QuickEdit || Console->InsertMode)
|
||||||
|
{
|
||||||
|
// Windows does this, even if it's not documented on MSDN
|
||||||
|
*ConsoleMode |= ENABLE_EXTENDED_FLAGS;
|
||||||
|
|
||||||
|
if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
|
||||||
|
if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
|
||||||
|
{
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
|
||||||
|
*ConsoleMode = Buffer->Mode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvSetConsoleMode(IN PCONSOLE Console,
|
||||||
|
IN PCONSOLE_IO_OBJECT Object,
|
||||||
|
IN ULONG ConsoleMode)
|
||||||
|
{
|
||||||
|
#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
|
||||||
|
#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
|
||||||
|
ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
|
||||||
|
ENABLE_MOUSE_INPUT )
|
||||||
|
#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT )
|
||||||
|
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (Console == NULL || Object == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Validity check */
|
||||||
|
ASSERT(Console == Object->Console);
|
||||||
|
|
||||||
|
if (INPUT_BUFFER == Object->Type)
|
||||||
|
{
|
||||||
|
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
|
||||||
|
|
||||||
|
DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Only the presence of valid mode flags is allowed.
|
||||||
|
*/
|
||||||
|
if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES))
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS,
|
||||||
|
* then consider the flags invalid.
|
||||||
|
*
|
||||||
|
if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) &&
|
||||||
|
(ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 )
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3. Now we can continue.
|
||||||
|
*/
|
||||||
|
if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
|
||||||
|
{
|
||||||
|
Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
|
||||||
|
Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
|
||||||
|
}
|
||||||
|
InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
|
||||||
|
}
|
||||||
|
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
|
||||||
|
{
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
|
||||||
|
|
||||||
|
DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode);
|
||||||
|
|
||||||
|
if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
||||||
|
IN OUT PWCHAR Title,
|
||||||
|
IN OUT PULONG BufLength)
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
if (Console == NULL || Title == NULL || BufLength == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Copy title of the console to the user title buffer */
|
||||||
|
if (*BufLength >= sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
Length = min(*BufLength - sizeof(WCHAR), Console->Title.Length);
|
||||||
|
RtlCopyMemory(Title, Console->Title.Buffer, Length);
|
||||||
|
Title[Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
*BufLength = Console->Title.Length;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
||||||
|
IN PWCHAR Title,
|
||||||
|
IN ULONG BufLength)
|
||||||
|
{
|
||||||
|
PWCHAR Buffer;
|
||||||
|
|
||||||
|
if (Console == NULL || Title == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Allocate a new buffer to hold the new title (NULL-terminated) */
|
||||||
|
Buffer = ConsoleAllocHeap(0, BufLength + sizeof(WCHAR));
|
||||||
|
if (!Buffer) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
/* Free the old title */
|
||||||
|
ConsoleFreeUnicodeString(&Console->Title);
|
||||||
|
|
||||||
|
/* Copy title to console */
|
||||||
|
Console->Title.Buffer = Buffer;
|
||||||
|
Console->Title.Length = BufLength;
|
||||||
|
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
|
||||||
|
RtlCopyMemory(Console->Title.Buffer, Title, Console->Title.Length);
|
||||||
|
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
|
// ConioChangeTitle(Console);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
||||||
|
OUT PUINT CodePage,
|
||||||
|
IN BOOLEAN InputCP)
|
||||||
|
{
|
||||||
|
if (Console == NULL || CodePage == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*CodePage = (InputCP ? Console->CodePage : Console->OutputCodePage);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvSetConsoleCP(IN PCONSOLE Console,
|
||||||
|
IN UINT CodePage,
|
||||||
|
IN BOOLEAN InputCP)
|
||||||
|
{
|
||||||
|
if (Console == NULL || !IsValidCodePage(CodePage))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (InputCP)
|
||||||
|
Console->CodePage = CodePage;
|
||||||
|
else
|
||||||
|
Console->OutputCodePage = CodePage;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGetConsoleProcessList(IN PCONSOLE Console,
|
||||||
|
IN OUT PULONG ProcessIdsList,
|
||||||
|
IN ULONG MaxIdListItems,
|
||||||
|
OUT PULONG ProcessIdsTotal)
|
||||||
|
{
|
||||||
|
PCONSOLE_PROCESS_DATA current;
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
|
||||||
|
if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*ProcessIdsTotal = 0;
|
||||||
|
|
||||||
|
for (current_entry = Console->ProcessList.Flink;
|
||||||
|
current_entry != &Console->ProcessList;
|
||||||
|
current_entry = current_entry->Flink)
|
||||||
|
{
|
||||||
|
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
|
||||||
|
if (++(*ProcessIdsTotal) <= MaxIdListItems)
|
||||||
|
{
|
||||||
|
*ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConDrvGenerateConsoleCtrlEvent
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
|
||||||
|
IN ULONG ProcessGroupId,
|
||||||
|
IN ULONG Event)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
PCONSOLE_PROCESS_DATA current;
|
||||||
|
|
||||||
|
/* If the console is already being destroyed, just return */
|
||||||
|
if (!ConDrvValidateConsole(Console, CONSOLE_RUNNING, FALSE))
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop through the process list, from the most recent process
|
||||||
|
* (the active one) to the oldest one (the first created, i.e.
|
||||||
|
* the console leader process), and for each, send an event
|
||||||
|
* (new processes are inserted at the head of the console process list).
|
||||||
|
*/
|
||||||
|
current_entry = Console->ProcessList.Flink;
|
||||||
|
while (current_entry != &Console->ProcessList)
|
||||||
|
{
|
||||||
|
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
|
||||||
|
current_entry = current_entry->Flink;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only processes belonging to the same process group are signaled.
|
||||||
|
* If the process group ID is zero, then all the processes are signaled.
|
||||||
|
*/
|
||||||
|
if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
|
||||||
|
{
|
||||||
|
Status = ConDrvConsoleCtrlEvent(Event, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -135,137 +135,24 @@ PurgeInputBuffer(PCONSOLE Console)
|
||||||
CloseHandle(Console->InputBuffer.ActiveEvent);
|
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD FASTCALL
|
VOID NTAPI
|
||||||
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
|
ConDrvProcessKey(IN PCONSOLE Console,
|
||||||
|
IN BOOLEAN Down,
|
||||||
|
IN UINT VirtualKeyCode,
|
||||||
|
IN UINT VirtualScanCode,
|
||||||
|
IN WCHAR UnicodeChar,
|
||||||
|
IN ULONG ShiftState,
|
||||||
|
IN BYTE KeyStateCtrl)
|
||||||
{
|
{
|
||||||
DWORD ssOut = 0;
|
|
||||||
|
|
||||||
if (KeyState[VK_CAPITAL] & 0x01)
|
|
||||||
ssOut |= CAPSLOCK_ON;
|
|
||||||
|
|
||||||
if (KeyState[VK_NUMLOCK] & 0x01)
|
|
||||||
ssOut |= NUMLOCK_ON;
|
|
||||||
|
|
||||||
if (KeyState[VK_SCROLL] & 0x01)
|
|
||||||
ssOut |= SCROLLLOCK_ON;
|
|
||||||
|
|
||||||
if (KeyState[VK_SHIFT] & 0x80)
|
|
||||||
ssOut |= SHIFT_PRESSED;
|
|
||||||
|
|
||||||
if (KeyState[VK_LCONTROL] & 0x80)
|
|
||||||
ssOut |= LEFT_CTRL_PRESSED;
|
|
||||||
if (KeyState[VK_RCONTROL] & 0x80)
|
|
||||||
ssOut |= RIGHT_CTRL_PRESSED;
|
|
||||||
|
|
||||||
if (KeyState[VK_LMENU] & 0x80)
|
|
||||||
ssOut |= LEFT_ALT_PRESSED;
|
|
||||||
if (KeyState[VK_RMENU] & 0x80)
|
|
||||||
ssOut |= RIGHT_ALT_PRESSED;
|
|
||||||
|
|
||||||
/* See WM_CHAR MSDN documentation for instance */
|
|
||||||
if (lParam & 0x01000000)
|
|
||||||
ssOut |= ENHANCED_KEY;
|
|
||||||
|
|
||||||
return ssOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID WINAPI
|
|
||||||
ConioProcessKey(PCONSOLE Console, MSG* msg)
|
|
||||||
{
|
|
||||||
static BYTE KeyState[256] = { 0 };
|
|
||||||
/* MSDN mentions that you should use the last virtual key code received
|
|
||||||
* when putting a virtual key identity to a WM_CHAR message since multiple
|
|
||||||
* or translated keys may be involved. */
|
|
||||||
static UINT LastVirtualKey = 0;
|
|
||||||
DWORD ShiftState;
|
|
||||||
WCHAR UnicodeChar;
|
|
||||||
UINT VirtualKeyCode;
|
|
||||||
UINT VirtualScanCode;
|
|
||||||
BOOL Down = FALSE;
|
|
||||||
INPUT_RECORD er;
|
INPUT_RECORD er;
|
||||||
BOOLEAN Fake; // synthesized, not a real event
|
|
||||||
BOOLEAN NotChar; // message should not be used to return a character
|
|
||||||
|
|
||||||
if (NULL == Console)
|
|
||||||
{
|
|
||||||
DPRINT1("No Active Console!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
|
|
||||||
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
|
|
||||||
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
|
|
||||||
|
|
||||||
GetKeyboardState(KeyState);
|
|
||||||
ShiftState = ConioGetShiftState(KeyState, msg->lParam);
|
|
||||||
|
|
||||||
if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
|
|
||||||
{
|
|
||||||
VirtualKeyCode = LastVirtualKey;
|
|
||||||
UnicodeChar = msg->wParam;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WCHAR Chars[2];
|
|
||||||
INT RetChars = 0;
|
|
||||||
|
|
||||||
VirtualKeyCode = msg->wParam;
|
|
||||||
RetChars = ToUnicodeEx(VirtualKeyCode,
|
|
||||||
VirtualScanCode,
|
|
||||||
KeyState,
|
|
||||||
Chars,
|
|
||||||
2,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
er.EventType = KEY_EVENT;
|
|
||||||
er.Event.KeyEvent.bKeyDown = Down;
|
|
||||||
er.Event.KeyEvent.wRepeatCount = 1;
|
|
||||||
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
|
||||||
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
|
||||||
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
|
||||||
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
|
||||||
|
|
||||||
if (ConioProcessKeyCallback(Console,
|
|
||||||
msg,
|
|
||||||
KeyState[VK_MENU],
|
|
||||||
ShiftState,
|
|
||||||
VirtualKeyCode,
|
|
||||||
Down))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fake = UnicodeChar &&
|
|
||||||
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
|
|
||||||
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
|
|
||||||
NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
|
|
||||||
if (NotChar) LastVirtualKey = msg->wParam;
|
|
||||||
|
|
||||||
DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
|
|
||||||
Down ? "down" : "up ",
|
|
||||||
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
|
|
||||||
"char" : "key ",
|
|
||||||
Fake ? "fake" : "real",
|
|
||||||
NotChar ? "notc" : "char",
|
|
||||||
VirtualScanCode,
|
|
||||||
VirtualKeyCode,
|
|
||||||
(UnicodeChar >= L' ') ? UnicodeChar : L'.',
|
|
||||||
ShiftState);
|
|
||||||
|
|
||||||
if (Fake) return;
|
|
||||||
|
|
||||||
/* process Ctrl-C and Ctrl-Break */
|
/* process Ctrl-C and Ctrl-Break */
|
||||||
if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||||
er.Event.KeyEvent.bKeyDown &&
|
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
|
||||||
((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
|
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
|
||||||
(er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
|
|
||||||
(er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Console_Api Ctrl-C\n");
|
DPRINT1("Console_Api Ctrl-C\n");
|
||||||
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
||||||
|
|
||||||
if (Console->LineBuffer && !Console->LineComplete)
|
if (Console->LineBuffer && !Console->LineComplete)
|
||||||
{
|
{
|
||||||
|
@ -276,39 +163,46 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != (er.Event.KeyEvent.dwControlKeyState
|
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
|
||||||
& (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
|
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
|
||||||
&& (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
|
|
||||||
|| VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
|
|
||||||
{
|
{
|
||||||
if (er.Event.KeyEvent.bKeyDown)
|
if (!Down) return;
|
||||||
|
|
||||||
|
/* scroll up or down */
|
||||||
|
if (VK_UP == VirtualKeyCode)
|
||||||
{
|
{
|
||||||
/* scroll up or down */
|
/* only scroll up if there is room to scroll up into */
|
||||||
if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
|
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
||||||
{
|
{
|
||||||
/* only scroll up if there is room to scroll up into */
|
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
||||||
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
|
||||||
{
|
Console->ActiveBuffer->ScreenBufferSize.Y;
|
||||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
Console->ActiveBuffer->CursorPosition.Y++;
|
||||||
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
|
|
||||||
Console->ActiveBuffer->ScreenBufferSize.Y;
|
|
||||||
Console->ActiveBuffer->CursorPosition.Y++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* only scroll down if there is room to scroll down into */
|
|
||||||
if (Console->ActiveBuffer->CursorPosition.Y != 0)
|
|
||||||
{
|
|
||||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
|
|
||||||
Console->ActiveBuffer->ScreenBufferSize.Y;
|
|
||||||
Console->ActiveBuffer->CursorPosition.Y--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ConioDrawConsole(Console);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* only scroll down if there is room to scroll down into */
|
||||||
|
if (Console->ActiveBuffer->CursorPosition.Y != 0)
|
||||||
|
{
|
||||||
|
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
|
||||||
|
Console->ActiveBuffer->ScreenBufferSize.Y;
|
||||||
|
Console->ActiveBuffer->CursorPosition.Y--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConioDrawConsole(Console);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
er.EventType = KEY_EVENT;
|
||||||
|
er.Event.KeyEvent.bKeyDown = Down;
|
||||||
|
er.Event.KeyEvent.wRepeatCount = 1;
|
||||||
|
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
||||||
|
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
||||||
|
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
||||||
|
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
||||||
|
|
||||||
ConioProcessInputEvent(Console, &er);
|
ConioProcessInputEvent(Console, &er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,13 @@
|
||||||
|
|
||||||
VOID FASTCALL PurgeInputBuffer(PCONSOLE Console);
|
VOID FASTCALL PurgeInputBuffer(PCONSOLE Console);
|
||||||
|
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvProcessKey(IN PCONSOLE Console,
|
||||||
|
IN BOOLEAN Down,
|
||||||
|
IN UINT VirtualKeyCode,
|
||||||
|
IN UINT VirtualScanCode,
|
||||||
|
IN WCHAR UnicodeChar,
|
||||||
|
IN ULONG ShiftState,
|
||||||
|
IN BYTE KeyStateCtrl);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -10,43 +10,41 @@
|
||||||
|
|
||||||
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
||||||
|
|
||||||
#define ConioCleanupConsole(Console) \
|
|
||||||
(Console)->TermIFace.Vtbl->CleanupConsole(Console)
|
|
||||||
#define ConioDrawRegion(Console, Region) \
|
#define ConioDrawRegion(Console, Region) \
|
||||||
(Console)->TermIFace.Vtbl->DrawRegion((Console), (Region))
|
(Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region))
|
||||||
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
||||||
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Block), (CurStartX), (CurStartY), \
|
||||||
(ScrolledLines), (Buffer), (Length))
|
(ScrolledLines), (Buffer), (Length))
|
||||||
#define ConioSetCursorInfo(Console, Buff) \
|
#define ConioSetCursorInfo(Console, Buff) \
|
||||||
(Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (Buff))
|
||||||
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
|
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
|
||||||
(Console)->TermIFace.Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
|
(Console)->TermIFace.Vtbl->SetScreenInfo(&(Console)->TermIFace, (Buff), (OldCursorX), (OldCursorY))
|
||||||
#define ConioResizeTerminal(Console) \
|
#define ConioResizeTerminal(Console) \
|
||||||
(Console)->TermIFace.Vtbl->ResizeTerminal(Console)
|
(Console)->TermIFace.Vtbl->ResizeTerminal(&(Console)->TermIFace)
|
||||||
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
|
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
|
||||||
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
(Console)->TermIFace.Vtbl->ProcessKeyCallback(&(Console)->TermIFace, (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
||||||
#define ConioRefreshInternalInfo(Console) \
|
#define ConioRefreshInternalInfo(Console) \
|
||||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo(Console)
|
(Console)->TermIFace.Vtbl->RefreshInternalInfo(&(Console)->TermIFace)
|
||||||
|
|
||||||
#define ConioChangeTitle(Console) \
|
#define ConioChangeTitle(Console) \
|
||||||
(Console)->TermIFace.Vtbl->ChangeTitle(Console)
|
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
|
||||||
#define ConioChangeIcon(Console, hWindowIcon) \
|
#define ConioChangeIcon(Console, hWindowIcon) \
|
||||||
(Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
|
(Console)->TermIFace.Vtbl->ChangeIcon(&(Console)->TermIFace, (hWindowIcon))
|
||||||
#define ConioGetConsoleWindowHandle(Console) \
|
#define ConioGetConsoleWindowHandle(Console) \
|
||||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
|
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(&(Console)->TermIFace)
|
||||||
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
||||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||||
#define ConioGetDisplayMode(Console) \
|
#define ConioGetDisplayMode(Console) \
|
||||||
(Console)->TermIFace.Vtbl->GetDisplayMode(Console)
|
(Console)->TermIFace.Vtbl->GetDisplayMode(&(Console)->TermIFace)
|
||||||
#define ConioSetDisplayMode(Console, NewMode) \
|
#define ConioSetDisplayMode(Console, NewMode) \
|
||||||
(Console)->TermIFace.Vtbl->SetDisplayMode((Console), (NewMode))
|
(Console)->TermIFace.Vtbl->SetDisplayMode(&(Console)->TermIFace, (NewMode))
|
||||||
#define ConioShowMouseCursor(Console, Show) \
|
#define ConioShowMouseCursor(Console, Show) \
|
||||||
(Console)->TermIFace.Vtbl->ShowMouseCursor((Console), (Show))
|
(Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show))
|
||||||
#define ConioSetMouseCursor(Console, hCursor) \
|
#define ConioSetMouseCursor(Console, hCursor) \
|
||||||
(Console)->TermIFace.Vtbl->SetMouseCursor((Console), (hCursor))
|
(Console)->TermIFace.Vtbl->SetMouseCursor(&(Console)->TermIFace, (hCursor))
|
||||||
#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \
|
#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \
|
||||||
(Console)->TermIFace.Vtbl->MenuControl((Console), (CmdIdLow), (CmdIdHigh))
|
(Console)->TermIFace.Vtbl->MenuControl(&(Console)->TermIFace, (CmdIdLow), (CmdIdHigh))
|
||||||
#define ConioSetMenuClose(Console, Enable) \
|
#define ConioSetMenuClose(Console, Enable) \
|
||||||
(Console)->TermIFace.Vtbl->SetMenuClose((Console), (Enable))
|
(Console)->TermIFace.Vtbl->SetMenuClose(&(Console)->TermIFace, (Enable))
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -150,6 +150,11 @@ ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
||||||
// ConioDrawConsole(Console);
|
// ConioDrawConsole(Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCONSOLE_SCREEN_BUFFER
|
||||||
|
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console)
|
||||||
|
{
|
||||||
|
return (Console ? Console->ActiveBuffer : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC SERVER APIS *********************************************************/
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -40,4 +40,7 @@ NTSTATUS FASTCALL ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
||||||
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||||
VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||||
|
|
||||||
|
PCONSOLE_SCREEN_BUFFER
|
||||||
|
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,16 +8,44 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
VOID WINAPI ConSrvInitConsoleSupport(VOID);
|
VOID NTAPI
|
||||||
|
ConDrvInitConsoleSupport(VOID);
|
||||||
|
|
||||||
NTSTATUS WINAPI ConSrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
NTSTATUS WINAPI
|
||||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
ConSrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
||||||
IN PCSR_PROCESS ConsoleLeaderProcess);
|
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
|
IN ULONG ConsoleLeaderProcessId);
|
||||||
VOID WINAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console);
|
VOID WINAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console);
|
||||||
|
|
||||||
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
struct _CONSOLE** /* PCONSOLE* */ Console,
|
struct _CONSOLE** /* PCONSOLE* */ Console,
|
||||||
BOOL LockConsole);
|
BOOL LockConsole);
|
||||||
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* /* PCONSOLE */ Console,
|
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* /* PCONSOLE */ Console,
|
||||||
BOOL WasConsoleLocked);
|
BOOL WasConsoleLocked);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvGrabConsole(IN struct _CONSOLE* /* PCONSOLE */ Console,
|
||||||
|
IN BOOLEAN LockConsole);
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvReleaseConsole(IN struct _CONSOLE* /* PCONSOLE */ Console,
|
||||||
|
IN BOOLEAN WasConsoleLocked);
|
||||||
|
|
||||||
|
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
|
||||||
|
typedef struct _CONSOLE_INFO CONSOLE_INFO, *PCONSOLE_INFO;
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
||||||
|
// IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
|
IN PCONSOLE_INFO ConsoleInfo,
|
||||||
|
IN ULONG ConsoleLeaderProcessId);
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvRegisterFrontEnd(IN struct _CONSOLE* /* PCONSOLE */ Console,
|
||||||
|
IN PFRONTEND FrontEnd);
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
ConDrvDeregisterFrontEnd(IN struct _CONSOLE* /* PCONSOLE */ Console);
|
||||||
|
VOID NTAPI
|
||||||
|
ConDrvDeleteConsole(IN struct _CONSOLE* /* PCONSOLE */ Console);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
379
reactos/win32ss/user/consrv/frontendctl.c
Normal file
379
reactos/win32ss/user/consrv/frontendctl.c
Normal file
|
@ -0,0 +1,379 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/frontendctl.c
|
||||||
|
* PURPOSE: Terminal Front-Ends Control
|
||||||
|
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include "consrv.h"
|
||||||
|
#include "include/conio.h"
|
||||||
|
#include "conio.h"
|
||||||
|
#include "conoutput.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "handle.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* HardwareStateProperty
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* Set/Get the value of the HardwareState and switch
|
||||||
|
* between direct video buffer ouput and GDI windowed
|
||||||
|
* output.
|
||||||
|
* ARGUMENTS
|
||||||
|
* Client hands us a CONSOLE_GETSETHWSTATE object.
|
||||||
|
* We use the same object to Request.
|
||||||
|
* NOTE
|
||||||
|
* ConsoleHwState has the correct size to be compatible
|
||||||
|
* with NT's, but values are not.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
static NTSTATUS FASTCALL
|
||||||
|
SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState)
|
||||||
|
{
|
||||||
|
DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
|
||||||
|
|
||||||
|
if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
|
||||||
|
||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
|
||||||
|
{
|
||||||
|
if (Console->HardwareState != ConsoleHwState)
|
||||||
|
{
|
||||||
|
/* TODO: implement switching from full screen to windowed mode */
|
||||||
|
/* TODO: or back; now simply store the hardware state */
|
||||||
|
Console->HardwareState = ConsoleHwState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CSR_API(SrvGetConsoleHardwareState)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
HardwareStateRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_READ,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
HardwareStateRequest->State = Console->HardwareState;
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return Status;
|
||||||
|
#else
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleHardwareState)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
HardwareStateRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Setting console hardware state.\n");
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
Status = SetConsoleHardwareState(Console, HardwareStateRequest->State);
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return Status;
|
||||||
|
#else
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvGetConsoleDisplayMode)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
&Console, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
GetDisplayModeRequest->DisplayMode = ConioGetDisplayMode(Console);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleDisplayMode)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
|
||||||
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
SetDisplayModeRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
|
||||||
|
if (ConioSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode))
|
||||||
|
{
|
||||||
|
SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvGetLargestConsoleWindowSize)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
GetLargestWindowSizeRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_READ,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
ConioGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size);
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvShowConsoleCursor)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
|
||||||
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
ShowCursorRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
|
||||||
|
ShowCursorRequest->RefCount = ConioShowMouseCursor(Console, ShowCursorRequest->Show);
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleCursor)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOL Success;
|
||||||
|
PCONSOLE_SETCURSOR SetCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
|
||||||
|
// FIXME: Tests show that this function is used only for graphics screen buffers
|
||||||
|
// and otherwise it returns false + set last error to invalid handle.
|
||||||
|
// NOTE: I find that behaviour is ridiculous but ok, let's accept that at the moment...
|
||||||
|
Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
SetCursorRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
|
||||||
|
Success = ConioSetMouseCursor(Console, SetCursorRequest->hCursor);
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvConsoleMenuControl)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
|
||||||
|
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
MenuControlRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Console = Buff->Header.Console;
|
||||||
|
|
||||||
|
MenuControlRequest->hMenu = ConioMenuControl(Console,
|
||||||
|
MenuControlRequest->dwCmdIdLow,
|
||||||
|
MenuControlRequest->dwCmdIdHigh);
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleMenuClose)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOL Success;
|
||||||
|
PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
&Console, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Success = ConioSetMenuClose(Console, SetMenuCloseRequest->Enable);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleWindowInfo)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff;
|
||||||
|
SMALL_RECT WindowRect = SetWindowInfoRequest->WindowRect;
|
||||||
|
|
||||||
|
DPRINT("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
|
||||||
|
SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
|
||||||
|
WindowRect.Left, WindowRect.Top, WindowRect.Right, WindowRect.Bottom);
|
||||||
|
|
||||||
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
|
SetWindowInfoRequest->OutputHandle,
|
||||||
|
&Buff,
|
||||||
|
GENERIC_READ,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
if (SetWindowInfoRequest->Absolute == FALSE)
|
||||||
|
{
|
||||||
|
/* Relative positions given. Transform them to absolute ones */
|
||||||
|
WindowRect.Left += Buff->ViewOrigin.X;
|
||||||
|
WindowRect.Top += Buff->ViewOrigin.Y;
|
||||||
|
WindowRect.Right += Buff->ViewOrigin.X + Buff->ViewSize.X - 1;
|
||||||
|
WindowRect.Bottom += Buff->ViewOrigin.Y + Buff->ViewSize.Y - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See MSDN documentation on SetConsoleWindowInfo about the performed checks */
|
||||||
|
if ( (WindowRect.Left < 0) || (WindowRect.Top < 0) ||
|
||||||
|
(WindowRect.Right >= Buff->ScreenBufferSize.X) ||
|
||||||
|
(WindowRect.Bottom >= Buff->ScreenBufferSize.Y) ||
|
||||||
|
(WindowRect.Right <= WindowRect.Left) ||
|
||||||
|
(WindowRect.Bottom <= WindowRect.Top) )
|
||||||
|
{
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buff->ViewOrigin.X = WindowRect.Left;
|
||||||
|
Buff->ViewOrigin.Y = WindowRect.Top;
|
||||||
|
|
||||||
|
Buff->ViewSize.X = WindowRect.Right - WindowRect.Left + 1;
|
||||||
|
Buff->ViewSize.Y = WindowRect.Bottom - WindowRect.Top + 1;
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvGetConsoleWindow)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
GetWindowRequest->WindowHandle = ConioGetConsoleWindowHandle(Console);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvSetConsoleIcon)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Status = (ConioChangeIcon(Console, SetIconRequest->WindowIcon)
|
||||||
|
? STATUS_SUCCESS
|
||||||
|
: STATUS_UNSUCCESSFUL);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvGetConsoleSelectionInfo)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest;
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
memset(&GetSelectionInfoRequest->Info, 0, sizeof(CONSOLE_SELECTION_INFO));
|
||||||
|
if (Console->Selection.dwFlags != 0)
|
||||||
|
GetSelectionInfoRequest->Info = Console->Selection;
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
File diff suppressed because it is too large
Load diff
146
reactos/win32ss/user/consrv/frontends/input.c
Normal file
146
reactos/win32ss/user/consrv/frontends/input.c
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/frontends/input.c
|
||||||
|
* PURPOSE: Common Front-Ends Input functions
|
||||||
|
* PROGRAMMERS: Jeffrey Morlan
|
||||||
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include "consrv.h"
|
||||||
|
#include "include/conio.h"
|
||||||
|
#include "conio.h"
|
||||||
|
#include "coninput.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
static DWORD FASTCALL
|
||||||
|
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
|
||||||
|
{
|
||||||
|
DWORD ssOut = 0;
|
||||||
|
|
||||||
|
if (KeyState[VK_CAPITAL] & 0x01)
|
||||||
|
ssOut |= CAPSLOCK_ON;
|
||||||
|
|
||||||
|
if (KeyState[VK_NUMLOCK] & 0x01)
|
||||||
|
ssOut |= NUMLOCK_ON;
|
||||||
|
|
||||||
|
if (KeyState[VK_SCROLL] & 0x01)
|
||||||
|
ssOut |= SCROLLLOCK_ON;
|
||||||
|
|
||||||
|
if (KeyState[VK_SHIFT] & 0x80)
|
||||||
|
ssOut |= SHIFT_PRESSED;
|
||||||
|
|
||||||
|
if (KeyState[VK_LCONTROL] & 0x80)
|
||||||
|
ssOut |= LEFT_CTRL_PRESSED;
|
||||||
|
if (KeyState[VK_RCONTROL] & 0x80)
|
||||||
|
ssOut |= RIGHT_CTRL_PRESSED;
|
||||||
|
|
||||||
|
if (KeyState[VK_LMENU] & 0x80)
|
||||||
|
ssOut |= LEFT_ALT_PRESSED;
|
||||||
|
if (KeyState[VK_RMENU] & 0x80)
|
||||||
|
ssOut |= RIGHT_ALT_PRESSED;
|
||||||
|
|
||||||
|
/* See WM_CHAR MSDN documentation for instance */
|
||||||
|
if (lParam & 0x01000000)
|
||||||
|
ssOut |= ENHANCED_KEY;
|
||||||
|
|
||||||
|
return ssOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID WINAPI
|
||||||
|
ConioProcessKey(PCONSOLE Console, MSG* msg)
|
||||||
|
{
|
||||||
|
static BYTE KeyState[256] = { 0 };
|
||||||
|
/* MSDN mentions that you should use the last virtual key code received
|
||||||
|
* when putting a virtual key identity to a WM_CHAR message since multiple
|
||||||
|
* or translated keys may be involved. */
|
||||||
|
static UINT LastVirtualKey = 0;
|
||||||
|
DWORD ShiftState;
|
||||||
|
WCHAR UnicodeChar;
|
||||||
|
UINT VirtualKeyCode;
|
||||||
|
UINT VirtualScanCode;
|
||||||
|
BOOL Down = FALSE;
|
||||||
|
BOOLEAN Fake; // synthesized, not a real event
|
||||||
|
BOOLEAN NotChar; // message should not be used to return a character
|
||||||
|
|
||||||
|
if (NULL == Console)
|
||||||
|
{
|
||||||
|
DPRINT1("No Active Console!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
|
||||||
|
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
|
||||||
|
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
|
||||||
|
|
||||||
|
GetKeyboardState(KeyState);
|
||||||
|
ShiftState = ConioGetShiftState(KeyState, msg->lParam);
|
||||||
|
|
||||||
|
if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
|
||||||
|
{
|
||||||
|
VirtualKeyCode = LastVirtualKey;
|
||||||
|
UnicodeChar = msg->wParam;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WCHAR Chars[2];
|
||||||
|
INT RetChars = 0;
|
||||||
|
|
||||||
|
VirtualKeyCode = msg->wParam;
|
||||||
|
RetChars = ToUnicodeEx(VirtualKeyCode,
|
||||||
|
VirtualScanCode,
|
||||||
|
KeyState,
|
||||||
|
Chars,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConioProcessKeyCallback(Console,
|
||||||
|
msg,
|
||||||
|
KeyState[VK_MENU],
|
||||||
|
ShiftState,
|
||||||
|
VirtualKeyCode,
|
||||||
|
Down))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fake = UnicodeChar &&
|
||||||
|
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
|
||||||
|
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
|
||||||
|
NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
|
||||||
|
if (NotChar) LastVirtualKey = msg->wParam;
|
||||||
|
|
||||||
|
DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
|
||||||
|
Down ? "down" : "up ",
|
||||||
|
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
|
||||||
|
"char" : "key ",
|
||||||
|
Fake ? "fake" : "real",
|
||||||
|
NotChar ? "notc" : "char",
|
||||||
|
VirtualScanCode,
|
||||||
|
VirtualKeyCode,
|
||||||
|
(UnicodeChar >= L' ') ? UnicodeChar : L'.',
|
||||||
|
ShiftState);
|
||||||
|
|
||||||
|
if (Fake) return;
|
||||||
|
|
||||||
|
/* Send the key press to the console driver */
|
||||||
|
ConDrvProcessKey(Console,
|
||||||
|
Down,
|
||||||
|
VirtualKeyCode,
|
||||||
|
VirtualScanCode,
|
||||||
|
UnicodeChar,
|
||||||
|
ShiftState,
|
||||||
|
KeyState[VK_CONTROL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -9,6 +9,8 @@
|
||||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef TUITERM_COMPILE
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "include/conio.h"
|
#include "include/conio.h"
|
||||||
#include "include/console.h"
|
#include "include/console.h"
|
||||||
|
@ -274,7 +276,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
{
|
{
|
||||||
if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||||
{
|
{
|
||||||
MSG Message;
|
MSG Message;
|
||||||
Message.hwnd = hWnd;
|
Message.hwnd = hWnd;
|
||||||
|
@ -290,7 +292,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||||
{
|
{
|
||||||
if (LOWORD(wParam) != WA_INACTIVE)
|
if (LOWORD(wParam) != WA_INACTIVE)
|
||||||
{
|
{
|
||||||
|
@ -440,9 +442,90 @@ Quit:
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiCleanupConsole(PCONSOLE Console)
|
TuiDeinitFrontEnd(IN OUT PFRONTEND This /*,
|
||||||
|
IN PCONSOLE Console */);
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
TuiInitFrontEnd(IN OUT PFRONTEND This,
|
||||||
|
IN PCONSOLE Console)
|
||||||
{
|
{
|
||||||
PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data;
|
PTUI_CONSOLE_DATA TuiData;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
|
||||||
|
if (This == NULL || Console == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
|
||||||
|
// return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// /* Initialize the console */
|
||||||
|
// Console->TermIFace.Vtbl = &TuiVtbl;
|
||||||
|
|
||||||
|
TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA));
|
||||||
|
if (!TuiData)
|
||||||
|
{
|
||||||
|
DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
// Console->TermIFace.Data = (PVOID)TuiData;
|
||||||
|
TuiData->Console = Console;
|
||||||
|
TuiData->hWindow = NULL;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&TuiData->Lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HACK: Resize the console since we don't support for now changing
|
||||||
|
* the console size when we display it with the hardware.
|
||||||
|
*/
|
||||||
|
// Console->ConsoleSize = PhysicalConsoleSize;
|
||||||
|
// ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);
|
||||||
|
|
||||||
|
// /* The console cannot be resized anymore */
|
||||||
|
// Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
|
||||||
|
// // ConioResizeTerminal(Console);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contrary to what we do in the GUI front-end, here we create
|
||||||
|
* an input thread for each console. It will dispatch all the
|
||||||
|
* input messages to the proper console (on the GUI it is done
|
||||||
|
* via the default GUI dispatch thread).
|
||||||
|
*/
|
||||||
|
ThreadHandle = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
TuiConsoleThread,
|
||||||
|
(PVOID)TuiData,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
if (NULL == ThreadHandle)
|
||||||
|
{
|
||||||
|
DPRINT1("CONSRV: Unable to create console thread\n");
|
||||||
|
// TuiDeinitFrontEnd(Console);
|
||||||
|
TuiDeinitFrontEnd(This);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
CloseHandle(ThreadHandle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert the newly created console in the list of virtual consoles
|
||||||
|
* and activate it (give it the focus).
|
||||||
|
*/
|
||||||
|
EnterCriticalSection(&ActiveVirtConsLock);
|
||||||
|
InsertTailList(&VirtConsList, &TuiData->Entry);
|
||||||
|
ActiveConsole = TuiData;
|
||||||
|
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||||
|
|
||||||
|
/* Finally, initialize the frontend structure */
|
||||||
|
This->Data = TuiData;
|
||||||
|
This->OldData = NULL;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WINAPI
|
||||||
|
TuiDeinitFrontEnd(IN OUT PFRONTEND This)
|
||||||
|
{
|
||||||
|
// PCONSOLE Console = This->Console;
|
||||||
|
PTUI_CONSOLE_DATA TuiData = This->Data; // Console->TermIFace.Data;
|
||||||
|
|
||||||
/* Close the notification window */
|
/* Close the notification window */
|
||||||
DestroyWindow(TuiData->hWindow);
|
DestroyWindow(TuiData->hWindow);
|
||||||
|
@ -473,13 +556,15 @@ TuiCleanupConsole(PCONSOLE Console)
|
||||||
/* Switch to the next console */
|
/* Switch to the next console */
|
||||||
if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console);
|
if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console);
|
||||||
|
|
||||||
Console->TermIFace.Data = NULL;
|
// Console->TermIFace.Data = NULL;
|
||||||
|
This->Data = NULL;
|
||||||
DeleteCriticalSection(&TuiData->Lock);
|
DeleteCriticalSection(&TuiData->Lock);
|
||||||
ConsoleFreeHeap(TuiData);
|
ConsoleFreeHeap(TuiData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
TuiDrawRegion(IN OUT PFRONTEND This,
|
||||||
|
SMALL_RECT* Region)
|
||||||
{
|
{
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||||
|
@ -517,8 +602,13 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
|
TuiWriteStream(IN OUT PFRONTEND This,
|
||||||
UINT ScrolledLines, PWCHAR Buffer, UINT Length)
|
SMALL_RECT* Region,
|
||||||
|
SHORT CursorStartX,
|
||||||
|
SHORT CursorStartY,
|
||||||
|
UINT ScrolledLines,
|
||||||
|
PWCHAR Buffer,
|
||||||
|
UINT Length)
|
||||||
{
|
{
|
||||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||||
PCHAR NewBuffer;
|
PCHAR NewBuffer;
|
||||||
|
@ -546,7 +636,8 @@ TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
TuiSetCursorInfo(IN OUT PFRONTEND This,
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff)
|
||||||
{
|
{
|
||||||
CONSOLE_CURSOR_INFO Info;
|
CONSOLE_CURSOR_INFO Info;
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
|
@ -567,7 +658,10 @@ TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX, SHORT OldCursorY)
|
TuiSetScreenInfo(IN OUT PFRONTEND This,
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff,
|
||||||
|
SHORT OldCursorX,
|
||||||
|
SHORT OldCursorY)
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFO Info;
|
CONSOLE_SCREEN_BUFFER_INFO Info;
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
|
@ -590,12 +684,17 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiResizeTerminal(PCONSOLE Console)
|
TuiResizeTerminal(IN OUT PFRONTEND This)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down)
|
TuiProcessKeyCallback(IN OUT PFRONTEND This,
|
||||||
|
MSG* msg,
|
||||||
|
BYTE KeyStateMenu,
|
||||||
|
DWORD ShiftState,
|
||||||
|
UINT VirtualKeyCode,
|
||||||
|
BOOL Down)
|
||||||
{
|
{
|
||||||
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
|
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
|
||||||
VK_TAB == VirtualKeyCode)
|
VK_TAB == VirtualKeyCode)
|
||||||
|
@ -616,43 +715,46 @@ TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD Shift
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiRefreshInternalInfo(PCONSOLE Console)
|
TuiRefreshInternalInfo(IN OUT PFRONTEND This)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiChangeTitle(PCONSOLE Console)
|
TuiChangeTitle(IN OUT PFRONTEND This)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
|
TuiChangeIcon(IN OUT PFRONTEND This,
|
||||||
|
HICON hWindowIcon)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND WINAPI
|
static HWND WINAPI
|
||||||
TuiGetConsoleWindowHandle(PCONSOLE Console)
|
TuiGetConsoleWindowHandle(IN OUT PFRONTEND This)
|
||||||
{
|
{
|
||||||
PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data;
|
PTUI_CONSOLE_DATA TuiData = This->Data;
|
||||||
return TuiData->hWindow;
|
return TuiData->hWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize)
|
TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
|
||||||
|
PCOORD pSize)
|
||||||
{
|
{
|
||||||
if (!pSize) return;
|
if (!pSize) return;
|
||||||
*pSize = PhysicalConsoleSize;
|
*pSize = PhysicalConsoleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI
|
static ULONG WINAPI
|
||||||
TuiGetDisplayMode(PCONSOLE Console)
|
TuiGetDisplayMode(IN OUT PFRONTEND This)
|
||||||
{
|
{
|
||||||
return CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN;
|
return CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
|
TuiSetDisplayMode(IN OUT PFRONTEND This,
|
||||||
|
ULONG NewMode)
|
||||||
{
|
{
|
||||||
// if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
|
// if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
|
||||||
// return FALSE;
|
// return FALSE;
|
||||||
|
@ -660,32 +762,38 @@ TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT WINAPI
|
static INT WINAPI
|
||||||
TuiShowMouseCursor(PCONSOLE Console, BOOL Show)
|
TuiShowMouseCursor(IN OUT PFRONTEND This,
|
||||||
|
BOOL Show)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor)
|
TuiSetMouseCursor(IN OUT PFRONTEND This,
|
||||||
|
HCURSOR hCursor)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HMENU WINAPI
|
static HMENU WINAPI
|
||||||
TuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh)
|
TuiMenuControl(IN OUT PFRONTEND This,
|
||||||
|
UINT cmdIdLow,
|
||||||
|
UINT cmdIdHigh)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetMenuClose(PCONSOLE Console, BOOL Enable)
|
TuiSetMenuClose(IN OUT PFRONTEND This,
|
||||||
|
BOOL Enable)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FRONTEND_VTBL TuiVtbl =
|
static FRONTEND_VTBL TuiVtbl =
|
||||||
{
|
{
|
||||||
TuiCleanupConsole,
|
TuiInitFrontEnd,
|
||||||
|
TuiDeinitFrontEnd,
|
||||||
TuiDrawRegion,
|
TuiDrawRegion,
|
||||||
TuiWriteStream,
|
TuiWriteStream,
|
||||||
TuiSetCursorInfo,
|
TuiSetCursorInfo,
|
||||||
|
@ -705,80 +813,49 @@ static FRONTEND_VTBL TuiVtbl =
|
||||||
TuiSetMenuClose,
|
TuiSetMenuClose,
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
// static BOOL
|
||||||
TuiInitConsole(PCONSOLE Console,
|
// DtbgIsDesktopVisible(VOID)
|
||||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
// {
|
||||||
PCONSOLE_INFO ConsoleInfo,
|
// return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
|
||||||
DWORD ProcessId)
|
// }
|
||||||
|
static BOOLEAN
|
||||||
|
IsConsoleMode(VOID)
|
||||||
{
|
{
|
||||||
PTUI_CONSOLE_DATA TuiData;
|
return (BOOLEAN)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE);
|
||||||
HANDLE ThreadHandle;
|
}
|
||||||
|
|
||||||
if (Console == NULL || ConsoleInfo == NULL)
|
NTSTATUS NTAPI
|
||||||
|
TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
||||||
|
IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||||
|
IN OUT PVOID ExtraConsoleInfo,
|
||||||
|
IN ULONG ProcessId)
|
||||||
|
{
|
||||||
|
if (FrontEnd == NULL || ConsoleInfo == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
|
/* We must be in console mode already */
|
||||||
return STATUS_INVALID_PARAMETER;
|
if (!IsConsoleMode()) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* Initialize the TUI terminal emulator */
|
/* Initialize the TUI terminal emulator */
|
||||||
if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL;
|
if (!TuiInit(ConsoleInfo->CodePage)) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* Initialize the console */
|
/* Finally, initialize the frontend structure */
|
||||||
Console->TermIFace.Vtbl = &TuiVtbl;
|
FrontEnd->Vtbl = &TuiVtbl;
|
||||||
|
FrontEnd->Data = NULL;
|
||||||
TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA));
|
FrontEnd->OldData = NULL;
|
||||||
if (!TuiData)
|
|
||||||
{
|
|
||||||
DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
Console->TermIFace.Data = (PVOID)TuiData;
|
|
||||||
TuiData->Console = Console;
|
|
||||||
TuiData->hWindow = NULL;
|
|
||||||
|
|
||||||
InitializeCriticalSection(&TuiData->Lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HACK: Resize the console since we don't support for now changing
|
|
||||||
* the console size when we display it with the hardware.
|
|
||||||
*/
|
|
||||||
Console->ConsoleSize = PhysicalConsoleSize;
|
|
||||||
ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);
|
|
||||||
|
|
||||||
/* The console cannot be resized anymore */
|
|
||||||
Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
|
|
||||||
// ConioResizeTerminal(Console);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Contrary to what we do in the GUI front-end, here we create
|
|
||||||
* an input thread for each console. It will dispatch all the
|
|
||||||
* input messages to the proper console (on the GUI it is done
|
|
||||||
* via the default GUI dispatch thread).
|
|
||||||
*/
|
|
||||||
ThreadHandle = CreateThread(NULL,
|
|
||||||
0,
|
|
||||||
TuiConsoleThread,
|
|
||||||
(PVOID)TuiData,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
if (NULL == ThreadHandle)
|
|
||||||
{
|
|
||||||
DPRINT1("CONSRV: Unable to create console thread\n");
|
|
||||||
TuiCleanupConsole(Console);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
CloseHandle(ThreadHandle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert the newly created console in the list of virtual consoles
|
|
||||||
* and activate it (give it the focus).
|
|
||||||
*/
|
|
||||||
EnterCriticalSection(&ActiveVirtConsLock);
|
|
||||||
InsertTailList(&VirtConsList, &TuiData->Entry);
|
|
||||||
ActiveConsole = TuiData;
|
|
||||||
LeaveCriticalSection(&ActiveVirtConsLock);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI
|
||||||
|
TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd)
|
||||||
|
{
|
||||||
|
if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (FrontEnd->Data) TuiDeinitFrontEnd(FrontEnd);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -443,7 +443,7 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
if (ConSrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
|
if (ConDrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
|
||||||
{
|
{
|
||||||
_InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
|
_InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
|
||||||
|
|
||||||
|
@ -492,7 +492,9 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
ConSrvFreeHandlesTable(ProcessData);
|
ConSrvFreeHandlesTable(ProcessData);
|
||||||
|
|
||||||
/* Initialize a new Console owned by this process */
|
/* Initialize a new Console owned by this process */
|
||||||
Status = ConSrvInitConsole(&ProcessData->Console, ConsoleStartInfo, ProcessData->Process);
|
Status = ConSrvInitConsole(&ProcessData->Console,
|
||||||
|
ConsoleStartInfo,
|
||||||
|
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console initialization failed\n");
|
DPRINT1("Console initialization failed\n");
|
||||||
|
@ -551,7 +553,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
/* Validate and lock the console */
|
/* Validate and lock the console */
|
||||||
if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
if (!ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||||
{
|
{
|
||||||
// FIXME: Find another status code
|
// FIXME: Find another status code
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
@ -629,7 +631,7 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
/* Validate and lock the console */
|
/* Validate and lock the console */
|
||||||
if (ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
if (ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||||
{
|
{
|
||||||
DPRINT("ConSrvRemoveConsole - Locking OK\n");
|
DPRINT("ConSrvRemoveConsole - Locking OK\n");
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ struct _CONSOLE_SCREEN_BUFFER
|
||||||
COORD OldScreenBufferSize; /* Old size of this screen buffer */
|
COORD OldScreenBufferSize; /* Old size of this screen buffer */
|
||||||
COORD OldViewSize; /* Old associated view size */
|
COORD OldViewSize; /* Old associated view size */
|
||||||
|
|
||||||
COORD ViewOrigin; /* Beginning offset for the actual display area */
|
COORD ViewOrigin; /* Beginning offset for the actual display area */
|
||||||
|
|
||||||
/***** Put that VV in TEXTMODE_SCREEN_BUFFER ?? *****/
|
/***** Put that VV in TEXTMODE_SCREEN_BUFFER ?? *****/
|
||||||
USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
|
USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
|
||||||
|
@ -173,79 +173,85 @@ typedef struct _CONSOLE_INPUT_BUFFER
|
||||||
USHORT Mode; /* Input buffer modes */
|
USHORT Mode; /* Input buffer modes */
|
||||||
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
|
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
|
||||||
|
/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO;
|
||||||
typedef struct _FRONTEND_VTBL
|
typedef struct _FRONTEND_VTBL
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Internal interface (functions called by the console server only)
|
* Internal interface (functions called by the console server only)
|
||||||
*/
|
*/
|
||||||
// BOOL (WINAPI *Init)();
|
NTSTATUS (WINAPI *InitFrontEnd)(IN OUT PFRONTEND This,
|
||||||
VOID (WINAPI *CleanupConsole)(struct _CONSOLE* Console);
|
IN struct _CONSOLE* Console);
|
||||||
|
VOID (WINAPI *DeinitFrontEnd)(IN OUT PFRONTEND This);
|
||||||
|
|
||||||
/* Interface used for both text-mode and graphics screen buffers */
|
/* Interface used for both text-mode and graphics screen buffers */
|
||||||
VOID (WINAPI *DrawRegion)(struct _CONSOLE* Console,
|
VOID (WINAPI *DrawRegion)(IN OUT PFRONTEND This,
|
||||||
SMALL_RECT* Region);
|
SMALL_RECT* Region);
|
||||||
/* Interface used only for text-mode screen buffers */
|
/* Interface used only for text-mode screen buffers */
|
||||||
VOID (WINAPI *WriteStream)(struct _CONSOLE* Console,
|
VOID (WINAPI *WriteStream)(IN OUT PFRONTEND This,
|
||||||
SMALL_RECT* Block,
|
SMALL_RECT* Block,
|
||||||
SHORT CursorStartX,
|
SHORT CursorStartX,
|
||||||
SHORT CursorStartY,
|
SHORT CursorStartY,
|
||||||
UINT ScrolledLines,
|
UINT ScrolledLines,
|
||||||
PWCHAR Buffer,
|
PWCHAR Buffer,
|
||||||
UINT Length);
|
UINT Length);
|
||||||
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetCursorInfo)(IN OUT PFRONTEND This,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||||
BOOL (WINAPI *SetScreenInfo)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetScreenInfo)(IN OUT PFRONTEND This,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||||
SHORT OldCursorX,
|
SHORT OldCursorX,
|
||||||
SHORT OldCursorY);
|
SHORT OldCursorY);
|
||||||
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
|
VOID (WINAPI *ResizeTerminal)(IN OUT PFRONTEND This);
|
||||||
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
|
BOOL (WINAPI *ProcessKeyCallback)(IN OUT PFRONTEND This,
|
||||||
MSG* msg,
|
MSG* msg,
|
||||||
BYTE KeyStateMenu,
|
BYTE KeyStateMenu,
|
||||||
DWORD ShiftState,
|
DWORD ShiftState,
|
||||||
UINT VirtualKeyCode,
|
UINT VirtualKeyCode,
|
||||||
BOOL Down);
|
BOOL Down);
|
||||||
VOID (WINAPI *RefreshInternalInfo)(struct _CONSOLE* Console);
|
VOID (WINAPI *RefreshInternalInfo)(IN OUT PFRONTEND This);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External interface (functions corresponding to the Console API)
|
* External interface (functions corresponding to the Console API)
|
||||||
*/
|
*/
|
||||||
VOID (WINAPI *ChangeTitle)(struct _CONSOLE* Console);
|
VOID (WINAPI *ChangeTitle)(IN OUT PFRONTEND This);
|
||||||
BOOL (WINAPI *ChangeIcon)(struct _CONSOLE* Console,
|
BOOL (WINAPI *ChangeIcon)(IN OUT PFRONTEND This,
|
||||||
HICON hWindowIcon);
|
HICON hWindowIcon);
|
||||||
HWND (WINAPI *GetConsoleWindowHandle)(struct _CONSOLE* Console);
|
HWND (WINAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This);
|
||||||
VOID (WINAPI *GetLargestConsoleWindowSize)(struct _CONSOLE* Console,
|
VOID (WINAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This,
|
||||||
PCOORD pSize);
|
PCOORD pSize);
|
||||||
ULONG (WINAPI *GetDisplayMode)(struct _CONSOLE* Console);
|
ULONG (WINAPI *GetDisplayMode)(IN OUT PFRONTEND This);
|
||||||
BOOL (WINAPI *SetDisplayMode)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetDisplayMode)(IN OUT PFRONTEND This,
|
||||||
ULONG NewMode);
|
ULONG NewMode);
|
||||||
INT (WINAPI *ShowMouseCursor)(struct _CONSOLE* Console,
|
INT (WINAPI *ShowMouseCursor)(IN OUT PFRONTEND This,
|
||||||
BOOL Show);
|
BOOL Show);
|
||||||
BOOL (WINAPI *SetMouseCursor)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetMouseCursor)(IN OUT PFRONTEND This,
|
||||||
HCURSOR hCursor);
|
HCURSOR hCursor);
|
||||||
HMENU (WINAPI *MenuControl)(struct _CONSOLE* Console,
|
HMENU (WINAPI *MenuControl)(IN OUT PFRONTEND This,
|
||||||
UINT cmdIdLow,
|
UINT cmdIdLow,
|
||||||
UINT cmdIdHigh);
|
UINT cmdIdHigh);
|
||||||
BOOL (WINAPI *SetMenuClose)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetMenuClose)(IN OUT PFRONTEND This,
|
||||||
BOOL Enable);
|
BOOL Enable);
|
||||||
|
|
||||||
#if 0 // Possible future front-end interface
|
#if 0 // Possible future front-end interface
|
||||||
BOOL (WINAPI *GetFrontEndProperty)(struct _CONSOLE* Console,
|
BOOL (WINAPI *GetFrontEndProperty)(IN OUT PFRONTEND This,
|
||||||
ULONG Flag,
|
ULONG Flag,
|
||||||
PVOID Info,
|
PVOID Info,
|
||||||
ULONG Size);
|
ULONG Size);
|
||||||
BOOL (WINAPI *SetFrontEndProperty)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetFrontEndProperty)(IN OUT PFRONTEND This,
|
||||||
ULONG Flag,
|
ULONG Flag,
|
||||||
PVOID Info /*,
|
PVOID Info /*,
|
||||||
ULONG Size */);
|
ULONG Size */);
|
||||||
#endif
|
#endif
|
||||||
} FRONTEND_VTBL, *PFRONTEND_VTBL;
|
} FRONTEND_VTBL, *PFRONTEND_VTBL;
|
||||||
|
|
||||||
typedef struct _FRONTEND_IFACE
|
struct _FRONTEND
|
||||||
{
|
{
|
||||||
PFRONTEND_VTBL Vtbl; /* Virtual table */
|
PFRONTEND_VTBL Vtbl; /* Virtual table */
|
||||||
PVOID Data; /* Private data */
|
struct _CONSOLE* Console; /* Console to which the frontend is attached to */
|
||||||
PVOID OldData; /* Reserved */
|
PVOID Data; /* Private data */
|
||||||
} FRONTEND_IFACE, *PFRONTEND_IFACE;
|
PVOID OldData; /* Reserved */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WARNING: Change the state of the console ONLY when the console is locked !
|
* WARNING: Change the state of the console ONLY when the console is locked !
|
||||||
|
@ -267,7 +273,7 @@ typedef struct _CONSOLE
|
||||||
LIST_ENTRY Entry; /* Entry in the list of consoles */
|
LIST_ENTRY Entry; /* Entry in the list of consoles */
|
||||||
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
||||||
|
|
||||||
FRONTEND_IFACE TermIFace; /* Frontend-specific interface */
|
FRONTEND TermIFace; /* Frontend-specific interface */
|
||||||
|
|
||||||
/**************************** Input buffer and data ***************************/
|
/**************************** Input buffer and data ***************************/
|
||||||
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
|
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
|
||||||
|
@ -324,9 +330,11 @@ typedef struct _CONSOLE
|
||||||
/* console.c */
|
/* console.c */
|
||||||
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
|
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
|
||||||
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
|
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
|
||||||
ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
|
|
||||||
ULONG ProcessGroupId,
|
NTSTATUS NTAPI
|
||||||
DWORD Event);
|
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
|
||||||
|
IN ULONG ProcessGroupId,
|
||||||
|
IN ULONG Event);
|
||||||
|
|
||||||
/* coninput.c */
|
/* coninput.c */
|
||||||
VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
|
VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
|
||||||
|
|
|
@ -8,14 +8,21 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
BOOL FASTCALL ConSrvValidateConsolePointer(PCONSOLE Console);
|
BOOLEAN NTAPI
|
||||||
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
ConDrvValidateConsolePointer(IN PCONSOLE Console);
|
||||||
CONSOLE_STATE ExpectedState);
|
|
||||||
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
BOOLEAN NTAPI
|
||||||
CONSOLE_STATE ExpectedState,
|
ConDrvValidateConsoleState(IN PCONSOLE Console,
|
||||||
BOOL LockConsole);
|
IN CONSOLE_STATE ExpectedState);
|
||||||
BOOL FASTCALL ConSrvValidateConsole(PCONSOLE Console,
|
|
||||||
CONSOLE_STATE ExpectedState,
|
BOOLEAN NTAPI
|
||||||
BOOL LockConsole);
|
ConDrvValidateConsoleUnsafe(IN PCONSOLE Console,
|
||||||
|
IN CONSOLE_STATE ExpectedState,
|
||||||
|
IN BOOLEAN LockConsole);
|
||||||
|
|
||||||
|
BOOLEAN NTAPI
|
||||||
|
ConDrvValidateConsole(IN PCONSOLE Console,
|
||||||
|
IN CONSOLE_STATE ExpectedState,
|
||||||
|
IN BOOLEAN LockConsole);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -365,7 +365,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||||
|
|
||||||
/* Validate and lock the parent's console */
|
/* Validate and lock the parent's console */
|
||||||
if (ConSrvValidateConsole(SourceProcessData->Console, CONSOLE_RUNNING, TRUE))
|
if (ConDrvValidateConsole(SourceProcessData->Console, CONSOLE_RUNNING, TRUE))
|
||||||
{
|
{
|
||||||
/* Inherit the parent's handles table */
|
/* Inherit the parent's handles table */
|
||||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||||
|
@ -508,7 +508,7 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization)
|
||||||
if (!ConSrvHeap) return STATUS_NO_MEMORY;
|
if (!ConSrvHeap) return STATUS_NO_MEMORY;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ConSrvInitConsoleSupport();
|
ConDrvInitConsoleSupport();
|
||||||
|
|
||||||
/* Setup the DLL Object */
|
/* Setup the DLL Object */
|
||||||
LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER;
|
LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue