Skip to content

Commit b306f46

Browse files
committed
[MSGINA] Revisit WlxActivateUserShell(), add support for "Logon User Name" (reactos#8370)
- Add SAL annotations; - Avoid using hardcoded buffer sizes in function calls. - If the start-application (Userinit) launched successfully, store in the logged-in user's Explorer key, value `"Logon User Name"`, the user name that was entered verbatim in the "Log On" dialog to log into the system. This value is used as a "convenience" to display the `"Log Off <username>"` item in the explorer's Start menu (see `explorer!util.cpp:GetCurrentLoggedOnUserName()`), and the corresponding item in the "Shut Down" dialog. - utils.c: Introduce the `RegOpenLoggedOnHKCU()` helper, for opening the current logged-in user HKCU key. NOTE: Regarding the `.Default` registry key, see: https://devblogs.microsoft.com/oldnewthing/20070302-00/?p=27783
1 parent 55ed59c commit b306f46

File tree

3 files changed

+114
-27
lines changed

3 files changed

+114
-27
lines changed

dll/win32/msgina/msgina.c

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -499,46 +499,46 @@ WlxStartApplication(
499499
/*
500500
* @implemented
501501
*/
502-
BOOL WINAPI
502+
BOOL
503+
WINAPI
503504
WlxActivateUserShell(
504-
PVOID pWlxContext,
505-
PWSTR pszDesktopName,
506-
PWSTR pszMprLogonScript,
507-
PVOID pEnvironment)
505+
_In_ PVOID pWlxContext,
506+
_In_ PWSTR pszDesktopName,
507+
_In_ PWSTR pszMprLogonScript,
508+
_In_ PVOID pEnvironment)
508509
{
509-
HKEY hKey;
510+
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
511+
HKEY hKey, hKeyCurrentUser;
510512
DWORD BufSize, ValueType;
511-
WCHAR pszUserInitApp[MAX_PATH + 1];
512-
WCHAR pszExpUserInitApp[MAX_PATH];
513513
DWORD len;
514514
LONG rc;
515+
BOOL ret;
516+
WCHAR pszUserInitApp[MAX_PATH + 1];
517+
WCHAR pszExpUserInitApp[MAX_PATH];
515518

516519
TRACE("WlxActivateUserShell()\n");
517520

518521
UNREFERENCED_PARAMETER(pszMprLogonScript);
519522

520-
/* Get the path of userinit */
521-
rc = RegOpenKeyExW(
522-
HKEY_LOCAL_MACHINE,
523-
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
524-
0,
525-
KEY_QUERY_VALUE,
526-
&hKey);
523+
/* Get the path of Userinit */
524+
rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
525+
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
526+
0,
527+
KEY_QUERY_VALUE,
528+
&hKey);
527529
if (rc != ERROR_SUCCESS)
528530
{
529531
WARN("RegOpenKeyExW() failed with error %lu\n", rc);
530532
return FALSE;
531533
}
532534

533-
/* Query userinit application */
534535
BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL);
535-
rc = RegQueryValueExW(
536-
hKey,
537-
L"Userinit",
538-
NULL,
539-
&ValueType,
540-
(LPBYTE)pszUserInitApp,
541-
&BufSize);
536+
rc = RegQueryValueExW(hKey,
537+
L"Userinit",
538+
NULL,
539+
&ValueType,
540+
(PBYTE)pszUserInitApp,
541+
&BufSize);
542542
RegCloseKey(hKey);
543543
if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ))
544544
{
@@ -547,15 +547,52 @@ WlxActivateUserShell(
547547
}
548548
pszUserInitApp[MAX_PATH] = UNICODE_NULL;
549549

550-
len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
551-
if (len > MAX_PATH)
550+
len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, _countof(pszExpUserInitApp));
551+
if (len > _countof(pszExpUserInitApp))
552552
{
553553
WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len);
554554
return FALSE;
555555
}
556556

