/****************************** Module Header ******************************\
* Module Name: logon.c
*
* Copyright (c) 1992, Microsoft Corporation
*
* Handles logoff dialog.
*
* History:
* 2-25-92 JohanneC Created -
*
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
BOOL
SetGINAEnvVars (
PGLOBALS pGlobals
);
BOOL
SetupBasicEnvironment(
PVOID * ppEnv
)
{
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
DWORD dwComputerNameSize = MAX_COMPUTERNAME_LENGTH+1;
if (GetComputerName (szComputerName, &dwComputerNameSize)) {
SetUserEnvironmentVariable(ppEnv, COMPUTERNAME_VARIABLE, (LPTSTR) szComputerName, TRUE);
}
return(TRUE);
}
/***************************************************************************\
* SetupUserEnvironment
*
* Initializes all system and user environment variables, retrieves the user's
* profile, sets current directory...
*
* Returns TRUE on success, FALSE on failure.
*
* History:
* 2-28-92 Johannec Created
*
\***************************************************************************/
BOOL
SetupUserEnvironment(
PGLOBALS pGlobals
)
{
PVOID pEnv = NULL;
TCHAR lpHomeShare[MAX_PATH] = TEXT("");
TCHAR lpHomePath[MAX_PATH] = TEXT("");
TCHAR lpHomeDrive[4] = TEXT("");
TCHAR lpHomeDirectory[MAX_PATH] = TEXT("");
TCHAR lpUserProfile[MAX_PATH];
DWORD dwSize = MAX_PATH;
NTSTATUS Status;
if (!pGlobals->hEventLog) {
//
// Register the event source for winlogon events.
//
pGlobals->hEventLog = RegisterEventSource(NULL, EVENTLOG_SOURCE);
}
/*
* Create a new environment for the user.
*/
if (!CreateUserEnvironment(&pEnv))
{
return(FALSE);
}
SetupBasicEnvironment(&pEnv);
/*
* Initialize user's environment.
*/
#if 0
SetUserEnvironmentVariable(&pEnv, USERNAME_VARIABLE, (LPTSTR)pGlobals->UserName, TRUE);
SetUserEnvironmentVariable(&pEnv, USERDOMAIN_VARIABLE, (LPTSTR)pGlobals->Domain, TRUE);
if (pGlobals->Profile->HomeDirectoryDrive.Length &&
(pGlobals->Profile->HomeDirectoryDrive.Length + 1) < MAX_PATH) {
lstrcpy(lpHomeDrive, pGlobals->Profile->HomeDirectoryDrive.Buffer);
}
if (pGlobals->Profile->HomeDirectory.Length &&
(pGlobals->Profile->HomeDirectory.Length + 1) < MAX_PATH) {
lstrcpy(lpHomeDirectory, pGlobals->Profile->HomeDirectory.Buffer);
}
#endif
SetHomeDirectoryEnvVars(&pEnv, lpHomeDirectory,
lpHomeDrive, lpHomeShare, lpHomePath);
#if 0
if (pGlobals->Profile->ProfilePath.Length) {
pGlobals->UserProfile.ProfilePath =
AllocAndExpandEnvironmentStrings(pGlobals->Profile->ProfilePath.Buffer);
} else {
pGlobals->UserProfile.ProfilePath = NULL;
}
#endif
//
// Load the user's profile into the registry
//
Status = RestoreUserProfile(pGlobals);
if (Status != STATUS_SUCCESS) {
DebugLog((DEB_ERROR, "restoring the user profile failed"));
return(FALSE);
}
//
// Set USERPROFILE environment variable
//
if (GetUserProfileDirectory (pGlobals->UserProcessData.UserToken,
lpUserProfile, &dwSize)) {
SetUserEnvironmentVariable(&pEnv, USERPROFILE_VARIABLE, lpUserProfile, TRUE);
}
pGlobals->UserProcessData.pEnvironment = pEnv;
if (pGlobals->UserProcessData.CurrentDirectory = (LPTSTR)Alloc(
sizeof(TCHAR)*(lstrlen(lpHomeDirectory)+1)))
lstrcpy(pGlobals->UserProcessData.CurrentDirectory, lpHomeDirectory);
//
// Set the GINA environment variables in the registry
//
SetGINAEnvVars (pGlobals);
/*
* Set all windows controls to be the user's settings.
*/
InitSystemParametersInfo(pGlobals, TRUE);
return(TRUE);
}
/***************************************************************************\
* ResetEnvironment
*
*
* History:
* 2-28-92 Johannec Created
*
\***************************************************************************/
VOID
ResetEnvironment(
PGLOBALS pGlobals
)
{
//
// If they were logged on as system, all these values will be NULL
//
if (pGlobals->UserProcessData.CurrentDirectory) {
Free(pGlobals->UserProcessData.CurrentDirectory);
pGlobals->UserProcessData.CurrentDirectory = NULL;
}
if (pGlobals->UserProcessData.pEnvironment) {
RtlDestroyEnvironment(pGlobals->UserProcessData.pEnvironment);
pGlobals->UserProcessData.pEnvironment = NULL;
}
if (pGlobals->UserProfile.ProfilePath) {
Free(pGlobals->UserProfile.ProfilePath);
pGlobals->UserProfile.ProfilePath = NULL;
}
if (pGlobals->UserProfile.PolicyPath) {
Free(pGlobals->UserProfile.PolicyPath);
pGlobals->UserProfile.PolicyPath = NULL;
}
if (pGlobals->UserProfile.NetworkDefaultUserProfile) {
Free(pGlobals->UserProfile.NetworkDefaultUserProfile);
pGlobals->UserProfile.NetworkDefaultUserProfile = NULL;
}
if (pGlobals->UserProfile.ServerName) {
Free(pGlobals->UserProfile.ServerName);
pGlobals->UserProfile.ServerName = NULL;
}
if (pGlobals->UserProfile.Environment) {
Free(pGlobals->UserProfile.Environment);
pGlobals->UserProfile.Environment = NULL;
}
//
// Reset all windows controls to be the default settings
//
InitSystemParametersInfo(pGlobals, FALSE);
}
/***************************************************************************\
* OpenHKeyCurrentUser
*
* Opens HKeyCurrentUser to point at the current logged on user's profile.
*
* Returns TRUE on success, FALSE on failure
*
* History:
* 06-16-92 Davidc Created
*
\***************************************************************************/
BOOL
OpenHKeyCurrentUser(
PGLOBALS pGlobals
)
{
DWORD err;
HANDLE ImpersonationHandle;
BOOL Result;
//
// Make sure HKEY_CURRENT_USER is closed before
// remapping it.
//
try {
RegCloseKey(HKEY_CURRENT_USER);
} except(EXCEPTION_EXECUTE_HANDLER) {};
//
// Get in the correct context before we reference the registry
//
ImpersonationHandle = ImpersonateUser(&pGlobals->UserProcessData, NULL);
if (ImpersonationHandle == NULL) {
DebugLog((DEB_ERROR, "OpenHKeyCurrentUser failed to impersonate user"));
return(FALSE);
}
//
// Access the registry to force HKEY_CURRENT_USER to be re-opened
//
err = RegEnumKey(HKEY_CURRENT_USER, 0, NULL, 0);
//
// Return to our own context
//
Result = StopImpersonating(ImpersonationHandle);
ASSERT(Result);
return(TRUE);
}
/***************************************************************************\
* CloseHKeyCurrentUser
*
* Closes HKEY_CURRENT_USER.
* Any registry reference will automatically re-open it, so this is
* only a token gesture - but it allows the registry hive to be unloaded.
*
* Returns nothing
*
* History:
* 06-16-92 Davidc Created
*
\***************************************************************************/
VOID
CloseHKeyCurrentUser(
PGLOBALS pGlobals
)
{
DWORD err;
err = RegCloseKey(HKEY_CURRENT_USER);
ASSERT(err == ERROR_SUCCESS);
}
/***************************************************************************\
* FUNCTION: SetEnvironmentULong
*
* PURPOSE: Sets the value of an environment variable to the string
* representation of the passed data.
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetEnvironmentULong(
LPTSTR Variable,
ULONG Value
)
{
TCHAR Buffer[10];
int Result;
Result = _snwprintf(Buffer, sizeof(Buffer)/sizeof(TCHAR), TEXT("%x"), Value);
ASSERT(Result < sizeof(Buffer));
return (SetEnvironmentVariable(Variable, Buffer));
}
/***************************************************************************\
* FUNCTION: SetEnvironmentLargeInt
*
* PURPOSE: Sets the value of an environment variable to the string
* representation of the passed data.
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 01-12-93 Davidc Created.
*
\***************************************************************************/
BOOL
SetEnvironmentLargeInt(
LPTSTR Variable,
LARGE_INTEGER Value
)
{
TCHAR Buffer[20];
int Result;
Result = _snwprintf(Buffer, sizeof(Buffer)/sizeof(TCHAR), TEXT("%x:%x"), Value.HighPart, Value.LowPart);
ASSERT(Result < sizeof(Buffer));
return (SetEnvironmentVariable(Variable, Buffer));
}
/***************************************************************************\
* FUNCTION: SetGINAEnvVars
*
* PURPOSE: Sets the environment variables GINA passed back to the
* volatile environment in the user's profile
*
* RETURNS: TRUE on success, FALSE on failure
*
* HISTORY:
*
* 09-26-95 EricFlo Created.
*
\***************************************************************************/
#define MAX_VALUE_LEN 1024
BOOL
SetGINAEnvVars (
PGLOBALS pGlobals
)
{
TCHAR szValueName[MAX_VALUE_LEN + 1];
TCHAR szValue[MAX_VALUE_LEN + 1];
LPTSTR lpEnv = pGlobals->UserProfile.Environment;
LPTSTR lpEnd, lpBegin, lpTemp;
HKEY hKey = NULL;
DWORD dwDisp;
BOOL bRetVal = FALSE;
DWORD cPercent, len, i;
if (!lpEnv) {
return TRUE;
}
if (!OpenHKeyCurrentUser(pGlobals)) {
DebugLog((DEB_ERROR, "SetGINAEnvVars: Failed to open HKeyCurrentUser"));
return FALSE;
}
if (RegCreateKeyEx(HKEY_CURRENT_USER,
TEXT("Volatile Environment"),
0,
NULL,
REG_OPTION_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
&dwDisp) != ERROR_SUCCESS) {
goto Exit;
}
lpEnd = lpBegin = lpEnv;
for (;;) {
//
// Skip leading blanks
//
while (*lpEnd == TEXT(' ')) {
lpEnd++;
}
lpBegin = lpEnd;
//
// Search for the = sign
//
while (*lpEnd && *lpEnd != TEXT('=')) {
lpEnd++;
}
if (!*lpEnd) {
goto Exit;
}
//
// Null terminate and copy to value name buffer
//
*lpEnd = TEXT('\0');
if (lstrlen(lpBegin) + 1 > MAX_VALUE_LEN) {
goto Exit;
}
lstrcpy (szValueName, lpBegin);
*lpEnd++ = TEXT('=');
//
// Trim off any trailing spaces
//
lpTemp = szValueName + (lstrlen (szValueName) - 1);
while (*lpTemp && (*lpTemp == TEXT(' ')) ) {
lpTemp--;
}
lpTemp++;
*lpTemp = TEXT('\0');
//
// Skip leading blanks before value data
//
while (*lpEnd == TEXT(' ')) {
lpEnd++;
}
lpBegin = lpEnd;
//
// Search for the null terminator
//
while (*lpEnd) {
lpEnd++;
}
if (lstrlen(lpBegin) + 1 > MAX_VALUE_LEN) {
goto Exit;
}
lstrcpy (szValue, lpBegin);
//
// Trim off any trailing spaces
//
lpTemp = szValue + (lstrlen (szValue) - 1);
while (*lpTemp && (*lpTemp == TEXT(' ')) ) {
lpTemp--;
}
lpTemp++;
*lpTemp = TEXT('\0');
//
// Scan the value data to see if a 2 % signs exist.
// If so, then this is an expand_sz type.
//
cPercent = 0;
len = lstrlen (szValue);
for (i = 0; i < len; i++) {
if (szValue[i] == TEXT('%')) {
cPercent++;
}
}
//
// Set it in the user profile
//
RegSetValueEx (hKey,
szValueName,
0,
(cPercent >= 2) ? REG_EXPAND_SZ : REG_SZ,
(LPBYTE) szValue,
(len + 1) * sizeof(TCHAR));
lpEnd++;
if (!*lpEnd) {
break;
}
lpBegin = lpEnd;
}
bRetVal = TRUE;
Exit:
if (hKey) {
RegCloseKey (hKey);
}
CloseHKeyCurrentUser(pGlobals);
return bRetVal;
}