Send proper messages/events to processes during logoff and kill them if they
[reactos.git] / reactos / lib / user32 / misc / exit.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/misc/exit.c
6 * PURPOSE: Shutdown related functions
7 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
8 */
9
10 #include <user32.h>
11
12 /*
13 * Sequence of events:
14 *
15 * - App (usually explorer) calls ExitWindowsEx()
16 * - ExitWindowsEx() sends a message to CSRSS
17 * - CSRSS impersonates the caller and sends a message to a hidden WinLogon window
18 * - WinLogon checks if the caller has the required privileges
19 * - WinLogon enters pending log-out state
20 * - WinLogon impersonates the interactive user and calls ExitWindowsEx() again,
21 * passing some special internal flags
22 * - CSRSS loops over all processes of the interactive user (sorted by their
23 * SetProcessShutdownParameters() level), sending WM_QUERYENDSESSION and
24 * WM_ENDSESSION messages to its top-level windows. If the messages aren't
25 * processed within the timeout period (registry key HKCU\Control Panel\Desktop\HungAppTimeout)
26 * CSRSS will put up a dialog box asking if the process should be terminated.
27 * Using the registry key HKCU\Control Panel\Desktop\AutoEndTask you can
28 * specify that the dialog box shouldn't be shown and CSRSS should just
29 * terminate the thread. If the the WM_ENDSESSION message is processed
30 * but the thread doesn't terminate within the timeout specified by
31 * HKCU\Control Panel\Desktop\WaitToKillAppTimeout CSRSS will terminate
32 * the thread. When all the top-level windows have been destroyed CSRSS
33 * will terminate the process.
34 * If the process is a console process, CSRSS will send a CTRL_LOGOFF_EVENT
35 * to the console control handler on logoff. No event is sent on shutdown.
36 * If the handler doesn't respond in time the same activities as for GUI
37 * apps (i.e. display dialog box etc) take place. This also happens if
38 * the handler returns TRUE.
39 * - This ends the processing for the first ExitWindowsEx() call from WinLogon.
40 * Execution continues in WinLogon, which calls ExitWindowsEx() again to
41 * terminate COM processes in the interactive user's session.
42 * - WinLogon stops impersonating the interactive user (whos processes are
43 * all dead by now). and enters log-out state
44 * - If the ExitWindowsEx() request was for a logoff, WinLogon sends a SAS
45 * event (to display the "press ctrl+alt+del") to the GINA. WinLogon then
46 * waits for the GINA to send a SAS event to login.
47 * - If the ExitWindowsEx() request was for shutdown/restart, WinLogon calls
48 * ExitWindowsEx() again in the system process context.
49 * - CSRSS goes through the motions of sending WM_QUERYENDSESSION/WM_ENDSESSION
50 * to GUI processes running in the system process context but won't display
51 * dialog boxes or kill threads/processes. Same for console processes,
52 * using the CTRL_SHUTDOWN_EVENT. The Service Control Manager is one of
53 * these console processes and has a special timeout value WaitToKillServiceTimeout.
54 * - WinLogon issues a "InitiateSystemShutdown" request to the SM (SMSS API # 1)
55 * - the SM propagates the shutdown request to every environment subsystem it
56 * started since bootstrap time (still active ones, of course)
57 * - each environment subsystem, on shutdown request, releases every resource
58 * it aquired during its life (processes, memory etc), then dies
59 * - when every environment subsystem has gone to bed, the SM actually initiates
60 * the kernel and executive shutdown by calling NtShutdownSystem.
61 */
62 /*
63 * @implemented
64 */
65 BOOL STDCALL
66 ExitWindowsEx(UINT uFlags,
67 DWORD dwReserved)
68 {
69 CSR_API_MESSAGE Request;
70 ULONG CsrRequest;
71 NTSTATUS Status;
72
73 CsrRequest = MAKE_CSR_API(EXIT_REACTOS, CSR_GUI);
74 Request.Data.ExitReactosRequest.Flags = uFlags;
75 Request.Data.ExitReactosRequest.Reserved = dwReserved;
76
77 Status = CsrClientCallServer(&Request,
78 NULL,
79 CsrRequest,
80 sizeof(CSR_API_MESSAGE));
81 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
82 {
83 SetLastError(RtlNtStatusToDosError(Status));
84 return(FALSE);
85 }
86
87 return(TRUE);
88 }
89
90
91 /*
92 * @implemented
93 */
94 BOOL STDCALL
95 RegisterServicesProcess(DWORD ServicesProcessId)
96 {
97 CSR_API_MESSAGE Request;
98 ULONG CsrRequest;
99 NTSTATUS Status;
100
101 CsrRequest = MAKE_CSR_API(REGISTER_SERVICES_PROCESS, CSR_GUI);
102 Request.Data.RegisterServicesProcessRequest.ProcessId = (HANDLE)ServicesProcessId;
103
104 Status = CsrClientCallServer(&Request,
105 NULL,
106 CsrRequest,
107 sizeof(CSR_API_MESSAGE));
108 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
109 {
110 SetLastError(RtlNtStatusToDosError(Status));
111 return(FALSE);
112 }
113
114 return(TRUE);
115 }
116
117 /* EOF */