mtpfws/mtpfw/dataproviders/dputility/src/cmtpsendobjectinfo.cpp
changeset 0 d0791faffa3f
child 2 4843bb5893b6
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <f32file.h>
       
    17 #include <bautils.h>
       
    18 #include <mtp/cmtpdataproviderplugin.h>
       
    19 #include <mtp/mmtpdataproviderframework.h>
       
    20 
       
    21 #include <mtp/cmtpobjectmetadata.h>
       
    22 #include <mtp/cmtptypefile.h>
       
    23 #include <mtp/cmtptypeobjectinfo.h>
       
    24 #include <mtp/cmtptypeobjectproplist.h>
       
    25 #include <mtp/cmtptypestring.h>
       
    26 #include <mtp/mmtpobjectmgr.h>
       
    27 #include <mtp/mmtpstoragemgr.h>
       
    28 #include <mtp/mtpprotocolconstants.h>
       
    29 
       
    30 
       
    31 #include <mtp/tmtptyperequest.h>
       
    32 #include "cmtpconnection.h"
       
    33 #include "cmtpconnectionmgr.h"
       
    34 #include "cmtpsendobjectinfo.h"
       
    35 #include "mtpdppanic.h"
       
    36 #include "cmtpfsexclusionmgr.h"
       
    37 #include "cmtpdataprovidercontroller.h"
       
    38 #include "cmtpdataprovider.h"
       
    39 
       
    40 
       
    41 // Class constants.
       
    42 __FLOG_STMT(_LIT8(KComponent,"SendObjectInfo");)
       
    43 
       
    44 /**
       
    45 Verification data for the SendObjectInfo request
       
    46 */
       
    47 const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] = 
       
    48     {
       
    49         {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0},                
       
    50         {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, EMTPElementAttrDir, 2, KMTPHandleAll, KMTPHandleNone}
       
    51     };
       
    52 
       
    53 
       
    54 /**
       
    55 Two-phase construction method
       
    56 @param aFramework  The data provider framework
       
    57 @param aConnection The connection from which the request comes
       
    58 @return a pointer to the created request processor object
       
    59 */ 
       
    60 EXPORT_C MMTPRequestProcessor* CMTPSendObjectInfo::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection)
       
    61     {
       
    62     CMTPSendObjectInfo* self = new (ELeave) CMTPSendObjectInfo(aFramework, aConnection);
       
    63     CleanupStack::PushL(self);
       
    64     self->ConstructL();
       
    65     CleanupStack::Pop(self);
       
    66     return self;
       
    67     }
       
    68 
       
    69 /**
       
    70 Destructor
       
    71 */    
       
    72 EXPORT_C CMTPSendObjectInfo::~CMTPSendObjectInfo()
       
    73     {
       
    74     __FLOG(_L8("~CMTPSendObjectInfo - Entry"));
       
    75     
       
    76     if ((iProgress == EObjectInfoSucceed ||
       
    77         iProgress == EObjectInfoFail || 
       
    78         iProgress == EObjectInfoInProgress) && !iNoRollback)
       
    79         {
       
    80         // Not finished SendObjectInfo/PropList SendObject pair detected.
       
    81         Rollback();
       
    82         }
       
    83     
       
    84     iDpSingletons.Close();
       
    85     delete iDateMod;
       
    86     delete iFileReceived;
       
    87     delete iParentSuid;    
       
    88     delete iReceivedObject;
       
    89     delete iObjectInfo;
       
    90     delete iObjectPropList;
       
    91     iSingletons.Close();
       
    92     __FLOG(_L8("~CMTPSendObjectInfo - Exit"));
       
    93     __FLOG_CLOSE; 
       
    94     }
       
    95 
       
    96 /**
       
    97 Standard c++ constructor
       
    98 @param aFramework    The data provider framework
       
    99 @param aConnection    The connection from which the request comes
       
   100 */    
       
   101 CMTPSendObjectInfo::CMTPSendObjectInfo(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) :
       
   102     CMTPRequestProcessor(aFramework, aConnection, 0, NULL)
       
   103     {
       
   104     }
       
   105 
       
   106 /**
       
   107 Verify the request
       
   108 @return EMTPRespCodeOK if request is verified, otherwise one of the error response codes
       
   109 */    
       
   110 TMTPResponseCode CMTPSendObjectInfo::CheckRequestL()
       
   111     {
       
   112     __FLOG(_L8("CheckRequestL - Entry"));
       
   113     TMTPResponseCode result = CheckSendingStateL();
       
   114     
       
   115     if (result != EMTPRespCodeOK) 
       
   116         {
       
   117         return result;
       
   118         }
       
   119     
       
   120     if (iProgress == EObjectNone)    //this is the SendObjectInfo phase
       
   121         {
       
   122         iElementCount = sizeof(KMTPSendObjectInfoPolicy) / sizeof(TMTPRequestElementInfo);
       
   123         iElements = KMTPSendObjectInfoPolicy;            
       
   124         }
       
   125     else if (iProgress == EObjectInfoSucceed)
       
   126         {
       
   127         iElementCount = 0;
       
   128         iElements = NULL;
       
   129         }
       
   130     //coverity[var_deref_model]
       
   131 	result = CMTPRequestProcessor::CheckRequestL();     	
       
   132  
       
   133     if (EMTPRespCodeOK == result)
       
   134         {
       
   135         result = MatchStoreAndParentL();
       
   136         }
       
   137         
       
   138     if (result == EMTPRespCodeOK && iOperationCode == EMTPOpCodeSendObjectPropList)
       
   139         {
       
   140         TMTPFormatCode formatCode = static_cast<TMTPFormatCode>(Request().Uint32(TMTPTypeRequest::ERequestParameter3));
       
   141         if (!iDpSingletons.ExclusionMgrL().IsFormatValid(formatCode))
       
   142             {
       
   143             result = EMTPRespCodeInvalidObjectFormatCode;
       
   144             }
       
   145         else
       
   146             {
       
   147             iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   148             TUint32 objectSizeHigh = Request().Uint32(TMTPTypeRequest::ERequestParameter4);
       
   149             TUint32 objectSizeLow = Request().Uint32(TMTPTypeRequest::ERequestParameter5);
       
   150             if (iStorageId == KMTPStorageDefault)
       
   151                 {
       
   152                 iStorageId = iFramework.StorageMgr().DefaultStorageId();
       
   153                 }
       
   154             iObjectSize = MAKE_TUINT64(objectSizeHigh, objectSizeLow);
       
   155             if (IsTooLarge(iObjectSize))
       
   156                 {
       
   157                 result = EMTPRespCodeObjectTooLarge;            
       
   158                 }
       
   159          	   
       
   160             //File size is limited to KMaxTInt64 that is 8ExaBytes
       
   161             //if the object size is more,then report this error.
       
   162             if (!CanStoreFileL(iStorageId, iObjectSize)||(iObjectSize > (KMaxTInt64)))
       
   163                 {
       
   164                 result = EMTPRespCodeStoreFull;
       
   165                 }
       
   166             }
       
   167         }
       
   168         
       
   169     // If the previous request is not SendObjectInfo or SendObjectPropList, SendObject fails
       
   170     if (result == EMTPRespCodeOK && iOperationCode == EMTPOpCodeSendObject)
       
   171         {
       
   172         if (iPreviousTransactionID + 1 != Request().Uint32(TMTPTypeRequest::ERequestTransactionID))
       
   173             {
       
   174             result = EMTPRespCodeNoValidObjectInfo;
       
   175             }
       
   176         }
       
   177         
       
   178     __FLOG_VA((_L8("Result = 0x%04X"), result));
       
   179     __FLOG(_L8("CheckRequestL - Exit"));
       
   180     return result;    
       
   181     }
       
   182     
       
   183 TBool CMTPSendObjectInfo::HasDataphase() const
       
   184     {
       
   185     return ETrue;
       
   186     }
       
   187 
       
   188 /**
       
   189 SendObjectInfo/SendObject request handler
       
   190 NOTE: SendObjectInfo has to be comes before SendObject requests.  To maintain the state information
       
   191 between the two requests, the two requests are combined together in one request processor.
       
   192 */    
       
   193 void CMTPSendObjectInfo::ServiceL()
       
   194     {
       
   195     __FLOG(_L8("ServiceL - Entry"));
       
   196     if (iProgress == EObjectNone)
       
   197         {
       
   198         iIsFolder = EFalse;
       
   199         if (iOperationCode == EMTPOpCodeSendObjectInfo)
       
   200             {
       
   201             ServiceSendObjectInfoL();
       
   202             }
       
   203         else
       
   204             {
       
   205             ServiceSendObjectPropListL();
       
   206             }
       
   207         }
       
   208     else
       
   209         {
       
   210         ServiceSendObjectL();
       
   211         }    
       
   212     __FLOG(_L8("ServiceL - Exit"));
       
   213     }
       
   214 
       
   215 /**
       
   216 Second-phase construction
       
   217 */        
       
   218 void CMTPSendObjectInfo::ConstructL()
       
   219     {
       
   220     __FLOG_OPEN(KMTPSubsystem, KComponent);
       
   221     __FLOG(_L8("ConstructL - Entry")); 
       
   222     iExpectedSendObjectRequest.SetUint16(TMTPTypeRequest::ERequestOperationCode, EMTPOpCodeSendObject);
       
   223     iReceivedObject = CMTPObjectMetaData::NewL();
       
   224     iReceivedObject->SetUint(CMTPObjectMetaData::EDataProviderId, iFramework.DataProviderId());
       
   225     iDpSingletons.OpenL(iFramework);
       
   226     iNoRollback = EFalse;
       
   227     iSingletons.OpenL();
       
   228     __FLOG(_L8("ConstructL - Exit"));
       
   229     }
       
   230 
       
   231 /**
       
   232 Override to match both the SendObjectInfo and SendObject requests
       
   233 @param aRequest    The request to match
       
   234 @param aConnection The connection from which the request comes
       
   235 @return ETrue if the processor can handle the request, otherwise EFalse
       
   236 */        
       
   237 TBool CMTPSendObjectInfo::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
       
   238     {
       
   239     __FLOG(_L8("Match - Entry"));
       
   240     TBool result = EFalse;
       
   241     TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   242     if ((operationCode == EMTPOpCodeSendObjectInfo || 
       
   243         operationCode == EMTPOpCodeSendObject ||
       
   244         operationCode == EMTPOpCodeSendObjectPropList) &&
       
   245         &iConnection == &aConnection)
       
   246         {
       
   247         result = ETrue;
       
   248         }
       
   249     __FLOG(_L8("Match - Exit"));
       
   250     return result;    
       
   251     }
       
   252 
       
   253 /**
       
   254 Override to handle the response phase of SendObjectInfo and SendObject requests
       
   255 @return EFalse
       
   256 */
       
   257 TBool CMTPSendObjectInfo::DoHandleResponsePhaseL()
       
   258     {
       
   259     __FLOG(_L8("DoHandleResponsePhaseL - Entry"));
       
   260     //to check if the sending/receiving data is successful
       
   261     TBool successful = !iCancelled;
       
   262     if (iProgress == EObjectInfoInProgress)
       
   263         {
       
   264         if (iOperationCode == EMTPOpCodeSendObjectInfo)
       
   265             {            
       
   266             successful = DoHandleSendObjectInfoCompleteL();
       
   267             }
       
   268         else
       
   269             {
       
   270             successful = DoHandleSendObjectPropListCompleteL();
       
   271             }
       
   272         iProgress = (successful ? EObjectInfoSucceed : EObjectInfoFail);
       
   273         if(iIsFolder && iProgress == EObjectInfoSucceed)
       
   274 			{
       
   275 			iProgress = EObjectNone;
       
   276 			}
       
   277         }
       
   278     else if (iProgress == ESendObjectInProgress)
       
   279         {
       
   280         successful = DoHandleSendObjectCompleteL();
       
   281         iProgress = (successful ? ESendObjectSucceed : ESendObjectFail);
       
   282         }
       
   283         
       
   284     __FLOG(_L8("DoHandleResponsePhaseL - Exit"));
       
   285     return EFalse;
       
   286     }
       
   287 
       
   288 /**
       
   289 Override to handle the completing phase of SendObjectInfo and SendObject requests
       
   290 @return ETrue if succesfully received the file, otherwise EFalse
       
   291 */    
       
   292 TBool CMTPSendObjectInfo::DoHandleCompletingPhaseL()
       
   293     {
       
   294     __FLOG(_L8("DoHandleCompletingPhaseL - Entry"));
       
   295     TBool result = ETrue;
       
   296     CMTPRequestProcessor::DoHandleCompletingPhaseL();
       
   297     if (iProgress == EObjectInfoSucceed)
       
   298         {
       
   299         if (iOperationCode == EMTPOpCodeSendObjectInfo || iOperationCode == EMTPOpCodeSendObjectPropList)
       
   300             {
       
   301             iPreviousTransactionID = Request().Uint32(TMTPTypeRequest::ERequestTransactionID);
       
   302             }
       
   303         result = EFalse;
       
   304         }
       
   305     else if (iProgress == ESendObjectFail)
       
   306         {
       
   307         if (iOperationCode == EMTPOpCodeSendObject)
       
   308             {
       
   309             iPreviousTransactionID++;
       
   310             }
       
   311         iProgress = EObjectInfoSucceed;
       
   312         result = EFalse;
       
   313         }
       
   314     
       
   315     __FLOG(_L8("DoHandleCompletingPhaseL - Exit"));
       
   316     return result;    
       
   317     }
       
   318 
       
   319 
       
   320 /**
       
   321 Verify if the SendObject request comes after SendObjectInfo request
       
   322 @return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
       
   323 EMTPRespCodeNoValidObjectInfo
       
   324 */
       
   325 TMTPResponseCode CMTPSendObjectInfo::CheckSendingStateL()
       
   326     {
       
   327     __FLOG(_L8("CheckSendingState - Entry"));
       
   328     TMTPResponseCode result = EMTPRespCodeOK;
       
   329     iOperationCode = Request().Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   330 
       
   331     if (iOperationCode == EMTPOpCodeSendObject)
       
   332     	{
       
   333     	//In ParseRouter everytime SendObject gets resolved then will be removed from Registry
       
   334     	//Right away therefore we need reRegister it here again in case possible cancelRequest
       
   335     	//Against this SendObject being raised.
       
   336     	iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
   337     	iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
   338        	}        
       
   339     
       
   340     if (iProgress == EObjectNone)
       
   341         {
       
   342         if (iOperationCode == EMTPOpCodeSendObject)
       
   343             {
       
   344             result = EMTPRespCodeNoValidObjectInfo;
       
   345             }        
       
   346         }
       
   347     else if (iProgress == EObjectInfoSucceed) 
       
   348         {
       
   349         if (iOperationCode == EMTPOpCodeSendObjectInfo || iOperationCode == EMTPOpCodeSendObjectPropList)
       
   350             {
       
   351             //SendObjectInfo/SendObjectPropList sending the folder over which not necessarily
       
   352             //being followed by SendObject as per MTP Specification in which case we need unregister RouteRequest of 
       
   353             //SendObject made by previous SendObjectInfo/SendObjectPropList transaction without SendObject being followed.
       
   354             if( iIsFolder )
       
   355             	{
       
   356             	iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   357         		}
       
   358         
       
   359             delete iObjectInfo;
       
   360             iObjectInfo = NULL;
       
   361             delete iObjectPropList;
       
   362             iObjectPropList = NULL;
       
   363             iProgress = EObjectNone;
       
   364             }
       
   365         }
       
   366     else 
       
   367         {
       
   368         Panic(EMTPDpSendObjectStateInvalid);
       
   369         }
       
   370     __FLOG(_L8("CheckSendingState - Exit"));
       
   371     return result;    
       
   372     }
       
   373 
       
   374 /**
       
   375 SendObjectInfo request handler
       
   376 */
       
   377 void CMTPSendObjectInfo::ServiceSendObjectInfoL()
       
   378     {
       
   379     __FLOG(_L8("ServiceSendObjectInfoL - Entry"));
       
   380     delete iObjectInfo;
       
   381     iObjectInfo = NULL;
       
   382     iObjectInfo = CMTPTypeObjectInfo::NewL();
       
   383     iCancelled = EFalse;
       
   384     ReceiveDataL(*iObjectInfo);
       
   385     iProgress = EObjectInfoInProgress;
       
   386     __FLOG(_L8("ServiceSendObjectInfoL - Exit"));
       
   387     }
       
   388 
       
   389 /**
       
   390 SendObjectPropList request handler
       
   391 */
       
   392 void CMTPSendObjectInfo::ServiceSendObjectPropListL()
       
   393     {
       
   394     __FLOG(_L8("ServiceSendObjectPropListL - Entry"));
       
   395     delete iObjectPropList;
       
   396     iObjectPropList = NULL;
       
   397     iObjectPropList = CMTPTypeObjectPropList::NewL();
       
   398     iCancelled = EFalse;
       
   399     iReceivedObject->SetUint(CMTPObjectMetaData::EFormatCode, iRequest->Uint32(TMTPTypeRequest::ERequestParameter3));
       
   400     ReceiveDataL(*iObjectPropList);
       
   401     iProgress = EObjectInfoInProgress;
       
   402     __FLOG(_L8("ServiceSendObjectPropListL - Exit"));
       
   403     }
       
   404     
       
   405 /**
       
   406 SendObject request handler
       
   407 */    
       
   408 void CMTPSendObjectInfo::ServiceSendObjectL()
       
   409     {
       
   410     __FLOG(_L8("ServiceSendObjectL - Entry"));
       
   411     if (iIsFolder)
       
   412         {
       
   413         // A generic folder doesn't have anything interesting during its data phase
       
   414         ReceiveDataL(iNullObject);
       
   415         }
       
   416     else    
       
   417         {        
       
   418         ReceiveDataL(*iFileReceived);
       
   419         }
       
   420     
       
   421     iProgress = ESendObjectInProgress;
       
   422     __FLOG(_L8("ServiceSendObjectL - Exit"));
       
   423     }
       
   424 
       
   425 /**
       
   426 Get a default parent object, if the request does not specify a parent object.
       
   427 */
       
   428 void CMTPSendObjectInfo::GetDefaultParentObjectL()
       
   429     {    
       
   430     __FLOG(_L8("GetDefaultParentObjectL - Entry"));
       
   431     if (iStorageId == KMTPStorageDefault)
       
   432         {
       
   433         iStorageId = iFramework.StorageMgr().DefaultStorageId();
       
   434         }
       
   435     TInt drive(iFramework.StorageMgr().DriveNumber(iStorageId));
       
   436     User::LeaveIfError(drive);
       
   437 
       
   438     // Obtain the root of the drive.  Logical storages can sometimes have a filesystem root
       
   439     // other than <drive>:\ .  For example an MP3 DP might have a root of c:\media\music\
       
   440     // The DevDP needs to be aware of this when handling associations (folders) so they are
       
   441     // created in the correct location on the filesystem.
       
   442     delete iParentSuid;
       
   443     iParentSuid = NULL;
       
   444     iParentSuid=(iFramework.StorageMgr().StorageL(iStorageId).DesC(CMTPStorageMetaData::EStorageSuid)).AllocL();
       
   445     iReceivedObject->SetUint(CMTPObjectMetaData::EParentHandle, KMTPHandleNoParent);
       
   446     __FLOG(_L8("GetDefaultParentObjectL - Exit"));        
       
   447     }
       
   448 
       
   449 /**
       
   450 Get parent object and storage id
       
   451 @return EMTPRespCodeOK if successful, otherwise, EMTPRespCodeInvalidParentObject
       
   452 */
       
   453 TMTPResponseCode CMTPSendObjectInfo::GetParentObjectAndStorageIdL()
       
   454     {
       
   455     __FLOG(_L8("GetParentObjectAndStorageIdL - Entry"));    
       
   456     __ASSERT_DEBUG(iRequestChecker, Panic(EMTPDpRequestCheckNull));
       
   457 
       
   458     iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   459     iParentHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
       
   460     //does not take ownership
       
   461     CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iParentHandle);
       
   462 
       
   463     if (!parentObjectInfo)
       
   464         {
       
   465         GetDefaultParentObjectL();    
       
   466         }
       
   467     else
       
   468         {        
       
   469         delete iParentSuid;
       
   470         iParentSuid = NULL;
       
   471         iParentSuid = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL();
       
   472         iReceivedObject->SetUint(CMTPObjectMetaData::EParentHandle, iParentHandle);
       
   473         }
       
   474 
       
   475     __FLOG_VA((_L8("iParentSuid = %S"), iParentSuid));
       
   476     __FLOG(_L8("GetParentObjectAndStorageIdL - Exit"));    
       
   477     return EMTPRespCodeOK;
       
   478     }
       
   479 
       
   480 /**
       
   481 Handling the completing phase of SendObjectInfo request
       
   482 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   483 */    
       
   484 TBool CMTPSendObjectInfo::DoHandleSendObjectInfoCompleteL()
       
   485     {
       
   486     __FLOG(_L8("DoHandleSendObjectInfoCompleteL - Entry"));    
       
   487     TBool result(ETrue);
       
   488     TUint16 format(iObjectInfo->Uint16L(CMTPTypeObjectInfo::EObjectFormat));
       
   489     
       
   490     result = iDpSingletons.ExclusionMgrL().IsFormatValid(TMTPFormatCode(format));
       
   491     
       
   492     if (result)
       
   493         {
       
   494         __FLOG_VA((_L8("ASSOCIATION TYPE IS: %X"), iObjectInfo->Uint16L(CMTPTypeObjectInfo::EAssociationType)));        
       
   495 		if(format == EMTPFormatCodeAssociation)
       
   496 			{
       
   497 			if((iObjectInfo->Uint16L(CMTPTypeObjectInfo::EAssociationType) == EMTPAssociationTypeGenericFolder) ||
       
   498         		      (iObjectInfo->Uint16L(CMTPTypeObjectInfo::EAssociationType) == EMTPAssociationTypeUndefined))
       
   499 				iIsFolder = ETrue;
       
   500 			else{
       
   501 				SendResponseL(EMTPRespCodeInvalidDataset);
       
   502 	            result = EFalse;	
       
   503 				}
       
   504 			}
       
   505         delete iDateMod;
       
   506         iDateMod = NULL;
       
   507     
       
   508         iDateMod = iObjectInfo->StringCharsL(CMTPTypeObjectInfo::EDateModified).AllocL();
       
   509     
       
   510         TMTPResponseCode responseCode(GetParentObjectAndStorageIdL());
       
   511         if (responseCode != EMTPRespCodeOK)
       
   512             {
       
   513             SendResponseL(responseCode);
       
   514             result = EFalse;
       
   515             }
       
   516         }
       
   517     else
       
   518         {
       
   519         SendResponseL(EMTPRespCodeInvalidObjectFormatCode);
       
   520         }
       
   521         
       
   522     if (result)
       
   523         {
       
   524         iObjectSize = iObjectInfo->Uint32L(CMTPTypeObjectInfo::EObjectCompressedSize);
       
   525         
       
   526         if (IsTooLarge(iObjectSize))
       
   527             {
       
   528             SendResponseL(EMTPRespCodeObjectTooLarge);
       
   529             result = EFalse;            
       
   530             }
       
   531         if(result && !CanStoreFileL(iStorageId, iObjectSize))
       
   532             {
       
   533             SendResponseL(EMTPRespCodeStoreFull);
       
   534             result = EFalse;            
       
   535             }
       
   536         }
       
   537 
       
   538     if (result)
       
   539         {
       
   540         iProtectionStatus = iObjectInfo->Uint16L(CMTPTypeObjectInfo::EProtectionStatus);
       
   541         result = GetFullPathNameL(iObjectInfo->StringCharsL(CMTPTypeObjectInfo::EFilename));
       
   542         if (!result)
       
   543             {        
       
   544             // File and/or parent pathname invalid.
       
   545             SendResponseL(EMTPRespCodeInvalidDataset);
       
   546             }
       
   547         }
       
   548 
       
   549     if (result)
       
   550         {    
       
   551         result &= !Exists(iFullPath);
       
   552         if (!result)
       
   553             {        
       
   554             // Object with the same name already exists.
       
   555             iNoRollback = ETrue;
       
   556             SendResponseL(EMTPRespCodeAccessDenied);
       
   557             }
       
   558         }
       
   559     
       
   560     if (result)
       
   561         {
       
   562         iReceivedObject->SetUint(CMTPObjectMetaData::EFormatCode, format);
       
   563         
       
   564         if (iIsFolder)
       
   565         	{
       
   566         	iReceivedObject->SetUint(CMTPObjectMetaData::EFormatSubCode, EMTPAssociationTypeGenericFolder);
       
   567         	}
       
   568         	
       
   569         TRAPD(err, CreateFsObjectL());
       
   570         
       
   571         if (err != KErrNone)
       
   572             {
       
   573             SendResponseL(ErrorToMTPError(err));
       
   574             }
       
   575         else
       
   576             {
       
   577             ReserveObjectL();
       
   578             }
       
   579         }
       
   580     __FLOG(_L8("DoHandleSendObjectInfoCompleteL - Exit"));
       
   581     return result;    
       
   582     }
       
   583 
       
   584 /**
       
   585 Handling the completing phase of SendObjectPropList request
       
   586 @return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
       
   587 */    
       
   588 TBool CMTPSendObjectInfo::DoHandleSendObjectPropListCompleteL()
       
   589     {
       
   590     __FLOG(_L8("DoHandleSendObjectPropListCompleteL - Entry"));
       
   591     TBool result(ETrue);
       
   592     
       
   593     TMTPResponseCode responseCode(GetParentObjectAndStorageIdL());
       
   594     if (responseCode != EMTPRespCodeOK)
       
   595         {
       
   596         SendResponseL(responseCode);
       
   597         result = EFalse;
       
   598         }    
       
   599 
       
   600     if (result)
       
   601         {
       
   602         // Any kind of association is treated as a folder
       
   603         const TUint32 formatCode(Request().Uint32(TMTPTypeRequest::ERequestParameter3));
       
   604         iIsFolder = (formatCode == EMTPFormatCodeAssociation);
       
   605 
       
   606         TInt invalidParameterIndex = KErrNotFound;
       
   607         responseCode = VerifyObjectPropListL(invalidParameterIndex);
       
   608         result = (responseCode == EMTPRespCodeOK);    
       
   609         if (!result)
       
   610             {
       
   611             TUint32 parameters[4];
       
   612             parameters[0] = 0;
       
   613             parameters[1] = 0;
       
   614             parameters[2] = 0;
       
   615             parameters[3] = invalidParameterIndex;
       
   616             SendResponseL(responseCode, 4, parameters);
       
   617             }
       
   618         }
       
   619         
       
   620     if (result) 
       
   621         {
       
   622         result = !Exists(iFullPath);
       
   623         if (!result)
       
   624             {
       
   625             // Object with the same name already exists.
       
   626             iNoRollback = ETrue;
       
   627             SendResponseL(EMTPRespCodeAccessDenied);
       
   628             }
       
   629         }    
       
   630     
       
   631     if (result)
       
   632         {
       
   633         if (iIsFolder)
       
   634         	{
       
   635         	iReceivedObject->SetUint(CMTPObjectMetaData::EFormatSubCode, EMTPAssociationTypeGenericFolder);
       
   636         	}
       
   637         
       
   638         TRAPD(err, CreateFsObjectL());
       
   639         
       
   640         if (err != KErrNone)
       
   641             {
       
   642             SendResponseL(ErrorToMTPError(err));
       
   643             }
       
   644         else
       
   645             {
       
   646             ReserveObjectL();
       
   647             }
       
   648         }
       
   649         
       
   650     __FLOG(_L8("DoHandleSendObjectPropListCompleteL - Exit"));
       
   651     return result;    
       
   652     }
       
   653     
       
   654 /**
       
   655 Handling the completing phase of SendObject request
       
   656 @return ETrue if the object has been successfully saved on the device, otherwise, EFalse
       
   657 */    
       
   658 TBool CMTPSendObjectInfo::DoHandleSendObjectCompleteL()
       
   659     {
       
   660     __FLOG(_L8("DoHandleSendObjectCompleteL - Entry"));
       
   661     TBool result(ETrue);
       
   662         
       
   663     if (!iIsFolder)
       
   664         {        
       
   665         delete iFileReceived;
       
   666         iFileReceived = NULL;
       
   667         
       
   668         TEntry fileEntry;
       
   669         User::LeaveIfError(iFramework.Fs().Entry(iFullPath, fileEntry));
       
   670 
       
   671         if (fileEntry.FileSize() != iObjectSize)
       
   672             {
       
   673             iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   674             
       
   675             iFramework.Fs().Delete(iFullPath);
       
   676             iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObject);
       
   677             TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge;
       
   678             if (fileEntry.FileSize() < iObjectSize)
       
   679                 {
       
   680                 responseCode = EMTPRespCodeInvalidDataset;
       
   681                 }
       
   682             SendResponseL(responseCode);
       
   683             result = EFalse;
       
   684             }
       
   685         }
       
   686     
       
   687     
       
   688     // Get the result of the SendObject operation. 
       
   689     RMTPFramework frameworkSingletons;   
       
   690     frameworkSingletons.OpenL();
       
   691     TUint connectionId = iConnection.ConnectionId();
       
   692     CMTPConnectionMgr& connectionMgr = frameworkSingletons.ConnectionMgr();
       
   693     CMTPConnection& connection = connectionMgr.ConnectionL(connectionId);
       
   694     TInt ret = connection.GetDataReceiveResult(); 
       
   695     frameworkSingletons.Close();
       
   696      // SendObject is cancelled or connection is dropped.
       
   697     if(result && (iCancelled || (ret == KErrAbort)))
       
   698         {
       
   699         __FLOG(_L8("It is a cancel for sendObject."));
       
   700         iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   701         Rollback();
       
   702         SendResponseL(EMTPRespCodeTransactionCancelled);        
       
   703         }
       
   704     else if (result && !iCancelled)
       
   705 	    {
       
   706 	     iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
       
   707         
       
   708         //The MTP spec states that it is not mandatory for SendObjectInfo/SendObjectPropList
       
   709         //to be followed by a SendObject.  An object is reserved in the ObjectStore on 
       
   710         //receiving a SendObjectInfo/SendObjectPropList request, but we only commit it 
       
   711         //on receiving the corresponding SendObject request.  With Associations however 
       
   712         //we commit the object straight away as the SendObject phase is often absent 
       
   713         //with folder creation.
       
   714 
       
   715         if(!iIsFolder)
       
   716         	{
       
   717 			SetPropertiesL();    
       
   718         	iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObject);
       
   719         	
       
   720         	TParsePtrC file( iFullPath );
       
   721         	_LIT( KTxtExtensionODF, ".odf" );
       
   722         	if ( file.ExtPresent() && file.Ext().CompareF(KTxtExtensionODF)==0 )
       
   723         	    {;
       
   724         	    TUint32 DpId = iFramework.DataProviderId();
       
   725         	    DpId = iDpSingletons.MTPUtility().GetDpId(file.Ext().Mid(1),KNullDesC);
       
   726         	    //The data provider which owns all mimetypes of a file extension is not found 
       
   727         	    if ( 255 == DpId )
       
   728         	        {
       
   729         	        HBufC* mime = NULL;
       
   730         	        mime = iDpSingletons.MTPUtility().ContainerMimeType(iFullPath);
       
   731         	        if ( mime != NULL )
       
   732         	            {
       
   733         	            DpId = iDpSingletons.MTPUtility().GetDpId(file.Ext().Mid(1),*mime);
       
   734         	            delete mime;
       
   735         	            mime = NULL;
       
   736         	            }
       
   737         	        }
       
   738         	    if ( DpId!=iFramework.DataProviderId() && DpId!=255)
       
   739         	        {
       
   740         	        iReceivedObject->SetUint(CMTPObjectMetaData::EDataProviderId,DpId);
       
   741         	        //iReceivedObject->SetUint(CMTPObjectMetaData::EFormatCode,format);
       
   742         	        iFramework.ObjectMgr().ModifyObjectL(*iReceivedObject);
       
   743         	        TUint32 handle = iReceivedObject->Uint(CMTPObjectMetaData::EHandle);
       
   744         	        iSingletons.DpController().NotifyDataProvidersL(DpId,EMTPObjectAdded,(TAny*)&handle);
       
   745         	        }
       
   746         	    }
       
   747         	}
       
   748         
       
   749         SendResponseL(EMTPRespCodeOK);
       
   750 	    }
       
   751     __FLOG(_L8("DoHandleSendObjectCompleteL - Exit"));
       
   752     return result;
       
   753     }
       
   754 
       
   755 
       
   756 /**
       
   757 Get the full path name of the object to be saved
       
   758 @param aFileName, on entry, contains the file name of the object,
       
   759 on return, contains the full path name of the object to be saved
       
   760 @return ETrue if the name is valid, EFalse otherwise
       
   761 */
       
   762 TBool CMTPSendObjectInfo::GetFullPathNameL(const TDesC& aFileName)
       
   763     {
       
   764     __FLOG(_L8("GetFullPathNameL - Entry"));
       
   765     TBool result(EFalse);
       
   766     if (aFileName.Length() > 0)
       
   767         {
       
   768         iFullPath = *iParentSuid;
       
   769         if (iFullPath.Length() + aFileName.Length() < iFullPath.MaxLength())
       
   770             {
       
   771             iFullPath.Append(aFileName);
       
   772             if (iIsFolder)
       
   773                 {
       
   774                 iFullPath.Append(KPathDelimiter);
       
   775                 
       
   776                    TBool valid(EFalse);
       
   777                 if (BaflUtils::CheckWhetherFullNameRefersToFolder(iFullPath, valid) == KErrNone)
       
   778                     {
       
   779                     result = valid;
       
   780                     }
       
   781                 }
       
   782             else
       
   783                 {
       
   784                 result = iFramework.Fs().IsValidName(iFullPath);
       
   785                 }
       
   786             }
       
   787         }
       
   788 
       
   789 #ifdef __FLOG_ACTIVE
       
   790     TFileName tempName;
       
   791     tempName.Copy(iFullPath);
       
   792     tempName.Collapse();
       
   793     __FLOG_VA((_L8("iFullPath = %S, Result = %d"), &tempName, result));
       
   794     __FLOG(_L8("GetFullPathNameL - Exit"));
       
   795 #endif
       
   796     return result;
       
   797     }
       
   798 
       
   799 /**
       
   800 Check if we can store the file on the storage
       
   801 @return ETrue if yes, otherwise EFalse
       
   802 */
       
   803 TBool CMTPSendObjectInfo::CanStoreFileL(TUint32 aStorageId, TInt64 aObjectSize) const
       
   804     {
       
   805     __FLOG(_L8("CanStoreFileL - Entry"));
       
   806     TBool result(ETrue);
       
   807     if (aStorageId == KMTPStorageDefault)
       
   808         {
       
   809         aStorageId = iFramework.StorageMgr().DefaultStorageId();
       
   810         }
       
   811     TInt drive( iFramework.StorageMgr().DriveNumber(aStorageId) );
       
   812     User::LeaveIfError(drive);
       
   813     TVolumeInfo volumeInfo;
       
   814     User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive));
       
   815     if (volumeInfo.iFree < aObjectSize)
       
   816         {        
       
   817         result = EFalse;
       
   818         }
       
   819     __FLOG_VA((_L8("Result = %d"), result));
       
   820     __FLOG(_L8("CanStoreFileL - Exit"));
       
   821     return result;        
       
   822     }
       
   823 
       
   824 /**
       
   825 Check if the object is too large
       
   826 @return ETrue if yes, otherwise EFalse
       
   827 */
       
   828 TBool CMTPSendObjectInfo::IsTooLarge(TUint64 aObjectSize) const
       
   829     {
       
   830     __FLOG(_L8("IsTooLarge - Entry"));
       
   831     TBool ret(aObjectSize > KMaxTInt64);
       
   832     
       
   833     if(!ret)
       
   834         {
       
   835         TBuf<255> fsname;
       
   836         TUint32 storageId = iStorageId;
       
   837         if (storageId == KMTPStorageDefault)
       
   838             {
       
   839             storageId = iFramework.StorageMgr().DefaultStorageId();
       
   840             }
       
   841         TInt drive( iFramework.StorageMgr().DriveNumber(storageId) );
       
   842         User::LeaveIfError(drive);
       
   843         iFramework.Fs().FileSystemSubType(drive, fsname);        
       
   844         
       
   845         const TUint64 KMaxFatFileSize = 0xFFFFFFFF; //Maximal file size supported by all FAT filesystems (4GB-1)
       
   846         _LIT(KFsFAT16, "FAT16");
       
   847         _LIT(KFsFAT32, "FAT32");
       
   848         
       
   849         if((fsname.CompareF(KFsFAT16) == 0 || fsname.CompareF(KFsFAT32) == 0) && aObjectSize > KMaxFatFileSize)
       
   850             {
       
   851             ret = ETrue;
       
   852             }
       
   853         }
       
   854     __FLOG_VA((_L8("Result = %d"), ret));
       
   855     __FLOG(_L8("IsTooLarge - Exit"));
       
   856     return ret;
       
   857     }
       
   858     
       
   859 /**
       
   860 Check if the file already exists on the storage.
       
   861 @return ETrue if file is exists, otherwise EFalse
       
   862 */
       
   863 TBool CMTPSendObjectInfo::Exists(const TDesC& aName) const
       
   864     {
       
   865     __FLOG(_L8("Exists - Entry"));
       
   866     // This detects both files and folders
       
   867     TBool ret(EFalse); 
       
   868     ret = BaflUtils::FileExists(iFramework.Fs(), aName);
       
   869     __FLOG_VA((_L8("Result = %d"), ret));
       
   870     __FLOG(_L8("Exists - Exit"));
       
   871     return ret;
       
   872     }
       
   873 
       
   874 /**
       
   875 Check if the property list is valid and extract properties (file name)
       
   876 @param aInvalidParameterIndex if invalid, contains the index of the property.  Undefined, if it is valid.
       
   877 @return if error, one of the error response code; otherwise EMTPRespCodeOK
       
   878 */
       
   879 TMTPResponseCode CMTPSendObjectInfo::VerifyObjectPropListL(TInt& aInvalidParameterIndex)
       
   880     {
       
   881     __FLOG(_L8("VerifyObjectPropListL - Entry"));
       
   882     TMTPResponseCode responseCode(EMTPRespCodeOK);
       
   883     const TUint KCount(iObjectPropList->NumberOfElements());
       
   884 	iObjectPropList->ResetCursor();
       
   885     for (TUint i(0); (i < KCount); i++)
       
   886         {
       
   887 		CMTPTypeObjectPropListElement& KElement=iObjectPropList->GetNextElementL();
       
   888         const TUint32 KHandle(KElement.Uint32L(CMTPTypeObjectPropListElement::EObjectHandle));
       
   889         aInvalidParameterIndex = i;
       
   890         if (KHandle != KMTPHandleNone)
       
   891             {
       
   892             responseCode = EMTPRespCodeInvalidObjectHandle;            
       
   893             break;
       
   894             }
       
   895             
       
   896         responseCode = CheckPropCodeL(KElement);
       
   897         if (responseCode != EMTPRespCodeOK)
       
   898             {
       
   899             break;
       
   900             }
       
   901         responseCode = ExtractPropertyL(KElement);
       
   902         if (responseCode != EMTPRespCodeOK)
       
   903             {
       
   904             break;
       
   905             }        
       
   906         }
       
   907     __FLOG_VA((_L8("Result = 0x%04X"), responseCode));
       
   908     __FLOG(_L8("VerifyObjectPropListL - Exit"));
       
   909     return responseCode;        
       
   910     }
       
   911 
       
   912 /**
       
   913 Extracts the file information from the object property list element
       
   914 @param aElement an object property list element
       
   915 @param aPropertyCode MTP property code for the element
       
   916 @return MTP response code
       
   917 */
       
   918 TMTPResponseCode CMTPSendObjectInfo::ExtractPropertyL(const CMTPTypeObjectPropListElement& aElement)
       
   919     {
       
   920     __FLOG(_L8("ExtractPropertyL - Entry"));
       
   921     TMTPResponseCode responseCode(EMTPRespCodeOK);
       
   922     switch (aElement.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode))
       
   923         {
       
   924     case EMTPObjectPropCodeAssociationDesc:
       
   925         // Actually, any association is treated as a folder, and iIsFolder should already be set
       
   926         iIsFolder = ((aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) == EMTPAssociationTypeGenericFolder)||
       
   927 					(aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) == EMTPAssociationTypeUndefined));
       
   928         break;
       
   929         
       
   930     case EMTPObjectPropCodeObjectFileName:
       
   931         {
       
   932         const TDesC& KFileName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
       
   933         if (!GetFullPathNameL(KFileName))
       
   934             {
       
   935             responseCode = EMTPRespCodeInvalidDataset;
       
   936             }
       
   937         }
       
   938         break;
       
   939 
       
   940     case EMTPObjectPropCodeProtectionStatus:
       
   941         {
       
   942         iProtectionStatus = aElement.Uint16L(CMTPTypeObjectPropListElement::EValue);
       
   943         if (iProtectionStatus !=  EMTPProtectionNoProtection &&
       
   944             iProtectionStatus != EMTPProtectionReadOnly)
       
   945             {
       
   946             responseCode = EMTPRespCodeParameterNotSupported;
       
   947             }
       
   948         }
       
   949         break;
       
   950 
       
   951     case EMTPObjectPropCodeDateModified:
       
   952         delete iDateMod;
       
   953         iDateMod = NULL;
       
   954         iDateMod = aElement.StringL(CMTPTypeObjectPropListElement::EValue).AllocL();
       
   955         break;
       
   956     case EMTPObjectPropCodeName:
       
   957     	iName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
       
   958     	break;
       
   959     default:
       
   960         break;
       
   961         }
       
   962     __FLOG_VA((_L8("Result = 0x%04X"), responseCode));
       
   963     __FLOG(_L8("ExtractPropertyL - Exit"));
       
   964     return responseCode;    
       
   965     }
       
   966 
       
   967 /**
       
   968 Validates the data type for a given property code.
       
   969 @param aElement an object property list element
       
   970 @param aPropertyCode MTP property code for the element
       
   971 @return EMTPRespCodeOK if the combination is valid, or another MTP response code if not
       
   972 */
       
   973 TMTPResponseCode CMTPSendObjectInfo::CheckPropCodeL(const CMTPTypeObjectPropListElement& aElement) const
       
   974     {
       
   975     __FLOG(_L8("CheckPropCode - Entry"));
       
   976     TMTPResponseCode responseCode(EMTPRespCodeOK);
       
   977     switch(aElement.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode))
       
   978         {
       
   979     case EMTPObjectPropCodeStorageID:
       
   980         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32)
       
   981             {
       
   982             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   983             }
       
   984         else if (iStorageId != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue))
       
   985             {
       
   986             responseCode = EMTPRespCodeInvalidDataset;
       
   987             }
       
   988         break;
       
   989     
       
   990     case EMTPObjectPropCodeObjectFormat:
       
   991         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16)
       
   992             {
       
   993             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
   994             }
       
   995         else if (Request().Uint32(TMTPTypeRequest::ERequestParameter3) != aElement.Uint16L(CMTPTypeObjectPropListElement::EValue))
       
   996             {
       
   997             responseCode = EMTPRespCodeInvalidDataset;
       
   998             }
       
   999         break;
       
  1000        
       
  1001     case EMTPObjectPropCodeObjectSize:
       
  1002         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT64)
       
  1003             {
       
  1004             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1005             }
       
  1006         else if (iObjectSize != aElement.Uint64L(CMTPTypeObjectPropListElement::EValue))
       
  1007             {
       
  1008             responseCode = EMTPRespCodeInvalidDataset;
       
  1009             }
       
  1010         break;
       
  1011          
       
  1012     case EMTPObjectPropCodeParentObject:
       
  1013         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32)
       
  1014             {
       
  1015             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1016             }
       
  1017         else if (Request().Uint32(TMTPTypeRequest::ERequestParameter2) != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue))
       
  1018             {
       
  1019             responseCode = EMTPRespCodeInvalidDataset;
       
  1020             }
       
  1021         break;
       
  1022 
       
  1023     case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
       
  1024         responseCode =     EMTPRespCodeAccessDenied;
       
  1025         break;
       
  1026 
       
  1027     case EMTPObjectPropCodeProtectionStatus:
       
  1028         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16)
       
  1029             {
       
  1030             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1031             }                        
       
  1032         break;
       
  1033         
       
  1034     case EMTPObjectPropCodeDateModified:                    
       
  1035     case EMTPObjectPropCodeObjectFileName:    
       
  1036     case EMTPObjectPropCodeName:
       
  1037         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeString)
       
  1038             {
       
  1039             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1040             }
       
  1041         break;
       
  1042         
       
  1043     case EMTPObjectPropCodeNonConsumable:
       
  1044         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT8)
       
  1045             {
       
  1046             responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1047             }
       
  1048         break;
       
  1049         
       
  1050     case EMTPObjectPropCodeAssociationType:
       
  1051         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16)
       
  1052              {
       
  1053              responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1054              }
       
  1055     	break;
       
  1056     	
       
  1057     case EMTPObjectPropCodeAssociationDesc:
       
  1058         if (aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32)
       
  1059              {
       
  1060              responseCode = EMTPRespCodeInvalidObjectPropFormat;
       
  1061              }
       
  1062     	break;
       
  1063                 
       
  1064     default:
       
  1065         responseCode = EMTPRespCodeInvalidObjectPropCode;
       
  1066         break;
       
  1067         }
       
  1068     __FLOG_VA((_L8("Result = 0x%04X"), responseCode));
       
  1069     __FLOG(_L8("CheckPropCode - Exit"));
       
  1070     return responseCode;    
       
  1071     }
       
  1072 
       
  1073 /**
       
  1074 Validates the data type for a given property code.
       
  1075 @return EMTPRespCodeOK if the parent handle matches the store id, or another MTP response code if not
       
  1076 */
       
  1077 TMTPResponseCode CMTPSendObjectInfo::MatchStoreAndParentL() const
       
  1078     {
       
  1079     TMTPResponseCode ret = EMTPRespCodeOK;
       
  1080     const TUint32 storeId(Request().Uint32(TMTPTypeRequest::ERequestParameter1));
       
  1081     const TUint32 parentHandle(Request().Uint32(TMTPTypeRequest::ERequestParameter2));
       
  1082     
       
  1083     // this checking is only valid when the second parameter is not a special value.
       
  1084     if (parentHandle != KMTPHandleAll && parentHandle != KMTPHandleNone)
       
  1085         {
       
  1086         //does not take owernship
       
  1087         CMTPObjectMetaData* parentObjInfo = iRequestChecker->GetObjectInfo(parentHandle);
       
  1088         __ASSERT_DEBUG(parentObjInfo, Panic(EMTPDpObjectNull));
       
  1089         
       
  1090         if (parentObjInfo->Uint(CMTPObjectMetaData::EStorageId) != storeId)      
       
  1091             {
       
  1092             ret = EMTPRespCodeInvalidObjectHandle;
       
  1093             }
       
  1094         }
       
  1095         
       
  1096     return ret;
       
  1097     }
       
  1098 
       
  1099 /**
       
  1100 Reserves space for and assigns an object handle to the received object, then
       
  1101 sends a success response.
       
  1102 */
       
  1103 void CMTPSendObjectInfo::ReserveObjectL()
       
  1104     {
       
  1105     __FLOG(_L8("ReserveObjectL - Entry"));    
       
  1106     iReceivedObject->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
       
  1107     iReceivedObject->SetDesCL(CMTPObjectMetaData::ESuid, iFullPath);
       
  1108     
       
  1109     iFramework.ObjectMgr().ReserveObjectHandleL(*iReceivedObject, iObjectSize);    
       
  1110     
       
  1111     if(iIsFolder)
       
  1112         {
       
  1113         SetPropertiesL(); 
       
  1114         iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObject);       
       
  1115         }
       
  1116     else
       
  1117     	{
       
  1118     	iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
       
  1119     	iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
       
  1120     	}
       
  1121     TUint32 parameters[3];
       
  1122     parameters[0] = iStorageId;
       
  1123     parameters[1] = iParentHandle;
       
  1124     parameters[2] = iReceivedObject->Uint(CMTPObjectMetaData::EHandle);
       
  1125     SendResponseL(EMTPRespCodeOK, (sizeof(parameters) / sizeof(parameters[0])), parameters);
       
  1126     __FLOG(_L8("ReserveObjectL - Exit"));    
       
  1127     }
       
  1128     
       
  1129 void CMTPSendObjectInfo::CreateFsObjectL()
       
  1130     {
       
  1131     if (iIsFolder)
       
  1132         {
       
  1133         User::LeaveIfError(iFramework.Fs().MkDirAll(iFullPath));
       
  1134         }
       
  1135     else
       
  1136         {
       
  1137         delete iFileReceived;
       
  1138         iFileReceived = NULL;
       
  1139         iFileReceived = CMTPTypeFile::NewL(iFramework.Fs(), iFullPath, EFileWrite);
       
  1140         iFileReceived->SetSizeL(iObjectSize);
       
  1141         }
       
  1142     }
       
  1143     
       
  1144 void CMTPSendObjectInfo::Rollback()
       
  1145     {
       
  1146     if(iIsFolder)
       
  1147         {
       
  1148         __FLOG(_L8("It is a folder cancel process."));
       
  1149         iFramework.Fs().RmDir(iFullPath);
       
  1150         // If it is folder, delete it from MTP database, i.e ObjectStore.
       
  1151         TRAP_IGNORE(iFramework.ObjectMgr().RemoveObjectL(iFullPath));
       
  1152         }
       
  1153     else
       
  1154         {
       
  1155         __FLOG(_L8("It is a file cancel process."));
       
  1156         // Delete this object from file system.
       
  1157         iFramework.Fs().Delete(iFullPath);
       
  1158         TRAP_IGNORE(iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObject));
       
  1159         }
       
  1160     }
       
  1161     
       
  1162 TMTPResponseCode CMTPSendObjectInfo::ErrorToMTPError(TInt aError) const
       
  1163     {
       
  1164     TMTPResponseCode resp = EMTPRespCodeGeneralError;
       
  1165     
       
  1166     switch (aError)
       
  1167         {
       
  1168     case KErrNone:
       
  1169         resp = EMTPRespCodeOK;
       
  1170         break;
       
  1171         
       
  1172     case KErrAccessDenied:
       
  1173         resp = EMTPRespCodeAccessDenied;
       
  1174         break;
       
  1175         
       
  1176     case KErrDiskFull:
       
  1177         resp = EMTPRespCodeStoreFull;
       
  1178         break;
       
  1179         }
       
  1180         
       
  1181     return resp;
       
  1182     }
       
  1183 
       
  1184 /**
       
  1185 Sets the read only status on the current file to match the sent object.
       
  1186 */
       
  1187 void CMTPSendObjectInfo::SetPropertiesL()
       
  1188     {
       
  1189     __FLOG(_L8("SetPropertiesL - Entry"));
       
  1190     TEntry entry;
       
  1191     User::LeaveIfError(iFramework.Fs().Entry(iFullPath, entry));  
       
  1192     
       
  1193     TUint16 assoc(EMTPAssociationTypeUndefined);
       
  1194 	if (entry.IsDir())
       
  1195 		{
       
  1196 		assoc = EMTPAssociationTypeGenericFolder;
       
  1197 		}
       
  1198 	iReceivedObject->SetUint(CMTPObjectMetaData::EFormatSubCode, assoc);    
       
  1199         
       
  1200     if (iName.Length() == 0)
       
  1201     {
       
  1202     	if (entry.IsDir())
       
  1203     	{
       
  1204     		TParsePtrC pathParser(iFullPath.Left(iFullPath.Length() - 1)); // Ignore the trailing "\".
       
  1205     		iName = pathParser.Name();
       
  1206     	}
       
  1207     	else
       
  1208     	{
       
  1209         	TParsePtrC pathParser(iFullPath);
       
  1210         	iName = pathParser.Name();
       
  1211     	}
       
  1212     }    
       
  1213     
       
  1214     if (iProtectionStatus ==  EMTPProtectionNoProtection ||
       
  1215         iProtectionStatus == EMTPProtectionReadOnly)
       
  1216         {
       
  1217         entry.iAtt &= ~(KEntryAttNormal | KEntryAttReadOnly);
       
  1218         if (iProtectionStatus == EMTPProtectionNoProtection)
       
  1219             {                        
       
  1220             entry.iAtt |= KEntryAttNormal;
       
  1221             }
       
  1222         else
       
  1223             {
       
  1224             entry.iAtt |= KEntryAttReadOnly;
       
  1225             }
       
  1226         User::LeaveIfError(iFramework.Fs().SetAtt(iFullPath, entry.iAtt, ~entry.iAtt));
       
  1227         }
       
  1228     iReceivedObject->SetDesCL(CMTPObjectMetaData::EName, iName);
       
  1229     
       
  1230     __FLOG(_L8("SetPropertiesL - Exit"));
       
  1231     }
       
  1232