Introduce new helper functions Win32CsrInitHandlesTable and Win32CsrAllocateConsole and use them in many places (in ConsoleConnect, SrvAllocConsole and SrvAttachConsole).

svn path=/branches/ros-csrss/; revision=58184
This commit is contained in:
Hermès Bélusca-Maïto 2013-01-16 22:25:12 +00:00
parent 573e7edb6f
commit 44782833a8
5 changed files with 177 additions and 193 deletions

View file

@ -210,7 +210,7 @@ IntCheckForConsoleFileName(IN LPCWSTR pszName,
DeviceNameInfo = RtlIsDosDeviceName_U(pszName);
if (DeviceNameInfo != 0)
{
ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + (ULONG_PTR)((DeviceNameInfo >> 16) & 0xFFFF));
ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF));
}
/* Return a standard console "file" name according to what we passed in parameters */

View file

@ -255,7 +255,7 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
current_entry = current_entry->Flink;
ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
ConioConsoleCtrlEvent(CTRL_C_EVENT, current);
}
if (Console->LineBuffer && !Console->LineComplete)
{

View file

@ -308,7 +308,6 @@ CSR_API(SrvAllocConsole)
/** This comes from ConsoleConnect!! **/
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
@ -321,13 +320,17 @@ CSR_API(SrvAllocConsole)
*/
Win32CsrReleaseConsole(ProcessData);
// Win32CsrFreeHandlesTable(ProcessData);
#endif
/* Initialize a new Console owned by the Console Leader Process */
Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
Status = Win32CsrAllocateConsole(ProcessData,
&AllocConsoleRequest->InputHandle,
&AllocConsoleRequest->OutputHandle,
&AllocConsoleRequest->ErrorHandle,
AllocConsoleRequest->ShowCmd,
ConsoleLeader);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
DPRINT1("Console allocation failed\n");
return Status;
}
@ -337,75 +340,6 @@ CSR_API(SrvAllocConsole)
/* Insert the process into the processes list of the console */
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
/* Return it to the caller */
AllocConsoleRequest->Console = ProcessData->Console;
/*
* Create a new handle table - Insert the IO handles
*/
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
/* Insert the Input handle */
Status = Win32CsrInsertObject(ProcessData,
&AllocConsoleRequest->InputHandle,
&ProcessData->Console->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the input handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
/* Insert the Output handle */
Status = Win32CsrInsertObject(ProcessData,
&AllocConsoleRequest->OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the output handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->InputHandle);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
/* Insert the Error handle */
Status = Win32CsrInsertObject(ProcessData,
&AllocConsoleRequest->ErrorHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the error handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->OutputHandle);
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->InputHandle);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
/* Duplicate the Event */
Status = NtDuplicateObject(NtCurrentProcess(),
ProcessData->Console->ActiveEvent,
@ -416,19 +350,12 @@ CSR_API(SrvAllocConsole)
{
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
Win32CsrReleaseConsole(ProcessData);
// if (NewConsole)
// {
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->ErrorHandle);
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->OutputHandle);
// Win32CsrReleaseObject(ProcessData,
// AllocConsoleRequest->InputHandle);
// }
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
// ProcessData->Console = NULL;
return Status;
}
/* Return it to the caller */
AllocConsoleRequest->Console = ProcessData->Console;
/* Input Wait Handle */
AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent;
@ -492,6 +419,19 @@ CSR_API(SrvAttachConsole)
/** This comes from ConsoleNewProcess!! **/
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
/*
* 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(TargetProcessData);
// Win32CsrFreeHandlesTable(TargetProcessData);
/*
* Inherit the console from the parent,
* if any, otherwise return an error.
@ -504,11 +444,18 @@ CSR_API(SrvAttachConsole)
}
TargetProcessData->Console = SourceProcessData->Console;
DPRINT1("SrvAttachConsole - Copy the handle table (1)\n");
Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
DPRINT1("SrvAttachConsole - Copy the handle table (2)\n");
/// REMARK: This code comes from Win32CsrAllocateConsole.
/* Initialize the handles table */
Status = Win32CsrInitHandlesTable(TargetProcessData,
&AttachConsoleRequest->InputHandle,
&AttachConsoleRequest->OutputHandle,
&AttachConsoleRequest->ErrorHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize the handles table\n");
// Win32CsrReleaseConsole(TargetProcessData);
TargetProcessData->Console = NULL;
goto Quit;
}
@ -522,9 +469,6 @@ CSR_API(SrvAttachConsole)
/* 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. **/
@ -540,21 +484,12 @@ CSR_API(SrvAttachConsole)
{
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;
}
/* Return it to the caller */
AttachConsoleRequest->Console = TargetProcessData->Console;
/* Input Wait Handle */
AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;

View file

