ReactOS 0.4.15-dev-7918-g2a2556c
shutdown.c File Reference
#include "winlogon.h"
#include <rpc.h>
#include <winreg_s.h>
Include dependency graph for shutdown.c:

Go to the source code of this file.

Classes

struct  _SYS_SHUTDOWN_PARAMS
 

Macros

#define SHUTDOWN_TIMER_ID   2000
 
#define SECONDS_PER_DAY   86400
 
#define SECONDS_PER_DECADE   315360000
 

Typedefs

typedef struct _SYS_SHUTDOWN_PARAMS SYS_SHUTDOWN_PARAMS
 
typedef struct _SYS_SHUTDOWN_PARAMSPSYS_SHUTDOWN_PARAMS
 

Functions

static BOOL DoSystemShutdown (IN PSYS_SHUTDOWN_PARAMS pShutdownParams)
 
static VOID OnTimer (IN HWND hwndDlg, IN PSYS_SHUTDOWN_PARAMS pShutdownParams)
 
static INT_PTR CALLBACK ShutdownDialogProc (IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
 
static DWORD WINAPI InitiateSystemShutdownThread (IN LPVOID lpParameter)
 
DWORD TerminateSystemShutdown (VOID)
 
DWORD StartSystemShutdown (IN PUNICODE_STRING pMessage, IN ULONG dwTimeout, IN BOOLEAN bForceAppsClosed, IN BOOLEAN bRebootAfterShutdown, IN ULONG dwReason)
 

Variables

SYS_SHUTDOWN_PARAMS g_ShutdownParams
 

Macro Definition Documentation

◆ SECONDS_PER_DAY

#define SECONDS_PER_DAY   86400

Definition at line 21 of file shutdown.c.

◆ SECONDS_PER_DECADE

#define SECONDS_PER_DECADE   315360000

Definition at line 22 of file shutdown.c.

◆ SHUTDOWN_TIMER_ID

#define SHUTDOWN_TIMER_ID   2000

Definition at line 20 of file shutdown.c.

Typedef Documentation

◆ PSYS_SHUTDOWN_PARAMS

◆ SYS_SHUTDOWN_PARAMS

Function Documentation

◆ DoSystemShutdown()

static BOOL DoSystemShutdown ( IN PSYS_SHUTDOWN_PARAMS  pShutdownParams)
static

Definition at line 49 of file shutdown.c.

51{
53
54 /* If shutdown has been cancelled, bail out now */
55 if (!pShutdownParams->bShuttingDown)
56 return TRUE;
57
58 Success = ExitWindowsEx((pShutdownParams->bRebootAfterShutdown ? EWX_REBOOT : EWX_SHUTDOWN) |
59 (pShutdownParams->bForceAppsClosed ? EWX_FORCE : 0),
60 pShutdownParams->dwReason);
61 if (!Success)
62 {
63 /* Something went wrong, cancel shutdown */
64 pShutdownParams->bShuttingDown = FALSE;
65 }
66
67 return Success;
68}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EWX_SHUTDOWN
Definition: winuser.h:639
#define EWX_REBOOT
Definition: winuser.h:638
#define EWX_FORCE
Definition: winuser.h:635
BOOL WINAPI ExitWindowsEx(_In_ UINT, _In_ DWORD)

Referenced by InitiateSystemShutdownThread(), and StartSystemShutdown().

◆ InitiateSystemShutdownThread()

static DWORD WINAPI InitiateSystemShutdownThread ( IN LPVOID  lpParameter)
static

Definition at line 231 of file shutdown.c.

233{
234 PSYS_SHUTDOWN_PARAMS pShutdownParams;
235 HDESK hInputDesktop;
237 INT_PTR res;
238
239 pShutdownParams = (PSYS_SHUTDOWN_PARAMS)lpParameter;
240
241 /* Default to initial dialog position */
242 pShutdownParams->wpPos.length = 0;
243
244 /* Continuously display the shutdown dialog on the current input desktop */
245 while (TRUE)
246 {
247 /* Retrieve the current input desktop */
248 hInputDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL);
249 if (!hInputDesktop)
250 {
251 /* No input desktop on the current WinSta0, just shut down */
252 ERR("OpenInputDesktop() failed, error 0x%lx\n", GetLastError());
253 break;
254 }
255
256 /* Remember it for checking desktop changes later */
257 pShutdownParams->hShutdownDesk = hInputDesktop;
258 if (!GetUserObjectInformationW(pShutdownParams->hShutdownDesk,
259 UOI_NAME,
260 pShutdownParams->DesktopName,
261 sizeof(pShutdownParams->DesktopName),
262 &dwSize))
263 {
264 ERR("GetUserObjectInformationW(0x%p) failed, error 0x%lx\n",
265 pShutdownParams->hShutdownDesk, GetLastError());
266 }
267
268 /* Assign the desktop to the current thread */
269 SetThreadDesktop(hInputDesktop);
270
271 /* Display the shutdown dialog on the current input desktop */
274 NULL,
276 (LPARAM)pShutdownParams);
277
278 /* Close the desktop */
279 CloseDesktop(hInputDesktop);
280
281 /*
282 * Check why the dialog has been closed.
283 *
284 * - If it failed to be created (returned -1), don't care about
285 * re-creating it, and proceed directly to shutdown.
286 *
287 * - If it closed unexpectedly (returned != 1), check whether a
288 * shutdown is in progress. If the shutdown has been cancelled,
289 * just bail out; if a shutdown is in progress and the timeout
290 * is 0, bail out and proceed to shutdown.
291 *
292 * - If the dialog has closed because the input desktop changed,
293 * loop again and recreate it on the new desktop.
294 */
295 if ((res == -1) || (res != IDCANCEL) ||
296 !(pShutdownParams->bShuttingDown && (pShutdownParams->dwTimeout > 0)))
297 {
298 break;
299 }
300 }
301
302 /* Reset dialog information */
303 pShutdownParams->hShutdownDesk = NULL;
304 ZeroMemory(&pShutdownParams->DesktopName, sizeof(pShutdownParams->DesktopName));
305 ZeroMemory(&pShutdownParams->wpPos, sizeof(pShutdownParams->wpPos));
306
307 if (pShutdownParams->pszMessage)
308 {
309 HeapFree(GetProcessHeap(), 0, pShutdownParams->pszMessage);
310 pShutdownParams->pszMessage = NULL;
311 }
312
313 if (pShutdownParams->bShuttingDown)
314 {
315 /* Perform the system shutdown */
316 if (DoSystemShutdown(pShutdownParams))
317 return ERROR_SUCCESS;
318 else
319 return GetLastError();
320 }
321
322 pShutdownParams->bShuttingDown = FALSE;
323 return ERROR_SUCCESS;
324}
HINSTANCE hAppInstance
Definition: mmc.c:23
#define IDD_SYSSHUTDOWN
Definition: resource.h:16
static BOOL DoSystemShutdown(IN PSYS_SHUTDOWN_PARAMS pShutdownParams)
Definition: shutdown.c:49
static INT_PTR CALLBACK ShutdownDialogProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: shutdown.c:171
struct _SYS_SHUTDOWN_PARAMS * PSYS_SHUTDOWN_PARAMS
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define GENERIC_ALL
Definition: nt_native.h:92
WCHAR DesktopName[512]
Definition: shutdown.c:32
BOOLEAN bShuttingDown
Definition: shutdown.c:35
WINDOWPLACEMENT wpPos
Definition: shutdown.c:33
int32_t INT_PTR
Definition: typedefs.h:64
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LONG_PTR LPARAM
Definition: windef.h:208
#define IDCANCEL
Definition: winuser.h:831
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define UOI_NAME
Definition: winuser.h:1084
HDESK WINAPI OpenInputDesktop(_In_ DWORD, _In_ BOOL, _In_ DWORD)
BOOL WINAPI GetUserObjectInformationW(_In_ HANDLE hObj, _In_ int nIndex, _Out_writes_bytes_opt_(nLength) PVOID pvInfo, _In_ DWORD nLength, _Out_opt_ LPDWORD lpnLengthNeeded)
BOOL WINAPI CloseDesktop(_In_ HDESK)
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)

