[WINLOGON]

- Move playing log on sound to HandleLogon
- Don't use HKEY_CURRENT_USER for accessing user registry key. This key points to settings of user which started Winlogon process (SYSTEM) instead of logged user. Instead use HKU\SID.
See issue #5436 for more details.

svn path=/trunk/; revision=54232
This commit is contained in:
Rafal Harabien 2011-10-22 18:28:05 +00:00
parent a29cf1d59d
commit 4772994fec
3 changed files with 193 additions and 127 deletions

View file

@ -195,6 +195,192 @@ cleanup:
return ret;
}
BOOL
PlaySoundRoutine(
IN LPCWSTR FileName,
IN UINT bLogon,
IN UINT Flags)
{
typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
typedef UINT (WINAPI *WAVEOUTGETNUMDEVS)(VOID);
PLAYSOUNDW Play;
WAVEOUTGETNUMDEVS waveOutGetNumDevs;
UINT NumDevs;
HMODULE hLibrary;
BOOL Ret = FALSE;
hLibrary = LoadLibraryW(L"winmm.dll");
if (hLibrary)
{
waveOutGetNumDevs = (WAVEOUTGETNUMDEVS)GetProcAddress(hLibrary, "waveOutGetNumDevs");
if (waveOutGetNumDevs)
{
NumDevs = waveOutGetNumDevs();
if (!NumDevs)
{
if (!bLogon)
{
Beep(500, 500);
}
FreeLibrary(hLibrary);
return FALSE;
}
}
Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
if (Play)
{
Ret = Play(FileName, NULL, Flags);
}
FreeLibrary(hLibrary);
}
return Ret;
}
DWORD
WINAPI
PlayLogonSoundThread(
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;
UNICODE_STRING SidString;
NTSTATUS Status;
ULONG Index = 0;
SC_HANDLE hSCManager, hService;
/* 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 service manager */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (!hSCManager)
{
ERR("OpenSCManager failed (%x)\n", GetLastError());
return 0;
}
/* Open wdmaud service */
hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
if (!hService)
{
/* Sound is not installed */
TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
CloseServiceHandle(hSCManager);
return 0;
}
/* Wait for wdmaud start */
do
{
if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
{
TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError());
break;
}
if (Info.dwCurrentState == SERVICE_RUNNING)
break;
Sleep(1000);
} while (Index++ < 20);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
/* If wdmaud is not running exit */
if (Info.dwCurrentState != SERVICE_RUNNING)
{
WARN("wdmaud has not started!\n");
return 0;
}
/* Sound subsystem is running. Play logon sound. */
TRACE("Playing logon sound: %ls\n", wszDest);
PlaySoundRoutine(wszDest, TRUE, SND_FILENAME);
return 0;
}
static VOID
PlayLogonSound(
IN OUT PWLSESSION Session)
{
HANDLE hThread;
hThread = CreateThread(NULL, 0, PlayLogonSoundThread, (PVOID)Session->UserToken, 0, NULL);
if (hThread)
CloseHandle(hThread);
}
static BOOL
HandleLogon(
IN OUT PWLSESSION Session)
@ -265,6 +451,10 @@ HandleLogon(
WARN("WL: Failed to initialize screen saver\n");
Session->hProfileInfo = ProfileInfo.hProfile;
/* Logon has successed. Play sound. */
PlayLogonSound(Session);
ret = TRUE;
cleanup:

View file

@ -23,125 +23,6 @@ PWLSESSION WLSession = NULL;
/* FUNCTIONS *****************************************************************/
BOOL
PlaySoundRoutine(
IN LPCWSTR FileName,
IN UINT bLogon,
IN UINT Flags)
{
typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
typedef UINT (WINAPI *WAVEOUTGETNUMDEVS)(VOID);
PLAYSOUNDW Play;
WAVEOUTGETNUMDEVS waveOutGetNumDevs;
UINT NumDevs;
HMODULE hLibrary;
BOOL Ret = FALSE;
hLibrary = LoadLibraryW(L"winmm.dll");
if (hLibrary)
{
waveOutGetNumDevs = (WAVEOUTGETNUMDEVS)GetProcAddress(hLibrary, "waveOutGetNumDevs");
if (waveOutGetNumDevs)
{
NumDevs = waveOutGetNumDevs();
if (!NumDevs)
{
if (!bLogon)
{
Beep(500, 500);
}
FreeLibrary(hLibrary);
return FALSE;
}
}
Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
if (Play)
{
Ret = Play(FileName, NULL, Flags);
}
FreeLibrary(hLibrary);
}
return Ret;
}
DWORD
WINAPI
PlayLogonSoundThread(
IN LPVOID lpParameter)
{
HKEY hKey;
WCHAR szBuffer[MAX_PATH] = {0};
WCHAR szDest[MAX_PATH];
DWORD dwSize = sizeof(szBuffer);
SERVICE_STATUS_PROCESS Info;
ULONG Index = 0;
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
ExitThread(0);
}
if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szBuffer, &dwSize) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
ExitThread(0);
}
RegCloseKey(hKey);
if (!szBuffer[0])
ExitThread(0);
szBuffer[MAX_PATH-1] = L'\0';
if (ExpandEnvironmentStringsW(szBuffer, szDest, MAX_PATH))
{
SC_HANDLE hSCManager, hService;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (!hSCManager)
ExitThread(0);;
hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
if (!hService)
{
CloseServiceHandle(hSCManager);
TRACE("WL: failed to open sysaudio Status %x\n", GetLastError());
ExitThread(0);
}
do
{
if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
{
TRACE("WL: QueryServiceStatusEx failed %x\n", GetLastError());
break;
}
if (Info.dwCurrentState == SERVICE_RUNNING)
break;
Sleep(1000);
}while(Index++ < 20);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
if (Info.dwCurrentState != SERVICE_RUNNING)
ExitThread(0);
PlaySoundRoutine(szDest, TRUE, SND_FILENAME);
}
ExitThread(0);
}
static BOOL
StartServicesManager(VOID)
{
@ -330,6 +211,7 @@ InitKeyboardLayouts()
return bRet;
}
BOOL
DisplayStatusMessage(
IN PWLSESSION Session,
@ -420,7 +302,6 @@ WinMain(
#endif
ULONG HardErrorResponse;
MSG Msg;
HANDLE hThread;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
@ -548,13 +429,6 @@ WinMain(
else
PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0);
/* Play logon sound */
hThread = CreateThread(NULL, 0, PlayLogonSoundThread, NULL, 0, NULL);
if (hThread)
{
CloseHandle(hThread);
}
/* Tell kernel that CurrentControlSet is good (needed
* to support Last good known configuration boot) */
NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1);

View file

@ -37,9 +37,11 @@
#include <rtlfuncs.h>
#include <exfuncs.h>
#include <setypes.h>
#include <sefuncs.h>
#include <ntsecapi.h>
#include <accctrl.h>
#include <aclapi.h>
#include <strsafe.h>
#include <reactos/undocuser.h>
#include <reactos/winlogon.h>