зеркало из https://github.com/mozilla/pjs.git
fix for #137886. Detect defunct previously migrated profiles and offer to re-migrate.
this is pref controlled, "profile.seconds_until_defunct. by default, we'll never offer to remigrate. initial patch by ccarlen. r=ccarlen,racham,sr=bienvenu
This commit is contained in:
Родитель
3faab993b1
Коммит
a376f9f56c
|
@ -623,6 +623,15 @@ pref("mousewheel.withaltkey.sysnumlines",false);
|
||||||
|
|
||||||
pref("profile.confirm_automigration",true);
|
pref("profile.confirm_automigration",true);
|
||||||
|
|
||||||
|
// the amount of time (in seconds) that must elapse
|
||||||
|
// before we think your mozilla profile is defunct
|
||||||
|
// and you'd benefit from re-migrating from 4.x
|
||||||
|
// see bug #137886 for more details
|
||||||
|
//
|
||||||
|
// if -1, we never think your profile is defunct
|
||||||
|
// and users will never see the remigrate UI.
|
||||||
|
pref("profile.seconds_until_defunct", -1);
|
||||||
|
|
||||||
// Customizable toolbar stuff
|
// Customizable toolbar stuff
|
||||||
pref("custtoolbar.personal_toolbar_folder", "");
|
pref("custtoolbar.personal_toolbar_folder", "");
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,8 @@ interface nsIProfileInternal : nsIProfile {
|
||||||
|
|
||||||
void migrateProfileInfo();
|
void migrateProfileInfo();
|
||||||
void migrateAllProfiles();
|
void migrateAllProfiles();
|
||||||
void migrateProfile(in wstring profileName, in boolean showProgressAsModalWindow);
|
void migrateProfile(in wstring profileName);
|
||||||
|
void remigrateProfile(in wstring profileName);
|
||||||
void forgetCurrentProfile();
|
void forgetCurrentProfile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,6 +109,12 @@ interface nsIProfileInternal : nsIProfile {
|
||||||
*/
|
*/
|
||||||
nsILocalFile getOriginalProfileDir(in wstring profileName);
|
nsILocalFile getOriginalProfileDir(in wstring profileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date on which a profile was last used.
|
||||||
|
* value is in milliseconds since midnight Jan 1, 1970 GMT (same as nsIFile)
|
||||||
|
*/
|
||||||
|
PRInt64 getProfileLastModTime(in wstring profileName);
|
||||||
|
|
||||||
attribute boolean automigrate;
|
attribute boolean automigrate;
|
||||||
readonly attribute nsIFile defaultProfileParentDir;
|
readonly attribute nsIFile defaultProfileParentDir;
|
||||||
readonly attribute wstring firstProfile;
|
readonly attribute wstring firstProfile;
|
||||||
|
|
|
@ -76,7 +76,7 @@ function RenameProfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profile.migrateProfile( profilename, true );
|
profile.migrateProfile( profilename );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -183,7 +183,7 @@ function onStart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profile.migrateProfile( profilename, true );
|
profile.migrateProfile( profilename );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,3 +9,7 @@ mailDirName=Mail
|
||||||
# newsDirName needs to be set to the same value as in 4.x
|
# newsDirName needs to be set to the same value as in 4.x
|
||||||
# see bug #55449
|
# see bug #55449
|
||||||
newsDirName=News
|
newsDirName=News
|
||||||
|
# see nsAppShellService::CheckAndRemigrateDefunctProfile()
|
||||||
|
# for where the confirmRemigration entries are used
|
||||||
|
# LOCALIZATION NOTE: Do not translate Unicode (\uXXXX) characters.
|
||||||
|
confirmRemigration=A more recent Netscape 4.5+ version of this profile (which contains your bookmarks, email settings, address books and preferences) was found.\u000aWould you like to use the more recent profile?
|
||||||
|
|
|
@ -328,7 +328,6 @@ nsProfile::~nsProfile()
|
||||||
if (--gInstanceCount == 0) {
|
if (--gInstanceCount == 0) {
|
||||||
|
|
||||||
delete gProfileDataAccess;
|
delete gProfileDataAccess;
|
||||||
|
|
||||||
delete gLocaleProfiles;
|
delete gLocaleProfiles;
|
||||||
|
|
||||||
NS_IF_RELEASE(sApp_PrefsDirectory50);
|
NS_IF_RELEASE(sApp_PrefsDirectory50);
|
||||||
|
@ -1058,9 +1057,43 @@ NS_IMETHODIMP nsProfile::GetOriginalProfileDir(const PRUnichar *profileName, nsI
|
||||||
NS_ENSURE_ARG_POINTER(originalDir);
|
NS_ENSURE_ARG_POINTER(originalDir);
|
||||||
*originalDir = nsnull;
|
*originalDir = nsnull;
|
||||||
|
|
||||||
|
Update4xProfileInfo();
|
||||||
return gProfileDataAccess->GetOriginalProfileDir(profileName, originalDir);
|
return gProfileDataAccess->GetOriginalProfileDir(profileName, originalDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsProfile::GetProfileLastModTime(const PRUnichar *profileName, PRInt64 *_retval)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG(profileName);
|
||||||
|
NS_ENSURE_ARG_POINTER(_retval);
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
// First, see if we can get the lastModTime from the registry.
|
||||||
|
// We only started putting it there from mozilla1.0.1
|
||||||
|
// The mod time will be zero if it has not been set.
|
||||||
|
ProfileStruct *profileInfo = nsnull;
|
||||||
|
rv = gProfileDataAccess->GetValue(profileName, &profileInfo);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
PRInt64 lastModTime = profileInfo->lastModTime;
|
||||||
|
delete profileInfo;
|
||||||
|
if (!LL_IS_ZERO(lastModTime)) {
|
||||||
|
*_retval = lastModTime;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we couldn't get a valid mod time from the registry,
|
||||||
|
// check the date of prefs.js. Since August, 2000 it is always
|
||||||
|
// written out on quitting the application.
|
||||||
|
nsCOMPtr<nsIFile> profileDir;
|
||||||
|
rv = GetProfileDir(profileName, getter_AddRefs(profileDir));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
rv = profileDir->Append("prefs.js");
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
return profileDir->GetLastModifiedTime(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsProfile::GetDefaultProfileParentDir(nsIFile **aDefaultProfileParentDir)
|
NS_IMETHODIMP nsProfile::GetDefaultProfileParentDir(nsIFile **aDefaultProfileParentDir)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aDefaultProfileParentDir);
|
NS_ENSURE_ARG_POINTER(aDefaultProfileParentDir);
|
||||||
|
@ -1172,9 +1205,12 @@ nsProfile::SetCurrentProfile(const PRUnichar * aCurrentProfile)
|
||||||
|
|
||||||
// Phase 3: Notify observers of a profile change
|
// Phase 3: Notify observers of a profile change
|
||||||
observerService->NotifyObservers(subject, "profile-before-change", context.get());
|
observerService->NotifyObservers(subject, "profile-before-change", context.get());
|
||||||
|
|
||||||
|
UpdateCurrentProfileModTime(PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the profile switch
|
// Do the profile switch
|
||||||
|
mCurrentProfileName.Assign(aCurrentProfile);
|
||||||
gProfileDataAccess->SetCurrentProfile(aCurrentProfile);
|
gProfileDataAccess->SetCurrentProfile(aCurrentProfile);
|
||||||
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
||||||
gProfileDataAccess->UpdateRegistry(nsnull);
|
gProfileDataAccess->UpdateRegistry(nsnull);
|
||||||
|
@ -1233,6 +1269,9 @@ NS_IMETHODIMP nsProfile::ShutDownCurrentProfile(PRUint32 shutDownType)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
// if shutDownType is not a well know value, skip the notifications
|
||||||
|
// see DoOnShutdown() in nsAppRunner.cpp for where we use this behaviour to our benefit
|
||||||
|
if (shutDownType == SHUTDOWN_PERSIST || shutDownType == SHUTDOWN_CLEANSE) {
|
||||||
nsCOMPtr<nsIObserverService> observerService =
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||||
NS_ENSURE_TRUE(observerService, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(observerService, NS_ERROR_FAILURE);
|
||||||
|
@ -1254,10 +1293,13 @@ NS_IMETHODIMP nsProfile::ShutDownCurrentProfile(PRUint32 shutDownType)
|
||||||
|
|
||||||
// Phase 3: Notify observers of a profile change
|
// Phase 3: Notify observers of a profile change
|
||||||
observerService->NotifyObservers(subject, "profile-before-change", context.get());
|
observerService->NotifyObservers(subject, "profile-before-change", context.get());
|
||||||
|
}
|
||||||
|
|
||||||
rv = UndefineFileLocations();
|
rv = UndefineFileLocations();
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Could not undefine file locations");
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Could not undefine file locations");
|
||||||
|
UpdateCurrentProfileModTime(PR_TRUE);
|
||||||
mCurrentProfileAvailable = PR_FALSE;
|
mCurrentProfileAvailable = PR_FALSE;
|
||||||
|
mCurrentProfileName.Truncate(0);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1440,7 +1482,8 @@ nsresult nsProfile::SetProfileDir(const PRUnichar *profileName, nsIFile *profile
|
||||||
rv = profileDir->Exists(&exists);
|
rv = profileDir->Exists(&exists);
|
||||||
if (NS_SUCCEEDED(rv) && !exists)
|
if (NS_SUCCEEDED(rv) && !exists)
|
||||||
rv = profileDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
rv = profileDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(profileDir));
|
nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(profileDir));
|
||||||
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
|
||||||
|
@ -1448,12 +1491,16 @@ nsresult nsProfile::SetProfileDir(const PRUnichar *profileName, nsIFile *profile
|
||||||
ProfileStruct* aProfile = new ProfileStruct();
|
ProfileStruct* aProfile = new ProfileStruct();
|
||||||
NS_ENSURE_TRUE(aProfile, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(aProfile, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
|
||||||
aProfile->profileName = profileName;
|
aProfile->profileName = profileName;
|
||||||
aProfile->SetResolvedProfileDir(localFile);
|
aProfile->SetResolvedProfileDir(localFile);
|
||||||
aProfile->isMigrated = PR_TRUE;
|
aProfile->isMigrated = PR_TRUE;
|
||||||
aProfile->isImportType = PR_FALSE;
|
aProfile->isImportType = PR_FALSE;
|
||||||
|
|
||||||
|
// convert "now" from microsecs to millisecs
|
||||||
|
PRInt64 oneThousand = LL_INIT(0, 1000);
|
||||||
|
PRInt64 nowInMilliSecs = PR_Now();
|
||||||
|
LL_DIV(aProfile->creationTime, nowInMilliSecs, oneThousand);
|
||||||
|
|
||||||
gProfileDataAccess->SetValue(aProfile);
|
gProfileDataAccess->SetValue(aProfile);
|
||||||
|
|
||||||
delete aProfile;
|
delete aProfile;
|
||||||
|
@ -1771,6 +1818,7 @@ NS_IMETHODIMP nsProfile::ForgetCurrentProfile()
|
||||||
|
|
||||||
gProfileDataAccess->mForgetProfileCalled = PR_TRUE;
|
gProfileDataAccess->mForgetProfileCalled = PR_TRUE;
|
||||||
mCurrentProfileAvailable = PR_FALSE;
|
mCurrentProfileAvailable = PR_FALSE;
|
||||||
|
mCurrentProfileName.Truncate(0);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1943,6 +1991,22 @@ char * nsProfile::GetOldRegLocation()
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsProfile::UpdateCurrentProfileModTime(PRBool updateRegistry)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
// convert "now" from microsecs to millisecs
|
||||||
|
PRInt64 oneThousand = LL_INIT(0, 1000);
|
||||||
|
PRInt64 nowInMilliSecs = PR_Now();
|
||||||
|
LL_DIV(nowInMilliSecs, nowInMilliSecs, oneThousand);
|
||||||
|
|
||||||
|
rv = gProfileDataAccess->SetProfileLastModTime(mCurrentProfileName.get(), nowInMilliSecs);
|
||||||
|
if (NS_SUCCEEDED(rv) && updateRegistry) {
|
||||||
|
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
||||||
|
gProfileDataAccess->UpdateRegistry(nsnull);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Migrate profile information from the 4x registry to 5x registry.
|
// Migrate profile information from the 4x registry to 5x registry.
|
||||||
NS_IMETHODIMP nsProfile::MigrateProfileInfo()
|
NS_IMETHODIMP nsProfile::MigrateProfileInfo()
|
||||||
|
@ -2080,41 +2144,22 @@ nsresult nsProfile::UndefineFileLocations()
|
||||||
// Set the profile to the current profile....debatable.
|
// Set the profile to the current profile....debatable.
|
||||||
// Calls PrefMigration service to do the Copy and Diverge
|
// Calls PrefMigration service to do the Copy and Diverge
|
||||||
// of 4x Profile information
|
// of 4x Profile information
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsModalWindow)
|
nsProfile::MigrateProfileInternal(const PRUnichar* profileName,
|
||||||
|
nsIFile* oldProfDir,
|
||||||
|
nsIFile* newProfDir)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(profileName);
|
NS_ENSURE_ARG_POINTER(profileName);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
#if defined(DEBUG_profile)
|
#if defined(DEBUG_profile)
|
||||||
printf("Inside Migrate Profile routine.\n" );
|
printf("Inside Migrate Profile routine.\n" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> oldProfDir;
|
|
||||||
nsCOMPtr<nsIFile> newProfDir;
|
|
||||||
|
|
||||||
rv = GetProfileDir(profileName, getter_AddRefs(oldProfDir));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR, getter_AddRefs(newProfDir));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
rv = newProfDir->AppendUnicode(profileName);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// This is unfortunate: There is no CreateUniqueUnicode
|
|
||||||
rv = newProfDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0775);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// always create level indirection when migrating
|
|
||||||
rv = AddLevelOfIndirection(newProfDir);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// Call migration service to do the work.
|
// Call migration service to do the work.
|
||||||
nsCOMPtr <nsIPrefMigration> pPrefMigrator;
|
nsCOMPtr <nsIPrefMigration> pPrefMigrator;
|
||||||
|
|
||||||
|
|
||||||
rv = nsComponentManager::CreateInstance(kPrefMigrationCID,
|
nsresult rv = nsComponentManager::CreateInstance(kPrefMigrationCID,
|
||||||
nsnull,
|
nsnull,
|
||||||
NS_GET_IID(nsIPrefMigration),
|
NS_GET_IID(nsIPrefMigration),
|
||||||
getter_AddRefs(pPrefMigrator));
|
getter_AddRefs(pPrefMigrator));
|
||||||
|
@ -2137,7 +2182,7 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
// you can do this a bunch of times.
|
// you can do this a bunch of times.
|
||||||
rv = pPrefMigrator->AddProfilePaths(oldProfDirStr, newProfDirStr);
|
rv = pPrefMigrator->AddProfilePaths(oldProfDirStr, newProfDirStr);
|
||||||
|
|
||||||
rv = pPrefMigrator->ProcessPrefs(showProgressAsModalWindow);
|
rv = pPrefMigrator->ProcessPrefs(PR_TRUE); // param is ignored
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// check for diskspace errors
|
// check for diskspace errors
|
||||||
|
@ -2198,12 +2243,90 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
rv = SetProfileDir(profileName, newProfDir);
|
rv = SetProfileDir(profileName, newProfDir);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
gProfileDataAccess->SetMigratedFromDir(profileName, oldProfDirLocal);
|
||||||
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
||||||
gProfileDataAccess->UpdateRegistry(nsnull);
|
gProfileDataAccess->UpdateRegistry(nsnull);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsProfile::MigrateProfile(const PRUnichar* profileName)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG(profileName);
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> oldProfDir;
|
||||||
|
nsCOMPtr<nsIFile> newProfDir;
|
||||||
|
|
||||||
|
rv = GetProfileDir(profileName, getter_AddRefs(oldProfDir));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR, getter_AddRefs(newProfDir));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
rv = newProfDir->AppendUnicode(profileName);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
rv = newProfDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0775);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
// always create level indirection when migrating
|
||||||
|
rv = AddLevelOfIndirection(newProfDir);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return MigrateProfileInternal(profileName, oldProfDir, newProfDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsProfile::RemigrateProfile(const PRUnichar* profileName)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(profileName);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> profileDir;
|
||||||
|
nsresult rv = GetProfileDir(profileName, getter_AddRefs(profileDir));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> newProfileDir;
|
||||||
|
rv = profileDir->Clone(getter_AddRefs(newProfileDir));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// The profile list used by GetOriginalProfileDir is the one with ALL 4.x
|
||||||
|
// profiles - even ones for which there's a moz profile of the same name.
|
||||||
|
nsCOMPtr<nsILocalFile> oldProfileDir;
|
||||||
|
rv = GetOriginalProfileDir(profileName, getter_AddRefs(oldProfileDir));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// In case of error, we'll restore what we've renamed.
|
||||||
|
nsXPIDLCString origDirLeafName;
|
||||||
|
rv = profileDir->GetLeafName(getter_Copies(origDirLeafName));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// Backup what we're remigrating by renaming it and leaving in place
|
||||||
|
// XXX todo: what if <xxxxxxxx>.slt-old already exists?
|
||||||
|
nsCAutoString newDirLeafName(origDirLeafName + NS_LITERAL_CSTRING("-old"));
|
||||||
|
rv = profileDir->MoveTo(nsnull, newDirLeafName.get());
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// Create a new directory for the remigrated profile
|
||||||
|
rv = newProfileDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create new directory for the remigrated profile");
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = MigrateProfileInternal(profileName, oldProfileDir, newProfileDir);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
newProfileDir->Remove(PR_TRUE);
|
||||||
|
profileDir->MoveTo(nsnull, origDirLeafName);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsProfile::ShowProfileWizard(void)
|
nsProfile::ShowProfileWizard(void)
|
||||||
{
|
{
|
||||||
|
@ -2266,7 +2389,7 @@ NS_IMETHODIMP nsProfile::MigrateAllProfiles()
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
for (PRUint32 i = 0; i < numOldProfiles; i++)
|
for (PRUint32 i = 0; i < numOldProfiles; i++)
|
||||||
{
|
{
|
||||||
rv = MigrateProfile(nameArray[i], PR_FALSE /* don't show progress as modal window */);
|
rv = MigrateProfile(nameArray[i]);
|
||||||
if (NS_FAILED(rv)) break;
|
if (NS_FAILED(rv)) break;
|
||||||
}
|
}
|
||||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numOldProfiles, nameArray);
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numOldProfiles, nameArray);
|
||||||
|
|
|
@ -87,6 +87,9 @@ private:
|
||||||
nsresult UndefineFileLocations();
|
nsresult UndefineFileLocations();
|
||||||
nsresult Update4xProfileInfo();
|
nsresult Update4xProfileInfo();
|
||||||
char * GetOldRegLocation();
|
char * GetOldRegLocation();
|
||||||
|
nsresult UpdateCurrentProfileModTime(PRBool updateRegistry);
|
||||||
|
nsresult MigrateProfileInternal(const PRUnichar *profileName,
|
||||||
|
nsIFile *oldProfDir, nsIFile *newProfDir);
|
||||||
|
|
||||||
PRBool mStartingUp;
|
PRBool mStartingUp;
|
||||||
PRBool mAutomigrate;
|
PRBool mAutomigrate;
|
||||||
|
@ -94,13 +97,14 @@ private:
|
||||||
PRBool mDiskSpaceErrorQuitCalled;
|
PRBool mDiskSpaceErrorQuitCalled;
|
||||||
PRBool mProfileChangeVetoed;
|
PRBool mProfileChangeVetoed;
|
||||||
|
|
||||||
|
nsString mCurrentProfileName;
|
||||||
PRBool mCurrentProfileAvailable;
|
PRBool mCurrentProfileAvailable;
|
||||||
|
|
||||||
PRBool mIsUILocaleSpecified;
|
PRBool mIsUILocaleSpecified;
|
||||||
nsAutoString mUILocaleName;
|
nsString mUILocaleName;
|
||||||
|
|
||||||
PRBool mIsContentLocaleSpecified;
|
PRBool mIsContentLocaleSpecified;
|
||||||
nsAutoString mContentLocaleName;
|
nsString mContentLocaleName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsProfile();
|
nsProfile();
|
||||||
|
|
|
@ -42,9 +42,6 @@
|
||||||
#include "nsICharsetConverterManager.h"
|
#include "nsICharsetConverterManager.h"
|
||||||
#include "nsIPlatformCharset.h"
|
#include "nsIPlatformCharset.h"
|
||||||
|
|
||||||
#define MAX_PERSISTENT_DATA_SIZE 1000
|
|
||||||
#define NUM_HEX_BYTES 8
|
|
||||||
#define ISHEX(c) ( ((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F') )
|
|
||||||
|
|
||||||
#if defined (XP_UNIX)
|
#if defined (XP_UNIX)
|
||||||
#define USER_ENVIRONMENT_VARIABLE "USER"
|
#define USER_ENVIRONMENT_VARIABLE "USER"
|
||||||
|
@ -76,7 +73,9 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CI
|
||||||
#define kRegistryDirectoryString (NS_LITERAL_STRING("directory"))
|
#define kRegistryDirectoryString (NS_LITERAL_STRING("directory"))
|
||||||
#define kRegistryNeedMigrationString (NS_LITERAL_STRING("NeedMigration"))
|
#define kRegistryNeedMigrationString (NS_LITERAL_STRING("NeedMigration"))
|
||||||
#define kRegistryMozRegDataMovedString (NS_LITERAL_STRING("OldRegDataMoved"))
|
#define kRegistryMozRegDataMovedString (NS_LITERAL_STRING("OldRegDataMoved"))
|
||||||
|
#define kRegistryCreationTimeString (NS_LITERAL_CSTRING("CreationTime"))
|
||||||
|
#define kRegistryLastModTimeString (NS_LITERAL_CSTRING("LastModTime"))
|
||||||
|
#define kRegistryMigratedFromString (NS_LITERAL_CSTRING("MigFromDir"))
|
||||||
#define kRegistryVersionString (NS_LITERAL_STRING("Version"))
|
#define kRegistryVersionString (NS_LITERAL_STRING("Version"))
|
||||||
#define kRegistryVersion_1_0 (NS_LITERAL_STRING("1.0"))
|
#define kRegistryVersion_1_0 (NS_LITERAL_STRING("1.0"))
|
||||||
#define kRegistryCurrentVersion (NS_LITERAL_STRING("1.0"))
|
#define kRegistryCurrentVersion (NS_LITERAL_STRING("1.0"))
|
||||||
|
@ -223,10 +222,9 @@ nsProfileAccess::GetValue(const PRUnichar* profileName, ProfileStruct** aProfile
|
||||||
nsresult
|
nsresult
|
||||||
nsProfileAccess::SetValue(ProfileStruct* aProfile)
|
nsProfileAccess::SetValue(ProfileStruct* aProfile)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aProfile, "Invalid profile");
|
NS_ENSURE_ARG(aProfile);
|
||||||
|
|
||||||
PRInt32 index = 0;
|
PRInt32 index = 0;
|
||||||
PRBool isNewProfile = PR_FALSE;
|
|
||||||
ProfileStruct* profileItem;
|
ProfileStruct* profileItem;
|
||||||
|
|
||||||
index = FindProfileIndex(aProfile->profileName.get(), aProfile->isImportType);
|
index = FindProfileIndex(aProfile->profileName.get(), aProfile->isImportType);
|
||||||
|
@ -234,43 +232,21 @@ nsProfileAccess::SetValue(ProfileStruct* aProfile)
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
profileItem = (ProfileStruct *) (mProfiles->ElementAt(index));
|
profileItem = (ProfileStruct *) (mProfiles->ElementAt(index));
|
||||||
|
*profileItem = *aProfile;
|
||||||
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isNewProfile = PR_TRUE;
|
profileItem = new ProfileStruct(*aProfile);
|
||||||
|
|
||||||
profileItem = new ProfileStruct();
|
|
||||||
if (!profileItem)
|
if (!profileItem)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
profileItem->profileName = aProfile->profileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
aProfile->CopyProfileLocation(profileItem);
|
|
||||||
|
|
||||||
profileItem->isMigrated = aProfile->isMigrated;
|
|
||||||
|
|
||||||
profileItem->isImportType = aProfile->isImportType;
|
|
||||||
|
|
||||||
profileItem->updateProfileEntry = PR_TRUE;
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
|
|
||||||
if (!aProfile->NCProfileName.IsEmpty())
|
if (!mProfiles) {
|
||||||
profileItem->NCProfileName = aProfile->NCProfileName;
|
mProfiles = new nsVoidArray;
|
||||||
|
|
||||||
if (!aProfile->NCDeniedService.IsEmpty())
|
|
||||||
profileItem->NCDeniedService = aProfile->NCDeniedService;
|
|
||||||
|
|
||||||
if (!aProfile->NCEmailAddress.IsEmpty())
|
|
||||||
profileItem->NCEmailAddress = aProfile->NCEmailAddress;
|
|
||||||
|
|
||||||
if (!aProfile->NCHavePregInfo.IsEmpty())
|
|
||||||
profileItem->NCHavePregInfo = aProfile->NCHavePregInfo;
|
|
||||||
|
|
||||||
|
|
||||||
if (isNewProfile) {
|
|
||||||
if (!mProfiles)
|
if (!mProfiles)
|
||||||
mProfiles = new nsVoidArray();
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
mProfiles->AppendElement((void*)profileItem);
|
mProfiles->AppendElement((void*)profileItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,12 +326,6 @@ nsProfileAccess::FillProfileInfo(nsIFile* regName)
|
||||||
kRegistryVersionString.get(),
|
kRegistryVersionString.get(),
|
||||||
getter_Copies(tmpVersion));
|
getter_Copies(tmpVersion));
|
||||||
|
|
||||||
if (tmpVersion == nsnull)
|
|
||||||
{
|
|
||||||
fixRegEntries = PR_TRUE;
|
|
||||||
mProfileDataChanged = PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the preg info
|
// Get the preg info
|
||||||
rv = registry->GetString(profilesTreeKey,
|
rv = registry->GetString(profilesTreeKey,
|
||||||
kRegistryHavePREGInfoString.get(),
|
kRegistryHavePREGInfoString.get(),
|
||||||
|
@ -440,8 +410,23 @@ nsProfileAccess::FillProfileInfo(nsIFile* regName)
|
||||||
profileItem->updateProfileEntry = PR_TRUE;
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
profileItem->profileName = NS_STATIC_CAST(const PRUnichar*, profile);
|
profileItem->profileName = NS_STATIC_CAST(const PRUnichar*, profile);
|
||||||
|
|
||||||
rv = profileItem->InternalizeLocation(registry, profKey, PR_FALSE, fixRegEntries);
|
PRInt64 tmpLongLong;
|
||||||
|
rv = registry->GetLongLong(profKey,
|
||||||
|
kRegistryCreationTimeString.get(),
|
||||||
|
&tmpLongLong);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
profileItem->creationTime = tmpLongLong;
|
||||||
|
|
||||||
|
rv = registry->GetLongLong(profKey,
|
||||||
|
kRegistryLastModTimeString.get(),
|
||||||
|
&tmpLongLong);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
profileItem->lastModTime = tmpLongLong;
|
||||||
|
|
||||||
|
rv = profileItem->InternalizeLocation(registry, profKey, PR_FALSE);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Internalizing profile location failed");
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Internalizing profile location failed");
|
||||||
|
// Not checking the error since most won't have this info
|
||||||
|
profileItem->InternalizeMigratedFromLocation(registry, profKey);
|
||||||
|
|
||||||
profileItem->isMigrated = isMigratedString.Equals(kRegistryYesString);
|
profileItem->isMigrated = isMigratedString.Equals(kRegistryYesString);
|
||||||
|
|
||||||
|
@ -768,6 +753,14 @@ nsProfileAccess::UpdateRegistry(nsIFile* regName)
|
||||||
kRegistryNCHavePREGInfoString.get(),
|
kRegistryNCHavePREGInfoString.get(),
|
||||||
profileItem->NCHavePregInfo.get());
|
profileItem->NCHavePregInfo.get());
|
||||||
|
|
||||||
|
registry->SetLongLong(profKey,
|
||||||
|
kRegistryCreationTimeString.get(),
|
||||||
|
&profileItem->creationTime);
|
||||||
|
|
||||||
|
registry->SetLongLong(profKey,
|
||||||
|
kRegistryLastModTimeString.get(),
|
||||||
|
&profileItem->lastModTime);
|
||||||
|
|
||||||
rv = profileItem->ExternalizeLocation(registry, profKey);
|
rv = profileItem->ExternalizeLocation(registry, profKey);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_ASSERTION(PR_FALSE, "Could not update profile location");
|
NS_ASSERTION(PR_FALSE, "Could not update profile location");
|
||||||
|
@ -775,6 +768,7 @@ nsProfileAccess::UpdateRegistry(nsIFile* regName)
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
profileItem->ExternalizeMigratedFromLocation(registry, profKey);
|
||||||
|
|
||||||
profileItem->updateProfileEntry = PR_FALSE;
|
profileItem->updateProfileEntry = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -818,11 +812,20 @@ nsProfileAccess::UpdateRegistry(nsIFile* regName)
|
||||||
kRegistryNCHavePREGInfoString.get(),
|
kRegistryNCHavePREGInfoString.get(),
|
||||||
profileItem->NCHavePregInfo.get());
|
profileItem->NCHavePregInfo.get());
|
||||||
|
|
||||||
|
registry->SetLongLong(profKey,
|
||||||
|
kRegistryCreationTimeString.get(),
|
||||||
|
&profileItem->creationTime);
|
||||||
|
|
||||||
|
registry->SetLongLong(profKey,
|
||||||
|
kRegistryLastModTimeString.get(),
|
||||||
|
&profileItem->lastModTime);
|
||||||
|
|
||||||
rv = profileItem->ExternalizeLocation(registry, profKey);
|
rv = profileItem->ExternalizeLocation(registry, profKey);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_ASSERTION(PR_FALSE, "Could not update profile location");
|
NS_ASSERTION(PR_FALSE, "Could not update profile location");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
profileItem->ExternalizeMigratedFromLocation(registry, profKey);
|
||||||
|
|
||||||
profileItem->updateProfileEntry = PR_FALSE;
|
profileItem->updateProfileEntry = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -873,6 +876,40 @@ nsProfileAccess::GetOriginalProfileDir(const PRUnichar *profileName, nsILocalFil
|
||||||
}
|
}
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsProfileAccess::SetMigratedFromDir(const PRUnichar *profileName, nsILocalFile *originalDir)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG(profileName);
|
||||||
|
NS_ENSURE_ARG(originalDir);
|
||||||
|
|
||||||
|
PRInt32 index = FindProfileIndex(profileName, PR_FALSE);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
ProfileStruct* profileItem = (ProfileStruct *) (mProfiles->ElementAt(index));
|
||||||
|
profileItem->migratedFrom = originalDir;
|
||||||
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsProfileAccess::SetProfileLastModTime(const PRUnichar *profileName, PRInt64 lastModTime)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG(profileName);
|
||||||
|
|
||||||
|
PRInt32 index = FindProfileIndex(profileName, PR_FALSE);
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
ProfileStruct* profileItem = (ProfileStruct *) (mProfiles->ElementAt(index));
|
||||||
|
profileItem->lastModTime = lastModTime;
|
||||||
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the list of profiles, 4x, 5x, or both.
|
// Return the list of profiles, 4x, 5x, or both.
|
||||||
nsresult
|
nsresult
|
||||||
nsProfileAccess::GetProfileList(PRInt32 whichKind, PRUint32 *length, PRUnichar ***result)
|
nsProfileAccess::GetProfileList(PRInt32 whichKind, PRUint32 *length, PRUnichar ***result)
|
||||||
|
@ -1063,7 +1100,7 @@ nsProfileAccess::Get4xProfileInfo(const char *registryName, PRBool fromImport)
|
||||||
|
|
||||||
profileItem->updateProfileEntry = PR_TRUE;
|
profileItem->updateProfileEntry = PR_TRUE;
|
||||||
profileItem->profileName = convertedProfName;
|
profileItem->profileName = convertedProfName;
|
||||||
rv = profileItem->InternalizeLocation(oldReg, key, PR_TRUE, PR_FALSE);
|
rv = profileItem->InternalizeLocation(oldReg, key, PR_TRUE);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get 4x profile location");
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get 4x profile location");
|
||||||
profileItem->isMigrated = PR_FALSE;
|
profileItem->isMigrated = PR_FALSE;
|
||||||
profileItem->isImportType = fromImport;
|
profileItem->isImportType = fromImport;
|
||||||
|
@ -1218,20 +1255,53 @@ nsProfileAccess::DetermineForceMigration(PRBool *forceMigration)
|
||||||
// class ProfileStruct
|
// class ProfileStruct
|
||||||
// **********************************************************************
|
// **********************************************************************
|
||||||
|
|
||||||
ProfileStruct::ProfileStruct(const ProfileStruct& src) :
|
ProfileStruct::ProfileStruct() :
|
||||||
profileName(src.profileName), isMigrated(src.isMigrated),
|
isMigrated(PR_FALSE), updateProfileEntry(PR_FALSE),
|
||||||
NCProfileName(src.NCProfileName), NCDeniedService(src.NCDeniedService),
|
isImportType(PR_FALSE),
|
||||||
NCEmailAddress(src.NCEmailAddress), NCHavePregInfo(src.NCHavePregInfo),
|
creationTime(LL_ZERO), lastModTime(LL_ZERO)
|
||||||
updateProfileEntry(src.updateProfileEntry),
|
|
||||||
isImportType(src.isImportType),
|
|
||||||
regLocationData(src.regLocationData)
|
|
||||||
{
|
{
|
||||||
if (src.resolvedLocation) {
|
}
|
||||||
|
|
||||||
|
ProfileStruct::ProfileStruct(const ProfileStruct& src)
|
||||||
|
{
|
||||||
|
*this = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileStruct& ProfileStruct::operator=(const ProfileStruct& rhs)
|
||||||
|
{
|
||||||
|
profileName = rhs.profileName;
|
||||||
|
isMigrated = rhs.isMigrated;
|
||||||
|
NCProfileName = rhs.NCProfileName;
|
||||||
|
NCDeniedService = rhs.NCDeniedService;
|
||||||
|
NCEmailAddress = rhs.NCEmailAddress;
|
||||||
|
NCHavePregInfo = rhs.NCHavePregInfo;
|
||||||
|
updateProfileEntry = rhs.updateProfileEntry;
|
||||||
|
isImportType = rhs.isImportType;
|
||||||
|
creationTime = rhs.creationTime;
|
||||||
|
lastModTime = rhs.lastModTime;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
nsCOMPtr<nsIFile> file;
|
nsCOMPtr<nsIFile> file;
|
||||||
nsresult rv = src.resolvedLocation->Clone(getter_AddRefs(file));
|
|
||||||
|
resolvedLocation = nsnull;
|
||||||
|
if (rhs.resolvedLocation) {
|
||||||
|
regLocationData.Truncate(0);
|
||||||
|
rv = rhs.resolvedLocation->Clone(getter_AddRefs(file));
|
||||||
if (NS_SUCCEEDED(rv))
|
if (NS_SUCCEEDED(rv))
|
||||||
resolvedLocation = do_QueryInterface(file);
|
resolvedLocation = do_QueryInterface(file);
|
||||||
|
file = nsnull;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
regLocationData = rhs.regLocationData;
|
||||||
|
|
||||||
|
migratedFrom = nsnull;
|
||||||
|
if (rhs.migratedFrom) {
|
||||||
|
rv = rhs.migratedFrom->Clone(getter_AddRefs(file));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
migratedFrom = do_QueryInterface(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult ProfileStruct::GetResolvedProfileDir(nsILocalFile **aDirectory)
|
nsresult ProfileStruct::GetResolvedProfileDir(nsILocalFile **aDirectory)
|
||||||
|
@ -1270,7 +1340,7 @@ nsresult ProfileStruct::CopyProfileLocation(ProfileStruct *destStruct)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult ProfileStruct::InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey, PRBool is4x, PRBool isOld50)
|
nsresult ProfileStruct::InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey, PRBool is4x)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsILocalFile> tempLocal;
|
nsCOMPtr<nsILocalFile> tempLocal;
|
||||||
|
@ -1315,71 +1385,6 @@ nsresult ProfileStruct::InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKe
|
||||||
{
|
{
|
||||||
nsXPIDLString regData;
|
nsXPIDLString regData;
|
||||||
|
|
||||||
if (isOld50) // Some format which was used around M10-M11. Can we forget about it?
|
|
||||||
{
|
|
||||||
|
|
||||||
rv = aRegistry->GetString(profKey,
|
|
||||||
kRegistryDirectoryString.get(),
|
|
||||||
getter_Copies(regData));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
PRBool haveHexBytes = PR_TRUE;
|
|
||||||
|
|
||||||
// Decode the directory name to return the ordinary string
|
|
||||||
nsCAutoString regDataCString; regDataCString.AssignWithConversion(regData);
|
|
||||||
nsInputStringStream stream(regDataCString.get());
|
|
||||||
|
|
||||||
char bigBuffer[MAX_PERSISTENT_DATA_SIZE + 1];
|
|
||||||
// The first 8 bytes of the data should be a hex version of the data size to follow.
|
|
||||||
PRInt32 bytesRead = NUM_HEX_BYTES;
|
|
||||||
bytesRead = stream.read(bigBuffer, bytesRead);
|
|
||||||
|
|
||||||
if (bytesRead != NUM_HEX_BYTES)
|
|
||||||
haveHexBytes = PR_FALSE;
|
|
||||||
|
|
||||||
if (haveHexBytes)
|
|
||||||
{
|
|
||||||
bigBuffer[NUM_HEX_BYTES] = '\0';
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_HEX_BYTES; i++)
|
|
||||||
{
|
|
||||||
if (!(ISHEX(bigBuffer[i])))
|
|
||||||
{
|
|
||||||
haveHexBytes = PR_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString dirNameString;
|
|
||||||
if (haveHexBytes)
|
|
||||||
{
|
|
||||||
PR_sscanf(bigBuffer, "%x", (PRUint32*)&bytesRead);
|
|
||||||
if (bytesRead > MAX_PERSISTENT_DATA_SIZE)
|
|
||||||
{
|
|
||||||
// Try to tolerate encoded values with no length header
|
|
||||||
bytesRead = NUM_HEX_BYTES +
|
|
||||||
stream.read(bigBuffer + NUM_HEX_BYTES,
|
|
||||||
MAX_PERSISTENT_DATA_SIZE - NUM_HEX_BYTES);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Now we know how many bytes to read, do it.
|
|
||||||
bytesRead = stream.read(bigBuffer, bytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we are null terminated
|
|
||||||
bigBuffer[bytesRead]='\0';
|
|
||||||
|
|
||||||
dirNameString.AssignWithConversion(nsDependentCString(bigBuffer, bytesRead).get());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dirNameString = regData;
|
|
||||||
|
|
||||||
rv = NS_NewUnicodeLocalFile(dirNameString.get(), PR_TRUE, getter_AddRefs(tempLocal));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = aRegistry->GetString(profKey,
|
rv = aRegistry->GetString(profKey,
|
||||||
kRegistryDirectoryString.get(),
|
kRegistryDirectoryString.get(),
|
||||||
getter_Copies(regData));
|
getter_Copies(regData));
|
||||||
|
@ -1399,7 +1404,6 @@ nsresult ProfileStruct::InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKe
|
||||||
#endif
|
#endif
|
||||||
rv = NS_NewUnicodeLocalFile(regLocationData.get(), PR_TRUE, getter_AddRefs(tempLocal));
|
rv = NS_NewUnicodeLocalFile(regLocationData.get(), PR_TRUE, getter_AddRefs(tempLocal));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && tempLocal)
|
if (NS_SUCCEEDED(rv) && tempLocal)
|
||||||
{
|
{
|
||||||
|
@ -1459,6 +1463,59 @@ nsresult ProfileStruct::ExternalizeLocation(nsIRegistry *aRegistry, nsRegistryKe
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult ProfileStruct::InternalizeMigratedFromLocation(nsIRegistry *aRegistry, nsRegistryKey profKey)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsXPIDLCString regData;
|
||||||
|
nsCOMPtr<nsILocalFile> tempLocal;
|
||||||
|
|
||||||
|
rv = aRegistry->GetStringUTF8(profKey,
|
||||||
|
kRegistryMigratedFromString.get(),
|
||||||
|
getter_Copies(regData));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
#ifdef XP_MAC
|
||||||
|
rv = NS_NewLocalFile(nsnull, PR_TRUE, getter_AddRefs(tempLocal));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
// The persistent desc on Mac is base64 encoded so plain ASCII
|
||||||
|
rv = tempLocal->SetPersistentDescriptor(regData.get());
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
migratedFrom = tempLocal;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rv = NS_NewUnicodeLocalFile(NS_ConvertUTF8toUCS2(regData).get(), PR_TRUE, getter_AddRefs(tempLocal));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
migratedFrom = tempLocal;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult ProfileStruct::ExternalizeMigratedFromLocation(nsIRegistry *aRegistry, nsRegistryKey profKey)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
nsXPIDLCString regData;
|
||||||
|
|
||||||
|
if (migratedFrom)
|
||||||
|
{
|
||||||
|
#if XP_MAC
|
||||||
|
rv = migratedFrom->GetPersistentDescriptor(getter_Copies(regData));
|
||||||
|
#else
|
||||||
|
nsXPIDLString ucPath;
|
||||||
|
rv = resolvedLocation->GetUnicodePath(getter_Copies(ucPath));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
regData = NS_ConvertUCS2toUTF8(ucPath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = aRegistry->SetStringUTF8(profKey,
|
||||||
|
kRegistryMigratedFromString.get(),
|
||||||
|
regData.get());
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult ProfileStruct::EnsureDirPathExists(nsILocalFile *aDir, PRBool *wasCreated)
|
nsresult ProfileStruct::EnsureDirPathExists(nsILocalFile *aDir, PRBool *wasCreated)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aDir);
|
NS_ENSURE_ARG(aDir);
|
||||||
|
|
|
@ -33,11 +33,13 @@
|
||||||
class ProfileStruct
|
class ProfileStruct
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ProfileStruct() { }
|
ProfileStruct();
|
||||||
ProfileStruct(const ProfileStruct& src);
|
ProfileStruct(const ProfileStruct& src);
|
||||||
|
|
||||||
~ProfileStruct() { }
|
~ProfileStruct() { }
|
||||||
|
|
||||||
|
ProfileStruct& operator=(const ProfileStruct& rhs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetResolvedProfileDir returns the directory specified in the
|
* GetResolvedProfileDir returns the directory specified in the
|
||||||
* registry. It will return NULL if the spec in the registry
|
* registry. It will return NULL if the spec in the registry
|
||||||
|
@ -63,12 +65,19 @@ public:
|
||||||
* Methods used by routines which internalize
|
* Methods used by routines which internalize
|
||||||
* and externalize profile info.
|
* and externalize profile info.
|
||||||
*/
|
*/
|
||||||
nsresult InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey, PRBool is4x, PRBool isOld50);
|
nsresult InternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey, PRBool is4x);
|
||||||
nsresult ExternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey);
|
nsresult ExternalizeLocation(nsIRegistry *aRegistry, nsRegistryKey profKey);
|
||||||
|
nsresult InternalizeMigratedFromLocation(nsIRegistry *aRegistry, nsRegistryKey profKey);
|
||||||
|
nsresult ExternalizeMigratedFromLocation(nsIRegistry *aRegistry, nsRegistryKey profKey);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsString profileName;
|
nsString profileName;
|
||||||
PRBool isMigrated;
|
PRBool isMigrated;
|
||||||
|
|
||||||
|
// The directory from which this profile was migrated from (if any)
|
||||||
|
// Added in mozilla1.0.1 and maintained in the registry
|
||||||
|
nsCOMPtr<nsILocalFile> migratedFrom;
|
||||||
|
|
||||||
nsString NCProfileName;
|
nsString NCProfileName;
|
||||||
nsString NCDeniedService;
|
nsString NCDeniedService;
|
||||||
nsString NCEmailAddress;
|
nsString NCEmailAddress;
|
||||||
|
@ -76,6 +85,11 @@ public:
|
||||||
PRBool updateProfileEntry;
|
PRBool updateProfileEntry;
|
||||||
// this flag detemines if we added this profile to the list for the import module.
|
// this flag detemines if we added this profile to the list for the import module.
|
||||||
PRBool isImportType;
|
PRBool isImportType;
|
||||||
|
// These fields were added in mozilla1.0.1 and maintained in the registry.
|
||||||
|
// Values are in milliseconds since midnight Jan 1, 1970 GMT (same as nsIFile)
|
||||||
|
// Their values will be LL_ZERO if undefined.
|
||||||
|
PRInt64 creationTime;
|
||||||
|
PRInt64 lastModTime;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult EnsureDirPathExists(nsILocalFile *aFile, PRBool *wasCreated);
|
nsresult EnsureDirPathExists(nsILocalFile *aFile, PRBool *wasCreated);
|
||||||
|
@ -115,6 +129,8 @@ public:
|
||||||
void GetFirstProfile(PRUnichar **firstProfile);
|
void GetFirstProfile(PRUnichar **firstProfile);
|
||||||
nsresult GetProfileList(PRInt32 whichKind, PRUint32 *length, PRUnichar ***result);
|
nsresult GetProfileList(PRInt32 whichKind, PRUint32 *length, PRUnichar ***result);
|
||||||
nsresult GetOriginalProfileDir(const PRUnichar *profileName, nsILocalFile **orginalDir);
|
nsresult GetOriginalProfileDir(const PRUnichar *profileName, nsILocalFile **orginalDir);
|
||||||
|
nsresult SetMigratedFromDir(const PRUnichar *profileName, nsILocalFile *orginalDir);
|
||||||
|
nsresult SetProfileLastModTime(const PRUnichar *profileName, PRInt64 lastModTime);
|
||||||
|
|
||||||
// if fromImport is true all the 4.x profiles will be added to mProfiles with the isImportType flag set.
|
// if fromImport is true all the 4.x profiles will be added to mProfiles with the isImportType flag set.
|
||||||
// pass fromImport as True only if you are calling from the Import Module.
|
// pass fromImport as True only if you are calling from the Import Module.
|
||||||
|
|
|
@ -80,6 +80,12 @@ PRBool OnMacOSX();
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
|
/* for the "remigration" stuff */
|
||||||
|
#include "nsIPrefService.h"
|
||||||
|
#include "nsIPrefBranch.h"
|
||||||
|
#include "nsIPromptService.h"
|
||||||
|
#include "nsIStringBundle.h"
|
||||||
|
|
||||||
#include "nsAppShellService.h"
|
#include "nsAppShellService.h"
|
||||||
#include "nsIProfileInternal.h"
|
#include "nsIProfileInternal.h"
|
||||||
|
|
||||||
|
@ -234,8 +240,7 @@ nsAppShellService::DoProfileStartup(nsICmdLineService *aCmdLineService, PRBool c
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsIProfileInternal> profileMgr(do_GetService(NS_PROFILE_CONTRACTID, &rv));
|
nsCOMPtr<nsIProfileInternal> profileMgr(do_GetService(NS_PROFILE_CONTRACTID, &rv));
|
||||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get profile manager");
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
PRBool saveQuitOnLastWindowClosing = mQuitOnLastWindowClosing;
|
PRBool saveQuitOnLastWindowClosing = mQuitOnLastWindowClosing;
|
||||||
mQuitOnLastWindowClosing = PR_FALSE;
|
mQuitOnLastWindowClosing = PR_FALSE;
|
||||||
|
@ -247,11 +252,148 @@ nsAppShellService::DoProfileStartup(nsICmdLineService *aCmdLineService, PRBool c
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mQuitOnLastWindowClosing = saveQuitOnLastWindowClosing;
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
rv = CheckAndRemigrateDefunctProfile();
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to check and remigrate profile");
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mQuitOnLastWindowClosing = saveQuitOnLastWindowClosing;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsAppShellService::CheckAndRemigrateDefunctProfile()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||||
|
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
PRInt32 secondsBeforeDefunct;
|
||||||
|
rv = prefBranch->GetIntPref("profile.seconds_until_defunct", &secondsBeforeDefunct);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// -1 is the value for "never go defunct"
|
||||||
|
// if the pref is set to -1, we'll never prompt the user to remigrate
|
||||||
|
// see all.js (and all-ns.js)
|
||||||
|
if (secondsBeforeDefunct == -1)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// used for converting
|
||||||
|
// seconds -> millisecs
|
||||||
|
// and microsecs -> millisecs
|
||||||
|
PRInt64 oneThousand = LL_INIT(0, 1000);
|
||||||
|
|
||||||
|
PRInt64 defunctInterval;
|
||||||
|
// Init as seconds
|
||||||
|
LL_I2L(defunctInterval, secondsBeforeDefunct);
|
||||||
|
// Convert secs to millisecs
|
||||||
|
LL_MUL(defunctInterval, defunctInterval, oneThousand);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIProfileInternal> profileMgr(do_GetService(NS_PROFILE_CONTRACTID, &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsXPIDLString profileName;
|
||||||
|
PRInt64 lastModTime;
|
||||||
|
profileMgr->GetCurrentProfile(getter_Copies(profileName));
|
||||||
|
rv = profileMgr->GetProfileLastModTime(profileName.get(), &lastModTime);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
// convert "now" from microsecs to millisecs
|
||||||
|
PRInt64 nowInMilliSecs = PR_Now();
|
||||||
|
LL_DIV(nowInMilliSecs, nowInMilliSecs, oneThousand);
|
||||||
|
|
||||||
|
// determine (using the pref value) when the profile would be considered defunct
|
||||||
|
PRInt64 defunctIntervalAgo;
|
||||||
|
LL_SUB(defunctIntervalAgo, nowInMilliSecs, defunctInterval);
|
||||||
|
|
||||||
|
// if we've used our current 6.x / mozilla profile more recently than
|
||||||
|
// when we'd consider it defunct, don't remigrate
|
||||||
|
if (LL_CMP(lastModTime, >, defunctIntervalAgo))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsILocalFile> origProfileDir;
|
||||||
|
rv = profileMgr->GetOriginalProfileDir(profileName, getter_AddRefs(origProfileDir));
|
||||||
|
// if this fails
|
||||||
|
// then the current profile is a new one (not from 4.x)
|
||||||
|
// so we are done.
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Now, we know that a matching 4.x profile exists
|
||||||
|
// See if it has any newer files in it than our defunct profile.
|
||||||
|
nsCOMPtr<nsISimpleEnumerator> dirEnum;
|
||||||
|
rv = origProfileDir->GetDirectoryEntries(getter_AddRefs(dirEnum));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
PRBool promptForRemigration = PR_FALSE;
|
||||||
|
PRBool hasMore;
|
||||||
|
while (NS_SUCCEEDED(dirEnum->HasMoreElements(&hasMore)) && hasMore) {
|
||||||
|
nsCOMPtr<nsILocalFile> currElem;
|
||||||
|
rv = dirEnum->GetNext(getter_AddRefs(currElem));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
PRInt64 currElemModTime;
|
||||||
|
rv = currElem->GetLastModifiedTime(&currElemModTime);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
// if this file in our 4.x profile is more recent than when we last used our mozilla / 6.x profile
|
||||||
|
// we should prompt for re-migration
|
||||||
|
if (LL_CMP(currElemModTime, >, lastModTime)) {
|
||||||
|
promptForRemigration = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing in the 4.x dir is newer than our defunct profile, return.
|
||||||
|
if (!promptForRemigration)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIStringBundleService> stringBundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIStringBundle> migrationBundle, brandBundle;
|
||||||
|
rv = stringBundleService->CreateBundle("chrome://communicator/locale/profile/migration.properties", getter_AddRefs(migrationBundle));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
rv = stringBundleService->CreateBundle("chrome://global/locale/brand.properties", getter_AddRefs(brandBundle));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsXPIDLString brandName;
|
||||||
|
rv = brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(), getter_Copies(brandName));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsXPIDLString dialogText;
|
||||||
|
rv = migrationBundle->GetStringFromName(NS_LITERAL_STRING("confirmRemigration").get(), getter_Copies(dialogText));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPromptService> promptService(do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
PRInt32 buttonPressed;
|
||||||
|
rv = promptService->ConfirmEx(nsnull, brandName.get(),
|
||||||
|
dialogText.get(),
|
||||||
|
(nsIPromptService::BUTTON_POS_0 *
|
||||||
|
nsIPromptService::BUTTON_TITLE_YES) +
|
||||||
|
(nsIPromptService::BUTTON_POS_1 *
|
||||||
|
nsIPromptService::BUTTON_TITLE_NO),
|
||||||
|
nsnull, nsnull, nsnull, nsnull, nsnull, &buttonPressed);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
if (buttonPressed == 0) {
|
||||||
|
// Need to shut down the current profile before remigrating it
|
||||||
|
profileMgr->ShutDownCurrentProfile(nsIProfile::SHUTDOWN_PERSIST);
|
||||||
|
// If this fails, it will restore what was there.
|
||||||
|
rv = profileMgr->RemigrateProfile(profileName.get());
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Remigration of profile failed.");
|
||||||
|
// Whether or not we succeeded or failed, need to reset this.
|
||||||
|
profileMgr->SetCurrentProfile(profileName.get());
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsAppShellService::CreateHiddenWindow()
|
nsAppShellService::CreateHiddenWindow()
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,6 +96,9 @@ protected:
|
||||||
|
|
||||||
static void* PR_CALLBACK HandleExitEvent(PLEvent* aEvent);
|
static void* PR_CALLBACK HandleExitEvent(PLEvent* aEvent);
|
||||||
static void PR_CALLBACK DestroyExitEvent(PLEvent* aEvent);
|
static void PR_CALLBACK DestroyExitEvent(PLEvent* aEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsresult CheckAndRemigrateDefunctProfile();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@ REQUIRES = xpcom \
|
||||||
uconv \
|
uconv \
|
||||||
locale \
|
locale \
|
||||||
xremoteservice \
|
xremoteservice \
|
||||||
|
profile \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
# for jprof
|
# for jprof
|
||||||
REQUIRES += jprof
|
REQUIRES += jprof
|
||||||
|
|
|
@ -96,6 +96,9 @@
|
||||||
#include "nsIXRemoteService.h"
|
#include "nsIXRemoteService.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// see DoOnShutdown()
|
||||||
|
#include "nsIProfile.h"
|
||||||
|
|
||||||
#ifdef NS_TRACE_MALLOC
|
#ifdef NS_TRACE_MALLOC
|
||||||
#include "nsTraceMalloc.h"
|
#include "nsTraceMalloc.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,7 +109,7 @@
|
||||||
|
|
||||||
#include "nsITimelineService.h"
|
#include "nsITimelineService.h"
|
||||||
|
|
||||||
#if defined(DEBUG_sspitzer) || defined(DEBUG_seth) || defined(DEBUG_pra)
|
#if defined(DEBUG_pra)
|
||||||
#define DEBUG_CMD_LINE
|
#define DEBUG_CMD_LINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -773,6 +776,17 @@ static nsresult DoOnShutdown()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
// call ShutDownCurrentProfile() so we update the last modified time of the profile
|
||||||
|
{
|
||||||
|
// scoping this in a block to force release
|
||||||
|
nsCOMPtr<nsIProfile> profileMgr(do_GetService(NS_PROFILE_CONTRACTID, &rv));
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get profile manager, so unable to update last modified time");
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// 0 is undefined, we use this secret value so that we don't notify
|
||||||
|
profileMgr->ShutDownCurrentProfile(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// save the prefs, in case they weren't saved
|
// save the prefs, in case they weren't saved
|
||||||
{
|
{
|
||||||
// scoping this in a block to force release
|
// scoping this in a block to force release
|
||||||
|
|
Загрузка…
Ссылка в новой задаче