diff -r 000000000000 -r a2952bb97e68 mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cmoveobject.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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( 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* 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 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