/*
* 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