mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/ccopyobject.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
child 25 d881023c13eb
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implement the operation: CopyObject
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <bautils.h>
       
    20 
       
    21 #include <mtp/mmtpdataproviderframework.h>
       
    22 #include <mtp/mmtpobjectmgr.h>
       
    23 #include <mtp/mmtpreferencemgr.h>
       
    24 #include <mtp/mmtpstoragemgr.h>
       
    25 #include <mtp/cmtpobjectmetadata.h>
       
    26 #include <mtp/cmtptypestring.h>
       
    27 #include <mtp/cmtptypearray.h>
       
    28 #include <mtp/cmtptypeobjectproplist.h>
       
    29 
       
    30 #include "ccopyobject.h"
       
    31 #include "mmmtpdplogger.h"
       
    32 #include "tmmmtpdppanic.h"
       
    33 #include "mmmtpdputility.h"
       
    34 #include "mmmtpdpconfig.h"
       
    35 #include "cmmmtpdpmetadataaccesswrapper.h"
       
    36 
       
    37 /**
       
    38 * Verification data for the CopyObject request
       
    39 */
       
    40 const TMTPRequestElementInfo KMTPCopyObjectPolicy[] =
       
    41     {
       
    42         {
       
    43         TMTPTypeRequest::ERequestParameter1,
       
    44         EMTPElementTypeObjectHandle,
       
    45         EMTPElementAttrFileOrDir,
       
    46         0,
       
    47         0,
       
    48         0
       
    49         },
       
    50         {
       
    51         TMTPTypeRequest::ERequestParameter2,
       
    52         EMTPElementTypeStorageId,
       
    53         EMTPElementAttrWrite,
       
    54         0,
       
    55         0,
       
    56         0
       
    57         },
       
    58         {
       
    59         TMTPTypeRequest::ERequestParameter3,
       
    60         EMTPElementTypeObjectHandle,
       
    61         EMTPElementAttrDir | EMTPElementAttrWrite,
       
    62         1,
       
    63         0,
       
    64         0
       
    65         }
       
    66     };
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CCopyObject::~CCopyObject
       
    70 // Destructor
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 EXPORT_C CCopyObject::~CCopyObject()
       
    74     {
       
    75     Cancel();
       
    76 
       
    77     delete iDest;
       
    78     delete iFileMan;
       
    79     iObjectHandles.Close();
       
    80     if ( iPropertyElement )
       
    81         delete iPropertyElement;
       
    82     delete iPropertyList;
       
    83     delete iPathToCopy;
       
    84     delete iNewRootFolder;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CCopyObject::CCopyObject
       
    89 // Standard c++ constructor
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C CCopyObject::CCopyObject( MMTPDataProviderFramework& aFramework,
       
    93     MMTPConnection& aConnection,
       
    94     MMmMtpDpConfig& aDpConfig ) :
       
    95     CRequestProcessor( aFramework,
       
    96         aConnection,
       
    97         sizeof ( KMTPCopyObjectPolicy ) / sizeof(TMTPRequestElementInfo),
       
    98         KMTPCopyObjectPolicy ),
       
    99     iDpConfig( aDpConfig ),
       
   100     iObjectHandles( KMmMtpRArrayGranularity )
       
   101     {
       
   102     PRINT( _L( "Operation: CopyObject(0x101A)" ) );
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CCopyObject::ServiceL
       
   107 // CopyObject request handler
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 EXPORT_C void CCopyObject::ServiceL()
       
   111     {
       
   112     PRINT( _L( "MM MTP => CCopyObject::ServiceL" ) );
       
   113     iHandle = KMTPHandleNone;
       
   114 
       
   115     CopyObjectL( iHandle );
       
   116 
       
   117     PRINT( _L( "MM MTP <= CCopyObject::ServiceL" ) );
       
   118     }
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 // CCopyObject::ConstructL
       
   122 // Second phase constructor
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 EXPORT_C void CCopyObject::ConstructL()
       
   126     {
       
   127     CActiveScheduler::Add( this );
       
   128 
       
   129     iPropertyList = CMTPTypeObjectPropList::NewL();
       
   130 
       
   131     // Set the CenRep value of MTP status,
       
   132     // also need to do in other processors which related to MPX
       
   133     SetPSStatus();
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CCopyObject::RunL
       
   138 //
       
   139 // -----------------------------------------------------------------------------
       
   140 //
       
   141 EXPORT_C void CCopyObject::RunL()
       
   142     {
       
   143     PRINT( _L( "MM MTP => CCopyObject::RunL" ) );
       
   144 
       
   145     if ( iCopyObjectIndex < iNumberOfObjects )
       
   146         {
       
   147         CopyAndUpdateL( iObjectHandles[iCopyObjectIndex++] );
       
   148 
       
   149         TRequestStatus* status = &iStatus;
       
   150         User::RequestComplete( status, iStatus.Int() );
       
   151         SetActive();
       
   152         }
       
   153     else
       
   154         {
       
   155         PRINT1( _L( "MM MTP <> CCopyObject::RunL iHandle = 0x%x" ), iHandle );
       
   156         SendResponseL( EMTPRespCodeOK, 1, &iHandle );
       
   157         }
       
   158 
       
   159     PRINT( _L( "MM MTP <= CCopyObject::RunL" ) );
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CCopyObject::CopyFileL
       
   164 // A helper function of CopyObjectL
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 TUint32 CCopyObject::CopyFileL( const TDesC& aNewFileName )
       
   168     {
       
   169     const TDesC& suid( iObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
       
   170     PRINT2( _L( "MM MTP => CCopyObject::CopyFileL old name = %S, aNewFileName = %S" ),
       
   171         &suid,
       
   172         &aNewFileName );
       
   173 
       
   174     GetPreviousPropertiesL( *iObjectInfo );
       
   175     User::LeaveIfError( iFileMan->Copy( suid, aNewFileName ) ); // iDest just folder
       
   176     User::LeaveIfError( iFramework.Fs().SetModified( aNewFileName, iPreviousModifiedTime ) );
       
   177     TUint32 handle = UpdateObjectInfoL( suid, aNewFileName );
       
   178 
       
   179     PRINT1( _L( "MM MTP <= CCopyObject::CopyFileL handle = 0x%x" ), handle );
       
   180 
       
   181     return handle;
       
   182     }
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CCopyObject::GenerateObjectHandleListL
       
   186 // Generate the list of handles that need to be copied to the new location
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CCopyObject::GenerateObjectHandleListL( TUint32 aParentHandle )
       
   190     {
       
   191     PRINT1( _L( "MM MTP => CCopyObject::GenerateObjectHandleListL aParentHandle = 0x%x" ),
       
   192         aParentHandle );
       
   193     RMTPObjectMgrQueryContext context;
       
   194     RArray<TUint> handles;
       
   195     CleanupClosePushL( context ); // + context
       
   196     CleanupClosePushL( handles ); // + handles
       
   197 
       
   198     TMTPObjectMgrQueryParams params( KMTPStorageAll, KMTPFormatsAll,
       
   199             aParentHandle );
       
   200     do
       
   201         {
       
   202         iFramework.ObjectMgr().GetObjectHandlesL( params, context, handles );
       
   203 
       
   204         TInt numberOfObjects = handles.Count();
       
   205         for ( TInt i = 0; i < numberOfObjects; i++ )
       
   206             {
       
   207             if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == iFramework.DataProviderId() )
       
   208                 {
       
   209                 iObjectHandles.AppendL( handles[i] );
       
   210                 continue;
       
   211                 }
       
   212 
       
   213             // Folder
       
   214             if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == 0 ) // We know that the device dp id is always 0, otherwise the whole MTP won't work.
       
   215                 {
       
   216                 GenerateObjectHandleListL( handles[i] );
       
   217                 }
       
   218             }
       
   219         }
       
   220     while ( !context.QueryComplete() );
       
   221 
       
   222     CleanupStack::PopAndDestroy( &handles ); // - handles
       
   223     CleanupStack::PopAndDestroy( &context ); // - context
       
   224     PRINT( _L( "MM MTP <= CCopyObject::GenerateObjectHandleListL" ) );
       
   225     }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CCopyObject::CopyFolderL
       
   229 // A helper function of CopyObjectL
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 TUint32 CCopyObject::CopyFolderL( const TDesC& aNewFolderName )
       
   233     {
       
   234     PRINT1( _L( "MM MTP => CCopyObject::CopyFolderL aNewFolderName = %S" ), &aNewFolderName );
       
   235     TUint32 handle = iFramework.ObjectMgr().HandleL( aNewFolderName ); // just get it
       
   236 
       
   237     GenerateObjectHandleListL( iObjectInfo->Uint( CMTPObjectMetaData::EHandle ) );
       
   238     iCopyObjectIndex = 0;
       
   239     iNumberOfObjects = iObjectHandles.Count();
       
   240     PRINT1( _L( "MM MTP <> CCopyObject::CopyFolderL iNumberOfObjects = %d" ), iNumberOfObjects );
       
   241 
       
   242     TRequestStatus* status = &iStatus;
       
   243     User::RequestComplete( status, iStatus.Int() );
       
   244     SetActive();
       
   245 
       
   246     PRINT1( _L( "MM MTP <= CCopyObject::CopyFolderL handle = 0x%x" ), handle );
       
   247     return handle;
       
   248     }
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // CCopyObject::CopyObjectL
       
   252 // Copy object operation
       
   253 // -----------------------------------------------------------------------------
       
   254 //
       
   255 void CCopyObject::CopyObjectL( TUint32& aNewHandle )
       
   256     {
       
   257     PRINT( _L( "MM MTP => CCopyObject::CopyObjectL" ) );
       
   258     TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   259     aNewHandle = KMTPHandleNone;
       
   260 
       
   261     GetParametersL();
       
   262 
       
   263     RBuf newObjectName;
       
   264     newObjectName.CleanupClosePushL(); // + newObjectName
       
   265     newObjectName.CreateL( KMaxFileName );
       
   266     newObjectName = *iDest;
       
   267 
       
   268     const TDesC& suid( iObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
       
   269     TParsePtrC fileNameParser( suid );
       
   270 
       
   271     // Check if the object is a folder or a file.
       
   272     TBool isFolder = EFalse;
       
   273     User::LeaveIfError( BaflUtils::IsFolder( iFramework.Fs(), suid, isFolder ) );
       
   274 
       
   275     if ( !isFolder )
       
   276         {
       
   277         if ( ( newObjectName.Length() + fileNameParser.NameAndExt().Length() ) <= newObjectName.MaxLength() )
       
   278             {
       
   279             newObjectName.Append( fileNameParser.NameAndExt() );
       
   280             }
       
   281         responseCode = CanCopyObjectL( suid, newObjectName );
       
   282         }
       
   283     else // It is a folder.
       
   284         {
       
   285         TFileName rightMostFolderName;
       
   286         User::LeaveIfError( BaflUtils::MostSignificantPartOfFullName( suid,
       
   287             rightMostFolderName ) );
       
   288         if ( ( newObjectName.Length() + rightMostFolderName.Length() + 1 ) <= newObjectName.MaxLength() )
       
   289             {
       
   290             newObjectName.Append( rightMostFolderName );
       
   291             // Add backslash.
       
   292             _LIT( KBackSlash, "\\" );
       
   293             newObjectName.Append( KBackSlash );
       
   294             }
       
   295         }
       
   296 
       
   297     delete iNewRootFolder;
       
   298     iNewRootFolder = NULL;
       
   299     iNewRootFolder = newObjectName.AllocL();
       
   300 
       
   301     if ( responseCode == EMTPRespCodeOK )
       
   302         {
       
   303         delete iFileMan;
       
   304         iFileMan = NULL;
       
   305         iFileMan = CFileMan::NewL( iFramework.Fs() );
       
   306 
       
   307         if ( !isFolder ) // It is a file.
       
   308             {
       
   309             aNewHandle = CopyFileL( newObjectName );
       
   310 //            if ( responseCode == EMTPRespCodeOK  )
       
   311             SendResponseL( EMTPRespCodeOK, 1, &aNewHandle );
       
   312 //            else
       
   313 //                SendResponseL( responseCode );
       
   314             }
       
   315         else // It is a folder.
       
   316             {
       
   317             delete iPathToCopy;
       
   318             iPathToCopy = NULL;
       
   319             iPathToCopy = suid.AllocL();
       
   320             PRINT1( _L( "MM MTP <> CCopyObject::CopyObjectL iPathToCopy = %S" ), iPathToCopy );
       
   321             aNewHandle = CopyFolderL( newObjectName );
       
   322             }
       
   323         }
       
   324     else
       
   325         SendResponseL( responseCode );
       
   326 
       
   327     CleanupStack::PopAndDestroy( &newObjectName ); // - newObjectName
       
   328     PRINT2( _L( "MM MTP <= CCopyObject::CopyObjectL responseCode = 0x%x, aNewHandle = 0x%x" ),
       
   329             responseCode, aNewHandle );
       
   330     }
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 // CCopyObject::GetParametersL
       
   334 // Retrieve the parameters of the request
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void CCopyObject::GetParametersL()
       
   338     {
       
   339     PRINT( _L( "MM MTP => CCopyObject::GetParametersL" ) );
       
   340     __ASSERT_DEBUG( iRequestChecker, Panic( EMmMTPDpRequestCheckNull ) );
       
   341 
       
   342     TUint32 objectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
       
   343     iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
       
   344     TUint32 parentObjectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
       
   345     PRINT3( _L( "MM MTP <> CCopyObject::GetParametersL Object Hanlde = 0x%x, StorageId = 0x%x, Parent Handle = 0x%x" ),
       
   346             objectHandle, iStorageId, parentObjectHandle );
       
   347 
       
   348     // not taking owernship
       
   349     iObjectInfo = iRequestChecker->GetObjectInfo( objectHandle );
       
   350     __ASSERT_DEBUG( iObjectInfo, Panic( EMmMTPDpObjectNull ) );
       
   351 
       
   352     if ( parentObjectHandle == 0 )
       
   353         {
       
   354         SetDefaultParentObjectL();
       
   355         }
       
   356     else
       
   357         {
       
   358         CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo( parentObjectHandle );
       
   359         __ASSERT_DEBUG( parentObjectInfo, Panic( EMmMTPDpObjectNull ) );
       
   360         delete iDest;
       
   361         iDest = NULL;
       
   362         iDest = parentObjectInfo->DesC( CMTPObjectMetaData::ESuid ).AllocL();
       
   363         iNewParentHandle = parentObjectHandle;
       
   364         }
       
   365     PRINT( _L( "MM MTP <= CCopyObject::GetParametersL" ) );
       
   366     }
       
   367 
       
   368 // -----------------------------------------------------------------------------
       
   369 // CCopyObject::SetDefaultParentObjectL
       
   370 // Get a default parent object, ff the request does not specify a parent object,
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 void CCopyObject::SetDefaultParentObjectL()
       
   374     {
       
   375     PRINT( _L( "MM MTP => CCopyObject::SetDefaultParentObjectL" ) );
       
   376 
       
   377     delete iDest;
       
   378     iDest = NULL;
       
   379     iDest = ( iFramework.StorageMgr().StorageL( iStorageId ).DesC(
       
   380                 CMTPStorageMetaData::EStorageSuid ) ).AllocL();
       
   381     PRINT1( _L( "MM MTP <> CCopyObject::SetDefaultParentObjectL Destination location is %S" ), iDest );
       
   382     iNewParentHandle = KMTPHandleNoParent;
       
   383     PRINT( _L( "MM MTP <= CCopyObject::SetDefaultParentObjectL" ) );
       
   384     }
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // CCopyObject::CanCopyObjectL
       
   388 // Check if we can copy the file to the new location
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 TMTPResponseCode CCopyObject::CanCopyObjectL( const TDesC& aOldName,
       
   392     const TDesC& aNewName ) const
       
   393     {
       
   394     PRINT2( _L( "MM MTP => CCopyObject::CanCopyObjectL aOldName = %S, aNewName = %S" ),
       
   395             &aOldName, &aNewName );
       
   396     TMTPResponseCode result = EMTPRespCodeOK;
       
   397 
       
   398     TEntry fileEntry;
       
   399     User::LeaveIfError( iFramework.Fs().Entry( aOldName, fileEntry ) );
       
   400     TDriveNumber drive( static_cast<TDriveNumber>( iFramework.StorageMgr().DriveNumber( iStorageId ) ) );
       
   401     User::LeaveIfError( drive );
       
   402     TVolumeInfo volumeInfo;
       
   403     User::LeaveIfError( iFramework.Fs().Volume( volumeInfo, drive ) );
       
   404 
       
   405     if ( volumeInfo.iFree < fileEntry.iSize )
       
   406         {
       
   407         result = EMTPRespCodeStoreFull;
       
   408         }
       
   409     else if ( BaflUtils::FileExists( iFramework.Fs(), aNewName ) )
       
   410         {
       
   411 #ifdef MMMTPDP_REPLACE_EXIST_FILE
       
   412         // delete the old one and replace
       
   413         TInt delErr = iFramework.Fs().Delete( aNewName );
       
   414         PRINT1( _L( "MM MTP <> CCopyObject::CanCopyObjectL delErr = %d" ), delErr );
       
   415         // delete from the metadata DB
       
   416         TRAPD( err, iFramework.ObjectMgr().RemoveObjectL( aNewName ) );
       
   417         PRINT1( _L( "MM MTP <> CCopyObject::CanCopyObjectL err = %d" ), err );
       
   418         // delete from video/mpx DB
       
   419         CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
       
   420         if ( iFramework.ObjectMgr().ObjectL( aNewName, *objectInfo ) )
       
   421             {
       
   422             TRAP( err, iDpConfig.GetWrapperL().DeleteObjectL( aNewName,
       
   423                 objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) );
       
   424             }
       
   425         CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
       
   426 
       
   427         if ( err )
       
   428             {
       
   429             // do nothing
       
   430             }
       
   431 #else
       
   432         result = EMTPRespCodeInvalidParentObject;
       
   433 #endif
       
   434         }
       
   435     // This is used to keep the same behavior in mass storage and device file manager.
       
   436     else if ( iObjectInfo->Uint( CMTPObjectMetaData::EFormatCode )
       
   437         == EMTPFormatCodeAbstractAudioVideoPlaylist )
       
   438         {
       
   439         PRINT( _L( "MM MTP <> CCopyObject::CanCopyObjectL playlist file can't copy" ) );
       
   440         result = EMTPRespCodeAccessDenied;
       
   441         }
       
   442 
       
   443     PRINT1( _L( "MM MTP <= CCopyObject::CanCopyObjectL result = 0x%x" ), result );
       
   444     return result;
       
   445     }
       
   446 
       
   447 // -----------------------------------------------------------------------------
       
   448 // CCopyObject::GetPreviousPropertiesL
       
   449 // Save the object properties before doing the copy
       
   450 // -----------------------------------------------------------------------------
       
   451 //
       
   452 void CCopyObject::GetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
       
   453     {
       
   454     PRINT( _L( "MM MTP => CCopyObject::GetPreviousPropertiesL" ) );
       
   455 
       
   456     const TDesC& suid( aObject.DesC( CMTPObjectMetaData::ESuid ) );
       
   457 
       
   458     User::LeaveIfError( iFramework.Fs().Modified( suid, iPreviousModifiedTime ) );
       
   459 
       
   460     TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
       
   461     const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( formatCode );
       
   462     TInt count = properties->Count();
       
   463 
       
   464     CMTPTypeString* textData = NULL;
       
   465     TInt err = KErrNone;
       
   466     TUint16 propCode;
       
   467     TUint32 handle = aObject.Uint( CMTPObjectMetaData::EHandle ) ;
       
   468 
       
   469     if ( iPropertyElement )
       
   470         {
       
   471         delete iPropertyElement;
       
   472         iPropertyElement = NULL;
       
   473         }
       
   474     
       
   475     for ( TInt i = 0; i < count; i++ )
       
   476         {
       
   477         propCode = (*properties)[i];
       
   478 
       
   479         switch( propCode )
       
   480             {
       
   481             case EMTPObjectPropCodeStorageID:
       
   482             case EMTPObjectPropCodeObjectFormat:
       
   483             case EMTPObjectPropCodeProtectionStatus:
       
   484             case EMTPObjectPropCodeObjectSize:
       
   485             case EMTPObjectPropCodeObjectFileName:
       
   486             case EMTPObjectPropCodeParentObject:
       
   487             case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
       
   488             case EMTPObjectPropCodeNonConsumable:
       
   489             case EMTPObjectPropCodeDateCreated:
       
   490             case EMTPObjectPropCodeDateModified:
       
   491                 break;
       
   492 
       
   493             case EMTPObjectPropCodeName:
       
   494             case EMTPObjectPropCodeDateAdded:
       
   495                 if ( ( propCode == EMTPObjectPropCodeName )
       
   496                    || ( ( !MmMtpDpUtility::IsVideoL( aObject.DesC( CMTPObjectMetaData::ESuid ), iFramework ) )
       
   497                         && ( propCode == EMTPObjectPropCodeDateAdded ) ) )
       
   498                     {
       
   499                     textData = CMTPTypeString::NewLC(); // + textData
       
   500 
       
   501                     TRAP( err, iDpConfig.GetWrapperL().GetObjectMetadataValueL( propCode,
       
   502                         *textData,
       
   503                         aObject ) );
       
   504 
       
   505                     PRINT1( _L( "MM MTP <> CCopyObject::GetPreviousPropertiesL::ServiceSpecificObjectPropertyL err = %d" ), err );
       
   506 
       
   507                     if ( err == KErrNone )
       
   508                         {
       
   509                         iPropertyElement = &(iPropertyList->ReservePropElemL(handle, propCode));
       
   510                         iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, textData->StringChars());
       
   511 //                        iPropertyElement = CMTPTypeObjectPropListElement::NewL(
       
   512 //                                handle, propCode, *textData );
       
   513                         }
       
   514                     else if ( err == KErrNotFound )
       
   515                         {
       
   516                         iPropertyElement = NULL;
       
   517                         }
       
   518                     else
       
   519                         {
       
   520                         User::Leave( err );
       
   521                         }
       
   522 
       
   523                     CleanupStack::PopAndDestroy( textData ); // - textData
       
   524                     }
       
   525                 break;
       
   526 
       
   527             default:
       
   528                 {
       
   529                 ServiceGetSpecificObjectPropertyL( propCode, handle, aObject );
       
   530                 }
       
   531                 break;
       
   532             }
       
   533 
       
   534         if ( iPropertyElement )
       
   535             {
       
   536             iPropertyList->CommitPropElemL( *iPropertyElement );
       
   537             iPropertyElement = NULL;
       
   538             }
       
   539         } // end of for loop
       
   540 
       
   541     PRINT1( _L( "MM MTP <= CCopyObject::GetPreviousPropertiesL err = %d" ), err );
       
   542     }
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CCopyObject::ServiceMetaDataToWrapper
       
   546 //
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 EXPORT_C TMTPResponseCode CCopyObject::ServiceMetaDataToWrapper(
       
   550     const TUint16 aPropCode,
       
   551     MMTPType& aNewData,
       
   552     const CMTPObjectMetaData& aObject )
       
   553     {
       
   554     TMTPResponseCode resCode = EMTPRespCodeOK;
       
   555 
       
   556     TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode,
       
   557         aNewData,
       
   558         aObject ) );
       
   559 
       
   560     PRINT1( _L("MM MTP <> CCopyObject::ServiceMetaDataToWrapper err = %d"), err);
       
   561 
       
   562     if ( err == KErrNone )
       
   563         {
       
   564         resCode = EMTPRespCodeOK;
       
   565         }
       
   566     else if ( err == KErrTooBig )
       
   567         // according to the codes of S60
       
   568         {
       
   569         resCode = EMTPRespCodeInvalidDataset;
       
   570         }
       
   571     else if ( err == KErrPermissionDenied )
       
   572         {
       
   573         resCode = EMTPRespCodeAccessDenied;
       
   574         }
       
   575     else if ( err == KErrNotFound )
       
   576         {
       
   577         if ( MmMtpDpUtility::HasMetadata( aObject.Uint( CMTPObjectMetaData::EFormatCode ) ) )
       
   578             resCode = EMTPRespCodeAccessDenied;
       
   579         else
       
   580             resCode = EMTPRespCodeOK;
       
   581         }
       
   582     else
       
   583         {
       
   584         resCode = EMTPRespCodeGeneralError;
       
   585         }
       
   586 
       
   587     PRINT1( _L("MM MTP <= CCopyObject::ServiceMetaDataToWrapper resCode = 0x%x"), resCode);
       
   588 
       
   589     return resCode;
       
   590     }
       
   591 
       
   592 // -----------------------------------------------------------------------------
       
   593 // CCopyObject::SetPreviousPropertiesL
       
   594 // Set the object properties after doing the copy
       
   595 // -----------------------------------------------------------------------------
       
   596 //
       
   597 void CCopyObject::SetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
       
   598     {
       
   599     PRINT( _L( "MM MTP => CCopyObject::SetPreviousPropertiesL" ) );
       
   600     const TInt count( iPropertyList->NumberOfElements() );
       
   601     PRINT1( _L( "MM MTP <> CCopyObject::SetPreviousPropertiesL count = %d" ), count );
       
   602     TMTPResponseCode respcode = EMTPRespCodeOK;
       
   603     CMTPTypeString* stringData = NULL;
       
   604     iPropertyList->ResetCursor();
       
   605     for ( TInt i = 0; i < count; i++ )
       
   606         {
       
   607         CMTPTypeObjectPropListElement& element = iPropertyList->GetNextElementL();
       
   608 
       
   609         TUint32 handle = element.Uint32L(
       
   610                 CMTPTypeObjectPropListElement::EObjectHandle );
       
   611         TUint16 propertyCode = element.Uint16L(
       
   612                 CMTPTypeObjectPropListElement::EPropertyCode );
       
   613         TUint16 dataType = element.Uint16L(
       
   614                 CMTPTypeObjectPropListElement::EDatatype );
       
   615         PRINT3( _L( "MM MTP <> CCopyObject::SetPreviousPropertiesL = 0x%x, propertyCode = 0x%x, dataType = 0x%x" ),
       
   616           handle, propertyCode, dataType );
       
   617 
       
   618         switch ( propertyCode )
       
   619             {
       
   620             case EMTPObjectPropCodeStorageID:
       
   621             case EMTPObjectPropCodeObjectFormat:
       
   622             case EMTPObjectPropCodeProtectionStatus:
       
   623             case EMTPObjectPropCodeObjectSize:
       
   624             case EMTPObjectPropCodeObjectFileName:
       
   625             case EMTPObjectPropCodeParentObject:
       
   626             case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
       
   627             case EMTPObjectPropCodeNonConsumable:
       
   628             case EMTPObjectPropCodeDateCreated:
       
   629             case EMTPObjectPropCodeDateModified:
       
   630             case EMTPObjectPropCodeDateAdded:
       
   631                 break;
       
   632 
       
   633             case EMTPObjectPropCodeName:
       
   634                 {
       
   635                 stringData = CMTPTypeString::NewLC(
       
   636                     element.StringL(
       
   637                     CMTPTypeObjectPropListElement::EValue)); // + stringData
       
   638 
       
   639                 respcode = ServiceMetaDataToWrapper( propertyCode,
       
   640                     *stringData,
       
   641                     aObject );
       
   642 
       
   643                 CleanupStack::PopAndDestroy( stringData ); // - stringData
       
   644                 }
       
   645                 break;
       
   646 
       
   647             default:
       
   648                 {
       
   649                 respcode = ServiceSetSpecificObjectPropertyL( propertyCode,
       
   650                         aObject,
       
   651                         element );
       
   652                 }
       
   653                 break;
       
   654             }
       
   655         } // end of for loop
       
   656 
       
   657     if( respcode == EMTPRespCodeOK )
       
   658         {
       
   659         // do nothing, ignore warning
       
   660         }
       
   661 
       
   662     PRINT1( _L( "MM MTP <= CCopyObject::SetPreviousPropertiesL respcode = 0x%x" ), respcode );
       
   663     }
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CCopyObject::UpdateObjectInfoL
       
   667 // Update object info in the database
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 TUint32 CCopyObject::UpdateObjectInfoL( const TDesC& aOldObjectName, const TDesC& aNewObjectName )
       
   671     {
       
   672     PRINT2( _L( "MM MTP => CCopyObject::UpdateObjectInfoL aOldObjectName = %S, aNewObjectName = %S" ),
       
   673             &aOldObjectName, &aNewObjectName );
       
   674     // We should not modify this object's handle, so just get a "copy".
       
   675     CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
       
   676     const TMTPTypeUint32 objectHandle( iObjectInfo->Uint( CMTPObjectMetaData::EHandle ) );
       
   677     if ( iFramework.ObjectMgr().ObjectL( objectHandle, *objectInfo) )
       
   678         {
       
   679         objectInfo->SetDesCL( CMTPObjectMetaData::ESuid, aNewObjectName );
       
   680         objectInfo->SetUint( CMTPObjectMetaData::EParentHandle,
       
   681                 iNewParentHandle );
       
   682         // Modify storage Id.
       
   683         objectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
       
   684         iFramework.ObjectMgr().InsertObjectL( *objectInfo );
       
   685         }
       
   686     else
       
   687         {
       
   688         User::Leave( KErrCorrupt );
       
   689         }
       
   690 
       
   691     TUint32 handle = objectInfo->Uint( CMTPObjectMetaData::EHandle );
       
   692     PRINT1( _L( "MM MTP <> CCopyObject::UpdateObjectInfoL handle = 0x%x" ), handle );
       
   693     SetPropertiesL( aOldObjectName, aNewObjectName, *objectInfo );
       
   694     CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
       
   695     PRINT( _L( "MM MTP <= CCopyObject::UpdateObjectInfoL" ) );
       
   696     return handle;
       
   697     }
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // CCopyObject::CopyAndUpdateL
       
   701 // Move a single object and update the database
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 void CCopyObject::CopyAndUpdateL( TUint32 aObjectHandle )
       
   705     {
       
   706     PRINT1( _L( "MM MTP => CopyObject::CopyAndUpdateL aObjectHanlde = 0x%x" ), aObjectHandle );
       
   707     CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
       
   708 
       
   709     if ( iFramework.ObjectMgr().ObjectL( aObjectHandle, *objectInfo ) )
       
   710         {
       
   711         // This is used to keep the same behavior in mass storage and device file manager.
       
   712         if ( objectInfo->Uint( CMTPObjectMetaData::EFormatCode )
       
   713             == EMTPFormatCodeAbstractAudioVideoPlaylist )
       
   714             {
       
   715             PRINT( _L( "MM MTP <> CopyObject::CopyAndUpdateL Playlist file don't to be copieds" ) );
       
   716             CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
       
   717             return;
       
   718             }
       
   719 
       
   720         RBuf fileName; // This is the source object name.
       
   721         fileName.CleanupClosePushL(); // + fileName
       
   722         fileName.CreateL( KMaxFileName );
       
   723 
       
   724         RBuf oldFileName;
       
   725         oldFileName.CleanupClosePushL(); // + oldFileName
       
   726         oldFileName.CreateL( KMaxFileName );
       
   727 
       
   728         RBuf rightPartName;
       
   729         rightPartName.CleanupClosePushL(); // + rightPartName
       
   730         rightPartName.CreateL( KMaxFileName );
       
   731 
       
   732         fileName = objectInfo->DesC( CMTPObjectMetaData::ESuid );
       
   733         oldFileName = fileName;
       
   734 
       
   735         rightPartName = fileName.Right( fileName.Length()
       
   736             - iPathToCopy->Length() );
       
   737 
       
   738         if ( ( iNewRootFolder->Length() + rightPartName.Length() ) > fileName.MaxLength() )
       
   739             {
       
   740             User::Leave( KErrCorrupt );
       
   741             }
       
   742 
       
   743         fileName.Zero();
       
   744         fileName.Append( *iNewRootFolder );
       
   745         fileName.Append( rightPartName );
       
   746         PRINT1( _L( "MM MTP <> CopyAndUpdateL fileName = %S" ), &fileName );
       
   747 
       
   748         if ( objectInfo->Uint( CMTPObjectMetaData::EDataProviderId )
       
   749             == iFramework.DataProviderId() )
       
   750             {
       
   751             // should copy before the set metadata DB
       
   752             GetPreviousPropertiesL( *objectInfo );
       
   753             TInt err = iFileMan->Copy( oldFileName, fileName );
       
   754             PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL err = %d" ), err );
       
   755             User::LeaveIfError( err );
       
   756             User::LeaveIfError( iFramework.Fs().SetModified( fileName,
       
   757                 iPreviousModifiedTime ) );
       
   758 
       
   759             // Modify Suid
       
   760             objectInfo->SetDesCL( CMTPObjectMetaData::ESuid, fileName );
       
   761 
       
   762             // Modify parentHandle
       
   763             TParsePtrC parentSuid( fileName );
       
   764             PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL parentSuid = %S" ), &(parentSuid.DriveAndPath()) );
       
   765 
       
   766             TUint32 parentHandle = iFramework.ObjectMgr().HandleL( parentSuid.DriveAndPath() );
       
   767             objectInfo->SetUint( CMTPObjectMetaData::EParentHandle, parentHandle );
       
   768             PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL parentHandle = 0x%x" ), parentHandle );
       
   769 
       
   770             // Modify storage Id.
       
   771             objectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
       
   772             TRAP( err, iFramework.ObjectMgr().InsertObjectL( *objectInfo ) );
       
   773             if ( err != KErrNone )
       
   774                 PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL err = %d" ), err );
       
   775             // Set the properties of the new object
       
   776             SetPropertiesL( oldFileName, fileName, *objectInfo );
       
   777             }
       
   778         // Else this is not the owner of this object, so don't update the object store.
       
   779 
       
   780         CleanupStack::PopAndDestroy( &rightPartName ); // - rightPartName
       
   781         CleanupStack::PopAndDestroy( &oldFileName ); // - oldFileName
       
   782         CleanupStack::PopAndDestroy( &fileName ); // - fileName
       
   783         }
       
   784     else
       
   785         {
       
   786         User::Leave( KErrCorrupt );
       
   787         }
       
   788 
       
   789     CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
       
   790 
       
   791     PRINT( _L( "MM MTP <= CopyObject::CopyAndUpdateL" ) );
       
   792     }
       
   793 
       
   794 // -----------------------------------------------------------------------------
       
   795 // CCopyObject::SetPropertiesL
       
   796 // Set the object properties in the object property store
       
   797 // -----------------------------------------------------------------------------
       
   798 //
       
   799 void CCopyObject::SetPropertiesL( const TDesC& aOldFileName,
       
   800         const TDesC& aNewFileName,
       
   801         const CMTPObjectMetaData& aObject )
       
   802     {
       
   803     PRINT( _L( "MM MTP => CCopyObject::SetPropertiesL" ) );
       
   804     // won't leave with KErrAlreadyExist
       
   805     iDpConfig.GetWrapperL().AddObjectL( aNewFileName );
       
   806 
       
   807     TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
       
   808     if ( formatCode == EMTPFormatCodeM3UPlaylist )
       
   809         {
       
   810         MMTPReferenceMgr& referenceMgr = iFramework.ReferenceMgr();
       
   811         CDesCArray* references = referenceMgr.ReferencesLC( aOldFileName ); // + references
       
   812         referenceMgr.SetReferencesL( aNewFileName, *references );
       
   813         CleanupStack::PopAndDestroy( references ); // - references
       
   814         }
       
   815 
       
   816     SetPreviousPropertiesL( aObject );
       
   817     PRINT( _L( "MM MTP <= CCopyObject::SetPropertiesL" ) );
       
   818     }
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // CCopyObject::RunError
       
   822 //
       
   823 // -----------------------------------------------------------------------------
       
   824 //
       
   825 EXPORT_C TInt CCopyObject::RunError( TInt aError )
       
   826     {
       
   827     if ( aError != KErrNone )
       
   828         PRINT1( _L( "MM MTP <> CCopyObject::RunError aError = %d" ), aError );
       
   829 
       
   830     TRAP_IGNORE( SendResponseL( EMTPRespCodeGeneralError ) );
       
   831     return KErrNone;
       
   832     }
       
   833 
       
   834 // end of file