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, ARRAYSIZE(buffer))) 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 NtTerminateProcess(Process->ProcessHandle, 0); 62 WaitForSingleObject(Process->ProcessHandle, ShutdownSettings.ProcessTerminateTimeout); 63 } 64 65 CsrDereferenceProcess(Process); 66 return CsrShutdownCsrProcess; 67 } 68 69 // NOTE: See http://blogs.msdn.com/b/ntdebugging/archive/2007/06/09/how-windows-shuts-down.aspx 70 ULONG 71 NTAPI 72 ConsoleClientShutdown(IN PCSR_PROCESS CsrProcess, 73 IN ULONG Flags, 74 IN BOOLEAN FirstPhase) 75 { 76 PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess); 77 78 /* Do not kill system processes when a user is logging off */ 79 if ((Flags & EWX_SHUTDOWN) == EWX_LOGOFF && 80 (CsrProcess->ShutdownFlags & (CsrShutdownSystem | CsrShutdownOther))) 81 { 82 DPRINT("Do not kill a system process in a logoff request!\n"); 83 return CsrShutdownNonCsrProcess; 84 } 85 86 /* Is it a console process? */ 87 if ( ProcessData->ConsoleHandle != NULL || 88 ProcessData->HandleTable != NULL ) 89 { 90 NotifyConsoleProcessForShutdown(CsrProcess, ProcessData, Flags); 91 92 /* We are done with the process itself */ 93 CsrDereferenceProcess(CsrProcess); 94 return CsrShutdownCsrProcess; 95 } 96 else 97 { 98 DPRINT("ConsoleClientShutdown(0x%p, 0x%x, %s) - Non-console process [0x%x, 0x%x]\n", 99 CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase", 100 CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread); 101 102 /* On first pass, let the gui server terminate all the processes that it owns */ 103 if (FirstPhase) return CsrShutdownNonCsrProcess; 104 105 /* Use the generic handler since this isn't a gui process */ 106 return NonConsoleProcessShutdown(CsrProcess, Flags); 107 } 108 109 return CsrShutdownNonCsrProcess; 110 } 111 112 /* EOF */ 113