557-
/* Start userinit app */
558-
return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp);
557+
/* Start the Userinit application */
558+
ret = WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp);
559+
if (!ret)
560+
return ret;
561+
562+
/* For convenience, store in the logged-in user's Explorer key, the user name
563+
* that was entered verbatim in the "Log On" dialog to log into the system.
564+
* This name may differ from the resulting user name used during authentication. */
565+
566+
/* Open the per-user registry key */
567+
rc = RegOpenLoggedOnHKCU(pgContext->UserToken,
568+
KEY_SET_VALUE,
569+
&hKeyCurrentUser);
570+
if (rc != ERROR_SUCCESS)
571+
{
572+
ERR("RegOpenLoggedOnHKCU() failed with error %ld\n", rc);
573+
return ret;
574+
}
575+
576+
/* Open the subkey and write the value */
577+
rc = RegOpenKeyExW(hKeyCurrentUser,
578+
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
579+
0,
580+
KEY_SET_VALUE,
581+
&hKey);
582+
if (rc == ERROR_SUCCESS)
583+
{
584+
len = wcslen(pgContext->UserName) + 1;
585+
RegSetValueExW(hKey,
586+
L"Logon User Name",
587+
0,
588+
REG_SZ,
589+
(PBYTE)pgContext->UserName,
590+
len * sizeof(WCHAR));
591+
RegCloseKey(hKey);
592+
}
593+
RegCloseKey(hKeyCurrentUser);
594+
595+
return ret;
559596
}
560597

561598
/*

dll/win32/msgina/msgina.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ ShutdownDialog(
146146

147147
/* utils.c */
148148

149+
LONG
150+
RegOpenLoggedOnHKCU(
151+
_In_opt_ HANDLE hUserToken,
152+
_In_ REGSAM samDesired,
153+
_Out_ PHKEY phkResult);
154+
149155
LONG
150156
ReadRegSzValue(
151157
_In_ HKEY hKey,

dll/win32/msgina/utils.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,50 @@
99

1010
#include "msgina.h"
1111

12+
/**
13+
* @brief
14+
* Opens and retrieves a handle to the HKEY_CURRENT_USER
15+
* corresponding to the specified logged-on user.
16+
*
17+
* @param[in] hUserToken
18+
* Optional handle to a primary or impersonation access token that represents
19+
* a logged-on user. See @b ImpersonateLoggedOnUser() for more information.
20+
* If NULL, opens the SYSTEM's HKEY_USERS\.Default (i.e. HKEY_USERS\S-1-5-18).
21+
*
22+
* @param[in] samDesired
23+
* A mask (type: REGSAM or ACCESS_MASK) that specifies the desired access
24+
* rights to the key. See @b RegOpenCurrentUser() for more information.
25+
*
26+
* @param[out] phkResult
27+
* A pointer to a variable that receives a handle to the opened key.
28+
* When the handle is no longer needed, close it with @b RegCloseKey().
29+
**/
30+
LONG
31+
RegOpenLoggedOnHKCU(
32+
_In_opt_ HANDLE hUserToken,
33+
_In_ REGSAM samDesired,
34+
_Out_ PHKEY phkResult)
35+
{
36+
LONG rc;
37+
38+
/* Impersonate the logged-on user if necessary */
39+
if (hUserToken && !ImpersonateLoggedOnUser(hUserToken))
40+
{
41+
rc = GetLastError();
42+
ERR("ImpersonateLoggedOnUser() failed with error %ld\n", rc);
43+
return rc;
44+
}
45+
46+
/* Open the logged-on user HKCU key */
47+
rc = RegOpenCurrentUser(samDesired, phkResult);
48+
49+
/* Revert the impersonation */
50+
if (hUserToken)
51+
RevertToSelf();
52+
53+
return rc;
54+
}
55+
1256
LONG
1357
ReadRegSzValue(
1458
_In_ HKEY hKey,

0 commit comments

Comments
 (0)