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