2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/shutdown.c
5 * PURPOSE: System shutdown dialog
6 * PROGRAMMERS: alpha5056 <alpha5056@users.noreply.github.com>
9 /* INCLUDES ******************************************************************/
13 #include <ntstrsafe.h>
17 /* DEFINES *******************************************************************/
19 #define IDT_SYSSHUTDOWN 2000
21 /* STRUCTS *******************************************************************/
23 typedef struct _SYS_SHUTDOWN_PARAMS
25 UNICODE_STRING usMessage
;
27 BOOLEAN bRebootAfterShutdown
;
28 BOOLEAN bForceAppsClosed
;
32 BOOLEAN bShuttingDown
;
33 } SYS_SHUTDOWN_PARAMS
, *PSYS_SHUTDOWN_PARAMS
;
35 /* GLOBALS *******************************************************************/
37 SYS_SHUTDOWN_PARAMS g_ShutdownParams
;
39 /* FUNCTIONS *****************************************************************/
45 PSYS_SHUTDOWN_PARAMS pShutdownParams
)
48 INT seconds
, minutes
, hours
;
50 seconds
= (INT
)pShutdownParams
->dwTimeout
;
51 hours
= seconds
/ 3600;
52 seconds
-= hours
* 3600;
53 minutes
= seconds
/ 60;
54 seconds
-= minutes
* 60;
56 RtlStringCbPrintfW(strbuf
, sizeof(strbuf
), L
"%d:%d:%d", hours
, minutes
, seconds
);
57 SetDlgItemTextW(hwndDlg
, IDC_SHUTDOWNTIMELEFT
, strbuf
);
59 if (pShutdownParams
->dwTimeout
== 0)
61 PostMessage(hwndDlg
, WM_CLOSE
, 0, 0);
62 ExitWindowsEx((pShutdownParams
->bRebootAfterShutdown
? EWX_REBOOT
: EWX_SHUTDOWN
) |
63 (pShutdownParams
->bForceAppsClosed
? EWX_FORCE
: 0),
64 pShutdownParams
->dwReason
);
67 pShutdownParams
->dwTimeout
--;
80 PSYS_SHUTDOWN_PARAMS pShutdownParams
;
82 pShutdownParams
= (PSYS_SHUTDOWN_PARAMS
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
87 pShutdownParams
= (PSYS_SHUTDOWN_PARAMS
)lParam
;
88 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pShutdownParams
);
90 pShutdownParams
->hShutdownDialog
= hwndDlg
;
92 if (pShutdownParams
->usMessage
.Length
)
94 SetDlgItemTextW(hwndDlg
,
96 pShutdownParams
->usMessage
.Buffer
);
98 RemoveMenu(GetSystemMenu(hwndDlg
, FALSE
), SC_CLOSE
, MF_BYCOMMAND
);
99 SetWindowPos(hwndDlg
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
);
100 PostMessage(hwndDlg
, WM_TIMER
, 0, 0);
101 SetTimer(hwndDlg
, IDT_SYSSHUTDOWN
, 1000, NULL
);
105 pShutdownParams
->hShutdownDialog
= NULL
;
106 pShutdownParams
->bShuttingDown
= FALSE
;
108 KillTimer(hwndDlg
, IDT_SYSSHUTDOWN
);
110 if (pShutdownParams
->usMessage
.Buffer
)
112 HeapFree(GetProcessHeap(), 0, pShutdownParams
->usMessage
.Buffer
);
113 RtlInitEmptyUnicodeString(&pShutdownParams
->usMessage
, NULL
, 0);
116 EndDialog(hwndDlg
, 0);
120 OnTimer(hwndDlg
, pShutdownParams
);
134 InitiateSystemShutdownThread(
137 PSYS_SHUTDOWN_PARAMS pShutdownParams
;
140 pShutdownParams
= (PSYS_SHUTDOWN_PARAMS
)lpParameter
;
142 status
= DialogBoxParamW(hAppInstance
,
143 MAKEINTRESOURCEW(IDD_SYSSHUTDOWN
),
146 (LPARAM
)pShutdownParams
);
149 return ERROR_SUCCESS
;
152 if (pShutdownParams
->usMessage
.Buffer
)
154 HeapFree(GetProcessHeap(), 0, pShutdownParams
->usMessage
.Buffer
);
155 RtlInitEmptyUnicodeString(&pShutdownParams
->usMessage
, NULL
, 0);
157 pShutdownParams
->bShuttingDown
= FALSE
;
159 return GetLastError();
164 TerminateSystemShutdown(VOID
)
166 if (g_ShutdownParams
.bShuttingDown
== FALSE
)
167 return ERROR_NO_SHUTDOWN_IN_PROGRESS
;
169 return PostMessage(g_ShutdownParams
.hShutdownDialog
, WM_CLOSE
, 0, 0) ? ERROR_SUCCESS
: GetLastError();
175 PUNICODE_STRING lpMessage
,
177 BOOLEAN bForceAppsClosed
,
178 BOOLEAN bRebootAfterShutdown
,
183 if (_InterlockedCompareExchange8((volatile char*)&g_ShutdownParams
.bShuttingDown
, TRUE
, FALSE
) == TRUE
)
184 return ERROR_SHUTDOWN_IN_PROGRESS
;
186 if (lpMessage
&& lpMessage
->Length
&& lpMessage
->Buffer
)
188 g_ShutdownParams
.usMessage
.Buffer
= HeapAlloc(GetProcessHeap(), 0, lpMessage
->Length
+ sizeof(UNICODE_NULL
));
189 if (g_ShutdownParams
.usMessage
.Buffer
== NULL
)
191 g_ShutdownParams
.bShuttingDown
= FALSE
;
192 return GetLastError();
195 RtlInitEmptyUnicodeString(&g_ShutdownParams
.usMessage
, g_ShutdownParams
.usMessage
.Buffer
, lpMessage
->Length
+ sizeof(UNICODE_NULL
));
196 RtlCopyUnicodeString(&(g_ShutdownParams
.usMessage
), (PUNICODE_STRING
)lpMessage
);
200 RtlInitEmptyUnicodeString(&g_ShutdownParams
.usMessage
, NULL
, 0);
203 g_ShutdownParams
.dwTimeout
= dwTimeout
;
204 g_ShutdownParams
.bForceAppsClosed
= bForceAppsClosed
;
205 g_ShutdownParams
.bRebootAfterShutdown
= bRebootAfterShutdown
;
206 g_ShutdownParams
.dwReason
= dwReason
;
208 hThread
= CreateThread(NULL
, 0, InitiateSystemShutdownThread
, (PVOID
)&g_ShutdownParams
, 0, NULL
);
211 CloseHandle(hThread
);
212 return ERROR_SUCCESS
;
215 if (g_ShutdownParams
.usMessage
.Buffer
)
217 HeapFree(GetProcessHeap(), 0, g_ShutdownParams
.usMessage
.Buffer
);
218 RtlInitEmptyUnicodeString(&g_ShutdownParams
.usMessage
, NULL
, 0);
221 g_ShutdownParams
.bShuttingDown
= FALSE
;
223 return GetLastError();