mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cmoveobject.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
child 25 d881023c13eb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cmoveobject.cpp	Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,849 @@
+/*
+* Copyright (c) 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:  Implement the operation: MoveObject
+*
+*/
+
+
+#include <bautils.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/mmtpstoragemgr.h>
+#include <mtp/mmtpreferencemgr.h>
+#include <mtp/cmtpobjectmetadata.h>
+#include <mtp/cmtptypearray.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/cmtptypeobjectproplist.h>
+
+#include "cmoveobject.h"
+#include "mmmtpdplogger.h"
+#include "tmmmtpdppanic.h"
+#include "mmmtpdputility.h"
+#include "cmmmtpdpmetadataaccesswrapper.h"
+#include "mmmtpdpconfig.h"
+
+/**
+* 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
+        }
+    };
+
+// -----------------------------------------------------------------------------
+// CMoveObject::NewL
+// Two-phase construction method
+// -----------------------------------------------------------------------------
+//
+//EXPORT_C MMmRequestProcessor* CMoveObject::NewL( MMTPDataProviderFramework& aFramework,
+//        MMTPConnection& aConnection,
+//        CMmMtpDpMetadataAccessWrapper& aWrapper )
+//    {
+//    CMoveObject* self = new (ELeave) CMoveObject( aFramework, aConnection, aWrapper );
+//    CleanupStack::PushL( self );
+//    self->ConstructL();
+//    CleanupStack::Pop( self );
+//
+//    return self;
+//    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::~CMoveObject
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMoveObject::~CMoveObject()
+    {
+    Cancel();
+
+    delete iDest;
+    delete iFileMan;
+    delete iPathToMove;
+    delete iNewRootFolder;
+    iObjectHandles.Close();
+    if ( iPropertyElement )
+        delete iPropertyElement;
+    delete iPropertyList;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::CMoveObject
+// Standard c++ constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMoveObject::CMoveObject( MMTPDataProviderFramework& aFramework,
+        MMTPConnection& aConnection,
+        MMmMtpDpConfig& aDpConfig) :
+    CRequestProcessor( aFramework, aConnection, sizeof( KMTPMoveObjectPolicy )
+            /sizeof( TMTPRequestElementInfo ), KMTPMoveObjectPolicy),
+    iDpConfig( aDpConfig ),
+    iObjectHandles( KMmMtpRArrayGranularity ),
+    iMoveObjectIndex( 0 )
+    {
+    PRINT( _L( "Operation: MoveObject(0x1019)" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::ServiceL
+// MoveObject request handler
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMoveObject::ServiceL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::ServiceL" ) );
+    TMTPResponseCode ret = MoveObjectL();
+    PRINT1( _L( "MM MTP <> CMoveObject::ServiceL ret = 0x%x" ), ret );
+    if ( EMTPRespCodeOK != ret )
+        {
+        SendResponseL( ret );
+        }
+    PRINT( _L( "MM MTP <= CMoveObject::ServiceL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::ConstructL
+// Second phase constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMoveObject::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+
+    iPropertyList = CMTPTypeObjectPropList::NewL();
+    SetPSStatus();
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::RunL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMoveObject::RunL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::RunL" ) );
+    if ( MoveOwnedObjectsL() )
+        {
+        // Reset iMoveObjectIndex count since move completed
+        iMoveObjectIndex = 0;
+
+        TMTPResponseCode ret = EMTPRespCodeOK;
+        // Delete the original folders in the device dp.
+        if ( iObjectInfo->Uint( CMTPObjectMetaData::EDataProviderId )
+                == iFramework.DataProviderId() )
+            {
+            ret = FinalPhaseMove();
+            }
+        PRINT1( _L("MM MTP <> CMoveObject::RunL ret = 0x%x"), ret );
+        SendResponseL( ret );
+        }
+    PRINT( _L( "MM MTP <= CMoveObject::RunL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::RunError
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMoveObject::RunError( TInt aError )
+    {
+    if ( aError != KErrNone )
+        PRINT1( _L( "MM MTP <> CMoveObject::RunError aError = %d" ), aError );
+    TRAP_IGNORE( SendResponseL( EMTPRespCodeGeneralError ) );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::MoveFileL
+// A helper function of MoveObjectL
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::MoveFileL( const TDesC& aNewFileName )
+    {
+    PRINT1( _L( "MM MTP => CMoveObject::MoveFileL aNewFileName = %S" ), &aNewFileName );
+    const TDesC& suid( iObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
+    TFileName oldFileName( suid ); // save the old file name, the suid will be modified
+    PRINT1( _L( "MM MTP <> CMoveObject::MoveFileL oldFileName = %S" ), &suid );
+
+    if ( iStorageId == iObjectInfo->Uint( CMTPObjectMetaData::EStorageId ) )
+        iSameStorage = ETrue;
+    else
+        iSameStorage = EFalse;
+    GetPreviousPropertiesL( *iObjectInfo );
+    User::LeaveIfError( iFileMan->Move( suid, aNewFileName ) ); // iDest just Folder
+    User::LeaveIfError( iFramework.Fs().SetModified( aNewFileName, iPreviousModifiedTime ) );
+
+    iObjectInfo->SetDesCL( CMTPObjectMetaData::ESuid, aNewFileName );
+    iObjectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
+    iObjectInfo->SetUint( CMTPObjectMetaData::EParentHandle, iNewParentHandle );
+    iFramework.ObjectMgr().ModifyObjectL( *iObjectInfo );
+    SetPropertiesL( oldFileName, aNewFileName, *iObjectInfo );
+    PRINT( _L( "MM MTP <= CMoveObject::MoveFileL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::MoveOwnedObjectsL
+// Move the objects through iterations of RunL
+// -----------------------------------------------------------------------------
+//
+TBool CMoveObject::MoveOwnedObjectsL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::MoveOwnedObjectsL" ) );
+    TBool ret = EFalse;
+
+    if ( iMoveObjectIndex < iNumberOfObjects )
+        {
+        MoveAndUpdateL( iObjectHandles[iMoveObjectIndex++] );
+
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, iStatus.Int() );
+        SetActive();
+        }
+    else
+        {
+        ret = ETrue;
+        }
+
+    PRINT1( _L( "MM MTP <= CMoveObject::MoveOwnedObjectsL ret = %d" ), ret );
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::MoveFolderL
+// A helper function of MoveObjectL
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::MoveFolderL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::MoveFolderL" ) );
+    RBuf oldFolderName;
+    oldFolderName.CreateL( KMaxFileName );
+    oldFolderName.CleanupClosePushL(); // + oldFileName
+    oldFolderName = iObjectInfo->DesC( CMTPObjectMetaData::ESuid );
+    PRINT1( _L( "MM MTP <> CMoveObject::MoveFolderL oldFolderName = %S" ), &oldFolderName );
+    iPathToMove = oldFolderName.AllocL();
+    CleanupStack::PopAndDestroy( &oldFolderName ); // - oldFolderName
+
+    GenerateObjectHandleListL( iObjectInfo->Uint( CMTPObjectMetaData::EHandle ) );
+
+    iNumberOfObjects = iObjectHandles.Count();
+    PRINT1( _L( "MM MTP <> CMoveObject::MoveFolderL iNumberOfObjects = %d" ), iNumberOfObjects );
+
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, iStatus.Int() );
+    SetActive();
+
+    PRINT( _L( "MM MTP <= CMoveObject::MoveFolderL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::MoveObjectL
+// move object operations
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CMoveObject::MoveObjectL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::MoveObjectL" ) );
+    TMTPResponseCode responseCode = EMTPRespCodeOK;
+
+    GetParametersL();
+
+    RBuf newObjectName;
+    newObjectName.CreateL( KMaxFileName );
+    newObjectName.CleanupClosePushL(); // + newObjectName
+    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();
+
+    if ( responseCode == EMTPRespCodeOK )
+        {
+        delete iFileMan;
+        iFileMan = NULL;
+        iFileMan = CFileMan::NewL( iFramework.Fs() );
+
+        if ( !isFolder )
+            {
+            MoveFileL( newObjectName );
+            SendResponseL( responseCode );
+            }
+        else
+            {
+            MoveFolderL();
+            }
+        }
+    CleanupStack::PopAndDestroy( &newObjectName ); // - newObjectName.
+
+    PRINT1( _L( "MM MTP <= CMoveObject::MoveObjectL responseCode = 0x%x" ), responseCode );
+    return responseCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::GetParametersL
+// Retrieve the parameters of the request
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::GetParametersL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::GetParametersL" ) );
+    __ASSERT_DEBUG( iRequestChecker, Panic( EMmMTPDpRequestCheckNull ) );
+
+    TUint32 objectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
+    iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
+    iNewParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
+    PRINT3( _L( "MM MTP <> objectHandle = 0x%x, iStoargeId = 0x%x, iNewParentHandle = 0x%x" ),
+            objectHandle, iStorageId, iNewParentHandle );
+
+    // not taking owernship
+    iObjectInfo = iRequestChecker->GetObjectInfo( objectHandle );
+    __ASSERT_DEBUG( iObjectInfo, Panic( EMmMTPDpObjectNull ) );
+
+    if ( iNewParentHandle == 0 )
+        {
+        SetDefaultParentObjectL();
+        }
+    else
+        {
+        CMTPObjectMetaData* parentObjectInfo =
+                iRequestChecker->GetObjectInfo( iNewParentHandle );
+        __ASSERT_DEBUG( parentObjectInfo, Panic( EMmMTPDpObjectNull ) );
+        delete iDest;
+        iDest = NULL;
+        iDest = parentObjectInfo->DesC( CMTPObjectMetaData::ESuid ).AllocL();
+        PRINT1( _L( "MM MTP <> CMoveObject::GetParametersL iDest = %S" ), iDest );
+        }
+    PRINT( _L( "MM MTP <= CMoveObject::GetParametersL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::SetDefaultParentObjectL
+// Get a default parent object, ff the request does not specify a parent object,
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::SetDefaultParentObjectL()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::SetDefaultParentObjectL" ) );
+
+    delete iDest;
+    iDest = NULL;
+    iDest = ( iFramework.StorageMgr().StorageL( iStorageId ).DesC(
+                CMTPStorageMetaData::EStorageSuid ) ).AllocL();
+    PRINT1( _L( "MM MTP <> CMoveObject::SetDefaultParentObjectL iDest = %S" ), iDest );
+    iNewParentHandle = KMTPHandleNoParent;
+    PRINT( _L( "MM MTP <= CMoveObject::SetDefaultParentObjectL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::CanMoveObjectL
+// Check if we can move the file to the new location
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CMoveObject::CanMoveObjectL( const TDesC& aOldName,
+        const TDesC& aNewName ) const
+    {
+    PRINT( _L( "MM MTP => CMoveObject::CanMoveObjectL" ) );
+    TMTPResponseCode result = EMTPRespCodeOK;
+
+    TEntry fileEntry;
+    User::LeaveIfError( iFramework.Fs().Entry( aOldName, fileEntry ) );
+    TDriveNumber drive( static_cast<TDriveNumber>( iFramework.StorageMgr().DriveNumber( iStorageId ) ) );
+    User::LeaveIfError( drive );
+    TVolumeInfo volumeInfo;
+    User::LeaveIfError( iFramework.Fs().Volume( volumeInfo, drive ) );
+
+    if ( volumeInfo.iFree < fileEntry.iSize )
+        {
+        result = EMTPRespCodeStoreFull;
+        }
+    else if ( BaflUtils::FileExists( iFramework.Fs(), aNewName ) )
+        {
+#ifdef MMMTPDP_REPLACE_EXIST_FILE
+        // delete the old one and replace
+        TInt delErr = iFramework.Fs().Delete( aNewName );
+        PRINT1( _L( "MM MTP <> CMoveObject::CanMoveObjectL delErr = %d" ), delErr );
+        // delete from the metadata DB
+        TRAPD( err, iFramework.ObjectMgr().RemoveObjectL( aNewName ) );
+        PRINT1( _L( "MM MTP <> CMoveObject::CanMoveObjectL err = %d" ), err );
+        // delete from video/mpx DB
+        CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
+        if ( iFramework.ObjectMgr().ObjectL( aNewName, *objectInfo ) )
+            {
+            TRAP( err, iDpConfig.GetWrapperL().DeleteObjectL( aNewName,
+                objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) );
+            }
+        CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
+        if ( err )
+            {
+            // do nothing
+            }
+#else
+        result = EMTPRespCodeInvalidParentObject;
+#endif
+        }
+
+    PRINT1( _L( "MM MTP <= CMoveObject::CanMoveObjectL result = 0x%x" ), result );
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::GetPreviousPropertiesL
+// Save the object properties before doing the move
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::GetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
+    {
+    PRINT( _L( "MM MTP => CMoveObject::GetPreviousPropertiesL" ) );
+
+    const TDesC& suid( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+
+    User::LeaveIfError( iFramework.Fs().Modified( suid, iPreviousModifiedTime ) );
+
+    // same storage, not necessary to get the properties
+    if ( iSameStorage )
+        return;
+
+    TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
+    const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( formatCode );
+    TInt count = properties->Count();
+    CMTPTypeString* textData = NULL;
+    TInt err = KErrNone;
+    TUint16 propCode;
+    TUint32 handle = aObject.Uint( CMTPObjectMetaData::EHandle ) ;
+
+    if ( iPropertyElement )
+        {
+        delete iPropertyElement;
+        iPropertyElement = NULL;
+        }
+
+    for ( TInt i = 0; i < count; i++ )
+        {
+        propCode = (*properties)[i];
+        switch( propCode )
+            {
+            case EMTPObjectPropCodeStorageID:
+            case EMTPObjectPropCodeObjectFormat:
+            case EMTPObjectPropCodeProtectionStatus:
+            case EMTPObjectPropCodeObjectSize:
+            case EMTPObjectPropCodeObjectFileName:
+            case EMTPObjectPropCodeParentObject:
+            case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
+            case EMTPObjectPropCodeNonConsumable:
+            case EMTPObjectPropCodeDateCreated:
+            case EMTPObjectPropCodeDateModified:
+                break;
+
+            case EMTPObjectPropCodeName:
+            case EMTPObjectPropCodeDateAdded:
+                if ( ( propCode == EMTPObjectPropCodeName )
+                   || ( ( !MmMtpDpUtility::IsVideoL( aObject.DesC( CMTPObjectMetaData::ESuid ), iFramework ) )
+                        && ( propCode == EMTPObjectPropCodeDateAdded ) ) )
+                    {
+                    textData = CMTPTypeString::NewLC(); // + textData
+
+                    TRAP( err, iDpConfig.GetWrapperL().GetObjectMetadataValueL( propCode,
+                        *textData,
+                        aObject ) );
+
+                    PRINT1( _L( "MM MTP <> CMoveObject::GetPreviousPropertiesL::ServiceSpecificObjectPropertyL err = %d" ), err );
+
+                    if ( err == KErrNone )
+                        {
+                        iPropertyElement = &(iPropertyList->ReservePropElemL(handle, propCode));
+                        iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, textData->StringChars());
+//                        iPropertyElement = CMTPTypeObjectPropListElement::NewL(
+//                            handle, propCode, *textData );
+                        }
+                    else if ( err == KErrNotFound )
+                        {
+                        iPropertyElement = NULL;
+                        }
+                    else
+                       {
+                       User::Leave( err );
+                       }
+
+                    CleanupStack::PopAndDestroy( textData ); // - textData
+                    }
+                break;
+
+            default:
+                {
+                ServiceGetSpecificObjectPropertyL( propCode, handle, aObject );
+                }
+                break;
+            }
+
+        if ( iPropertyElement )
+            {
+            iPropertyList->CommitPropElemL( *iPropertyElement );
+
+            iPropertyElement = NULL;
+            }
+
+        } // end of for loop
+
+    PRINT1( _L( "MM MTP <= CMoveObject::GetPreviousPropertiesL err = %d" ), err );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::ServiceMetaDataToWrapper
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TMTPResponseCode CMoveObject::ServiceMetaDataToWrapper(
+    const TUint16 aPropCode,
+    MMTPType& aNewData,
+    const CMTPObjectMetaData& aObject )
+    {
+    TMTPResponseCode resCode = EMTPRespCodeOK;
+
+    TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode,
+        aNewData,
+        aObject ) );
+
+    PRINT1( _L("MM MTP <> CMoveObject::ServiceMetaDataToWrapper err = %d"), err);
+
+    if ( err == KErrNone )
+        {
+        resCode = EMTPRespCodeOK;
+        }
+    else if ( err == KErrTooBig )
+        // according to the codes of S60
+        {
+        resCode = EMTPRespCodeInvalidDataset;
+        }
+    else if ( err == KErrPermissionDenied )
+        {
+        resCode = EMTPRespCodeAccessDenied;
+        }
+    else if ( err == KErrNotFound )
+        {
+        if ( MmMtpDpUtility::HasMetadata( aObject.Uint( CMTPObjectMetaData::EFormatCode ) ) )
+            resCode = EMTPRespCodeAccessDenied;
+        else
+            resCode = EMTPRespCodeOK;
+        }
+    else
+        {
+        resCode = EMTPRespCodeGeneralError;
+        }
+
+    PRINT1( _L("MM MTP <= CMoveObject::ServiceMetaDataToWrapper resCode = 0x%x"), resCode);
+
+    return resCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::SetPreviousPropertiesL
+// Set the object properties after doing the move
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::SetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
+    {
+    PRINT( _L( "MM MTP => CMoveObject::SetPreviousPropertiesL" ) );
+    const TInt count( iPropertyList->NumberOfElements() );
+    PRINT1( _L( "MM MTP <> CMoveObject::SetPreviousPropertiesL count = %d" ), count );
+    TMTPResponseCode respcode = EMTPRespCodeOK;
+    CMTPTypeString* stringData = NULL;
+    iPropertyList->ResetCursor();
+    
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CMTPTypeObjectPropListElement& element = iPropertyList->GetNextElementL( );
+
+        TUint32 handle = element.Uint32L(
+                CMTPTypeObjectPropListElement::EObjectHandle );
+        TUint16 propertyCode = element.Uint16L(
+                CMTPTypeObjectPropListElement::EPropertyCode );
+        TUint16 dataType = element.Uint16L(
+                CMTPTypeObjectPropListElement::EDatatype );
+        PRINT3( _L( "MM MTP <> CMoveObject::SetPreviousPropertiesL = 0x%x, propertyCode = 0x%x, dataType = 0x%x" ),
+          handle, propertyCode, dataType );
+
+        switch ( propertyCode )
+            {
+            case EMTPObjectPropCodeStorageID:
+            case EMTPObjectPropCodeObjectFormat:
+            case EMTPObjectPropCodeProtectionStatus:
+            case EMTPObjectPropCodeObjectSize:
+            case EMTPObjectPropCodeObjectFileName:
+            case EMTPObjectPropCodeParentObject:
+            case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
+            case EMTPObjectPropCodeNonConsumable:
+            case EMTPObjectPropCodeDateCreated:
+            case EMTPObjectPropCodeDateModified:
+            case EMTPObjectPropCodeDateAdded:
+                break;
+
+            case EMTPObjectPropCodeName:
+                {
+                stringData = CMTPTypeString::NewLC(
+                    element.StringL(CMTPTypeObjectPropListElement::EValue)); // + stringData
+
+                respcode = ServiceMetaDataToWrapper( propertyCode,
+                    *stringData,
+                    aObject );
+
+                CleanupStack::PopAndDestroy( stringData ); // - stringData
+                }
+                break;
+
+            default:
+                {
+                respcode = ServiceSetSpecificObjectPropertyL( propertyCode,
+                        aObject,
+                        element );
+                }
+                break;
+            }
+        } // end of for loop
+
+    if( respcode == EMTPRespCodeOK )
+        {
+        // do nothing, ignore warning
+        }
+
+    PRINT1( _L( "MM MTP <= CMoveObject::SetPreviousPropertiesL respcode = 0x%x" ), respcode );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::SetPropertiesL
+// Set the object properties in the object property store.
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::SetPropertiesL( const TDesC& aOldFileName, const TDesC& aNewFileName,
+        const CMTPObjectMetaData& aNewObject )
+    {
+    PRINT2( _L( "MM MTP => CMoveObject::SetPropertiesL aOldFileName = %S, aNewFileName = %S" ),
+            &aOldFileName, &aNewFileName );
+
+    TUint32 formatCode = aNewObject.Uint( CMTPObjectMetaData::EFormatCode );
+    // This is used to keep the same behavior in mass storage and device file manager.
+    if ( formatCode == EMTPFormatCodeAbstractAudioVideoPlaylist )
+        {
+        PRINT( _L( "MM MTP <> CMoveObject::SetPropertiesL Playlist file do not update the MPX DB" ) );
+        }
+    else
+        {
+        // if the two object in different stoarge, we should delete the old one and insert new one
+        if ( iSameStorage )
+            iDpConfig.GetWrapperL().RenameObjectL( aOldFileName, aNewFileName );
+        else
+            {
+            iDpConfig.GetWrapperL().DeleteObjectL( aOldFileName, formatCode );
+            iDpConfig.GetWrapperL().AddObjectL( aNewFileName );
+            SetPreviousPropertiesL( aNewObject );
+            }
+        }
+
+      // Reference DB is used PUID
+//    if ( formatCode == EMTPFormatCodeAbstractAudioVideoPlaylist
+//            || formatCode == EMTPFormatCodeM3UPlaylist )
+//        {
+//        MMTPReferenceMgr& referenceMgr = iFramework.ReferenceMgr();
+//        CDesCArray* references = referenceMgr.ReferencesLC( aOldFileName ); // + references
+//        referenceMgr.SetReferencesL( aNewFileName, *references );
+//        CleanupStack::PopAndDestroy( references ); // - references
+//        // delete the old references
+//        referenceMgr.RemoveReferencesL( aOldFileName );
+//        }
+
+
+    PRINT( _L( "MM MTP <= CMoveObject::SetPropertiesL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::FinalPhaseMove
+// This function will actually delete the orginal folders from the file system
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CMoveObject::FinalPhaseMove()
+    {
+    PRINT( _L( "MM MTP => CMoveObject::FinalPhaseMove" ) );
+    TMTPResponseCode ret = EMTPRespCodeOK;
+
+    TInt rel = iFileMan->RmDir( *iPathToMove );
+    PRINT1( _L( "MM MTP <> CMoveObject::FinalPhaseMove rel = %d" ), rel );
+
+    if ( rel != KErrNone )
+        {
+        ret = EMTPRespCodeGeneralError;
+        }
+
+    PRINT1( _L( "MM MTP <= CMoveObject::FinalPhaseMove ret = 0x%x" ), ret );
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::GenerateObjectHandleListL
+// Generate the list of handles that need to be moved to the new location
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::GenerateObjectHandleListL( TUint32 aParentHandle )
+    {
+    PRINT1( _L( "MM MTP => CMoveObject::GenerateObjectHandleListL aParentHandle = 0x%x" ), aParentHandle );
+    RMTPObjectMgrQueryContext context;
+    RArray<TUint> handles;
+    TMTPObjectMgrQueryParams params( KMTPStorageAll, KMTPFormatsAll,
+            aParentHandle );
+    CleanupClosePushL( context ); // + context
+    CleanupClosePushL( handles ); // - handles
+
+    do
+        {
+        iFramework.ObjectMgr().GetObjectHandlesL( params, context, handles );
+
+        TInt numberOfObjects = handles.Count();
+        for ( TInt i = 0; i < numberOfObjects; i++ )
+            {
+            if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == iFramework.DataProviderId() )
+                {
+                iObjectHandles.AppendL( handles[i] );
+                continue;
+                }
+
+            // Folder
+            if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == 0 ) // We know that the device dp id is always 0, otherwise the whole MTP won't work.
+                {
+                GenerateObjectHandleListL( handles[i] );
+                }
+            }
+        }
+    while ( !context.QueryComplete() );
+
+    CleanupStack::PopAndDestroy( &handles ); // - handles
+    CleanupStack::PopAndDestroy( &context ); // - contect
+
+    PRINT( _L( "MM MTP <= CMoveObject::GenerateObjectHandleListL" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMoveObject::MoveAndUpdateL
+// Move a single object and update the database
+// -----------------------------------------------------------------------------
+//
+void CMoveObject::MoveAndUpdateL( TUint32 aObjectHandle )
+    {
+    PRINT1( _L( "MM MTP => CMoveObject::MoveAndUpdateL aObjectHanlde = 0x%x" ), aObjectHandle );
+
+    CMTPObjectMetaData* objectInfo( CMTPObjectMetaData::NewLC() ); // + objectInfo
+
+    RBuf fileName;
+    fileName.CreateL( KMaxFileName );
+    fileName.CleanupClosePushL(); // + fileName
+
+    RBuf rightPartName;
+    rightPartName.CreateL( KMaxFileName );
+    rightPartName.CleanupClosePushL(); // + rightPartName
+
+    RBuf oldName;
+    oldName.CreateL( KMaxFileName );
+    oldName.CleanupClosePushL(); // + oldName
+
+    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 );
+            PRINT1( _L( "MM MTP <> MoveAndUpdateL fileName = %S" ), &fileName );
+
+            if ( iStorageId == objectInfo->Uint( CMTPObjectMetaData::EStorageId ) )
+                iSameStorage = ETrue;
+            else
+                iSameStorage = EFalse;
+            GetPreviousPropertiesL( *objectInfo );
+            TInt err = iFileMan->Move( oldName, fileName );
+            PRINT1( _L( "MM MTP <> CMoveObject::MoveAndUpdateL Move error code = %d" ), err );
+            User::LeaveIfError( err );
+            User::LeaveIfError( iFramework.Fs().SetModified( fileName, iPreviousModifiedTime ) );
+
+            objectInfo->SetDesCL( CMTPObjectMetaData::ESuid, fileName );
+            objectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
+            TParsePtrC parentSuid( fileName );
+            TUint32 parentHandle = iFramework.ObjectMgr().HandleL( parentSuid.DriveAndPath() );
+            objectInfo->SetUint( CMTPObjectMetaData::EParentHandle, parentHandle );
+
+            //TUint32 parentHandle = iFramework.ObjectMgr().HandleL( parentSuid.DriveAndPath() );
+            PRINT1( _L( "MM MTP <> CMoveObject::MoveAndUpdateL parentHandle = 0x%x" ), parentHandle );
+
+            iFramework.ObjectMgr().ModifyObjectL( *objectInfo );
+
+            SetPropertiesL( oldName, fileName, *objectInfo );
+            }
+        }
+    else
+        {
+        User::Leave( KErrCorrupt );
+        }
+
+    CleanupStack::PopAndDestroy( &oldName ); // - oldName
+    CleanupStack::PopAndDestroy( &rightPartName ); // - rightPartName
+    CleanupStack::PopAndDestroy( &fileName ); // - fileName
+    CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
+    PRINT( _L( "MM MTP <= CMoveObject::MoveAndUpdateL" ) );
+    }
+
+// end of file