//************************************************************* // // User Profile migration routines // // Microsoft Confidential // Copyright (c) Microsoft Corporation 1998 // All rights reserved // //************************************************************* #include "uenv.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) { 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'); lstrcpy(szLocalSettings, 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, MAX_FOLDER_SIZE); 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; // // 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. // lstrcpy (szTemp, szUserProfile); if ( LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2)) ) { lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile); ExpandEnvironmentStrings (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)); lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp3, ARRAYSIZE(szTemp) - dwUserProfile); ExpandEnvironmentStrings (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)); lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile); if (lstrcmpi(szTemp, szTemp3) == 0) { LoadString (g_hDllInstance, IDS_SH_PERSONAL, szTemp3, ARRAYSIZE(szTemp3)); lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp3, ARRAYSIZE(szTemp) - dwUserProfile); 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) { lpEnd = CheckSlash (szTemp); lstrcpyn (lpEnd, TEXT("ntuser.dat"), (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd)); } else { goto Exit; } SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN); lstrcpyn (lpEnd, TEXT("ntuser.dat.log"), (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd)); SetFileAttributes (szTemp, FILE_ATTRIBUTE_HIDDEN); DetermineLocalSettingsLocation(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)); lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE (szTemp) - dwUserProfile); } ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)); if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) { LoadString (g_hDllInstance, IDS_SH_CACHE, szTemp3, ARRAYSIZE(szTemp3)); lstrcpy (szTemp, szUserProfile); // // append the newly found localsettings // lstrcpyn (szTemp + dwUserProfile, szLocalSettings, ARRAYSIZE(szTemp) - dwUserProfile); if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) { lpEnd = CheckSlash(szTemp); lstrcpyn (lpEnd, szTemp3, (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd)); } else { goto Exit; } ExpandEnvironmentStrings (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)); lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE (szTemp) - dwUserProfile); } ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)); if (GetFileAttributesEx (szTemp2, GetFileExInfoStandard, &fad)) { LoadString (g_hDllInstance, IDS_SH_HISTORY, szTemp3, ARRAYSIZE(szTemp3)); lstrcpy (szTemp, szUserProfile); // // append the newly found localsettings // lstrcpyn (szTemp + dwUserProfile, szLocalSettings, ARRAYSIZE(szTemp) - dwUserProfile); if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) { lpEnd = CheckSlash(szTemp); } else { goto Exit; } lstrcpyn (lpEnd, szTemp3, (int)(ARRAYSIZE (szTemp) + szTemp - lpEnd)); ExpandEnvironmentStrings (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 // lstrcpy (szTemp, szUserProfile); if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) { lpEnd = CheckSlash (szTemp); } else { goto Exit; } if (RegCreateKeyEx (hKeyRoot, USER_SHELL_FOLDERS, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisp) == ERROR_SUCCESS) { lstrcpyn(lpEnd, szLocalSettings, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd)); 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) { lpEnd = CheckSlash (szTemp); } else { goto Exit; } // // Create the new special folders // for (i=0; i < g_dwNumShellFolders; i++) { if (c_ShellFolders[i].bNewNT5) { lstrcpyn (lpEnd, c_ShellFolders[i].szFolderLocation, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd)); 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 // lstrcpy (szTemp, szUserProfile); if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) { lpEnd = CheckSlash (szTemp); } 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) { lstrcpyn (lpEnd, c_ShellFolders[i].szFolderLocation, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd)); 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 (lstrcmpi (szTemp2, TEXT("%SystemDrive%\\TEMP")) != 0) { bSetTemp = FALSE; } if (lstrcmpi (szTemp2, TEXT("%USERPROFILE%\\TEMP")) == 0) { bSetTemp = TRUE; bCleanUpTemp = TRUE; } } if (bSetTemp) { LoadString (g_hDllInstance, IDS_SH_TEMP, szTemp2, ARRAYSIZE(szTemp2)); lstrcpyn(lpEnd, szLocalSettings, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd)); if(lstrlen(szTemp) < ARRAYSIZE(szTemp) - 1) { lpEnd = CheckSlash(lpEnd); lstrcpyn (lpEnd, szTemp2, (int)(ARRAYSIZE(szTemp) + szTemp - lpEnd)); } 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) { ExpandEnvironmentStrings (szTemp, szTemp2, ARRAYSIZE(szTemp2)); ExpandEnvironmentStrings (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))) && (ExpandEnvironmentStrings (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.. // lstrcpy (szTemp, szUserProfile); lstrcpyn (szTemp + dwUserProfile, szTemp2, ARRAYSIZE(szTemp) - dwUserProfile); ExpandEnvironmentStrings (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) lstrcpyn(szTemp3 + lstrlen(szTemp3), TEXT(";"), ARRAYSIZE(szTemp3) - lstrlen(szTemp3)); if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE, lpBgn, StringLen, szTemp2, lstrlen(szTemp2)) != CSTR_EQUAL) { int sz = MIN((int)(ARRAYSIZE(szTemp3) - lstrlen(szTemp3)), (StringLen+1)); lstrcpyn(szTemp3+lstrlen(szTemp3), lpBgn, sz); } else { lstrcpyn(szTemp3 + lstrlen(szTemp3), szLocalSettings, ARRAYSIZE(szTemp3) - lstrlen(szTemp3)); } // // 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) { ExpandEnvironmentStrings (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; // // Set the User Shell Folder paths in the registry // lstrcpy (szDirectory, TEXT("%USERPROFILE%")); lpEnd = CheckSlash (szDirectory); 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) { lstrcpy (lpEnd, 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 // lstrcpy (szDirectory, lpDirectory); lstrcat (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)); lstrcpy(szSubKey1, szSubKey); szSubKey1[dwMsHistLen] = TEXT('\0'); // // if the key name starts with MSHist // if (lstrcmpi(szSubKey1, IE_CACHEKEY_PREFIX) == 0) { 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 // lstrcpy(szCachePath1, szHistNew); lstrcpy(szSubKey1, szCachePath); szSubKey1[lstrlen(szHistOld)] = TEXT('\0'); if (lstrcmpi(szSubKey1, szHistOld) == 0) { lstrcat(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; }