mirror of
https://github.com/reactos/reactos.git
synced 2026-05-31 08:17:09 +08:00
[WINLOGON] Allow workstation (un)locking only if we are in the correct LogonState (#8132)
- Locking (`WLX_SAS_ACTION_LOCK_WKSTA`) is allowed only if `LogonState`
is either `STATE_LOGGED_ON` or `STATE_LOGGED_ON_SAS`, i.e., either the
user invokes the `user32:LockWorkStation()` API or presses Win-L, or,
opens the Logged-On SAS dialog then clicks on the "Lock Workstation" button.
- Unlocking (`WLX_SAS_ACTION_UNLOCK_WKSTA`) is allowed only if
`LogonState` is either `STATE_LOCKED` or `STATE_LOCKED_SAS`,
i.e., the workstation is locked and we are either on the Locked-
notice or on the SAS dialog that asks for the user credentials.
Additionally:
- Fix the invocation order of `LockHandler`/`UnlockHandler` notifications:
* the `LockHandler` is invoked on the Winlogon desktop, just before
displaying the Locked-notice dialog;
* the `UnlockHandler` is invoked on the Winlogon desktop, just before
switching back to the user's desktop.
- If we are on the Logged-On SAS dialog and the user presses Win-L to
lock the workstation (instead of pressing the corresponding dialog
button), the `DoGenericAction(WLX_SAS_ACTION_LOCK_WKSTA)` handler is
invoked asynchronously while the SAS dialog is still being displayed.
We thus need to ensure all the existing dialogs are closed before
displaying the Locked-notice dialog, in order to avoid stray dialogs
being shown concurrently.
This commit is contained in:
@@ -1093,12 +1093,19 @@ DoGenericAction(
|
||||
}
|
||||
break;
|
||||
case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */
|
||||
if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context))
|
||||
if ((Session->LogonState == STATE_LOGGED_ON) ||
|
||||
(Session->LogonState == STATE_LOGGED_ON_SAS))
|
||||
{
|
||||
SwitchDesktop(Session->WinlogonDesktop);
|
||||
Session->LogonState = STATE_LOCKED;
|
||||
Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
|
||||
CallNotificationDlls(Session, LockHandler);
|
||||
if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context))
|
||||
{
|
||||
Session->LogonState = STATE_LOCKED;
|
||||
SwitchDesktop(Session->WinlogonDesktop);
|
||||
/* We may be on the Logged-On SAS dialog, in which case
|
||||
* we need to close it if the lock action came via Win-L */
|
||||
CloseAllDialogWindows();
|
||||
CallNotificationDlls(Session, LockHandler);
|
||||
Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WLX_SAS_ACTION_LOGOFF: /* 0x04 */
|
||||
@@ -1145,9 +1152,13 @@ DoGenericAction(
|
||||
}
|
||||
break;
|
||||
case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */
|
||||
SwitchDesktop(Session->ApplicationDesktop);
|
||||
Session->LogonState = STATE_LOGGED_ON;
|
||||
CallNotificationDlls(Session, UnlockHandler);
|
||||
if ((Session->LogonState == STATE_LOCKED) ||
|
||||
(Session->LogonState == STATE_LOCKED_SAS))
|
||||
{
|
||||
CallNotificationDlls(Session, UnlockHandler);
|
||||
SwitchDesktop(Session->ApplicationDesktop);
|
||||
Session->LogonState = STATE_LOGGED_ON;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unknown SAS action 0x%lx\n", wlxAction);
|
||||
|
||||
Reference in New Issue
Block a user