Referenced by StartSystemShutdown().

◆ OnTimer()

static VOID OnTimer ( IN HWND  hwndDlg,
IN PSYS_SHUTDOWN_PARAMS  pShutdownParams 
)
static

Definition at line 72 of file shutdown.c.

75{
76 HDESK hInputDesktop;
79 INT iSeconds, iMinutes, iHours, iDays;
80 WCHAR szFormatBuffer[32];
81 WCHAR szBuffer[32];
82 WCHAR DesktopName[512];
83
84 if (!pShutdownParams->bShuttingDown)
85 {
86 /* Shutdown has been cancelled, close the dialog and bail out */
87 EndDialog(hwndDlg, IDABORT);
88 return;
89 }
90
91 /*
92 * Check whether the input desktop has changed. If so, close the dialog,
93 * and let the shutdown thread recreate it on the new desktop.
94 */
95
96 // TODO: Investigate: It would be great if we could also compare with
97 // our internally maintained desktop handles, before calling that heavy
98 // comparison.
99 // (Note that we cannot compare handles with arbitrary input desktop,
100 // since OpenInputDesktop() creates new handle instances everytime.)
101
102 hInputDesktop = OpenInputDesktop(0, FALSE, GENERIC_ALL);
103 if (!hInputDesktop)
104 {
105 /* No input desktop but we have a dialog: kill it */
106 ERR("OpenInputDesktop() failed, error 0x%lx\n", GetLastError());
107 EndDialog(hwndDlg, 0);
108 return;
109 }
110 bSuccess = GetUserObjectInformationW(hInputDesktop,
111 UOI_NAME,
112 DesktopName,
113 sizeof(DesktopName),
114 &dwSize);
115 if (!bSuccess)
116 {
117 ERR("GetUserObjectInformationW(0x%p) failed, error 0x%lx\n",
118 hInputDesktop, GetLastError());
119 }
120 CloseDesktop(hInputDesktop);
121
122 if (bSuccess && (wcscmp(DesktopName, pShutdownParams->DesktopName) != 0))
123 {
124 TRACE("Input desktop has changed: '%S' --> '%S'\n",
125 pShutdownParams->DesktopName, DesktopName);
126
127 /* Save the original dialog position to be restored later */
128 pShutdownParams->wpPos.length = sizeof(pShutdownParams->wpPos);
129 GetWindowPlacement(hwndDlg, &pShutdownParams->wpPos);
130
131 /* Close the dialog */
132 EndDialog(hwndDlg, IDCANCEL);
133 return;
134 }
135
136 /* Update the shutdown timeout */
137 if (pShutdownParams->dwTimeout < SECONDS_PER_DAY)
138 {
139 iSeconds = (INT)pShutdownParams->dwTimeout;
140 iHours = iSeconds / 3600;
141 iSeconds -= iHours * 3600;
142 iMinutes = iSeconds / 60;
143 iSeconds -= iMinutes * 60;
144
145 LoadStringW(hAppInstance, IDS_TIMEOUTSHORTFORMAT, szFormatBuffer, ARRAYSIZE(szFormatBuffer));
146 swprintf(szBuffer, szFormatBuffer, iHours, iMinutes, iSeconds);
147 }
148 else
149 {
150 iDays = (INT)(pShutdownParams->dwTimeout / SECONDS_PER_DAY);
151
152 LoadStringW(hAppInstance, IDS_TIMEOUTLONGFORMAT, szFormatBuffer, ARRAYSIZE(szFormatBuffer));
153 swprintf(szBuffer, szFormatBuffer, iDays);
154 }
155
156 SetDlgItemTextW(hwndDlg, IDC_SYSSHUTDOWNTIMELEFT, szBuffer);
157
158 if (pShutdownParams->dwTimeout == 0)
159 {
160 /* Close the dialog and let the shutdown thread perform the system shutdown */
161 EndDialog(hwndDlg, 0);
162 return;
163 }
164
165 pShutdownParams->dwTimeout--;
166}
#define IDC_SYSSHUTDOWNTIMELEFT
Definition: resource.h:18
#define IDS_TIMEOUTSHORTFORMAT
Definition: resource.h:36
#define IDS_TIMEOUTLONGFORMAT
Definition: resource.h:37
#define SECONDS_PER_DAY
Definition: shutdown.c:21
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define swprintf
Definition: precomp.h:40
static BOOLEAN bSuccess
Definition: drive.cpp:433
#define INT
Definition: polytest.cpp:20
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define TRACE(s)
Definition: solgame.cpp:4
int32_t INT
Definition: typedefs.h:58
BOOL WINAPI GetWindowPlacement(_In_ HWND, _Inout_ WINDOWPLACEMENT *)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
#define IDABORT
Definition: winuser.h:832
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ShutdownDialogProc().

