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,
- HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
+ ProcessData->Process);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
- NtClose(ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS]);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
ConSrvFreeHandlesTable(ProcessData);
ConSrvDeleteConsole(Console);
ProcessData->ConsoleHandle = NULL;
Status = NtDuplicateObject(NtCurrentProcess(),
Console->InputBuffer.ActiveEvent,
ProcessData->Process->ProcessHandle,
- &ProcessData->InputWaitHandle,
+ &ConsoleInitInfo->ConsoleStartInfo->InputWaitHandle,
EVENT_ALL_ACCESS, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
- NtClose(ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE]);
- NtClose(ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS]);
+ 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;
}
- /* Insert the process into the processes list of the console */
+ /* 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);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
- NtClose(ConsoleStartInfo->InitEvents[INIT_SUCCESS]);
+ NtDuplicateObject(ProcessData->Process->ProcessHandle,
+ ConsoleStartInfo->InitEvents[INIT_SUCCESS],
+ NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
ConSrvFreeHandlesTable(ProcessData);
ProcessData->ConsoleHandle = NULL;
goto Quit;
Status = NtDuplicateObject(NtCurrentProcess(),
Console->InputBuffer.ActiveEvent,
ProcessData->Process->ProcessHandle,
- &ProcessData->InputWaitHandle,
+ &ConsoleStartInfo->InputWaitHandle,
EVENT_ALL_ACCESS, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
- NtClose(ConsoleStartInfo->InitEvents[INIT_FAILURE]);
- NtClose(ConsoleStartInfo->InitEvents[INIT_SUCCESS]);
+ 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;
}
- /* Insert the process into the processes list of the console */
+ /* 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);
return Status;
}
-VOID
+NTSTATUS
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
{
PCONSOLE Console;
+ PCONSOLE_PROCESS_DATA ConsoleLeaderProcess;
DPRINT("ConSrvRemoveConsole\n");
- // RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ /* 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))
+ if (!ConSrvValidateConsole(&Console,
+ ProcessData->ConsoleHandle,
+ CONSOLE_RUNNING, TRUE))
{
- /* Retrieve the console leader process */
- PCONSOLE_PROCESS_DATA ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
+ // FIXME: Find another status code
+ return STATUS_UNSUCCESSFUL;
+ }
- DPRINT("ConSrvRemoveConsole - Locking OK\n");
+ DPRINT("ConSrvRemoveConsole - Locking OK\n");
- /* Close all console handles and free the handles table */
- ConSrvFreeHandlesTable(ProcessData);
+ /* Retrieve the console leader process */
+ ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
- /* Detach the process from the console */
- ProcessData->ConsoleHandle = NULL;
+ /* Close all console handles and free the handles table */
+ ConSrvFreeHandlesTable(ProcessData);
- /* Remove the process from the console's list of processes */
- RemoveEntryList(&ProcessData->ConsoleLink);
+ /* Detach the process from the console */
+ ProcessData->ConsoleHandle = NULL;
- /* Check whether the console should send a last close notification */
- if (Console->NotifyLastClose)
+ /* 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)
{
- /* 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)...
+ * ... reset the flag first (so that we avoid multiple notifications)
+ * and then send the last close notification.
*/
- 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;
- }
+ 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);
+ /* Update the internal info of the terminal */
+ TermRefreshInternalInfo(Console);
- /* Release the console */
- DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
- ConSrvReleaseConsole(Console, TRUE);
- //CloseHandle(ProcessData->InputWaitHandle);
- //ProcessData->InputWaitHandle = NULL;
- }
+ /* Release the console */
+ DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
+ ConSrvReleaseConsole(Console, TRUE);
- // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return STATUS_SUCCESS;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't get console\n");
+ DPRINT1("Can't get console, status %lx\n", Status);
return Status;
}