@ -140,6 +140,10 @@ CSR_API(SrvVerifyConsoleIoHandle);
CSR_API(SrvDuplicateHandle);
/// CSR_API(CsrGetInputWaitHandle);
NTSTATUS FASTCALL Win32CsrInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
OUT PHANDLE pInputHandle,
OUT PHANDLE pOutputHandle,
OUT PHANDLE pErrorHandle);
NTSTATUS FASTCALL Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
IN PCONSOLE_PROCESS_DATA TargetProcessData);
VOID FASTCALL Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData);
@ -157,6 +161,13 @@ NTSTATUS FASTCALL Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData,
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
NTSTATUS FASTCALL Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle);
NTSTATUS FASTCALL Win32CsrAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
int ShowCmd,
PCSR_PROCESS CsrProcess);
VOID FASTCALL Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS NTAPI ConsoleNewProcess(PCSR_PROCESS SourceProcess,

View file

@ -79,6 +79,82 @@ Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
/* FUNCTIONS *****************************************************************/
/* static */ NTSTATUS
FASTCALL
Win32CsrInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
OUT PHANDLE pInputHandle,
OUT PHANDLE pOutputHandle,
OUT PHANDLE pErrorHandle)
{
NTSTATUS Status;
HANDLE InputHandle = INVALID_HANDLE_VALUE,
OutputHandle = INVALID_HANDLE_VALUE,
ErrorHandle = INVALID_HANDLE_VALUE;
/*
* Initialize the handles table. Use temporary variables to store
* the handles values in such a way that, if we fail, we don't
* return to the caller invalid handle values.
*
* Insert the IO handles.
*/
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
/* Insert the Input handle */
Status = Win32CsrInsertObject(ProcessData,
&InputHandle,
&ProcessData->Console->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the input handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrFreeHandlesTable(ProcessData);
return Status;
}
/* Insert the Output handle */
Status = Win32CsrInsertObject(ProcessData,
&OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the output handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrFreeHandlesTable(ProcessData);
return Status;
}
/* Insert the Error handle */
Status = Win32CsrInsertObject(ProcessData,
&ErrorHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the error handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrFreeHandlesTable(ProcessData);
return Status;
}
/* Return the newly created handles */
*pInputHandle = InputHandle;
*pOutputHandle = OutputHandle;
*pErrorHandle = ErrorHandle;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
NTSTATUS
FASTCALL
Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
@ -282,6 +358,44 @@ Win32CsrUnlockObject(Object_t *Object)
Win32CsrUnlockConsole(Object->Console);
}
NTSTATUS
FASTCALL
Win32CsrAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
int ShowCmd,
PCSR_PROCESS CsrProcess)
{
NTSTATUS Status = STATUS_SUCCESS;
/* Initialize a new Console owned by the Console Leader Process */
Status = CsrInitConsole(&ProcessData->Console, ShowCmd, CsrProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
return Status;
}
/* Initialize the handles table */
Status = Win32CsrInitHandlesTable(ProcessData,
pInputHandle,
pOutputHandle,
pErrorHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize the handles table\n");
// Win32CsrReleaseConsole(ProcessData);
ConioDeleteConsole(ProcessData->Console);
ProcessData->Console = NULL;
return Status;
}
return Status;
}
VOID
FASTCALL
Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData)
@ -377,7 +491,6 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
return Status;
}
// FIXME: Do it before, or after the handles table inheritance ??
/* Temporary "inherit" the console from the parent */
TargetProcessData->ParentConsole = SourceProcessData->Console;
}
@ -402,7 +515,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
BOOLEAN NewConsole = FALSE;
DPRINT1("ConsoleConnect\n");
@ -440,11 +552,15 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
Win32CsrReleaseConsole(ProcessData);
/* Initialize a new Console owned by the Console Leader Process */
NewConsole = TRUE;
Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
Status = Win32CsrAllocateConsole(ProcessData,
&ConnectInfo->InputHandle,
&ConnectInfo->OutputHandle,
&ConnectInfo->ErrorHandle,
ConnectInfo->ShowCmd,
CsrProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
DPRINT1("Console allocation failed\n");
return Status;
}
}
@ -453,7 +569,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
DPRINT1("ConsoleConnect - Reuse current (parent's) console\n");
/* Reuse our current console */
NewConsole = FALSE;
ProcessData->Console = ConnectInfo->Console;
}
@ -463,77 +578,7 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
/* Insert the process into the processes list of the console */
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
/* Return it to the caller */
ConnectInfo->Console = ProcessData->Console;
if (NewConsole)
{
/*
* Create a new handle table - Insert the IO handles
*/
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
/* Insert the Input handle */
Status = Win32CsrInsertObject(ProcessData,
&ConnectInfo->InputHandle,
&ProcessData->Console->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the input handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
/* Insert the Output handle */
Status = Win32CsrInsertObject(ProcessData,
&ConnectInfo->OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the output handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->InputHandle);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
/* Insert the Error handle */
Status = Win32CsrInsertObject(ProcessData,
&ConnectInfo->ErrorHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the error handle\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Win32CsrReleaseConsole(ProcessData);
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->OutputHandle);
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->InputHandle);
// ConioDeleteConsole(ProcessData->Console);
// ProcessData->Console = NULL;
return Status;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
}
/// TODO: Move this up ?
/* Duplicate the Event */
Status = NtDuplicateObject(NtCurrentProcess(),
ProcessData->Console->ActiveEvent,
@ -544,19 +589,12 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
{
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
Win32CsrReleaseConsole(ProcessData);
// if (NewConsole)
// {
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->ErrorHandle);
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->OutputHandle);
// Win32CsrReleaseObject(ProcessData,
// ConnectInfo->InputHandle);
// }
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
// ProcessData->Console = NULL;
return Status;
}
/* Return it to the caller */
ConnectInfo->Console = ProcessData->Console;
/* Input Wait Handle */
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;