ReactOS 0.4.15-dev-7906-g1b85a5f
exit.c File Reference
#include <user32.h>
Include dependency graph for exit.c:

Go to the source code of this file.

Classes

struct  EXIT_REACTOS_DATA
 

Typedefs

typedef struct EXIT_REACTOS_DATAPEXIT_REACTOS_DATA
 

Functions

static BOOL ExitWindowsWorker (UINT uFlags, DWORD dwReserved, BOOL bCalledFromThread)
 
static DWORD WINAPI ExitWindowsThread (LPVOID Param)
 
BOOL WINAPI ExitWindowsEx (UINT uFlags, DWORD dwReserved)
 
BOOL WINAPI EndTask (HWND hWnd, BOOL fShutDown, BOOL fForce)
 

Typedef Documentation

◆ PEXIT_REACTOS_DATA

Function Documentation

◆ EndTask()

BOOL WINAPI EndTask ( HWND  hWnd,
BOOL  fShutDown,
BOOL  fForce 
)

Definition at line 207 of file exit.c.

210{
211 USER_API_MESSAGE ApiMessage;
212 PUSER_END_TASK EndTaskRequest = &ApiMessage.Data.EndTaskRequest;
213
214 UNREFERENCED_PARAMETER(fShutDown);
215
216 // EndTaskRequest->LastError = ERROR_SUCCESS;
217 EndTaskRequest->WndHandle = hWnd;
218 EndTaskRequest->Force = fForce;
219
221 NULL,
223 sizeof(*EndTaskRequest));
224 if (!NT_SUCCESS(ApiMessage.Status))
225 {
226 UserSetLastNTError(ApiMessage.Status);
227 return FALSE;
228 }
229
230 if (EndTaskRequest->LastError != ERROR_SUCCESS)
231 UserSetLastError(EndTaskRequest->LastError);
232
233 return EndTaskRequest->Success;
234}
HWND hWnd
Definition: settings.c:17
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI CsrClientCallServer(_Inout_ PCSR_API_MESSAGE ApiMessage, _Inout_opt_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ CSR_API_NUMBER ApiNumber, _In_ ULONG DataLength)
Definition: connect.c:366
NTSTATUS Status
Definition: csrmsg.h:110
USER_END_TASK EndTaskRequest
Definition: winmsg.h:109
union _USER_API_MESSAGE::@3541 Data
BOOL Force
Definition: winmsg.h:59
DWORD LastError
Definition: winmsg.h:57
BOOL Success
Definition: winmsg.h:60
HWND WndHandle
Definition: winmsg.h:58
VOID WINAPI UserSetLastError(IN DWORD dwErrCode)
Definition: misc.c:13
VOID WINAPI UserSetLastNTError(IN NTSTATUS Status)
Definition: misc.c:25
@ UserpEndTask
Definition: winmsg.h:22
#define USERSRV_SERVERDLL_INDEX
Definition: winmsg.h:15

Referenced by ApplicationPage_OnEndTask().

◆ ExitWindowsEx()

BOOL WINAPI ExitWindowsEx ( UINT  uFlags,
DWORD  dwReserved 
)

Definition at line 186 of file exit.c.

188{
189 /*
190 * FIXME:
191 * 1- Calling the Exit worker must be done under certain conditions.
192 * We may also need to warn the user if there are other people logged
193 * on this computer (see http://pve.proxmox.com/wiki/Windows_2003_guest_best_practices )
194 * 2- Call SrvRecordShutdownReason.
195 */
196
198
199 /* FIXME: Call SrvRecordShutdownReason if we failed */
200}
UINT uFlags
Definition: api.c:59
static BOOL ExitWindowsWorker(UINT uFlags, DWORD dwReserved, BOOL bCalledFromThread)
Definition: exit.c:87
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95

◆ ExitWindowsThread()

static DWORD WINAPI ExitWindowsThread ( LPVOID  Param)
static

Definition at line 71 of file exit.c.

72{
73 DWORD dwExitCode;
74 PEXIT_REACTOS_DATA ExitData = (PEXIT_REACTOS_DATA)Param;
75
76 /* Do the exit asynchronously */
77 if (ExitWindowsWorker(ExitData->uFlags, ExitData->dwReserved, TRUE))
78 dwExitCode = ERROR_SUCCESS;
79 else
80 dwExitCode = GetLastError();
81
82 ExitThread(dwExitCode);
83 return ERROR_SUCCESS;
84}
#define TRUE
Definition: types.h:120
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
struct EXIT_REACTOS_DATA * PEXIT_REACTOS_DATA
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwReserved
Definition: exit.c:61
UINT uFlags
Definition: exit.c:60
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by ExitWindowsWorker().

