[WINLOGON] Implement logoff and MessageBeep sounds support (#4755)

CORE-13951
This commit is contained in:
Thamatip Chitpong 2022-10-05 08:33:28 +07:00 committed by Hermès Bélusca-Maïto
parent cc114a0706
commit 9d48f26d29
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -4,7 +4,7 @@
* FILE: base/system/winlogon/sas.c * FILE: base/system/winlogon/sas.c
* PURPOSE: Secure Attention Sequence * PURPOSE: Secure Attention Sequence
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org) * Hervé Poussineau (hpoussin@reactos.org)
* Arnav Bhatt (arnavbhatt288@gmail.com) * Arnav Bhatt (arnavbhatt288@gmail.com)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 28/03/2004 * Created 28/03/2004
@ -290,88 +290,11 @@ WINAPI
PlayLogonSoundThread( PlayLogonSoundThread(
IN LPVOID lpParameter) IN LPVOID lpParameter)
{ {
BYTE TokenUserBuffer[256];
PTOKEN_USER pTokenUser = (TOKEN_USER*)TokenUserBuffer;
ULONG Length;
HKEY hKey;
WCHAR wszBuffer[MAX_PATH] = {0};
WCHAR wszDest[MAX_PATH];
DWORD dwSize = sizeof(wszBuffer), dwType;
SERVICE_STATUS_PROCESS Info; SERVICE_STATUS_PROCESS Info;
UNICODE_STRING SidString; DWORD dwSize;
NTSTATUS Status;
ULONG Index = 0; ULONG Index = 0;
SC_HANDLE hSCManager, hService; SC_HANDLE hSCManager, hService;
//
// FIXME: Isn't it possible to *JUST* impersonate the current user
// *AND* open its HKCU??
//
/* Get SID of current user */
Status = NtQueryInformationToken((HANDLE)lpParameter,
TokenUser,
TokenUserBuffer,
sizeof(TokenUserBuffer),
&Length);
if (!NT_SUCCESS(Status))
{
ERR("NtQueryInformationToken failed: %x!\n", Status);
return 0;
}
/* Convert SID to string */
RtlInitEmptyUnicodeString(&SidString, wszBuffer, sizeof(wszBuffer));
Status = RtlConvertSidToUnicodeString(&SidString, pTokenUser->User.Sid, FALSE);
if (!NT_SUCCESS(Status))
{
ERR("RtlConvertSidToUnicodeString failed: %x!\n", Status);
return 0;
}
/* Build path to logon sound registry key.
Note: We can't use HKCU here, because Winlogon is owned by SYSTEM user */
if (FAILED(StringCbCopyW(wszBuffer + SidString.Length/sizeof(WCHAR),
sizeof(wszBuffer) - SidString.Length,
L"\\AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current")))
{
/* SID is too long. Should not happen. */
ERR("StringCbCopyW failed!\n");
return 0;
}
/* Open registry key and query sound path */
if (RegOpenKeyExW(HKEY_USERS, wszBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
ERR("RegOpenKeyExW(%ls) failed!\n", wszBuffer);
return 0;
}
if (RegQueryValueExW(hKey, NULL, NULL, &dwType,
(LPBYTE)wszBuffer, &dwSize) != ERROR_SUCCESS ||
(dwType != REG_SZ && dwType != REG_EXPAND_SZ))
{
ERR("RegQueryValueExW failed!\n");
RegCloseKey(hKey);
return 0;
}
RegCloseKey(hKey);
if (!wszBuffer[0])
{
/* No sound has been set */
ERR("No sound has been set\n");
return 0;
}
/* Expand environment variables */
if (!ExpandEnvironmentStringsW(wszBuffer, wszDest, MAX_PATH))
{
ERR("ExpandEnvironmentStringsW failed!\n");
return 0;
}
/* Open the service manager */ /* Open the service manager */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (!hSCManager) if (!hSCManager)
@ -417,8 +340,16 @@ PlayLogonSoundThread(
} }
/* Sound subsystem is running. Play logon sound. */ /* Sound subsystem is running. Play logon sound. */
TRACE("Playing logon sound: %ls\n", wszDest); TRACE("Playing logon sound\n");
PlaySoundRoutine(wszDest, TRUE, SND_FILENAME); if (!ImpersonateLoggedOnUser((HANDLE)lpParameter))
{
ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError());
}
else
{
PlaySoundRoutine(L"WindowsLogon", TRUE, SND_ALIAS | SND_NODEFAULT);
RevertToSelf();
}
return 0; return 0;
} }
@ -434,6 +365,37 @@ PlayLogonSound(
CloseHandle(hThread); CloseHandle(hThread);
} }
static
VOID
PlayLogoffSound(
_In_ PWLSESSION Session)
{
if (!ImpersonateLoggedOnUser(Session->UserToken))
return;
PlaySoundRoutine(L"WindowsLogoff", FALSE, SND_ALIAS | SND_NODEFAULT);
RevertToSelf();
}
static
BOOL
PlayEventSound(
_In_ PWLSESSION Session,
_In_ LPCWSTR EventName)
{
BOOL bRet;
if (!ImpersonateLoggedOnUser(Session->UserToken))
return FALSE;
bRet = PlaySoundRoutine(EventName, FALSE, SND_ALIAS | SND_ASYNC | SND_NODEFAULT);
RevertToSelf();
return bRet;
}
static static
VOID VOID
RestoreAllConnections(PWLSESSION Session) RestoreAllConnections(PWLSESSION Session)
@ -880,7 +842,7 @@ HandleLogoff(
SwitchDesktop(Session->WinlogonDesktop); SwitchDesktop(Session->WinlogonDesktop);
// TODO: Play logoff sound! PlayLogoffSound(Session);
SetWindowStationUser(Session->InteractiveWindowStation, SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0); &LuidNone, NULL, 0);
@ -1274,38 +1236,40 @@ UnregisterHotKeys(
return TRUE; return TRUE;
} }
static
BOOL BOOL
WINAPI HandleMessageBeep(
HandleMessageBeep(UINT uType) _In_ PWLSESSION Session,
_In_ UINT uType)
{ {
LPWSTR EventName; LPWSTR EventName;
switch(uType) switch (uType)
{ {
case 0xFFFFFFFF: case 0xFFFFFFFF:
EventName = NULL; EventName = NULL;
break; break;
case MB_OK: case MB_OK:
EventName = L"SystemDefault"; EventName = L"SystemDefault";
break; break;
case MB_ICONASTERISK: case MB_ICONASTERISK:
EventName = L"SystemAsterisk"; EventName = L"SystemAsterisk";
break; break;
case MB_ICONEXCLAMATION: case MB_ICONEXCLAMATION:
EventName = L"SystemExclamation"; EventName = L"SystemExclamation";
break; break;
case MB_ICONHAND: case MB_ICONHAND:
EventName = L"SystemHand"; EventName = L"SystemHand";
break; break;
case MB_ICONQUESTION: case MB_ICONQUESTION:
EventName = L"SystemQuestion"; EventName = L"SystemQuestion";
break; break;
default: default:
WARN("Unhandled type %d\n", uType); WARN("Unhandled type %d\n", uType);
EventName = L"SystemDefault"; EventName = L"SystemDefault";
} }
return PlaySoundRoutine(EventName, FALSE, SND_ALIAS | SND_NOWAIT | SND_NOSTOP | SND_ASYNC); return PlayEventSound(Session, EventName);
} }
static static
@ -1376,7 +1340,7 @@ SASWindowProc(
{ {
case LN_MESSAGE_BEEP: case LN_MESSAGE_BEEP:
{ {
return HandleMessageBeep(lParam); return HandleMessageBeep(Session, lParam);
} }
case LN_SHELL_EXITED: case LN_SHELL_EXITED:
{ {