https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c05df38e86217cb00cd2e…
commit c05df38e86217cb00cd2e904d36ccdcea3de1b31
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Apr 13 23:24:55 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Apr 14 01:19:48 2020 +0200
[CONSRV] Move process-initialization-specific functions from handle.c into console.c .
- Move ConSrvInitHandlesTable() & rename it ConSrvInitProcessHandles()
since its purpose is to initialize the standard input, output and
error handles for a console process.
- Move ConSrvAllocateConsole(), ConSrvInheritConsole() and
ConSrvRemoveConsole().
---
win32ss/user/winsrv/consrv/console.c | 420 +++++++++++++++++++++++++++++++++
win32ss/user/winsrv/consrv/handle.c | 422 +---------------------------------
win32ss/user/winsrv/consrv/handle.h | 8 +
win32ss/user/winsrv/consrv/init.c | 5 -
win32ss/user/winsrv/consrv/procinit.h | 34 +--
5 files changed, 450 insertions(+), 439 deletions(-)
diff --git a/win32ss/user/winsrv/consrv/console.c b/win32ss/user/winsrv/consrv/console.c
index 12351a8b18c..1e35fdea127 100644
--- a/win32ss/user/winsrv/consrv/console.c
+++ b/win32ss/user/winsrv/consrv/console.c
@@ -551,6 +551,11 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
*NewConsole = NULL;
+ DPRINT("Initialization of console '%S' for process '%S' on desktop '%S'\n",
+ ConsoleInitInfo->ConsoleTitle ? ConsoleInitInfo->ConsoleTitle : L"n/a",
+ ConsoleInitInfo->AppName ? ConsoleInitInfo->AppName : L"n/a",
+ ConsoleInitInfo->Desktop ? ConsoleInitInfo->Desktop : L"n/a");
+
/*
* Load the console settings
*/
@@ -879,6 +884,421 @@ ConioUnpause(PCONSRV_CONSOLE Console, UCHAR Flags)
}
+/* CONSOLE PROCESS INITIALIZATION FUNCTIONS ***********************************/
+
+static NTSTATUS
+ConSrvInitProcessHandles(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+ IN PCONSRV_CONSOLE Console,
+ 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 process handles. 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 = ConSrvInsertObject(ProcessData,
+ &InputHandle,
+ &Console->InputBuffer.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);
+ ConSrvFreeHandlesTable(ProcessData);
+ return Status;
+ }
+
+ /* Insert the Output handle */
+ Status = ConSrvInsertObject(ProcessData,
+ &OutputHandle,
+ &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);
+ ConSrvFreeHandlesTable(ProcessData);
+ return Status;
+ }
+
+ /* Insert the Error handle */
+ Status = ConSrvInsertObject(ProcessData,
+ &ErrorHandle,
+ &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);
+ ConSrvFreeHandlesTable(ProcessData);
+ return Status;
+ }
+
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+
+ /* Return the newly created handles */
+ *pInputHandle = InputHandle;
+ *pOutputHandle = OutputHandle;
+ *pErrorHandle = ErrorHandle;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ConSrvAllocateConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+ OUT PHANDLE pInputHandle,
+ OUT PHANDLE pOutputHandle,
+ OUT PHANDLE pErrorHandle,
+ IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ HANDLE ConsoleHandle;
+ PCONSRV_CONSOLE Console;
+
+ /*
+ * 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 handle 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 handle table so that we can recreate
+ * a new one later on.
+ */
+ ConSrvFreeHandlesTable(ProcessData);
+
+ /* Initialize a new Console owned by this process */
+ Status = ConSrvInitConsole(&ConsoleHandle,
+ &Console,
+ ConsoleInitInfo,
+ ProcessData->Process);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Console initialization failed\n");
+ return Status;
+ }
+
+ /* Assign the new console handle */
+ ProcessData->ConsoleHandle = ConsoleHandle;
+
+ /* Initialize the process handles */
+ Status = ConSrvInitProcessHandles(ProcessData,
+ Console,
+ pInputHandle,
+ pOutputHandle,
+ pErrorHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to initialize the process handles\n");
+ ConSrvDeleteConsole(Console);
+ ProcessData->ConsoleHandle = NULL;
+ return Status;
+ }
+
+ /* Duplicate the Initialization Events */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InitEvents[INIT_SUCCESS],
+ ProcessData->Process->ProcessHandle,
+ &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
+ ConSrvFreeHandlesTable(ProcessData);
+ ConSrvDeleteConsole(Console);
+ ProcessData->ConsoleHandle = NULL;
+ return Status;
+ }
+
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InitEvents[INIT_FAILURE],
+ ProcessData->Process->ProcessHandle,
+ &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ ConSrvFreeHandlesTable(ProcessData);
+ ConSrvDeleteConsole(Console);
+ ProcessData->ConsoleHandle = NULL;
+ return Status;
+ }
+
+ /* Duplicate the Input Event */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InputBuffer.ActiveEvent,
+ ProcessData->Process->ProcessHandle,
+ &ConsoleInitInfo->ConsoleStartInfo->InputWaitHandle,
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ ConSrvFreeHandlesTable(ProcessData);
+ ConSrvDeleteConsole(Console);
+ ProcessData->ConsoleHandle = NULL;
+ return Status;
+ }
+
+ /* Mark the process as having a console */
+ ProcessData->ConsoleApp = TRUE;
+ ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
+
+ /* Return the console handle to the caller */
+ ConsoleInitInfo->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
+
+ /*
+ * Insert the process into the processes list of the console,
+ * and set its foreground priority.
+ */
+ InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
+ ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
+
+ /* Add a reference count because the process is tied to the console */
+ _InterlockedIncrement(&Console->ReferenceCount);
+
+ /* Update the internal info of the terminal */
+ TermRefreshInternalInfo(Console);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ConSrvInheritConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+ IN HANDLE ConsoleHandle,
+ IN BOOLEAN CreateNewHandleTable,
+ OUT PHANDLE pInputHandle,
+ OUT PHANDLE pOutputHandle,
+ OUT PHANDLE pErrorHandle,
+ IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PCONSRV_CONSOLE Console;
+
+ /* Validate and lock the console */
+ if (!ConSrvValidateConsole(&Console,
+ ConsoleHandle,
+ CONSOLE_RUNNING, TRUE))
+ {
+ // FIXME: Find another status code
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Inherit the console */
+ ProcessData->ConsoleHandle = ConsoleHandle;
+
+ if (CreateNewHandleTable)
+ {
+ /*
+ * 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 handle 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 handle table so that we can recreate
+ * a new one later on.
+ */
+ ConSrvFreeHandlesTable(ProcessData);
+
+ /* Initialize the process handles */
+ Status = ConSrvInitProcessHandles(ProcessData,
+ Console,
+ pInputHandle,
+ pOutputHandle,
+ pErrorHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to initialize the process handles\n");
+ ProcessData->ConsoleHandle = NULL;
+ goto Quit;
+ }
+ }
+
+ /* Duplicate the Initialization Events */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InitEvents[INIT_SUCCESS],
+ ProcessData->Process->ProcessHandle,
+ &ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
+ ConSrvFreeHandlesTable(ProcessData);
+ ProcessData->ConsoleHandle = NULL;
+ goto Quit;
+ }
+
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InitEvents[INIT_FAILURE],
+ ProcessData->Process->ProcessHandle,
+ &ConsoleStartInfo->InitEvents[INIT_FAILURE],
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ ConSrvFreeHandlesTable(ProcessData);
+ ProcessData->ConsoleHandle = NULL;
+ goto Quit;
+ }
+
+ /* Duplicate the Input Event */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ Console->InputBuffer.ActiveEvent,
+ ProcessData->Process->ProcessHandle,
+ &ConsoleStartInfo->InputWaitHandle,
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleStartInfo->InitEvents[INIT_FAILURE],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
+ ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handle table.
+ ProcessData->ConsoleHandle = NULL;
+ goto Quit;
+ }
+
+ /* Mark the process as having a console */
+ ProcessData->ConsoleApp = TRUE;
+ ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
+
+ /* Return the console handle to the caller */
+ ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
+
+ /*
+ * Insert the process into the processes list of the console,
+ * and set its foreground priority.
+ */
+ InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
+ ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
+
+ /* Add a reference count because the process is tied to the console */
+ _InterlockedIncrement(&Console->ReferenceCount);
+
+ /* Update the internal info of the terminal */
+ TermRefreshInternalInfo(Console);
+
+ Status = STATUS_SUCCESS;
+
+Quit:
+ /* Unlock the console and return */
+ LeaveCriticalSection(&Console->Lock);
+ return Status;
+}
+
+NTSTATUS
+ConSrvRemoveConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData)
+{
+ PCONSRV_CONSOLE Console;
+ PCONSOLE_PROCESS_DATA ConsoleLeaderProcess;
+
+ DPRINT("ConSrvRemoveConsole\n");
+
+ /* Mark the process as not having a console anymore */
+ ProcessData->ConsoleApp = FALSE;
+ ProcessData->Process->Flags &= ~CsrProcessIsConsoleApp;
+
+ /* Validate and lock the console */
+ if (!ConSrvValidateConsole(&Console,
+ ProcessData->ConsoleHandle,
+ CONSOLE_RUNNING, TRUE))
+ {
+ // FIXME: Find another status code
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DPRINT("ConSrvRemoveConsole - Locking OK\n");
+
+ /* Retrieve the console leader process */
+ ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
+
+ /* Close all console handles and free the handle table */
+ ConSrvFreeHandlesTable(ProcessData);
+
+ /* Detach the process from the console */
+ ProcessData->ConsoleHandle = NULL;
+
+ /* Remove the process from the console's list of processes */
+ RemoveEntryList(&ProcessData->ConsoleLink);
+
+ /* Check whether the console should send a last close notification */
+ if (Console->NotifyLastClose)
+ {
+ /* If we are removing the process which wants the last close notification... */
+ if (ProcessData == Console->NotifiedLastCloseProcess)
+ {
+ /* ... just reset the flag and the pointer... */
+ Console->NotifyLastClose = FALSE;
+ Console->NotifiedLastCloseProcess = NULL;
+ }
+ /*
+ * ... otherwise, if we are removing the console leader process
+ * (that cannot be the process wanting the notification, because
+ * the previous case already dealt with it)...
+ */
+ else if (ProcessData == ConsoleLeaderProcess)
+ {
+ /*
+ * ... reset the flag first (so that we avoid multiple notifications)
+ * and then send the last close notification.
+ */
+ Console->NotifyLastClose = FALSE;
+ ConSrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
+
+ /* Only now, reset the pointer */
+ Console->NotifiedLastCloseProcess = NULL;
+ }
+ }
+
+ /* Update the internal info of the terminal */
+ TermRefreshInternalInfo(Console);
+
+ /* Release the console */
+ DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
+ ConSrvReleaseConsole(Console, TRUE);
+
+ return STATUS_SUCCESS;
+}
+
+
/* CONSOLE PROCESS MANAGEMENT FUNCTIONS ***************************************/
NTSTATUS
diff --git a/win32ss/user/winsrv/consrv/handle.c b/win32ss/user/winsrv/consrv/handle.c
index 007533583dc..ec1afc9f6cf 100644
--- a/win32ss/user/winsrv/consrv/handle.c
+++ b/win32ss/user/winsrv/consrv/handle.c
@@ -116,89 +116,6 @@ ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle)
}
-
-
-
-
-/* Forward declaration, used in ConSrvInitHandlesTable */
-static VOID ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData);
-
-static NTSTATUS
-ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
- IN PCONSRV_CONSOLE Console,
- 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 = ConSrvInsertObject(ProcessData,
- &InputHandle,
- &Console->InputBuffer.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);
- ConSrvFreeHandlesTable(ProcessData);
- return Status;
- }
-
- /* Insert the Output handle */
- Status = ConSrvInsertObject(ProcessData,
- &OutputHandle,
- &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);
- ConSrvFreeHandlesTable(ProcessData);
- return Status;
- }
-
- /* Insert the Error handle */
- Status = ConSrvInsertObject(ProcessData,
- &ErrorHandle,
- &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);
- ConSrvFreeHandlesTable(ProcessData);
- return Status;
- }
-
- /* Return the newly created handles */
- *pInputHandle = InputHandle;
- *pOutputHandle = OutputHandle;
- *pErrorHandle = ErrorHandle;
-
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_SUCCESS;
-}
-
NTSTATUS
ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
IN PCONSOLE_PROCESS_DATA TargetProcessData)
@@ -251,7 +168,7 @@ Quit:
return Status;
}
-static VOID
+VOID
ConSrvFreeHandlesTable(IN PCONSOLE_PROCESS_DATA ProcessData)
{
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
@@ -470,343 +387,6 @@ ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
}
-
-NTSTATUS
-ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
- PHANDLE pInputHandle,
- PHANDLE pOutputHandle,
- PHANDLE pErrorHandle,
- PCONSOLE_INIT_INFO ConsoleInitInfo)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- HANDLE ConsoleHandle;
- PCONSRV_CONSOLE Console;
-
- /*
- * 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 handles table so that we can recreate
- * a new one later on.
- */
- ConSrvFreeHandlesTable(ProcessData);
-
- /* Initialize a new Console owned by this process */
- DPRINT("Initialization of console '%S' for process '%S' on desktop '%S'\n",
- ConsoleInitInfo->ConsoleTitle ? ConsoleInitInfo->ConsoleTitle : L"n/a",
- ConsoleInitInfo->AppName ? ConsoleInitInfo->AppName : L"n/a",
- ConsoleInitInfo->Desktop ? ConsoleInitInfo->Desktop : L"n/a");
- Status = ConSrvInitConsole(&ConsoleHandle,
- &Console,
- ConsoleInitInfo,
- ProcessData->Process);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Console initialization failed\n");
- return Status;
- }
-
- /* Assign the new console handle */
- ProcessData->ConsoleHandle = ConsoleHandle;
-
- /* Initialize the handles table */
- Status = ConSrvInitHandlesTable(ProcessData,
- Console,
- pInputHandle,
- pOutputHandle,
- pErrorHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize the handles table\n");
- ConSrvDeleteConsole(Console);
- ProcessData->ConsoleHandle = NULL;
- return Status;
- }
-
- /* Duplicate the Initialization Events */
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InitEvents[INIT_SUCCESS],
- ProcessData->Process->ProcessHandle,
- &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
- ConSrvFreeHandlesTable(ProcessData);
- ConSrvDeleteConsole(Console);
- ProcessData->ConsoleHandle = NULL;
- return Status;
- }
-
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InitEvents[INIT_FAILURE],
- ProcessData->Process->ProcessHandle,
- &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- ConSrvFreeHandlesTable(ProcessData);
- ConSrvDeleteConsole(Console);
- ProcessData->ConsoleHandle = NULL;
- return Status;
- }
-
- /* Duplicate the Input Event */
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InputBuffer.ActiveEvent,
- ProcessData->Process->ProcessHandle,
- &ConsoleInitInfo->ConsoleStartInfo->InputWaitHandle,
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- ConSrvFreeHandlesTable(ProcessData);
- ConSrvDeleteConsole(Console);
- ProcessData->ConsoleHandle = NULL;
- return Status;
- }
-
- /* Mark the process as having a console */
- ProcessData->ConsoleApp = TRUE;
- ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
-
- /* Return the console handle to the caller */
- ConsoleInitInfo->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
-
- /*
- * Insert the process into the processes list of the console,
- * and set its foreground priority.
- */
- InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
- ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
-
- /* Add a reference count because the process is tied to the console */
- _InterlockedIncrement(&Console->ReferenceCount);
-
- /* Update the internal info of the terminal */
- TermRefreshInternalInfo(Console);
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
- HANDLE ConsoleHandle,
- BOOLEAN CreateNewHandlesTable,
- PHANDLE pInputHandle,
- PHANDLE pOutputHandle,
- PHANDLE pErrorHandle,
- PCONSOLE_START_INFO ConsoleStartInfo)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PCONSRV_CONSOLE Console;
-
- /* Validate and lock the console */
- if (!ConSrvValidateConsole(&Console,
- ConsoleHandle,
- CONSOLE_RUNNING, TRUE))
- {
- // FIXME: Find another status code
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Inherit the console */
- ProcessData->ConsoleHandle = ConsoleHandle;
-
- if (CreateNewHandlesTable)
- {
- /*
- * 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 handles table so that we can recreate
- * a new one later on.
- */
- ConSrvFreeHandlesTable(ProcessData);
-
- /* Initialize the handles table */
- Status = ConSrvInitHandlesTable(ProcessData,
- Console,
- pInputHandle,
- pOutputHandle,
- pErrorHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize the handles table\n");
- ProcessData->ConsoleHandle = NULL;
- goto Quit;
- }
- }
-
- /* Duplicate the Initialization Events */
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InitEvents[INIT_SUCCESS],
- ProcessData->Process->ProcessHandle,
- &ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
- ConSrvFreeHandlesTable(ProcessData);
- ProcessData->ConsoleHandle = NULL;
- goto Quit;
- }
-
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InitEvents[INIT_FAILURE],
- ProcessData->Process->ProcessHandle,
- &ConsoleStartInfo->InitEvents[INIT_FAILURE],
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- ConSrvFreeHandlesTable(ProcessData);
- ProcessData->ConsoleHandle = NULL;
- goto Quit;
- }
-
- /* Duplicate the Input Event */
- Status = NtDuplicateObject(NtCurrentProcess(),
- Console->InputBuffer.ActiveEvent,
- ProcessData->Process->ProcessHandle,
- &ConsoleStartInfo->InputWaitHandle,
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleStartInfo->InitEvents[INIT_FAILURE],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- NtDuplicateObject(ProcessData->Process->ProcessHandle,
- ConsoleStartInfo->InitEvents[INIT_SUCCESS],
- NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
- ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
- ProcessData->ConsoleHandle = NULL;
- goto Quit;
- }
-
- /* Mark the process as having a console */
- ProcessData->ConsoleApp = TRUE;
- ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
-
- /* Return the console handle to the caller */
- ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
-
- /*
- * Insert the process into the processes list of the console,
- * and set its foreground priority.
- */
- InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
- ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
-
- /* Add a reference count because the process is tied to the console */
- _InterlockedIncrement(&Console->ReferenceCount);
-
- /* Update the internal info of the terminal */
- TermRefreshInternalInfo(Console);
-
- Status = STATUS_SUCCESS;
-
-Quit:
- /* Unlock the console and return */
- LeaveCriticalSection(&Console->Lock);
- return Status;
-}
-
-NTSTATUS
-ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
-{
- PCONSRV_CONSOLE Console;
- PCONSOLE_PROCESS_DATA ConsoleLeaderProcess;
-
- DPRINT("ConSrvRemoveConsole\n");
-
- /* Mark the process as not having a console anymore */
- ProcessData->ConsoleApp = FALSE;
- ProcessData->Process->Flags &= ~CsrProcessIsConsoleApp;
-
- /* Validate and lock the console */
- if (!ConSrvValidateConsole(&Console,
- ProcessData->ConsoleHandle,
- CONSOLE_RUNNING, TRUE))
- {
- // FIXME: Find another status code
- return STATUS_UNSUCCESSFUL;
- }
-
- DPRINT("ConSrvRemoveConsole - Locking OK\n");
-
- /* Retrieve the console leader process */
- ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
-
- /* Close all console handles and free the handles table */
- ConSrvFreeHandlesTable(ProcessData);
-
- /* Detach the process from the console */
- ProcessData->ConsoleHandle = NULL;
-
- /* Remove the process from the console's list of processes */
- RemoveEntryList(&ProcessData->ConsoleLink);
-
- /* Check whether the console should send a last close notification */
- if (Console->NotifyLastClose)
- {
- /* If we are removing the process which wants the last close notification... */
- if (ProcessData == Console->NotifiedLastCloseProcess)
- {
- /* ... just reset the flag and the pointer... */
- Console->NotifyLastClose = FALSE;
- Console->NotifiedLastCloseProcess = NULL;
- }
- /*
- * ... otherwise, if we are removing the console leader process
- * (that cannot be the process wanting the notification, because
- * the previous case already dealt with it)...
- */
- else if (ProcessData == ConsoleLeaderProcess)
- {
- /*
- * ... reset the flag first (so that we avoid multiple notifications)
- * and then send the last close notification.
- */
- Console->NotifyLastClose = FALSE;
- ConSrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
-
- /* Only now, reset the pointer */
- Console->NotifiedLastCloseProcess = NULL;
- }
- }
-
- /* Update the internal info of the terminal */
- TermRefreshInternalInfo(Console);
-
- /* Release the console */
- DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
- ConSrvReleaseConsole(Console, TRUE);
-
- return STATUS_SUCCESS;
-}
-
-
/* PUBLIC SERVER APIS *********************************************************/
/* API_NUMBER: ConsolepOpenConsole */
diff --git a/win32ss/user/winsrv/consrv/handle.h b/win32ss/user/winsrv/consrv/handle.h
index d154c5cc17c..525893e2735 100644
--- a/win32ss/user/winsrv/consrv/handle.h
+++ b/win32ss/user/winsrv/consrv/handle.h
@@ -10,6 +10,14 @@
#pragma once
+NTSTATUS
+ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
+ IN PCONSOLE_PROCESS_DATA TargetProcessData);
+
+VOID
+ConSrvFreeHandlesTable(IN PCONSOLE_PROCESS_DATA ProcessData);
+
+
VOID
ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
IN CONSOLE_IO_OBJECT_TYPE Type,
diff --git a/win32ss/user/winsrv/consrv/init.c b/win32ss/user/winsrv/consrv/init.c
index 448c1836965..4332ae531a4 100644
--- a/win32ss/user/winsrv/consrv/init.c
+++ b/win32ss/user/winsrv/consrv/init.c
@@ -320,11 +320,6 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
/* FUNCTIONS ******************************************************************/
-/* See handle.c */
-NTSTATUS
-ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
- IN PCONSOLE_PROCESS_DATA TargetProcessData);
-
NTSTATUS
NTAPI
ConSrvNewProcess(PCSR_PROCESS SourceProcess,
diff --git a/win32ss/user/winsrv/consrv/procinit.h b/win32ss/user/winsrv/consrv/procinit.h
index 716ecd0a815..6eac76df2b0 100644
--- a/win32ss/user/winsrv/consrv/procinit.h
+++ b/win32ss/user/winsrv/consrv/procinit.h
@@ -8,16 +8,24 @@
#pragma once
-NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
- PHANDLE pInputHandle,
- PHANDLE pOutputHandle,
- PHANDLE pErrorHandle,
- PCONSOLE_INIT_INFO ConsoleInitInfo);
-NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
- HANDLE ConsoleHandle,
- BOOLEAN CreateNewHandlesTable,
- PHANDLE pInputHandle,
- PHANDLE pOutputHandle,
- PHANDLE pErrorHandle,
- PCONSOLE_START_INFO ConsoleStartInfo);
-NTSTATUS ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
+NTSTATUS
+ConSrvAllocateConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+ OUT PHANDLE pInputHandle,
+ OUT PHANDLE pOutputHandle,
+ OUT PHANDLE pErrorHandle,
+ IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo);
+
+NTSTATUS
+ConSrvInheritConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData,
+ IN HANDLE ConsoleHandle,
+ IN BOOLEAN CreateNewHandleTable,
+ OUT PHANDLE pInputHandle,
+ OUT PHANDLE pOutputHandle,
+ OUT PHANDLE pErrorHandle,
+ IN OUT PCONSOLE_START_INFO ConsoleStartInfo);
+
+NTSTATUS
+ConSrvRemoveConsole(
+ IN OUT PCONSOLE_PROCESS_DATA ProcessData);