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