ReactOS 0.4.16-dev-136-g52192f1
shutdown.c File Reference
#include "usersrv.h"
#include <commctrl.h>
#include <psapi.h>
#include "resource.h"
#include <debug.h>
Include dependency graph for shutdown.c:

Go to the source code of this file.

Classes

struct  tagNOTIFY_CONTEXT
 
struct  tagMESSAGE_CONTEXT
 

Macros

#define NDEBUG
 
#define SHUTDOWN_SYSTEMCONTEXT   CsrShutdownSystem
 
#define SHUTDOWN_OTHERCONTEXT   CsrShutdownOther
 
#define MY_DPRINT   DPRINT1
 
#define MY_DPRINT2   DPRINT
 
#define QUERY_RESULT_ABORT   0
 
#define QUERY_RESULT_CONTINUE   1
 
#define QUERY_RESULT_TIMEOUT   2
 
#define QUERY_RESULT_ERROR   3
 
#define QUERY_RESULT_FORCE   4
 

Typedefs

typedef struct tagNOTIFY_CONTEXT NOTIFY_CONTEXT
 
typedef struct tagNOTIFY_CONTEXTPNOTIFY_CONTEXT
 
typedef void(WINAPIINITCOMMONCONTROLS_PROC) (void)
 
typedef struct tagMESSAGE_CONTEXT MESSAGE_CONTEXT
 
typedef struct tagMESSAGE_CONTEXTPMESSAGE_CONTEXT
 

Functions

static VOID CallInitCommonControls (VOID)
 
