[CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 19 Mar 2013 23:40:20 +0000 (23:40 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 19 Mar 2013 23:40:20 +0000 (23:40 +0000)
Use a new helper function ConSrvConsoleProcessCtrlEvent to send control events to processes belonging to a given console.

svn path=/branches/ros-csrss/; revision=58556

win32ss/user/consrv/coninput.c
win32ss/user/consrv/conio.h
win32ss/user/consrv/console.c
win32ss/user/consrv/guiconsole.c

index 68e3286..bfe882a 100644 (file)
@@ -227,18 +227,9 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
              (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 */
index 5f1872f..6ffd6cf 100644 (file)
@@ -238,10 +238,9 @@ NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
                                   IN PCSR_PROCESS ConsoleLeaderProcess);
 VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
 VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
-VOID FASTCALL ConSrvConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData);
-VOID FASTCALL ConSrvConsoleCtrlEventTimeout(DWORD Event,
-                                            PCONSOLE_PROCESS_DATA ProcessData,
-                                            DWORD Timeout);
+ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
+                                             ULONG ProcessGroupId,
+                                             DWORD Event);
 
 /* coninput.c */
 #define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
index 495ad23..1193eef 100644 (file)
 
 /* 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);
@@ -50,20 +53,59 @@ ConSrvConsoleCtrlEventTimeout(DWORD Event,
                                     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
@@ -1107,29 +1149,15 @@ CSR_API(SrvGenerateConsoleCtrlEvent)
     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;
 }
 
index 6a45f9f..51d0e04 100644 (file)
@@ -1040,29 +1040,15 @@ static VOID
 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);
 }