ReactOS  0.4.14-dev-297-g23e575c
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 }
BOOL Force
Definition: winmsg.h:59
#define ERROR_SUCCESS
Definition: deptool.c:10
#define USERSRV_SERVERDLL_INDEX
Definition: winmsg.h:15
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:365
HWND hWnd
Definition: settings.c:17
BOOL Success
Definition: winmsg.h:60
HWND WndHandle
Definition: winmsg.h:58
VOID WINAPI UserSetLastError(IN DWORD dwErrCode)
Definition: misc.c:13
NTSTATUS Status
Definition: csrmsg.h:112
smooth NULL
Definition: ftsmooth.c:416
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USER_END_TASK EndTaskRequest
Definition: winmsg.h:101
VOID WINAPI UserSetLastNTError(IN NTSTATUS Status)
Definition: misc.c:25
DWORD LastError
Definition: winmsg.h:57
union _USER_API_MESSAGE::@3413 Data

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 }
static BOOL ExitWindowsWorker(UINT uFlags, DWORD dwReserved, BOOL bCalledFromThread)
Definition: exit.c:87
UINT uFlags
Definition: api.c:59
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90

◆ 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
#define ERROR_SUCCESS
Definition: deptool.c:10
static BOOL ExitWindowsWorker(UINT uFlags, DWORD dwReserved, BOOL bCalledFromThread)
Definition: exit.c:87
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
struct EXIT_REACTOS_DATA * PEXIT_REACTOS_DATA
UINT uFlags
Definition: exit.c:60
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
DWORD dwReserved
Definition: exit.c:61
unsigned long DWORD
Definition: ntddk_ex.h:95

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 CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
#define USERSRV_SERVERDLL_INDEX
Definition: winmsg.h:15
static DWORD WINAPI ExitWindowsThread(LPVOID Param)
Definition: exit.c:71
DWORD LastError
Definition: winmsg.h:50
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:365
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
USER_EXIT_REACTOS ExitReactOSRequest
Definition: winmsg.h:100
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT uFlags
Definition: api.c:59
VOID WINAPI UserSetLastError(IN DWORD dwErrCode)
Definition: misc.c:13
UINT uFlags
Definition: exit.c:60
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:540
DWORD WINAPI MsgWaitForMultipleObjectsEx(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask, _In_ DWORD dwFlags)
NTSTATUS Status
Definition: csrmsg.h:112
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
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:136
smooth NULL
Definition: ftsmooth.c:416
DWORD dwReserved
Definition: exit.c:61
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID WINAPI UserSetLastNTError(IN NTSTATUS Status)
Definition: misc.c:25
#define QS_ALLINPUT
Definition: winuser.h:874
#define msg(x)
Definition: auth_time.c:54
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1182
union _USER_API_MESSAGE::@3413 Data
#define INFINITE
Definition: serial.h:102
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438

Referenced by ExitWindowsEx(), and ExitWindowsThread().