BOOLEAN bForceAppsClosed;
DWORD dwReason;
- HWND hShutdownDialog;
BOOLEAN bShuttingDown;
} SYS_SHUTDOWN_PARAMS, *PSYS_SHUTDOWN_PARAMS;
/* FUNCTIONS *****************************************************************/
+static
+BOOL
+DoSystemShutdown(
+ IN PSYS_SHUTDOWN_PARAMS pShutdownParams)
+{
+ BOOL Success;
+
+ if (pShutdownParams->pszMessage)
+ {
+ HeapFree(GetProcessHeap(), 0, pShutdownParams->pszMessage);
+ pShutdownParams->pszMessage = NULL;
+ }
+
+ /* If shutdown has been cancelled, bail out now */
+ if (!pShutdownParams->bShuttingDown)
+ return TRUE;
+
+ Success = ExitWindowsEx((pShutdownParams->bRebootAfterShutdown ? EWX_REBOOT : EWX_SHUTDOWN) |
+ (pShutdownParams->bForceAppsClosed ? EWX_FORCE : 0),
+ pShutdownParams->dwReason);
+ if (!Success)
+ {
+ /* Something went wrong, cancel shutdown */
+ pShutdownParams->bShuttingDown = FALSE;
+ }
+
+ return Success;
+}
+
+
static
VOID
OnTimer(
WCHAR szBuffer[12];
INT iSeconds, iMinutes, iHours, iDays;
+ if (!pShutdownParams->bShuttingDown)
+ {
+ /* Shutdown has been cancelled, close the dialog and bail out */
+ EndDialog(hwndDlg, 0);
+ return;
+ }
+
if (pShutdownParams->dwTimeout < SECONDS_PER_DAY)
{
iSeconds = (INT)pShutdownParams->dwTimeout;
else
{
iDays = (INT)(pShutdownParams->dwTimeout / SECONDS_PER_DAY);
- swprintf(szBuffer, L"%d days", iDays);
+ swprintf(szBuffer, L"%d days", iDays); // FIXME: Localize
}
SetDlgItemTextW(hwndDlg, IDC_SYSSHUTDOWNTIMELEFT, szBuffer);
if (pShutdownParams->dwTimeout == 0)
{
- PostMessage(hwndDlg, WM_CLOSE, 0, 0);
- ExitWindowsEx((pShutdownParams->bRebootAfterShutdown ? EWX_REBOOT : EWX_SHUTDOWN) |
- (pShutdownParams->bForceAppsClosed ? EWX_FORCE : 0),
- pShutdownParams->dwReason);
+ /* Close the dialog and perform the system shutdown */
+ EndDialog(hwndDlg, 0);
+ DoSystemShutdown(pShutdownParams);
+ return;
}
pShutdownParams->dwTimeout--;
switch (uMsg)
{
case WM_INITDIALOG:
+ {
pShutdownParams = (PSYS_SHUTDOWN_PARAMS)lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pShutdownParams);
- pShutdownParams->hShutdownDialog = hwndDlg;
-
if (pShutdownParams->pszMessage)
{
SetDlgItemTextW(hwndDlg,
pShutdownParams->pszMessage);
}
- RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
+ DeleteMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
PostMessage(hwndDlg, WM_TIMER, 0, 0);
SetTimer(hwndDlg, SHUTDOWN_TIMER_ID, 1000, NULL);
break;
+ }
- case WM_CLOSE:
- pShutdownParams->hShutdownDialog = NULL;
- pShutdownParams->bShuttingDown = FALSE;
-
+ /* NOTE: Do not handle WM_CLOSE */
+ case WM_DESTROY:
KillTimer(hwndDlg, SHUTDOWN_TIMER_ID);
-
- if (pShutdownParams->pszMessage)
- {
- HeapFree(GetProcessHeap(), 0, pShutdownParams->pszMessage);
- pShutdownParams->pszMessage = NULL;
- }
-
- EndDialog(hwndDlg, 0);
break;
case WM_TIMER:
NULL,
ShutdownDialogProc,
(LPARAM)pShutdownParams);
- if (status >= 0)
- {
- return ERROR_SUCCESS;
- }
if (pShutdownParams->pszMessage)
{
pShutdownParams->pszMessage = NULL;
}
- pShutdownParams->bShuttingDown = FALSE;
+ if (status >= 0)
+ return ERROR_SUCCESS;
+ pShutdownParams->bShuttingDown = FALSE;
return GetLastError();
}
DWORD
TerminateSystemShutdown(VOID)
{
- if (g_ShutdownParams.bShuttingDown == FALSE)
+ if (_InterlockedCompareExchange8((volatile char*)&g_ShutdownParams.bShuttingDown, FALSE, TRUE) == FALSE)
return ERROR_NO_SHUTDOWN_IN_PROGRESS;
- return PostMessage(g_ShutdownParams.hShutdownDialog, WM_CLOSE, 0, 0) ? ERROR_SUCCESS : GetLastError();
+ return ERROR_SUCCESS;
}
g_ShutdownParams.bRebootAfterShutdown = bRebootAfterShutdown;
g_ShutdownParams.dwReason = dwReason;
- hThread = CreateThread(NULL, 0, InitiateSystemShutdownThread, (PVOID)&g_ShutdownParams, 0, NULL);
- if (hThread)
+ /* If dwTimeout is zero perform an immediate system shutdown, otherwise display the countdown shutdown dialog */
+ if (g_ShutdownParams.dwTimeout == 0)
{
- CloseHandle(hThread);
- return ERROR_SUCCESS;
+ if (DoSystemShutdown(&g_ShutdownParams))
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ hThread = CreateThread(NULL, 0, InitiateSystemShutdownThread, (PVOID)&g_ShutdownParams, 0, NULL);
+ if (hThread)
+ {
+ CloseHandle(hThread);
+ return ERROR_SUCCESS;
+ }
}
if (g_ShutdownParams.pszMessage)
}
g_ShutdownParams.bShuttingDown = FALSE;
-
return GetLastError();
}