diff -r 5cc91383ab1e -r 7333d7932ef7 installationservices/swi/source/integrityservices/integrityservices.cpp --- 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