--- a/filemanager/Engine/src/CFileManagerActiveExecute.cpp Tue Feb 02 00:03:31 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1178 +0,0 @@
-/*
-* Copyright (c) 2002-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: Handles the copy/move operation
-*
-*/
-
-
-// INCLUDE FILES
-#include <bautils.h>
-//#include <cmgxfilemanager.h>
-//#include <mgxfilemanagerfactory.h>
-#include "CFileManagerActiveExecute.h"
-#include "MFileManagerProcessObserver.h"
-#include "CFileManagerEngine.h"
-#include "CFileManagerFileSystemIterator.h"
-#include "Cfilemanagerindexiterator.h"
-#include "CFileManagerCommonDefinitions.h"
-#include "CFileManagerUtils.h"
-#include "FileManagerDebug.h"
-#include "CFileManagerThreadWrapper.h"
-
-// CONSTANTS
-const TInt KFileManagerNotificationArrayGranularity = 64;
-
-// ============================ MEMBER FUNCTIONS ===============================
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::NewL
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C CFileManagerActiveExecute* CFileManagerActiveExecute::NewL(
- CFileManagerEngine& aEngine,
- MFileManagerProcessObserver::TFileManagerProcess aOperation,
- MFileManagerProcessObserver& aObserver,
- CArrayFixFlat<TInt>& aIndexList,
- const TDesC& aToFolder )
- {
- CFileManagerActiveExecute* self =
- new( ELeave ) CFileManagerActiveExecute(
- aEngine,
- aOperation,
- aObserver );
- CleanupStack::PushL( self );
- self->ConstructL( aIndexList, aToFolder );
- CleanupStack::Pop( self );
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::~CFileManagerActiveExecute
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C CFileManagerActiveExecute::~CFileManagerActiveExecute()
- {
- Cancel();
- delete iThreadWrapper;
- delete iItemIterator;
- delete iFullPath;
- delete iDestination;
- delete iToFolder;
- delete iIndexList;
- delete iChangedSrcItems;
- delete iChangedDstItems;
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ExecuteL
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C void CFileManagerActiveExecute::ExecuteL( TFileManagerSwitch aOverWrite )
- {
- TInt error( KErrNone );
-
- if ( iCancelled )
- {
- TFileName newName;
- TParsePtrC parse( *iFullPath );
- if ( parse.NameOrExtPresent() )
- {
- newName.Copy( parse.NameAndExt() );
- }
- else
- {
- TPtrC name( iEngine.LocalizedName( *iFullPath ) );
- if ( name.Length() > 0 )
- {
- newName.Copy( name );
- }
- else
- {
- newName = BaflUtils::FolderNameFromFullName( *iFullPath );
- }
- }
- iObserver.ProcessFinishedL( iError, newName );
- return;
- }
-
- if ( aOverWrite == ENoOverWrite )
- {
- iItemIterator->CurrentL( &iSrc, &iDst, iItemType );
- }
-
- if ( ( iDst && iDst->Length() > KMaxFileName ) || !iDst )
- {
- error = KErrBadName;
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, error );
- }
- else if ( iItemType == EFileManagerFile )
- {
-#ifdef __KEEP_DRM_CONTENT_ON_PHONE
- if ( iSrc && iDst &&
- CFileManagerUtils::IsFromInternalToRemovableDrive( iFs, *iSrc, *iDst ) )
- {
- TBool protectedFile( EFalse );
-
- // silently ignore this file if it is protected, or if there
- // was an error in checking.
- // Did consider leaving, but what about eg KErrNotFound - eg another
- // process moving/deleting the file...
- TInt ret( iEngine.IsDistributableFile( *iSrc, protectedFile ) );
- if( protectedFile || ret != KErrNone )
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrNone );
- SetActive();
- return;
- }
- }
-#endif
- DoOperation( aOverWrite );
- return;
- }
- else if ( iItemType == EFileManagerFolder )
- {
- if ( !iIsDstRemoteDrive && iEngine.IsNameFoundL( *iDst ) )
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrAlreadyExists );
- SetActive();
- return;
- }
- DoOperation( aOverWrite );
- return;
- }
- else
- {
- // We must complete this
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, error );
- }
- SetActive();
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::CancelExecution
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C void CFileManagerActiveExecute::CancelExecution()
- {
- FUNC_LOG
-
- iCancelled = ETrue;
-
- if ( iSrc )
- {
- iEngine.CancelTransfer( *iSrc );
- }
- if ( iDst )
- {
- iEngine.CancelTransfer( *iDst );
- }
- delete iThreadWrapper; // Cancel thread
- iThreadWrapper = NULL;
- Cancel();
- TRAP_IGNORE( CompleteL( KErrCancel ) );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::DoCancel
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::DoCancel()
- {
- iCancelled = ETrue;
-
- if ( iSrc )
- {
- iEngine.CancelTransfer( *iSrc );
- }
- if ( iDst )
- {
- iEngine.CancelTransfer( *iDst );
- }
- delete iThreadWrapper; // Cancel thread
- iThreadWrapper = NULL;
- }
-
-// ------------------------------------------------------------------------------
-// CFileManagerActiveExecute::KErrNoneAction
-//
-// ------------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::KErrNoneActionL()
- {
- UpdateNotifications( EFalse, KErrNone );
- if ( iItemIterator->NextL() )
- {
- ExecuteL( ENoOverWrite );
- }
- else
- {
- if ( iOperation == MFileManagerProcessObserver::EMoveProcess &&
- iEngine.IsFolder( iIndexList->At( 0 ) ) )
- {
- if ( !iFinalizeMove )
- {
- // Finalize move in the thread, the finalizing way take time
- iFinalizeMove = ETrue;
- DoOperation( ENoOverWrite );
- return;
- }
- }
- UpdateNotifications( ETrue, KErrNone );
- iObserver.ProcessFinishedL( KErrNone );
- }
-
- }
-
-// ------------------------------------------------------------------------------
-// CFileManagerActiveExecute::KErrAlreadyExistsAction
-//
-// ------------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::KErrAlreadyExistsActionL()
- {
- TParsePtrC dstParse( *iDst );
- HBufC* name = HBufC::NewLC( KMaxFileName );
- TPtr ptrName( name->Des() );
- TBool doContinue( EFalse );
-
- // Depending on target file can it be delete, we ask overwrite or rename.
- // If source and target is same, then rename is only possible choice.
- if ( iItemType == EFileManagerFile && iEngine.CanDelete( *iDst ) && iSrc->FindF( *iDst ) )
- {
- if ( iObserver.ProcessQueryOverWriteL( *iDst, ptrName, iOperation ) )
- {
- ExecuteL( EOverWrite );
- }
- else
- {
- // user does not want to overwrite item and ptrName should now contain
- // user given new name
- if ( ptrName.Length() > 0 )
- {
- ptrName.Insert( 0, dstParse.DriveAndPath() );
- if ( !iDst->CompareF( ptrName ) )
- {
- DoOperation( ENoOverWrite );
- }
- else
- {
- iDst->Des().Copy( ptrName );
- // Overwrite, because user already queried by overwrite
- DoOperation( EOverWrite );
- }
- }
- else
- {
- // User is not willing to rename item, continue current operation
- doContinue = ETrue;
- }
- }
- }
- else
- {
- // item can't be overwrite
- if ( iObserver.ProcessQueryRenameL( *iDst, ptrName, iOperation ) )
- {
- if ( ptrName.Length() > 0 )
- {
- if ( iItemType == EFileManagerFile )
- {
- ptrName.Insert( 0, dstParse.DriveAndPath() );
- iDst->Des().Copy( ptrName );
- }
- else if ( iItemType == EFileManagerFolder )
- {
- TPtr ptr( iDst->Des() );
- AddLastFolder( ptr, ptrName, *iToFolder );
- iDestination->Des().Copy( ptr );
- }
- // Overwrite, because user already queried by rename
- ExecuteL( EOverWrite );
- }
- else if ( iItemType == EFileManagerFolder )
- {
- iCancelled = ETrue;
- iError = KErrCancel;
- ExecuteL( ENoOverWrite );
- }
- else
- {
- // User is not willing to rename item, continue current operation
- doContinue = ETrue;
- }
- }
- else if ( iItemType == EFileManagerFolder )
- {
- iCancelled = ETrue;
- iError = KErrCancel;
- ExecuteL( ENoOverWrite );
- }
- else
- {
- // User is not willing to rename item, continue current operation
- doContinue = ETrue;
- }
- }
-
- CleanupStack::PopAndDestroy( name );
-
- if ( doContinue )
- {
- if ( iItemIterator->NextL() )
- {
- ExecuteL( ENoOverWrite );
- }
- else
- {
- UpdateNotifications( ETrue, KErrNone );
- iObserver.ProcessFinishedL( KErrNone );
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::RunL
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::RunL()
- {
- CompleteL( iStatus.Int() );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::CompleteL
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::CompleteL( TInt aError )
- {
- if ( iCancelled || !iItemIterator )
- {
- UpdateNotifications( ETrue, iError );
- TParsePtrC parse( CFileManagerUtils::StripFinalBackslash(
- *iDestination ) );
- if ( parse.NameOrExtPresent() )
- {
- iObserver.ProcessFinishedL( iError, parse.NameAndExt() );
- }
- else if ( parse.DrivePresent() )
- {
- iObserver.ProcessFinishedL( iError, parse.Drive() );
- }
- else
- {
- iObserver.ProcessFinishedL( iError );
- }
- return;
- }
-
- // Symbian returns KErrNone if source and destination
- // in moving is same. Here we have to treat it as error.
- if( iSrc && iDst )
- {
- if ( !iSrc->CompareF( *iDst ) && aError == KErrNone )
- {
- aError = KErrInUse;
- }
- }
-
- ERROR_LOG1( "CFileManagerActiveExecute::CompleteL()-aError=%d", aError )
-
- switch ( aError )
- {
- case KErrNone:
- {
- KErrNoneActionL();
- break;
- }
- case KErrAlreadyExists:
- {
- KErrAlreadyExistsActionL();
- break;
- }
- case KErrCancel: // Suppressed errors
- {
- UpdateNotifications( ETrue, KErrNone );
- iObserver.ProcessFinishedL( KErrNone );
- break;
- }
- default:
- {
- if ( iSrc )
- {
- // Try rename when moving and the target file exists and is in use
- if ( iOperation == MFileManagerProcessObserver::EMoveProcess &&
- aError == KErrInUse &&
- iDst &&
- iEngine.CanDelete( *iSrc ) &&
- iEngine.IsNameFoundL( *iDst ) )
- {
- KErrAlreadyExistsActionL();
- }
- else
- {
- UpdateNotifications( ETrue, aError );
- TParsePtrC parse( *iSrc );
- iObserver.ProcessFinishedL( aError, parse.NameAndExt() );
- }
- }
- else
- {
- UpdateNotifications( ETrue, aError );
- iObserver.ProcessFinishedL( aError );
- }
- break;
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::RunError
-//
-// -----------------------------------------------------------------------------
-//
-TInt CFileManagerActiveExecute::RunError(TInt aError)
- {
- return aError;
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::CFileManagerActiveExecute
-//
-// -----------------------------------------------------------------------------
-//
-CFileManagerActiveExecute::CFileManagerActiveExecute(
- CFileManagerEngine& aEngine,
- MFileManagerProcessObserver::TFileManagerProcess aOperation,
- MFileManagerProcessObserver& aObserver ) :
- CActive( CActive::EPriorityLow ), // Use low to avoid progress note mess up
- iEngine( aEngine ),
- iFs( aEngine.Fs() ),
- iOperation( aOperation ),
- iObserver( aObserver )
- {
- CActiveScheduler::Add( this );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ConstructL
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::ConstructL( CArrayFixFlat<TInt>& aIndexList,
- const TDesC& aToFolder )
- {
- iChangedSrcItems = new( ELeave ) CDesCArrayFlat(
- KFileManagerNotificationArrayGranularity );
- iChangedDstItems = new( ELeave ) CDesCArrayFlat(
- KFileManagerNotificationArrayGranularity );
-
- iToFolder = aToFolder.AllocL();
- TInt count( aIndexList.Count() );
- iIndexList = new( ELeave ) CArrayFixFlat< TInt >( count );
- for( TInt i( 0 ); i < count; ++i )
- {
- // make own copy of index list because caller may
- // destroy the original one.
- iIndexList->AppendL( aIndexList.At( i ) );
- }
-
- TInt index( iIndexList->At( iCurrentIndex ) );
-
- iFullPath = iEngine.IndexToFullPathL( index );
-
- TBool isDirectory( iEngine.IsFolder( index ) );
-
- iDestination = HBufC::NewL( KFmgrDoubleMaxFileName );
-
- if ( isDirectory )
- {
- TPtr ptr( iDestination->Des() );
- AddLastFolder( ptr, *iFullPath, *iToFolder );
- }
- else
- {
- iDestination->Des().Copy( aToFolder );
- }
-
- // Check that we are not copying/moving folder to inside it ( recursive copy )
- if ( isDirectory && !iDestination->FindF( *iFullPath ) &&
- iDestination->Length() > iFullPath->Length() )
- {
- iCancelled = ETrue;
- iError = KErrAccessDenied;
- }
- // Is destination path too long for file system
- else if ( iDestination->Length() > KMaxFileName )
- {
- iCancelled = ETrue;
- iError = KErrBadName;
- }
- else if ( isDirectory )
- {
- iItemIterator = CFileManagerFileSystemIterator::NewL(
- iFs, *iFullPath, *iDestination, iEngine );
- }
- else
- {
- iItemIterator = CFileManagerIndexIterator::NewL(
- iEngine, aIndexList, *iDestination );
- }
-
- // MG2 notification object
- //iMgxFileManager = &iEngine.MGXFileManagerL();
-
- // Check are operation source and target on the same drive
- TParsePtrC srcParse( *iFullPath );
- TParsePtrC dstParse( *iDestination );
- TPtrC srcDrv( srcParse.Drive() );
- TPtrC dstDrv( dstParse.Drive() );
- iOperationOnSameDrive = !( srcDrv.CompareF( dstDrv ) );
- iIsSrcRemoteDrive = CFileManagerUtils::IsRemoteDrive( iFs, srcDrv );
- iIsDstRemoteDrive = CFileManagerUtils::IsRemoteDrive( iFs, dstDrv );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::AddLastFolder
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::AddLastFolder( TDes& aResult,
- const TDesC& aSrc,
- const TDesC& aDst )
- {
- TInt lastBackslash = aSrc.LocateReverse( KFmgrBackslash()[0] );
- if ( lastBackslash != KErrNotFound )
- {
- // source is full path
- aResult.Copy( aSrc.Left( lastBackslash - 1 ) );
- // Last backslash is now temporary removed check next last backslash
- TInt secondLastBackslash( aResult.LocateReverse( KFmgrBackslash()[0] ) );
- // Now we know the coordinates of the last path
- aResult.Copy( iEngine.LocalizedName( aSrc ) );
- if ( aResult.Length() > 0 )
- {
- aResult.Insert( 0, aDst );
- aResult.Append( KFmgrBackslash );
- }
- else
- {
- aResult.Append( aDst );
- // Skip '\\'
- TInt startingPoint( secondLastBackslash + 1 );
- aResult.Append( aSrc.Mid( startingPoint,
- lastBackslash - secondLastBackslash ) );
- }
- }
- else
- {
- // source is only one folder name
- aResult.Copy( aDst );
- aResult.Append( aSrc );
- aResult.Append( KFmgrBackslash );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::DoOperation
-//
-// -----------------------------------------------------------------------------
-//
-TInt CFileManagerActiveExecute::DoOperation( TInt aSwitch )
- {
- // Source and destination must be different
- if ( iSrc && iDst && !iDst->CompareF( *iSrc ) )
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrAlreadyExists );
- SetActive();
- return KErrAlreadyExists;
- }
- TInt err( KErrNone );
-
- iSwitch = aSwitch;
-
- if ( !iThreadWrapper )
- {
- TRAP( err, iThreadWrapper = CFileManagerThreadWrapper::NewL() );
- if ( err != KErrNone )
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, err );
- SetActive();
- return err;
- }
- }
- if ( iThreadWrapper->IsThreadStarted() )
- {
- iThreadWrapper->ResumeThread();
- }
- else
- {
- err = iThreadWrapper->StartThread(
- *this, ENotifyStepFinished, EPriorityLess );
- if ( err != KErrNone )
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, err );
- SetActive();
- return err;
- }
- }
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::IsEmptyDir
-//
-// -----------------------------------------------------------------------------
-//
-TBool CFileManagerActiveExecute::IsEmptyDir( const TDesC& aDir )
- {
- return !CFileManagerUtils::HasAny(
- iFs, aDir, KEntryAttMatchMask | KEntryAttNormal );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ThreadCopyOrMoveStepL()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::ThreadCopyOrMoveStepL()
- {
- FUNC_LOG
-
- INFO_LOG2( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-%S=>%S",
- iSrc, iDst )
-
- TInt err( KErrNone );
-
- if ( iItemType == EFileManagerFolder )
- {
- // Handle folders
- err = iFs.MkDir( *iDst ); // Try faster way first
- LOG_IF_ERROR1(
- err,
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-MkDir,err=%d",
- err )
- if ( err != KErrNone && err != KErrCancel )
- {
- err = iFs.MkDirAll( *iDst );
- LOG_IF_ERROR1(
- err,
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-MkDirAll,err=%d",
- err )
- }
- if ( err == KErrNone )
- {
- TEntry entry;
- err = iFs.Entry( *iSrc, entry );
- if ( err == KErrNone )
- {
- iFs.SetEntry( *iDst, entry.iModified, entry.iAtt, 0 ); // Ignore error
- }
- }
- User::LeaveIfError( err );
- return;
- }
-
- // Handle files
- if ( iOperationOnSameDrive &&
- iOperation == MFileManagerProcessObserver::EMoveProcess )
- {
- INFO_LOG(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-MoveInsideDrive" )
-
- if ( iSwitch == EOverWrite )
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-Overwrite" )
-
- err = iFs.Replace( *iSrc, *iDst );
- }
- else
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-NoOverwrite" )
-
- err = iFs.Rename( *iSrc, *iDst );
- }
-
- LOG_IF_ERROR1(
- err,
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-OnSameDrive,err=%d",
- err )
-
- if ( err == KErrNone || err == KErrCancel )
- {
- // Optimized move was successful or cancelled
- User::LeaveIfError( err );
- // If move the files in the same drive, the application
- // just calculate the amount of the files, so it should
- // notify the observer that how many files have been moved.
- iBytesTransferredTotal++;
- TRAP_IGNORE( iObserver.ProcessAdvanceL(
- iBytesTransferredTotal ) );
- return;
- }
- }
-
- TInt64 fileSize( 0 );
- RFile64 srcFile;
-
- // Open source file
- if ( iOperation == MFileManagerProcessObserver::EMoveProcess )
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-Move" )
-
- User::LeaveIfError( srcFile.Open(
- iFs, *iSrc, EFileRead | EFileShareExclusive ) );
- }
- else
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-Copy" )
-
- User::LeaveIfError( srcFile.Open(
- iFs, *iSrc, EFileRead | EFileShareReadersOnly ) );
- }
- CleanupClosePushL( srcFile );
- User::LeaveIfError( srcFile.Size( fileSize ) );
-
- // Open destination file
- RFile64 dstFile;
- if ( iSwitch == EOverWrite )
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-Overwrite" )
-
- User::LeaveIfError( dstFile.Replace(
- iFs, *iDst, EFileWrite | EFileShareExclusive ) );
- }
- else
- {
- INFO_LOG( "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-NoOverwrite" )
-
- User::LeaveIfError( dstFile.Create(
- iFs, *iDst, EFileWrite | EFileShareExclusive ) );
- }
- CleanupClosePushL( dstFile );
-
- dstFile.SetSize( fileSize ); // Setting the size first speeds up operation
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-FileSize=%d",
- fileSize )
-
- // Create buffer and copy file data using it.
- // Note that buffer size should not be too big to make it is possible
- // to cancel the operation in reasonable time from the main thread.
-
- // Move these to CenRep to make configuration and fine tuning easier.
- const TInt64 KBigBufSize = 0x40000; // 256KB
- const TInt64 KMediumBufSize = 0x10000; // 64KB
- const TInt64 KSmallBufSize = 0x2000; // 8KB
-
- HBufC8* buf = HBufC8::New(
- Max( KSmallBufSize, Min( fileSize, KBigBufSize ) ) );
- if ( !buf )
- {
- buf = HBufC8::New( KMediumBufSize );
- }
- if ( !buf )
- {
- buf = HBufC8::New( KSmallBufSize );
- }
- if ( !buf )
- {
- User::Leave( KErrNoMemory );
- }
- CleanupStack::PushL( buf );
-
- TPtr8 block( buf->Des() );
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-BlockSize=%d",
- block.MaxSize() )
-
- while ( err == KErrNone && fileSize > 0 )
- {
- if ( iThreadWrapper->IsThreadCanceled() )
- {
- err = KErrCancel;
- break;
- }
- TInt blockSize( Min( fileSize, static_cast<TInt64>(block.MaxSize() ) ) );
- err = srcFile.Read( block, blockSize );
- if ( err == KErrNone )
- {
- if ( block.Length() == blockSize )
- {
- err = dstFile.Write( block, blockSize );
- if ( err == KErrNone )
- {
- fileSize -= blockSize;
-
- // Do not update the latest file transfer progress here.
- // Flushing file below may take a long time and
- // progress indicator should not get full before it.
- TRAP_IGNORE( iObserver.ProcessAdvanceL(
- iBytesTransferredTotal ) );
- iBytesTransferredTotal += blockSize;
- }
- }
- else
- {
- err = KErrCorrupt;
- }
- }
- }
-
- INFO_LOG2(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-BytesNotWritten=%d,err=%d",
- fileSize, err )
-
- CleanupStack::PopAndDestroy( buf );
-
- // Copy attributes
- TTime mod;
- if ( err == KErrNone )
- {
- err = srcFile.Modified( mod );
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-ModifiedRead,err=%d",
- err )
-
- }
- if ( err == KErrNone )
- {
- err = dstFile.SetModified( mod );
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-ModifiedWritten,err=%d",
- err )
- }
- TUint att( 0 );
- if ( err == KErrNone )
- {
- err = srcFile.Att( att );
-
- INFO_LOG2(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-AttributesRead,err=%d,att=%d",
- err, att )
- }
- if ( err == KErrNone )
- {
- // Ignore fail, because some drives like remote drives
- // do not support attributes at all
- dstFile.SetAtt( att, ( ~att ) & KEntryAttMaskSupported );
-
- INFO_LOG(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-AttributesWritten" )
- }
- // Flush file and finalize transfer progress of this file.
- // Don't flush if copying failed because it causes save dialog to appear
- // when remote drives are involved.
- if ( err == KErrNone )
- {
- err = dstFile.Flush();
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-Flushed,err=%d",
- err )
- }
- TRAP_IGNORE( iObserver.ProcessAdvanceL( iBytesTransferredTotal ) );
-
- CleanupStack::PopAndDestroy( &dstFile );
- CleanupStack::PopAndDestroy( &srcFile );
-
- // Delete source if move was succesful so far
- if ( err == KErrNone &&
- iOperation == MFileManagerProcessObserver::EMoveProcess )
- {
- // Ensure that read-only is removed before delete
- if ( att & KEntryAttReadOnly )
- {
- CFileManagerUtils::RemoveReadOnlyAttribute( iFs, *iSrc );
- }
- err = iFs.Delete( *iSrc );
-
- INFO_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-MoveSourceDeleted,err=%d",
- err )
- }
-
- // Delete incomplete destination if error
- if ( err != KErrNone )
- {
- // Ensure that read-only is removed before delete
- if ( att & KEntryAttReadOnly )
- {
- CFileManagerUtils::RemoveReadOnlyAttribute( iFs, *iDst );
- }
- iFs.Delete( *iDst );
-
- ERROR_LOG1(
- "CFileManagerActiveExecute::ThreadCopyOrMoveStepL-FailedDstDeleted,fail=%d",
- err )
- }
-
- User::LeaveIfError( err );
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::IsThreadDone()
-//
-// -----------------------------------------------------------------------------
-//
-TBool CFileManagerActiveExecute::IsThreadDone()
- {
- return EFalse;
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::NotifyThreadClientL()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::NotifyThreadClientL(
- TNotifyType aType, TInt aValue )
- {
- switch ( aType )
- {
- case ENotifyStepFinished:
- {
- CompleteL( aValue );
- break;
- }
- default:
- {
- break;
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::AppendArrayIfNotFound()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::AppendArrayIfNotFound(
- CDesCArray& aArray, const TDesC& aFullPath )
- {
- // Append if not already appended to the last item
- TBool append( ETrue );
- TInt count( aArray.MdcaCount() );
- if ( count > 0 )
- {
- TPtrC ptr( aArray.MdcaPoint( count - 1 ) );
- if ( !ptr.Compare( aFullPath ) )
- {
- append = EFalse;
- }
- }
- if ( append )
- {
- TRAPD( err, aArray.AppendL( aFullPath ) );
- if ( err != KErrNone )
- {
- ERROR_LOG1(
- "CFileManagerActiveExecute::AppendArrayIfNotFound-err=%d",
- err )
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::FlushArray()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::FlushArray( CDesCArray& aArray )
- {
- if ( aArray.MdcaCount() > 0 )
- {
-// TRAP_IGNORE( iMgxFileManager->UpdateL( aArray ) );
- aArray.Reset();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::UpdateNotifications()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::UpdateNotifications(
- TBool aFlush, TInt aError )
- {
- // Append notification item if operation was successful and
- // item does not already exist
- if ( aError == KErrNone && iSrc && iDst && iItemType == EFileManagerFile )
- {
- // Notifications are relevant only for local drives
- if ( iOperation == MFileManagerProcessObserver::EMoveProcess &&
- !iIsSrcRemoteDrive )
- {
- AppendArrayIfNotFound( *iChangedSrcItems, *iSrc );
- }
- if ( !iIsDstRemoteDrive )
- {
- AppendArrayIfNotFound( *iChangedDstItems, *iDst );
- }
- }
- if ( aFlush )
- {
- FlushArray( *iChangedSrcItems );
- FlushArray( *iChangedDstItems );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ThreadFinalizeMoveStepL()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::ThreadFinalizeMoveStepL()
- {
- FUNC_LOG
-
- HBufC* folderToDelete = HBufC::NewLC( KMaxFileName );
- TPtr ptrFolderToDelete( folderToDelete->Des() );
- CDirScan* dirScan = CDirScan::NewLC( iFs );
- dirScan->SetScanDataL(
- *iFullPath,
- KEntryAttNormal|KEntryAttHidden|KEntryAttSystem|
- KEntryAttDir|KEntryAttMatchExclusive,
- ESortNone,
- CDirScan::EScanUpTree );
- CDir* dir = NULL;
- dirScan->NextL( dir );
- while( dir )
- {
- CFileManagerUtils::RemoveReadOnlyAttribute(
- iFs, dirScan->FullPath() );
- CleanupStack::PushL( dir );
- TInt count( dir->Count() );
- for( TInt i( 0 ); i < count; ++i )
- {
- if ( iThreadWrapper->IsThreadCanceled() )
- {
- User::Leave( KErrCancel );
- }
- TPtrC abbrPath( dirScan->AbbreviatedPath() );
- const TEntry& entry( ( *dir )[ i ] );
- ptrFolderToDelete.Copy( *iFullPath );
- ptrFolderToDelete.Append(
- abbrPath.Right( abbrPath.Length() - 1 ) );
- ptrFolderToDelete.Append( entry.iName );
- ptrFolderToDelete.Append( KFmgrBackslash );
-#ifdef __KEEP_DRM_CONTENT_ON_PHONE
- if ( iSrc && iDst &&
- CFileManagerUtils::IsFromInternalToRemovableDrive( iFs, *iSrc, *iDst ) )
- {
- HBufC* targetFolderToDelete = HBufC::NewLC( KMaxFileName );
- TPtr ptrTargetFolderToDelete( targetFolderToDelete->Des() );
- ptrTargetFolderToDelete.Append( *iDestination );
- ptrTargetFolderToDelete.Append(
- abbrPath.Right( abbrPath.Length() - 1 ) );
- ptrTargetFolderToDelete.Append( entry.iName );
- ptrTargetFolderToDelete.Append( KFmgrBackslash );
-
- if ( IsEmptyDir( ptrFolderToDelete ) )
- {
- User::LeaveIfError( iFs.RmDir( ptrFolderToDelete ) );
- }
- else if ( IsEmptyDir( ptrTargetFolderToDelete ))
- {
- User::LeaveIfError( iFs.RmDir( ptrTargetFolderToDelete ) );
- }
- CleanupStack::PopAndDestroy( targetFolderToDelete );
- }
- else
- {
- User::LeaveIfError( iFs.RmDir( ptrFolderToDelete ) );
- }
-#else
- User::LeaveIfError( iFs.RmDir( ptrFolderToDelete ) );
-#endif
- }
- if ( iThreadWrapper->IsThreadCanceled() )
- {
- User::Leave( KErrCancel );
- }
- CleanupStack::PopAndDestroy( dir );
- dir = NULL;
- dirScan->NextL( dir );
- }
- CleanupStack::PopAndDestroy( dirScan );
- CleanupStack::PopAndDestroy( folderToDelete );
-#ifdef __KEEP_DRM_CONTENT_ON_PHONE
- if ( iSrc && iDst &&
- CFileManagerUtils::IsFromInternalToRemovableDrive( iFs, *iSrc, *iDst ) )
- {
- if ( IsEmptyDir( *iFullPath ) )
- {
- User::LeaveIfError( iFs.RmDir( *iFullPath ) );
- }
- }
- else
- {
- User::LeaveIfError( iFs.RmDir( *iFullPath ) );
- }
-#else
- User::LeaveIfError( iFs.RmDir( *iFullPath ) );
-#endif
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ThreadStepL()
-//
-// -----------------------------------------------------------------------------
-//
-void CFileManagerActiveExecute::ThreadStepL()
- {
- FUNC_LOG
-
- if ( !iFinalizeMove )
- {
- ThreadCopyOrMoveStepL();
- }
- else
- {
- ThreadFinalizeMoveStepL();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CFileManagerActiveExecute::ToFolder()
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C TPtrC CFileManagerActiveExecute::ToFolder()
- {
- if ( iToFolder )
- {
- return iToFolder->Des();
- }
- return TPtrC( KNullDesC );
- }
-
-// End of File