diff -r 6a20128ce557 -r ebfee66fde93 mmsengine/mmsmessage/src/mmsserverentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsengine/mmsmessage/src/mmsserverentry.cpp Fri Jun 04 10:25:39 2010 +0100 @@ -0,0 +1,618 @@ +/* +* Copyright (c) 2003-2007 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: +* Entry wrapper for server side components using CMmsEncode and CMmsDecode +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mmsconst.h" +#include "mmsservercommon.h" +#include "mmsserverentry.h" +#include "mmsheaders.h" +#include "mmssettings.h" +#include "mmsdrm.h" +#include "mmserrors.h" +#include "MmsEnginePrivateCRKeys.h" +#include "mmsattachmenthandler.h" +#include "mmsgenutils.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +#ifdef __MMS_HUTC_FWD_NO +const TInt KMms2 = 2; // just get rid of codescammer complaints +#endif + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// ==================== LOCAL FUNCTIONS ==================== + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// +// --------------------------------------------------------- +// +CMmsServerEntry::CMmsServerEntry( + RFs& aFs, + CMsvServerEntry& aServerEntry ): + iFs ( aFs ), + iServerEntry ( aServerEntry ), + iFileOpen( EFalse ) + { + } + +// --------------------------------------------------------- +// EPOC default constructor can leave. +// --------------------------------------------------------- +// +void CMmsServerEntry::ConstructL( TMsvId aServiceId ) + { + iServiceId = aServiceId; + if ( iServerEntry.Entry().Id() != aServiceId ) + { + // this is a message entry, we are supposed to handle it. + iMessageEntry = iServerEntry.Entry().Id(); + } + else + { + iMessageEntry = KMsvNullIndexEntryId; + } + + iMessageDrive = MessageServer::CurrentDriveL( iFs ); + + TMmsGenUtils::GetLoggingSettings( iLogAllDecoded, iDump ); + + // The context stays on the message entry, but service entry is freed + // The entry we got is only a reference. + // If the caller changes the entry, he must call SetCurrentEntry() to + // update the message entry. + iServerEntry.SetEntry( iMessageEntry ); + } + +// --------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------- +// +EXPORT_C CMmsServerEntry* CMmsServerEntry::NewL( + RFs& aFs, + CMsvServerEntry& aServerEntry, + TMsvId aServiceId) + { + CMmsServerEntry* self = new (ELeave) CMmsServerEntry( aFs, aServerEntry ); + + CleanupStack::PushL( self ); + self->ConstructL( aServiceId ); + CleanupStack::Pop( self ); + + return self; + } + + +// --------------------------------------------------------- +// Destructor. +// --------------------------------------------------------- +// +CMmsServerEntry::~CMmsServerEntry() + { + // release any entry we might be holding + Reset(); + + iServerEntry.SetEntry( KMsvNullIndexEntryId ); + } + +// --------------------------------------------------------- +// CMmsServerEntry::EditStoreL +// --------------------------------------------------------- +// +CMsvStore* CMmsServerEntry::EditStoreL() + { + return iServerEntry.EditStoreL(); + } + +// --------------------------------------------------------- +// CMmsServerEntry::ReadStoreL +// --------------------------------------------------------- +// +CMsvStore* CMmsServerEntry::ReadStoreL() + { + return iServerEntry.ReadStoreL(); + } + +// --------------------------------------------------------- +// CMmsServerEntry::GetIndexEntry +// --------------------------------------------------------- +// +TInt CMmsServerEntry::GetIndexEntry( TMsvEntry& aTMsvEntry ) + { + if ( iMessageEntry == KMsvNullIndexEntryId ) + { + return KErrNotFound; + } + aTMsvEntry = iServerEntry.Entry(); + return KErrNone; + } + +// --------------------------------------------------------- +// CMmsServerEntry::ChangeIndexEntry +// --------------------------------------------------------- +// +TInt CMmsServerEntry::ChangeIndexEntry( TMsvEntry& aTMsvEntry ) + { + TInt error = KErrNone; + if ( iMessageEntry == KMsvNullIndexEntryId ) + { + return KErrNotFound; + } + error = iServerEntry.ChangeEntry( aTMsvEntry ); + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry::SetCurrentEntry +// --------------------------------------------------------- +// +TInt CMmsServerEntry::SetCurrentEntry( TMsvId aId ) + { + TInt error = KErrNone; + if ( iMessageEntry == aId && iServerEntry.Entry().Id() == aId ) + { + // we already have the context + return error; + } + error = iServerEntry.SetEntry ( aId ); + if ( error == KErrNone ) + { + iMessageEntry = aId; + } + else + { + iMessageEntry = KMsvNullIndexEntryId; + } + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry::AttachmentsSizeL +// --------------------------------------------------------- +// +TInt CMmsServerEntry::AttachmentsSizeL( CMsvStore& aStore ) + { + return CMmsAttachmentHandler::AttachmentsSizeL( aStore ); + } + +// --------------------------------------------------------- +// CMmsServerEntry::DiskSpaceBelowCriticalLevelL +// --------------------------------------------------------- +// +TInt CMmsServerEntry::DiskSpaceBelowCriticalLevelL( TInt aDataSize ) + { + TInt error = KErrNone; + + if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( + &iFs, aDataSize, iMessageDrive ) ) + { + error = KErrDiskFull; + } + + return error; + } + + +// --------------------------------------------------------- +// CMmsServerEntry::StoreMmsHeadersL +// --------------------------------------------------------- +// +TInt CMmsServerEntry::StoreMmsHeadersL( CMmsHeaders& aMmsHeaders, CMsvStore* aStore ) + { + // The entry must be kept pointing to the message entry + // As all attachment are stored to the message enrty, it is + // no longer necessary to switch the context between message + // entry and attachment entry. + TInt error = KErrNone; + if ( DiskSpaceBelowCriticalLevelL( aMmsHeaders.Size() ) ) + { + error = KErrDiskFull; + } + + if ( error == KErrNone ) + { + CMsvStore* store = aStore; + if ( !aStore ) + { + store = iServerEntry.EditStoreL(); + CleanupStack::PushL(store); + } + aMmsHeaders.StoreL(*store); + if ( !aStore ) + { + store->CommitL(); + CleanupStack::PopAndDestroy( store ); + } + } + + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry::RestoreMmsHeadersL +// --------------------------------------------------------- +// +void CMmsServerEntry::RestoreMmsHeadersL( CMmsHeaders& aMmsHeaders, CMsvStore* aStore ) + { + // The entry must be kept pointing to the message entry + // As all attachment are stored to the message enrty, it is + // no longer necessary to switch the context between message + // entry and attachment entry. + CMsvStore* store = aStore; + if ( !aStore ) + { + store = iServerEntry.ReadStoreL(); + CleanupStack::PushL( store ); + } + aMmsHeaders.RestoreL( *store ); + if ( !aStore ) + { + CleanupStack::PopAndDestroy( store ); + } + } + +// --------------------------------------------------------- +// CMmsServerEntry::CreateFileAttachmentL +// --------------------------------------------------------- +// +TInt CMmsServerEntry::CreateFileAttachmentL( + CMsvStore& aStore, + const TDesC& aFileName, + const TPtrC8& aAttachmentData, + CMsvMimeHeaders& aMimeHeaders, + TMsvAttachmentId& aAttachment, + TInt& aAttachmentSize, + TInt32& aDRMFlags) + { + + TInt error = KErrNone; + CreateEmptyFileAttachmentL( + aStore, + aFileName, + aMimeHeaders, + aAttachment ); + + error = ProcessAttachmentDataL( aAttachmentData, aDRMFlags ); + + TInt error2 = KErrNone; + error2 = FinalizeAttachmentL( aStore, aAttachmentSize, aDRMFlags ); + + if ( error == KErrNone ) + { + error = error2; + } + + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry::DeleteEntry +// --------------------------------------------------------- +// +TInt CMmsServerEntry::DeleteEntry( TMsvId aEntryIndex ) + { + TInt error = iServerEntry.SetEntry( aEntryIndex ); + if ( error == KErrNone ) + { + error = iServerEntry.SetEntry( iServerEntry.Entry().Parent() ); + if ( error == KErrNone ) + { + error = iServerEntry.DeleteEntry( aEntryIndex ); + } + } + iServerEntry.SetEntry( KMsvNullIndexEntryId ); + iMessageEntry = KMsvNullIndexEntryId; + return error; + + } + +// --------------------------------------------------------- +// CMmsServerEntry::IsValidFilename +// --------------------------------------------------------- +// +TBool CMmsServerEntry::IsValidFilename( const TPtrC& aFileName ) + { + return CMmsAttachmentHandler::IsValidFilename( iFs, aFileName ); + } + +// --------------------------------------------------------- +// CMmsServerEntry::GetDecodingFlag +// --------------------------------------------------------- +// +TBool CMmsServerEntry::GetDecodingFlag() + { + return iLogAllDecoded; + } + +// --------------------------------------------------------- +// CMmsServerEntry::GetDumpFlag +// --------------------------------------------------------- +// +TBool CMmsServerEntry::GetDumpFlag() + { + return iDump; + } + +// --------------------------------------------------------- +// CMmsServerEntry:: +// --------------------------------------------------------- +// +void CMmsServerEntry::CreateEmptyFileAttachmentL( + CMsvStore& aStore, + const TDesC& aFileName, + CMsvMimeHeaders& aMimeHeaders, + TMsvAttachmentId& aAttachment ) + { + iAttaId = 0; + Reset(); + iRemoveDRM = EFalse; + + TBool noForward = EFalse; +// Hutch parameter handling disabled because there is a bug in DRM Asset +#ifdef __MMS_HUTC_FWD_NO +// Test for H. fwd=no parameter handling +// Also ringtone=no +// MMS DRM will eventually take care of both + TInt i = 0; + for ( i = 0; i < aMimeHeaders.ContentTypeParams().MdcaCount() - 1; i += KMms2 ) + { + if ( ( aMimeHeaders.ContentTypeParams().MdcaPoint( i ).CompareF( KMmsForwardHeader ) == 0 + || aMimeHeaders.ContentTypeParams().MdcaPoint( i ). + CompareF( KMmsRingtoneHeader ) == 0 ) + && aMimeHeaders.ContentTypeParams().MdcaPoint( i + 1 ).CompareF( KMmsNoHeader ) == 0 ) + { + noForward = ETrue; + } + } +#endif + + if ( aMimeHeaders.ContentSubType().FindF( KMmsDrmMessageCT ) != KErrNotFound || noForward ) + { + // This is a drm message. + if ( !iDrmHandler ) + { + iDrmHandler = CMmsDrmCaf::NewL(); + } + iDRMNeeded = iDrmHandler->RegisterL( aMimeHeaders ); + } + // We try to continue in any case if we did not run out of memory + // If check within MmsDrm fails, iDRMNeeded is set to true, and we will try + // DRM handling later. + + // store must be created before attachmentInfo because attachment info ownership + // will be transferred to attachment manager + + CMsvAttachment* attachmentInfo = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); + CleanupStack::PushL( attachmentInfo ); + + attachmentInfo->SetAttachmentNameL( aFileName ); + // We must set size after the data has been saved + attachmentInfo->SetComplete( ETrue ); + + // take type from mime headers + HBufC8* tempContentType = HBufC8::NewL( aMimeHeaders.ContentType().Length() + + aMimeHeaders.ContentSubType().Length() + 1 ); + CleanupStack::PushL( tempContentType ); + tempContentType->Des().Copy( aMimeHeaders.ContentType() ); + tempContentType->Des().Append( KMmsSlash8 ); + tempContentType->Des().Append( aMimeHeaders.ContentSubType() ); + attachmentInfo->SetMimeTypeL( tempContentType->Des() ); + CleanupStack::PopAndDestroy( tempContentType ); + + aMimeHeaders.StoreL( *attachmentInfo ); // Mime headers are streamed into atta info + + if ( DiskSpaceBelowCriticalLevelL( aMimeHeaders.Size() ) ) + { + CleanupStack::PopAndDestroy( attachmentInfo ); + User::Leave( KErrDiskFull ); + } + + MMsvAttachmentManagerSync& attaMan = aStore.AttachmentManagerExtensionsL(); + attaMan.CreateAttachmentL( aFileName, iAttaFile, attachmentInfo ); + CleanupStack::Pop( attachmentInfo ); + aAttachment = attachmentInfo->Id(); + iAttaId = aAttachment; + iFileOpen = ETrue; + + if ( iDRMNeeded ) + { + iDrmHandler->StartProcessingL( iAttaFile, attachmentInfo->FilePath(), aStore ); + // the atta file can now be closed + iAttaFile.Close(); + } + + } + +// --------------------------------------------------------- +// CMmsServerEntry:: +// --------------------------------------------------------- +// +TInt CMmsServerEntry::ProcessAttachmentDataL( + const TPtrC8& aAttachmentData, + TInt32& aDRMFlags ) + { + TInt error = KErrNone; + + if ( DiskSpaceBelowCriticalLevelL( aAttachmentData.Size() ) ) + { + return KErrDiskFull; + } + + if ( !iDRMNeeded ) + { + error = iAttaFile.Write( aAttachmentData ); + } + else + { + // if we have iDRMNeeded, we must also have the handler + error = iDrmHandler->WriteData( aAttachmentData ); + if ( error != KErrNone ) + { + error = KMmsErrorRemoveDRM; + iRemoveDRM = ETrue; + aDRMFlags |= EMmsDrmCorruptedAttachment; + } + } + + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry:: +// --------------------------------------------------------- +// +TInt CMmsServerEntry::FinalizeAttachmentL( + CMsvStore& aStore, + TInt& aAttachmentSize, + TInt32& aDRMFlags ) + { + TInt error = KErrNone; + + TInt size = 0; + if ( iFileOpen ) + { + if ( iDRMNeeded ) + { + // If DRM is needed, we have the handler + TRAP( error, iDrmHandler->EndProcessingL() ); + iFileOpen = EFalse; + if ( error != KErrNone ) + { + error = KMmsErrorRemoveDRM; + } + } + else + { + error = iAttaFile.Flush(); + iAttaFile.Size( size ); + } + } + aAttachmentSize = size; + + // reset closes the file and stream + Reset(); + + MMsvAttachmentManager& attaMan = aStore.AttachmentManagerL(); + MMsvAttachmentManagerSync& attaManSync = aStore.AttachmentManagerExtensionsL(); + + if ( iRemoveDRM || error == KMmsErrorRemoveDRM ) + { + error = KMmsErrorRemoveDRM; + aDRMFlags |= EMmsDrmCorruptedAttachment; + // can only remove synchronously if index is known. + TInt count = attaMan.AttachmentCount(); + TInt i = count - 1; + TBool found = EFalse; + while ( i >= 0 && !found ) + { + CMsvAttachment* attachmentInfo = attaMan.GetAttachmentInfoL( i ); + if ( attachmentInfo->Id() == iAttaId ) + { + found = ETrue; + } + else + { + i--; + } + delete attachmentInfo; + attachmentInfo = NULL; + } + if ( i >= 0 && found ) + { + attaManSync.RemoveAttachmentL( i ); + } + } + else + { + if ( size == 0 ) + { + // If the file was encrypted, te size could not be obtained before. + // See if we can get it now + RFile handle = attaMan.GetAttachmentFileL( iAttaId ); + handle.Size( size ); + handle.Close(); + } + CMsvAttachment* attachmentInfo = attaMan.GetAttachmentInfoL( iAttaId ); + CleanupStack::PushL( attachmentInfo ); + attachmentInfo->SetSize( size ); + TRAPD( error2, attaManSync.ModifyAttachmentInfoL( attachmentInfo ) ); + if ( error2 == KErrNone ) + { + CleanupStack::Pop( attachmentInfo ); + } + else + { + // if error, attachmentinfo ownership was not transferred + CleanupStack::PopAndDestroy( attachmentInfo ); + } + } + // Error about unsuccessful attachment info modification is not returned to caller. + // The attachment size info is unreliable anyway, actual file size should always be called + + iRemoveDRM = EFalse; + return error; + } + +// --------------------------------------------------------- +// CMmsServerEntry:: +// --------------------------------------------------------- +// +void CMmsServerEntry::Reset() + { + if ( iFileOpen ) + { + iAttaFile.Close(); + iFileOpen = EFalse; + } + + delete iDrmHandler; + iDrmHandler = NULL; + iDRMNeeded = EFalse; + + } + + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// End of File