mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:42:57 +00:00
[CONSRV]
Code reorganization only. svn path=/branches/ros-csrss/; revision=58618
This commit is contained in:
parent
ac02b55ded
commit
22ecec636a
10 changed files with 329 additions and 296 deletions
14
win32ss/user/consrv/alias.h
Normal file
14
win32ss/user/consrv/alias.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/alias.h
|
||||||
|
* PURPOSE: Alias support functions
|
||||||
|
* PROGRAMMERS: Christoph Wittich
|
||||||
|
* Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
VOID IntDeleteAllAliases(struct _ALIAS_HEADER *RootHeader);
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "conio.h"
|
#include "conio.h"
|
||||||
|
#include "lineinput.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
|
@ -277,12 +277,4 @@ NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console,
|
||||||
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||||
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale);
|
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale);
|
||||||
|
|
||||||
/* alias.c */
|
|
||||||
VOID IntDeleteAllAliases(struct _ALIAS_HEADER *RootHeader);
|
|
||||||
|
|
||||||
/* lineinput.c */
|
|
||||||
struct _HISTORY_BUFFER;
|
|
||||||
VOID FASTCALL HistoryDeleteBuffer(struct _HISTORY_BUFFER *Hist);
|
|
||||||
VOID FASTCALL LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent);
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "conio.h"
|
#include "conio.h"
|
||||||
|
#include "alias.h"
|
||||||
|
#include "lineinput.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#include "frontends/gui/guiterm.h"
|
#include "frontends/gui/guiterm.h"
|
||||||
|
@ -22,6 +24,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
@ -31,8 +34,17 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
static LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
||||||
/*static*/ RTL_RESOURCE ListLock;
|
static RTL_RESOURCE ListLock;
|
||||||
|
|
||||||
|
#define ConSrvLockConsoleListExclusive() \
|
||||||
|
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConSrvLockConsoleListShared() \
|
||||||
|
RtlAcquireResourceShared(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConSrvUnlockConsoleList() \
|
||||||
|
RtlReleaseResource(&ListLock)
|
||||||
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
@ -572,7 +584,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
ConSrvLockConsoleListExclusive();
|
ConSrvLockConsoleListExclusive();
|
||||||
|
|
||||||
/* Check the existence of the console, and if it's ok, continue */
|
/* Check the existence of the console, and if it's ok, continue */
|
||||||
if (!ConSrvValidatePointer(Console))
|
if (!ConSrvValidateConsolePointer(Console))
|
||||||
{
|
{
|
||||||
/* Unlock the console list and return */
|
/* Unlock the console list and return */
|
||||||
ConSrvUnlockConsoleList();
|
ConSrvUnlockConsoleList();
|
||||||
|
@ -622,7 +634,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
ConSrvLockConsoleListExclusive();
|
ConSrvLockConsoleListExclusive();
|
||||||
|
|
||||||
/* Re-check the existence of the console, and if it's ok, continue */
|
/* Re-check the existence of the console, and if it's ok, continue */
|
||||||
if (!ConSrvValidatePointer(Console))
|
if (!ConSrvValidateConsolePointer(Console))
|
||||||
{
|
{
|
||||||
/* Unlock the console list and return */
|
/* Unlock the console list and return */
|
||||||
ConSrvUnlockConsoleList();
|
ConSrvUnlockConsoleList();
|
||||||
|
@ -654,8 +666,8 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
|
|
||||||
if (Console->LineBuffer)
|
if (Console->LineBuffer)
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
|
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
|
||||||
while (!IsListEmpty(&Console->HistoryBuffers))
|
|
||||||
HistoryDeleteBuffer((struct _HISTORY_BUFFER *)Console->HistoryBuffers.Flink);
|
HistoryDeleteBuffers(Console);
|
||||||
|
|
||||||
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||||
if (!IsListEmpty(&Console->BufferList))
|
if (!IsListEmpty(&Console->BufferList))
|
||||||
|
@ -683,6 +695,94 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
ConSrvUnlockConsoleList();
|
ConSrvUnlockConsoleList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
ConSrvValidateConsolePointer(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
ConSrvValidateConsoleState(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState)
|
||||||
|
{
|
||||||
|
// if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/* The console must be locked */
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
return (Console->State == ExpectedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL 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 (!ConSrvValidateConsoleState(Console, ExpectedState))
|
||||||
|
{
|
||||||
|
if (LockConsole) LeaveCriticalSection(&Console->Lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
ConSrvValidateConsole(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL LockConsole)
|
||||||
|
{
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forbid creation or deletion of consoles when
|
||||||
|
* checking for the existence of a console.
|
||||||
|
*/
|
||||||
|
ConSrvLockConsoleListShared();
|
||||||
|
|
||||||
|
if (ConSrvValidateConsolePointer(Console))
|
||||||
|
{
|
||||||
|
RetVal = ConSrvValidateConsoleUnsafe(Console,
|
||||||
|
ExpectedState,
|
||||||
|
LockConsole);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PUBLIC SERVER APIS *********************************************************/
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ConSrvLockConsoleListExclusive() \
|
|
||||||
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
|
||||||
|
|
||||||
#define ConSrvLockConsoleListShared() \
|
|
||||||
RtlAcquireResourceShared(&ListLock, TRUE)
|
|
||||||
|
|
||||||
#define ConSrvUnlockConsoleList() \
|
|
||||||
RtlReleaseResource(&ListLock)
|
|
||||||
|
|
||||||
extern LIST_ENTRY ConsoleList;
|
|
||||||
extern RTL_RESOURCE ListLock;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
* 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 !
|
||||||
|
@ -39,7 +27,7 @@ NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
IN PCSR_PROCESS ConsoleLeaderProcess);
|
IN PCSR_PROCESS ConsoleLeaderProcess);
|
||||||
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
|
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
|
||||||
BOOL FASTCALL ConSrvValidatePointer(PCONSOLE Console);
|
BOOL FASTCALL ConSrvValidateConsolePointer(PCONSOLE Console);
|
||||||
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
||||||
CONSOLE_STATE ExpectedState);
|
CONSOLE_STATE ExpectedState);
|
||||||
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||||
|
|
|
@ -44,8 +44,6 @@
|
||||||
#include <win/console.h>
|
#include <win/console.h>
|
||||||
#include <win/conmsg.h>
|
#include <win/conmsg.h>
|
||||||
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern HINSTANCE ConSrvDllInstance;
|
extern HINSTANCE ConSrvDllInstance;
|
||||||
extern HANDLE ConSrvHeap;
|
extern HANDLE ConSrvHeap;
|
||||||
|
|
|
@ -182,7 +182,7 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
NTSTATUS
|
||||||
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||||
IN PCONSOLE_PROCESS_DATA TargetProcessData)
|
IN PCONSOLE_PROCESS_DATA TargetProcessData)
|
||||||
{
|
{
|
||||||
|
@ -564,98 +564,6 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
|
||||||
FASTCALL
|
|
||||||
ConSrvValidatePointer(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
FASTCALL
|
|
||||||
ConSrvValidateConsoleState(PCONSOLE Console,
|
|
||||||
CONSOLE_STATE ExpectedState)
|
|
||||||
{
|
|
||||||
// if (!Console) return FALSE;
|
|
||||||
|
|
||||||
/* The console must be locked */
|
|
||||||
// ASSERT(Console_locked);
|
|
||||||
|
|
||||||
return (Console->State == ExpectedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
FASTCALL
|
|
||||||
ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
|
||||||
CONSOLE_STATE ExpectedState,
|
|
||||||
BOOL 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 (!ConSrvValidateConsoleState(Console, ExpectedState))
|
|
||||||
{
|
|
||||||
if (LockConsole) LeaveCriticalSection(&Console->Lock);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
FASTCALL
|
|
||||||
ConSrvValidateConsole(PCONSOLE Console,
|
|
||||||
CONSOLE_STATE ExpectedState,
|
|
||||||
BOOL LockConsole)
|
|
||||||
{
|
|
||||||
BOOL RetVal = FALSE;
|
|
||||||
|
|
||||||
if (!Console) return FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Forbid creation or deletion of consoles when
|
|
||||||
* checking for the existence of a console.
|
|
||||||
*/
|
|
||||||
ConSrvLockConsoleListShared();
|
|
||||||
|
|
||||||
if (ConSrvValidatePointer(Console))
|
|
||||||
{
|
|
||||||
RetVal = ConSrvValidateConsoleUnsafe(Console,
|
|
||||||
ExpectedState,
|
|
||||||
LockConsole);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock the console list and return */
|
|
||||||
ConSrvUnlockConsoleList();
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
|
@ -711,179 +619,6 @@ ConSrvReleaseConsole(PCONSOLE Console,
|
||||||
if (RefCount <= 0) ConSrvDeleteConsole(Console);
|
if (RefCount <= 0) ConSrvDeleteConsole(Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|
||||||
PCSR_PROCESS TargetProcess)
|
|
||||||
{
|
|
||||||
/**************************************************************************
|
|
||||||
* This function is called whenever a new process (GUI or CUI) is created.
|
|
||||||
*
|
|
||||||
* Copy the parent's handles table here if both the parent and the child
|
|
||||||
* processes are CUI. If we must actually create our proper console (and
|
|
||||||
* thus do not inherit from the console handles of the parent's), then we
|
|
||||||
* will clean this table in the next ConSrvConnect call. Why we are doing
|
|
||||||
* this? It's because here, we still don't know whether or not we must create
|
|
||||||
* a new console instead of inherit it from the parent, and, because in
|
|
||||||
* ConSrvConnect we don't have any reference to the parent process anymore.
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
|
||||||
|
|
||||||
/* An empty target process is invalid */
|
|
||||||
if (!TargetProcess) return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
|
|
||||||
|
|
||||||
/**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
|
||||||
|
|
||||||
/* Initialize the new (target) process */
|
|
||||||
TargetProcessData->Process = TargetProcess;
|
|
||||||
TargetProcessData->ConsoleEvent = NULL;
|
|
||||||
TargetProcessData->Console = TargetProcessData->ParentConsole = NULL;
|
|
||||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
|
||||||
|
|
||||||
// Testing
|
|
||||||
TargetProcessData->HandleTableSize = 0;
|
|
||||||
TargetProcessData->HandleTable = NULL;
|
|
||||||
|
|
||||||
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
|
|
||||||
|
|
||||||
/* Do nothing if the source process is NULL */
|
|
||||||
if (!SourceProcess) return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If both of the processes (parent and new child) are console applications,
|
|
||||||
* then try to inherit handles from the parent process.
|
|
||||||
*/
|
|
||||||
if ( SourceProcessData->Console != NULL && /* SourceProcessData->ConsoleApp */
|
|
||||||
TargetProcessData->ConsoleApp )
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
|
||||||
|
|
||||||
/* Temporary save the parent's console */
|
|
||||||
TargetProcessData->ParentConsole = SourceProcessData->Console;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|
||||||
IN OUT PVOID ConnectionInfo,
|
|
||||||
IN OUT PULONG ConnectionInfoLength)
|
|
||||||
{
|
|
||||||
/**************************************************************************
|
|
||||||
* This function is called whenever a CUI new process is created.
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
|
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
|
||||||
|
|
||||||
if ( ConnectionInfo == NULL ||
|
|
||||||
ConnectionInfoLength == NULL ||
|
|
||||||
*ConnectionInfoLength != sizeof(CONSOLE_CONNECTION_INFO) )
|
|
||||||
{
|
|
||||||
DPRINT1("CONSRV: Connection failed\n");
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't need a console, then get out of here */
|
|
||||||
if (!ConnectInfo->ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
|
|
||||||
{
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't have a console, then create a new one... */
|
|
||||||
if (!ConnectInfo->Console ||
|
|
||||||
ConnectInfo->Console != ProcessData->ParentConsole)
|
|
||||||
{
|
|
||||||
DPRINT1("ConSrvConnect - Allocate a new console\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We are about to create a new console. However when ConSrvNewProcess
|
|
||||||
* was called, we didn't know that we wanted to create a new console and
|
|
||||||
* therefore, we by default inherited the handles table from our parent
|
|
||||||
* process. It's only now that we notice that in fact we do not need
|
|
||||||
* them, because we've created a new console and thus we must use it.
|
|
||||||
*
|
|
||||||
* Therefore, free the console we can have and our handles table,
|
|
||||||
* and recreate a new one later on.
|
|
||||||
*/
|
|
||||||
ConSrvRemoveConsole(ProcessData);
|
|
||||||
|
|
||||||
/* Initialize a new Console owned by the Console Leader Process */
|
|
||||||
Status = ConSrvAllocateConsole(ProcessData,
|
|
||||||
&ConnectInfo->InputHandle,
|
|
||||||
&ConnectInfo->OutputHandle,
|
|
||||||
&ConnectInfo->ErrorHandle,
|
|
||||||
&ConnectInfo->ConsoleStartInfo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Console allocation failed\n");
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* We inherit it from the parent */
|
|
||||||
{
|
|
||||||
DPRINT1("ConSrvConnect - Reuse current (parent's) console\n");
|
|
||||||
|
|
||||||
/* Reuse our current console */
|
|
||||||
Status = ConSrvInheritConsole(ProcessData,
|
|
||||||
ConnectInfo->Console,
|
|
||||||
FALSE,
|
|
||||||
NULL, // &ConnectInfo->InputHandle,
|
|
||||||
NULL, // &ConnectInfo->OutputHandle,
|
|
||||||
NULL); // &ConnectInfo->ErrorHandle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Console inheritance failed\n");
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return it to the caller */
|
|
||||||
ConnectInfo->Console = ProcessData->Console;
|
|
||||||
|
|
||||||
/* Input Wait Handle */
|
|
||||||
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
|
|
||||||
|
|
||||||
/* Set the Property Dialog Handler */
|
|
||||||
ProcessData->PropDispatcher = ConnectInfo->PropDispatcher;
|
|
||||||
|
|
||||||
/* Set the Ctrl Dispatcher */
|
|
||||||
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ConSrvDisconnect(PCSR_PROCESS Process)
|
|
||||||
{
|
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
if ( ProcessData->Console != NULL ||
|
|
||||||
ProcessData->HandleTable != NULL )
|
|
||||||
{
|
|
||||||
DPRINT1("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
|
||||||
ConSrvRemoveConsole(ProcessData);
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* PUBLIC SERVER APIS *********************************************************/
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,183 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||||
|
IN PCONSOLE_PROCESS_DATA TargetProcessData);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
|
PCSR_PROCESS TargetProcess)
|
||||||
|
{
|
||||||
|
/**************************************************************************
|
||||||
|
* This function is called whenever a new process (GUI or CUI) is created.
|
||||||
|
*
|
||||||
|
* Copy the parent's handles table here if both the parent and the child
|
||||||
|
* processes are CUI. If we must actually create our proper console (and
|
||||||
|
* thus do not inherit from the console handles of the parent's), then we
|
||||||
|
* will clean this table in the next ConSrvConnect call. Why we are doing
|
||||||
|
* this? It's because here, we still don't know whether or not we must create
|
||||||
|
* a new console instead of inherit it from the parent, and, because in
|
||||||
|
* ConSrvConnect we don't have any reference to the parent process anymore.
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
||||||
|
|
||||||
|
/* An empty target process is invalid */
|
||||||
|
if (!TargetProcess) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
|
||||||
|
|
||||||
|
/**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
||||||
|
|
||||||
|
/* Initialize the new (target) process */
|
||||||
|
TargetProcessData->Process = TargetProcess;
|
||||||
|
TargetProcessData->ConsoleEvent = NULL;
|
||||||
|
TargetProcessData->Console = TargetProcessData->ParentConsole = NULL;
|
||||||
|
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
||||||
|
|
||||||
|
// Testing
|
||||||
|
TargetProcessData->HandleTableSize = 0;
|
||||||
|
TargetProcessData->HandleTable = NULL;
|
||||||
|
|
||||||
|
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
/* Do nothing if the source process is NULL */
|
||||||
|
if (!SourceProcess) return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If both of the processes (parent and new child) are console applications,
|
||||||
|
* then try to inherit handles from the parent process.
|
||||||
|
*/
|
||||||
|
if ( SourceProcessData->Console != NULL && /* SourceProcessData->ConsoleApp */
|
||||||
|
TargetProcessData->ConsoleApp )
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Temporary save the parent's console */
|
||||||
|
TargetProcessData->ParentConsole = SourceProcessData->Console;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
|
IN OUT PVOID ConnectionInfo,
|
||||||
|
IN OUT PULONG ConnectionInfoLength)
|
||||||
|
{
|
||||||
|
/**************************************************************************
|
||||||
|
* This function is called whenever a CUI new process is created.
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
|
||||||
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||||
|
|
||||||
|
if ( ConnectionInfo == NULL ||
|
||||||
|
ConnectionInfoLength == NULL ||
|
||||||
|
*ConnectionInfoLength != sizeof(CONSOLE_CONNECTION_INFO) )
|
||||||
|
{
|
||||||
|
DPRINT1("CONSRV: Connection failed\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't need a console, then get out of here */
|
||||||
|
if (!ConnectInfo->ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't have a console, then create a new one... */
|
||||||
|
if (!ConnectInfo->Console ||
|
||||||
|
ConnectInfo->Console != ProcessData->ParentConsole)
|
||||||
|
{
|
||||||
|
DPRINT1("ConSrvConnect - Allocate a new console\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are about to create a new console. However when ConSrvNewProcess
|
||||||
|
* was called, we didn't know that we wanted to create a new console and
|
||||||
|
* therefore, we by default inherited the handles table from our parent
|
||||||
|
* process. It's only now that we notice that in fact we do not need
|
||||||
|
* them, because we've created a new console and thus we must use it.
|
||||||
|
*
|
||||||
|
* Therefore, free the console we can have and our handles table,
|
||||||
|
* and recreate a new one later on.
|
||||||
|
*/
|
||||||
|
ConSrvRemoveConsole(ProcessData);
|
||||||
|
|
||||||
|
/* Initialize a new Console owned by the Console Leader Process */
|
||||||
|
Status = ConSrvAllocateConsole(ProcessData,
|
||||||
|
&ConnectInfo->InputHandle,
|
||||||
|
&ConnectInfo->OutputHandle,
|
||||||
|
&ConnectInfo->ErrorHandle,
|
||||||
|
&ConnectInfo->ConsoleStartInfo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Console allocation failed\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* We inherit it from the parent */
|
||||||
|
{
|
||||||
|
DPRINT1("ConSrvConnect - Reuse current (parent's) console\n");
|
||||||
|
|
||||||
|
/* Reuse our current console */
|
||||||
|
Status = ConSrvInheritConsole(ProcessData,
|
||||||
|
ConnectInfo->Console,
|
||||||
|
FALSE,
|
||||||
|
NULL, // &ConnectInfo->InputHandle,
|
||||||
|
NULL, // &ConnectInfo->OutputHandle,
|
||||||
|
NULL); // &ConnectInfo->ErrorHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Console inheritance failed\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return it to the caller */
|
||||||
|
ConnectInfo->Console = ProcessData->Console;
|
||||||
|
|
||||||
|
/* Input Wait Handle */
|
||||||
|
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
|
||||||
|
|
||||||
|
/* Set the Property Dialog Handler */
|
||||||
|
ProcessData->PropDispatcher = ConnectInfo->PropDispatcher;
|
||||||
|
|
||||||
|
/* Set the Ctrl Dispatcher */
|
||||||
|
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ConSrvDisconnect(PCSR_PROCESS Process)
|
||||||
|
{
|
||||||
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
if ( ProcessData->Console != NULL ||
|
||||||
|
ProcessData->HandleTable != NULL )
|
||||||
|
{
|
||||||
|
DPRINT1("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
||||||
|
ConSrvRemoveConsole(ProcessData);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
}
|
||||||
|
|
||||||
CSR_SERVER_DLL_INIT(ConServerDllInitialization)
|
CSR_SERVER_DLL_INIT(ConServerDllInitialization)
|
||||||
{
|
{
|
||||||
/* Initialize the memory */
|
/* Initialize the memory */
|
||||||
|
|
|
@ -138,7 +138,7 @@ HistoryFindBuffer(PCONSOLE Console, PUNICODE_STRING ExeName)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
static VOID
|
||||||
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
||||||
{
|
{
|
||||||
if (!Hist) return;
|
if (!Hist) return;
|
||||||
|
@ -151,6 +151,20 @@ HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Hist);
|
RtlFreeHeap(ConSrvHeap, 0, Hist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
HistoryDeleteBuffers(PCONSOLE Console)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PHISTORY_BUFFER HistoryBuffer;
|
||||||
|
|
||||||
|
while (!IsListEmpty(&Console->HistoryBuffers))
|
||||||
|
{
|
||||||
|
CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
|
||||||
|
HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
|
||||||
|
HistoryDeleteBuffer(HistoryBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
LineInputSetPos(PCONSOLE Console, UINT Pos)
|
LineInputSetPos(PCONSOLE Console, UINT Pos)
|
||||||
{
|
{
|
||||||
|
|
14
win32ss/user/consrv/lineinput.h
Normal file
14
win32ss/user/consrv/lineinput.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/lineinput.c
|
||||||
|
* PURPOSE: Console line input functions
|
||||||
|
* PROGRAMMERS: Jeffrey Morlan
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
VOID FASTCALL HistoryDeleteBuffers(PCONSOLE Console);
|
||||||
|
VOID FASTCALL LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent);
|
||||||
|
|
||||||
|
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue