From 44782833a864cb188841ce56ebaef194cc4e98c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 16 Jan 2013 22:25:12 +0000 Subject: [PATCH] [CONSRV] 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 --- dll/win32/kernel32/client/console/console.c | 2 +- win32ss/user/consrv/coninput.c | 2 +- win32ss/user/consrv/console.c | 141 ++++--------- win32ss/user/consrv/consrv.h | 11 + win32ss/user/consrv/handle.c | 214 ++++++++++++-------- 5 files changed, 177 insertions(+), 193 deletions(-) diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index 983440953b8..84c8d9a88f0 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -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 */ diff --git a/win32ss/user/consrv/coninput.c b/win32ss/user/consrv/coninput.c index 8b4e3b89f99..617ffef4cff 100644 --- a/win32ss/user/consrv/coninput.c +++ b/win32ss/user/consrv/coninput.c @@ -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) { diff --git a/win32ss/user/consrv/console.c b/win32ss/user/consrv/console.c index ee63a6cd72c..eff26925320 100644 --- a/win32ss/user/consrv/console.c +++ b/win32ss/user/consrv/console.c @@ -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; diff --git a/win32ss/user/consrv/consrv.h b/win32ss/user/consrv/consrv.h index 3d73cde96ce..97d115fafa0 100644 --- a/win32ss/user/consrv/consrv.h +++ b/win32ss/user/consrv/consrv.h @@ -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, diff --git a/win32ss/user/consrv/handle.c b/win32ss/user/consrv/handle.c index eddb4b83eca..8787bae78a4 100644 --- a/win32ss/user/consrv/handle.c +++ b/win32ss/user/consrv/handle.c @@ -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;