◆ ShutdownDialogProc()

static INT_PTR CALLBACK ShutdownDialogProc ( IN HWND  hwndDlg,
IN UINT  uMsg,
IN WPARAM  wParam,
IN LPARAM  lParam 
)
static

Definition at line 171 of file shutdown.c.

176{
177 PSYS_SHUTDOWN_PARAMS pShutdownParams;
178
179 pShutdownParams = (PSYS_SHUTDOWN_PARAMS)GetWindowLongPtrW(hwndDlg, DWLP_USER);
180
181 switch (uMsg)
182 {
183 case WM_INITDIALOG:
184 {
185 pShutdownParams = (PSYS_SHUTDOWN_PARAMS)lParam;
186 SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)pShutdownParams);
187
188 /* Display the shutdown message */
189 if (pShutdownParams->pszMessage)
190 {
191 SetDlgItemTextW(hwndDlg,
193 pShutdownParams->pszMessage);
194 }
195
196 /* Remove the Close menu item */
198
199 /* Position the window (initial position, or restore from old) */
200 if (pShutdownParams->wpPos.length == sizeof(pShutdownParams->wpPos))
201 SetWindowPlacement(hwndDlg, &pShutdownParams->wpPos);
202
203 SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0,
205
206 /* Initialize the timer */
207 PostMessageW(hwndDlg, WM_TIMER, 0, 0);
208 SetTimer(hwndDlg, SHUTDOWN_TIMER_ID, 1000, NULL);
209 break;
210 }
211
212 /* NOTE: Do not handle WM_CLOSE */
213 case WM_DESTROY:
215 break;
216
217 case WM_TIMER:
218 OnTimer(hwndDlg, pShutdownParams);
219 break;
220
221 default:
222 return FALSE;
223 }
224
225 return TRUE;
226}
#define IDC_SYSSHUTDOWNMESSAGE
Definition: resource.h:19
static VOID OnTimer(IN HWND hwndDlg, IN PSYS_SHUTDOWN_PARAMS pShutdownParams)
Definition: shutdown.c:72
#define SHUTDOWN_TIMER_ID
Definition: shutdown.c:20
LPARAM lParam
Definition: combotst.c:139
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define MF_BYCOMMAND
Definition: winuser.h:202
#define DWLP_USER
Definition: winuser.h:872
#define GetWindowLongPtrW
Definition: winuser.h:4829
#define HWND_TOPMOST
Definition: winuser.h:1208
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SWP_NOMOVE
Definition: winuser.h:1244
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_INITDIALOG
Definition: winuser.h:1739
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_TIMER
Definition: winuser.h:1742
#define SWP_SHOWWINDOW
Definition: winuser.h:1248
#define SC_CLOSE
Definition: winuser.h:2592
#define WM_DESTROY
Definition: winuser.h:1609
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5346
BOOL WINAPI SetWindowPlacement(_In_ HWND hWnd, _In_ const WINDOWPLACEMENT *)

