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:
Hermès Bélusca-Maïto 2013-06-23 00:18:47 +00:00
parent f00adc9916
commit c34686cca0
18 changed files with 2502 additions and 1762 deletions

View file

@ -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

View 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: 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 */

View file

@ -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);
} }

View file

@ -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 */

View file

@ -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 */

View file

@ -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 *********************************************************/

View file

@ -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

View file

@ -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 */

View 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

View 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 */

View file

@ -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 */

View file

@ -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");

View file

@ -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);

View file

@ -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 */

View file

@ -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;