(er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
(er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
{
- PCONSOLE_PROCESS_DATA current;
- PLIST_ENTRY current_entry;
-
DPRINT1("Console_Api Ctrl-C\n");
+ ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
- current_entry = Console->ProcessList.Flink;
- while (current_entry != &Console->ProcessList)
- {
- current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
- current_entry = current_entry->Flink;
- ConSrvConsoleCtrlEvent(CTRL_C_EVENT, current);
- }
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
/* PRIVATE FUNCTIONS **********************************************************/
-BOOL FASTCALL
+#ifdef TUI_CONSOLE
+static BOOL
DtbgIsDesktopVisible(VOID)
{
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
}
+#endif
-VOID FASTCALL
+static ULONG
ConSrvConsoleCtrlEventTimeout(DWORD Event,
PCONSOLE_PROCESS_DATA ProcessData,
DWORD Timeout)
{
+ ULONG Status = ERROR_SUCCESS;
HANDLE Thread;
DPRINT("ConSrvConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
UlongToPtr(Event), 0, NULL);
if (NULL == Thread)
{
- DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
- return;
+ Status = GetLastError();
+ DPRINT1("Failed thread creation (Error: 0x%x)\n", Status);
+ }
+ else
+ {
+ DPRINT("We succeeded at creating ProcessData->CtrlDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
+ WaitForSingleObject(Thread, Timeout);
+ CloseHandle(Thread);
}
-
- DPRINT("We succeeded at creating ProcessData->CtrlDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
- WaitForSingleObject(Thread, Timeout);
- CloseHandle(Thread);
}
+
+ return Status;
}
-VOID FASTCALL
-ConSrvConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData)
+static ULONG
+ConSrvConsoleCtrlEvent(DWORD Event,
+ PCONSOLE_PROCESS_DATA ProcessData)
{
- ConSrvConsoleCtrlEventTimeout(Event, ProcessData, 0);
+ return ConSrvConsoleCtrlEventTimeout(Event, ProcessData, 0);
+}
+
+ULONG FASTCALL
+ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
+ ULONG ProcessGroupId,
+ DWORD Event)
+{
+ ULONG Status = ERROR_SUCCESS;
+ PLIST_ENTRY current_entry;
+ PCONSOLE_PROCESS_DATA current;
+
+ /*
+ * Loop through the process list, from the most recent process
+ * (the active one) to the oldest one (the first created, i.e.
+ * the console leader process), and for each, send an event
+ * (new processes are inserted at the head of the console process list).
+ */
+ current_entry = Console->ProcessList.Flink;
+ while (current_entry != &Console->ProcessList)
+ {
+ current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
+ current_entry = current_entry->Flink;
+
+ /*
+ * Only processes belonging to the same process group are signaled.
+ * If the process group ID is zero, then all the processes are signaled.
+ */
+ if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
+ {
+ Status = ConSrvConsoleCtrlEvent(Event, current);
+ }
+ }
+
+ return Status;
}
VOID FASTCALL
NTSTATUS Status;
PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest;
PCONSOLE Console;
- PCONSOLE_PROCESS_DATA current;
- PLIST_ENTRY current_entry;
- DWORD Group;
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
- Group = GenerateCtrlEventRequest->ProcessGroup;
- Status = STATUS_INVALID_PARAMETER;
- for (current_entry = Console->ProcessList.Flink;
- current_entry != &Console->ProcessList;
- current_entry = current_entry->Flink)
- {
- current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
- if (Group == 0 || current->Process->ProcessGroupId == Group)
- {
- ConSrvConsoleCtrlEvent(GenerateCtrlEventRequest->Event, current);
- Status = STATUS_SUCCESS;
- }
- }
+ Status = ConSrvConsoleProcessCtrlEvent(Console,
+ GenerateCtrlEventRequest->ProcessGroup,
+ GenerateCtrlEventRequest->Event);
ConSrvReleaseConsole(Console, TRUE);
-
return Status;
}
GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData)
{
PCONSOLE Console = GuiData->Console;
- PLIST_ENTRY current_entry;
- PCONSOLE_PROCESS_DATA current;
/// LOCK /// EnterCriticalSection(&Console->Lock);
/*
- * Loop through the process list, from the most recent process
- * (the active one) to the oldest one (the first created,
- * i.e. the console leader process), and for each, send a
- * CTRL-CLOSE event (new processes are inserted at the head
- * of the console process list).
+ * FIXME: Windows will wait up to 5 seconds for the thread to exit.
+ * We shouldn't wait here, though, since the console lock is entered.
+ * A copy of the thread list probably needs to be made.
*/
- current_entry = Console->ProcessList.Flink;
- while (current_entry != &Console->ProcessList)
- {
- current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
- current_entry = current_entry->Flink;
-
- /* FIXME: Windows will wait up to 5 seconds for the thread to exit.
- * We shouldn't wait here, though, since the console lock is entered.
- * A copy of the thread list probably needs to be made. */
- ConSrvConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
- }
+ ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
/// LOCK /// LeaveCriticalSection(&Console->Lock);
}