diff -r 3673b591050c -r ef55b168cedb mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp --- a/mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp Wed Apr 14 16:49:36 2010 +0300 +++ b/mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp Tue Apr 27 17:30:23 2010 +0300 @@ -23,6 +23,7 @@ #include #include +#include "cmtpfsentrycache.h" #include "cmtpstoragemgr.h" #include "cmtpmoveobject.h" #include "mtpdppanic.h" @@ -61,12 +62,17 @@ Destructor */ EXPORT_C CMTPMoveObject::~CMTPMoveObject() - { + { + Cancel(); + iDpSingletons.Close(); + iSingletons.Close(); + + delete iTimer; + delete iNewFileName; delete iDest; delete iFileMan; delete iPathToMove; - delete iNewRootFolder; - iSingletons.Close(); + delete iNewRootFolder; __FLOG_CLOSE; } @@ -75,7 +81,7 @@ */ CMTPMoveObject::CMTPMoveObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) : CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPMoveObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPMoveObjectPolicy), - iMoveObjectIndex(0) + iMoveObjectIndex(0), iTimer(NULL) { __FLOG_OPEN(KMTPSubsystem, KComponent); } @@ -104,6 +110,21 @@ result = EMTPRespCodeStoreReadOnly; } + if(result == EMTPRespCodeOK) + { + const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid)); + iIsFolder = EFalse; + User::LeaveIfError(BaflUtils::IsFolder(iFramework.Fs(), suid, iIsFolder)); + if(!iIsFolder) + { + if(iDpSingletons.MovingBigFileCache().IsOnGoing()) + { + __FLOG(_L8("CheckRequestL - A big file moving is ongoing, respond with access denied")); + result = EMTPRespCodeAccessDenied; + } + } + } + __FLOG(_L8("CheckRequestL - Exit")); return result; } @@ -112,7 +133,8 @@ MoveObject request handler */ void CMTPMoveObject::ServiceL() - { + { + __FLOG(_L8("ServiceL - Entry")); TMTPResponseCode ret = EMTPRespCodeOK; TRAPD(err, ret = MoveObjectL()); if (err != KErrNone) @@ -123,6 +145,7 @@ { SendResponseL(ret); } + __FLOG(_L8("ServiceL - Exit")); } /** @@ -131,6 +154,7 @@ void CMTPMoveObject::ConstructL() { iSingletons.OpenL(); + iDpSingletons.OpenL(iFramework); } @@ -143,12 +167,38 @@ __FLOG(_L8("MoveFileL - Entry")); const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid)); GetPreviousPropertiesL(suid); - User::LeaveIfError(iFileMan->Move(suid, *iDest)); - SetPreviousPropertiesL(aNewFileName); - iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName); - iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); - iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle); - iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo); + + if(iFramework.StorageMgr().DriveNumber(iObjectInfo->Uint(CMTPObjectMetaData::EStorageId)) == + iFramework.StorageMgr().DriveNumber(iStorageId)) + //Move file to the same storage + { + User::LeaveIfError(iFileMan->Move(suid, *iDest)); + SetPreviousPropertiesL(aNewFileName); + iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName); + iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); + iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle); + iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo); + SendResponseL(EMTPRespCodeOK); + } + else + //Move file between different storages + { + delete iNewFileName; + iNewFileName = NULL; + iNewFileName = aNewFileName.AllocL(); // Store the new file name + + User::LeaveIfError(iFileMan->Move(suid, *iDest, CFileMan::EOverWrite, iStatus)); + if ( !IsActive() ) + { + SetActive(); + } + + delete iTimer; + iTimer = NULL; + iTimer = CPeriodic::NewL(EPriorityStandard); + TTimeIntervalMicroSeconds32 KMoveObjectIntervalNone = 0; + iTimer->Start(TTimeIntervalMicroSeconds32(KMoveObjectTimeOut), KMoveObjectIntervalNone, TCallBack(CMTPMoveObject::OnTimeoutL, this)); + } __FLOG(_L8("MoveFileL - Exit")); } @@ -206,10 +256,7 @@ TParsePtrC fileNameParser(suid); // Check if the object is a folder or a file. - TBool isFolder = EFalse; - User::LeaveIfError(BaflUtils::IsFolder(iFramework.Fs(), suid, isFolder)); - - if(!isFolder) + if(!iIsFolder) { if((newObjectName.Length() + fileNameParser.NameAndExt().Length()) <= newObjectName.MaxLength()) { @@ -239,10 +286,9 @@ iFileMan = NULL; iFileMan = CFileMan::NewL(iFramework.Fs()); - if(!isFolder) + if(!iIsFolder) { MoveFileL(newObjectName); - SendResponseL(responseCode); } else { @@ -347,7 +393,129 @@ __FLOG(_L8("SetPreviousPropertiesL - Exit")); } +/** + Call back function, called when the timer expired for big file moving. + Send response to initiator and cache the target file entry info, which is used to send response + to getobjectproplist and getobjectinfo. +*/ +TInt CMTPMoveObject::OnTimeoutL(TAny* aPtr) + { + CMTPMoveObject* moveObjectProcessor = static_cast(aPtr); + moveObjectProcessor->DoOnTimeoutL(); + return KErrNone; + } +void CMTPMoveObject::DoOnTimeoutL() + { + __FLOG(_L8("DoOnTimeoutL - Entry")); + + if (iTimer) + { + if (iTimer->IsActive()) + { + iTimer->Cancel(); + } + delete iTimer; + iTimer = NULL; + } + + const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid)); + TEntry fileEntry; + User::LeaveIfError(iFramework.Fs().Entry(suid, fileEntry)); + TUint32 handle = iObjectInfo->Uint(CMTPObjectMetaData::EHandle); + + iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, *iNewFileName); + iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); + iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle); + iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo); + + CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache(); + + // Cache the target file entry info, which is used to send response to getobjectproplist and getobjectinfo + aCache.SetOnGoing(ETrue); + aCache.SetTargetHandle(handle); + aCache.SetFileEntry(fileEntry); + + __FLOG(_L8("UpdateFSEntryCache, sending response with respond code OK for a big file move")); + SendResponseL(EMTPRespCodeOK); + + __FLOG(_L8("DoOnTimeoutL - Exit")); + } +/** + CMTPMoveObject::RunL +*/ +void CMTPMoveObject::RunL() + { + __FLOG(_L8("RunL - Entry")); + + User::LeaveIfError(iStatus.Int()); + SetPreviousPropertiesL(*iNewFileName); + CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache(); + // Check to see if we are moving a big file + if(aCache.IsOnGoing()) + { + __FLOG(_L8("RunL - Big file move complete")); + aCache.SetOnGoing(EFalse); + aCache.SetTargetHandle(KMTPHandleNone); + } + else + { + //Cancel the timer + if(iTimer) + { + if(iTimer->IsActive()) + { + iTimer->Cancel(); + } + delete iTimer; + iTimer = NULL; + } + iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, *iNewFileName); + iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); + iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle); + iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo); + __FLOG(_L8("RunL, sending response with respond code OK for a normal file move")); + SendResponseL(EMTPRespCodeOK); + } + __FLOG(_L8("RunL - Exit")); + } + +/** +Override to handle the complete phase of move object +*/ +TBool CMTPMoveObject::DoHandleCompletingPhaseL() + { + CMTPRequestProcessor::DoHandleCompletingPhaseL(); + + CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache(); + if(aCache.IsOnGoing()) + { + return EFalse; + } + else + { + return ETrue; + } + } + +/** +Override to match MoveObject request +@param aRequest The request to match +@param aConnection The connection from which the request comes +@return ETrue if the processor can handle the request, otherwise EFalse +*/ +TBool CMTPMoveObject::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const + { + __FLOG(_L8("Match - Entry")); + TBool result = EFalse; + TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode); + if ((operationCode == EMTPOpCodeMoveObject) && &iConnection == &aConnection) + { + result = ETrue; + } + __FLOG_VA((_L8("Match -- Exit with result = %d"), result)); + return result; + }