mirror of
https://github.com/reactos/reactos.git
synced 2025-05-16 15:50:24 +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 "conio.h"
|
||||
#include "lineinput.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
|
|
@ -277,12 +277,4 @@ NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console,
|
|||
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
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 */
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "consrv.h"
|
||||
#include "conio.h"
|
||||
#include "alias.h"
|
||||
#include "lineinput.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "frontends/gui/guiterm.h"
|
||||
|
@ -22,6 +24,7 @@
|
|||
#endif
|
||||
|
||||
#include "console.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <shlobj.h>
|
||||
|
@ -31,8 +34,17 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
||||
/*static*/ RTL_RESOURCE ListLock;
|
||||
static LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
||||
static RTL_RESOURCE ListLock;
|
||||
|
||||
#define ConSrvLockConsoleListExclusive() \
|
||||
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
||||
|
||||
#define ConSrvLockConsoleListShared() \
|
||||
RtlAcquireResourceShared(&ListLock, TRUE)
|
||||
|
||||
#define ConSrvUnlockConsoleList() \
|
||||
RtlReleaseResource(&ListLock)
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
@ -572,7 +584,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
|||
ConSrvLockConsoleListExclusive();
|
||||
|
||||
/* Check the existence of the console, and if it's ok, continue */
|
||||
if (!ConSrvValidatePointer(Console))
|
||||
if (!ConSrvValidateConsolePointer(Console))
|
||||
{
|
||||
/* Unlock the console list and return */
|
||||
ConSrvUnlockConsoleList();
|
||||
|
@ -622,7 +634,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
|||
ConSrvLockConsoleListExclusive();
|
||||
|
||||
/* 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 */
|
||||
ConSrvUnlockConsoleList();
|
||||
|
@ -654,8 +666,8 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
|||
|
||||
if (Console->LineBuffer)
|
||||
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
|
||||
while (!IsListEmpty(&Console->HistoryBuffers))
|
||||
HistoryDeleteBuffer((struct _HISTORY_BUFFER *)Console->HistoryBuffers.Flink);
|
||||
|
||||
HistoryDeleteBuffers(Console);
|
||||
|
||||
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
if (!IsListEmpty(&Console->BufferList))
|
||||
|
@ -683,6 +695,94 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
|||
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 *********************************************************/
|
||||
|
||||
|
|
|
@ -8,18 +8,6 @@
|
|||
|
||||
#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
|
||||
/*
|
||||
* 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 PCSR_PROCESS ConsoleLeaderProcess);
|
||||
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
|
||||
BOOL FASTCALL ConSrvValidatePointer(PCONSOLE Console);
|
||||
BOOL FASTCALL ConSrvValidateConsolePointer(PCONSOLE Console);
|
||||
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
||||
CONSOLE_STATE ExpectedState);
|
||||
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
#include <win/console.h>
|
||||
#include <win/conmsg.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
extern HINSTANCE ConSrvDllInstance;
|
||||
extern HANDLE ConSrvHeap;
|
||||
|
|
|
@ -182,7 +182,7 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
NTSTATUS
|
||||
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||
IN PCONSOLE_PROCESS_DATA TargetProcessData)
|
||||
{
|
||||
|
@ -564,98 +564,6 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
|||
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
|
||||
FASTCALL
|
||||
ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
|
@ -711,179 +619,6 @@ ConSrvReleaseConsole(PCONSOLE 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 *********************************************************/
|
||||
|
||||
|
|
|
@ -300,6 +300,183 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
|
|||
|
||||
/* 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)
|
||||
{
|
||||
/* Initialize the memory */
|
||||
|
|
|
@ -138,7 +138,7 @@ HistoryFindBuffer(PCONSOLE Console, PUNICODE_STRING ExeName)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
static VOID
|
||||
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
||||
{
|
||||
if (!Hist) return;
|
||||
|
@ -151,6 +151,20 @@ HistoryDeleteBuffer(PHISTORY_BUFFER 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
|
||||
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…
Reference in a new issue