[WINLOGON][MSGINA] Improve WLX_SAS_ACTION_TASKLIST handling in logged-on/logged-on SAS states (#8131)

CORE-13478
Addendum to commit 46dcab7ab.

The `WLX_SAS_ACTION_TASKLIST` action can be invoked in three scenarii to
open the Task-Manager:

1. from the logged-on state (`LogonState == STATE_LOGGED_ON`), when the
   user presses Ctrl-Shift-Esc while being on its own desktop (usual case);

2. from the Logged-On SAS dialog (`LogonState == STATE_LOGGED_ON_SAS`),
   when the user presses the "Task-Manager" button: here Winlogon should
   switch back to the user's desktop, restoring `STATE_LOGGED_ON` and
   start the TaskMgr;

3. or when the user presses Ctrl-Shift-Esc **while being on the Logged-On
   SAS dialog**: in this case, the Task-Manager is started on the
   currently-hidden user's desktop (and so, will be hidden), but the SAS
   dialog stays open. The user will see the opened TaskMgr once (s)he
   closes the SAS dialog and Winlogon switches back to the user's desktop.

In order to support these scenarii, the `WLX_SAS_ACTION_TASKLIST` action
handling is reworked:

- `SASWindowProc(WM_HOTKEY, IDHK_CTRL_SHIFT_ESC)` always invokes the
  `DoGenericAction(WLX_SAS_ACTION_TASKLIST)`: this allows centralizing
  inside `DoGenericAction()` the condition checks for starting TaskMgr.

- `DoGenericAction(WLX_SAS_ACTION_TASKLIST)` just starts the Task-Manager
  only if the Winlogon's `LogonState` is either `STATE_LOGGED_ON` or
  `STATE_LOGGED_ON_SAS`. It doesn't attempt there to switch desktops nor
  change the `LogonState` value, in order to support scenarii 2 and 3.

- The switch from/to Winlogon/user's desktops when going to the
  `LogonState: STATE_LOGGED_ON -> STATE_LOGGED_ON_SAS` change is done
  in `DispatchSAS()`, just before invoking the GINA's `WlxLoggedOnSAS()`
  (see below for more details) and just after it returns, only in the
  necessary cases.

----

[MSGINA] The WlxLoggedOnSAS() dialog shouldn't switch the desktops itself.

This behaviour can be observed on Windows with Winlogon debugging + tracing
enabled. It is Winlogon instead that does the desktop switch itself, as for
all the other SAS dialogs, in addition to changing its internal `LogonState`.

Fix for commit 7aecedf79 (r58785).
This commit is contained in:
Hermès Bélusca-Maïto 2025-06-14 18:10:41 +02:00
parent a8c5f55315
commit b0fbeb6801
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 29 additions and 15 deletions

View file

@ -1135,9 +1135,14 @@ DoGenericAction(
}
break;
case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
SwitchDesktop(Session->ApplicationDesktop);
Session->LogonState = STATE_LOGGED_ON;
StartTaskManager(Session);
if ((Session->LogonState == STATE_LOGGED_ON) ||
(Session->LogonState == STATE_LOGGED_ON_SAS))
{
/* Start a Task-Manager instance on the application desktop.
* If the user pressed Ctrl-Shift-Esc while being on the
* Logged-On SAS dialog (on the Winlogon desktop), stay there. */
StartTaskManager(Session);
}
break;
case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */
SwitchDesktop(Session->ApplicationDesktop);
@ -1193,7 +1198,26 @@ DispatchSAS(
case STATE_LOGGED_ON:
Session->LogonState = STATE_LOGGED_ON_SAS;
SwitchDesktop(Session->WinlogonDesktop);
wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOnSAS(Session->Gina.Context, dwSasType, NULL);
if ((wlxAction == WLX_SAS_ACTION_NONE) ||
(wlxAction == WLX_SAS_ACTION_TASKLIST))
{
/*
* If the user canceled (WLX_SAS_ACTION_NONE) the
* Logged-On SAS dialog, or clicked on the Task-Manager
* button (WLX_SAS_ACTION_TASKLIST), switch back to
* the application desktop and return to log-on state.
* In the latter case, the Task-Manager is launched
* by DoGenericAction(WLX_SAS_ACTION_TASKLIST), which
* doesn't automatically do the switch back, because
* the user may have also pressed on Ctrl-Shift-Esc
* to start it while being on the Logged-On SAS dialog
* and wanting to stay there.
*/
SwitchDesktop(Session->ApplicationDesktop);
Session->LogonState = STATE_LOGGED_ON;
}
break;
case STATE_LOGGED_ON_SAS:
@ -1361,8 +1385,7 @@ SASWindowProc(
case IDHK_CTRL_SHIFT_ESC:
{
TRACE("SAS: CONTROL+SHIFT+ESCAPE\n");
if (Session->LogonState == STATE_LOGGED_ON)
DoGenericAction(Session, WLX_SAS_ACTION_TASKLIST);
DoGenericAction(Session, WLX_SAS_ACTION_TASKLIST);
return TRUE;
}
case IDHK_WIN_L:

View file

@ -1062,14 +1062,11 @@ GUILoggedOnSAS(
if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL)
{
/* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
/* Nothing to do for WLX_SAS_TYPE_TIMEOUT; the dialog will
* close itself thanks to the use of WlxDialogBoxParam */
return WLX_SAS_ACTION_NONE;
}
pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon(
pgContext->hWlx);
result = pgContext->pWlxFuncs->WlxDialogBoxParam(
pgContext->hWlx,
pgContext->hDllInstance,
@ -1084,12 +1081,6 @@ GUILoggedOnSAS(
result = WLX_SAS_ACTION_NONE;
}
if (result == WLX_SAS_ACTION_NONE)
{
pgContext->pWlxFuncs->WlxSwitchDesktopToUser(
pgContext->hWlx);
}
return result;
}