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
|
||||
coninput.c
|
||||
conoutput.c
|
||||
graphics.c
|
||||
text.c
|
||||
console.c
|
||||
frontendctl.c
|
||||
handle.c
|
||||
init.c
|
||||
lineinput.c
|
||||
settings.c
|
||||
condrv/console.c
|
||||
condrv/graphics.c
|
||||
frontends/input.c
|
||||
frontends/gui/guiterm.c
|
||||
frontends/gui/guisettings.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);
|
||||
}
|
||||
|
||||
static DWORD FASTCALL
|
||||
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
|
||||
VOID NTAPI
|
||||
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;
|
||||
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 */
|
||||
if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||
er.Event.KeyEvent.bKeyDown &&
|
||||
((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
|
||||
(er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
|
||||
(er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
|
||||
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
|
||||
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
|
||||
{
|
||||
DPRINT1("Console_Api Ctrl-C\n");
|
||||
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
||||
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
||||
|
||||
if (Console->LineBuffer && !Console->LineComplete)
|
||||
{
|
||||
|
@ -276,39 +163,46 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (0 != (er.Event.KeyEvent.dwControlKeyState
|
||||
& (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
|
||||
&& (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
|
||||
|| VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
|
||||
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
|
||||
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
|
||||
{
|
||||
if (er.Event.KeyEvent.bKeyDown)
|
||||
if (!Down) return;
|
||||
|
||||
/* scroll up or down */
|
||||
if (VK_UP == VirtualKeyCode)
|
||||
{
|
||||
/* scroll up or down */
|
||||
if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
|
||||
/* only scroll up if there is room to scroll up into */
|
||||
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
||||
{
|
||||
/* only scroll up if there is room to scroll up into */
|
||||
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
||||
{
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
||||
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
|
||||
Console->ActiveBuffer->ScreenBufferSize.Y;
|
||||
Console->ActiveBuffer->CursorPosition.Y++;
|
||||
}
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,4 +11,13 @@
|
|||
|
||||
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 */
|
||||
|
|
|
@ -10,43 +10,41 @@
|
|||
|
||||
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
||||
|
||||
#define ConioCleanupConsole(Console) \
|
||||
(Console)->TermIFace.Vtbl->CleanupConsole(Console)
|
||||
#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) \
|
||||
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
||||
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Block), (CurStartX), (CurStartY), \
|
||||
(ScrolledLines), (Buffer), (Length))
|
||||
#define ConioSetCursorInfo(Console, Buff) \
|
||||
(Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
||||
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (Buff))
|
||||
#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) \
|
||||
(Console)->TermIFace.Vtbl->ResizeTerminal(Console)
|
||||
(Console)->TermIFace.Vtbl->ResizeTerminal(&(Console)->TermIFace)
|
||||
#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) \
|
||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo(Console)
|
||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo(&(Console)->TermIFace)
|
||||
|
||||
#define ConioChangeTitle(Console) \
|
||||
(Console)->TermIFace.Vtbl->ChangeTitle(Console)
|
||||
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
|
||||
#define ConioChangeIcon(Console, hWindowIcon) \
|
||||
(Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
|
||||
(Console)->TermIFace.Vtbl->ChangeIcon(&(Console)->TermIFace, (hWindowIcon))
|
||||
#define ConioGetConsoleWindowHandle(Console) \
|
||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
|
||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(&(Console)->TermIFace)
|
||||
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||
#define ConioGetDisplayMode(Console) \
|
||||
(Console)->TermIFace.Vtbl->GetDisplayMode(Console)
|
||||
(Console)->TermIFace.Vtbl->GetDisplayMode(&(Console)->TermIFace)
|
||||
#define ConioSetDisplayMode(Console, NewMode) \
|
||||
(Console)->TermIFace.Vtbl->SetDisplayMode((Console), (NewMode))
|
||||
(Console)->TermIFace.Vtbl->SetDisplayMode(&(Console)->TermIFace, (NewMode))
|
||||
#define ConioShowMouseCursor(Console, Show) \
|
||||
(Console)->TermIFace.Vtbl->ShowMouseCursor((Console), (Show))
|
||||
(Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show))
|
||||
#define ConioSetMouseCursor(Console, hCursor) \
|
||||
(Console)->TermIFace.Vtbl->SetMouseCursor((Console), (hCursor))
|
||||
(Console)->TermIFace.Vtbl->SetMouseCursor(&(Console)->TermIFace, (hCursor))
|
||||
#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \
|
||||
(Console)->TermIFace.Vtbl->MenuControl((Console), (CmdIdLow), (CmdIdHigh))
|
||||
(Console)->TermIFace.Vtbl->MenuControl(&(Console)->TermIFace, (CmdIdLow), (CmdIdHigh))
|
||||
#define ConioSetMenuClose(Console, Enable) \
|
||||
(Console)->TermIFace.Vtbl->SetMenuClose((Console), (Enable))
|
||||
(Console)->TermIFace.Vtbl->SetMenuClose(&(Console)->TermIFace, (Enable))
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -150,6 +150,11 @@ ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
|||
// ConioDrawConsole(Console);
|
||||
}
|
||||
|
||||
PCONSOLE_SCREEN_BUFFER
|
||||
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console)
|
||||
{
|
||||
return (Console ? Console->ActiveBuffer : NULL);
|
||||
}
|
||||
|
||||
/* PUBLIC SERVER APIS *********************************************************/
|
||||
|
||||
|
|
|
@ -40,4 +40,7 @@ NTSTATUS FASTCALL ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|||
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
|
||||
PCONSOLE_SCREEN_BUFFER
|
||||
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console);
|
||||
|
||||
/* EOF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,16 +8,44 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
VOID WINAPI ConSrvInitConsoleSupport(VOID);
|
||||
VOID NTAPI
|
||||
ConDrvInitConsoleSupport(VOID);
|
||||
|
||||
NTSTATUS WINAPI ConSrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN PCSR_PROCESS ConsoleLeaderProcess);
|
||||
NTSTATUS WINAPI
|
||||
ConSrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN ULONG ConsoleLeaderProcessId);
|
||||
VOID WINAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console);
|
||||
|
||||
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
struct _CONSOLE** /* PCONSOLE* */ Console,
|
||||
BOOL LockConsole);
|
||||
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* /* PCONSOLE */ Console,
|
||||
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 */
|
||||
|
|
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)
|
||||
*/
|
||||
|
||||
#ifdef TUITERM_COMPILE
|
||||
|
||||
#include "consrv.h"
|
||||
#include "include/conio.h"
|
||||
#include "include/console.h"
|
||||
|
@ -274,7 +276,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||
if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||
{
|
||||
MSG Message;
|
||||
Message.hwnd = hWnd;
|
||||
|
@ -290,7 +292,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||
if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
|
||||
{
|
||||
if (LOWORD(wParam) != WA_INACTIVE)
|
||||
{
|
||||
|
@ -440,9 +442,90 @@ Quit:
|
|||
******************************************************************************/
|
||||
|
||||
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 */
|
||||
DestroyWindow(TuiData->hWindow);
|
||||
|
@ -473,13 +556,15 @@ TuiCleanupConsole(PCONSOLE Console)
|
|||
/* Switch to the next console */
|
||||
if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console);
|
||||
|
||||
Console->TermIFace.Data = NULL;
|
||||
// Console->TermIFace.Data = NULL;
|
||||
This->Data = NULL;
|
||||
DeleteCriticalSection(&TuiData->Lock);
|
||||
ConsoleFreeHeap(TuiData);
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||
TuiDrawRegion(IN OUT PFRONTEND This,
|
||||
SMALL_RECT* Region)
|
||||
{
|
||||
DWORD BytesReturned;
|
||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||
|
@ -517,8 +602,13 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
|||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
|
||||
UINT ScrolledLines, PWCHAR Buffer, UINT Length)
|
||||
TuiWriteStream(IN OUT PFRONTEND This,
|
||||
SMALL_RECT* Region,
|
||||
SHORT CursorStartX,
|
||||
SHORT CursorStartY,
|
||||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length)
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||
PCHAR NewBuffer;
|
||||
|
@ -546,7 +636,8 @@ TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C
|
|||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||
TuiSetCursorInfo(IN OUT PFRONTEND This,
|
||||
PCONSOLE_SCREEN_BUFFER Buff)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO Info;
|
||||
DWORD BytesReturned;
|
||||
|
@ -567,7 +658,10 @@ TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
|||
}
|
||||
|
||||
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;
|
||||
DWORD BytesReturned;
|
||||
|
@ -590,12 +684,17 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX
|
|||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiResizeTerminal(PCONSOLE Console)
|
||||
TuiResizeTerminal(IN OUT PFRONTEND This)
|
||||
{
|
||||
}
|
||||
|
||||
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)) &&
|
||||
VK_TAB == VirtualKeyCode)
|
||||
|
@ -616,43 +715,46 @@ TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD Shift
|
|||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiRefreshInternalInfo(PCONSOLE Console)
|
||||
TuiRefreshInternalInfo(IN OUT PFRONTEND This)
|
||||
{
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiChangeTitle(PCONSOLE Console)
|
||||
TuiChangeTitle(IN OUT PFRONTEND This)
|
||||
{
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
|
||||
TuiChangeIcon(IN OUT PFRONTEND This,
|
||||
HICON hWindowIcon)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize)
|
||||
TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
|
||||
PCOORD pSize)
|
||||
{
|
||||
if (!pSize) return;
|
||||
*pSize = PhysicalConsoleSize;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
TuiGetDisplayMode(PCONSOLE Console)
|
||||
TuiGetDisplayMode(IN OUT PFRONTEND This)
|
||||
{
|
||||
return CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
|
||||
TuiSetDisplayMode(IN OUT PFRONTEND This,
|
||||
ULONG NewMode)
|
||||
{
|
||||
// if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
|
||||
// return FALSE;
|
||||
|
@ -660,32 +762,38 @@ TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
|
|||
}
|
||||
|
||||
static INT WINAPI
|
||||
TuiShowMouseCursor(PCONSOLE Console, BOOL Show)
|
||||
TuiShowMouseCursor(IN OUT PFRONTEND This,
|
||||
BOOL Show)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor)
|
||||
TuiSetMouseCursor(IN OUT PFRONTEND This,
|
||||
HCURSOR hCursor)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HMENU WINAPI
|
||||
TuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh)
|
||||
TuiMenuControl(IN OUT PFRONTEND This,
|
||||
UINT cmdIdLow,
|
||||
UINT cmdIdHigh)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiSetMenuClose(PCONSOLE Console, BOOL Enable)
|
||||
TuiSetMenuClose(IN OUT PFRONTEND This,
|
||||
BOOL Enable)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static FRONTEND_VTBL TuiVtbl =
|
||||
{
|
||||
TuiCleanupConsole,
|
||||
TuiInitFrontEnd,
|
||||
TuiDeinitFrontEnd,
|
||||
TuiDrawRegion,
|
||||
TuiWriteStream,
|
||||
TuiSetCursorInfo,
|
||||
|
@ -705,80 +813,49 @@ static FRONTEND_VTBL TuiVtbl =
|
|||
TuiSetMenuClose,
|
||||
};
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
TuiInitConsole(PCONSOLE Console,
|
||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
PCONSOLE_INFO ConsoleInfo,
|
||||
DWORD ProcessId)
|
||||
// static BOOL
|
||||
// DtbgIsDesktopVisible(VOID)
|
||||
// {
|
||||
// return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
|
||||
// }
|
||||
static BOOLEAN
|
||||
IsConsoleMode(VOID)
|
||||
{
|
||||
PTUI_CONSOLE_DATA TuiData;
|
||||
HANDLE ThreadHandle;
|
||||
return (BOOLEAN)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
/* We must be in console mode already */
|
||||
if (!IsConsoleMode()) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Initialize the TUI terminal emulator */
|
||||
if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL;
|
||||
if (!TuiInit(ConsoleInfo->CodePage)) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* 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");
|
||||
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);
|
||||
/* Finally, initialize the frontend structure */
|
||||
FrontEnd->Vtbl = &TuiVtbl;
|
||||
FrontEnd->Data = NULL;
|
||||
FrontEnd->OldData = NULL;
|
||||
|
||||
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 */
|
||||
|
|
|
@ -443,7 +443,7 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
if (ConSrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
|
||||
if (ConDrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
|
||||
{
|
||||
_InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
|
||||
|
||||
|
@ -492,7 +492,9 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
ConSrvFreeHandlesTable(ProcessData);
|
||||
|
||||
/* 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))
|
||||
{
|
||||
DPRINT1("Console initialization failed\n");
|
||||
|
@ -551,7 +553,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Validate and lock the console */
|
||||
if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||
if (!ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||
{
|
||||
// FIXME: Find another status code
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
@ -629,7 +631,7 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
|||
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* Validate and lock the console */
|
||||
if (ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||
if (ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||
{
|
||||
DPRINT("ConSrvRemoveConsole - Locking OK\n");
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ struct _CONSOLE_SCREEN_BUFFER
|
|||
COORD OldScreenBufferSize; /* Old size of this screen buffer */
|
||||
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 ?? *****/
|
||||
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 */
|
||||
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
|
||||
|
||||
|
||||
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
|
||||
/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO;
|
||||
typedef struct _FRONTEND_VTBL
|
||||
{
|
||||
/*
|
||||
* Internal interface (functions called by the console server only)
|
||||
*/
|
||||
// BOOL (WINAPI *Init)();
|
||||
VOID (WINAPI *CleanupConsole)(struct _CONSOLE* Console);
|
||||
NTSTATUS (WINAPI *InitFrontEnd)(IN OUT PFRONTEND This,
|
||||
IN struct _CONSOLE* Console);
|
||||
VOID (WINAPI *DeinitFrontEnd)(IN OUT PFRONTEND This);
|
||||
|
||||
/* 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);
|
||||
/* Interface used only for text-mode screen buffers */
|
||||
VOID (WINAPI *WriteStream)(struct _CONSOLE* Console,
|
||||
VOID (WINAPI *WriteStream)(IN OUT PFRONTEND This,
|
||||
SMALL_RECT* Block,
|
||||
SHORT CursorStartX,
|
||||
SHORT CursorStartY,
|
||||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length);
|
||||
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *SetCursorInfo)(IN OUT PFRONTEND This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||
BOOL (WINAPI *SetScreenInfo)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *SetScreenInfo)(IN OUT PFRONTEND This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||
SHORT OldCursorX,
|
||||
SHORT OldCursorY);
|
||||
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
|
||||
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
|
||||
VOID (WINAPI *ResizeTerminal)(IN OUT PFRONTEND This);
|
||||
BOOL (WINAPI *ProcessKeyCallback)(IN OUT PFRONTEND This,
|
||||
MSG* msg,
|
||||
BYTE KeyStateMenu,
|
||||
DWORD ShiftState,
|
||||
UINT VirtualKeyCode,
|
||||
BOOL Down);
|
||||
VOID (WINAPI *RefreshInternalInfo)(struct _CONSOLE* Console);
|
||||
VOID (WINAPI *RefreshInternalInfo)(IN OUT PFRONTEND This);
|
||||
|
||||
/*
|
||||
* External interface (functions corresponding to the Console API)
|
||||
*/
|
||||
VOID (WINAPI *ChangeTitle)(struct _CONSOLE* Console);
|
||||
BOOL (WINAPI *ChangeIcon)(struct _CONSOLE* Console,
|
||||
VOID (WINAPI *ChangeTitle)(IN OUT PFRONTEND This);
|
||||
BOOL (WINAPI *ChangeIcon)(IN OUT PFRONTEND This,
|
||||
HICON hWindowIcon);
|
||||
HWND (WINAPI *GetConsoleWindowHandle)(struct _CONSOLE* Console);
|
||||
VOID (WINAPI *GetLargestConsoleWindowSize)(struct _CONSOLE* Console,
|
||||
HWND (WINAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This);
|
||||
VOID (WINAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This,
|
||||
PCOORD pSize);
|
||||
ULONG (WINAPI *GetDisplayMode)(struct _CONSOLE* Console);
|
||||
BOOL (WINAPI *SetDisplayMode)(struct _CONSOLE* Console,
|
||||
ULONG (WINAPI *GetDisplayMode)(IN OUT PFRONTEND This);
|
||||
BOOL (WINAPI *SetDisplayMode)(IN OUT PFRONTEND This,
|
||||
ULONG NewMode);
|
||||
INT (WINAPI *ShowMouseCursor)(struct _CONSOLE* Console,
|
||||
INT (WINAPI *ShowMouseCursor)(IN OUT PFRONTEND This,
|
||||
BOOL Show);
|
||||
BOOL (WINAPI *SetMouseCursor)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *SetMouseCursor)(IN OUT PFRONTEND This,
|
||||
HCURSOR hCursor);
|
||||
HMENU (WINAPI *MenuControl)(struct _CONSOLE* Console,
|
||||
HMENU (WINAPI *MenuControl)(IN OUT PFRONTEND This,
|
||||
UINT cmdIdLow,
|
||||
UINT cmdIdHigh);
|
||||
BOOL (WINAPI *SetMenuClose)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *SetMenuClose)(IN OUT PFRONTEND This,
|
||||
BOOL Enable);
|
||||
|
||||
#if 0 // Possible future front-end interface
|
||||
BOOL (WINAPI *GetFrontEndProperty)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *GetFrontEndProperty)(IN OUT PFRONTEND This,
|
||||
ULONG Flag,
|
||||
PVOID Info,
|
||||
ULONG Size);
|
||||
BOOL (WINAPI *SetFrontEndProperty)(struct _CONSOLE* Console,
|
||||
BOOL (WINAPI *SetFrontEndProperty)(IN OUT PFRONTEND This,
|
||||
ULONG Flag,
|
||||
PVOID Info /*,
|
||||
ULONG Size */);
|
||||
#endif
|
||||
} FRONTEND_VTBL, *PFRONTEND_VTBL;
|
||||
|
||||
typedef struct _FRONTEND_IFACE
|
||||
struct _FRONTEND
|
||||
{
|
||||
PFRONTEND_VTBL Vtbl; /* Virtual table */
|
||||
PVOID Data; /* Private data */
|
||||
PVOID OldData; /* Reserved */
|
||||
} FRONTEND_IFACE, *PFRONTEND_IFACE;
|
||||
PFRONTEND_VTBL Vtbl; /* Virtual table */
|
||||
struct _CONSOLE* Console; /* Console to which the frontend is attached to */
|
||||
PVOID Data; /* Private data */
|
||||
PVOID OldData; /* Reserved */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 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 ***************************/
|
||||
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
|
||||
|
@ -324,9 +330,11 @@ typedef struct _CONSOLE
|
|||
/* console.c */
|
||||
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
|
||||
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
|
||||
ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
|
||||
ULONG ProcessGroupId,
|
||||
DWORD Event);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
|
||||
IN ULONG ProcessGroupId,
|
||||
IN ULONG Event);
|
||||
|
||||
/* coninput.c */
|
||||
VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
|
||||
|
|
|
@ -8,14 +8,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
BOOL FASTCALL ConSrvValidateConsolePointer(PCONSOLE Console);
|
||||
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
||||
CONSOLE_STATE ExpectedState);
|
||||
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||
CONSOLE_STATE ExpectedState,
|
||||
BOOL LockConsole);
|
||||
BOOL FASTCALL ConSrvValidateConsole(PCONSOLE Console,
|
||||
CONSOLE_STATE ExpectedState,
|
||||
BOOL LockConsole);
|
||||
BOOLEAN NTAPI
|
||||
ConDrvValidateConsolePointer(IN PCONSOLE Console);
|
||||
|
||||
BOOLEAN NTAPI
|
||||
ConDrvValidateConsoleState(IN PCONSOLE Console,
|
||||
IN CONSOLE_STATE ExpectedState);
|
||||
|
||||
BOOLEAN NTAPI
|
||||
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 */
|
||||
|
|
|
@ -365,7 +365,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||
|
||||
/* 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 */
|
||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||
|
@ -508,7 +508,7 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization)
|
|||
if (!ConSrvHeap) return STATUS_NO_MEMORY;
|
||||
*/
|
||||
|
||||
ConSrvInitConsoleSupport();
|
||||
ConDrvInitConsoleSupport();
|
||||
|
||||
/* Setup the DLL Object */
|
||||
LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue