mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[WINLOGON] Usability enhancement for the RPC SystemShutdown functionality.
- Perform an immediate system shutdown if the timeout is zero, otherwise display the countdown shutdown dialog. - Cleanup pShutdownParams->pszMessage as soon as the dialog goes away. - It actually appears (tested on Windows 2000 and 2003) that sending WM_CLOSE messages from a user-mode app to the shutdown dialog really do nothing (and in particular does not cancel the shutdown!), so modify the code to take this fact into account.
This commit is contained in:
parent
03c233bcd0
commit
cb20bf8c90
1 changed files with 65 additions and 33 deletions
|
@ -30,7 +30,6 @@ typedef struct _SYS_SHUTDOWN_PARAMS
|
|||
BOOLEAN bForceAppsClosed;
|
||||
DWORD dwReason;
|
||||
|
||||
HWND hShutdownDialog;
|
||||
BOOLEAN bShuttingDown;
|
||||
} SYS_SHUTDOWN_PARAMS, *PSYS_SHUTDOWN_PARAMS;
|
||||
|
||||
|
@ -42,6 +41,36 @@ SYS_SHUTDOWN_PARAMS g_ShutdownParams;
|
|||
|
||||
/* 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(
|
||||
|
@ -51,6 +80,13 @@ 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;
|
||||
|
@ -64,17 +100,17 @@ OnTimer(
|
|||
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--;
|
||||
|
@ -97,11 +133,10 @@ ShutdownDialogProc(
|
|||
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,
|
||||
|
@ -109,26 +144,17 @@ ShutdownDialogProc(
|
|||
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:
|
||||
|
@ -159,10 +185,6 @@ InitiateSystemShutdownThread(
|
|||
NULL,
|
||||
ShutdownDialogProc,
|
||||
(LPARAM)pShutdownParams);
|
||||
if (status >= 0)
|
||||
{
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if (pShutdownParams->pszMessage)
|
||||
{
|
||||
|
@ -170,8 +192,10 @@ InitiateSystemShutdownThread(
|
|||
pShutdownParams->pszMessage = NULL;
|
||||
}
|
||||
|
||||
pShutdownParams->bShuttingDown = FALSE;
|
||||
if (status >= 0)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
pShutdownParams->bShuttingDown = FALSE;
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
|
@ -179,10 +203,10 @@ InitiateSystemShutdownThread(
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,11 +252,20 @@ StartSystemShutdown(
|
|||
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)
|
||||
|
@ -242,7 +275,6 @@ StartSystemShutdown(
|
|||
}
|
||||
|
||||
g_ShutdownParams.bShuttingDown = FALSE;
|
||||
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue