You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1004 lines
33 KiB
1004 lines
33 KiB
//*************************************************************
|
|
//
|
|
// User Profile migration routines
|
|
//
|
|
// Microsoft Confidential
|
|
// Copyright (c) Microsoft Corporation 1998
|
|
// All rights reserved
|
|
//
|
|
//*************************************************************
|
|
|
|
#include "uenv.h"
|
|
#include "strsafe.h"
|
|
|
|
UINT CountItems (LPTSTR lpDirectory);
|
|
|
|
BOOL SearchAndReplaceIEHistory(LPTSTR szIEHistKeyRoot, LPTSTR szHistOld, LPTSTR szHistNew);
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// DetermineLocalSettingsLocation()
|
|
//
|
|
// Purpose: Determines where to put the local settings
|
|
//
|
|
// Parameters: none
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Look at all the shell folders and see which of them are expected to go to
|
|
// local settings on nt5. Some of them might already be moved to random
|
|
// locations based on the localisations. We should figure out where it is
|
|
// pointing to by looking at these locations and make a call
|
|
//*************************************************************
|
|
|
|
|
|
BOOL DetermineLocalSettingsLocation(LPTSTR szLocalSettings, DWORD cchLocalSettings)
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
LPTSTR lpEnd, lpBgn;
|
|
HKEY hKey, hKeyRoot;
|
|
DWORD dwDisp, dwSize, dwType, i;
|
|
|
|
if (RegOpenCurrentUser(KEY_READ | KEY_WRITE, &hKeyRoot) == ERROR_SUCCESS) {
|
|
|
|
if (RegOpenKeyEx(hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
|
|
|
|
|
for (i=0; i < g_dwNumShellFolders; i++) {
|
|
if (c_ShellFolders[i].bNewNT5 && c_ShellFolders[i].bLocalSettings) {
|
|
|
|
dwSize = sizeof(szPath);
|
|
|
|
if (RegQueryValueEx(hKey, c_ShellFolders[i].lpFolderName,
|
|
0, &dwType, (LPBYTE)szPath, &dwSize) == ERROR_SUCCESS) {
|
|
|
|
if (lstrlen(szPath) > lstrlen(TEXT("%userprofile%"))) {
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: Considering shell folder %s"), szPath));
|
|
|
|
//
|
|
// Move the pointer upto the next slash
|
|
//
|
|
|
|
lpBgn = szPath + lstrlen(TEXT("%userprofile%"))+1;
|
|
lpEnd = lpBgn;
|
|
|
|
for (;(*lpEnd != TEXT('\0'));lpEnd++) {
|
|
|
|
//
|
|
// we have found a shellfolder of the form %userprofile%\subdir\xxx
|
|
// assume this subdir as the localsettings path
|
|
//
|
|
|
|
if (( (*lpEnd) == TEXT('\\') ) && ( (*(lpEnd+1)) != TEXT('\0')) )
|
|
break;
|
|
}
|
|
|
|
|
|
if ((*lpEnd == TEXT('\\')) && (*(lpEnd+1) != TEXT('\0'))) {
|
|
*lpEnd = TEXT('\0');
|
|
StringCchCopy(szLocalSettings, cchLocalSettings, lpBgn);
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: Assuming %s to be the local settings directory"), lpBgn));
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hKeyRoot);
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
RegCloseKey(hKeyRoot);
|
|
}
|
|
|
|
//
|
|
// otherwise load it from the rc file
|
|
//
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_LOCALSETTINGS, szLocalSettings, MIN(MAX_FOLDER_SIZE , cchLocalSettings));
|
|
DebugMsg((DM_VERBOSE, TEXT("DetermineLocalSettingsLocation: No Local Settings was found, using %s"), szLocalSettings));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// MigrateNT4ToNT5()
|
|
//
|
|
// Purpose: Migrates a user profile from NT4 to NT5
|
|
//
|
|
// Parameters: none
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL WINAPI MigrateNT4ToNT5 (void)
|
|
{
|
|
TCHAR szTemp[MAX_PATH];
|
|
TCHAR szTemp2[MAX_PATH];
|
|
TCHAR szTemp3[MAX_PATH];
|
|
TCHAR szLocalSettings[MAX_PATH];
|
|
LPTSTR lpEnd, lpEnd1, lpBgn=NULL;
|
|
HKEY hKey = NULL, hKeyRoot = NULL;
|
|
DWORD dwDisp, dwSize, dwType, i;
|
|
BOOL bSetTemp = TRUE;
|
|
BOOL bCleanUpTemp = FALSE;
|
|
WIN32_FILE_ATTRIBUTE_DATA fad;
|
|
const LPTSTR szUserProfile = TEXT("%USERPROFILE%\\");
|
|
DWORD dwUserProfile = lstrlen(szUserProfile);
|
|
DWORD dwString = 0;
|
|
int StringLen;
|
|
DWORD cchEnd;
|
|
|
|
//
|
|
// Get the root registry key handle
|
|
//
|
|
|
|
if (RegOpenCurrentUser(KEY_READ | KEY_WRITE, &hKeyRoot) != ERROR_SUCCESS) {
|
|
DebugMsg((DM_WARNING, TEXT("MigrateNT4ToNT5: Failed to get root registry key with %d"),
|
|
GetLastError()));
|
|
}
|
|
|
|
|
|
//
|
|
// Convert Personal to My Documents
|
|
//
|
|
// We have to be careful with this directory. We'll rename
|
|
// Personal to My Documents only if the Personal directory
|
|
// is empty. After this, we'll fix up the registry special folder
|
|
// location only if it is still pointing at the default Personal location.
|
|
//
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
|
|
if ( LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2)) )
|
|
{
|
|
//lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile);
|
|
StringCchCat(szTemp, ARRAYSIZE(szTemp), szTemp2);
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2))))
|
|
{
|
|
|
|
//
|
|
// Check if the personal directory exists
|
|
//
|
|
|
|
if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
|
|
|
|
//
|
|
// Check if the personal directory is empty
|
|
//
|
|
|
|
if (!CountItems (szTemp2)) {
|
|
|
|
//
|
|
// The directory is empty, so rename it to My Documents
|
|
//
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_PERSONAL, szTemp3, ARRAYSIZE(szTemp3));
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp3);
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3))))
|
|
{
|
|
|
|
if (MoveFileEx(szTemp2, szTemp3, 0)) {
|
|
|
|
//
|
|
// Now we need to fix up the registry value if it is still set
|
|
// to the default of %USERPROFILE%\Personal
|
|
//
|
|
|
|
if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS) {
|
|
|
|
dwSize = sizeof(szTemp3);
|
|
szTemp3[0] = TEXT('\0');
|
|
if (RegQueryValueEx (hKey, TEXT("Personal"), NULL, &dwType,
|
|
(LPBYTE) szTemp3, &dwSize) == ERROR_SUCCESS) {
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2));
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp2);
|
|
|
|
if (lstrcmpi(szTemp, szTemp3) == 0) {
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_PERSONAL, szTemp3, ARRAYSIZE(szTemp3));
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp3);
|
|
|
|
RegSetValueEx (hKey, TEXT("Personal"), 0, REG_EXPAND_SZ,
|
|
(LPBYTE) szTemp, (lstrlen(szTemp) + 1) * sizeof(TCHAR));
|
|
|
|
|
|
//
|
|
// We need to reinitialize the global variables now because
|
|
// the path to the My Documents and My Pictures folder has changed.
|
|
//
|
|
|
|
InitializeGlobals(g_hDllInstance);
|
|
}
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Get the user profile directory
|
|
//
|
|
|
|
dwString = GetEnvironmentVariable (TEXT("USERPROFILE"), szTemp, ARRAYSIZE (szTemp));
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Upgrading <%s> from NT4 to NT5"),
|
|
szTemp));
|
|
|
|
|
|
//
|
|
// Hide ntuser.dat and ntuser.dat.log
|
|
//
|
|
|
|
if(dwString < ARRAYSIZE(szTemp) - 1 && dwString > 0) {
|
|
lpEnd = CheckSlashEx (szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
StringCchCopy (lpEnd, cchEnd, TEXT("ntuser.dat"));
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN);
|
|
|
|
StringCchCopy (lpEnd, cchEnd, TEXT("ntuser.dat.log"));
|
|
SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN);
|
|
|
|
|
|
DetermineLocalSettingsLocation(szLocalSettings, ARRAYSIZE(szLocalSettings));
|
|
|
|
|
|
//
|
|
// Check if Temporary Internet Files exists in the root of the
|
|
// user's profile. If so, move it to the new location
|
|
//
|
|
// migrate these stuff before we nuke the old User_shell_folders
|
|
//
|
|
|
|
if (RegOpenKeyEx(hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
|
|
|
dwSize = sizeof(szTemp);
|
|
|
|
if (RegQueryValueEx(hKey, TEXT("Cache"), 0, &dwType, (LPBYTE)szTemp, &dwSize) != ERROR_SUCCESS) {
|
|
|
|
//
|
|
// if this value is not there go by the default location from the
|
|
// resources
|
|
//
|
|
|
|
LoadString (g_hDllInstance, IDS_TEMPINTERNETFILES, szTemp2, ARRAYSIZE(szTemp2));
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp2);
|
|
}
|
|
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)))) {
|
|
|
|
if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_CACHE, szTemp3, ARRAYSIZE(szTemp3));
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
|
|
//
|
|
// append the newly found localsettings
|
|
//
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szLocalSettings);
|
|
|
|
if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
|
|
lpEnd = CheckSlashEx(szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
StringCchCopy (lpEnd, cchEnd, szTemp3);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3)))) {
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: New temp int files folder (expand path) %s"), szTemp3));
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Old temp int files folder (expand path) %s"), szTemp2));
|
|
|
|
if (lstrcmpi(szTemp2, szTemp3) != 0) {
|
|
if (CopyProfileDirectory (szTemp2, szTemp3, CPD_IGNOREHIVE)) {
|
|
Delnode (szTemp2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if History exists in the root of the user's profile.
|
|
// If so, move it to the new location
|
|
//
|
|
|
|
dwSize = sizeof(szTemp);
|
|
|
|
if (RegQueryValueEx(hKey, TEXT("History"), 0, &dwType, (LPBYTE)szTemp, &dwSize) != ERROR_SUCCESS) {
|
|
|
|
//
|
|
// if this value is not there go by the default location from the
|
|
// resources
|
|
//
|
|
|
|
LoadString (g_hDllInstance, IDS_HISTORY, szTemp2, ARRAYSIZE(szTemp2));
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp2);
|
|
}
|
|
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)))) {
|
|
|
|
if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) {
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_HISTORY, szTemp3, ARRAYSIZE(szTemp3));
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
|
|
//
|
|
// append the newly found localsettings
|
|
//
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szLocalSettings);
|
|
if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
|
|
lpEnd = CheckSlashEx(szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
|
|
StringCchCopy (lpEnd, cchEnd, szTemp3);
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp3, ARRAYSIZE(szTemp3)))) {
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: New histroy folder (expand path) %s"), szTemp3));
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Old histroy folder (expand path) %s"), szTemp2));
|
|
|
|
if (lstrcmpi(szTemp2, szTemp3) != 0) {
|
|
if (CopyProfileDirectory (szTemp2, szTemp3, CPD_IGNOREHIVE)) {
|
|
Delnode (szTemp2);
|
|
SearchAndReplaceIEHistory(IE4_CACHE_KEY, szTemp2, szTemp3);
|
|
SearchAndReplaceIEHistory(IE5_CACHE_KEY, szTemp2, szTemp3);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// Update the local settings key with the new value
|
|
//
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
|
|
lpEnd = CheckSlashEx(szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
|
|
if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &hKey,
|
|
&dwDisp) == ERROR_SUCCESS) {
|
|
|
|
StringCchCopy(lpEnd, cchEnd, szLocalSettings);
|
|
|
|
RegSetValueEx (hKey, TEXT("Local Settings"),
|
|
0, REG_EXPAND_SZ, (LPBYTE) szTemp,
|
|
((lstrlen(szTemp) + 1) * sizeof(TCHAR)));
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Update the local settings folder with %s"), szTemp));
|
|
|
|
|
|
//
|
|
// Globals needs to reinitialised because LocalSettings might be different from
|
|
// the one specified in the rc file
|
|
//
|
|
|
|
InitializeGlobals(g_hDllInstance);
|
|
|
|
|
|
//
|
|
// Get the user profile directory
|
|
//
|
|
|
|
dwString = GetEnvironmentVariable (TEXT("USERPROFILE"), szTemp, ARRAYSIZE (szTemp));
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Upgrading <%s> from NT4 to NT5"),
|
|
szTemp));
|
|
|
|
if(dwString < ARRAYSIZE(szTemp) - 1 && dwString > 0) {
|
|
lpEnd = CheckSlashEx (szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Create the new special folders
|
|
//
|
|
|
|
for (i=0; i < g_dwNumShellFolders; i++) {
|
|
|
|
if (c_ShellFolders[i].bNewNT5) {
|
|
|
|
StringCchCopy (lpEnd, cchEnd, c_ShellFolders[i].szFolderLocation);
|
|
|
|
if (!CreateNestedDirectory(szTemp, NULL)) {
|
|
DebugMsg((DM_WARNING, TEXT("MigrateNT4ToNT5: Failed to create the destination directory <%s>. Error = %d"),
|
|
szTemp, GetLastError()));
|
|
}
|
|
|
|
if (c_ShellFolders[i].bHidden) {
|
|
SetFileAttributes(szTemp, FILE_ATTRIBUTE_HIDDEN);
|
|
} else {
|
|
SetFileAttributes(szTemp, FILE_ATTRIBUTE_NORMAL);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Set the new special folders in the User Shell Folder registry key
|
|
//
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
|
|
lpEnd = CheckSlashEx (szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
|
|
if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &hKey,
|
|
&dwDisp) == ERROR_SUCCESS) {
|
|
|
|
for (i=0; i < g_dwNumShellFolders; i++) {
|
|
|
|
if (c_ShellFolders[i].bNewNT5 && c_ShellFolders[i].bAddCSIDL) {
|
|
StringCchCopy (lpEnd, cchEnd, c_ShellFolders[i].szFolderLocation);
|
|
|
|
RegSetValueEx (hKey, c_ShellFolders[i].lpFolderName,
|
|
0, REG_EXPAND_SZ, (LPBYTE) szTemp,
|
|
((lstrlen(szTemp) + 1) * sizeof(TCHAR)));
|
|
}
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Query the user's environment for a TEMP environment variable.
|
|
//
|
|
|
|
if (RegCreateKeyEx (hKeyRoot, TEXT("Environment"), 0,
|
|
NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &hKey,
|
|
&dwDisp) == ERROR_SUCCESS) {
|
|
|
|
|
|
szTemp2[0] = TEXT('\0');
|
|
dwSize = sizeof(szTemp2);
|
|
RegQueryValueEx (hKey, TEXT("TEMP"), NULL, &dwType,
|
|
(LPBYTE) szTemp2, &dwSize);
|
|
|
|
|
|
//
|
|
// Decide if we should set the temp and tmp environment variables.
|
|
// We need to be careful to not blast someone's custom temp variable
|
|
// if it already exists, but at the same time it's ok to remap this if
|
|
// temp is still set to the NT4 default of %SystemDrive%\TEMP.
|
|
//
|
|
|
|
if (szTemp2[0] != TEXT('\0')) {
|
|
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, szTemp2, -1, TEXT("%SystemDrive%\\TEMP"), -1) != CSTR_EQUAL) {
|
|
bSetTemp = FALSE;
|
|
}
|
|
|
|
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, szTemp2, -1, TEXT("%USERPROFILE%\\TEMP"), -1) == CSTR_EQUAL) {
|
|
bSetTemp = TRUE;
|
|
bCleanUpTemp = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if (bSetTemp) {
|
|
LoadString (g_hDllInstance, IDS_SH_TEMP, szTemp2, ARRAYSIZE(szTemp2));
|
|
StringCchCopy(lpEnd, cchEnd, szLocalSettings);
|
|
if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) {
|
|
lpEnd = CheckSlashEx(szTemp, ARRAYSIZE(szTemp), &cchEnd);
|
|
StringCchCopy (lpEnd, cchEnd, szTemp2);
|
|
}
|
|
else {
|
|
goto Exit;
|
|
}
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Setting the Temp directory to <%s>"), szTemp));
|
|
|
|
|
|
RegSetValueEx (hKey, TEXT("TEMP"), 0, REG_EXPAND_SZ,
|
|
(LPBYTE) szTemp, (lstrlen (szTemp) + 1) * sizeof(TCHAR));
|
|
|
|
RegSetValueEx (hKey, TEXT("TMP"), 0, REG_EXPAND_SZ,
|
|
(LPBYTE) szTemp, (lstrlen (szTemp) + 1) * sizeof(TCHAR));
|
|
}
|
|
|
|
if (bCleanUpTemp) {
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2))) &&
|
|
SUCCEEDED(SafeExpandEnvironmentStrings (TEXT("%USERPROFILE%\\TEMP"), szTemp, ARRAYSIZE(szTemp)))) {
|
|
|
|
if (CopyProfileDirectory (szTemp, szTemp2, CPD_IGNOREHIVE)) {
|
|
Delnode (szTemp);
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// Migrate the Template Directory if it exists. Copy it from %systemroot%\shellnew
|
|
// to Templates directory userprofile..
|
|
//
|
|
|
|
if ((LoadString (g_hDllInstance, IDS_SH_TEMPLATES2, szTemp2, ARRAYSIZE(szTemp2))) &&
|
|
(SUCCEEDED(SafeExpandEnvironmentStrings (szTemp2, szTemp3, ARRAYSIZE(szTemp3)))) &&
|
|
(LoadString (g_hDllInstance, IDS_SH_TEMPLATES, szTemp2, ARRAYSIZE(szTemp2)))) {
|
|
|
|
//
|
|
// if all of the above succeeded
|
|
// szTemp3 will have the full path for the old templates dir..
|
|
//
|
|
|
|
StringCchCopy (szTemp, ARRAYSIZE(szTemp), szUserProfile);
|
|
StringCchCat (szTemp, ARRAYSIZE(szTemp), szTemp2);
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)))) {
|
|
|
|
if (GetFileAttributesEx (szTemp3, GetFileExInfoStandard, &fad)) {
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Copying Template files from %s to %s"), szTemp3, szTemp2));
|
|
CopyProfileDirectory(szTemp3, szTemp2, CPD_IGNORECOPYERRORS | CPD_IGNOREHIVE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Set the user preference exclusion list. This will
|
|
// prevent the Local Settings folder from roaming
|
|
//
|
|
|
|
if (LoadString (g_hDllInstance, IDS_EXCLUSIONLIST,
|
|
szTemp, ARRAYSIZE(szTemp))) {
|
|
|
|
if (RegCreateKeyEx (hKeyRoot, WINLOGON_KEY,
|
|
0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &hKey,
|
|
&dwDisp) == ERROR_SUCCESS) {
|
|
|
|
|
|
dwSize = sizeof(szTemp);
|
|
|
|
RegQueryValueEx (hKey, TEXT("ExcludeProfileDirs"),
|
|
NULL, &dwType, (LPBYTE) szTemp,
|
|
&dwSize);
|
|
|
|
//
|
|
// Read in the value of the local settings
|
|
//
|
|
|
|
LoadString (g_hDllInstance, IDS_SH_LOCALSETTINGS,
|
|
szTemp2, ARRAYSIZE(szTemp2));
|
|
|
|
|
|
//
|
|
// Loop through the list
|
|
//
|
|
|
|
lpBgn = lpEnd = szTemp;
|
|
*szTemp3 = TEXT('\0');
|
|
|
|
while (*lpEnd) {
|
|
|
|
//
|
|
// Look for the semicolon separator
|
|
//
|
|
|
|
while (*lpEnd && ((*lpEnd) != TEXT(';'))) {
|
|
lpEnd++;
|
|
}
|
|
|
|
|
|
//
|
|
// Remove any leading spaces
|
|
//
|
|
|
|
while (*lpBgn == TEXT(' ')) {
|
|
lpBgn++;
|
|
}
|
|
|
|
|
|
//
|
|
// if it has come here we are going to attach something
|
|
// to the end of szTmp3
|
|
//
|
|
|
|
StringLen = (int)(lpEnd - lpBgn);
|
|
|
|
if (*szTemp3)
|
|
StringCchCat(szTemp3, ARRAYSIZE(szTemp3), TEXT(";"));
|
|
|
|
if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE,
|
|
lpBgn, StringLen, szTemp2, lstrlen(szTemp2)) != CSTR_EQUAL) {
|
|
|
|
StringCchCatN (szTemp3, ARRAYSIZE(szTemp3), lpBgn, StringLen);
|
|
}
|
|
else {
|
|
StringCchCat (szTemp3, ARRAYSIZE(szTemp3), szLocalSettings);
|
|
}
|
|
|
|
|
|
//
|
|
// If we are at the end of the exclusion list, we're done
|
|
//
|
|
|
|
if (!(*lpEnd)) {
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Prep for the next entry
|
|
//
|
|
|
|
lpEnd++;
|
|
lpBgn = lpEnd;
|
|
}
|
|
|
|
|
|
RegSetValueEx (hKey, TEXT("ExcludeProfileDirs"),
|
|
0, REG_SZ, (LPBYTE) szTemp3,
|
|
((lstrlen(szTemp3) + 1) * sizeof(TCHAR)));
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Set the exclusionlist value to default")));
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure the hidden bit is set correctly for each special folder
|
|
//
|
|
|
|
if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
|
|
|
for (i=0; i < g_dwNumShellFolders; i++) {
|
|
|
|
dwSize = sizeof(szTemp);
|
|
szTemp[0] = TEXT('\0');
|
|
|
|
if (RegQueryValueEx (hKey, c_ShellFolders[i].lpFolderName,
|
|
NULL, &dwType, (LPBYTE) szTemp,
|
|
&dwSize) == ERROR_SUCCESS) {
|
|
|
|
if (SUCCEEDED(SafeExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2))))
|
|
{
|
|
if (c_ShellFolders[i].bHidden) {
|
|
SetFileAttributes(szTemp2, FILE_ATTRIBUTE_HIDDEN);
|
|
} else {
|
|
SetFileAttributes(szTemp2, FILE_ATTRIBUTE_NORMAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
|
|
if(hKey != NULL) {
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
|
|
if (hKeyRoot != NULL) {
|
|
RegCloseKey (hKeyRoot);
|
|
}
|
|
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("MigrateNT4ToNT5: Finished.")));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// ResetUserSpecialFolderPaths()
|
|
//
|
|
// Purpose: Sets all of the user special folder paths back
|
|
// to their defaults
|
|
//
|
|
// Parameters: none
|
|
//
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL WINAPI ResetUserSpecialFolderPaths(void)
|
|
{
|
|
TCHAR szDirectory [MAX_PATH];
|
|
HKEY hKey, hKeyRoot;
|
|
DWORD dwDisp, i;
|
|
LPTSTR lpEnd;
|
|
DWORD cchEnd;
|
|
|
|
|
|
//
|
|
// Set the User Shell Folder paths in the registry
|
|
//
|
|
|
|
StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), TEXT("%USERPROFILE%"));
|
|
lpEnd = CheckSlashEx (szDirectory, ARRAYSIZE(szDirectory), &cchEnd );
|
|
|
|
if (RegOpenCurrentUser(KEY_WRITE, &hKeyRoot) == ERROR_SUCCESS) {
|
|
|
|
if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
|
|
0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE, NULL, &hKey,
|
|
&dwDisp) == ERROR_SUCCESS) {
|
|
|
|
for (i=0; i < g_dwNumShellFolders; i++) {
|
|
|
|
if (c_ShellFolders[i].bAddCSIDL) {
|
|
StringCchCopy (lpEnd, cchEnd, c_ShellFolders[i].szFolderLocation);
|
|
|
|
RegSetValueEx (hKey, c_ShellFolders[i].lpFolderName,
|
|
0, REG_EXPAND_SZ, (LPBYTE) szDirectory,
|
|
((lstrlen(szDirectory) + 1) * sizeof(TCHAR)));
|
|
}
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
}
|
|
RegCloseKey (hKeyRoot);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CountItems()
|
|
//
|
|
// Purpose: Counts the number of files and subdirectories
|
|
// in the given subdirectory
|
|
//
|
|
// Parameters: lpDirectory - parent directory
|
|
//
|
|
// Return: Item count
|
|
//
|
|
//*************************************************************
|
|
|
|
UINT CountItems (LPTSTR lpDirectory)
|
|
{
|
|
TCHAR szDirectory[MAX_PATH];
|
|
HANDLE hFile;
|
|
WIN32_FIND_DATA fd;
|
|
UINT uiCount = 0;
|
|
|
|
|
|
//
|
|
// Search through the directory
|
|
//
|
|
|
|
if (SUCCEEDED(StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), lpDirectory)) &&
|
|
SUCCEEDED(StringCchCat (szDirectory, ARRAYSIZE(szDirectory), TEXT("\\*.*"))))
|
|
{
|
|
|
|
hFile = FindFirstFile(szDirectory, &fd);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
return uiCount;
|
|
}
|
|
|
|
|
|
do {
|
|
|
|
//
|
|
// Check for "." and ".."
|
|
//
|
|
|
|
if (!lstrcmpi(fd.cFileName, TEXT("."))) {
|
|
continue;
|
|
}
|
|
|
|
if (!lstrcmpi(fd.cFileName, TEXT(".."))) {
|
|
continue;
|
|
}
|
|
|
|
uiCount++;
|
|
|
|
//
|
|
// Find the next entry
|
|
//
|
|
|
|
} while (FindNextFile(hFile, &fd));
|
|
|
|
|
|
FindClose(hFile);
|
|
}
|
|
|
|
return uiCount;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// SearchAndReplaceIEHistory()
|
|
//
|
|
// Purpose: Searches and Replaces the registry kesy pointing to
|
|
// the old location in IE Cahe to point to New Location
|
|
//
|
|
// Parameters:
|
|
// szIEHistKeyRoot - Root of the history key
|
|
// szHistOld - Old History Key
|
|
// szHistNew - New Location of History Key
|
|
//
|
|
// Return: TRUE if success, else False
|
|
//
|
|
// Created:
|
|
//
|
|
// Notes:
|
|
// Change the "HKCU\S\M\W\CV\Internet Settings\Cache\Extensible Cache\"MSHist***\CachePath" and
|
|
// Change the "HKCU\S\M\W\CV\Internet Settings\5.0\Cache\Extensible Cache\MSHis***\CachePath"
|
|
// value to the new place
|
|
//*************************************************************
|
|
|
|
BOOL SearchAndReplaceIEHistory(LPTSTR szIEHistKeyRoot, LPTSTR szHistOld, LPTSTR szHistNew)
|
|
{
|
|
DWORD dwIndex = 0, dwMsHistLen, dwLen;
|
|
TCHAR szSubKey[MAX_PATH+1], szSubKey1[MAX_PATH+1];
|
|
TCHAR szCachePath[MAX_PATH];
|
|
TCHAR szCachePath1[MAX_PATH];
|
|
FILETIME ftWrite;
|
|
HKEY hIECacheKey, hKey;
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Fixing up the IE Registry keys")));
|
|
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, szIEHistKeyRoot, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
|
|
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Enumerating the keys under %s"), szIEHistKeyRoot));
|
|
|
|
dwMsHistLen = lstrlen(IE_CACHEKEY_PREFIX);
|
|
|
|
dwLen = ARRAYSIZE(szSubKey);
|
|
|
|
while (RegEnumKeyEx(hKey, dwIndex, szSubKey, &dwLen, NULL, NULL, NULL, &ftWrite) == ERROR_SUCCESS) {
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Testing Key %s"), szSubKey));
|
|
|
|
StringCchCopy(szSubKey1, ARRAYSIZE(szSubKey1), szSubKey);
|
|
szSubKey1[dwMsHistLen] = TEXT('\0');
|
|
|
|
//
|
|
// if the key name starts with MSHist
|
|
//
|
|
|
|
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, szSubKey1, -1, IE_CACHEKEY_PREFIX, -1) == CSTR_EQUAL) {
|
|
|
|
if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hIECacheKey) == ERROR_SUCCESS) {
|
|
DWORD dwLen1;
|
|
|
|
//
|
|
// Get the current value
|
|
//
|
|
|
|
|
|
dwLen1 = sizeof(szCachePath);
|
|
if (RegQueryValueEx(hIECacheKey, TEXT("CachePath"), 0, NULL, (LPBYTE)szCachePath, &dwLen1) == ERROR_SUCCESS) {
|
|
|
|
//
|
|
// Replace the szHistOld prefix with szHistNew value
|
|
//
|
|
|
|
StringCchCopy(szCachePath1, ARRAYSIZE(szCachePath1), szHistNew);
|
|
|
|
StringCchCopy(szSubKey1, ARRAYSIZE(szSubKey1), szCachePath);
|
|
szSubKey1[lstrlen(szHistOld)] = TEXT('\0');
|
|
|
|
if (lstrcmpi(szSubKey1, szHistOld) == 0) {
|
|
|
|
|
|
StringCchCat(szCachePath1, ARRAYSIZE(szCachePath1), szCachePath+lstrlen(szHistOld));
|
|
|
|
RegSetValueEx(hIECacheKey, TEXT("CachePath"), 0, REG_SZ, (LPBYTE)szCachePath1, (lstrlen(szCachePath1)+1)*sizeof(TCHAR));
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Finally, under %s Replacing %s with %s"), szSubKey, szCachePath, szCachePath1));
|
|
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Existing CachePath %s doesn't have %s, skipping.."), szCachePath, szHistOld));
|
|
}
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Could not open CachePath value")));
|
|
}
|
|
|
|
RegCloseKey(hIECacheKey);
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Could not open %s subkey"), szSubKey));
|
|
}
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: %s subkey does not have %s prefix"), szSubKey, IE_CACHEKEY_PREFIX));
|
|
}
|
|
|
|
dwIndex++;
|
|
dwLen = ARRAYSIZE(szSubKey);
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Getting %d subkey next.."), dwIndex+1));
|
|
|
|
}
|
|
|
|
//
|
|
// Close if the open succeeded
|
|
//
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("SearchAndReplaceIEHistory: Failed to open the root of the key %s"), szIEHistKeyRoot));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|