Referenced by InitiateSystemShutdownThread(), and ShutdownDialog().

◆ StartSystemShutdown()

DWORD StartSystemShutdown ( IN PUNICODE_STRING  pMessage,
IN ULONG  dwTimeout,
IN BOOLEAN  bForceAppsClosed,
IN BOOLEAN  bRebootAfterShutdown,
IN ULONG  dwReason 
)

Definition at line 337 of file shutdown.c.

343{
345
346 /* Fail if the timeout is 10 years or more */
349
352
353 if ((dwTimeout != 0) && pMessage && pMessage->Length && pMessage->Buffer)
354 {
357 pMessage->Length + sizeof(UNICODE_NULL));
359 {
361 return GetLastError();
362 }
363
365 pMessage->Buffer,
366 pMessage->Length / sizeof(WCHAR));
367 }
368 else
369 {
371 }
372
374 g_ShutdownParams.bForceAppsClosed = bForceAppsClosed;
375 g_ShutdownParams.bRebootAfterShutdown = bRebootAfterShutdown;
377
378 /* If dwTimeout is zero perform an immediate system shutdown,
379 * otherwise display the countdown shutdown dialog. */
381 {
383 return ERROR_SUCCESS;
384 }
385 else
386 {
389 if (hThread)
390 {
392 return ERROR_SUCCESS;
393 }
394 }
395
397 {
400 }
401
403 return GetLastError();
404}
DWORD dwReason
Definition: misc.cpp:154
#define SECONDS_PER_DECADE
Definition: shutdown.c:22
static DWORD WINAPI InitiateSystemShutdownThread(IN LPVOID lpParameter)
Definition: shutdown.c:231
SYS_SHUTDOWN_PARAMS g_ShutdownParams
Definition: shutdown.c:43
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
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
char _InterlockedCompareExchange8(_Interlocked_operand_ char volatile *_Destination, char _Exchange, char _Comparand)
HANDLE hThread
Definition: wizard.c:28
#define UNICODE_NULL
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
BOOLEAN bForceAppsClosed
Definition: shutdown.c:37
BOOLEAN bRebootAfterShutdown
Definition: shutdown.c:36
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD dwTimeout
Definition: wincrypt.h:6081
#define ERROR_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:651

Referenced by BaseInitiateSystemShutdownEx().

◆ TerminateSystemShutdown()

DWORD TerminateSystemShutdown ( VOID  )

Definition at line 328 of file shutdown.c.

329{
332
333 return ERROR_SUCCESS;
334}
#define ERROR_NO_SHUTDOWN_IN_PROGRESS
Definition: winerror.h:652

Referenced by BaseAbortSystemShutdown().

Variable Documentation

◆ g_ShutdownParams

SYS_SHUTDOWN_PARAMS g_ShutdownParams

Definition at line 43 of file shutdown.c.

Referenced by StartSystemShutdown(), and TerminateSystemShutdown().