static VOID FASTCALL UpdateProgressBar (HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
 
static INT_PTR CALLBACK EndNowDlgProc (HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
 
static DWORD WINAPI EndNowThreadProc (LPVOID Parameter)
 
static DWORD WINAPI SendClientShutdown (LPVOID Parameter)
 
static BOOL NotifyTopLevelWindow (HWND Wnd, PNOTIFY_CONTEXT NotifyContext)
 
static BOOLEAN IsConsoleMode (VOID)
 
static BOOL ThreadShutdownNotify (IN PCSR_THREAD CsrThread, IN ULONG Flags, IN ULONG Flags2, IN PNOTIFY_CONTEXT Context)
 
static ULONG NotifyUserProcessForShutdown (PCSR_PROCESS CsrProcess, PSHUTDOWN_SETTINGS ShutdownSettings, UINT Flags)
 
static NTSTATUS FASTCALL UserExitReactOS (PCSR_THREAD CsrThread, UINT Flags)
 
ULONG NTAPI UserClientShutdown (IN PCSR_PROCESS CsrProcess, IN ULONG Flags, IN BOOLEAN FirstPhase)
 
 CSR_API (SrvExitWindowsEx)
 
 CSR_API (SrvEndTask)
 
 CSR_API (SrvRecordShutdownReason)
 

Variables

static HMODULE hComCtl32Lib = NULL
 

Macro Definition Documentation

◆ MY_DPRINT

#define MY_DPRINT   DPRINT1

Definition at line 32 of file shutdown.c.

◆ MY_DPRINT2

#define MY_DPRINT2   DPRINT

Definition at line 33 of file shutdown.c.

◆ NDEBUG

#define NDEBUG

Definition at line 18 of file shutdown.c.

◆ QUERY_RESULT_ABORT

#define QUERY_RESULT_ABORT   0

Definition at line 52 of file shutdown.c.

◆ QUERY_RESULT_CONTINUE

#define QUERY_RESULT_CONTINUE   1

Definition at line 53 of file shutdown.c.

◆ QUERY_RESULT_ERROR

#define QUERY_RESULT_ERROR   3

Definition at line 55 of file shutdown.c.

◆ QUERY_RESULT_FORCE

#define QUERY_RESULT_FORCE   4

Definition at line 56 of file shutdown.c.

◆ QUERY_RESULT_TIMEOUT

#define QUERY_RESULT_TIMEOUT   2

Definition at line 54 of file shutdown.c.

◆ SHUTDOWN_OTHERCONTEXT

#define SHUTDOWN_OTHERCONTEXT   CsrShutdownOther

Definition at line 28 of file shutdown.c.

◆ SHUTDOWN_SYSTEMCONTEXT

#define SHUTDOWN_SYSTEMCONTEXT   CsrShutdownSystem

Definition at line 27 of file shutdown.c.

Typedef Documentation

◆ INITCOMMONCONTROLS_PROC

typedef void(WINAPI * INITCOMMONCONTROLS_PROC) (void)

Definition at line 58 of file shutdown.c.

◆ MESSAGE_CONTEXT

◆ NOTIFY_CONTEXT

◆ PMESSAGE_CONTEXT

◆ PNOTIFY_CONTEXT

Function Documentation

◆ CallInitCommonControls()

static VOID CallInitCommonControls ( VOID  )
static

Definition at line 75 of file shutdown.c.

76{
77 static BOOL Initialized = FALSE;
79
80 if (Initialized) return;
81
82 hComCtl32Lib = LoadLibraryW(L"COMCTL32.DLL");
83 if (hComCtl32Lib == NULL) return;
84
85 InitProc = (INITCOMMONCONTROLS_PROC)GetProcAddress(hComCtl32Lib, "InitCommonControls");
86 if (InitProc == NULL) return;
87
88 (*InitProc)();
89
91}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadLibraryW(x)
Definition: compat.h:747
unsigned int BOOL
Definition: ntddk_ex.h:94
@ Initialized
Definition: ketypes.h:388
#define L(x)
Definition: ntvdm.h:50
static HMODULE hComCtl32Lib
Definition: shutdown.c:72
void(WINAPI * INITCOMMONCONTROLS_PROC)(void)
Definition: shutdown.c:58

Referenced by EndNowThreadProc().

◆ CSR_API() [1/3]

CSR_API ( SrvEndTask  )

Definition at line 827 of file shutdown.c.

828{
829 PUSER_END_TASK EndTaskRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.EndTaskRequest;
831
832 // FIXME: This is HACK-plemented!!
833 DPRINT1("SrvEndTask is HACKPLEMENTED!!\n");
834
837 NULL,
838 0);
839 if (!NT_SUCCESS(Status))
840 {
841 DPRINT1("Failed to set thread desktop!\n");
842 return Status;
843 }
844
845 SendMessageW(EndTaskRequest->WndHandle, WM_CLOSE, 0, 0);
846 // PostMessageW(EndTaskRequest->WndHandle, WM_CLOSE, 0, 0);
847
848 if (IsWindow(EndTaskRequest->WndHandle))
849 {
850 if (EndTaskRequest->Force)
851 {
852 EndTaskRequest->Success = DestroyWindow(EndTaskRequest->WndHandle);
853 EndTaskRequest->LastError = GetLastError();
854 }
855 else
856 {
857 EndTaskRequest->Success = FALSE;
858 }
859 }
860 else
861 {
862 EndTaskRequest->Success = TRUE;
863 EndTaskRequest->LastError = ERROR_SUCCESS;
864 }
865
867
868 return STATUS_SUCCESS;
869}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI NtUserSetInformationThread(IN HANDLE ThreadHandle, IN USERTHREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: ntstubs.c:673
@ UserThreadRestoreDesktop
Definition: ntuser.h:77
@ UserThreadUseActiveDesktop
Definition: ntuser.h:75
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOL Force
Definition: winmsg.h:59
DWORD LastError
Definition: winmsg.h:57
BOOL Success
Definition: winmsg.h:60
HWND WndHandle
Definition: winmsg.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
struct _USER_API_MESSAGE * PUSER_API_MESSAGE
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_CLOSE
Definition: winuser.h:1624
BOOL WINAPI DestroyWindow(_In_ HWND)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define NtCurrentThread()

◆ CSR_API() [2/3]

CSR_API ( SrvExitWindowsEx  )

Definition at line 802 of file shutdown.c.

803{
805 PUSER_EXIT_REACTOS ExitReactOSRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.ExitReactOSRequest;
806
809 NULL,
810 0);
811 if (!NT_SUCCESS(Status))
812 {
813 DPRINT1("Failed to set thread desktop!\n");
814 return Status;
815 }
816
817 Status = UserExitReactOS(CsrGetClientThread(), ExitReactOSRequest->Flags);
818 ExitReactOSRequest->Success = NT_SUCCESS(Status);
819 ExitReactOSRequest->LastError = GetLastError();
820
822
823 return Status;
824}
#define CsrGetClientThread()
Definition: csrsrv.h:77
DWORD LastError
Definition: winmsg.h:50
static NTSTATUS FASTCALL UserExitReactOS(PCSR_THREAD CsrThread, UINT Flags)
Definition: shutdown.c:610

◆ CSR_API() [3/3]

CSR_API ( SrvRecordShutdownReason  )

Definition at line 872 of file shutdown.c.

873{
874 DPRINT1("%s not yet implemented\n", __FUNCTION__);
876}
#define __FUNCTION__
Definition: types.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ EndNowDlgProc()

static INT_PTR CALLBACK EndNowDlgProc ( HWND  Dlg,
UINT  Msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 108 of file shutdown.c.

109{
111 PNOTIFY_CONTEXT NotifyContext;
113 DWORD TitleLength;
114 int Len;
116
117 switch(Msg)
118 {
119 case WM_INITDIALOG:
120 NotifyContext = (PNOTIFY_CONTEXT)lParam;
121 NotifyContext->EndNowResult = QUERY_RESULT_ABORT;
123 TitleLength = SendMessageW(NotifyContext->WndClient, WM_GETTEXTLENGTH,
124 0, 0) +
126 Title = HeapAlloc(UserServerHeap, 0, (TitleLength + 1) * sizeof(WCHAR));
127 if (Title)
128 {
129 Len = GetWindowTextW(Dlg, Title, TitleLength + 1);
130 SendMessageW(NotifyContext->WndClient, WM_GETTEXT,
131 TitleLength + 1 - Len, (LPARAM)(Title + Len));
132 SetWindowTextW(Dlg, Title);
134 }
137 NotifyContext->ShutdownSettings->WaitToKillAppTimeout / 2);
138 UpdateProgressBar(ProgressBar, NotifyContext);
139 SetTimer(Dlg, 0, 200, NULL);
140 Result = FALSE;
141 break;
142
143 case WM_TIMER:
144 NotifyContext = (PNOTIFY_CONTEXT)GetWindowLongPtrW(Dlg, DWLP_USER);
146 UpdateProgressBar(ProgressBar, NotifyContext);
147 Result = TRUE;
148 break;
149
150 case WM_COMMAND:
152 {
153 NotifyContext = (PNOTIFY_CONTEXT)GetWindowLongPtrW(Dlg, DWLP_USER);
154 NotifyContext->EndNowResult = QUERY_RESULT_FORCE;
155 MY_DPRINT("Closing progress dlg by hand\n");
156 SendMessageW(Dlg, WM_CLOSE, 0, 0);
157 Result = TRUE;
158 }
159 else
160 {
161 Result = FALSE;
162 }
163 break;
164
165 case WM_CLOSE:
166 MY_DPRINT("WM_CLOSE\n");
167 DestroyWindow(Dlg);
168 Result = TRUE;
169 break;
170
171 case WM_DESTROY:
172 MY_DPRINT("WM_DESTROY\n");
173 NotifyContext = (PNOTIFY_CONTEXT)GetWindowLongPtrW(Dlg, DWLP_USER);
174 NotifyContext->Dlg = NULL;
175 KillTimer(Dlg, 0);
176 PostQuitMessage(NotifyContext->EndNowResult);
177 Result = TRUE;
178 break;
179
180 default:
181 Result = FALSE;
182 break;
183 }
184
185 return Result;
186}
struct @1636 Msg[]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define Len
Definition: deflate.h:82
#define IDC_PROGRESS
Definition: resource.h:21
static const WCHAR Title[]
Definition: oid.c:1259
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned long DWORD
Definition: ntddk_ex.h:95
static PPROGRESSBAR ProgressBar
Definition: fmtchk.c:17
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define LOWORD(l)
Definition: pedump.c:82
#define PBM_SETRANGE32
Definition: commctrl.h:2193
PSHUTDOWN_SETTINGS ShutdownSettings
Definition: shutdown.c:49
DWORD EndNowResult
Definition: shutdown.c:45
ULONG WaitToKillAppTimeout
Definition: winsrv.h:52
int32_t INT_PTR
Definition: typedefs.h:64
#define HIWORD(l)
Definition: typedefs.h:247
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1384
HANDLE UserServerHeap
Definition: init.c:31
#define IDC_END_NOW
Definition: resource.h:16
static VOID FASTCALL UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
Definition: shutdown.c:94
#define MY_DPRINT
Definition: shutdown.c:32
#define QUERY_RESULT_FORCE
Definition: shutdown.c:56
#define QUERY_RESULT_ABORT
Definition: shutdown.c:52
struct tagNOTIFY_CONTEXT * PNOTIFY_CONTEXT
LONG_PTR LPARAM
Definition: windef.h:208
#define WM_GETTEXTLENGTH
Definition: winuser.h:1622
#define DWLP_USER
Definition: winuser.h:875
#define GetWindowLongPtrW
Definition: winuser.h:4832
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1743
#define WM_GETTEXT
Definition: winuser.h:1621
#define WM_INITDIALOG
Definition: winuser.h:1742
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#define WM_TIMER
Definition: winuser.h:1745
int WINAPI GetWindowTextLengthW(_In_ HWND)
#define BN_CLICKED
Definition: winuser.h:1928
#define WM_DESTROY
Definition: winuser.h:1612
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5358
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by EndNowThreadProc().

◆ EndNowThreadProc()

static DWORD WINAPI EndNowThreadProc ( LPVOID  Parameter)
static

Definition at line 189 of file shutdown.c.

190{
192 MSG Msg;
193
194#if 0
195 SetThreadDesktop(NotifyContext->Desktop);
196 SwitchDesktop(NotifyContext->Desktop);
197#else
198 /* For now show the end task dialog in the active desktop */
201 NULL,
202 0);
203#endif
204
208 EndNowDlgProc, (LPARAM)NotifyContext);
209 if (NotifyContext->Dlg == NULL)
210 return 0;
211
212 ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL);
213
214 while (GetMessageW(&Msg, NULL, 0, 0))
215 {
216 if (!IsDialogMessage(NotifyContext->Dlg, &Msg))
217 {
220 }
221 }
222
223 return Msg.wParam;
224}
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
HINSTANCE UserServerDllInstance
Definition: init.c:21
#define IDD_END_NOW
Definition: resource.h:10
static VOID CallInitCommonControls(VOID)
Definition: shutdown.c:75
static INT_PTR CALLBACK EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: shutdown.c:108
#define SW_SHOWNORMAL
Definition: winuser.h:773
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI SwitchDesktop(_In_ HDESK)
#define IsDialogMessage
Definition: winuser.h:5821
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define CreateDialogParam
Definition: winuser.h:5764
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define MAKEINTRESOURCE
Definition: winuser.h:591
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by NotifyTopLevelWindow().

