diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,402 @@ +// Copyright (c) 2007-2009 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: +// + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "cmtpmoveobject.h" +#include "mtpdppanic.h" + + +__FLOG_STMT(_LIT8(KComponent,"MoveObject");) + +/** +Verification data for the MoveObject request +*/ +const TMTPRequestElementInfo KMTPMoveObjectPolicy[] = + { + {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeObjectHandle, EMTPElementAttrFileOrDir | EMTPElementAttrWrite, 0, 0, 0}, + {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeStorageId, EMTPElementAttrWrite, 0, 0, 0}, + {TMTPTypeRequest::ERequestParameter3, EMTPElementTypeObjectHandle, EMTPElementAttrDir | EMTPElementAttrWrite, 1, 0, 0} + }; + +/** +Two-phase construction method +@param aPlugin The data provider plugin +@param aFramework The data provider framework +@param aConnection The connection from which the request comes +@return a pointer to the created request processor object +*/ +EXPORT_C MMTPRequestProcessor* CMTPMoveObject::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) + { + CMTPMoveObject* self = new (ELeave) CMTPMoveObject(aFramework, aConnection); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +/** +Destructor +*/ +EXPORT_C CMTPMoveObject::~CMTPMoveObject() + { + delete iDest; + delete iFileMan; + delete iPathToMove; + delete iNewRootFolder; + __FLOG_CLOSE; + } + +/** +Standard c++ constructor +*/ +CMTPMoveObject::CMTPMoveObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) : + CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPMoveObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPMoveObjectPolicy), + iMoveObjectIndex(0) + { + __FLOG_OPEN(KMTPSubsystem, KComponent); + } + +/** +MoveObject request handler +*/ +void CMTPMoveObject::ServiceL() + { + TMTPResponseCode ret = MoveObjectL(); + if (EMTPRespCodeOK != ret) + { + SendResponseL(ret); + } + } + +/** + Second phase constructor +*/ +void CMTPMoveObject::ConstructL() + { + } + +void CMTPMoveObject::RunL() + { + __FLOG(_L8("RunL - Entry")); + SendResponseL( EMTPRespCodeOK ); + __FLOG(_L8("RunL - Exit")); + } + +TInt CMTPMoveObject::RunError(TInt /*aError*/) + { + TRAP_IGNORE(SendResponseL(EMTPRespCodeGeneralError)); + return KErrNone; + } + +/** +A helper function of MoveObjectL. +@param aNewFileName the new file name after the object is moved. +*/ +void CMTPMoveObject::MoveFileL(const TDesC& aNewFileName) + { + __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); + __FLOG(_L8("MoveFileL - Exit")); + } + +/** +A helper function of MoveObjectL. +@param aNewFolderName the new file folder name after the folder is moved. +*/ +void CMTPMoveObject::MoveFolderL() + { + __FLOG(_L8("MoveFolderL - Entry")); + + RBuf oldFolderName; + oldFolderName.CreateL(KMaxFileName); + oldFolderName.CleanupClosePushL(); + oldFolderName = iObjectInfo->DesC(CMTPObjectMetaData::ESuid); + iPathToMove = oldFolderName.AllocL(); + + if (iObjectInfo->Uint(CMTPObjectMetaData::EDataProviderId) == iFramework.DataProviderId()) + { + GetPreviousPropertiesL(oldFolderName); + // Remove backslash. + oldFolderName.SetLength(oldFolderName.Length() - 1); + SetPreviousPropertiesL(*iNewRootFolder); + _LIT(KBackSlash, "\\"); + oldFolderName.Append(KBackSlash); + + iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, *iNewRootFolder); + iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle); + iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); + iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo); + } + + CleanupStack::PopAndDestroy(); // oldFolderName. + + __FLOG(_L8("MoveFolderL - Exit")); + } + +/** +move object operations +@return A valid MTP response code. +*/ +TMTPResponseCode CMTPMoveObject::MoveObjectL() + { + __FLOG(_L8("MoveObjectL - Entry")); + TMTPResponseCode responseCode = EMTPRespCodeOK; + + GetParametersL(); + + RBuf newObjectName; + newObjectName.CreateL(KMaxFileName); + newObjectName.CleanupClosePushL(); + newObjectName = *iDest; + + const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid)); + 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((newObjectName.Length() + fileNameParser.NameAndExt().Length()) <= newObjectName.MaxLength()) + { + newObjectName.Append(fileNameParser.NameAndExt()); + } + responseCode = CanMoveObjectL(suid, newObjectName); + } + else // It is a folder. + { + TFileName rightMostFolderName; + User::LeaveIfError(BaflUtils::MostSignificantPartOfFullName(suid, rightMostFolderName)); + if((newObjectName.Length() + rightMostFolderName.Length() + 1) <= newObjectName.MaxLength()) + { + newObjectName.Append(rightMostFolderName); + // Add backslash. + _LIT(KBackSlash, "\\"); + newObjectName.Append(KBackSlash); + } + } + + iNewRootFolder = newObjectName.AllocL(); + __FLOG(*iNewRootFolder); + + if(responseCode == EMTPRespCodeOK) + { + delete iFileMan; + iFileMan = NULL; + iFileMan = CFileMan::NewL(iFramework.Fs()); + + if(!isFolder) + { + MoveFileL(newObjectName); + SendResponseL(responseCode); + } + else + { + MoveFolderL(); + SendResponseL(responseCode); + } + } + CleanupStack::PopAndDestroy(); // newObjectName. + __FLOG(_L8("MoveObjectL - Exit")); + return responseCode; + } + +/** +Retrieve the parameters of the request +*/ +void CMTPMoveObject::GetParametersL() + { + __FLOG(_L8("GetParametersL - Entry")); + __ASSERT_DEBUG(iRequestChecker, Panic(EMTPDpRequestCheckNull)); + + TUint32 objectHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter1); + iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter2); + iNewParentHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter3); + + //not taking owernship + iObjectInfo = iRequestChecker->GetObjectInfo(objectHandle); + __ASSERT_DEBUG(iObjectInfo, Panic(EMTPDpObjectNull)); + + if(iNewParentHandle == 0) + { + SetDefaultParentObjectL(); + } + else + { + CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iNewParentHandle); + __ASSERT_DEBUG(parentObjectInfo, Panic(EMTPDpObjectNull)); + delete iDest; + iDest = NULL; + iDest = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL(); + } + __FLOG(_L8("GetParametersL - Exit")); + } + +/** +Get a default parent object, ff the request does not specify a parent object, +*/ +void CMTPMoveObject::SetDefaultParentObjectL() + { + __FLOG(_L8("SetDefaultParentObjectL - Entry")); + const CMTPStorageMetaData& storageMetaData( iFramework.StorageMgr().StorageL(iStorageId) ); + const TDesC& driveBuf( storageMetaData.DesC(CMTPStorageMetaData::EStorageSuid) ); + delete iDest; + iDest = NULL; + iDest = driveBuf.AllocL(); + iNewParentHandle = KMTPHandleNoParent; + __FLOG(_L8("SetDefaultParentObjectL - Exit")); + } + +/** +Check if we can move the file to the new location +*/ +TMTPResponseCode CMTPMoveObject::CanMoveObjectL(const TDesC& aOldName, const TDesC& aNewName) const + { + __FLOG(_L8("CanMoveObjectL - Entry")); + TMTPResponseCode result = EMTPRespCodeOK; + + TEntry fileEntry; + User::LeaveIfError(iFramework.Fs().Entry(aOldName, fileEntry)); + TInt drive(iFramework.StorageMgr().DriveNumber(iStorageId)); + User::LeaveIfError(drive); + TVolumeInfo volumeInfo; + User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive)); + +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + if(volumeInfo.iFree < fileEntry.FileSize()) +#else + if(volumeInfo.iFree < fileEntry.iSize) +#endif + { + result = EMTPRespCodeStoreFull; + } + else if (BaflUtils::FileExists(iFramework.Fs(), aNewName)) + { + result = EMTPRespCodeInvalidParentObject; + } + __FLOG_VA((_L8("CanMoveObjectL - Exit with response code 0x%04X"), result)); + return result; + } + +/** +Save the object properties before moving +*/ +void CMTPMoveObject::GetPreviousPropertiesL(const TDesC& aFileName) + { + __FLOG(_L8("GetPreviousPropertiesL - Entry")); + User::LeaveIfError(iFramework.Fs().Modified(aFileName, iPreviousModifiedTime)); + __FLOG(_L8("GetPreviousPropertiesL - Exit")); + } + +/** +Set the object properties after moving +*/ +void CMTPMoveObject::SetPreviousPropertiesL(const TDesC& aFileName) + { + __FLOG(_L8("SetPreviousPropertiesL - Entry")); + User::LeaveIfError(iFramework.Fs().SetModified(aFileName, iPreviousModifiedTime)); + __FLOG(_L8("SetPreviousPropertiesL - Exit")); + } + + +/* This function will actually delete the orginal folders from the file system. */ +TMTPResponseCode CMTPMoveObject::FinalPhaseMove() + { + __FLOG(_L8("FinalPhaseMove - Entry")); + TMTPResponseCode ret = EMTPRespCodeOK; + __FLOG(*iPathToMove); + TInt rel = iFileMan->RmDir(*iPathToMove); + __FLOG_VA((_L8("Error code of RmDir is %d"),rel)); + if (rel != KErrNone) + { + ret = EMTPRespCodeGeneralError; + } + __FLOG(_L8("FinalPhaseMove - Exit")); + return ret; + } + +/* Move a single object and update the database */ +void CMTPMoveObject::MoveAndUpdateL(TUint32 aObjectHandle) + { + __FLOG(_L8("MoveAndUpdateL - Entry")); + CMTPObjectMetaData* objectInfo(CMTPObjectMetaData::NewLC()); + RBuf fileName; + fileName.CreateL(KMaxFileName); + fileName.CleanupClosePushL(); + RBuf rightPartName; + rightPartName.CreateL(KMaxFileName); + rightPartName.CleanupClosePushL(); + RBuf oldName; + oldName.CreateL(KMaxFileName); + oldName.CleanupClosePushL(); + + if(iFramework.ObjectMgr().ObjectL(TMTPTypeUint32(aObjectHandle), *objectInfo)) + { + fileName = objectInfo->DesC(CMTPObjectMetaData::ESuid); + oldName = fileName; + + if (objectInfo->Uint(CMTPObjectMetaData::EDataProviderId) == iFramework.DataProviderId()) + { + rightPartName = fileName.Right(fileName.Length() - iPathToMove->Length()); + + if((iNewRootFolder->Length() + rightPartName.Length()) > fileName.MaxLength()) + { + User::Leave(KErrCorrupt); + } + + fileName.Zero(); + fileName.Append(*iNewRootFolder); + fileName.Append(rightPartName); + objectInfo->SetDesCL(CMTPObjectMetaData::ESuid, fileName); + objectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId); + iFramework.ObjectMgr().ModifyObjectL(*objectInfo); + } + } + else + { + User::Leave(KErrCorrupt); + } + + iFileMan->Move(oldName, fileName); + + CleanupStack::PopAndDestroy(&oldName); + CleanupStack::PopAndDestroy(&rightPartName); + CleanupStack::PopAndDestroy(&fileName); + CleanupStack::PopAndDestroy(objectInfo); + __FLOG(_L8("MoveAndUpdateL - Exit")); + } + + + + +