[WINLOGON] Add WLSESSION logon timestamp (#7590)

Remove startup sound hack.
CORE-13951
This commit is contained in:
Thamatip Chitpong 2025-01-08 08:28:24 +07:00 committed by GitHub
parent 6363f7820d
commit 1dfba2a699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 55 additions and 26 deletions

View file

@ -46,6 +46,12 @@ static BOOL ExitReactOSInProgress = FALSE;
LUID LuidNone = {0, 0}; LUID LuidNone = {0, 0};
typedef struct tagLOGON_SOUND_DATA
{
HANDLE UserToken;
BOOL IsStartup;
} LOGON_SOUND_DATA, *PLOGON_SOUND_DATA;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static BOOL static BOOL
@ -286,26 +292,12 @@ PlaySoundRoutine(
} }
static static
BOOL
IsFirstLogon(VOID)
{
/* FIXME: All of this is a HACK, designed specifically for PlayLogonSoundThread.
* Don't call IsFirstLogon multiple times inside the same function. And please
* note that this function is not thread-safe. */
static BOOL bFirstLogon = TRUE;
if (bFirstLogon)
{
bFirstLogon = FALSE;
return TRUE;
}
return FALSE;
}
DWORD DWORD
WINAPI WINAPI
PlayLogonSoundThread( PlayLogonSoundThread(
IN LPVOID lpParameter) _In_ LPVOID lpParameter)
{ {
PLOGON_SOUND_DATA SoundData = (PLOGON_SOUND_DATA)lpParameter;
SERVICE_STATUS_PROCESS Info; SERVICE_STATUS_PROCESS Info;
DWORD dwSize; DWORD dwSize;
ULONG Index = 0; ULONG Index = 0;
@ -316,7 +308,7 @@ PlayLogonSoundThread(
if (!hSCManager) if (!hSCManager)
{ {
ERR("OpenSCManager failed (%x)\n", GetLastError()); ERR("OpenSCManager failed (%x)\n", GetLastError());
return 0; goto Cleanup;
} }
/* Open the wdmaud service */ /* Open the wdmaud service */
@ -326,7 +318,7 @@ PlayLogonSoundThread(
/* The service is not installed */ /* The service is not installed */
TRACE("Failed to open wdmaud service (%x)\n", GetLastError()); TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
CloseServiceHandle(hSCManager); CloseServiceHandle(hSCManager);
return 0; goto Cleanup;
} }
/* Wait for wdmaud to start */ /* Wait for wdmaud to start */
@ -352,34 +344,49 @@ PlayLogonSoundThread(
if (Info.dwCurrentState != SERVICE_RUNNING) if (Info.dwCurrentState != SERVICE_RUNNING)
{ {
WARN("wdmaud has not started!\n"); WARN("wdmaud has not started!\n");
return 0; goto Cleanup;
} }
/* Sound subsystem is running. Play logon sound. */ /* Sound subsystem is running. Play logon sound. */
TRACE("Playing logon sound\n"); TRACE("Playing %s sound\n", SoundData->IsStartup ? "startup" : "logon");
if (!ImpersonateLoggedOnUser((HANDLE)lpParameter)) if (!ImpersonateLoggedOnUser(SoundData->UserToken))
{ {
ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError()); ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError());
} }
else else
{ {
PlaySoundRoutine(IsFirstLogon() ? L"SystemStart" : L"WindowsLogon", PlaySoundRoutine(SoundData->IsStartup ? L"SystemStart" : L"WindowsLogon",
TRUE, TRUE,
SND_ALIAS | SND_NODEFAULT); SND_ALIAS | SND_NODEFAULT);
RevertToSelf(); RevertToSelf();
} }
Cleanup:
HeapFree(GetProcessHeap(), 0, SoundData);
return 0; return 0;
} }
static static
VOID VOID
PlayLogonSound( PlayLogonSound(
IN OUT PWLSESSION Session) _In_ PWLSESSION Session)
{ {
PLOGON_SOUND_DATA SoundData;
HANDLE hThread; HANDLE hThread;
hThread = CreateThread(NULL, 0, PlayLogonSoundThread, (PVOID)Session->UserToken, 0, NULL); SoundData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGON_SOUND_DATA));
if (hThread) if (!SoundData)
return;
SoundData->UserToken = Session->UserToken;
SoundData->IsStartup = IsFirstLogon(Session);
hThread = CreateThread(NULL, 0, PlayLogonSoundThread, SoundData, 0, NULL);
if (!hThread)
{
HeapFree(GetProcessHeap(), 0, SoundData);
return;
}
CloseHandle(hThread); CloseHandle(hThread);
} }
@ -571,6 +578,9 @@ HandleLogon(
/* Logon has succeeded. Play sound. */ /* Logon has succeeded. Play sound. */
PlayLogonSound(Session); PlayLogonSound(Session);
/* NOTE: The logon timestamp has to be set after calling PlayLogonSound
* to correctly detect the startup event (first logon) */
SetLogonTimestamp(Session);
ret = TRUE; ret = TRUE;
cleanup: cleanup:

View file

@ -41,6 +41,7 @@
#include <winwlx.h> #include <winwlx.h>
#include <ndk/rtlfuncs.h> #include <ndk/rtlfuncs.h>
#include <ndk/exfuncs.h> #include <ndk/exfuncs.h>
#include <ndk/kefuncs.h>
#include <strsafe.h> #include <strsafe.h>
/* PSEH for SEH Support */ /* PSEH for SEH Support */
@ -233,6 +234,7 @@ typedef struct _WLSESSION
HANDLE hProfileInfo; HANDLE hProfileInfo;
LOGON_STATE LogonState; LOGON_STATE LogonState;
DWORD DialogTimeout; /* Timeout for dialog boxes, in seconds */ DWORD DialogTimeout; /* Timeout for dialog boxes, in seconds */
LARGE_INTEGER LastLogon;
/* Screen-saver informations */ /* Screen-saver informations */
#ifndef USE_GETLASTINPUTINFO #ifndef USE_GETLASTINPUTINFO
@ -285,6 +287,23 @@ extern PWLSESSION WLSession;
((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \ ((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \
) )
FORCEINLINE
VOID
SetLogonTimestamp(
_Inout_ PWLSESSION Session)
{
NtQuerySystemTime(&Session->LastLogon);
}
FORCEINLINE
BOOL
IsFirstLogon(
_In_ PWLSESSION Session)
{
/* The WLSESSION::LastLogon is initialized to 0 so this is OK */
return (Session->LastLogon.QuadPart == 0);
}
/* environment.c */ /* environment.c */
BOOL BOOL
CreateUserEnvironment(IN PWLSESSION Session); CreateUserEnvironment(IN PWLSESSION Session);