◆ IsConsoleMode()

static BOOLEAN IsConsoleMode ( VOID  )
static

Definition at line 392 of file shutdown.c.

393{
395}
unsigned char BOOLEAN
DWORD_PTR NTAPI NtUserCallNoParam(DWORD Routine)
Definition: simplecall.c:59
#define NOPARAM_ROUTINE_ISCONSOLEMODE
Definition: ntuser.h:3580

Referenced by ThreadShutdownNotify().

◆ NotifyTopLevelWindow()

static BOOL NotifyTopLevelWindow ( HWND  Wnd,
PNOTIFY_CONTEXT  NotifyContext 
)
static

Definition at line 280 of file shutdown.c.

281{
282 MESSAGE_CONTEXT MessageContext;
283 DWORD Now, Passed;
284 DWORD Timeout, WaitStatus;
285 HANDLE MessageThread;
286 HANDLE Threads[2];
287
289
290 Now = GetTickCount();
291 if (NotifyContext->StartTime == 0)
292 NotifyContext->StartTime = Now;
293
294 /*
295 * Note: Passed is computed correctly even when GetTickCount()
296 * wraps due to unsigned arithmetic.
297 */
298 Passed = Now - NotifyContext->StartTime;
299 MessageContext.Wnd = Wnd;
300 MessageContext.Msg = NotifyContext->Msg;
301 MessageContext.wParam = NotifyContext->wParam;
302 MessageContext.lParam = NotifyContext->lParam;
303 MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
304 if (!NotifyContext->ShutdownSettings->AutoEndTasks)
305 {
306 MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
307 }
308 if (Passed < MessageContext.Timeout)
309 {
310 MessageContext.Timeout -= Passed;
311 MessageThread = CreateThread(NULL, 0, SendClientShutdown,
312 (LPVOID)&MessageContext, 0, NULL);
313 if (MessageThread == NULL)
314 {
315 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
316 return FALSE;
317 }
318 Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
319 if (Passed < Timeout)
320 {
321 Timeout -= Passed;
322 WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE);
323 }
324 else
325 {
326 WaitStatus = WAIT_TIMEOUT;
327 }
328 if (WAIT_TIMEOUT == WaitStatus)
329 {
330 NotifyContext->WndClient = Wnd;
331 if (NotifyContext->UIThread == NULL && NotifyContext->ShowUI)
332 {
333 NotifyContext->UIThread = CreateThread(NULL, 0,
335 (LPVOID)NotifyContext,
336 0, NULL);
337 }
338 Threads[0] = MessageThread;
339 Threads[1] = NotifyContext->UIThread;
340 WaitStatus = WaitForMultipleObjectsEx(NotifyContext->UIThread == NULL ?
341 1 : 2,
342 Threads, FALSE, INFINITE,
343 FALSE);
344 if (WaitStatus == WAIT_OBJECT_0)
345 {
346 if (!GetExitCodeThread(MessageThread, &NotifyContext->QueryResult))
347 {
348 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
349 }
350 }
351 else if (WaitStatus == WAIT_OBJECT_0 + 1)
352 {
353 if (!GetExitCodeThread(NotifyContext->UIThread,
354 &NotifyContext->QueryResult))
355 {
356 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
357 }
358 }
359 else
360 {
361 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
362 }
363 if (WaitStatus != WAIT_OBJECT_0)
364 {
366 }
367 }
368 else if (WaitStatus == WAIT_OBJECT_0)
369 {
370 if (!GetExitCodeThread(MessageThread,
371 &NotifyContext->QueryResult))
372 {
373 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
374 }
375 }
376 else
377 {
378 NotifyContext->QueryResult = QUERY_RESULT_ERROR;
379 }
380 CloseHandle(MessageThread);
381 }
382 else
383 {
384 NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT;
385 }
386
387 DPRINT("NotifyContext->QueryResult == %d\n", NotifyContext->QueryResult);
388 return (NotifyContext->QueryResult == QUERY_RESULT_CONTINUE);
389}
#define WAIT_TIMEOUT
Definition: dderror.h:14
#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 TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define INFINITE
Definition: serial.h:102
struct tm * Now
Definition: output.c:19
static ULONG Timeout
Definition: ping.c:61
#define DPRINT
Definition: sndvol32.h:73
HANDLE UIThread
Definition: shutdown.c:47
DWORD QueryResult
Definition: shutdown.c:43
ULONG HungAppTimeout
Definition: winsrv.h:51
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
DWORD WINAPI WaitForMultipleObjectsEx(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:169
#define QUERY_RESULT_CONTINUE
Definition: shutdown.c:53
static DWORD WINAPI SendClientShutdown(LPVOID Parameter)
Definition: shutdown.c:227
static DWORD WINAPI EndNowThreadProc(LPVOID Parameter)
Definition: shutdown.c:189
#define QUERY_RESULT_TIMEOUT
Definition: shutdown.c:54
#define QUERY_RESULT_ERROR
Definition: shutdown.c:55
#define WAIT_OBJECT_0
Definition: winbase.h:406
BOOL WINAPI SetForegroundWindow(_In_ HWND)

Referenced by ThreadShutdownNotify().

◆ NotifyUserProcessForShutdown()

static ULONG NotifyUserProcessForShutdown ( PCSR_PROCESS  CsrProcess,
PSHUTDOWN_SETTINGS  ShutdownSettings,
UINT  Flags 
)
static

Definition at line 488 of file shutdown.c.

491{
492 DWORD QueryResult = QUERY_RESULT_CONTINUE;
495 PLIST_ENTRY NextEntry;
497 BOOL FoundWindows = FALSE;
498
499 /* In case we make a forced shutdown, just kill the process */
500 if (Flags & EWX_FORCE)
502
503 Context.ShutdownSettings = ShutdownSettings;
504 Context.QueryResult = QUERY_RESULT_CONTINUE; // We continue shutdown by default.
505
506 /* Lock the process */
507 CsrLockProcessByClientId(CsrProcess->ClientId.UniqueProcess, &Process);
508
509 /* Send first the QUERYENDSESSION messages to all the threads of the process */
510 MY_DPRINT2("Sending the QUERYENDSESSION messages...\n");
511
512 NextEntry = CsrProcess->ThreadList.Flink;
513 while (NextEntry != &CsrProcess->ThreadList)
514 {
515 /* Get the current thread entry */
517
518 /* Move to the next entry */
519 NextEntry = NextEntry->Flink;
520
521 /* If the thread is being terminated, just skip it */
522 if (Thread->Flags & CsrThreadTerminated) continue;
523
524 /* Reference the thread and temporarily unlock the process */
527
528 Context.QueryResult = QUERY_RESULT_CONTINUE;
530 {
531 FoundWindows = TRUE;
532 }
533
534 /* Lock the process again and dereference the thread */
535 CsrLockProcessByClientId(CsrProcess->ClientId.UniqueProcess, &Process);
537
538 // FIXME: Analyze Context.QueryResult !!
539 if (Context.QueryResult == QUERY_RESULT_ABORT) goto Quit;
540 }
541
542 if (!FoundWindows)
543 {
544 /* We looped all threads but no top level window was found so we didn't send any message */
545 /* Let the console server run the generic process shutdown handler */
548 }
549
550 QueryResult = Context.QueryResult;
551 MY_DPRINT2("QueryResult = %s\n",
552 QueryResult == QUERY_RESULT_ABORT ? "Abort" : "Continue");
553
554 /* Now send the ENDSESSION messages to the threads */
555 MY_DPRINT2("Now sending the ENDSESSION messages...\n");
556
557 NextEntry = CsrProcess->ThreadList.Flink;
558 while (NextEntry != &CsrProcess->ThreadList)
559 {
560 /* Get the current thread entry */
562
563 /* Move to the next entry */
564 NextEntry = NextEntry->Flink;
565
566 /* If the thread is being terminated, just skip it */
567 if (Thread->Flags & CsrThreadTerminated) continue;
568
569 /* Reference the thread and temporarily unlock the process */
572
573 Context.QueryResult = QUERY_RESULT_CONTINUE;
575 (QUERY_RESULT_ABORT != QueryResult) ? MCS_ENDSESSION : 0,
576 &Context);
577
578 /* Lock the process again and dereference the thread */
579 CsrLockProcessByClientId(CsrProcess->ClientId.UniqueProcess, &Process);
581 }
582
583Quit:
584 /* Unlock the process */
586
587#if 0
588 if (Context.UIThread)
589 {
590 if (Context.Dlg)
591 {
592 SendMessageW(Context.Dlg, WM_CLOSE, 0, 0);
593 }
594 else
595 {
597 }
598 CloseHandle(Context.UIThread);
599 }
600#endif
601
602 /* Kill the process unless we abort shutdown */
603 if (QueryResult == QUERY_RESULT_ABORT)
605
607}
VOID NTAPI CsrReferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:1043
NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1410
VOID NTAPI CsrDereferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:776
NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSR_PROCESS *CsrProcess OPTIONAL)
@ CsrThreadTerminated
Definition: csrsrv.h:106
@ CsrShutdownNonCsrProcess
Definition: csrsrv.h:113
@ CsrShutdownCsrProcess
Definition: csrsrv.h:112
@ CsrShutdownCancelled
Definition: csrsrv.h:114
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define MCS_QUERYENDSESSION
Definition: undocuser.h:106
#define MCS_ENDSESSION
Definition: undocuser.h:105
static int Link(const char **args)
Definition: vfdcmd.c:2414
PKPROCESS CsrProcess
Definition: videoprt.c:39
SHUTDOWN_SETTINGS ShutdownSettings
Definition: init.c:24
#define MY_DPRINT2
Definition: shutdown.c:33
static BOOL ThreadShutdownNotify(IN PCSR_THREAD CsrThread, IN ULONG Flags, IN ULONG Flags2, IN PNOTIFY_CONTEXT Context)
Definition: shutdown.c:401
#define EWX_FORCE
Definition: winuser.h:635
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UserClientShutdown().

