mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[KERNEL32]
- Correct a error return code (in AllocConsole). - Implement AttachConsole (inspired by AllocConsole). [CONSRV] - Correct a error return code (in AllocConsole). - Introduce helper functions to simplify console-initialization code. - Implement server-side of AttachConsole (I used pieces of code from ConsoleNewProcess, ConsoleConnect and SrvAllocConsole). Some debug prints were introduced (for debug-purposes :P), will be removed when all things work. TODO: have a look on the handles code. svn path=/branches/ros-csrss/; revision=58166
This commit is contained in:
parent
074466b15e
commit
df7477717c
6 changed files with 416 additions and 213 deletions
|
@ -802,8 +802,8 @@ AllocConsole(VOID)
|
||||||
|
|
||||||
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
||||||
{
|
{
|
||||||
DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
|
DPRINT1("AllocConsole: Allocate duplicate console to the same Process\n");
|
||||||
BaseSetLastNTError (STATUS_OBJECT_NAME_EXISTS);
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,7 +824,6 @@ AllocConsole(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
|
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
|
||||||
|
|
||||||
SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
|
SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
|
||||||
SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
|
SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
|
||||||
SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
|
SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
|
||||||
|
@ -1910,13 +1909,50 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
* AttachConsole
|
* AttachConsole
|
||||||
*
|
*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
|
*
|
||||||
|
* @note Strongly inspired by AllocConsole.
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
AttachConsole(DWORD dwProcessId)
|
AttachConsole(DWORD dwProcessId)
|
||||||
{
|
{
|
||||||
DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
|
NTSTATUS Status;
|
||||||
|
CONSOLE_API_MESSAGE ApiMessage;
|
||||||
|
PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
|
||||||
|
|
||||||
|
DPRINT1("AttachConsole(%lu)\n", dwProcessId);
|
||||||
|
|
||||||
|
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
||||||
|
{
|
||||||
|
DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
|
||||||
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachConsoleRequest->ProcessId = dwProcessId;
|
||||||
|
AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
|
||||||
|
|
||||||
|
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||||
|
NULL,
|
||||||
|
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
|
||||||
|
sizeof(CONSOLE_ATTACHCONSOLE));
|
||||||
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AttachConsoleRequest->Console;
|
||||||
|
SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
|
||||||
|
SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
|
||||||
|
SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
|
||||||
|
|
||||||
|
/* Initialize Console Ctrl Handler */
|
||||||
|
InitConsoleCtrlHandling();
|
||||||
|
|
||||||
|
InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ typedef enum _CONSRV_API_NUMBER
|
||||||
// ConsolepRegisterConsoleIME,
|
// ConsolepRegisterConsoleIME,
|
||||||
// ConsolepUnregisterConsoleIME,
|
// ConsolepUnregisterConsoleIME,
|
||||||
// ConsolepGetLangId,
|
// ConsolepGetLangId,
|
||||||
// ConsolepAttach,
|
ConsolepAttach,
|
||||||
ConsolepGetSelectionInfo,
|
ConsolepGetSelectionInfo,
|
||||||
ConsolepGetProcessList,
|
ConsolepGetProcessList,
|
||||||
ConsolepGetHistory,
|
ConsolepGetHistory,
|
||||||
|
@ -177,6 +177,17 @@ typedef struct
|
||||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||||
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process console.
|
||||||
|
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
|
||||||
|
HANDLE InputHandle;
|
||||||
|
HANDLE OutputHandle;
|
||||||
|
HANDLE ErrorHandle;
|
||||||
|
HANDLE InputWaitHandle;
|
||||||
|
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||||
|
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Dummy;
|
ULONG Dummy;
|
||||||
|
@ -543,6 +554,7 @@ typedef struct _CONSOLE_API_MESSAGE
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
CONSOLE_ALLOCCONSOLE AllocConsoleRequest;
|
CONSOLE_ALLOCCONSOLE AllocConsoleRequest;
|
||||||
|
CONSOLE_ATTACHCONSOLE AttachConsoleRequest;
|
||||||
CONSOLE_FREECONSOLE FreeConsoleRequest;
|
CONSOLE_FREECONSOLE FreeConsoleRequest;
|
||||||
|
|
||||||
/* Handles */
|
/* Handles */
|
||||||
|
|
|
@ -301,58 +301,52 @@ CSR_API(SrvAllocConsole)
|
||||||
if (ProcessData->Console != NULL)
|
if (ProcessData->Console != NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Process already has a console\n");
|
DPRINT1("Process already has a console\n");
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
/******************************************************************************/
|
||||||
|
/** This comes from ConsoleConnect!! **/
|
||||||
DPRINT1("SrvAllocConsole - Checkpoint 1\n");
|
DPRINT1("SrvAllocConsole - Checkpoint 1\n");
|
||||||
|
|
||||||
|
#if 0000
|
||||||
|
/*
|
||||||
|
* We are about to create a new console. However when ConsoleNewProcess
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// Win32CsrFreeHandlesTable(ProcessData);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize a new Console owned by the Console Leader Process */
|
/* Initialize a new Console owned by the Console Leader Process */
|
||||||
Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
|
Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console initialization failed\n");
|
DPRINT1("Console initialization failed\n");
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a reference count because the process is tied to the console */
|
||||||
|
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
||||||
|
|
||||||
/* Insert the process into the processes list of the console */
|
/* Insert the process into the processes list of the console */
|
||||||
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
|
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
|
||||||
|
|
||||||
/* Return it to the caller */
|
/* Return it to the caller */
|
||||||
AllocConsoleRequest->Console = ProcessData->Console;
|
AllocConsoleRequest->Console = ProcessData->Console;
|
||||||
|
|
||||||
/* Add a reference count because the process is tied to the console */
|
|
||||||
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
|
||||||
|
|
||||||
#if 0000
|
|
||||||
/*
|
|
||||||
* We've just created a new console. However when ConsoleNewProcess 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 our handles table and recreate a new one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
/* Close all console handles and free the handle table memory */
|
|
||||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
|
||||||
{
|
|
||||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
|
||||||
}
|
|
||||||
ProcessData->HandleTableSize = 0;
|
|
||||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
|
||||||
ProcessData->HandleTable = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new handle table - Insert the IO handles
|
* Create a new handle table - Insert the IO handles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
/* Insert the Input handle */
|
/* Insert the Input handle */
|
||||||
Status = Win32CsrInsertObject(ProcessData,
|
Status = Win32CsrInsertObject(ProcessData,
|
||||||
&AllocConsoleRequest->InputHandle,
|
&AllocConsoleRequest->InputHandle,
|
||||||
|
@ -363,9 +357,10 @@ CSR_API(SrvAllocConsole)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the input handle\n");
|
DPRINT1("Failed to insert the input handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,11 +374,12 @@ CSR_API(SrvAllocConsole)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the output handle\n");
|
DPRINT1("Failed to insert the output handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
AllocConsoleRequest->InputHandle);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// AllocConsoleRequest->InputHandle);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,16 +393,19 @@ CSR_API(SrvAllocConsole)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the error handle\n");
|
DPRINT1("Failed to insert the error handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
AllocConsoleRequest->OutputHandle);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
AllocConsoleRequest->InputHandle);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// AllocConsoleRequest->OutputHandle);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// AllocConsoleRequest->InputHandle);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
/* Duplicate the Event */
|
/* Duplicate the Event */
|
||||||
Status = NtDuplicateObject(NtCurrentProcess(),
|
Status = NtDuplicateObject(NtCurrentProcess(),
|
||||||
ProcessData->Console->ActiveEvent,
|
ProcessData->Console->ActiveEvent,
|
||||||
|
@ -416,18 +415,18 @@ CSR_API(SrvAllocConsole)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
// if (NewConsole /* || !ProcessData->bInheritHandles */)
|
// if (NewConsole)
|
||||||
{
|
// {
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
AllocConsoleRequest->ErrorHandle);
|
// AllocConsoleRequest->ErrorHandle);
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
AllocConsoleRequest->OutputHandle);
|
// AllocConsoleRequest->OutputHandle);
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
AllocConsoleRequest->InputHandle);
|
// AllocConsoleRequest->InputHandle);
|
||||||
}
|
// }
|
||||||
ProcessData->Console = NULL;
|
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
/* Input Wait Handle */
|
/* Input Wait Handle */
|
||||||
|
@ -436,15 +435,149 @@ CSR_API(SrvAllocConsole)
|
||||||
/* Set the Ctrl Dispatcher */
|
/* Set the Ctrl Dispatcher */
|
||||||
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
||||||
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSR_API(SrvAttachConsole)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AttachConsoleRequest;
|
||||||
|
PCSR_PROCESS SourceProcess = NULL; // The parent process.
|
||||||
|
PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves.
|
||||||
|
HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId);
|
||||||
|
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
||||||
|
|
||||||
|
DPRINT("SrvAttachConsole\n");
|
||||||
|
|
||||||
|
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
|
||||||
|
|
||||||
|
if (TargetProcessData->Console != NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Process already has a console\n");
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
||||||
|
{
|
||||||
|
PROCESS_BASIC_INFORMATION ProcessInfo;
|
||||||
|
ULONG Length = sizeof(ProcessInfo);
|
||||||
|
|
||||||
|
/* Get the real parent's ID */
|
||||||
|
|
||||||
|
Status = NtQueryInformationProcess(TargetProcess->ProcessHandle,
|
||||||
|
ProcessBasicInformation,
|
||||||
|
&ProcessInfo,
|
||||||
|
Length, &Length);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("We, process (ID) %lu;%lu\n", TargetProcess->ClientId.UniqueProcess, TargetProcess->ClientId.UniqueThread);
|
||||||
|
ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId);
|
||||||
|
DPRINT("Parent process ID = %lu\n", ProcessId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock the target process via its PID */
|
||||||
|
DPRINT1("Lock process Id %lu\n", ProcessId);
|
||||||
|
Status = CsrLockProcessByClientId(ProcessId, &SourceProcess);
|
||||||
|
DPRINT1("Lock process Status %lu\n", Status);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
DPRINT1("AttachConsole OK\n");
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/** This comes from ConsoleNewProcess!! **/
|
||||||
|
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inherit the console from the parent,
|
||||||
|
* if any, otherwise return an error.
|
||||||
|
*/
|
||||||
|
DPRINT1("SourceProcessData->Console = 0x%p\n", SourceProcessData->Console);
|
||||||
|
if (SourceProcessData->Console == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
TargetProcessData->Console = SourceProcessData->Console;
|
||||||
|
|
||||||
|
DPRINT1("SrvAttachConsole - Copy the handle table (1)\n");
|
||||||
|
Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||||
|
DPRINT1("SrvAttachConsole - Copy the handle table (2)\n");
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/** This comes from ConsoleConnect / SrvAllocConsole!! **/
|
||||||
|
/* Add a reference count because the process is tied to the console */
|
||||||
|
_InterlockedIncrement(&TargetProcessData->Console->ReferenceCount);
|
||||||
|
|
||||||
|
/* Insert the process into the processes list of the console */
|
||||||
|
InsertHeadList(&TargetProcessData->Console->ProcessList, &TargetProcessData->ConsoleLink);
|
||||||
|
|
||||||
|
/* Return it to the caller */
|
||||||
|
AttachConsoleRequest->Console = TargetProcessData->Console;
|
||||||
|
|
||||||
|
/** Here, we inherited the console handles from the "source" process,
|
||||||
|
** so no need to reinitialize the handles table. **/
|
||||||
|
|
||||||
|
DPRINT1("SrvAttachConsole - Checkpoint\n");
|
||||||
|
|
||||||
|
/* Duplicate the Event */
|
||||||
|
Status = NtDuplicateObject(NtCurrentProcess(),
|
||||||
|
TargetProcessData->Console->ActiveEvent,
|
||||||
|
TargetProcessData->Process->ProcessHandle,
|
||||||
|
&TargetProcessData->ConsoleEvent,
|
||||||
|
EVENT_ALL_ACCESS, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||||
|
Win32CsrReleaseConsole(TargetProcessData);
|
||||||
|
// #if 0
|
||||||
|
// if (NewConsole)
|
||||||
|
// {
|
||||||
|
// Win32CsrReleaseObject(TargetProcessData,
|
||||||
|
// AttachConsoleRequest->ErrorHandle);
|
||||||
|
// Win32CsrReleaseObject(TargetProcessData,
|
||||||
|
// AttachConsoleRequest->OutputHandle);
|
||||||
|
// Win32CsrReleaseObject(TargetProcessData,
|
||||||
|
// AttachConsoleRequest->InputHandle);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
// ConioDeleteConsole(TargetProcessData->Console); // FIXME: Just release the console ?
|
||||||
|
// TargetProcessData->Console = NULL;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
/* Input Wait Handle */
|
||||||
|
AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;
|
||||||
|
|
||||||
|
/* Set the Ctrl Dispatcher */
|
||||||
|
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
|
||||||
|
DPRINT("CONSRV: CtrlDispatcher address: %x\n", TargetProcessData->CtrlDispatcher);
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
DPRINT1("SrvAttachConsole - exiting 1\n");
|
||||||
|
/* Unlock the "source" process */
|
||||||
|
CsrUnlockProcess(SourceProcess);
|
||||||
|
DPRINT1("SrvAttachConsole - exiting 2\n");
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
CSR_API(SrvFreeConsole)
|
CSR_API(SrvFreeConsole)
|
||||||
{
|
{
|
||||||
DPRINT1("SrvFreeConsole\n");
|
DPRINT1("SrvFreeConsole\n");
|
||||||
Win32CsrReleaseConsole(CsrGetClientThread()->Process);
|
Win32CsrReleaseConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ typedef struct _CONSOLE_PROCESS_DATA
|
||||||
/* PCONSOLE */ struct _CONSOLE* Console;
|
/* PCONSOLE */ struct _CONSOLE* Console;
|
||||||
/* PCONSOLE */ struct _CONSOLE* ParentConsole;
|
/* PCONSOLE */ struct _CONSOLE* ParentConsole;
|
||||||
|
|
||||||
// BOOL bInheritHandles;
|
|
||||||
BOOL ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
BOOL ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
||||||
|
|
||||||
RTL_CRITICAL_SECTION HandleTableLock;
|
RTL_CRITICAL_SECTION HandleTableLock;
|
||||||
|
@ -118,6 +117,7 @@ CSR_API(SrvSetConsoleScreenBufferSize);
|
||||||
/* console.c */
|
/* console.c */
|
||||||
CSR_API(SrvOpenConsole);
|
CSR_API(SrvOpenConsole);
|
||||||
CSR_API(SrvAllocConsole);
|
CSR_API(SrvAllocConsole);
|
||||||
|
CSR_API(SrvAttachConsole);
|
||||||
CSR_API(SrvFreeConsole);
|
CSR_API(SrvFreeConsole);
|
||||||
CSR_API(SrvSetConsoleMode);
|
CSR_API(SrvSetConsoleMode);
|
||||||
CSR_API(SrvGetConsoleMode);
|
CSR_API(SrvGetConsoleMode);
|
||||||
|
@ -139,6 +139,9 @@ CSR_API(SrvVerifyConsoleIoHandle);
|
||||||
CSR_API(SrvDuplicateHandle);
|
CSR_API(SrvDuplicateHandle);
|
||||||
/// CSR_API(CsrGetInputWaitHandle);
|
/// CSR_API(CsrGetInputWaitHandle);
|
||||||
|
|
||||||
|
NTSTATUS FASTCALL Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||||
|
IN PCONSOLE_PROCESS_DATA TargetProcessData);
|
||||||
|
VOID FASTCALL Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData);
|
||||||
NTSTATUS FASTCALL Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
NTSTATUS FASTCALL Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
PHANDLE Handle,
|
PHANDLE Handle,
|
||||||
Object_t *Object,
|
Object_t *Object,
|
||||||
|
@ -153,6 +156,7 @@ NTSTATUS FASTCALL Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
|
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
|
||||||
NTSTATUS FASTCALL Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
|
NTSTATUS FASTCALL Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
HANDLE Handle);
|
HANDLE Handle);
|
||||||
|
VOID FASTCALL Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData);
|
||||||
|
|
||||||
NTSTATUS NTAPI ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
NTSTATUS NTAPI ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
PCSR_PROCESS TargetProcess);
|
PCSR_PROCESS TargetProcess);
|
||||||
|
@ -160,7 +164,6 @@ NTSTATUS NTAPI ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
IN OUT PVOID ConnectionInfo,
|
IN OUT PVOID ConnectionInfo,
|
||||||
IN OUT PULONG ConnectionInfoLength);
|
IN OUT PULONG ConnectionInfoLength);
|
||||||
VOID NTAPI ConsoleDisconnect(PCSR_PROCESS Process);
|
VOID NTAPI ConsoleDisconnect(PCSR_PROCESS Process);
|
||||||
VOID NTAPI Win32CsrReleaseConsole(PCSR_PROCESS Process);
|
|
||||||
|
|
||||||
/* lineinput.c */
|
/* lineinput.c */
|
||||||
CSR_API(SrvGetConsoleCommandHistoryLength);
|
CSR_API(SrvGetConsoleCommandHistoryLength);
|
||||||
|
|
|
@ -79,6 +79,85 @@ Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FASTCALL
|
||||||
|
Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||||
|
IN PCONSOLE_PROCESS_DATA TargetProcessData)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
/* Inherit a handles table only if there is no already */
|
||||||
|
if (TargetProcessData->HandleTable != NULL /* || TargetProcessData->HandleTableSize != 0 */)
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL; /* STATUS_INVALID_PARAMETER */
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new handle table for the child process */
|
||||||
|
TargetProcessData->HandleTable = RtlAllocateHeap(ConSrvHeap,
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
SourceProcessData->HandleTableSize
|
||||||
|
* sizeof(CONSOLE_IO_HANDLE));
|
||||||
|
if (TargetProcessData->HandleTable == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the parent process' handles table and, for each handle,
|
||||||
|
* do a copy of it and reference it, if the handle is inheritable.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
|
||||||
|
{
|
||||||
|
if (SourceProcessData->HandleTable[i].Object != NULL &&
|
||||||
|
SourceProcessData->HandleTable[i].Inheritable)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Copy the handle data and increment the reference count of the
|
||||||
|
* pointed object (via the call to Win32CsrCreateHandleEntry).
|
||||||
|
*/
|
||||||
|
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
|
||||||
|
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
|
{
|
||||||
|
DPRINT1("Win32CsrFreeHandlesTable\n");
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
if (ProcessData->HandleTable != NULL)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Close all console handles and free the handle table memory */
|
||||||
|
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||||
|
{
|
||||||
|
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||||
|
}
|
||||||
|
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
||||||
|
ProcessData->HandleTable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessData->HandleTableSize = 0;
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
FASTCALL
|
FASTCALL
|
||||||
Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
|
@ -122,7 +201,8 @@ Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
ProcessData->HandleTable[i].Inheritable = Inheritable;
|
ProcessData->HandleTable[i].Inheritable = Inheritable;
|
||||||
ProcessData->HandleTable[i].ShareMode = ShareMode;
|
ProcessData->HandleTable[i].ShareMode = ShareMode;
|
||||||
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
|
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
|
||||||
*Handle = UlongToHandle((i << 2) | 0x3);
|
*Handle = ULongToHandle((i << 2) | 0x3);
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -202,9 +282,33 @@ Win32CsrUnlockObject(Object_t *Object)
|
||||||
Win32CsrUnlockConsole(Object->Console);
|
Win32CsrUnlockConsole(Object->Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
|
{
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
DPRINT1("Win32CsrReleaseConsole\n");
|
||||||
|
|
||||||
|
/* Close all console handles and free the handle table memory */
|
||||||
|
Win32CsrFreeHandlesTable(ProcessData);
|
||||||
|
|
||||||
|
/* Detach process from console */
|
||||||
|
Console = ProcessData->Console;
|
||||||
|
if (Console != NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Win32CsrReleaseConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
|
||||||
|
ProcessData->Console = NULL;
|
||||||
|
EnterCriticalSection(&Console->Lock);
|
||||||
|
RemoveEntryList(&ProcessData->ConsoleLink);
|
||||||
|
Win32CsrUnlockConsole(Console);
|
||||||
|
//CloseHandle(ProcessData->ConsoleEvent);
|
||||||
|
//ProcessData->ConsoleEvent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Remark: this function can be called by SrvAttachConsole (not yet implemented) **/
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
|
@ -223,7 +327,6 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
DPRINT1("ConsoleNewProcess inside\n");
|
DPRINT1("ConsoleNewProcess inside\n");
|
||||||
DPRINT1("SourceProcess = 0x%p ; TargetProcess = 0x%p\n", SourceProcess, TargetProcess);
|
DPRINT1("SourceProcess = 0x%p ; TargetProcess = 0x%p\n", SourceProcess, TargetProcess);
|
||||||
|
@ -243,14 +346,13 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
TargetProcessData->Process = TargetProcess;
|
TargetProcessData->Process = TargetProcess;
|
||||||
TargetProcessData->ConsoleEvent = NULL;
|
TargetProcessData->ConsoleEvent = NULL;
|
||||||
TargetProcessData->Console = TargetProcessData->ParentConsole = NULL;
|
TargetProcessData->Console = TargetProcessData->ParentConsole = NULL;
|
||||||
// TargetProcessData->bInheritHandles = FALSE;
|
|
||||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
TargetProcessData->HandleTableSize = 0;
|
TargetProcessData->HandleTableSize = 0;
|
||||||
TargetProcessData->HandleTable = NULL;
|
TargetProcessData->HandleTable = NULL;
|
||||||
|
|
||||||
/* HACK */ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
|
/**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
|
||||||
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
|
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
|
||||||
|
|
||||||
/* Do nothing if the source process is NULL */
|
/* Do nothing if the source process is NULL */
|
||||||
|
@ -267,51 +369,17 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
if ( SourceProcessData->Console != NULL && /* SourceProcessData->ConsoleApp */
|
if ( SourceProcessData->Console != NULL && /* SourceProcessData->ConsoleApp */
|
||||||
TargetProcessData->ConsoleApp )
|
TargetProcessData->ConsoleApp )
|
||||||
{
|
{
|
||||||
/*
|
NTSTATUS Status;
|
||||||
if (TargetProcessData->HandleTableSize)
|
|
||||||
{
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
DPRINT1("ConsoleNewProcess - Copy the handle table (1)\n");
|
Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Do it before, or after the handles table inheritance ??
|
||||||
/* Temporary "inherit" the console from the parent */
|
/* Temporary "inherit" the console from the parent */
|
||||||
TargetProcessData->ParentConsole = SourceProcessData->Console;
|
TargetProcessData->ParentConsole = SourceProcessData->Console;
|
||||||
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
|
|
||||||
DPRINT1("ConsoleNewProcess - Copy the handle table (2)\n");
|
|
||||||
|
|
||||||
/* Allocate a new handle table for the child process */
|
|
||||||
TargetProcessData->HandleTable = RtlAllocateHeap(ConSrvHeap,
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
SourceProcessData->HandleTableSize
|
|
||||||
* sizeof(CONSOLE_IO_HANDLE));
|
|
||||||
if (TargetProcessData->HandleTable == NULL)
|
|
||||||
{
|
|
||||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse the parent process' handles table and, for each handle,
|
|
||||||
* do a copy of it and reference it, if the handle is inheritable.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
|
|
||||||
{
|
|
||||||
if (SourceProcessData->HandleTable[i].Object != NULL &&
|
|
||||||
SourceProcessData->HandleTable[i].Inheritable)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Copy the handle data and increment the reference count of the
|
|
||||||
* pointed object (via the call to Win32CsrCreateHandleEntry).
|
|
||||||
*/
|
|
||||||
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
|
|
||||||
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -335,7 +403,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
|
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||||
BOOLEAN NewConsole = FALSE;
|
BOOLEAN NewConsole = FALSE;
|
||||||
// PCONSOLE Console = NULL;
|
|
||||||
|
|
||||||
DPRINT1("ConsoleConnect\n");
|
DPRINT1("ConsoleConnect\n");
|
||||||
|
|
||||||
|
@ -354,21 +421,30 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
|
|
||||||
/* If we don't have a console, then create a new one... */
|
/* If we don't have a console, then create a new one... */
|
||||||
if (!ConnectInfo->Console ||
|
if (!ConnectInfo->Console ||
|
||||||
ConnectInfo->Console != ProcessData->ParentConsole)
|
ConnectInfo->Console != ProcessData->ParentConsole)
|
||||||
{
|
{
|
||||||
DPRINT1("ConsoleConnect - Allocate a new console\n");
|
DPRINT1("ConsoleConnect - Allocate a new console\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are about to create a new console. However when ConsoleNewProcess
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
|
||||||
/* Initialize a new Console owned by the Console Leader Process */
|
/* Initialize a new Console owned by the Console Leader Process */
|
||||||
NewConsole = TRUE;
|
NewConsole = TRUE;
|
||||||
Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
|
Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console initialization failed\n");
|
DPRINT1("Console initialization failed\n");
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,42 +457,23 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
ProcessData->Console = ConnectInfo->Console;
|
ProcessData->Console = ConnectInfo->Console;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a reference count because the process is tied to the console */
|
||||||
|
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
||||||
|
|
||||||
/* Insert the process into the processes list of the console */
|
/* Insert the process into the processes list of the console */
|
||||||
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
|
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
|
||||||
|
|
||||||
/* Return it to the caller */
|
/* Return it to the caller */
|
||||||
ConnectInfo->Console = ProcessData->Console;
|
ConnectInfo->Console = ProcessData->Console;
|
||||||
|
|
||||||
/* Add a reference count because the process is tied to the console */
|
if (NewConsole)
|
||||||
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
|
||||||
|
|
||||||
if (NewConsole /* || !ProcessData->bInheritHandles */)
|
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* We've just created a new console. However when ConsoleNewProcess 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 our handles table and recreate a new one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
/* Close all console handles and free the handle table memory */
|
|
||||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
|
||||||
{
|
|
||||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
|
||||||
}
|
|
||||||
ProcessData->HandleTableSize = 0;
|
|
||||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
|
||||||
ProcessData->HandleTable = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new handle table - Insert the IO handles
|
* Create a new handle table - Insert the IO handles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
/* Insert the Input handle */
|
/* Insert the Input handle */
|
||||||
Status = Win32CsrInsertObject(ProcessData,
|
Status = Win32CsrInsertObject(ProcessData,
|
||||||
&ConnectInfo->InputHandle,
|
&ConnectInfo->InputHandle,
|
||||||
|
@ -427,9 +484,10 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the input handle\n");
|
DPRINT1("Failed to insert the input handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,11 +501,12 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the output handle\n");
|
DPRINT1("Failed to insert the output handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
ConnectInfo->InputHandle);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// ConnectInfo->InputHandle);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,15 +520,18 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to insert the error handle\n");
|
DPRINT1("Failed to insert the error handle\n");
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
ConnectInfo->OutputHandle);
|
|
||||||
Win32CsrReleaseObject(ProcessData,
|
|
||||||
ConnectInfo->InputHandle);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// ConnectInfo->OutputHandle);
|
||||||
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
|
// ConnectInfo->InputHandle);
|
||||||
|
// ConioDeleteConsole(ProcessData->Console);
|
||||||
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the Event */
|
/* Duplicate the Event */
|
||||||
|
@ -481,18 +543,18 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||||
ConioDeleteConsole(ProcessData->Console);
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
if (NewConsole /* || !ProcessData->bInheritHandles */)
|
// if (NewConsole)
|
||||||
{
|
// {
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
ConnectInfo->ErrorHandle);
|
// ConnectInfo->ErrorHandle);
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
ConnectInfo->OutputHandle);
|
// ConnectInfo->OutputHandle);
|
||||||
Win32CsrReleaseObject(ProcessData,
|
// Win32CsrReleaseObject(ProcessData,
|
||||||
ConnectInfo->InputHandle);
|
// ConnectInfo->InputHandle);
|
||||||
}
|
// }
|
||||||
ProcessData->Console = NULL;
|
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
// ProcessData->Console = NULL;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
/* Input Wait Handle */
|
/* Input Wait Handle */
|
||||||
|
@ -500,49 +562,11 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
|
|
||||||
/* Set the Ctrl Dispatcher */
|
/* Set the Ctrl Dispatcher */
|
||||||
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
|
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
|
||||||
DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
WINAPI
|
|
||||||
Win32CsrReleaseConsole(PCSR_PROCESS Process)
|
|
||||||
{
|
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
|
|
||||||
PCONSOLE Console;
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
DPRINT1("Win32CsrReleaseConsole\n");
|
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
|
|
||||||
/* Close all console handles and free the handle table memory */
|
|
||||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
|
||||||
{
|
|
||||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
|
||||||
}
|
|
||||||
ProcessData->HandleTableSize = 0;
|
|
||||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
|
||||||
ProcessData->HandleTable = NULL;
|
|
||||||
|
|
||||||
/* Detach process from console */
|
|
||||||
Console = ProcessData->Console;
|
|
||||||
if (Console != NULL)
|
|
||||||
{
|
|
||||||
DPRINT1("Win32CsrReleaseConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
|
|
||||||
ProcessData->Console = NULL;
|
|
||||||
EnterCriticalSection(&Console->Lock);
|
|
||||||
RemoveEntryList(&ProcessData->ConsoleLink);
|
|
||||||
Win32CsrUnlockConsole(Console);
|
|
||||||
//CloseHandle(ProcessData->ConsoleEvent);
|
|
||||||
//ProcessData->ConsoleEvent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
WINAPI
|
WINAPI
|
||||||
ConsoleDisconnect(PCSR_PROCESS Process)
|
ConsoleDisconnect(PCSR_PROCESS Process)
|
||||||
|
@ -551,19 +575,14 @@ ConsoleDisconnect(PCSR_PROCESS Process)
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
||||||
*
|
|
||||||
* Only do something if the process is a CUI. <-- modify this behaviour if
|
|
||||||
* we deal with a GUI which
|
|
||||||
* quits and acquired a
|
|
||||||
* console...
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
DPRINT1("ConsoleDisconnect called\n");
|
DPRINT1("ConsoleDisconnect called\n");
|
||||||
// if (ProcessData->Console != NULL)
|
if ( ProcessData->Console != NULL ||
|
||||||
if (ProcessData->ConsoleApp)
|
ProcessData->HandleTable != NULL )
|
||||||
{
|
{
|
||||||
DPRINT1("ConsoleDisconnect - calling Win32CsrReleaseConsole\n");
|
DPRINT1("ConsoleDisconnect - calling Win32CsrReleaseConsole\n");
|
||||||
Win32CsrReleaseConsole(Process);
|
Win32CsrReleaseConsole(ProcessData);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
|
@ -107,7 +107,7 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber] =
|
||||||
// SrvRegisterConsoleIME,
|
// SrvRegisterConsoleIME,
|
||||||
// SrvUnregisterConsoleIME,
|
// SrvUnregisterConsoleIME,
|
||||||
// SrvGetConsoleLangId,
|
// SrvGetConsoleLangId,
|
||||||
// SrvAttachConsole,
|
SrvAttachConsole,
|
||||||
SrvGetConsoleSelectionInfo,
|
SrvGetConsoleSelectionInfo,
|
||||||
SrvGetConsoleProcessList,
|
SrvGetConsoleProcessList,
|
||||||
SrvGetConsoleHistory,
|
SrvGetConsoleHistory,
|
||||||
|
@ -198,7 +198,7 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] =
|
||||||
// FALSE, // SrvRegisterConsoleIME,
|
// FALSE, // SrvRegisterConsoleIME,
|
||||||
// FALSE, // SrvUnregisterConsoleIME,
|
// FALSE, // SrvUnregisterConsoleIME,
|
||||||
// FALSE, // SrvGetConsoleLangId,
|
// FALSE, // SrvGetConsoleLangId,
|
||||||
// FALSE, // SrvAttachConsole,
|
FALSE, // SrvAttachConsole,
|
||||||
FALSE, // SrvGetConsoleSelectionInfo,
|
FALSE, // SrvGetConsoleSelectionInfo,
|
||||||
FALSE, // SrvGetConsoleProcessList,
|
FALSE, // SrvGetConsoleProcessList,
|
||||||
FALSE, // SrvGetConsoleHistory,
|
FALSE, // SrvGetConsoleHistory,
|
||||||
|
@ -291,7 +291,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber] =
|
||||||
// "RegisterConsoleIME",
|
// "RegisterConsoleIME",
|
||||||
// "UnregisterConsoleIME",
|
// "UnregisterConsoleIME",
|
||||||
// "GetConsoleLangId",
|
// "GetConsoleLangId",
|
||||||
// "AttachConsole",
|
"AttachConsole",
|
||||||
"GetConsoleSelectionInfo",
|
"GetConsoleSelectionInfo",
|
||||||
"GetConsoleProcessList",
|
"GetConsoleProcessList",
|
||||||
"GetConsoleHistory",
|
"GetConsoleHistory",
|
||||||
|
|
Loading…
Reference in a new issue