--- a/installationservices/swi/source/integrityservices/integrityservices.cpp Thu Aug 19 10:02:49 2010 +0300
+++ b/installationservices/swi/source/integrityservices/integrityservices.cpp Tue Aug 31 15:21:33 2010 +0300
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
@@ -138,6 +138,41 @@
CleanupStack::PopAndDestroy(localFilenameHeap);
}
+void CIntegrityServices::CopyToBackupL(const TDesC& aSource, const TDesC& aBackup)
+ {
+ // Copying a file isn't atomic so we create a temporary backup file first
+ RBuf backupTmpName;
+ backupTmpName.Create(aBackup.Length() + 4);
+ CleanupClosePushL(backupTmpName);
+ backupTmpName.Copy(aBackup);
+ _LIT(KTmpExt, ".tmp");
+ backupTmpName.Append(KTmpExt);
+
+ // Copying a file is not an atomic operation so add the temporary
+ // file to the journal to enable cleanup if a power failure occurs before
+ // the rename
+ SimulatePowerFailureL(EFailAddingTempFile, EBeforeJournal, backupTmpName);
+ iJournal->TemporaryL(backupTmpName);
+ SimulatePowerFailureL(EFailAddingTempFile, EAfterJournal, backupTmpName);
+
+ CFileMan* fileMan = CFileMan::NewL(iFs);
+ CleanupStack::PushL(fileMan);
+
+ TInt err = fileMan->Copy(aSource, backupTmpName);
+ DEBUG_PRINTF4(_L("CopyToBackupL: Copying %S to %S, err %d"), &aSource, &backupTmpName, err);
+ User::LeaveIfError(err);
+
+ // Backup is complete, use RFs::Rename as atomic 'commit' of backup
+ err = iFs.Rename(backupTmpName, aBackup);
+ DEBUG_PRINTF2(_L("CopyToBackupL: Commit backup returned error %d"), err);
+ User::LeaveIfError(err);
+ CleanupStack::PopAndDestroy(2, &backupTmpName); // backupTmpName, fileMan
+
+ // Now the backup is safe the original can be deleted
+ err = iLoader.Delete(aSource);
+ DEBUG_PRINTF3(_L("CopyToBackupL: RLoader::Delete %S returned error %d"), &aSource, err);
+ User::LeaveIfError(err);
+ }
EXPORT_C void CIntegrityServices::RemoveL(const TDesC& aFileName)
{
@@ -178,11 +213,20 @@
}
SimulatePowerFailureL(EFailRemovingFile, EBeforeAction, aFileName);
-
- err = iFs.Rename(localFilename, backupFileName);
- DEBUG_PRINTF4(_L("Renamed %S as %S error %d"), &localFilename, &backupFileName, err);
- User::LeaveIfError(err);
-
+
+ _LIT(KSysBinMatch, "?:\\sys\\bin\\*");
+ if (localFilename.MatchF(KSysBinMatch) == 0)
+ {
+ // A copy is slower than a rename to only use the
+ // demand paging safe API for files in sys\bin
+ CopyToBackupL(localFilename, backupFileName);
+ }
+ else
+ {
+ err = iFs.Rename(localFilename, backupFileName);
+ DEBUG_PRINTF4(_L("Renamed %S as %S error %d"), &localFilename, &backupFileName, err);
+ User::LeaveIfError(err);
+ }
SimulatePowerFailureL(EFailRemovingFile, EAfterAction, aFileName);
}
else