diff --git a/dll/win32/msgina/msgina.c b/dll/win32/msgina/msgina.c index bcde8e93394..859cb7b1221 100644 --- a/dll/win32/msgina/msgina.c +++ b/dll/win32/msgina/msgina.c @@ -499,46 +499,46 @@ WlxStartApplication( /* * @implemented */ -BOOL WINAPI +BOOL +WINAPI WlxActivateUserShell( - PVOID pWlxContext, - PWSTR pszDesktopName, - PWSTR pszMprLogonScript, - PVOID pEnvironment) + _In_ PVOID pWlxContext, + _In_ PWSTR pszDesktopName, + _In_ PWSTR pszMprLogonScript, + _In_ PVOID pEnvironment) { - HKEY hKey; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + HKEY hKey, hKeyCurrentUser; DWORD BufSize, ValueType; - WCHAR pszUserInitApp[MAX_PATH + 1]; - WCHAR pszExpUserInitApp[MAX_PATH]; DWORD len; LONG rc; + BOOL ret; + WCHAR pszUserInitApp[MAX_PATH + 1]; + WCHAR pszExpUserInitApp[MAX_PATH]; TRACE("WlxActivateUserShell()\n"); UNREFERENCED_PARAMETER(pszMprLogonScript); - /* Get the path of userinit */ - rc = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", - 0, - KEY_QUERY_VALUE, - &hKey); + /* Get the path of Userinit */ + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", + 0, + KEY_QUERY_VALUE, + &hKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyExW() failed with error %lu\n", rc); return FALSE; } - /* Query userinit application */ BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL); - rc = RegQueryValueExW( - hKey, - L"Userinit", - NULL, - &ValueType, - (LPBYTE)pszUserInitApp, - &BufSize); + rc = RegQueryValueExW(hKey, + L"Userinit", + NULL, + &ValueType, + (PBYTE)pszUserInitApp, + &BufSize); RegCloseKey(hKey); if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ)) { @@ -547,15 +547,52 @@ WlxActivateUserShell( } pszUserInitApp[MAX_PATH] = UNICODE_NULL; - len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH); - if (len > MAX_PATH) + len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, _countof(pszExpUserInitApp)); + if (len > _countof(pszExpUserInitApp)) { WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len); return FALSE; } - /* Start userinit app */ - return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp); + /* Start the Userinit application */ + ret = WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp); + if (!ret) + return ret; + + /* For convenience, store in the logged-in user's Explorer key, the user name + * that was entered verbatim in the "Log On" dialog to log into the system. + * This name may differ from the resulting user name used during authentication. */ + + /* Open the per-user registry key */ + rc = RegOpenLoggedOnHKCU(pgContext->UserToken, + KEY_SET_VALUE, + &hKeyCurrentUser); + if (rc != ERROR_SUCCESS) + { + ERR("RegOpenLoggedOnHKCU() failed with error %ld\n", rc); + return ret; + } + + /* Open the subkey and write the value */ + rc = RegOpenKeyExW(hKeyCurrentUser, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", + 0, + KEY_SET_VALUE, + &hKey); + if (rc == ERROR_SUCCESS) + { + len = wcslen(pgContext->UserName) + 1; + RegSetValueExW(hKey, + L"Logon User Name", + 0, + REG_SZ, + (PBYTE)pgContext->UserName, + len * sizeof(WCHAR)); + RegCloseKey(hKey); + } + RegCloseKey(hKeyCurrentUser); + + return ret; } /* diff --git a/dll/win32/msgina/msgina.h b/dll/win32/msgina/msgina.h index 405653bc884..fa15132ec72 100644 --- a/dll/win32/msgina/msgina.h +++ b/dll/win32/msgina/msgina.h @@ -146,6 +146,12 @@ ShutdownDialog( /* utils.c */ +LONG +RegOpenLoggedOnHKCU( + _In_opt_ HANDLE hUserToken, + _In_ REGSAM samDesired, + _Out_ PHKEY phkResult); + LONG ReadRegSzValue( _In_ HKEY hKey, diff --git a/dll/win32/msgina/utils.c b/dll/win32/msgina/utils.c index 6047ea19773..c53a4c0eaab 100644 --- a/dll/win32/msgina/utils.c +++ b/dll/win32/msgina/utils.c @@ -9,6 +9,50 @@ #include "msgina.h" +/** + * @brief + * Opens and retrieves a handle to the HKEY_CURRENT_USER + * corresponding to the specified logged-on user. + * + * @param[in] hUserToken + * Optional handle to a primary or impersonation access token that represents + * a logged-on user. See @b ImpersonateLoggedOnUser() for more information. + * If NULL, opens the SYSTEM's HKEY_USERS\.Default (i.e. HKEY_USERS\S-1-5-18). + * + * @param[in] samDesired + * A mask (type: REGSAM or ACCESS_MASK) that specifies the desired access + * rights to the key. See @b RegOpenCurrentUser() for more information. + * + * @param[out] phkResult + * A pointer to a variable that receives a handle to the opened key. + * When the handle is no longer needed, close it with @b RegCloseKey(). + **/ +LONG +RegOpenLoggedOnHKCU( + _In_opt_ HANDLE hUserToken, + _In_ REGSAM samDesired, + _Out_ PHKEY phkResult) +{ + LONG rc; + + /* Impersonate the logged-on user if necessary */ + if (hUserToken && !ImpersonateLoggedOnUser(hUserToken)) + { + rc = GetLastError(); + ERR("ImpersonateLoggedOnUser() failed with error %ld\n", rc); + return rc; + } + + /* Open the logged-on user HKCU key */ + rc = RegOpenCurrentUser(samDesired, phkResult); + + /* Revert the impersonation */ + if (hUserToken) + RevertToSelf(); + + return rc; +} + LONG ReadRegSzValue( _In_ HKEY hKey,