ReactOS 0.4.15-dev-7113-g9ea2222
shutdown.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User API Server DLL
4 * FILE: win32ss/user/winsrv/usersrv/shutdown.c
5 * PURPOSE: Logout/shutdown
6 * PROGRAMMERS:
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "usersrv.h"
12
13#include <commctrl.h>
14#include <psapi.h>
15
16#include "resource.h"
17
18#define NDEBUG
19#include <debug.h>
20
21/* GLOBALS ********************************************************************/
22
23// Those flags (that are used for CsrProcess->ShutdownFlags) are named
24// in accordance to the only public one: SHUTDOWN_NORETRY used for the
25// SetProcessShutdownParameters API.
26#if !defined(SHUTDOWN_SYSTEMCONTEXT) && !defined(SHUTDOWN_OTHERCONTEXT)
27#define SHUTDOWN_SYSTEMCONTEXT CsrShutdownSystem
28#define SHUTDOWN_OTHERCONTEXT CsrShutdownOther
29#endif
30
31// The DPRINTs that need to really be removed as soon as everything works.
32#define MY_DPRINT DPRINT1
33#define MY_DPRINT2 DPRINT
34
35typedef struct tagNOTIFY_CONTEXT
36{
40 // HDESK Desktop;
41 // HDESK OldDesktop;
51
52#define QUERY_RESULT_ABORT 0
53#define QUERY_RESULT_CONTINUE 1
54#define QUERY_RESULT_TIMEOUT 2
55#define QUERY_RESULT_ERROR 3
56#define QUERY_RESULT_FORCE 4
57
59
60typedef struct tagMESSAGE_CONTEXT
61{
68
69
70/* FUNCTIONS ******************************************************************/
71
73
74static VOID
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}
92
93static VOID FASTCALL
94UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
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}
106
107static INT_PTR CALLBACK
109{
111 PNOTIFY_CONTEXT NotifyContext;
112 HWND ProgressBar;
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 }
135 ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
136 SendMessageW(ProgressBar, PBM_SETRANGE32, 0,
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);
145 ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
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}
187
188static DWORD WINAPI
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}
225
226static DWORD WINAPI
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}
278
279static BOOL
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}
390
391static BOOLEAN
393{
395}
396
397/************************************************/
398
399
400static BOOL
402 IN ULONG Flags,
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}
486
487static ULONG
490 UINT Flags)
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}
608
609static NTSTATUS FASTCALL
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}
728
729
730ULONG
731NTAPI
733 IN ULONG Flags,
734 IN BOOLEAN FirstPhase)
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 {
780 if (!GetProcessImageFileNameW(CsrProcess->ProcessHandle, buffer, MAX_PATH))
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);
791
793
794 /* We are done */
797}
798
799
800/* PUBLIC SERVER APIS *********************************************************/
801
802/* API_NUMBER: UserpExitWindowsEx */
803CSR_API(SrvExitWindowsEx)
804{
806 PUSER_EXIT_REACTOS ExitReactOSRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.ExitReactOSRequest;
807
810 NULL,
811 0);
812 if (!NT_SUCCESS(Status))
813 {
814 DPRINT1("Failed to set thread desktop!\n");
815 return Status;
816 }
817
818 Status = UserExitReactOS(CsrGetClientThread(), ExitReactOSRequest->Flags);
819 ExitReactOSRequest->Success = NT_SUCCESS(Status);
820 ExitReactOSRequest->LastError = GetLastError();
821
823
824 return Status;
825}
826
827/* API_NUMBER: UserpEndTask */
828CSR_API(SrvEndTask)
829{
830 PUSER_END_TASK EndTaskRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.EndTaskRequest;
832
833 // FIXME: This is HACK-plemented!!
834 DPRINT1("SrvEndTask is HACKPLEMENTED!!\n");
835
838 NULL,
839 0);
840 if (!NT_SUCCESS(Status))
841 {
842 DPRINT1("Failed to set thread desktop!\n");
843 return Status;
844 }
845
846 SendMessageW(EndTaskRequest->WndHandle, WM_CLOSE, 0, 0);
847 // PostMessageW(EndTaskRequest->WndHandle, WM_CLOSE, 0, 0);
848
849 if (IsWindow(EndTaskRequest->WndHandle))
850 {
851 if (EndTaskRequest->Force)
852 {
853 EndTaskRequest->Success = DestroyWindow(EndTaskRequest->WndHandle);
854 EndTaskRequest->LastError = GetLastError();
855 }
856 else
857 {
858 EndTaskRequest->Success = FALSE;
859 }
860 }
861 else
862 {
863 EndTaskRequest->Success = TRUE;
864 EndTaskRequest->LastError = ERROR_SUCCESS;
865 }
866
868
869 return STATUS_SUCCESS;
870}
871
872/* API_NUMBER: UserpRecordShutdownReason */
873CSR_API(SrvRecordShutdownReason)
874{
875 DPRINT1("%s not yet implemented\n", __FUNCTION__);
877}
878
879/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define HandleToUlong(h)
Definition: basetsd.h:79
#define UNIMPLEMENTED
Definition: debug.h:115
struct @1619 Msg[]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
VOID NTAPI CsrReferenceThread(IN PCSR_THREAD CsrThread)
Definition: thredsup.c:1043
NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1410
#define CsrGetClientThread()
Definition: csrsrv.h:77
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
#define CSR_API(n)
Definition: csrsrv.h:176
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
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
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
@ CsrShutdownNonCsrProcess
Definition: csrsrv.h:113
@ CsrShutdownCsrProcess
Definition: csrsrv.h:112
@ CsrShutdownCancelled
Definition: csrsrv.h:114
VOID NTAPI CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:691
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define Len
Definition: deflate.h:82
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IDC_PROGRESS
Definition: resource.h:21
static const WCHAR Title[]
Definition: oid.c:1259
#define CloseHandle
Definition: compat.h:739
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define LoadLibraryW(x)
Definition: compat.h:747
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
DWORD WINAPI GetProcessImageFileNameW(HANDLE hProcess, LPWSTR lpImageFileName, DWORD nSize)
Definition: psapi.c:1163
#define __FUNCTION__
Definition: types.h:116
#define INFINITE
Definition: serial.h:102
@ Success
Definition: eventcreate.c:712
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
localAdvHdr Flags2
Definition: fsrtlfuncs.h:1692
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLuint buffer
Definition: glext.h:5915
GLuint64EXT * result
Definition: glext.h:11304
NTSTATUS NTAPI NtUserSetInformationThread(IN HANDLE ThreadHandle, IN USERTHREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: ntstubs.c:673
DWORD_PTR NTAPI NtUserCallNoParam(DWORD Routine)
Definition: simplecall.c:59
#define NOPARAM_ROUTINE_ISCONSOLEMODE
Definition: ntuser.h:3600
@ UserThreadEndShutdown
Definition: ntuser.h:74
@ UserThreadRestoreDesktop
Definition: ntuser.h:77
@ UserThreadInitiateShutdown
Definition: ntuser.h:73
@ UserThreadUseActiveDesktop
Definition: ntuser.h:75
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
@ Initialized
Definition: ketypes.h:388
#define FASTCALL
Definition: nt_native.h:50
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
#define L(x)
Definition: ntvdm.h:50
struct tm * Now
Definition: output.c:19
#define LOWORD(l)
Definition: pedump.c:82
static ULONG Timeout
Definition: ping.c:61
#define PBM_SETRANGE32
Definition: commctrl.h:2188
#define PBM_SETPOS
Definition: commctrl.h:2184
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
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
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LONG HighPart
DWORD LowPart
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 LastError
Definition: winmsg.h:50
HANDLE UIThread
Definition: shutdown.c:47
PSHUTDOWN_SETTINGS ShutdownSettings
Definition: shutdown.c:49
DWORD EndNowResult
Definition: shutdown.c:45
DWORD QueryResult
Definition: shutdown.c:43
ULONG HungAppTimeout
Definition: winsrv.h:49
ULONG WaitToKillAppTimeout
Definition: winsrv.h:50
ULONG ProcessTerminateTimeout
Definition: winsrv.h:52
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define STATUS_RETRY
Definition: udferr_usr.h:182
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define MCSR_GOODFORSHUTDOWN
Definition: undocuser.h:108
#define MCS_QUERYENDSESSION
Definition: undocuser.h:106
#define MCSR_SHUTDOWNFINISHED
Definition: undocuser.h:109
#define MCS_ENDSESSION
Definition: undocuser.h:105
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:129
#define WM_CLIENTSHUTDOWN
Definition: undocuser.h:35
#define EWX_CALLER_WINLOGON_LOGOFF
Definition: undocuser.h:130
#define MCSR_DONOTSHUTDOWN
Definition: undocuser.h:110
static int Link(const char **args)
Definition: vfdcmd.c:2414
PKPROCESS CsrProcess
Definition: videoprt.c:39
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
SHUTDOWN_SETTINGS ShutdownSettings
Definition: init.c:24
BOOL CALLBACK FindTopLevelWnd(IN HWND hWnd, IN LPARAM lParam)
Definition: init.c:94
HANDLE UserServerHeap
Definition: init.c:31
HINSTANCE UserServerDllInstance
Definition: init.c:21
ULONG_PTR LogonProcessId
Definition: register.c:21
#define IDC_END_NOW
Definition: resource.h:16
#define IDD_END_NOW
Definition: resource.h:10
#define QUERY_RESULT_CONTINUE
Definition: shutdown.c:53
static DWORD WINAPI SendClientShutdown(LPVOID Parameter)
Definition: shutdown.c:227
static VOID CallInitCommonControls(VOID)
Definition: shutdown.c:75
static VOID FASTCALL UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
Definition: shutdown.c:94
struct tagMESSAGE_CONTEXT MESSAGE_CONTEXT
static NTSTATUS FASTCALL UserExitReactOS(PCSR_THREAD CsrThread, UINT Flags)
Definition: shutdown.c:610
#define SHUTDOWN_OTHERCONTEXT
Definition: shutdown.c:28
struct tagMESSAGE_CONTEXT * PMESSAGE_CONTEXT
#define MY_DPRINT2
Definition: shutdown.c:33
static BOOL NotifyTopLevelWindow(HWND Wnd, PNOTIFY_CONTEXT NotifyContext)
Definition: shutdown.c:280
#define MY_DPRINT
Definition: shutdown.c:32
static DWORD WINAPI EndNowThreadProc(LPVOID Parameter)
Definition: shutdown.c:189
static BOOLEAN IsConsoleMode(VOID)
Definition: shutdown.c:392
struct tagNOTIFY_CONTEXT NOTIFY_CONTEXT
static INT_PTR CALLBACK EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: shutdown.c:108
#define QUERY_RESULT_TIMEOUT
Definition: shutdown.c:54
static HMODULE hComCtl32Lib
Definition: shutdown.c:72
void(WINAPI * INITCOMMONCONTROLS_PROC)(void)
Definition: shutdown.c:58
#define QUERY_RESULT_FORCE
Definition: shutdown.c:56
#define QUERY_RESULT_ABORT
Definition: shutdown.c:52
#define SHUTDOWN_SYSTEMCONTEXT
Definition: shutdown.c:27
#define QUERY_RESULT_ERROR
Definition: shutdown.c:55
ULONG NTAPI UserClientShutdown(IN PCSR_PROCESS CsrProcess, IN ULONG Flags, IN BOOLEAN FirstPhase)
Definition: shutdown.c:732
struct tagNOTIFY_CONTEXT * PNOTIFY_CONTEXT
static BOOL ThreadShutdownNotify(IN PCSR_THREAD CsrThread, IN ULONG Flags, IN ULONG Flags2, IN PNOTIFY_CONTEXT Context)
Definition: shutdown.c:401
static ULONG NotifyUserProcessForShutdown(PCSR_PROCESS CsrProcess, PSHUTDOWN_SETTINGS ShutdownSettings, UINT Flags)
Definition: shutdown.c:488
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
#define WAIT_OBJECT_0
Definition: winbase.h:406
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
struct _USER_API_MESSAGE * PUSER_API_MESSAGE
#define SW_SHOWNORMAL
Definition: winuser.h:769
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
#define GW_OWNER
Definition: winuser.h:766
#define EWX_POWEROFF
Definition: winuser.h:637
#define EWX_SHUTDOWN
Definition: winuser.h:639
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_GETTEXTLENGTH
Definition: winuser.h:1618
#define WM_CLOSE
Definition: winuser.h:1620
BOOL WINAPI SendNotifyMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DWLP_USER
Definition: winuser.h:871
#define GetWindowLongPtrW
Definition: winuser.h:4828
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI SwitchDesktop(_In_ HDESK)
#define IsDialogMessage
Definition: winuser.h:5808
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1739
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define EWX_LOGOFF
Definition: winuser.h:636
#define CreateDialogParam
Definition: winuser.h:5751
#define WM_GETTEXT
Definition: winuser.h:1617
#define WM_INITDIALOG
Definition: winuser.h:1738
LRESULT WINAPI SendMessageTimeoutW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
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 EWX_REBOOT
Definition: winuser.h:638
#define WM_TIMER
Definition: winuser.h:1741
#define EWX_FORCE
Definition: winuser.h:635
int WINAPI GetWindowTextLengthW(_In_ HWND)
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define BN_CLICKED
Definition: winuser.h:1924
#define WM_DESTROY
Definition: winuser.h:1608
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
BOOL WINAPI EnumThreadWindows(_In_ DWORD, _In_ WNDENUMPROC, _In_ LPARAM)
#define SetWindowLongPtrW
Definition: winuser.h:5345
BOOL WINAPI DestroyWindow(_In_ HWND)
#define MAKEINTRESOURCE
Definition: winuser.h:591
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SMTO_NORMAL
Definition: winuser.h:1224
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define NtCurrentThread()