◆ SendClientShutdown()

static DWORD WINAPI SendClientShutdown ( LPVOID  Parameter)
static

Definition at line 227 of file shutdown.c.

228{
231
232 /* If the shutdown is aborted, just notify the process, there is no need to wait */
233 if ((Context->wParam & (MCS_QUERYENDSESSION | MCS_ENDSESSION)) == 0)
234 {
235 DPRINT("Called WM_CLIENTSHUTDOWN with wParam == 0 ...\n");
237 Context->wParam, Context->lParam);
239 }
240
242 Context->wParam, Context->lParam,
243 SMTO_NORMAL, Context->Timeout, &Result))
244 {
245 DWORD Ret;
246
247 if (Context->wParam & MCS_QUERYENDSESSION)
248 {
249 /* WM_QUERYENDSESSION case */
250 switch (Result)
251 {
253 Ret = QUERY_RESULT_ABORT;
254 break;
255
258 default:
260 }
261 }
262 else
263 {
264 /* WM_ENDSESSION case */
266 }
267
268 DPRINT("SendClientShutdown -- Return == %s\n",
269 Ret == QUERY_RESULT_CONTINUE ? "Continue" : "Abort");
270 return Ret;
271 }
272
273 DPRINT1("SendClientShutdown -- Error == %s\n",
274 GetLastError() == 0 ? "Timeout" : "error");
275
277}
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define MCSR_GOODFORSHUTDOWN
Definition: undocuser.h:108
#define MCSR_SHUTDOWNFINISHED
Definition: undocuser.h:109
#define WM_CLIENTSHUTDOWN
Definition: undocuser.h:35
#define MCSR_DONOTSHUTDOWN
Definition: undocuser.h:110
struct tagMESSAGE_CONTEXT * PMESSAGE_CONTEXT
BOOL WINAPI SendNotifyMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageTimeoutW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define SMTO_NORMAL
Definition: winuser.h:1228

