[WINSRV] consrv: Implement terminating console processes on shutdown

Also stub handling non-console, non-gui processes.
This commit is contained in:
Giannis Adamopoulos 2019-01-03 14:26:57 +02:00
parent 0a80b77e76
commit 4bef6f5913
3 changed files with 70 additions and 10 deletions

View file

@ -805,7 +805,7 @@ ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
static NTSTATUS NTSTATUS
ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent, ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData, IN PCONSOLE_PROCESS_DATA ProcessData,
IN ULONG Timeout) IN ULONG Timeout)

View file

@ -47,3 +47,8 @@ ConSrvValidateConsole(OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ Consol
IN HANDLE ConsoleHandle, IN HANDLE ConsoleHandle,
IN CONSOLE_STATE ExpectedState, IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole); IN BOOLEAN LockConsole);
NTSTATUS
ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData,
IN ULONG Timeout);

View file

@ -9,12 +9,64 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include "consrv.h" #include "consrv.h"
#include <psapi.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
static void
NotifyConsoleProcessForShutdown(IN PCSR_PROCESS CsrProcess,
IN PCONSOLE_PROCESS_DATA ProcessData,
IN ULONG Flags)
{
DPRINT1("ConsoleClientShutdown(0x%p, 0x%x) - Console process [0x%x, 0x%x]\n",
CsrProcess, Flags, CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread);
/* Send a log-off event. In reality this should be way more complex */
ConSrvConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData,
ShutdownSettings.WaitToKillAppTimeout);
}
static BOOL
NotifyGenericProcessForShutdown(IN PCSR_PROCESS CsrProcess,
IN ULONG Flags)
{
/* FIXME: Implement the generic process shutdown handler */
UNIMPLEMENTED_ONCE;
return TRUE;
}
ULONG
NTAPI
NonConsoleProcessShutdown(IN PCSR_PROCESS Process,
IN ULONG Flags)
{
if (NotifyGenericProcessForShutdown(Process, Flags))
{
/* Terminate this process */
#if DBG
WCHAR buffer[MAX_PATH];
if (!GetProcessImageFileNameW(Process->ProcessHandle, buffer, MAX_PATH))
{
DPRINT1("Terminating process %x\n", Process->ClientId.UniqueProcess);
}
else
{
DPRINT1("Terminating process %x (%S)\n", Process->ClientId.UniqueProcess, buffer);
}
#endif
NtTerminateProcess(Process->ProcessHandle, 0);
WaitForSingleObject(Process->ProcessHandle, ShutdownSettings.ProcessTerminateTimeout);
}
CsrDereferenceProcess(Process);
return CsrShutdownCsrProcess;
}
// NOTE: See http://blogs.msdn.com/b/ntdebugging/archive/2007/06/09/how-windows-shuts-down.aspx // NOTE: See http://blogs.msdn.com/b/ntdebugging/archive/2007/06/09/how-windows-shuts-down.aspx
ULONG ULONG
NTAPI NTAPI
@ -24,14 +76,19 @@ ConsoleClientShutdown(IN PCSR_PROCESS CsrProcess,
{ {
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess); PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
//FIXME: UNIMPLEMENTED! /* Do not kill system processes when a user is logging off */
if ((Flags & EWX_SHUTDOWN) == EWX_LOGOFF &&
(CsrProcess->ShutdownFlags & (CsrShutdownSystem | CsrShutdownOther)))
{
DPRINT("Do not kill a system process in a logoff request!\n");
return CsrShutdownNonCsrProcess;
}
/* Is it a console process? */
if ( ProcessData->ConsoleHandle != NULL || if ( ProcessData->ConsoleHandle != NULL ||
ProcessData->HandleTable != NULL ) ProcessData->HandleTable != NULL )
{ {
DPRINT("ConsoleClientShutdown(0x%p, 0x%x, %s) - Console process [0x%x, 0x%x]\n", NotifyConsoleProcessForShutdown(CsrProcess, ProcessData, Flags);
CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase",
CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread);
/* We are done with the process itself */ /* We are done with the process itself */
CsrDereferenceProcess(CsrProcess); CsrDereferenceProcess(CsrProcess);
@ -43,13 +100,11 @@ ConsoleClientShutdown(IN PCSR_PROCESS CsrProcess,
CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase", CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase",
CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread); CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread);
/* On first pass, ignore the process since the GUI server should take it... */ /* On first pass, let the gui server terminate all the processes that it owns */
if (FirstPhase) return CsrShutdownNonCsrProcess; if (FirstPhase) return CsrShutdownNonCsrProcess;
/* ... otherwise, call the generic handler */ /* Use the generic handler since this isn't a gui process */
// FIXME: Should call a generic shutdown handler!! return NonConsoleProcessShutdown(CsrProcess, Flags);
CsrDereferenceProcess(CsrProcess);
return CsrShutdownCsrProcess;
} }
return CsrShutdownNonCsrProcess; return CsrShutdownNonCsrProcess;