mmsengine/mmsmessage/src/mmsserverentry.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsengine/mmsmessage/src/mmsserverentry.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -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    <msventry.h>
+#include    <msvstd.h>
+#include    <msvapi.h>
+#include    <apparc.h>
+#include    <badesca.h>
+#include    <msvstore.h>
+#include    <cmsvmimeheaders.h>
+#include    <mmsvattachmentmanager.h>
+#include    <mmsvattachmentmanagersync.h>
+#include    <centralrepository.h>
+
+#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