diff -r 000000000000 -r a2952bb97e68 mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csetobjectproplist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csetobjectproplist.cpp Thu Dec 17 08:55:47 2009 +0200 @@ -0,0 +1,378 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implement the operation: SetObjectPropList +* +*/ + + +#include +#include +#include +#include +#include + +#include "csetobjectproplist.h" +#include "cmmmtpdpmetadataaccesswrapper.h" +#include "mmmtpdputility.h" +#include "mmmtpdplogger.h" +#include "mmmtpdpconfig.h" + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::NewL +// Two-phase construction method +// ----------------------------------------------------------------------------- +// +//EXPORT_C MMmRequestProcessor* CSetObjectPropList::NewL( MMTPDataProviderFramework& aFramework, +// MMTPConnection& aConnection, +// CMmMtpDpMetadataAccessWrapper& aWrapper ) +// { +// CSetObjectPropList* self = new ( ELeave ) CSetObjectPropList( aFramework, +// aConnection, +// aWrapper ); +// CleanupStack::PushL( self ); +// self->ConstructL(); +// CleanupStack::Pop( self ); +// return self; +// } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::CSetObjectPropList +// Standard c++ constructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CSetObjectPropList::CSetObjectPropList( MMTPDataProviderFramework& aFramework, + MMTPConnection& aConnection, + MMmMtpDpConfig& aDpConfig ) : + CRequestProcessor( aFramework, aConnection, 0, NULL), + iObjectMgr( aFramework.ObjectMgr() ), + iFs( aFramework.Fs() ), + iDpConfig( aDpConfig ), + iUnprocessedIndex ( 0 ) + { + PRINT( _L( "Operation: SetObjectPropList(0x9806)" ) ); + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::ConstructL +// 2nd Phase Constructor +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSetObjectPropList::ConstructL() + { + CActiveScheduler::Add( this ); + + iPropertyList = CMTPTypeObjectPropList::NewL(); + SetPSStatus(); + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::~CSetObjectPropList +// Destructor +// ----------------------------------------------------------------------------- +// +EXPORT_C CSetObjectPropList::~CSetObjectPropList() + { + Cancel(); + delete iPropertyList; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::ServiceL +// SetObjectPropList request handler +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSetObjectPropList::ServiceL() + { + PRINT( _L( "MM MTP => CSetObjectPropList::ServiceL" ) ); + // Recieve the data from the property list + ReceiveDataL( *iPropertyList ); + PRINT( _L( "MM MTP <= CSetObjectPropList::ServiceL" ) ); + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::DoHandleResponsePhaseL +// Completing phase for the request handler +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CSetObjectPropList::DoHandleResponsePhaseL() + { + PRINT( _L( "MM MTP => CSetObjectPropList::DoHandleResponsePhaseL" ) ); + + iElementCount = iPropertyList->NumberOfElements(); + iPropertyList->ResetCursor(); + if( iElementCount > 0 ) + { + iUnprocessedIndex = 0; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, iStatus.Int() ); + SetActive(); + } + else + { + SendResponseL( EMTPRespCodeOK ); + } + + PRINT( _L( "MM MTP <= CSetObjectPropList::DoHandleResponsePhaseL" ) ); + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::SetObjectPropListL +// Set object proplist +// ----------------------------------------------------------------------------- +// +TMTPResponseCode CSetObjectPropList::SetObjectPropListL( + const CMTPTypeObjectPropListElement& aPropListElement ) + { + PRINT( _L( "MM MTP => CSetObjectPropList::SetObjectPropListL" ) ); + + TMTPTypeUint16 protectionStatus( EMTPProtectionNoProtection ); + TMTPResponseCode responseCode( EMTPRespCodeOK ); + + TUint32 handle = aPropListElement.Uint32L( CMTPTypeObjectPropListElement::EObjectHandle ); + TUint16 propertyCode = aPropListElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ); + TUint16 dataType = aPropListElement.Uint16L( CMTPTypeObjectPropListElement::EDatatype ); + PRINT3( _L( "MM MTP <> handle = 0x%x, propertyCode = 0x%x, dataType = 0x%x" ), + handle, propertyCode, dataType ); + + responseCode = MmMtpDpUtility::CheckPropType( propertyCode, dataType ); + PRINT1( _L( "MM MTP <> CheckPropType response code is 0x%x" ), responseCode ); + if( responseCode != EMTPRespCodeOK ) + return responseCode; + + if ( iFramework.ObjectMgr().ObjectOwnerId( handle ) + == iFramework.DataProviderId() ) + { + PRINT( _L( "MM MTP => CSetObjectPropList::SetObjectPropListL enter" ) ); + CMTPObjectMetaData* object = CMTPObjectMetaData::NewLC(); // + object + iFramework.ObjectMgr().ObjectL( handle, *object ); + + if ( protectionStatus.Value() != EMTPProtectionNoProtection ) + { + //for some reason, P4S expects Access Denied response instead of write protected + return EMTPRespCodeAccessDenied; // EMTPRespCodeObjectWriteProtected; + } + + switch ( propertyCode ) + { + case EMTPObjectPropCodeStorageID: + case EMTPObjectPropCodeObjectFormat: + case EMTPObjectPropCodeProtectionStatus: + case EMTPObjectPropCodeObjectSize: + case EMTPObjectPropCodeParentObject: + case EMTPObjectPropCodePersistentUniqueObjectIdentifier: + case EMTPObjectPropCodeNonConsumable: + case EMTPObjectPropCodeDateAdded: + case EMTPObjectPropCodeDateCreated: + case EMTPObjectPropCodeDateModified: + { + responseCode = EMTPRespCodeAccessDenied; + } + break; + + case EMTPObjectPropCodeObjectFileName: + { + TPtrC suid( object->DesC( CMTPObjectMetaData::ESuid ) ); + TBuf newSuid( aPropListElement.StringL( + CMTPTypeObjectPropListElement::EValue ) ); + TInt err = KErrNone; + err = MmMtpDpUtility::UpdateObjectFileName( iFramework.Fs(), suid, newSuid ); + PRINT1( _L( "MM MTP <> Update object file name err = %d" ), err ); + if ( KErrOverflow == err ) // full path name is too long + { + responseCode = EMTPRespCodeInvalidDataset; + } + else if ( ( KErrNone == err ) || ( KErrAlreadyExists == err ) ) + { + TRAP( err, iDpConfig.GetWrapperL().RenameObjectL( suid, newSuid ) ); //Update MPX DB + PRINT1( _L( "MM MTP <> Rename Object err = %d" ), err ); + // it is ok if file is not found in DB, following S60 solution + if ( KErrNotFound == err ) + { + TRAP( err, iDpConfig.GetWrapperL().AddObjectL( newSuid ) ); + PRINT1( _L( "MM MTP <> Add Object err = %d" ), err ); + } + + if ( KErrNone == err ) + { + object->SetDesCL( CMTPObjectMetaData::ESuid, newSuid ); + iFramework.ObjectMgr().ModifyObjectL( *object ); + } + else + { + responseCode = EMTPRespCodeGeneralError; + } + } + } + break; + + case EMTPObjectPropCodeName: + { + CMTPTypeString* stringData = CMTPTypeString::NewLC( + aPropListElement.StringL( + CMTPTypeObjectPropListElement::EValue ) );// + stringData + + responseCode = ServiceMetaDataToWrapperL( propertyCode, + *stringData, *object ); + + CleanupStack::PopAndDestroy( stringData );// - stringData + } + break; + + default: + { + /*// trap and handle with response code here, so correct fail index should report + TRAPD( err, responseCode = ServiceSpecificObjectPropertyL( propertyCode, *object, aPropListElement ) ); + PRINT1( _L("MM MTP <> CSetObjectPropList::SetObjectPropListL, ServiceSpecificObjectPropertyL, err = %d"), err ); + + if ( err == KErrNotSupported ) + { + responseCode = EMTPRespCodeAccessDenied; + }*/ + responseCode = ServiceSpecificObjectPropertyL( propertyCode, *object, + aPropListElement ); + } + break; + } + + CleanupStack::PopAndDestroy( object ); // - object + } + + PRINT1( _L( "MM MTP <= CSetObjectPropList::SetObjectPropListL responseCode = 0x%x" ), responseCode ); + return responseCode; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::HasDataphase +// Decide if has data phase +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CSetObjectPropList::HasDataphase() const + { + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::ServiceMetaDataToWrapperL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TMTPResponseCode CSetObjectPropList::ServiceMetaDataToWrapperL( + const TUint16 aPropCode, + MMTPType& aNewData, + const CMTPObjectMetaData& aObjectMetaData ) + { + TMTPResponseCode resCode = EMTPRespCodeOK; + + TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode, + aNewData, + aObjectMetaData ) ); + + PRINT1( _L("MM MTP <> CSetObjectPropList::ServiceMetaDataToWrapperL err = %d"), err); + + if ( err == KErrNone ) + { + resCode = EMTPRespCodeOK; + } + else if ( err == KErrTooBig ) + // according to the codes of S60 + { + resCode = EMTPRespCodeInvalidDataset; + } + else if ( err == KErrPermissionDenied ) + { + resCode = EMTPRespCodeAccessDenied; + } + else if ( err == KErrNotFound ) + { + if( MmMtpDpUtility::HasMetadata( aObjectMetaData.Uint( CMTPObjectMetaData::EFormatCode ) ) ) + SendResponseL( EMTPRespCodeAccessDenied ); + } + else + { + // add new virtual call to see if the above condition can be handle probably + err = HandleSpecificWrapperError( err, aObjectMetaData ); + + if ( err != KErrNone ) + resCode = EMTPRespCodeGeneralError; + } + + PRINT1( _L( "MM MTP <= CSetObjectPropList::ServiceMetaDataToWrapperL resCode = 0x%x" ), resCode ); + + return resCode; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::RunL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSetObjectPropList::RunL() + { + if ( iUnprocessedIndex < iElementCount ) + { + TMTPResponseCode responseCode = SetObjectPropListL( iPropertyList->GetNextElementL()); + + if ( responseCode != EMTPRespCodeOK ) + { + SendResponseL( responseCode, 1, &iUnprocessedIndex ); + } + else + { + // Complete ourselves with current TRequestStatus + // Increase index to process next handle on next round + iUnprocessedIndex++; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, iStatus.Int() ); + SetActive(); + } + } + else // all handles processed, can send data + { + SendResponseL( EMTPRespCodeOK ); + } + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::RunError +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CSetObjectPropList::RunError( TInt aError ) + { + PRINT1( _L( "MM MTP <> CSetObjectPropList::RunError with error %d" ), aError ); + + // Reschedule ourselves + // TODO: go to next index or increase? + // iUnprocessedIndex++ +// TRequestStatus* status = &iStatus; +// User::RequestComplete( status, aError ); +// SetActive(); + PRINT1( _L( "MM MTP <> CGetObjectPropList::RunError aError = %d" ), aError ); + TRAP_IGNORE( SendResponseL( EMTPRespCodeGeneralError ) ); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CSetObjectPropList::DoCancel() +// Cancel the process +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSetObjectPropList::DoCancel() + { + + } + +// end of file