[WINLOGON] Fixes for logon/logoff steps and notifications (#8325)

- The `LogonHandler` notification should be invoked only once for a
  given logon operation. It is invoked in `HandleLogon()` after access
  to the window station (and desktop) is allowed for the user logging in.
  And so, it must not be invoked elsewhere, when no user is logged in
  (or a logon failure happened), like after a call to `WlxDisplaySASNotice()`...

- Invoke the `StartShellHandler` notification **before** starting the
  shell, and the `PostShellHandler` notification **after** the shell
  started.

- Invoke the `LogoffHandler` notification on the application desktop,
  just after having terminated all the user's programs, and before
  switching back to Winlogon's desktop.

- Add and show the 'Logging off' status message.

- When performing the following actions:
  `WLX_SAS_ACTION_LOGOFF`, `WLX_SAS_ACTION_FORCE_LOGOFF`,
  as well as:
  `WLX_SAS_ACTION_SHUTDOWN`, `WLX_SAS_ACTION_SHUTDOWN_POWER_OFF`,
  `WLX_SAS_ACTION_SHUTDOWN_REBOOT`,
  ensure that Winlogon is in a correct LogonState for doing the logoff
  sequence.

----

Test results for Winlogon notifications, after fix:

- `Asynchronous: FALSE, Impersonation: FALSE`

  ```
  WLEventStartup: 30 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventLogon: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventStartShell: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventPostShell: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventLock: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventUnlock: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventStartScreenSaver: 32 tests executed (0 marked as todo, 6 failures), 0 skipped.
  WLEventStopScreenSaver: 32 tests executed (0 marked as todo, 5 failures), 0 skipped.
  WLEventLogoff: 32 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventShutdown: 31 tests executed (0 marked as todo, 3 failures), 0 skipped.
  ```

- `Asynchronous: FALSE, Impersonation: TRUE`

  ```
  WLEventStartup: 30 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventLogon: 33 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventStartShell: 33 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventPostShell: 33 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventLock: 33 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventUnlock: 33 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventStartScreenSaver: 34 tests executed (0 marked as todo, 3 failures), 0 skipped.
  WLEventStopScreenSaver: 34 tests executed (0 marked as todo, 2 failures), 0 skipped.
  WLEventLogoff: 34 tests executed (0 marked as todo, 1 failure), 0 skipped.
  WLEventShutdown: 31 tests executed (0 marked as todo, 3 failures), 0 skipped.
  ```
This commit is contained in:
Hermès Bélusca-Maïto
2025-06-12 22:35:52 +02:00
parent 0bd6b3dd58
commit 27e147a8ce
32 changed files with 55 additions and 12 deletions

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Приготвяне за сън..."
IDS_SAVEYOURSETTINGS "Записване на настройките ви..."
IDS_REACTOSISSTARTINGUP "ReactOS тръгва..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -59,6 +59,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Příprava k přechodu do režimu hibernace..."
IDS_SAVEYOURSETTINGS "Ukládání osobního nastavení..."
IDS_REACTOSISSTARTINGUP "ReactOS se spouští..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d dní"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Vorbereiten für den Ruhezustand..."
IDS_SAVEYOURSETTINGS "Speichern Ihrer persönlichen Einstellungen..."
IDS_REACTOSISSTARTINGUP "ReactOS startet..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d Tage"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparing to Hibernate..."
IDS_SAVEYOURSETTINGS "Γίνεται αποθήκευση των ρυθμίσεών σας..."
IDS_REACTOSISSTARTINGUP "Το ReactOS ξεκινά..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparing to Hibernate..."
IDS_SAVEYOURSETTINGS "Saving your settings..."
IDS_REACTOSISSTARTINGUP "ReactOS is starting up..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Hibernando..."
IDS_SAVEYOURSETTINGS "Guardando su configuración personal..."
IDS_REACTOSISSTARTINGUP "ReactOS se está iniciando..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d días"
END

View File

@@ -57,6 +57,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparando para hibernar..."
IDS_SAVEYOURSETTINGS "Gordetzen zure pertsonal konfigurazioa..."
IDS_REACTOSISSTARTINGUP "Itzaron, ReactOS hasi da..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d egunak"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Préparation de l'hibernation..."
IDS_SAVEYOURSETTINGS "Enregistrement de vos paramètres..."
IDS_REACTOSISSTARTINGUP "Démarrage de ReactOS..."
IDS_LOGGINGOFF "Fermeture de session..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d jours"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "מתכונן לשינה..."
IDS_SAVEYOURSETTINGS "שומר את הגדרותיך..."
IDS_REACTOSISSTARTINGUP "ReactOS מופעל..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Hibernálás előkészítése..."
IDS_SAVEYOURSETTINGS "Beállítások mentése..."
IDS_REACTOSISSTARTINGUP "A ReactOS indul..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d nap"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Menyiapkan untuk Tidur..."
IDS_SAVEYOURSETTINGS "Menyimpan setelan anda..."
IDS_REACTOSISSTARTINGUP "ReactOS dimulai..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d hari"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparazione Ibernazione..."
IDS_SAVEYOURSETTINGS "Salvataggio delle impostazioni personali..."
IDS_REACTOSISSTARTINGUP "ReactOS si sta avviando..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "休止状態の準備をしています..."
IDS_SAVEYOURSETTINGS "設定を保存しています..."
IDS_REACTOSISSTARTINGUP "ReactOS を起動しています..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d 日"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Ruošiamasi išjungti įrašant..."
IDS_SAVEYOURSETTINGS "Išsaugomos nuostatos..."
IDS_REACTOSISSTARTINGUP "Paleidžiama ReactOS..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Bersedia untuk berhibernasi..."
IDS_SAVEYOURSETTINGS "Menyimpan seting anda..."
IDS_REACTOSISSTARTINGUP "ReactOS sedang bermula komputer anda..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Slaapstand wordt voorbereid..."
IDS_SAVEYOURSETTINGS "Persoonlijke instellingen worden opgeslagen..."
IDS_REACTOSISSTARTINGUP "ReactOS is aan het opstarten..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Forbreder dvalemodus..."
IDS_SAVEYOURSETTINGS "Lagrer innstillingene..."
IDS_REACTOSISSTARTINGUP "ReactOS starter opp..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -58,6 +58,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Trwa przygotowywanie do hibernacji..."
IDS_SAVEYOURSETTINGS "Trwa zapisywanie ustawień..."
IDS_REACTOSISSTARTINGUP "Trwa uruchamianie systemu ReactOS..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d dni"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparando para Hibernar..."
IDS_SAVEYOURSETTINGS "Salvando suas configurações..."
IDS_REACTOSISSTARTINGUP "ReactOS está iniciando..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Preparando para Hibernar..."
IDS_SAVEYOURSETTINGS "A guardar as suas configurações..."
IDS_REACTOSISSTARTINGUP "ReactOS está a iniciar..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -54,12 +54,13 @@ BEGIN
IDS_RUNNINGLOGONSCRIPTS "Se rulează script-urile de Log on…"
IDS_LOADINGYOURPERSONALSETTINGS "Se încarcă setările personale…"
IDS_CLOSINGNETWORKCONNECTIONS "Se închid conexiunile reţelei…"
IDS_REACTOSISRESTARTING "Se repornește..."
IDS_REACTOSISSHUTTINGDOWN "Se închide..."
IDS_REACTOSISRESTARTING "Se repornește"
IDS_REACTOSISSHUTTINGDOWN "Se închide"
IDS_PREPARETOSTANDBY "Se pregăteşte pentru starea de veghe…"
IDS_PREPARETOHIBERNATE "Se pregăteşte pentru hibernare…"
IDS_SAVEYOURSETTINGS "Se salvează setările…"
IDS_REACTOSISSTARTINGUP "Se porneşte ReactOS…"
IDS_LOGGINGOFF "Logging off…"
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d zile"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Подготовка к переходу в спящий режим..."
IDS_SAVEYOURSETTINGS "Сохраняются настройки..."
IDS_REACTOSISSTARTINGUP "ReactOS загружается..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d дней"
END

View File

@@ -58,6 +58,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Systém sa pripravuje na prechod do režimu dlhodobého spánku..."
IDS_SAVEYOURSETTINGS "Systém ukladá Vaše nastavenia..."
IDS_REACTOSISSTARTINGUP "Systém ReactOS sa spúšťa..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d dní"
END

View File

@@ -54,6 +54,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Pergatitet per letargji..."
IDS_SAVEYOURSETTINGS "Ruan konfigurimin tuaj..."
IDS_REACTOSISSTARTINGUP "ReactOS po fillon..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Förbereder för viloläge..."
IDS_SAVEYOURSETTINGS "Sparar dina inställningar..."
IDS_REACTOSISSTARTINGUP "ReactOS startas..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -52,6 +52,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Hazırda Beklemeye Hazırlanıyor..."
IDS_SAVEYOURSETTINGS "Ayarlarınız Kaydediliyor..."
IDS_REACTOSISSTARTINGUP "ReactOS Başlatılıyor..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -50,6 +50,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "Підготовка до сплячого режиму..."
IDS_SAVEYOURSETTINGS "Збереження параметрів..."
IDS_REACTOSISSTARTINGUP "Запуск ReactOS..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d days"
END

View File

@@ -60,6 +60,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "正在准备休眠..."
IDS_SAVEYOURSETTINGS "正在保存设置..."
IDS_REACTOSISSTARTINGUP "ReactOS 正在启动..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d 天"
END

View File

@@ -58,6 +58,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "正在準備休眠..."
IDS_SAVEYOURSETTINGS "正在儲存設定..."
IDS_REACTOSISSTARTINGUP "ReactOS 正在啟動..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d 日"
END

View File

@@ -58,6 +58,7 @@ BEGIN
IDS_PREPARETOHIBERNATE "正在準備休眠..."
IDS_SAVEYOURSETTINGS "正在儲存設定..."
IDS_REACTOSISSTARTINGUP "ReactOS 正在啟動..."
IDS_LOGGINGOFF "Logging off..."
IDS_TIMEOUTSHORTFORMAT "%02d:%02d:%02d"
IDS_TIMEOUTLONGFORMAT "%d 天"
END

View File

@@ -33,6 +33,7 @@
#define IDS_PREPARETOHIBERNATE 1686
#define IDS_SAVEYOURSETTINGS 1687
#define IDS_REACTOSISSTARTINGUP 1690
#define IDS_LOGGINGOFF 1691
#define IDS_TIMEOUTSHORTFORMAT 1695
#define IDS_TIMEOUTLONGFORMAT 1696
#define IDS_REACTOSISRESTARTING 1697

View File

@@ -642,8 +642,6 @@ HandleLogon(
goto cleanup;
}
CallNotificationDlls(Session, LogonHandler);
/* Enable per-user settings */
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
UpdatePerUserSystemParameters(0, TRUE);
@@ -662,19 +660,22 @@ HandleLogon(
goto cleanup;
}
CallNotificationDlls(Session, LogonHandler);
/* Connect remote resources */
RestoreAllConnections(Session);
/* Start the user shell */
CallNotificationDlls(Session, StartShellHandler);
if (!StartUserShell(Session))
{
//WCHAR StatusMsg[256];
WARN("WL: WlxActivateUserShell() failed\n");
//LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, sizeof(StatusMsg) / sizeof(StatusMsg[0]));
//LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, ARRAYSIZE(StatusMsg));
//MessageBoxW(0, StatusMsg, NULL, MB_ICONERROR);
goto cleanup;
}
CallNotificationDlls(Session, StartShellHandler);
CallNotificationDlls(Session, PostShellHandler);
if (!InitializeScreenSaver(Session))
WARN("WL: Failed to initialize screen saver\n");
@@ -1039,6 +1040,13 @@ HandleLogoff(
return Status;
}
/* Invoke Logoff notifications on the application desktop */
SwitchDesktop(Session->ApplicationDesktop);
DisplayStatusMessage(Session, Session->ApplicationDesktop, IDS_LOGGINGOFF);
CallNotificationDlls(Session, LogoffHandler);
RemoveStatusMessage(Session);
/* The remaining Logoff steps run on the Winlogon desktop */
SwitchDesktop(Session->WinlogonDesktop);
PlayLogoffShutdownSound(Session, WLX_SHUTTINGDOWN(wlxAction));
@@ -1052,9 +1060,6 @@ HandleLogoff(
SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0);
// DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOGGINGOFF);
CallNotificationDlls(Session, LogoffHandler);
/* Kill remaining COM processes that may have been started by logoff scripts */
hThread = CreateThread(psa, 0, KillComProcesses, (PVOID)Session->UserToken, 0, NULL);
if (hThread)
@@ -1205,7 +1210,6 @@ DoGenericAction(
{
Session->LogonState = STATE_LOGGED_OFF;
Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
CallNotificationDlls(Session, LogonHandler);
}
}
break;
@@ -1246,8 +1250,16 @@ DoGenericAction(
case WLX_SAS_ACTION_FORCE_LOGOFF: /* 0x09 */
case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */
case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */
if (Session->LogonState != STATE_LOGGED_OFF)
if ((Session->LogonState != STATE_INIT) &&
(Session->LogonState != STATE_LOGGED_OFF) &&
(Session->LogonState != STATE_LOGGED_OFF_SAS) &&
(Session->LogonState != STATE_SHUT_DOWN))
{
ASSERT((Session->LogonState == STATE_LOGGED_ON) ||
(Session->LogonState == STATE_LOGGED_ON_SAS) ||
(Session->LogonState == STATE_LOCKED) ||
(Session->LogonState == STATE_LOCKED_SAS));
if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context))
break;
if (!NT_SUCCESS(HandleLogoff(Session, wlxAction)))