◆ ExitWindowsWorker()

static BOOL ExitWindowsWorker ( UINT  uFlags,
DWORD  dwReserved,
BOOL  bCalledFromThread 
)
static

Definition at line 87 of file exit.c.

90{
91 EXIT_REACTOS_DATA ExitData;
92 HANDLE hExitThread;
93 DWORD ExitCode;
94 MSG msg;
95
96 USER_API_MESSAGE ApiMessage;
97 PUSER_EXIT_REACTOS ExitReactOSRequest = &ApiMessage.Data.ExitReactOSRequest;
98
99 /*
100 * 1- FIXME: Call NtUserCallOneParam(uFlags, ONEPARAM_ROUTINE_PREPAREFORLOGOFF);
101 * If success we can continue, otherwise we must fail.
102 */
103
104 /*
105 * 2- Send the Exit request to CSRSS (and to Win32k indirectly).
106 * We can shutdown synchronously or asynchronously.
107 */
108
109 // ExitReactOSRequest->LastError = ERROR_SUCCESS;
110 ExitReactOSRequest->Flags = uFlags;
111
113 NULL,
115 sizeof(*ExitReactOSRequest));
116
117 /* Set the last error accordingly */
118 if (NT_SUCCESS(ApiMessage.Status) || ApiMessage.Status == STATUS_CANT_WAIT)
119 {
120 if (ExitReactOSRequest->LastError != ERROR_SUCCESS)
121 UserSetLastError(ExitReactOSRequest->LastError);
122 }
123 else
124 {
125 UserSetLastNTError(ApiMessage.Status);
126 ExitReactOSRequest->Success = FALSE;
127 }
128
129 /*
130 * In case CSR call succeeded and we did a synchronous exit
131 * (STATUS_CANT_WAIT is considered as a non-success status),
132 * return the real state of the operation now.
133 */
134 if (NT_SUCCESS(ApiMessage.Status))
135 return ExitReactOSRequest->Success;
136
137 /*
138 * In case something failed: we have a non-success status and:
139 * - either we were doing a synchronous exit (Status != STATUS_CANT_WAIT), or
140 * - we were doing an asynchronous exit because we were called recursively via
141 * another thread but we failed to exit,
142 * then bail out immediately, otherwise we would enter an infinite loop of exit requests.
143 *
144 * On the contrary if we need to do an asynchronous exit (Status == STATUS_CANT_WAIT
145 * and not called recursively via another thread), then continue and do the exit.
146 */
147 if (ApiMessage.Status != STATUS_CANT_WAIT || bCalledFromThread)
148 {
149 UserSetLastNTError(ApiMessage.Status);
150 return FALSE;
151 }
152
153 /*
154 * 3- Win32k wants us to perform an asynchronous exit. Run the request in a thread.
155 * (ApiMessage.Status == STATUS_CANT_WAIT and not already called from a thread)
156 */
157 ExitData.uFlags = uFlags;
158 ExitData.dwReserved = dwReserved;
159 hExitThread = CreateThread(NULL, 0, ExitWindowsThread, &ExitData, 0, NULL);
160 if (hExitThread == NULL)
161 return FALSE;
162
163 /* Pump and discard any input events sent to the app(s) */
164 while (MsgWaitForMultipleObjectsEx(1, &hExitThread, INFINITE, QS_ALLINPUT, 0))
165 {
166 while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
168 }
169
170 /* Finally, return to caller */
171 if (!GetExitCodeThread(hExitThread, &ExitCode))
172 ExitCode = GetLastError();
173
174 CloseHandle(hExitThread);
175
176 if (ExitCode != ERROR_SUCCESS)
177 UserSetLastError(ExitCode);
178
179 return (ExitCode == ERROR_SUCCESS);
180}
#define msg(x)
Definition: auth_time.c:54
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
#define INFINITE
Definition: serial.h:102
static DWORD WINAPI ExitWindowsThread(LPVOID Param)
Definition: exit.c:71
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
USER_EXIT_REACTOS ExitReactOSRequest
Definition: winmsg.h:108
DWORD LastError
Definition: winmsg.h:50
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
@ UserpExitWindowsEx
Definition: winmsg.h:21
#define QS_ALLINPUT
Definition: winuser.h:903
DWORD WINAPI MsgWaitForMultipleObjectsEx(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask, _In_ DWORD dwFlags)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1196
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)

Referenced by ExitWindowsEx(), and ExitWindowsThread().