installationservices/swi/source/integrityservices/integrityservices.cpp
branchRCL_3
changeset 25 7333d7932ef7
parent 17 741e5bba2bd1
child 26 8b7f4e561641
--- 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