mtpdataproviders/mtppictbridgedp/src/cmtppictbridgedpsendobjectinfo.cpp
changeset 0 d0791faffa3f
child 11 4843bb5893b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpdataproviders/mtppictbridgedp/src/cmtppictbridgedpsendobjectinfo.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,984 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#include <f32file.h>
+#include <bautils.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/cmtpobjectmetadata.h>
+#include <mtp/cmtptypefile.h>
+#include <mtp/cmtptypeobjectinfo.h>
+#include <mtp/cmtptypeobjectproplist.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/mmtpstoragemgr.h>
+#include <mtp/mtpprotocolconstants.h>
+#include <mtp/mmtpconnection.h>
+#include <mtp/tmtptyperequest.h>
+#include "ptpdef.h"
+#include "cmtppictbridgedpsendobjectinfo.h"
+#include "mtppictbridgedppanic.h"
+#include "mtppictbridgedpconst.h"
+#include "cmtppictbridgeprinter.h"
+#include "cptpserver.h"
+#include "cmtpconnection.h"
+#include "cmtpconnectionmgr.h"
+
+/**
+Verification data for the SendObjectInfo request
+*/
+const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] = 
+    {
+    {TMTPTypeRequest::ERequestParameter1, EMTPElementTypeStorageId, EMTPElementAttrWrite, 1, 0, 0},                
+    {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeObjectHandle, EMTPElementAttrWrite, 2, KMTPHandleAll, KMTPHandleNone}
+    };
+
+
+/**
+Two-phase construction method
+@param aFramework  The data provider framework
+@param aConnection The connection from which the request comes
+@return a pointer to the created request processor object
+*/ 
+MMTPRequestProcessor* CMTPPictBridgeDpSendObjectInfo::NewL(
+    MMTPDataProviderFramework& aFramework,
+    MMTPConnection& aConnection,
+    CMTPPictBridgeDataProvider& aDataProvider)
+    {
+    CMTPPictBridgeDpSendObjectInfo* self = new (ELeave) CMTPPictBridgeDpSendObjectInfo(aFramework, aConnection, aDataProvider);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+Destructor
+*/    
+CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo()
+    {
+    __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo iProgress=%d iNoRollback=%d "), iProgress, iNoRollback));
+
+    if ((iProgress == EObjectInfoSucceed || 
+        iProgress == EObjectInfoFail || 
+        iProgress == EObjectInfoInProgress) && !iNoRollback)
+        {
+        // Not finished SendObjectInfo/PropList SendObject pair detected.
+        Rollback();
+        }
+ 
+    iDpSingletons.Close();
+    delete iDateModP;
+    delete iFileReceivedP;
+    delete iParentSuidP;    
+    delete iReceivedObjectP;
+    delete iObjectInfoP;
+    delete iObjectPropList;
+
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::~CMTPPictBridgeDpSendObjectInfo"));
+    __FLOG_CLOSE;
+    }
+
+/**
+Standard c++ constructor
+@param aFramework    The data provider framework
+@param aConnection    The connection from which the request comes
+*/    
+CMTPPictBridgeDpSendObjectInfo::CMTPPictBridgeDpSendObjectInfo(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection, CMTPPictBridgeDataProvider& aDataProvider):
+    CMTPRequestProcessor(aFramework, aConnection, 0, NULL),
+    iPictBridgeDP(aDataProvider)
+    {
+    }
+
+/**
+Verify the request
+@return EMTPRespCodeOK if request is verified, otherwise one of the error response codes
+*/    
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckRequestL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckRequestL"));    
+    TMTPResponseCode result = CheckSendingStateL();
+    
+    if (result != EMTPRespCodeOK) 
+        {
+        return result;
+        }
+    
+    if (iProgress == EObjectNone)    //this is the SendObjectInfo phase
+        {
+        iElementCount = sizeof(KMTPSendObjectInfoPolicy) / sizeof(TMTPRequestElementInfo);
+        iElements = KMTPSendObjectInfoPolicy;            
+        }
+    else if (iProgress == EObjectInfoSucceed)
+        {
+        iElementCount = 0;
+        iElements     = NULL;
+        }
+
+    if (iElements)
+        {
+        result = CMTPRequestProcessor::CheckRequestL();    
+        }
+
+    if ( EMTPRespCodeOK == result )
+        {
+        result = MatchStoreAndParentL();
+        }
+
+    if (( EMTPRespCodeOK == result ) && ( EMTPOpCodeSendObjectPropList == iOperationCode ))
+        {
+        iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
+        TUint32 objectSizeHigh = Request().Uint32(TMTPTypeRequest::ERequestParameter4);
+        TUint32 objectSizeLow = Request().Uint32(TMTPTypeRequest::ERequestParameter5);
+        iObjectSize = MAKE_TUINT64(objectSizeHigh, objectSizeLow);
+        if (IsTooLarge(iObjectSize))
+            {
+             result = EMTPRespCodeObjectTooLarge;            
+            }
+        if(result && !CanStoreFileL(iStorageId, iObjectSize))
+           {
+           result = EMTPRespCodeStoreFull;            
+           }        
+        }
+    // If the previous request is not SendObjectInfo, SendObject fails
+    if (result == EMTPRespCodeOK && iOperationCode == EMTPOpCodeSendObject)
+        {
+        if (iPreviousTransactionID + 1 != Request().Uint32(TMTPTypeRequest::ERequestTransactionID))
+            {
+            result = EMTPRespCodeNoValidObjectInfo;
+            }
+        }
+        
+    __FLOG_VA((_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckRequestL 0x%04x"), result));    
+
+    return result;    
+    }
+    
+TBool CMTPPictBridgeDpSendObjectInfo::HasDataphase() const
+    {
+    return ETrue;
+    }
+
+/**
+SendObjectInfo/SendObject request handler
+NOTE: SendObjectInfo has to be comes before SendObject requests.  To maintain the state information
+between the two requests, the two requests are combined together in one request processor.
+*/    
+void CMTPPictBridgeDpSendObjectInfo::ServiceL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ServiceL"));
+    if (iProgress == EObjectNone)
+        {
+        if ( EMTPOpCodeSendObjectInfo == iOperationCode )
+            {
+            ServiceSendObjectInfoL();
+            }
+        else
+            {
+            ServiceSendObjectPropListL();
+            }
+        }
+    else
+        {
+        ServiceSendObjectL();
+        }    
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ServiceL"));    
+    }
+
+/**
+Second-phase construction
+*/        
+void CMTPPictBridgeDpSendObjectInfo::ConstructL()
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ConstructL"));      
+    iExpectedSendObjectRequest.SetUint16(TMTPTypeRequest::ERequestOperationCode, EMTPOpCodeSendObject);
+    iReceivedObjectP = CMTPObjectMetaData::NewL();
+    iReceivedObjectP->SetUint(CMTPObjectMetaData::EDataProviderId, iFramework.DataProviderId());
+    iDpSingletons.OpenL(iFramework);
+    iNoRollback = EFalse;
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ConstructL"));    
+    }
+
+/**
+Override to match both the SendObjectInfo and SendObject requests
+@param aRequest    The request to match
+@param aConnection The connection from which the request comes
+@return ETrue if the processor can handle the request, otherwise EFalse
+*/        
+TBool CMTPPictBridgeDpSendObjectInfo::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::Match"));    
+    TBool result = EFalse;
+    TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
+    if ((operationCode == EMTPOpCodeSendObjectInfo || 
+        operationCode == EMTPOpCodeSendObject ||
+        operationCode == EMTPOpCodeSendObjectPropList) &&
+        &iConnection == &aConnection)
+        {
+        result = ETrue;
+        }
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::Match"));    
+    return result;    
+    }
+
+/**
+Override to handle the response phase of SendObjectInfo and SendObject requests
+@return EFalse
+*/
+TBool CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL()
+    {
+    __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL iProgress==%d opCode==0x%x"),iProgress, iOperationCode));
+    //to check if the sending/receiving data is successful
+    TBool successful = !iCancelled;
+    if (iProgress == EObjectInfoInProgress)
+        {
+        if (iOperationCode == EMTPOpCodeSendObjectInfo)
+            {            
+            successful = DoHandleSendObjectInfoCompleteL();
+            }
+        else
+            {
+            successful = DoHandleSendObjectPropListCompleteL();
+            }
+        iProgress = (successful ? EObjectInfoSucceed : EObjectInfoFail);
+        }
+    else if (iProgress == ESendObjectInProgress)
+        {
+        successful = DoHandleSendObjectCompleteL();
+        iProgress = (successful ? ESendObjectSucceed : ESendObjectFail);
+        }        
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleResponsePhaseL"));    
+    return EFalse;
+    }
+
+/**
+Override to handle the completing phase of SendObjectInfo and SendObject requests
+@return ETrue if succesfully received the file, otherwise EFalse
+*/    
+TBool CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL()
+    {
+    __FLOG_VA((_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL iProgress==%d opCode==0x%x"),iProgress, iOperationCode));
+    TBool result = ETrue;
+    CMTPRequestProcessor::DoHandleCompletingPhaseL();
+    if (iProgress == EObjectInfoSucceed)
+        {
+        if (( iOperationCode == EMTPOpCodeSendObjectInfo ) || ( iOperationCode == EMTPOpCodeSendObjectPropList ))
+            {
+            iPreviousTransactionID = Request().Uint32(TMTPTypeRequest::ERequestTransactionID);
+            }
+        result = EFalse;
+        }
+    else if (iProgress == ESendObjectSucceed)
+        {
+        iPictBridgeDP.PtpServer()->Printer()->DpsObjectReceived(iReceivedObjectP->Uint(CMTPObjectMetaData::EHandle));
+        }
+    else if (iProgress == ESendObjectFail)
+        {
+        if (iOperationCode == EMTPOpCodeSendObject)
+            {
+            iPreviousTransactionID++;
+            }
+        iProgress = EObjectInfoSucceed;
+        result = EFalse;
+        }
+    
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleCompletingPhaseL"));    
+    return result;    
+    }
+
+/**
+Verify if the SendObject request comes after SendObjectInfo request
+@return EMTPRespCodeOK if SendObject request comes after a valid SendObjectInfo request, otherwise
+EMTPRespCodeNoValidObjectInfo
+*/
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL"));    
+    TMTPResponseCode result = EMTPRespCodeOK;
+    iOperationCode = Request().Uint16(TMTPTypeRequest::ERequestOperationCode);
+
+    if (iOperationCode == EMTPOpCodeSendObject)
+        {
+        //In ParseRouter everytime SendObject gets resolved then will be removed from Registry
+        //Right away therefore we need reRegister it here again in case possible cancelRequest
+        //Against this SendObject being raised.
+        iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
+        iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
+        }
+   
+    if (iProgress == EObjectNone)
+        {
+        if (iOperationCode == EMTPOpCodeSendObject)
+            {
+            result = EMTPRespCodeNoValidObjectInfo;
+            }        
+        }
+    else if (iProgress == EObjectInfoSucceed) 
+        {
+        if (iOperationCode == EMTPOpCodeSendObjectInfo || iOperationCode == EMTPOpCodeSendObjectPropList)
+            {
+            // Not finished SendObjectInfo/SendObject pair detected, need to remove the object reservation that was created, unless the object already existed
+            if (!iNoRollback )
+                {
+                __FLOG(_L8("  CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL ... Rolling back!"));
+                Rollback();
+                }
+
+            delete iObjectInfoP;
+            iObjectInfoP = NULL;
+            delete iObjectPropList;
+            iObjectPropList = NULL;
+            iProgress = EObjectNone;
+            }
+        }
+    else 
+        {
+        Panic(EMTPPictBridgeDpSendObjectStateInvalid);
+        }
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckSendingStateL"));    
+    return result;    
+    }
+
+/**
+SendObjectInfo request handler
+*/
+void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectInfoL()
+    {
+    delete iObjectInfoP;
+    iObjectInfoP = NULL;
+    iObjectInfoP = CMTPTypeObjectInfo::NewL();
+    ReceiveDataL(*iObjectInfoP);
+    iProgress = EObjectInfoInProgress;
+    }
+
+/**
+ServiceSendObjectPropListL request handler
+*/ 
+void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectPropListL()
+    {
+    delete iObjectPropList;
+    iObjectPropList = NULL;
+    iObjectPropList = CMTPTypeObjectPropList::NewL();
+    ReceiveDataL( *iObjectPropList );
+    iProgress = EObjectInfoInProgress;
+    }
+
+/**
+SendObject request handler
+*/    
+void CMTPPictBridgeDpSendObjectInfo::ServiceSendObjectL()
+    {    
+    ReceiveDataL(*iFileReceivedP);    
+    iProgress = ESendObjectInProgress;
+    }
+
+/**
+Get a default parent object, if the request does not specify a parent object.
+*/
+void CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL()
+    {    
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL"));    
+
+    if (iStorageId == KMTPStorageDefault)
+        {
+        iStorageId = iFramework.StorageMgr().DefaultStorageId();
+        }
+    TInt drive(static_cast<TDriveNumber>(iFramework.StorageMgr().DriveNumber(iStorageId)));
+    User::LeaveIfError(drive);
+
+    // Obtain the root of the drive.  Logical storages can sometimes have a filesystem root
+    // other than <drive>:\ .  For example an MP3 DP might have a root of c:\media\music\
+
+    delete iParentSuidP;
+    iParentSuidP = NULL;
+    iParentSuidP=(iFramework.StorageMgr().StorageL(iStorageId).DesC(CMTPStorageMetaData::EStorageSuid)).AllocL();
+    iReceivedObjectP->SetUint(CMTPObjectMetaData::EParentHandle, KMTPHandleNoParent);
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::GetDefaultParentObjectL"));            
+    }
+
+/**
+Get parent object and storage id
+@return EMTPRespCodeOK if successful, otherwise, EMTPRespCodeInvalidParentObject
+*/
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL"));    
+    __ASSERT_DEBUG(iRequestChecker, Panic(EMTPPictBridgeDpRequestCheckNull));
+
+    iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
+    iParentHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
+    //does not take ownership
+    CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iParentHandle);
+
+    if (!parentObjectInfo)
+        {
+        GetDefaultParentObjectL();    
+        }
+    else
+        {        
+        delete iParentSuidP;
+        iParentSuidP = NULL;
+        iParentSuidP = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL();
+        iReceivedObjectP->SetUint(CMTPObjectMetaData::EParentHandle, iParentHandle);
+        }
+
+    __FLOG_VA((_L16("<< CMTPPictBridgeDpSendObjectInfo::GetParentObjectAndStorageIdL %S"), iParentSuidP));    
+    return EMTPRespCodeOK;
+    }
+
+/**
+Handling the completing phase of SendObjectInfo request
+@return ETrue if the specified object can be saved on the specified location, otherwise, EFalse
+*/    
+TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL"));    
+    TBool result(ETrue);
+    TUint16 format(iObjectInfoP->Uint16L(CMTPTypeObjectInfo::EObjectFormat));
+    
+    result = IsFormatValid(TMTPFormatCode(format));
+    
+    if (result)
+        {
+        delete iDateModP;
+        iDateModP = NULL;
+        iDateModP = iObjectInfoP->StringCharsL(CMTPTypeObjectInfo::EDateModified).AllocL();
+    
+        TMTPResponseCode responseCode(GetParentObjectAndStorageIdL());
+        if (responseCode != EMTPRespCodeOK)
+            {
+            SendResponseL(responseCode);
+            result = EFalse;
+            }
+        }
+    else
+        {
+        SendResponseL(EMTPRespCodeInvalidObjectFormatCode);
+        }
+
+    if (result)
+        {
+        iObjectSize = iObjectInfoP->Uint32L(CMTPTypeObjectInfo::EObjectCompressedSize);
+        if (IsTooLarge(iObjectSize))
+            {
+            SendResponseL(EMTPRespCodeObjectTooLarge);
+            result = EFalse;            
+            }
+        if(result && !CanStoreFileL(iStorageId, iObjectSize))
+            {
+            SendResponseL(EMTPRespCodeStoreFull);
+            result = EFalse;            
+            }
+        }
+
+    if (result)
+        {
+        iProtectionStatus = iObjectInfoP->Uint16L(CMTPTypeObjectInfo::EProtectionStatus);
+        if (iProtectionStatus !=  EMTPProtectionNoProtection &&
+            iProtectionStatus != EMTPProtectionReadOnly)
+            {
+            SendResponseL(EMTPRespCodeParameterNotSupported);
+            result = EFalse;
+            }
+        }
+
+    if (result)
+        {
+        result = GetFullPathNameL(iObjectInfoP->StringCharsL(CMTPTypeObjectInfo::EFilename));
+        if (!result)
+            {        
+            // File and/or parent pathname invalid.
+            SendResponseL(EMTPRespCodeInvalidDataset);
+            }
+        }
+
+    // pictbridge objects should be overwritten
+/*
+    if (result)
+        {    
+        result &= !Exists(iFullPath);
+        if (!result)
+            {        
+            // Object with the same name already exists.
+            __FLOG(_L8("   no rollback"));
+			iNoRollback = ETrue;
+            SendResponseL(EMTPRespCodeAccessDenied);
+            }
+        }
+  */
+    
+    if (result)
+        {
+        iReceivedObjectP->SetUint(CMTPObjectMetaData::EFormatCode, format);
+        iPictBridgeDP.PtpServer()->Printer()->DpsDiscovery(iFullPath, &iConnection);
+        TRAPD(err, CreateFsObjectL()); 
+        
+        if (err != KErrNone)
+            {
+            SendResponseL(ErrorToMTPError(err));
+            }
+        else
+            {
+            ReserveObjectL();
+            }
+        }
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectInfoCompleteL"));    
+    return result;    
+    }
+
+
+TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL"));
+    TBool result(ETrue);
+    TMTPResponseCode responseCode( GetParentObjectAndStorageIdL() );
+    if ( responseCode != EMTPRespCodeOK )
+        {
+        SendResponseL( responseCode );
+        result = EFalse;
+        }
+    
+    if ( result )
+        {
+        TInt invalidParameterIndex = KErrNotFound;
+        responseCode = VerifyObjectPropListL( invalidParameterIndex );
+        result = ( responseCode == EMTPRespCodeOK );
+        if ( !result )
+            {
+            TUint32 parameters[4];
+            parameters[0] = 0;
+            parameters[1] = 0;
+            parameters[2] = 0;
+            parameters[3] = invalidParameterIndex;
+            SendResponseL( responseCode, 4, parameters );
+            }
+        }
+
+    if ( result )
+        {
+        iReceivedObjectP->SetUint(CMTPObjectMetaData::EFormatCode, iRequest->Uint32( TMTPTypeRequest::ERequestParameter3 ));
+        iPictBridgeDP.PtpServer()->Printer()->DpsDiscovery(iFullPath, &iConnection);
+        TRAPD(err, CreateFsObjectL());
+        if ( err != KErrNone )
+            {
+            SendResponseL(ErrorToMTPError(err));
+            }
+        else
+            {
+            ReserveObjectL();
+            }
+        }
+
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectPropListCompleteL"));
+    return result;
+    }
+
+/**
+*/
+TBool CMTPPictBridgeDpSendObjectInfo::IsFormatValid(TMTPFormatCode aFormat) const
+    {
+    __FLOG_VA((_L8(">> CMTPPictGetObjectPropDesc::IsFormatValid %d"),aFormat));
+    TInt count(sizeof(KMTPValidCodeExtensionMappings) / sizeof(KMTPValidCodeExtensionMappings[0]));        
+    for(TInt i = 0; i < count; i++)
+        {
+        if (KMTPValidCodeExtensionMappings[i].iFormatCode == aFormat)
+            {
+            __FLOG(_L8("<< CMTPPictGetObjectPropDesc::IsFormatValid ETrue"));
+            return ETrue;
+            }
+        }
+    __FLOG(_L8("<< CMTPPictGetObjectPropDesc::IsFormatValid EFalse"));
+    return EFalse;
+    }
+    
+/**
+Handling the completing phase of SendObject request
+@return ETrue if the object has been successfully saved on the device, otherwise, EFalse
+*/    
+TBool CMTPPictBridgeDpSendObjectInfo::DoHandleSendObjectCompleteL()
+    {
+    __FLOG_VA((_L8(">> CMTPPictGetObjectPropDesc::DoHandleSendObjectCompleteL size=%d cancelled=%d"), iObjectSize, iCancelled));
+    TBool result(ETrue);
+                
+    delete iFileReceivedP;
+    iFileReceivedP = NULL;
+        
+    TEntry fileEntry;
+    User::LeaveIfError(iFramework.Fs().Entry(iFullPath, fileEntry));
+
+    if (fileEntry.FileSize() != iObjectSize)
+        {
+        __FLOG_VA((_L8("   sizes differ %d!=%d"),fileEntry.iSize, iObjectSize));
+        iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
+         
+        iFramework.Fs().Delete(iFullPath);
+        iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObjectP);
+        TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge;
+        if (fileEntry.FileSize() < iObjectSize)
+            {
+            responseCode = EMTPRespCodeInvalidDataset;
+            }
+        SendResponseL(responseCode);
+        result = EFalse;
+        }
+
+    
+    // Get the result of the SendObject operation. 
+    RMTPFramework frameworkSingletons;   
+    frameworkSingletons.OpenL();
+    TUint connectionId = iConnection.ConnectionId();
+    CMTPConnectionMgr& connectionMgr = frameworkSingletons.ConnectionMgr();
+    CMTPConnection& connection = connectionMgr.ConnectionL(connectionId);
+    TInt ret = connection.GetDataReceiveResult(); 
+    frameworkSingletons.Close();
+     // SendObject is cancelled or connection is dropped.
+    if(result && (iCancelled || (ret == KErrAbort)))
+        {
+        iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
+        Rollback();
+        SendResponseL(EMTPRespCodeTransactionCancelled);        
+        }
+    else if (result && !iCancelled)
+        {
+         iFramework.RouteRequestUnregisterL(iExpectedSendObjectRequest, iConnection);
+        
+        //The MTP spec states that it is not mandatory for SendObjectInfo
+        //to be followed by a SendObject.  An object is reserved in the ObjectStore on 
+        //receiving a SendObjectInfo request, but we only commit it 
+        //on receiving the corresponding SendObject request.  With Associations however 
+        //we commit the object straight away as the SendObject phase is often absent 
+        //with folder creation.
+
+
+        iFramework.ObjectMgr().CommitReservedObjectHandleL(*iReceivedObjectP);
+        SendResponseL(EMTPRespCodeOK);
+        }
+    __FLOG(_L8("<< CMTPPictGetObjectPropDesc::DoHandleSendObjectCompleteL"));
+    return result;
+    }
+
+/**
+Get the full path name of the object to be saved
+@param aFileName, on entry, contains the file name of the object,
+on return, contains the full path name of the object to be saved
+@return ETrue if the name is valid, EFalse otherwise
+*/
+TBool CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL(const TDesC& aFileName)
+    {
+    __FLOG_VA((_L16(">> CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL file %S"), &aFileName));
+    TBool result(EFalse);
+    if (aFileName.Length() > 0)
+        {
+        iFullPath = *iParentSuidP;
+        if (iFullPath.Length() + aFileName.Length() < iFullPath.MaxLength())
+            {
+            iFullPath.Append(aFileName);
+            result = iFramework.Fs().IsValidName(iFullPath);
+            }
+        }
+
+    __FLOG_VA((_L16("<< CMTPPictBridgeDpSendObjectInfo::GetFullPathNameL full path %S"), &iFullPath));
+    return result;
+    }
+
+/**
+Check if we can store the file on the storage
+@return ETrue if yes, otherwise EFalse
+*/
+TBool CMTPPictBridgeDpSendObjectInfo::CanStoreFileL(TUint32 aStorageId, TInt64 aObjectSize) const
+    {
+    TBool result(ETrue);
+    if (aStorageId == KMTPStorageDefault)
+        {
+        aStorageId = iFramework.StorageMgr().DefaultStorageId();
+        }
+    TInt drive(iFramework.StorageMgr().DriveNumber(aStorageId));
+    User::LeaveIfError(drive);
+    TVolumeInfo volumeInfo;
+    User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive));
+    if (volumeInfo.iFree < aObjectSize)
+        {        
+        result = EFalse;
+        }
+    return result;        
+    }
+
+/**
+Check if the object is too large
+@return ETrue if yes, otherwise EFalse
+*/
+TBool CMTPPictBridgeDpSendObjectInfo::IsTooLarge(TUint64 aObjectSize) const
+    {
+    TBool ret(aObjectSize > KMaxTInt64);
+    return ret;
+    }
+    
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL( TInt& aInvalidParameterIndex )
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL"));
+    TMTPResponseCode responseCode( EMTPRespCodeOK );
+    const TUint KCount( iObjectPropList->NumberOfElements() );
+    iObjectPropList->ResetCursor();
+    for ( TUint i(0); (i < KCount); i++ )
+        {
+        CMTPTypeObjectPropListElement& KElement=iObjectPropList->GetNextElementL();
+        const TUint32 KHandle( KElement.Uint32L(CMTPTypeObjectPropListElement::EObjectHandle) );
+        aInvalidParameterIndex = i;
+        if ( KHandle != KMTPHandleNone )
+            {
+            responseCode = EMTPRespCodeInvalidObjectHandle;  
+            break;
+            }
+        responseCode = CheckPropCodeL( KElement );
+        if ( responseCode != EMTPRespCodeOK )
+            {
+            break;
+            }
+        responseCode = ExtractPropertyL(KElement);
+        if ( responseCode != EMTPRespCodeOK )
+            {
+            break;
+            }  
+        }
+
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::VerifyObjectPropListL"));
+    return responseCode;
+    }
+
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL( const CMTPTypeObjectPropListElement& aElement )
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL"));
+    TMTPResponseCode responseCode(EMTPRespCodeOK);
+    switch ( aElement.Uint16L(CMTPTypeObjectPropListElement::EPropertyCode) )
+        {
+    case EMTPObjectPropCodeObjectFileName:
+        {
+        const TDesC& KFileName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
+        if (!GetFullPathNameL(KFileName))
+            {
+            responseCode = EMTPRespCodeInvalidDataset;
+            }
+        }
+        break;
+
+    case EMTPObjectPropCodeProtectionStatus:
+        {
+        iProtectionStatus = aElement.Uint16L(CMTPTypeObjectPropListElement::EValue);
+        if (iProtectionStatus !=  EMTPProtectionNoProtection &&
+            iProtectionStatus != EMTPProtectionReadOnly)
+            {
+            responseCode = EMTPRespCodeParameterNotSupported;
+            }
+        }
+        break;
+
+    case EMTPObjectPropCodeDateModified:
+        delete iDateModP;
+        iDateModP = NULL;
+        iDateModP = aElement.StringL(CMTPTypeObjectPropListElement::EValue).AllocL();
+        break;
+    case EMTPObjectPropCodeName:
+    	iName = aElement.StringL(CMTPTypeObjectPropListElement::EValue);
+    	break;
+    default:
+        break;
+        }
+
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ExtractPropertyL"));
+    return responseCode;
+    }
+    
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL( const CMTPTypeObjectPropListElement& aElement ) const
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL"));
+    TMTPResponseCode responseCode( EMTPRespCodeOK );
+    switch( aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ))
+        {
+        case EMTPObjectPropCodeStorageID:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+            else if ( iStorageId != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) )
+                {
+                responseCode = EMTPRespCodeInvalidDataset;
+                }
+            }
+            break;
+        case EMTPObjectPropCodeObjectFormat:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+        else if (Request().Uint32(TMTPTypeRequest::ERequestParameter3) != aElement.Uint16L(CMTPTypeObjectPropListElement::EValue))
+                {
+                responseCode = EMTPRespCodeInvalidDataset;
+                }
+            }
+            break;
+        case EMTPObjectPropCodeObjectSize:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT64 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+        else if (iObjectSize != aElement.Uint64L(CMTPTypeObjectPropListElement::EValue))
+                {
+                responseCode = EMTPRespCodeInvalidDataset;
+                }
+            }
+            break;
+        case EMTPObjectPropCodeParentObject:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT32 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+            else if( Request().Uint32(TMTPTypeRequest::ERequestParameter2) != aElement.Uint32L(CMTPTypeObjectPropListElement::EValue) )
+                {
+                responseCode = EMTPRespCodeInvalidDataset;
+                }
+            }
+            break;
+        case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
+            {
+            responseCode = EMTPRespCodeAccessDenied;
+            }
+            break;
+        case EMTPObjectPropCodeProtectionStatus:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT16 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+            }
+            break;
+        case EMTPObjectPropCodeDateModified:
+        case EMTPObjectPropCodeObjectFileName:
+        case EMTPObjectPropCodeName:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeString )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+            }
+            break;
+        case EMTPObjectPropCodeNonConsumable:
+            {
+            if ( aElement.Uint16L(CMTPTypeObjectPropListElement::EDatatype) != EMTPTypeUINT8 )
+                {
+                responseCode = EMTPRespCodeInvalidObjectPropFormat;
+                }
+            }
+            break;
+        default:
+            {
+            responseCode = EMTPRespCodeInvalidObjectPropCode;
+            }
+            break;
+        }
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CheckPropCodeL"));
+    return responseCode; 
+    }
+
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL() const
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL"));
+    TMTPResponseCode ret = EMTPRespCodeOK;
+    const TUint32 storeId(Request().Uint32(TMTPTypeRequest::ERequestParameter1));
+    const TUint32 parentHandle(Request().Uint32(TMTPTypeRequest::ERequestParameter2));
+    if (parentHandle != KMTPHandleAll && parentHandle != KMTPHandleNone)
+        {
+        CMTPObjectMetaData* parentObjInfo = iRequestChecker->GetObjectInfo(parentHandle);
+        __ASSERT_DEBUG(parentObjInfo, Panic(EMTPPictBridgeDpObjectNull));
+
+        if (parentObjInfo->Uint(CMTPObjectMetaData::EStorageId) != storeId)   
+            {
+            ret = EMTPRespCodeInvalidObjectHandle;
+            }
+        }
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::MatchStoreAndParentL"));
+    return ret;
+    }
+
+/**
+Reserves space for and assigns an object handle to the received object, then
+sends a success response.
+*/
+void CMTPPictBridgeDpSendObjectInfo::ReserveObjectL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::ReserveObjectL"));    
+    iReceivedObjectP->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
+    iReceivedObjectP->SetDesCL(CMTPObjectMetaData::ESuid, iFullPath);
+    
+    iFramework.ObjectMgr().ReserveObjectHandleL(*iReceivedObjectP, iObjectSize);    
+    
+    iExpectedSendObjectRequest.SetUint32(TMTPTypeRequest::ERequestSessionID, iSessionId);
+    iFramework.RouteRequestRegisterL(iExpectedSendObjectRequest, iConnection);
+    TUint32 parameters[3];
+    parameters[0] = iStorageId;
+    parameters[1] = iParentHandle;
+    parameters[2] = iReceivedObjectP->Uint(CMTPObjectMetaData::EHandle);
+    SendResponseL(EMTPRespCodeOK, (sizeof(parameters) / sizeof(parameters[0])), parameters);
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::ReserveObjectL"));    
+    }
+    
+void CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL"));    
+    delete iFileReceivedP;
+    iFileReceivedP = NULL;
+    iFileReceivedP = CMTPTypeFile::NewL(iFramework.Fs(), iFullPath, EFileWrite);
+    iFileReceivedP->SetSizeL(iObjectSize);
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::CreateFsObjectL"));    
+    }
+    
+void CMTPPictBridgeDpSendObjectInfo::Rollback()
+    {
+    __FLOG(_L8(">> CMTPPictBridgeDpSendObjectInfo::Rollback"));
+    // Delete this object from file system.
+    delete iFileReceivedP;
+    iFileReceivedP=NULL;
+    TInt err=iFramework.Fs().Delete(iFullPath);
+    __FLOG_VA((_L16(">> CMTPPictBridgeDpSendObjectInfo::Rollback deleted %S with return code %d"), &iFullPath, err));
+    TRAP_IGNORE(iFramework.ObjectMgr().UnreserveObjectHandleL(*iReceivedObjectP));
+    __FLOG(_L8("<< CMTPPictBridgeDpSendObjectInfo::Rollback"));    
+    }
+    
+TMTPResponseCode CMTPPictBridgeDpSendObjectInfo::ErrorToMTPError(TInt aError) const
+    {
+    TMTPResponseCode resp = EMTPRespCodeGeneralError;
+    
+    switch (aError)
+        {
+    case KErrAccessDenied:
+        resp = EMTPRespCodeAccessDenied;
+        break;
+        
+    case KErrDiskFull:
+        resp = EMTPRespCodeStoreFull;
+        break;
+
+    default:
+        resp = EMTPRespCodeGeneralError;
+        break;
+        }
+        
+    return resp;
+    }
+