Referenced by NotifyTopLevelWindow().

◆ ThreadShutdownNotify()

static BOOL ThreadShutdownNotify ( IN PCSR_THREAD  CsrThread,
IN ULONG  Flags,
IN ULONG  Flags2,
IN PNOTIFY_CONTEXT  Context 
)
static

Definition at line 401 of file shutdown.c.

405{
406 HWND TopWnd = NULL;
407
408 EnumThreadWindows(HandleToUlong(CsrThread->ClientId.UniqueThread),
409 FindTopLevelWnd, (LPARAM)&TopWnd);
410 if (TopWnd)
411 {
412 HWND hWndOwner;
413
414 /*** FOR TESTING PURPOSES ONLY!! ***/
415 HWND tmpWnd;
416 tmpWnd = TopWnd;
417 /***********************************/
418
419 while ((hWndOwner = GetWindow(TopWnd, GW_OWNER)) != NULL)
420 {
421 MY_DPRINT("GetWindow(TopWnd, GW_OWNER) not returned NULL...\n");
422 TopWnd = hWndOwner;
423 }
424 if (TopWnd != tmpWnd) MY_DPRINT("(TopWnd = %x) != (tmpWnd = %x)\n", TopWnd, tmpWnd);
425 }
426 else
427 {
428 return FALSE;
429 }
430
431 Context->wParam = Flags2;
432 Context->lParam = (0 != (Flags & EWX_CALLER_WINLOGON_LOGOFF) ?
433 ENDSESSION_LOGOFF : 0);
434
435 Context->StartTime = 0;
436 Context->UIThread = NULL;
438 Context->Dlg = NULL;
439
440#if 0 // Obviously, switching desktops like that from within WINSRV doesn't work...
441 {
444 // Context->Desktop = GetThreadDesktop(HandleToUlong(CsrThread->ClientId.UniqueThread));
446 MY_DPRINT("Last error = %d\n", GetLastError());
447 MY_DPRINT("Before switching to desktop 0x%x\n", Context->Desktop);
448 Success = SwitchDesktop(Context->Desktop);
449 MY_DPRINT("After switching to desktop (Success = %s ; last error = %d); going to notify top-level...\n",
450 Success ? "TRUE" : "FALSE", GetLastError());
451 }
452#endif
453
455
456/******************************************************************************/
457#if 1
458 if (Context->UIThread)
459 {
460 MY_DPRINT("Context->UIThread != NULL\n");
461 if (Context->Dlg)
462 {
463 MY_DPRINT("Sending WM_CLOSE because Dlg is != NULL\n");
464 SendMessageW(Context->Dlg, WM_CLOSE, 0, 0);
465 }
466 else
467 {
468 MY_DPRINT("Terminating UIThread thread with QUERY_RESULT_ERROR\n");
470 }
471 CloseHandle(Context->UIThread);
472 Context->UIThread = NULL;
473 Context->Dlg = NULL;
474 }
475#endif
476/******************************************************************************/
477
478#if 0
479 MY_DPRINT("Switch back to old desktop 0x%x\n", Context->OldDesktop);
480 SwitchDesktop(Context->OldDesktop);
481 MY_DPRINT("Switched back ok\n");
482#endif
483
484 return TRUE;
485}
#define HandleToUlong(h)
Definition: basetsd.h:79
@ Success
Definition: eventcreate.c:712
localAdvHdr Flags2
Definition: fsrtlfuncs.h:1692
#define EWX_CALLER_WINLOGON_LOGOFF
Definition: undocuser.h:130
BOOL CALLBACK FindTopLevelWnd(IN HWND hWnd, IN LPARAM lParam)
Definition: init.c:94
static BOOL NotifyTopLevelWindow(HWND Wnd, PNOTIFY_CONTEXT NotifyContext)
Definition: shutdown.c:280
static BOOLEAN IsConsoleMode(VOID)
Definition: shutdown.c:392
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
#define GW_OWNER
Definition: winuser.h:769
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
BOOL WINAPI EnumThreadWindows(_In_ DWORD, _In_ WNDENUMPROC, _In_ LPARAM)

