xref: /reactos/win32ss/user/winsrv/consrv/shutdown.c (revision d2c71d76)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Console Server DLL
4  * FILE:            win32ss/user/winsrv/consrv/shutdown.c
5  * PURPOSE:         Processes Shutdown
6  * PROGRAMMERS:     Alex Ionescu
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "consrv.h"
12 #include <psapi.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* FUNCTIONS ******************************************************************/
18 
19 static void
20 NotifyConsoleProcessForShutdown(IN PCSR_PROCESS CsrProcess,
21                                 IN PCONSOLE_PROCESS_DATA ProcessData,
22                                 IN ULONG Flags)
23 {
24     DPRINT1("ConsoleClientShutdown(0x%p, 0x%x) - Console process [0x%x, 0x%x]\n",
25              CsrProcess, Flags, CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread);
26 
27     /* Send a log-off event. In reality this should be way more complex */
28     ConSrvConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData,
29                                   ShutdownSettings.WaitToKillAppTimeout);
30 }
31 
32 static BOOL
33 NotifyGenericProcessForShutdown(IN PCSR_PROCESS CsrProcess,
34                                 IN ULONG Flags)
35 {
36     /* FIXME: Implement the generic process shutdown handler */
37     UNIMPLEMENTED_ONCE;
38 
39     return TRUE;
40 }
41 
42 ULONG
43 NTAPI
44 NonConsoleProcessShutdown(IN PCSR_PROCESS Process,
45                           IN ULONG Flags)
46 {
47     if (NotifyGenericProcessForShutdown(Process, Flags))
48     {
49         /* Terminate this process */
50 #if DBG
51         WCHAR buffer[MAX_PATH];
52         if (!GetProcessImageFileNameW(Process->ProcessHandle, buffer, MAX_PATH))
53         {
54             DPRINT1("Terminating process %x\n", Process->ClientId.UniqueProcess);
55         }
56         else
57         {
58             DPRINT1("Terminating process %x (%S)\n", Process->ClientId.UniqueProcess, buffer);
59         }
60 #endif
61 
62         NtTerminateProcess(Process->ProcessHandle, 0);
63         WaitForSingleObject(Process->ProcessHandle, ShutdownSettings.ProcessTerminateTimeout);
64     }
65 
66     CsrDereferenceProcess(Process);
67     return CsrShutdownCsrProcess;
68 }
69 
70 // NOTE: See http://blogs.msdn.com/b/ntdebugging/archive/2007/06/09/how-windows-shuts-down.aspx
71 ULONG
72 NTAPI
73 ConsoleClientShutdown(IN PCSR_PROCESS CsrProcess,
74                       IN ULONG Flags,
75                       IN BOOLEAN FirstPhase)
76 {
77     PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
78 
79     /* Do not kill system processes when a user is logging off */
80     if ((Flags & EWX_SHUTDOWN) == EWX_LOGOFF &&
81         (CsrProcess->ShutdownFlags & (CsrShutdownSystem | CsrShutdownOther)))
82     {
83         DPRINT("Do not kill a system process in a logoff request!\n");
84         return CsrShutdownNonCsrProcess;
85     }
86 
87     /* Is it a console process? */
88     if ( ProcessData->ConsoleHandle != NULL ||
89          ProcessData->HandleTable   != NULL )
90     {
91         NotifyConsoleProcessForShutdown(CsrProcess, ProcessData, Flags);
92 
93         /* We are done with the process itself */
94         CsrDereferenceProcess(CsrProcess);
95         return CsrShutdownCsrProcess;
96     }
97     else
98     {
99         DPRINT("ConsoleClientShutdown(0x%p, 0x%x, %s) - Non-console process [0x%x, 0x%x]\n",
100                 CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase",
101                 CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread);
102 
103         /* On first pass, let the gui server terminate all the processes that it owns */
104         if (FirstPhase) return CsrShutdownNonCsrProcess;
105 
106         /* Use the generic handler since this isn't a gui process */
107         return NonConsoleProcessShutdown(CsrProcess, Flags);
108     }
109 
110     return CsrShutdownNonCsrProcess;
111 }
112 
113 /* EOF */
114