Author: rharabien Date: Sat Oct 22 18:28:05 2011 New Revision: 54232
URL: http://svn.reactos.org/svn/reactos?rev=54232&view=rev Log: [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.
Modified: trunk/reactos/base/system/winlogon/sas.c trunk/reactos/base/system/winlogon/winlogon.c trunk/reactos/base/system/winlogon/winlogon.h
Modified: trunk/reactos/base/system/winlogon/sas.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/sas.c?... ============================================================================== --- trunk/reactos/base/system/winlogon/sas.c [iso-8859-1] (original) +++ trunk/reactos/base/system/winlogon/sas.c [iso-8859-1] Sat Oct 22 18:28:05 2011 @@ -195,6 +195,192 @@ 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 @@ WARN("WL: Failed to initialize screen saver\n");
Session->hProfileInfo = ProfileInfo.hProfile; + + /* Logon has successed. Play sound. */ + PlayLogonSound(Session); + ret = TRUE;
cleanup:
Modified: trunk/reactos/base/system/winlogon/winlogon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/winlog... ============================================================================== --- trunk/reactos/base/system/winlogon/winlogon.c [iso-8859-1] (original) +++ trunk/reactos/base/system/winlogon/winlogon.c [iso-8859-1] Sat Oct 22 18:28:05 2011 @@ -22,125 +22,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 @@ return bRet; }
+ BOOL DisplayStatusMessage( IN PWLSESSION Session, @@ -420,7 +302,6 @@ #endif ULONG HardErrorResponse; MSG Msg; - HANDLE hThread;
UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); @@ -548,13 +429,6 @@ 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);
Modified: trunk/reactos/base/system/winlogon/winlogon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/winlog... ============================================================================== --- trunk/reactos/base/system/winlogon/winlogon.h [iso-8859-1] (original) +++ trunk/reactos/base/system/winlogon/winlogon.h [iso-8859-1] Sat Oct 22 18:28:05 2011 @@ -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>