Referenced by NotifyUserProcessForShutdown().

◆ UpdateProgressBar()

static VOID FASTCALL UpdateProgressBar ( HWND  ProgressBar,
PNOTIFY_CONTEXT  NotifyContext 
)
static

Definition at line 94 of file shutdown.c.

95{
96 DWORD Passed;
97
98 Passed = GetTickCount() - NotifyContext->StartTime;
99 Passed -= NotifyContext->ShutdownSettings->HungAppTimeout;
100 if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed)
101 {
102 Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
103 }
104 SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0);
105}
#define PBM_SETPOS
Definition: commctrl.h:2189

Referenced by EndNowDlgProc().

◆ UserClientShutdown()

ULONG NTAPI UserClientShutdown ( IN PCSR_PROCESS  CsrProcess,
IN ULONG  Flags,
IN BOOLEAN  FirstPhase 
)

Definition at line 732 of file shutdown.c.

735{
737
738 DPRINT("UserClientShutdown(0x%p, 0x%x, %s) - [0x%x, 0x%x], ShutdownFlags: %lu\n",
739 CsrProcess, Flags, FirstPhase ? "FirstPhase" : "LastPhase",
740 CsrProcess->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueThread,
741 CsrProcess->ShutdownFlags);
742
743 /*
744 * Check for process validity
745 */
746
747 /* Do not kill system processes when a user is logging off */
748 if ((Flags & EWX_SHUTDOWN) == EWX_LOGOFF &&
750 {
751 DPRINT("Do not kill a system process in a logoff request!\n");
753 }
754
755 /* Do not kill Winlogon */
756 if (CsrProcess->ClientId.UniqueProcess == UlongToHandle(LogonProcessId))
757 {
758 DPRINT("Not killing Winlogon; CsrProcess->ShutdownFlags = %lu\n",
759 CsrProcess->ShutdownFlags);
760
761 /* Returning CsrShutdownCsrProcess means that we handled this process by doing nothing */
762 /* This will mark winlogon as processed so consrv won't be notified again for it */
765 }
766
767 /* Notify the process for shutdown if needed */
770 {
772 DPRINT1("Process 0x%x aborted shutdown\n", CsrProcess->ClientId.UniqueProcess);
773 return result;
774 }
775
776 /* Terminate this process */
777#if DBG
778 {
781 {
782 DPRINT1("Terminating process %x\n", CsrProcess->ClientId.UniqueProcess);
783 }
784 else
785 {
786 DPRINT1("Terminating process %x (%S)\n", CsrProcess->ClientId.UniqueProcess, buffer);
787 }
788 }
789#endif
790 NtTerminateProcess(CsrProcess->ProcessHandle, 0);
792
793 /* We are done */
796}
#define UlongToHandle(ul)
Definition: basetsd.h:97
VOID NTAPI CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:691
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetProcessImageFileNameW(HANDLE hProcess, LPWSTR lpImageFileName, DWORD nSize)
Definition: psapi.c:1163
GLuint buffer
Definition: glext.h:5915
GLuint64EXT * result
Definition: glext.h:11304
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
ULONG ProcessTerminateTimeout
Definition: winsrv.h:54
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t ULONG
Definition: typedefs.h:59
ULONG_PTR LogonProcessId
Definition: register.c:21
#define SHUTDOWN_OTHERCONTEXT
Definition: shutdown.c:28
#define SHUTDOWN_SYSTEMCONTEXT
Definition: shutdown.c:27
static ULONG NotifyUserProcessForShutdown(PCSR_PROCESS CsrProcess, PSHUTDOWN_SETTINGS ShutdownSettings, UINT Flags)
Definition: shutdown.c:488
#define EWX_SHUTDOWN
Definition: winuser.h:639
#define EWX_LOGOFF
Definition: winuser.h:636

Referenced by CSR_SERVER_DLL_INIT().

◆ UserExitReactOS()

static NTSTATUS FASTCALL UserExitReactOS ( PCSR_THREAD  CsrThread,
UINT  Flags 
)
static

Definition at line 610 of file shutdown.c.

611{
613 LUID CallerLuid;
614
616 DWORD ThreadId = HandleToUlong(CsrThread->ClientId.UniqueThread);
617
618 DPRINT1("SrvExitWindowsEx(ClientId: %lx.%lx, Flags: 0x%x)\n",
619 ProcessId, ThreadId, Flags);
620
621 /*
622 * Check for flags validity
623 */
624
626 {
627 /* Only Winlogon can call this */
629 {
630 DPRINT1("SrvExitWindowsEx call not from Winlogon\n");
632 }
633 }
634
635 /* Implicitely add the shutdown flag when we poweroff or reboot */
636 if (Flags & (EWX_POWEROFF | EWX_REBOOT))
638
639 /*
640 * Impersonate and retrieve the caller's LUID so that
641 * we can only shutdown processes in its context.
642 */
645
646 Status = CsrGetProcessLuid(NULL, &CallerLuid);
647 if (!NT_SUCCESS(Status))
648 {
649 DPRINT1("Unable to get caller LUID, Status = 0x%08x\n", Status);
650 goto Quit;
651 }
652
653 DPRINT("Caller LUID is: %lx.%lx\n", CallerLuid.HighPart, CallerLuid.LowPart);
654
655 /* Shutdown loop */
656 while (TRUE)
657 {
658 /* Notify Win32k and potentially Winlogon of the shutdown */
661 &Flags, sizeof(Flags));
662 DPRINT("Win32k says: %lx\n", Status);
663 switch (Status)
664 {
665 /* We cannot wait here, the caller should start a new thread */
666 case STATUS_CANT_WAIT:
667 DPRINT1("NtUserSetInformationThread returned STATUS_CANT_WAIT\n");
668 goto Quit;
669
670 /* Shutdown is in progress */
671 case STATUS_PENDING:
672 DPRINT1("NtUserSetInformationThread returned STATUS_PENDING\n");
673 goto Quit;
674
675 /* Abort */
676 case STATUS_RETRY:
677 {
678 DPRINT1("NtUserSetInformationThread returned STATUS_RETRY\n");
680 continue;
681 }
682
683 default:
684 {
685 if (!NT_SUCCESS(Status))
686 {
687 // FIXME: Use some UserSetLastNTError or SetLastNtError
688 // that we have defined for user32 or win32k usage only...
690 goto Quit;
691 }
692 }
693 }
694
695 /* All good */
696 break;
697 }
698
699 /*
700 * OK we can continue. Now magic happens:
701 *
702 * Terminate all Win32 processes, stop if we find one kicking
703 * and screaming it doesn't want to die.
704 *
705 * This function calls the ShutdownProcessCallback callback of
706 * each CSR server for each Win32 process.
707 */
708 Status = CsrShutdownProcesses(&CallerLuid, Flags);
709 if (!NT_SUCCESS(Status))
710 {
711 DPRINT1("Failed to shutdown processes, Status = 0x%08x\n", Status);
712 }
713
714 // FIXME: If Status == STATUS_CANCELLED, call RecordShutdownReason
715
716 /* Tell Win32k and potentially Winlogon that we're done */
719 &Status, sizeof(Status));
720
721 DPRINT("SrvExitWindowsEx returned 0x%08x\n", Status);
722
723Quit:
724 /* We are done */
726 return Status;
727}
#define UNIMPLEMENTED
Definition: debug.h:118
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
NTSTATUS NTAPI CsrShutdownProcesses(IN PLUID CallerLuid, IN ULONG Flags)
Definition: procsup.c:1277
NTSTATUS NTAPI CsrGetProcessLuid(IN HANDLE hProcess OPTIONAL, OUT PLUID Luid)
Definition: procsup.c:828
#define SetLastError(x)
Definition: compat.h:752
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
@ UserThreadEndShutdown
Definition: ntuser.h:74
@ UserThreadInitiateShutdown
Definition: ntuser.h:73
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
HANDLE ThreadHandle
Definition: csrsrv.h:71
CLIENT_ID ClientId
Definition: csrsrv.h:68
LONG HighPart
DWORD LowPart
#define STATUS_RETRY
Definition: udferr_usr.h:182
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:129
#define EWX_POWEROFF
Definition: winuser.h:637
#define EWX_REBOOT
Definition: winuser.h:638

Referenced by CSR_API().

Variable Documentation

◆ hComCtl32Lib

HMODULE hComCtl32Lib = NULL
static

Definition at line 72 of file shutdown.c.

Referenced by CallInitCommonControls().