reactos/reactos/dll/win32/userenv/setup.c
Hermès Bélusca-Maïto c24dcb3ff2 [USERENV]
- Split the huge "InitializeProfiles" function into itself and a helper "CreateStandardProfile", the latter is called to set up the "Default User" and "All Users" profile directories & registry settings.
- Use StringSafe functions where needed.
- Some of the shell registry values (the multimedia ones in particular) and the Fonts folder path, are not set by userenv.dll but are set by shell32.dll when it is registered during 2nd stage setup.

[SHELL32]: The above-mentioned shell reg vals are already there, but few have different translations than the ones that were in userenv. Translators, please review & fix if needed!

[SYSSETUP]: It is syssetup.dll which sets up the 'Program Files' & 'Common Files' directories & registry values at 2nd stage setup, as done on Windows' setup. Move the code that did this from our userenv to syssetup.

svn path=/trunk/; revision=73518
2017-01-10 15:28:49 +00:00

507 lines
16 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: dll/win32/userenv/setup.c
* PURPOSE: Profile setup functions
* PROGRAMMERS: Eric Kohl
* Hermes Belusca-Maito
*/
#include "precomp.h"
#define NDEBUG
#include <debug.h>
#include "resources.h"
typedef struct _FOLDERDATA
{
LPWSTR lpValueName;
LPWSTR lpPath;
UINT uId;
BOOL bHidden;
BOOL bShellFolder;
BOOL bUserShellFolder;
} FOLDERDATA, *PFOLDERDATA;
static FOLDERDATA
UserShellFolders[] =
{
{L"AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
{L"Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
{L"Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
{L"Personal", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
{L"NetHood", L"NetHood", IDS_NETHOOD, TRUE, TRUE, TRUE},
{L"PrintHood", L"PrintHood", IDS_PRINTHOOD, TRUE, TRUE, TRUE},
{L"Recent", L"Recent", IDS_RECENT, TRUE, TRUE, TRUE},
{L"SendTo", L"SendTo", IDS_SENDTO, FALSE, TRUE, TRUE},
{L"Templates", L"Templates", IDS_TEMPLATES, FALSE, TRUE, TRUE},
{L"Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
{L"Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
{L"Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
{L"Local Settings", L"Local Settings", IDS_LOCALSETTINGS, TRUE, TRUE, TRUE},
{L"Local AppData", L"Local Settings\\Application Data", IDS_LOCALAPPDATA, TRUE, TRUE, TRUE},
{L"Temp", L"Local Settings\\Temp", IDS_TEMP, FALSE, FALSE, FALSE},
{L"Cache", L"Local Settings\\Temporary Internet Files", IDS_CACHE, FALSE, TRUE, TRUE},
{L"History", L"Local Settings\\History", IDS_HISTORY, FALSE, TRUE, TRUE},
{L"Cookies", L"Cookies", IDS_COOKIES, FALSE, TRUE, TRUE},
{NULL, NULL, -1, FALSE, FALSE, FALSE}
};
static FOLDERDATA
CommonShellFolders[] =
{
{L"Common AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
{L"Common Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
{L"Common Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
{L"Common Documents", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
{L"Common Templates", L"Templates", IDS_TEMPLATES, TRUE, TRUE, TRUE},
{L"Common Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
{L"Common Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
{L"Common Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
{NULL, NULL, -1, FALSE, FALSE, FALSE}
};
typedef struct _PROFILEPARAMS
{
LPCWSTR pszProfileName;
LPCWSTR pszProfileRegValue;
LPCWSTR pszEnvVar;
LPCWSTR pszEnvVarProfilePath;
PFOLDERDATA pFolderList;
HKEY hRootKey;
LPCWSTR pszShellFoldersKey;
LPCWSTR pszUserShellFoldersKey;
} PROFILEPARAMS, *PPROFILEPARAMS;
static PROFILEPARAMS
StandardProfiles[] =
{
{
L"Default User", L"DefaultUserProfile",
L"USERPROFILE", L"%USERPROFILE%",
UserShellFolders,
HKEY_USERS,
L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"
},
{
L"All Users", L"AllUsersProfile",
L"ALLUSERSPROFILE", L"%ALLUSERSPROFILE%",
CommonShellFolders,
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"
},
};
static
BOOL
CreateStandardProfile(IN LPCWSTR pszProfilesPath,
IN HKEY hProfileListKey,
IN PPROFILEPARAMS pProfileParams)
{
LONG Error;
PFOLDERDATA lpFolderData;
HKEY hKey;
DWORD dwLength;
WCHAR szProfilePath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
/*
* Create the standard profile main directory
*/
StringCbCopyW(szBuffer, sizeof(szBuffer), pProfileParams->pszProfileName);
/* Build the profile directory path */
StringCbCopyW(szProfilePath, sizeof(szProfilePath), pszProfilesPath);
StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
/* Attempt profile directory creation */
// FIXME: Security!
if (!CreateDirectoryW(szProfilePath, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
/* Directory existed, let's try to append the postfix */
if (!AppendSystemPostfix(szBuffer, ARRAYSIZE(szBuffer)))
{
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
return FALSE;
}
/* Attempt again creation with appended postfix */
StringCbCopyW(szProfilePath, sizeof(szProfilePath), pszProfilesPath);
StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
// FIXME: Security!
if (!CreateDirectoryW(szProfilePath, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
}
}
/* Set 'DefaultUserProfile' / 'AllUsersProfile' value */
/* Store the default user / all users profile path in the registry */
dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
Error = RegSetValueExW(hProfileListKey,
pProfileParams->pszProfileRegValue,
0,
REG_SZ,
(LPBYTE)szBuffer,
dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
/* Set 'Default User' / 'All Users' profile */
SetEnvironmentVariableW(pProfileParams->pszEnvVar, szProfilePath);
/*
* Create the standard profile sub-directories and associated registry keys
*/
/* Create 'Default User' / 'All Users' subdirectories */
/* FIXME: Take these paths from the registry */
lpFolderData = pProfileParams->pFolderList;
while (lpFolderData->lpValueName != NULL)
{
StringCbCopyW(szBuffer, sizeof(szBuffer), szProfilePath);
StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
/* Append the folder name */
dwLength = wcslen(szBuffer);
if (!LoadStringW(hInstance,
lpFolderData->uId,
&szBuffer[dwLength],
ARRAYSIZE(szBuffer) - dwLength))
{
/* Use the default name instead */
StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
}
// FIXME: Security!
if (!CreateDirectoryW(szBuffer, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
}
if (lpFolderData->bHidden)
SetFileAttributesW(szBuffer, FILE_ATTRIBUTE_HIDDEN);
lpFolderData++;
}
/* Set 'Shell Folders' values */
Error = RegOpenKeyExW(pProfileParams->hRootKey,
pProfileParams->pszShellFoldersKey,
0,
KEY_SET_VALUE,
&hKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
/*
* NOTE: This is identical to UpdateUsersShellFolderSettings().
*/
lpFolderData = pProfileParams->pFolderList;
while (lpFolderData->lpValueName != NULL)
{
if (lpFolderData->bShellFolder)
{
StringCbCopyW(szBuffer, sizeof(szBuffer), szProfilePath);
StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
/* Append the folder name */
dwLength = wcslen(szBuffer);
if (!LoadStringW(hInstance,
lpFolderData->uId,
&szBuffer[dwLength],
ARRAYSIZE(szBuffer) - dwLength))
{
/* Use the default name instead */
StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
}
dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
Error = RegSetValueExW(hKey,
lpFolderData->lpValueName,
0,
REG_SZ,
(LPBYTE)szBuffer,
dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
SetLastError((DWORD)Error);
return FALSE;
}
}
lpFolderData++;
}
RegCloseKey(hKey);
/* Set 'User Shell Folders' values */
Error = RegOpenKeyExW(pProfileParams->hRootKey,
pProfileParams->pszUserShellFoldersKey,
0,
KEY_SET_VALUE,
&hKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
lpFolderData = pProfileParams->pFolderList;
while (lpFolderData->lpValueName != NULL)
{
if (lpFolderData->bUserShellFolder)
{
StringCbCopyW(szBuffer, sizeof(szBuffer), pProfileParams->pszEnvVarProfilePath);
StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
/* Append the folder name */
dwLength = wcslen(szBuffer);
if (!LoadStringW(hInstance,
lpFolderData->uId,
&szBuffer[dwLength],
ARRAYSIZE(szBuffer) - dwLength))
{
/* Use the default name instead */
StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
}
dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
Error = RegSetValueExW(hKey,
lpFolderData->lpValueName,
0,
REG_EXPAND_SZ,
(LPBYTE)szBuffer,
dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
SetLastError((DWORD)Error);
return FALSE;
}
}
lpFolderData++;
}
RegCloseKey(hKey);
return TRUE;
}
BOOL
WINAPI
InitializeProfiles(VOID)
{
LONG Error;
HKEY hKey;
DWORD dwLength;
WCHAR szProfilesPath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
DPRINT("InitializeProfiles()\n");
/* Load profiles directory path */
if (!LoadStringW(hInstance,
IDS_PROFILEPATH,
szBuffer,
ARRAYSIZE(szBuffer)))
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
0,
KEY_SET_VALUE,
&hKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
/* Expand it */
if (!ExpandEnvironmentStringsW(szBuffer,
szProfilesPath,
ARRAYSIZE(szProfilesPath)))
{
DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey(hKey);
return FALSE;
}
/* Create profiles directory */
// FIXME: Security!
if (!CreateDirectoryW(szProfilesPath, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
DPRINT1("Error: %lu\n", GetLastError());
RegCloseKey(hKey);
return FALSE;
}
}
/* Store the profiles directory path (unexpanded) in the registry */
dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
Error = RegSetValueExW(hKey,
L"ProfilesDirectory",
0,
REG_EXPAND_SZ,
(LPBYTE)szBuffer,
dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hKey);
SetLastError((DWORD)Error);
return FALSE;
}
/* Create 'Default User' profile directory path */
if (!CreateStandardProfile(szProfilesPath, hKey, &StandardProfiles[0]))
{
DPRINT1("CreateStandardProfile(L\"%S\") failed.\n", StandardProfiles[0].pszProfileName);
RegCloseKey(hKey);
return FALSE;
}
/* Create 'All Users' profile directory path */
if (!CreateStandardProfile(szProfilesPath, hKey, &StandardProfiles[1]))
{
DPRINT1("CreateStandardProfile(L\"%S\") failed.\n", StandardProfiles[1].pszProfileName);
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
DPRINT("Success\n");
return TRUE;
}
/*
* NOTE: See CreateStandardProfile() too.
* Used by registry.c!CreateUserHive()
*/
BOOL
UpdateUsersShellFolderSettings(LPCWSTR lpUserProfilePath,
HKEY hUserKey)
{
WCHAR szBuffer[MAX_PATH];
DWORD dwLength;
PFOLDERDATA lpFolderData;
HKEY hFoldersKey;
LONG Error;
DPRINT("UpdateUsersShellFolderSettings() called\n");
DPRINT("User profile path: %S\n", lpUserProfilePath);
Error = RegOpenKeyExW(hUserKey,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
0,
KEY_SET_VALUE,
&hFoldersKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
lpFolderData = &UserShellFolders[0];
while (lpFolderData->lpValueName != NULL)
{
if (lpFolderData->bShellFolder)
{
StringCbCopyW(szBuffer, sizeof(szBuffer), lpUserProfilePath);
StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
/* Append the folder name */
dwLength = wcslen(szBuffer);
if (!LoadStringW(hInstance,
lpFolderData->uId,
&szBuffer[dwLength],
ARRAYSIZE(szBuffer) - dwLength))
{
/* Use the default name instead */
StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
}
DPRINT("%S: %S\n", lpFolderData->lpValueName, szBuffer);
dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
Error = RegSetValueExW(hFoldersKey,
lpFolderData->lpValueName,
0,
REG_SZ,
(LPBYTE)szBuffer,
dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey(hFoldersKey);
SetLastError((DWORD)Error);
return FALSE;
}
}
lpFolderData++;
}
RegCloseKey(hFoldersKey);
DPRINT("UpdateUsersShellFolderSettings() done\n");
return TRUE;
}
/* EOF */