Author: hbelusca
Date: Tue Apr 22 00:46:49 2014
New Revision: 62861
URL:
http://svn.reactos.org/svn/reactos?rev=62861&view=rev
Log:
[CONSRV]
- Introduce a helper function to query the console leader process (instead of using
duplicated code).
- Fix the algorithm of the last close notification, as demonstrated by the tests I did on
windows 2003 (test app is provided in CORE-7250):
a console app that registered for the last close notification, closes only if the
process that was the console leader process at the time the app registered for the
notification, is killed.
In this case, we notify the app, and we clear some flags. On the contrary, if we close
the app that registered for the notification, we just clear the flags without doing extra
operations.
Modified:
trunk/reactos/win32ss/user/winsrv/consrv/condrv/console.c
trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
trunk/reactos/win32ss/user/winsrv/consrv/handle.c
trunk/reactos/win32ss/user/winsrv/consrv/include/conio.h
Modified: trunk/reactos/win32ss/user/winsrv/consrv/condrv/console.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
==============================================================================
--- trunk/reactos/win32ss/user/winsrv/consrv/condrv/console.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/winsrv/consrv/condrv/console.c [iso-8859-1] Tue Apr 22
00:46:49 2014
@@ -1091,6 +1091,16 @@
return STATUS_SUCCESS;
}
+PCONSOLE_PROCESS_DATA NTAPI
+ConDrvGetConsoleLeaderProcess(IN PCONSOLE Console)
+{
+ if (Console == NULL) return NULL;
+
+ return CONTAINING_RECORD(Console->ProcessList.Blink,
+ CONSOLE_PROCESS_DATA,
+ ConsoleLink);
+}
+
NTSTATUS NTAPI
ConDrvGetConsoleProcessList(IN PCONSOLE Console,
IN OUT PULONG ProcessIdsList,
Modified: trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
==============================================================================
--- trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c [iso-8859-1]
(original)
+++ trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c [iso-8859-1] Tue Apr
22 00:46:49 2014
@@ -48,9 +48,7 @@
PCONSOLE_PROCESS_DATA ProcessData;
CLIENT_ID ConsoleLeaderCID;
- ProcessData = CONTAINING_RECORD(GuiData->Console->ProcessList.Blink,
- CONSOLE_PROCESS_DATA,
- ConsoleLink);
+ ProcessData = ConDrvGetConsoleLeaderProcess(GuiData->Console);
ConsoleLeaderCID = ProcessData->Process->ClientId;
SetWindowLongPtrW(GuiData->hWindow, GWLP_CONSOLE_LEADER_PID,
(LONG_PTR)(ConsoleLeaderCID.UniqueProcess));
Modified: trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
==============================================================================
--- trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c [iso-8859-1]
(original)
+++ trunk/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c [iso-8859-1] Tue
Apr 22 00:46:49 2014
@@ -356,9 +356,7 @@
NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
/* Get the console leader process, our client */
- ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
- CONSOLE_PROCESS_DATA,
- ConsoleLink);
+ ProcessData = ConDrvGetConsoleLeaderProcess(Console);
/* Duplicate the section handle for the client */
Status = NtDuplicateObject(NtCurrentProcess(),
@@ -430,9 +428,7 @@
PGUI_CONSOLE_INFO GuiInfo = NULL;
/* Get the console leader process, our client */
- ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
- CONSOLE_PROCESS_DATA,
- ConsoleLink);
+ ProcessData = ConDrvGetConsoleLeaderProcess(Console);
/* Duplicate the section handle for ourselves */
Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
Modified: trunk/reactos/win32ss/user/winsrv/consrv/handle.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
==============================================================================
--- trunk/reactos/win32ss/user/winsrv/consrv/handle.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/winsrv/consrv/handle.c [iso-8859-1] Tue Apr 22 00:46:49
2014
@@ -633,10 +633,6 @@
return Status;
}
-NTSTATUS
-ConDrvConsoleCtrlEvent(IN ULONG CtrlEvent,
- IN PCONSOLE_PROCESS_DATA ProcessData);
-
VOID
FASTCALL
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
@@ -652,6 +648,9 @@
ProcessData->ConsoleHandle,
CONSOLE_RUNNING, TRUE))
{
+ /* Retrieve the console leader process */
+ PCONSOLE_PROCESS_DATA ConsoleLeaderProcess =
ConDrvGetConsoleLeaderProcess(Console);
+
DPRINT("ConSrvRemoveConsole - Locking OK\n");
/* Close all console handles and free the handles table */
@@ -660,35 +659,40 @@
/* Detach the process from the console */
ProcessData->ConsoleHandle = NULL;
- /* Remove ourselves from the console's list of processes */
+ /* 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;
+ ConDrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT,
Console->NotifiedLastCloseProcess);
+
+ /* Only now, reset the pointer */
+ Console->NotifiedLastCloseProcess = NULL;
+ }
+ }
/* Update the internal info of the terminal */
TermRefreshInternalInfo(Console);
-
- /*
- * Check if there is only one process still attached to the console,
- * and that the console should send a control event in this case.
- */
- if ((Console->ProcessList.Flink != &Console->ProcessList) &&
- (Console->ProcessList.Flink->Flink == &Console->ProcessList)
&&
- // (Console->ProcessList.Flink == Console->ProcessList.Blink)
&&
- Console->NotifyLastClose)
- {
- PCONSOLE_PROCESS_DATA LastProcess =
CONTAINING_RECORD(Console->ProcessList.Flink,
- CONSOLE_PROCESS_DATA,
- ConsoleLink);
- /* If the remaining process is the one that wanted the notification... */
- if (LastProcess == Console->NotifiedLastCloseProcess)
- {
- /* ... notify it that it's the only one remaining on the console */
- ConDrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, LastProcess);
- }
-
- /* In any case reset the pointer and the flag */
- Console->NotifiedLastCloseProcess = NULL;
- Console->NotifyLastClose = FALSE;
- }
/* Release the console */
DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount =
%lu\n", Console->ReferenceCount);
Modified: trunk/reactos/win32ss/user/winsrv/consrv/include/conio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
==============================================================================
--- trunk/reactos/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1] Tue Apr 22
00:46:49 2014
@@ -343,6 +343,11 @@
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
+PCONSOLE_PROCESS_DATA NTAPI
+ConDrvGetConsoleLeaderProcess(IN PCONSOLE Console);
+NTSTATUS
+ConDrvConsoleCtrlEvent(IN ULONG CtrlEvent,
+ IN PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS NTAPI
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
IN ULONG ProcessGroupId,