diff -r 491b3ed49290 -r 65326cf895ed filemanager/Engine/src/CFileManagerRemovableDriveHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/filemanager/Engine/src/CFileManagerRemovableDriveHandler.cpp Wed Sep 01 12:31:07 2010 +0100 @@ -0,0 +1,1337 @@ +/* +* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0"" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Wraps removable drive functionality +* +*/ + + + +// INCLUDE FILES +#include +#include "CFileManagerRemovableDriveHandler.h" +#include "MFileManagerProcessObserver.h" +#include "CFileManagerUtils.h" +#include "CFileManagerEngine.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#endif // RD_MULTIPLE_DRIVE +#include +#include +#include "CMMCScBkupEngine.h" +#include "MMCScBkupOperations.h" +#include "CMMCScBkupOperationParameters.h" +#include "CFileManagerItemProperties.h" +#include "CFileManagerBackupSettings.h" +#include "FileManagerPrivateCRKeys.h" +#include "BkupEngine.hrh" +#include "FileManagerDebug.h" +#include "CFileManagerCommonDefinitions.h" +#include "FileManagerUID.h" +#include "filemanagerprivatepskeys.h" + + +// CONSTANTS +const TInt KEjectScanInterval = 1000000; // 1 second +const TInt KEjectScanRoundsMax = 7; +NONSHARABLE_CLASS(TMaskLookup) + { + public: + TUint32 iBkupMask; + TUint32 iFmgrMask; + }; + +const TMaskLookup KMaskLookup[] = { + { EBUCatSettings, EFileManagerBackupContentSettings }, + { EBUCatMessages, EFileManagerBackupContentMessages }, + { EBUCatContacts, EFileManagerBackupContentContacts }, + { EBUCatCalendar, EFileManagerBackupContentCalendar }, + { EBUCatBookmarks, EFileManagerBackupContentBookmarks }, + { EBUCatUserFiles, EFileManagerBackupContentUserFiles } +}; +const TUint32 KMaskLookupLen = + sizeof( KMaskLookup ) / sizeof( KMaskLookup[ 0 ] ); + +const TInt KForcedFormatTimeout = 1000000; +const TInt KAppCloseTimeout = 1000000; +const TInt KFileManagerAppUid = 0x101F84EB; + +NONSHARABLE_CLASS(TFileManagerVolumeNameStore) + { +public: + inline TFileManagerVolumeNameStore() : iDrive( KErrNotFound ), iName( KNullDesC ) {}; + + TInt iDrive; // The drive using the store + TFileName iName; // Use the same length than TVolumeInfo + }; + +typedef TPckg< TFileManagerVolumeNameStore > TFileManagerVolumeNameStorePckg; + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::CFileManagerRemovableDriveHandler +// --------------------------------------------------------------------------- +// +CFileManagerRemovableDriveHandler::CFileManagerRemovableDriveHandler( + RFs& aFs, + CFileManagerUtils& aUtils, + CFileManagerEngine& aEngine ) : + CActive( CActive::EPriorityStandard ), + iFs( aFs ), + iUtils( aUtils ), + iEngine( aEngine ) + { + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::ConstructL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::ConstructL() + { + CActiveScheduler::Add( this ); + iBkupEngine = CMMCScBkupEngine::NewL( iFs ); + PublishBurStatus( EFileManagerBkupStatusUnset ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::NewL +// --------------------------------------------------------------------------- +// +CFileManagerRemovableDriveHandler* CFileManagerRemovableDriveHandler::NewL( + RFs& aFs, + CFileManagerUtils& aUtils, + CFileManagerEngine& aEngine ) + { + CFileManagerRemovableDriveHandler* self = + new( ELeave ) CFileManagerRemovableDriveHandler( + aFs, aUtils, aEngine ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::~CFileManagerRemovableDriveHandler +// --------------------------------------------------------------------------- +// +CFileManagerRemovableDriveHandler::~CFileManagerRemovableDriveHandler() + { + Cancel(); + delete iBSWrapper; + delete iEjectScanPeriodic; + delete iBkupEngine; + iFormatter.Close(); + PublishBurStatus( EFileManagerBkupStatusUnset ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::EjectScanAndShutdownApps +// --------------------------------------------------------------------------- +// +TInt CFileManagerRemovableDriveHandler::EjectScanAndShutdownApps( TAny* ptr ) + { + CFileManagerRemovableDriveHandler* self = + static_cast< CFileManagerRemovableDriveHandler* >( ptr ); + TRAPD( err, self->DoEjectScanAndShutdownL() ); + if ( err != KErrNone ) + { + self->EjectComplete( err ); + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::DoEjectScanAndShutdownL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::DoEjectScanAndShutdownL() + { + RWsSession wsSession; + User::LeaveIfError( wsSession.Connect() ); + CleanupClosePushL( wsSession ); + + const TInt KDefaultWgIdArraySize = 4; + CArrayFixFlat* wgIds = new( ELeave ) CArrayFixFlat< TInt >( + KDefaultWgIdArraySize ); + CleanupStack::PushL( wgIds ); + User::LeaveIfError( wsSession.WindowGroupList( 0, wgIds ) ); + TInt last( wgIds->Count() - 1 ); + TInt appsToShutDown( 0 ); + + for ( TInt i( last ); i >= 0; i-- ) + { + CApaWindowGroupName* doomedApp = + CApaWindowGroupName::NewLC( wsSession, wgIds->At( i ) ); + TBool systemApp( doomedApp->IsSystem() ); + TBool hiddenApp( doomedApp->Hidden() ); + + if ( !systemApp && !hiddenApp && doomedApp->AppUid().iUid != KFileManagerAppUid ) + { + appsToShutDown++; + TApaTask* task = new (ELeave) TApaTask( wsSession ); + CleanupDeletePushL( task ); + task->SetWgId( wgIds->At( i ) ); + + if ( !iEjectScanRounds ) + { + // applications are kindly requested to close themselves + // on the first round + task->EndTask(); + } + else if ( iEjectScanRounds >= KEjectScanRoundsMax ) + { + task->KillTask(); + } + CleanupStack::PopAndDestroy( task ); + } + CleanupStack::PopAndDestroy( doomedApp ); + } + CleanupStack::PopAndDestroy( wgIds ); + + if ( !appsToShutDown || iEjectScanRounds >= KEjectScanRoundsMax ) + { + EjectComplete( KErrNone ); + } + iEjectScanRounds++; + + CleanupStack::PopAndDestroy( &wsSession ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::EjectComplete +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::EjectComplete( TInt aErr ) + { + delete iEjectScanPeriodic; + iEjectScanPeriodic = NULL; + iLastError = aErr; + + TRAP_IGNORE( InformFinishL() ); + + RProperty::Set( + KPSUidCoreApplicationUIs, + KCoreAppUIsMmcRemovedWithoutEject, + ECoreAppUIsEjectCommandNotUsed ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::InformStartL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::InformStartL( TInt aTotalCount ) + { + iLastError = KErrNone; + if ( iObserver ) + { + iObserver->ProcessStartedL( iProcess, aTotalCount ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::InformUpdateL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::InformUpdateL( TInt aCount ) + { + if ( iObserver ) + { + iObserver->ProcessAdvanceL( aCount ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::InformFinishL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::InformFinishL() + { + iEngine.ClearDriveInfo(); + PublishBurStatus( EFileManagerBkupStatusUnset ); + iProcess = MFileManagerProcessObserver::ENoProcess; + if ( iObserver ) + { + iObserver->ProcessFinishedL( iLastError, KNullDesC ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::InformError +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::InformError( TInt aErr ) + { + iLastError = aErr; + if ( iObserver ) + { + iObserver->Error( aErr ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::HandleBkupEngineEventL +// --------------------------------------------------------------------------- +// +TInt CFileManagerRemovableDriveHandler::HandleBkupEngineEventL( + MMMCScBkupEngineObserver::TEvent aEvent, TInt aAssociatedData ) + { + TInt ret( KErrNone ); + switch( aEvent ) + { + case MMMCScBkupEngineObserver::ECommonOperationStarting: + { + iFinalValue = KMaxTInt; + InformStartL( KMaxTInt ); + break; + } + case MMMCScBkupEngineObserver::ECommonSizeOfTaskUnderstood: + { + iFinalValue = aAssociatedData; + InformStartL( aAssociatedData ); + break; + } + case MMMCScBkupEngineObserver::ECommonOperationPrepareEnded: + { + PublishBurStatus( EFileManagerBkupStatusUnset ); + // In order to show finished dialog prior SysAp's note, + // inform observer already at prepare-ended state. + if( iProcess == MFileManagerProcessObserver::ERestoreProcess ) + { + if ( iFinalValue ) + { + InformUpdateL( iFinalValue ); + } + InformFinishL(); + } + break; + } + case MMMCScBkupEngineObserver::ECommonOperationEnded: + { + PublishBurStatus( EFileManagerBkupStatusUnset ); + if( iProcess != MFileManagerProcessObserver::ERestoreProcess ) + { + if ( iFinalValue ) + { + InformUpdateL( iFinalValue ); + } + InformFinishL(); + } + break; + } + case MMMCScBkupEngineObserver::ECommonOperationError: + { + iLastError = aAssociatedData; + break; + } + case MMMCScBkupEngineObserver::ECommonProgress: + { + InformUpdateL( aAssociatedData ); + break; + } + case MMMCScBkupEngineObserver::EBackupAnalysingData: + { + if ( iObserver && + iProcess == MFileManagerProcessObserver::EBackupProcess ) + { + ret = iObserver->NotifyL( + MFileManagerProcessObserver::ENotifyBackupMemoryLow, + aAssociatedData ); + } + break; + } + default: + { + break; + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::SetObserver +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::SetObserver( + MFileManagerProcessObserver* aObserver ) + { + iObserver = aObserver; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::BackupFileNameLC +// --------------------------------------------------------------------------- +// +HBufC* CFileManagerRemovableDriveHandler::BackupFileNameLC( + TBool aFullPath ) const + { + HBufC* file = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_MMC_BACKUP_FILE ); + if ( !aFullPath ) + { + return file; // Get just name + } + // Get full path +#ifdef RD_MULTIPLE_DRIVE + TInt drive( 0 ); + User::LeaveIfError( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultRemovableMassStorage, drive ) ); + TDriveUnit driveUnit( drive ); +#else // RD_MULTIPLE_DRIVE + TDriveUnit driveUnit( PathInfo::MemoryCardRootPath() ); +#endif // RD_MULTIPLE_DRIVE + HBufC* fileAndPath = HBufC::NewLC( KMaxFileName ); + TPtr ptr( fileAndPath->Des() ); + TPtr filePtr( file->Des() ); + ptr.Copy( driveUnit.Name() ); + ptr.Append( filePtr ); + CleanupStack::Pop( fileAndPath ); + CleanupStack::PopAndDestroy( file ); + CleanupStack::PushL( fileAndPath ); + return fileAndPath; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartFormatL() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartFormatL( + const TInt aDrive ) + { + TInt err( KErrNone ); + + iDrive = aDrive; + iProcess = MFileManagerProcessObserver::EFormatProcess; + iFinalValue = 0; + + TRAP( err, InformStartL( 0 ) ); + if ( err == KErrNone ) + { + // Close apps and then start format + TRAP( err, CloseAppsL() ); + } + if ( err != KErrNone ) + { + EndFormatProcessL( err ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartEjectL() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartEjectL() + { + TRAPD( err, StartEjectScanL() ); + if ( err != KErrNone ) + { + iProcess = MFileManagerProcessObserver::ENoProcess; + User::Leave( err ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartEjectScanL() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartEjectScanL() + { + iProcess = MFileManagerProcessObserver::EEjectProcess; + InformStartL( 0 ); + + RProperty::Set( + KPSUidCoreApplicationUIs, + KCoreAppUIsMmcRemovedWithoutEject, + ECoreAppUIsEjectCommandUsed ); + + iEjectScanRounds = 0; + iEjectScanPeriodic = CPeriodic::NewL( CActive::EPriorityLow ); + iEjectScanPeriodic->Start( + KEjectScanInterval, + KEjectScanInterval, + TCallBack( EjectScanAndShutdownApps, this ) ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::CancelProcess() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::CancelProcess() + { + switch( iProcess ) + { + case MFileManagerProcessObserver::EFormatProcess: + { + Cancel(); + break; + } + case MFileManagerProcessObserver::EBackupProcess: // FALLTHROUGH + case MFileManagerProcessObserver::ERestoreProcess: + case MFileManagerProcessObserver::ESchBackupProcess: + { + PublishBurStatus( EFileManagerBkupStatusUnset ); + iBkupEngine->CancelOperation(); + break; + } + default: + { + break; + } + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::BackupFileExistsL() +// --------------------------------------------------------------------------- +// +TBool CFileManagerRemovableDriveHandler::BackupFileExistsL( + const TInt /*aDrive*/ ) + { + HBufC* backupFile = BackupFileNameLC( ETrue ); + TBool ret( iBkupEngine->ValidArchiveForRestore( *backupFile ) ); + CleanupStack::PopAndDestroy( backupFile ); + return ret; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartBackupL() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartBackupL( + MFileManagerProcessObserver::TFileManagerProcess aProcess ) + { + if ( aProcess != MFileManagerProcessObserver::EBackupProcess && + aProcess != MFileManagerProcessObserver::ESchBackupProcess ) + { + User::Leave( KErrNotSupported ); + } + + CCoeEnv* coeEnv = CCoeEnv::Static(); + + // Create backup params - ownership is transferred to + // secure backup engine + TResourceReader driveReader; + coeEnv->CreateResourceReaderLC( + driveReader, + R_FILEMANAGER_BACKUP_RESTORE_DRIVES_AND_OPERATIONS ); + TResourceReader categoryReader; + coeEnv->CreateResourceReaderLC( + categoryReader, + R_FILEMANAGER_BACKUP_CATEGORIES ); + +#ifdef RD_FILE_MANAGER_BACKUP + + CFileManagerBackupSettings& settings( iEngine.BackupSettingsL() ); + TUint32 bkupContent( FmgrToBkupMask( settings.Content() ) ); + TInt drive( settings.TargetDrive() ); + + CMMCScBkupOpParamsBackupFull* params = + CMMCScBkupOpParamsBackupFull::NewL( + driveReader, + categoryReader, + TDriveNumber( drive ), + bkupContent ); + +#else // RD_FILE_MANAGER_BACKUP + + HBufC* backupFile = BackupFileNameLC( ETrue ); + TInt drive = TDriveUnit( *backupFile ); + CleanupStack::PopAndDestroy( backupFile ); + + CMMCScBkupOpParamsBackupFull* params = + CMMCScBkupOpParamsBackupFull::NewL( driveReader, + categoryReader, + TDriveNumber( drive ), + EBUCatAllInOne ); + +#endif // RD_FILE_MANAGER_BACKUP + + CleanupStack::PopAndDestroy(); // categoryReader + CleanupStack::PopAndDestroy(); // driveReader + + CleanupStack::PushL( params ); + TBool diskFull( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, 0, drive ) ); + CleanupStack::Pop( params ); + + if ( diskFull ) + { + iProcess = aProcess; + TRAP_IGNORE( InformStartL( KMaxTInt ) ); + iLastError = KErrDiskFull; + TRAP_IGNORE( InformFinishL() ); + iProcess = MFileManagerProcessObserver::ENoProcess; + delete params; + } + else + { + // Start the process - engine owns the parameters immediately + iProcess = aProcess; + + PublishBurStatus( EFileManagerBkupStatusBackup ); + TRAPD( err, iBkupEngine->StartOperationL( + EMMCScBkupOperationTypeFullBackup, *this, params ) ); + if ( err != KErrNone ) + { + PublishBurStatus( EFileManagerBkupStatusUnset ); + iProcess = MFileManagerProcessObserver::ENoProcess; + User::Leave( err ); + } + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartRestoreL() +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartRestoreL() + { + TBool diskFull( SysUtil::DiskSpaceBelowCriticalLevelL( + &iFs, 0, KFmgrSystemDrive ) ); + if ( diskFull ) + { + iProcess = MFileManagerProcessObserver::ERestoreProcess; + TRAP_IGNORE( InformStartL( KMaxTInt ) ); + iLastError = KErrDiskFull; + TRAP_IGNORE( InformFinishL() ); + iProcess = MFileManagerProcessObserver::ENoProcess; + return; + } + + CFileManagerBackupSettings& bkupSettings( iEngine.BackupSettingsL() ); + + // Create restore params - ownership is transferred to + // secure backup engine + TResourceReader driveReader; + CCoeEnv::Static()->CreateResourceReaderLC( + driveReader, + R_FILEMANAGER_BACKUP_RESTORE_DRIVES_AND_OPERATIONS ); + +#ifdef RD_FILE_MANAGER_BACKUP + + CMMCScBkupOpParamsRestoreFull* params = + CMMCScBkupOpParamsRestoreFull::NewL( + driveReader, + EBUCatAllSeparately ); + CleanupStack::PopAndDestroy(); // driveReader + CleanupStack::PushL( params ); + + // Get list of all archives + RPointerArray< CMMCScBkupArchiveInfo > archives; + TCleanupItem cleanupItem( ResetAndDestroyArchives, &archives ); + CleanupStack::PushL( cleanupItem ); + iBkupEngine->ListArchivesL( + archives, + params, + bkupSettings.AllowedDriveAttMatchMask() ); + + // Get user set restore selection + RArray< CFileManagerRestoreSettings::TInfo > selection; + CleanupClosePushL( selection ); + CFileManagerRestoreSettings& rstSettings( iEngine.RestoreSettingsL() ); + rstSettings.GetSelectionL( selection ); + + // Remove non user selected archives + TInt i( 0 ); + while ( i < archives.Count() ) + { + TBool remove( ETrue ); + + // Compare archives category and drive + CMMCScBkupArchiveInfo* archiveInfo = archives[ i ]; + TUint32 fmgrContent( + BkupToFmgrMask( archiveInfo->Category().iFlags ) ); + TInt drive( archiveInfo->Drive() ); + + TInt count( selection.Count() ); + for( TInt j( 0 ); j < count; ++j ) + { + const CFileManagerRestoreSettings::TInfo& info( selection[ j ] ); + if ( ( drive == info.iDrive ) && ( fmgrContent & info.iContent ) ) + { + // Found user selected archive + // Do not check this archive again + selection.Remove( j ); + remove = EFalse; + break; + } + } + if ( remove ) + { + // Remove non selected archive + archives.Remove( i ); + delete archiveInfo; + } + else + { + // Move to next archive + ++i; + } + } + + CleanupStack::PopAndDestroy( &selection ); + params->SetArchiveInfosL( archives ); + CleanupStack::Pop( &archives ); + archives.Close(); + CleanupStack::Pop( params ); + +#else // RD_FILE_MANAGER_BACKUP + + CMMCScBkupOpParamsRestoreFull* params = + CMMCScBkupOpParamsRestoreFull::NewL( driveReader, EBUCatAllInOne ); + CleanupStack::PopAndDestroy(); // driveReader + + // Get list of all archives + RPointerArray< CMMCScBkupArchiveInfo > archives; + TCleanupItem cleanupItem( ResetAndDestroyArchives, &archives ); + CleanupStack::PushL( cleanupItem ); + iBkupEngine->ListArchivesL( + archives, + params, + bkupSettings.AllowedDriveAttMatchMask() ); + params->SetArchiveInfosL( archives ); + CleanupStack::Pop( &archives ); + +#endif // RD_FILE_MANAGER_BACKUP + + // Start the process - engine owns the parameters immediately + iProcess = MFileManagerProcessObserver::ERestoreProcess; + PublishBurStatus( EFileManagerBkupStatusRestore ); + TRAPD( err, iBkupEngine->StartOperationL( + EMMCScBkupOperationTypeFullRestore, *this, params ) ); + if ( err != KErrNone ) + { + PublishBurStatus( EFileManagerBkupStatusUnset ); + iProcess = MFileManagerProcessObserver::ENoProcess; + User::Leave( err ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::GetRestoreInfoArrayL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::GetRestoreInfoArrayL( + RArray< CFileManagerRestoreSettings::TInfo >& aArray, + const TInt aDrive ) + { + + CleanupClosePushL( aArray ); + + CFileManagerBackupSettings& settings( iEngine.BackupSettingsL() ); + aArray.Reset(); + + TResourceReader driveReader; + CCoeEnv::Static()->CreateResourceReaderLC( + driveReader, + R_FILEMANAGER_BACKUP_RESTORE_DRIVES_AND_OPERATIONS ); + + CMMCScBkupOpParamsRestoreFull* params = + CMMCScBkupOpParamsRestoreFull::NewL( + driveReader, EBUCatAllSeparately ); + CleanupStack::PopAndDestroy(); // driveReader + CleanupStack::PushL( params ); + + // Get list of all archives + RPointerArray< CMMCScBkupArchiveInfo > archives; + TCleanupItem cleanupItem( ResetAndDestroyArchives, &archives ); + CleanupStack::PushL( cleanupItem ); + iBkupEngine->ListArchivesL( + archives, + params, + settings.AllowedDriveAttMatchMask(), + aDrive ); + + // Prepare time zone conversion + RTz tz; + User::LeaveIfError( tz.Connect() ); + CleanupClosePushL( tz ); + + // Fill restore info + CFileManagerRestoreSettings::TInfo info; + TInt count( archives.Count() ); + aArray.ReserveL( count ); + + for( TInt i( 0 ); i < count; ++i ) + { + // Content + CMMCScBkupArchiveInfo& archiveInfo( *archives[ i ] ); + info.iContent = BkupToFmgrMask( archiveInfo.Category().iFlags ); + + // Local time + info.iTime = archiveInfo.DateTime(); + User::LeaveIfError( tz.ConvertToLocalTime( info.iTime ) ); + + // Drive + info.iDrive = archiveInfo.Drive(); + + aArray.AppendL( info ); + } + + CleanupStack::PopAndDestroy( &tz ); + CleanupStack::PopAndDestroy( &archives ); + CleanupStack::PopAndDestroy( params ); + CleanupStack::Pop( &aArray ) ; + + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::DoCancel +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::DoCancel() + { + switch( iProcess ) + { + case MFileManagerProcessObserver::EFormatProcess: + { + TRAP_IGNORE( EndFormatProcessL( KErrCancel ) ); + break; + } + default: + { + break; + } + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::RunL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::RunL() + { + TInt err( iStatus.Int() ); + switch( iProcess ) + { + case MFileManagerProcessObserver::EFormatProcess: + { + if( err != KErrNone ) + { + if ( !iFinalValue && err == KErrInUse ) + { + // Some app remained open, try still to start format + StartFormatProcessL(); + } + else + { + // Format failed + EndFormatProcessL( err ); + } + } + else if( !iFinalValue ) + { + // Apps have been closed. Start format. + StartFormatProcessL(); + } + else if( iFormatCountBuf() > 0 ) + { + // Update observer and format next track + InformUpdateL( iFinalValue - iFormatCountBuf() ); + iFormatter.Next( iFormatCountBuf, iStatus ); + SetActive( ); + } + else + { + // Format complete + EndFormatProcessL( KErrNone ); + } + break; + } + default: + { + break; + } + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::RunError +// --------------------------------------------------------------------------- +// +TInt CFileManagerRemovableDriveHandler::RunError( TInt aError ) + { + switch( iProcess ) + { + case MFileManagerProcessObserver::EFormatProcess: + { + TRAP_IGNORE( EndFormatProcessL( aError ) ); + break; + } + default: + { + break; + } + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::EndFormatProcessL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::EndFormatProcessL( TInt aErr ) + { + iFormatter.Close(); + iLastError = aErr; + if( aErr == KErrNone ) + { + // Restore the volume name stored before format operation. + TRAPD( err, RestoreVolumeNameL( iDrive ) ); + LOG_IF_ERROR1( err, + "FileManagerRemovableDriveHandler::EndFormatProcessL-RestoreVolumeName %d", + err ); + iUtils.CreateDefaultFolders( iDrive ); + } + else if ( aErr != KErrCancel ) + { + InformError( aErr ); + } + TRAPD( err, RestartAppsL() ); + LOG_IF_ERROR1( err, + "FileManagerRemovableDriveHandler::EndFormatProcessL-Restart apps %d", + err ); + InformFinishL(); + + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::StartFormatProcessL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StartFormatProcessL() + { + // Store the current volume name over format operation. + TRAPD( err, StoreVolumeNameL( iDrive ) ); + LOG_IF_ERROR1( + err, + "FileManagerRemovableDriveHandler::StartFormatProcessL-StoreVolumeName %d", + err ); + TDriveName driveName( TDriveUnit( iDrive ).Name() ); + // Resolve drive character and open formatter + iFormatter.Close(); + err = iFormatter.Open( + iFs, driveName, EFullFormat, iFinalValue ); + // Forced format for locked card + if ( err == KErrLocked ) + { + // Erase password and try again + err = iFs.ErasePassword( iDrive ); + if (err == KErrNone) + { + err = iFormatter.Open(iFs, driveName, EFullFormat , iFinalValue ); + } + } + if (err == KErrInUse) + { + TBool reallyFormat = ETrue; + if (reallyFormat) + { + err = iFormatter.Open( + iFs, driveName, EFullFormat | EForceFormat, iFinalValue ); + } + } + TFullName fsName; + if (err == KErrNone) + { + err = iFs.FileSystemName( fsName, iDrive ); + + if ( err == KErrNone && fsName.Length() > 0 ) + { + // Prevent SysAp shutting down applications + RProperty::Set( + KPSUidCoreApplicationUIs, + KCoreAppUIsMmcRemovedWithoutEject, + ECoreAppUIsEjectCommandUsed ); + } + else + { + // Don't continue with format if there is no file system name + // or file system name could not be obtained. + err = KErrCancel; + } + } + + // On successful open of RFormat::Open(), iFinalValue contains the number of + // tracks to be formatted + + if ( iFinalValue && err == KErrNone ) + { + TRAP( err, InformStartL( iFinalValue ) ); + if ( err == KErrNone ) + { + iFormatCountBuf = iFinalValue; + iFormatter.Next( iFormatCountBuf, iStatus ); + SetActive(); + } + } + if ( !iFinalValue || err != KErrNone ) + { + EndFormatProcessL( err ); + } + } +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::CloseAppsL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::CloseAppsL() + { + delete iBSWrapper; + iBSWrapper = NULL; + + iBSWrapper = CBaBackupSessionWrapper::NewL(); + + TBackupOperationAttributes atts( + MBackupObserver::EReleaseLockNoAccess, + MBackupOperationObserver::EStart ); + iBSWrapper->NotifyBackupOperationL( atts ); + iBSWrapper->CloseAll( MBackupObserver::EReleaseLockNoAccess, iStatus ); + SetActive(); + + // Memory card formatting cannot be executed if there are open files on it. + // It has been detected, that in some cases memory card using applications + // have no time to close file handles before formatting is tried to be executed. + // To address this issue, we need to add a delay here after client-notification + // about pending format and real formatting procedure. + User::After( KAppCloseTimeout ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::RestartAppsL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::RestartAppsL() + { + if ( !iBSWrapper ) + { + return; + } + + TBackupOperationAttributes atts( + MBackupObserver::ETakeLock, MBackupOperationObserver::EEnd ); + iBSWrapper->NotifyBackupOperationL( atts ); + iBSWrapper->RestartAll(); + + // Get rid of the wrapper instance + delete iBSWrapper; + iBSWrapper = NULL; + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::ResetAndDestroyArchives +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::ResetAndDestroyArchives( TAny* aPtr ) + { + RPointerArray< CMMCScBkupArchiveInfo >* archive = + static_cast< RPointerArray< CMMCScBkupArchiveInfo >* >( aPtr ); + archive->ResetAndDestroy(); + archive->Close(); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::BkupToFmgrMask +// --------------------------------------------------------------------------- +// +TUint32 CFileManagerRemovableDriveHandler::BkupToFmgrMask( + const TUint32 aBkupMask ) + { + TUint32 ret( 0 ); + + for( TInt i( 0 ); i < KMaskLookupLen; ++i ) + { + if ( aBkupMask & KMaskLookup[ i ].iBkupMask ) + { + ret |= KMaskLookup[ i ].iFmgrMask; + } + } + return ret; + } + +#ifdef RD_FILE_MANAGER_BACKUP +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::FmgrToBkupMask +// --------------------------------------------------------------------------- +// +TUint32 CFileManagerRemovableDriveHandler::FmgrToBkupMask( + const TUint32 aFmrgMask ) + { + TUint32 ret( 0 ); + + for( TInt i( 0 ); i < KMaskLookupLen; ++i ) + { + if ( ( aFmrgMask & EFileManagerBackupContentAll ) || + ( aFmrgMask & KMaskLookup[ i ].iFmgrMask ) ) + { + ret |= KMaskLookup[ i ].iBkupMask; + } + } + return ret; + } +#endif // RD_FILE_MANAGER_BACKUP + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::IsProcessOngoing +// --------------------------------------------------------------------------- +// +TBool CFileManagerRemovableDriveHandler::IsProcessOngoing() const + { + return iProcess != MFileManagerProcessObserver::ENoProcess; + } + +// ----------------------------------------------------------------------------- +// CFileManagerEngine::PublishBurStatus() +// +// ----------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::PublishBurStatus( TInt aType ) + { + _LIT_SECURITY_POLICY_S0( KFileManagerBkupWritePolicy, KFileManagerUID3 ); + _LIT_SECURITY_POLICY_PASS( KFileManagerBkupReadPolicy ); + + TInt err( RProperty::Set( + KPSUidFileManagerStatus, KFileManagerBkupStatus, aType ) ); + if ( err != KErrNone ) + { + err = RProperty::Define( + KPSUidFileManagerStatus, KFileManagerBkupStatus, + RProperty::EInt, KFileManagerBkupReadPolicy, + KFileManagerBkupWritePolicy ); + if ( err == KErrNone || err == KErrAlreadyExists ) + { + err = RProperty::Set( + KPSUidFileManagerStatus, KFileManagerBkupStatus, aType ); + } + } + LOG_IF_ERROR1( + err, "FileManagerRemovableDriveHandler::PublishBurStatus-err=%d", err ) + } + +// ----------------------------------------------------------------------------- +// CFileManagerEngine::IsMassStorageDrive() +// +// ----------------------------------------------------------------------------- +// +#ifdef RD_MULTIPLE_DRIVE + +TBool CFileManagerRemovableDriveHandler::IsInternalMassStorage( TInt aDrive ) + { + FUNC_LOG; + + TBool ret( EFalse ); + TUint driveStatus( 0 ); + DriveInfo::GetDriveStatus( iFs, aDrive, driveStatus ); + if ( ( driveStatus & DriveInfo::EDriveInternal ) && + ( driveStatus & DriveInfo::EDriveExternallyMountable ) ) + { + ret = ETrue; + } + INFO_LOG2( + "FileManagerRemovableDriveHandler::IsInternalMassStorage-drive=%d,ret=%d", + aDrive, ret ); + return ret; + } + +#else // RD_MULTIPLE_DRIVE + +TBool CFileManagerRemovableDriveHandler::IsInternalMassStorage( TInt /*aDrive*/ ) + { + FUNC_LOG; + + TInt ret( EFalse ); + return ret; + } + +#endif // RD_MULTIPLE_DRIVE + +// ----------------------------------------------------------------------------- +// CFileManagerEngine::StoreVolumeNameL() +// +// ----------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::StoreVolumeNameL( TInt aDrive ) + { + FUNC_LOG; + + if ( IsInternalMassStorage( aDrive ) ) + { + TVolumeInfo volumeInfo; + User::LeaveIfError( iFs.Volume( volumeInfo, aDrive ) ); + CRepository* cenRep = CRepository::NewLC( KCRUidFileManagerSettings ); + TFileManagerVolumeNameStore volumeStore; + TFileManagerVolumeNameStorePckg volumeStorePckg( volumeStore ); + volumeStore.iDrive = aDrive; + volumeStore.iName.Copy( volumeInfo.iName ); + User::LeaveIfError( cenRep->Set( + KFileManagerStoredInternalMassStorageVolumeName, volumeStorePckg ) ); + CleanupStack::PopAndDestroy( cenRep ); + INFO_LOG2( + "FileManagerRemovableDriveHandler::StoreVolumeNameL-drive=%d,name=%S", + aDrive, &volumeStore.iName ); + } + } + +// ----------------------------------------------------------------------------- +// CFileManagerEngine::RestoreVolumeNameL() +// +// ----------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::RestoreVolumeNameL( TInt aDrive ) + { + FUNC_LOG; + + if ( IsInternalMassStorage( aDrive ) ) + { + TFileName volumeName; + CRepository* cenRep = CRepository::NewLC( KCRUidFileManagerSettings ); + TFileManagerVolumeNameStore volumeStore; + TFileManagerVolumeNameStorePckg volumeStorePckg( volumeStore ); + TInt err( cenRep->Get( + KFileManagerStoredInternalMassStorageVolumeName, volumeStorePckg ) ); + if ( err == KErrNone && volumeStore.iDrive == aDrive ) + { + volumeName.Copy( volumeStore.iName ); + } + if ( !volumeName.Length() ) + { + User::LeaveIfError( cenRep->Get( + KFileManagerDefaultInternalMassStorageVolumeName, volumeName ) ); + } + if ( volumeName.Length() > 0 ) + { + User::LeaveIfError( iFs.SetVolumeLabel( volumeName, aDrive ) ); + } + CleanupStack::PopAndDestroy( cenRep ); + INFO_LOG2( + "FileManagerRemovableDriveHandler::RestoreVolumeNameL-drive=%d,name=%S", + aDrive, &volumeName ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::ListArchivesL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::ListArchivesL( + RPointerArray< CMMCScBkupArchiveInfo >& aArchives, + const CFileManagerBackupSettings& aBackupSettings ) + { + aArchives.ResetAndDestroy(); + TResourceReader driveReader; + CCoeEnv::Static()->CreateResourceReaderLC( + driveReader, + R_FILEMANAGER_BACKUP_RESTORE_DRIVES_AND_OPERATIONS ); + CMMCScBkupOpParamsRestoreFull* params = + CMMCScBkupOpParamsRestoreFull::NewL( + driveReader, EBUCatAllSeparately ); + CleanupStack::PopAndDestroy(); // driveReader + CleanupStack::PushL( params ); + iBkupEngine->ListArchivesL( + aArchives, params, aBackupSettings.AllowedDriveAttMatchMask() ); + CleanupStack::PopAndDestroy( params ); + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::LatestBackupTimeL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::LatestBackupTimeL( + TTime& aBackupTime ) + { + aBackupTime = 0; + CFileManagerBackupSettings& bkupSettings( iEngine.BackupSettingsL() ); + RPointerArray< CMMCScBkupArchiveInfo > archives; + TCleanupItem cleanupItem( ResetAndDestroyArchives, &archives ); + CleanupStack::PushL( cleanupItem ); + ListArchivesL( archives, bkupSettings ); + + // Find the latest archive + TBool found( EFalse ); + TInt count( archives.Count() ); + for( TInt i( 0 ); i < count; ++i ) + { + TTime time( archives[ i ]->DateTime() ); + if ( time > aBackupTime ) + { + aBackupTime = time; + found = ETrue; + } + } + CleanupStack::PopAndDestroy( &archives ); + if ( !found ) + { + User::Leave( KErrNotFound ); + } + } + +// --------------------------------------------------------------------------- +// CFileManagerRemovableDriveHandler::DeleteBackupsL +// --------------------------------------------------------------------------- +// +void CFileManagerRemovableDriveHandler::DeleteBackupsL() + { + CFileManagerBackupSettings& bkupSettings( iEngine.BackupSettingsL() ); + RPointerArray< CMMCScBkupArchiveInfo > archives; + TCleanupItem cleanupItem( ResetAndDestroyArchives, &archives ); + CleanupStack::PushL( cleanupItem ); + ListArchivesL( archives, bkupSettings ); + + // Get the user set selection + RArray< CFileManagerRestoreSettings::TInfo > selection; + CleanupClosePushL( selection ); + CFileManagerRestoreSettings& rstSettings( iEngine.RestoreSettingsL() ); + rstSettings.GetSelectionL( selection ); + + // Delete selected archives + TInt archivesCount( archives.Count() ); + for ( TInt i( 0 ); i < archivesCount; ++i ) + { + CMMCScBkupArchiveInfo* archiveInfo = archives[ i ]; + TUint32 fmgrContent( + BkupToFmgrMask( archiveInfo->Category().iFlags ) ); + TInt drive( archiveInfo->Drive() ); + TInt selectionCount( selection.Count() ); + for( TInt j( 0 ); j < selectionCount; ++j ) + { + const CFileManagerRestoreSettings::TInfo& info( selection[ j ] ); + if ( ( drive == info.iDrive ) && ( fmgrContent & info.iContent ) ) + { + TPtrC fullPath( archiveInfo->FileName() ); + User::LeaveIfError( + CFileManagerUtils::RemoveReadOnlyAttribute( + iFs, fullPath ) ); + User::LeaveIfError( iFs.Delete( fullPath ) ); + selection.Remove( j ); // Do not check again + break; + } + } + } + CleanupStack::PopAndDestroy( &selection ); + CleanupStack::PopAndDestroy( &archives ); + } + + +// End of File