upnpmediaserver/contentdirectoryservice/src/upnpcontentdirectory.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:29:11 +0300
branchRCL_3
changeset 12 cdcbf344a1d3
parent 1 499c41045f6d
child 13 e0762c15653a
permissions -rw-r--r--
Revision: 201012 Kit: 201035

/** @file
* Copyright (c) 2005-2006 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:  Content Directory
 *
*/


// INCLUDE FILES
#include <fbs.h>
#include <uri8.h>
#include <pathinfo.h>
#include <xml/dom/xmlengdom.h>
#include <xml/dom/xmlengserializationoptions.h>
#include <xml/dom/xmlengdomparser.h>
#include <sysutil.h>
#include <bautils.h>
#include <caf/caf.h>
#include <caf/manager.h>

#include "upnpsender.h"
#include "upnpcontentdirectory.h"
#include "upnperrors.h"
#include "upnpdominterface.h"
#include "upnpstring.h"
#include "upnpargument.h" 
#include "upnphttpmessagefactory.h" 
#include "upnpcons.h"
#include "upnpdevice.h"
#include "upnpfileutils.h"
#include "upnpcommonupnplits.h"
#include "upnpcontainerupdateid.h"
#include "upnpcontentdirectorydb.h"
#include "upnpfiletransfertimerobserver.h"
#include "upnperror.h"
#include "upnpcustomlog.h"
#include "upnpprotocolinfo.h"
#include "upnpcontentdirectoryglobals.h"
#include "upnpresourcesbean.h"
#include "upnpcdutils.h"
#include "upnpmetadatastorage.h"
#include "upnpautodestroyobjectlist.h"
#include "upnpautodestroyobject.h"
#include "upnpcontentdirectoryeventobserver.h"
#include "upnpfiletransferevent.h"
#include "upnpfiletransfer.h"
#include "upnpprotocolinfolocal.h"
#include "upnpxmlcontentfilter.h"
#include "upnpstatehandler.h"
#include "upnptransferuploader.h"
#include "upnpmimemapper.h"
#include "upnptransfercontroller.h"
#include "upnptransferinterface.h"
#include "upnpdlnafilter.h"
#include "upnphttpserversession.h"
#include "upnphttpserverruntime.h"
#include "upnpsettings.h"
#include "upnpdeviceimplementationbase.h"
#include "upnpsecuritymanager.h"
#include "upnpmediaserversettings.h"

// Constant definitions
using namespace UpnpPaths;
using namespace UpnpDlnaProtocolInfo;

// ============================= LOCAL FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// DestroyRPointerArray
// Defined in upnpelementfactory.cpp
// -----------------------------------------------------------------------------
//
void DestroyRArray( TAny* aArray );
void RPointerArrayTPtrC8( TAny* aArray )
    {
    RPointerArray<TPtrC8>* array =
            reinterpret_cast<RPointerArray<TPtrC8>*>(aArray);
    array->ResetAndDestroy( );
    }

// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CUpnpContentDirectory
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CUpnpContentDirectory::CUpnpContentDirectory( CUpnpDevice& aDevice,
    MUpnpThumbnailCreatorObserver* aThmbObs, MUpnpTransferInterface* aTransfer ) :

    CUpnpServiceImplementation(aDevice), iThmbObs(aThmbObs),
            iTransferHandler(aTransfer)

    {
    SetExecutedAction( EUndefinedAction );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::~CUpnpContentDirectory
// C++ default destructor
// -----------------------------------------------------------------------------
//
CUpnpContentDirectory::~CUpnpContentDirectory()
    {
    delete iDownloadDir;
    delete iThumbDir;
    delete iElementdb;

    delete iTransferController;
    delete iMimeToExtMap;

    delete iContentDirectoryDb;

    iThObjectIds.Close( );

    iThumbnailCreators.ResetAndDestroy( );

    iDOMImpl.Close( );
    if ( iBitmapServerConnection == KErrNone )
        RFbsSession::Disconnect( );
    iFs.Close( );
    if ( iEcomUsed )
        {
        REComSession::FinalClose( );
        }
    delete iAutoDestroyObjects;
    delete iStateHandler;
    if ( iHttpServerSession )
        {
        iHttpServerSession->Stop();
        }
    delete iHttpServerSession;
    delete iDlnaFilter;
    delete iSecurityManager;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ConstructL
// Two-phased constructor.
// Initialize variables, set parent service and create XML reader.
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::ConstructL( TUpnpCdSettings aSettings,
    CUpnpMetadataStorage* aMetadataStorage )
    {
    iDOMImpl.OpenL( );

    iTransferController = CUpnpTransferController::NewL( this );

    iMimeToExtMap = CUpnpMimeMapper::NewL( );

    BaseConstructL( aSettings.iDescriptionPath, KContentDirectoryType( ) );

    User::LeaveIfNull( aSettings.iDevice );
    
    CUpnpSecurityManager* secMan = CUpnpSecurityManager::NewInstanceFromUpnpSettingsL();
    
    iSecurityManager = secMan;
    iDlnaFilter = CUpnpDlnaFilter::NewL( this, secMan );
    
    iElementdb = CUpnpElementFactory::NewL( aSettings.iObjectsXmlPath );
    iElementdb->GetContentDirectoryReference( this );

    SetStateVariableL( KSystemUpdateID( ), KZero( ) );
    SetStateVariableL( KContainerUpdateIDs( ), UpnpCD::KEmptyString( ) );
    SetStateVariableL( KTransferIDs( ), UpnpCD::KEmptyString( ) , EFalse );
    SetStateVariableL( KSortCapsVariableName( ), KSortCapabilities( ) );
    SetStateVariableL( KSearchCapsVariableName( ), KSearchCapabilities( ) );

    // file session 
    User::LeaveIfError( iFs.Connect( ) );

    iBitmapServerConnection = RFbsSession::Connect( );
    iDownloadDir = aSettings.iDownloadDir.AllocL( );
    iThumbDir = aSettings.iThumbnailDir.AllocL( );
    iContentDirectoryDb = CUpnpContentDirectoryDb::NewL( aMetadataStorage );
    iAutoDestroyObjects = CUpnpAutoDestroyObjectList::NewL( );
    iCreateThumbnails = aSettings.iCreateThumbnail;
    iMaxRequestCount = aSettings.iMaxRequestCount;
    iEventObserver = aSettings.iEventObserver;
    iStateHandler = CUpnpStateHandler::NewL( this );
    
    ConstructHttpL();
    }

void CUpnpContentDirectory::ConstructHttpL()
    {
    TInt iapId = CUpnpSettings::GetIapL();
    iHttpServerSession = CUpnpHttpServerSession::NewL( iapId, *this );
    iHttpServerSession->DefaultRuntime().SetCreator( *this );
    iHttpServerSession->StartL();
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CUpnpContentDirectory* CUpnpContentDirectory::NewL(
    TUpnpCdSettings aSettings, CUpnpMetadataStorage* aMetadataStorage,
    MUpnpTransferInterface* aTransfer )
    {
    CUpnpContentDirectory* cd = new (ELeave) CUpnpContentDirectory( *aSettings.iDevice,
            aSettings.iThmbObs,
            aTransfer
    );
    CleanupStack::PushL( cd );
    cd->ConstructL( aSettings, aMetadataStorage );
    CleanupStack::Pop( cd );
    return cd;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ActionReceivedLD
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::ActionReceivedLD( CUpnpAction* aAction )
    {
    CleanupStack::PushL( aAction );
    //check security
    if ( iSecurityManager &&
            KErrNone != iSecurityManager->AuthorizeAction( aAction ) )
        {
        //server returns upnp error action failed when not authorized
        User::Leave(EActionFailed);
        }
    // in case of low disk space
    if ( !IsDbOrDiskProblemL( aAction ) )
        {
        // handle event
        TInt ret = EUpnpUndefined;
        TRAPD( err, ret = DoActionReceivedL( aAction ) );
        if ( DataBaseHasBeenRecoveredL( err ) )
            {
            TRAP( err, ret = DoActionReceivedL( aAction ) );
            if ( err == KErrCorrupt )
                {
                err = iContentDirectoryDb->RecreateDatabaseFile();
                }
            }
        else if ( err == KErrNone )
            {
            err = ret;
            }
        LOGS( "ContentDirectory ActionReceivedLD sending soon." );
        DoSendActionL( aAction, TUpnpError( err ) );
        }
    CleanupStack::PopAndDestroy( aAction );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoActionReceivedL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::DoActionReceivedL( CUpnpAction* aAction )
    {
    // sendAndDestroy defines that after processing action must be 
    // sent and destroyed
    TUpnpErrorCode err = EUndefined;

    // Get the name, saves calls in the if-else statements
    TPtrC8 name( aAction->Name() );
    // Verify the action and do the operation(s)
    if ( name.Compare( KBrowse ) == 0 )
        {
        err = BrowseL( aAction );
        }
    else if ( name.Compare( KCreateReference ) == 0 )
        {
        err = CreateReferenceL( aAction );
        }
    else if ( name.Compare( KCreateObject ) == 0 )
        {
        LOGS( "ContentDirectory: Creating a new object" );
        err = CreateObjectL( aAction );
        }
    else if ( name.Compare( KDeleteResource ) == 0 )
        {
        err = DeleteResourceL( aAction );
        }
    else if ( name.Compare( KDestroyObject ) == 0 )
        {
        err = DestroyObjectL( aAction );
        }
    else if ( name.Compare( KExportResource ) == 0 )
        {
        err = ExportResourceL( aAction );
        }
    else if ( name.Compare( KGetSearchCapabilities ) == 0 )
        {
        err = GetSearchCapabilitiesL( aAction );
        }
    else if ( name.Compare( KGetSortCapabilities ) == 0 )
        {
        err = GetSortCapabilitiesL( aAction );
        }
    else if ( name.Compare( KGetSystemUpdateID ) == 0 )
        {
        err = GetSystemUpdateIdL( aAction );
        }
    else if ( name.Compare( KGetTransferProgress ) == 0 )
        {
        err = GetTransferProgressL( aAction );
        }
    else if ( name.Compare( KImportResource ) == 0 )
        {
        err = ImportResourceL( aAction );
        }
    else if ( name.Compare( KStopTransferResource ) == 0 )
        {
        err = StopTransferResourceL( aAction );
        }
    else
        {
        err = EInvalidAction;
        }
    return err;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoActionReceivedCDL
// -----------------------------------------------------------------------------
//    
void CUpnpContentDirectory::HttpGetStartedSoapNotifyL( TInt /*aSessionId*/)
    {
    // not needed upnp response returned by ActionReceivedCDL
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoActionReceivedCDL
// -----------------------------------------------------------------------------
//    
void CUpnpContentDirectory::HttpPostStartedL( TInt /*aSessionId*/)
    {
    // not needed upnp response returned by ActionReceivedCDL
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::UnknownHttpEventReceivedL 
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::UnknownHttpEventReceivedL( CUpnpHttpMessage& aHttpMsg )
    {
    CUpnpFileTransferEvent* transferEvent =
            iTransferController->TransferL( aHttpMsg.SessionId( ) );
    if ( !transferEvent )
        {
        return;
        }

    TInt err = aHttpMsg.Error( );
    if ( err != EHttpRequestTimeout && err != EHttpInsufficientStorage )
        {
        err = EHttpOk;
        }

    HBufC* fileName16 = UpnpString::ToUnicodeL( aHttpMsg.InFilename( ) );
    CleanupStack::PushL( fileName16 );
    transferEvent->SetFilePathL( *fileName16 );
    CleanupStack::PopAndDestroy( fileName16 );

    iTransferController->HttpResponseReceivedL( aHttpMsg.SessionId( ), err );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsDrmFileL 
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsDrmFileL( const TDesC8& aFileName )
    {
    HBufC* tmp = UpnpCdUtils::Des8ToDesLC( aFileName );
    TBool ret = IsDrmFileL( *tmp );
    CleanupStack::PopAndDestroy( tmp );
    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsDrmFileL 
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsDrmFileL( const TDesC& aFileName )
    {
    if ( !BaflUtils::FileExists( iFs, aFileName ) )
        {
        return EFalse;
        }
    TBool ret = EFalse;
    TInt value=0, err;

    ContentAccess::CManager *manager = ContentAccess::CManager::NewL( );
    CleanupStack::PushL( manager );

    ContentAccess::CVirtualPath *path =
            ContentAccess::CVirtualPath::NewL( aFileName );
    CleanupStack::PushL( path );

    ContentAccess::TVirtualPathPtr virtualPath = *path;

    err = manager->GetAttribute( ContentAccess::EIsProtected, value,
        virtualPath );
    if ( err == KErrNone )
        {
        if ( value )
            {
            // delete file
            iFs.Delete( aFileName );
            ret = ETrue;
            }
        }
    CleanupStack::PopAndDestroy( 2, manager );

    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateReferenceL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::CreateReferenceL( CUpnpAction*& aAction )
    {
    TUpnpErrorCode ret = EUpnpUndefined;

    // Get IDs from action 
    TInt conId( KErrNotFound );
    TInt objId( KErrNotFound );

    TInt err = UpnpCdUtils::StringToInteger(
        aAction->ArgumentValue( KContainerID ), &conId );
    if ( err!=KErrNone )
        {
        err=ENoContainer;
        User::Leave( ENoContainer );
        }

    err = UpnpCdUtils::StringToInteger(
        aAction->ArgumentValue( UpnpCD::KObjectID ), &objId );
    if ( err!=KErrNone )
        {
        err=ENoContainer;
        User::Leave( ENoSuchObject );
        }

    objId = iContentDirectoryDb->ReferedObjectIdL( objId );

    RXmlEngDocument conDidl;
    RXmlEngDocument objDidl;
    CleanupClosePushL( conDidl );
    CleanupClosePushL( objDidl );

    ret = iContentDirectoryDb->GetObjectL( conId, conDidl, KAsterisk8 );
    if ( ret != EUpnpOk )
        User::Leave( ENoContainer );

    ret = iContentDirectoryDb->GetObjectL( objId, objDidl, KAsterisk8 );
    if ( ret != EUpnpOk )
        User::Leave( ENoSuchObject );

    TXmlEngElement con = conDidl.DocumentElement().FirstChild().AsElement( );
    TXmlEngElement obj = objDidl.DocumentElement().FirstChild().AsElement( );

    if ( obj.Name().Compare( KItem ) != 0 )
        {
        User::Leave( ENoSuchObject );
        }
    if ( con.Name().Compare( KContainer ) != 0 )
        {
        User::Leave( ENoContainer );
        }
    if ( iContentDirectoryDb->CheckObjectRestrictionL( conId ) != EUpnpOk )
        {
        User::Leave( ERestrictedParentObject );
        }

    TInt refId;
    RXmlEngDocument refDidl = iContentDirectoryDb->PrepareDidlDocumentL( );
    CleanupClosePushL( refDidl );

    TXmlEngElement refEl = refDidl.DocumentElement().AddNewElementSameNsL( KItem( ) );

    refEl.AddNewAttributeL( KRefID( ),
        aAction->ArgumentValue( UpnpCD::KObjectID ) );

    refEl.AddNewAttributeL( KParentID( ),
        aAction->ArgumentValue( KContainerID ) );

    refEl.AddNewAttributeL( KRestricted( ), KFalseValue8( ) );

    // title
    TXmlEngElement objTitle;
    UpnpDomInterface::GetElementL( obj, objTitle, KObjTiltleColName8( ) );
    refEl.AppendChildL( objTitle.Unlink().AsElement( ) );

    // class
    TXmlEngElement objClass;
    UpnpDomInterface::GetElementL( obj, objClass, KObjClassColName8( ) );
    refEl.AppendChildL( objClass.Unlink().AsElement( ) );

    iContentDirectoryDb->InsertObjectL( refDidl, conId, &refId );

    //increase system update ID
    iStateHandler->IncreaseSystemUpdateIdL( );
    iStateHandler->IncreaseContainerUpdateIdL( (TDesC8&)aAction->ArgumentValue( KContainerID ) );

    TBuf8<KMaxIntegerLen> newid;
    newid.Num( refId );
    aAction->SetArgumentL( (TDesC8&)KNewID, newid );

    CleanupStack::PopAndDestroy( &refDidl );
    CleanupStack::PopAndDestroy( &objDidl );
    CleanupStack::PopAndDestroy( &conDidl );

    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::BrowseL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::BrowseL( CUpnpAction*& aAction )
    {
    RDebug::Print( _L( "CUpnpContentDirectory::BrowseL start" ) );
    TInt err( KErrGeneral );

    //Check ObjectID
    TInt objectID( KErrNotFound );
    err = UpnpCdUtils::StringToInteger(
        (TDesC8&)aAction->ArgumentValue( UpnpCD::KObjectID( ) ), &objectID );
    if ( err != KErrNone )
        {
        User::Leave( ENoSuchObject );
        }
    //Check SortCriteria
    if ( aAction->ArgumentValue( (TDesC8&) KSortCriteria ).Compare( (TDesC8&)KSortCapabilities )
            != 0 )
        {
        User::Leave( EInvalidSort ); //wrong sort flag
        }

    //Check BrowseFlag
    TDesC8& browseFlag =
            (TDesC8&)aAction->ArgumentValue( (TDesC8&)KBrowseFlag );
    if ( browseFlag.Compare( KBrowseMeta ) != 0
            && browseFlag.Compare( KBrowseChilds ) != 0 )
        {
        User::Leave( EInvalidArgs ); //wrong browse flag    
        }

    //Check StartIndex
    TInt startIndex( KErrNotFound );
    err = UpnpString::StringToInt(
        (TDesC8&)aAction->ArgumentValue( (TDesC8&)KStartingIndex ),
        &startIndex );
    if ( KErrNone != err )
        {
        User::Leave( EInvalidArgs );
        }

    //Additional check of StartIndex, see documentation
    if ( browseFlag.Compare( KBrowseMeta ) == 0 && startIndex != 0 )
        {
        User::Leave( EInvalidArgs );
        }

    //Check RequestedCount
    TInt reqCount( KErrNotFound );
    err = UpnpString::StringToInt(
        (TDesC8&)aAction->ArgumentValue( (TDesC8&)KRequestedCount ),
        &reqCount );
    if ( KErrNone != err )
        {
        User::Leave( EInvalidArgs );
        }

    //Filter
    HBufC8* filter = aAction->ArgumentValue( KFilter() ).AllocLC( );
    filter->Des().TrimAll( );

    // Metadata browse
    if ( browseFlag.Compare( KBrowseMeta ) == 0 )
        {

        RXmlEngDocument objectDoc;
        CleanupClosePushL( objectDoc );
        // Try to get original object not a reference 
        TInt id = iContentDirectoryDb->ReferedObjectIdL( objectID );
        CleanupStack::Check( &objectDoc );
        TUpnpErrorCode err = EUndefined;
        err = iContentDirectoryDb->GetObjectL( id, objectDoc, *filter );
        if ( err != EUpnpOk )
            User::Leave( err );
        CleanupStack::Check( &objectDoc );
        //--------- new solution for references --------

        // if id != objectID it means that we have a reference, so now id = 'real object id' and objectID = 'reference object id' 
        if ( id != objectID )
            {
            TInt refParentID = iContentDirectoryDb->GetParentIdL( objectID );
            User::LeaveIfError( refParentID );

            UpnpCdUtils::SetObjectIdL(
                UpnpCdUtils::GetObjectElementL( objectDoc ), objectID );
            UpnpCdUtils::SetObjectRefIdL(
                UpnpCdUtils::GetObjectElementL( objectDoc ), id );
            UpnpCdUtils::SetObjectParentIdL(
                UpnpCdUtils::GetObjectElementL( objectDoc ), refParentID );
            UpnpCdUtils::SetRestrictedFieldL(
                UpnpCdUtils::GetObjectElementL( objectDoc ), EFalse );
            }
        //---------------------------------------------

        // Serialize object to descriptor - without DIDL-Lite element
        RBuf8 buf;
        TXmlEngSerializationOptions
                options(TXmlEngSerializationOptions::KOptionOmitXMLDeclaration
                        | TXmlEngSerializationOptions::KOptionIncludeNsPrefixes);
        objectDoc.SaveL( buf, iElementdb->ActiveElementL( objectDoc ),
            options );
        CleanupStack::Check( &objectDoc );
        CleanupClosePushL( buf );
        HBufC8* subResponse = buf.AllocLC( );

        CBufFlat* response = CBufFlat::NewL( KRespBufGranularity );
        CleanupStack::PushL( response );
        UpnpString::AppendStringL( *response, KDidlTag );
        UpnpString::AppendStringL( *response, *subResponse );
        UpnpString::AppendStringL( *response, (TDesC8&) KDidlEnd( ) );

        HBufC8* resultTmp =
                UpnpCdUtils::EncodeXmlStringL( response->Ptr( 0 ) );
        CleanupStack::PushL( resultTmp );
        TPtr8 resultTmpPtr(resultTmp->Des( ));
        InsertRealIpAndPortL( resultTmpPtr );

        // Set action's OUT arguments       
        TBuf8<KMaxIntegerLen> num;

        //Result
        aAction->SetArgumentL( KResult, *resultTmp );

        //NumberReturned
        num.Num( 1 );
        aAction->SetArgumentL( KNumberReturned, num );

        //TotalMatches
        //num.Num(1);
        aAction->SetArgumentL( KTotalMatches, num );

        //UpadateID 
        num.Format(
            UpnpCD::KOneNumber,
            ContainerUpdateId( (TDesC8&)aAction->ArgumentValue( (TDesC8&)UpnpCD::KObjectID ) ) );
        aAction->SetArgumentL( KUpdateID, num );

        // clean up
        CleanupStack::PopAndDestroy( resultTmp );
        CleanupStack::PopAndDestroy( response );
        CleanupStack::PopAndDestroy( subResponse );
        CleanupStack::PopAndDestroy( &buf );
        CleanupStack::PopAndDestroy( &objectDoc );

        }
    //Children browse
    else if ( browseFlag.Compare( KBrowseChilds ) == 0 )
        {
        //array contains pointers to direct childrens.
        RArray<TInt> listOfAllObjects;
        CleanupClosePushL( listOfAllObjects );

        TUpnpErrorCode err = iContentDirectoryDb->GetObjectListL( objectID,
            listOfAllObjects );

        if ( err == ENoSuchObject )
            {
            User::Leave( err );
            }

        // if requestedCount==0 then return all matched objects
        if ( !reqCount )
            {
            reqCount = listOfAllObjects.Count( );
            }

        // if requestedCount cannot be greater than iMaxRequestCount
        if ( iMaxRequestCount > 0 && reqCount > iMaxRequestCount )
            {
            reqCount = iMaxRequestCount;
            }

        // get upnp objects
        RArray<RXmlEngDocument> objs;
        CleanupStack::PushL(TCleanupItem( DestroyRArray, &objs ));

        if ( startIndex < listOfAllObjects.Count( ) )
            { // prepare list of objects which are to be returned
            if ( startIndex + reqCount > listOfAllObjects.Count( ) )
                reqCount = listOfAllObjects.Count( ) - startIndex;
            RArray<TInt> alistOfWantedObjs( &listOfAllObjects[startIndex],
                reqCount);

            iContentDirectoryDb->GetObjectListL( alistOfWantedObjs, *filter,
                objs );
            }

        // prepare response
        // Result
        HBufC8* resp = SerializeObjectsListL( objs );
        CleanupStack::PushL( resp );
        TPtr8 respPtr(resp->Des( ));
        InsertRealIpAndPortL( respPtr );
        aAction->SetArgumentL( KResult, *resp );
        // NumberReturned
        TBuf8<KMaxIntegerLen> num;
        num.Num( objs.Count( ) );
        aAction->SetArgumentL( KNumberReturned, num );
        // TotalMatches
        num.Num( listOfAllObjects.Count( ) );
        aAction->SetArgumentL( KTotalMatches, num );
        // UpdateID
        num.Format(
            UpnpCD::KOneNumber,
            ContainerUpdateId( (TDesC8&)aAction->ArgumentValue( (TDesC8&)UpnpCD::KObjectID ) ) );
        aAction->SetArgumentL( KUpdateID, num );

        // clean up
        CleanupStack::PopAndDestroy( resp );
        CleanupStack::PopAndDestroy( &objs );
        CleanupStack::PopAndDestroy( &listOfAllObjects );
        }
    else //no valid browseflag
        {
        User::Leave( EInvalidArgs );
        }

    RDebug::Print( _L( "CUpnpContentDirectory::BrowseL Result got OK" ) );

    CleanupStack::PopAndDestroy( filter );

    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SerializeObjectsListL
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::SerializeObjectsListL(
    const RArray<RXmlEngDocument>& aObjs )
    {
    CBufFlat* buff = CBufFlat::NewL( KRespBufGranularity );
    CleanupStack::PushL( buff );

    // Didl start
    UpnpString::AppendStringL( *buff, KDidlTag );

    // content
    for ( TInt i = 0; i < aObjs.Count( ); i++ )
        {
        RBuf8 tmp;
        TXmlEngSerializationOptions
                options(TXmlEngSerializationOptions::KOptionOmitXMLDeclaration
                        | TXmlEngSerializationOptions::KOptionIncludeNsPrefixes);
        aObjs[i].SaveL( tmp, iElementdb->ActiveElementL( aObjs[i] ), options );
        CleanupClosePushL( tmp );
        UpnpString::AppendStringL( *buff, tmp );
        UpnpString::AppendStringL( *buff, KLF8 );
        CleanupStack::PopAndDestroy( &tmp );
        }

    // Didl end
    UpnpString::AppendStringL( *buff, KDidlEnd );

    // prepare to return
    HBufC8* ret = UpnpCdUtils::EncodeXmlStringL( buff->Ptr( 0 ) );

    // clean up
    CleanupStack::PopAndDestroy( buff );

    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DestroyObjectL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::DestroyObjectL( CUpnpAction*& aAction )
    {
    TInt objId( KErrNotFound );

    TInt error(0);
    error = UpnpCdUtils::StringToInteger(
        (TDesC8&)aAction->ArgumentValue( UpnpCD::KObjectID( ) ), &objId );
    if ( (error == KErrArgument)||(error == KErrOverflow) )
        {
        User::Leave( ENoSuchObject );
        }
    else if ( error<0 )
        {
        User::Leave( error );
        }
    // check object restriction
    TUpnpErrorCode err = iContentDirectoryDb->CheckObjectRestrictionL( objId ); // if returned ENoContainer it is OK because first of all the restriction is checked
    if ( err == ERestrictedObject || err == ENoSuchObject )
        {
        User::Leave( err );
        }

    // check parent restriction
    err = iContentDirectoryDb->CheckObjectRestrictionL( objId );
    if ( err == ERestrictedObject )
        {
        User::Leave( ERestrictedParentObject );
        }

    // root and download containers must not be deleted
    if ( objId <= KDownloadContId )
        {
        /*
         Designing a UPnP AV MediaServer (3.2.4): 
         "If a CDS implementation exposes a CDS object that is not restricted but cannot fulfill a
         CDS:DestroyObject(), CDS:CreateObject(), or CDS:UpdateObject() request, then the MediaServer should
         return error code 720 to indicate the request could not be processed."
         */
        User::Leave( ECannotProcess );
        }

    RArray<TInt> refList;
    CleanupClosePushL( refList );

    TBuf8<KMaxIntegerLen> containerID;
    containerID.Num( iContentDirectoryDb->GetParentIdL( objId ) );

    iContentDirectoryDb->DeleteObjectL( objId, refList, ETrue );

    iStateHandler->IncreaseSystemUpdateIdL( );
    iStateHandler->IncreaseContainerUpdateIdL( containerID );

    for ( TInt i(0); i<refList.Count( ); i++ )
        {
        if ( objId!=refList[i] )
            {
            containerID.Num( refList[i] );
            iStateHandler->IncreaseSystemUpdateIdL( );
            iStateHandler->IncreaseContainerUpdateIdL( containerID );
            }
        }
    // clean up
    CleanupStack::PopAndDestroy( &refList );
    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AddToMetaDbL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::AddToMetaDbL(
    RXmlEngDocument& aFragment, TInt aContainer, TInt* aId, TBool aIsLocal )
    {
    // res list
    RArray<TXmlEngElement> resList;
    CleanupClosePushL( resList );
    UpnpDomInterface::GetElementListL( aFragment.DocumentElement( ), resList,
        KRes );

    // a source file for thumbnail
    HBufC* thumbSrcFile = NULL;

    if ( aIsLocal )
        { // local action
        // create thumbnail if there is only one res in the object
        if ( resList.Count( ) == 1 )
            {
            // get resource file name
            TPtrC8 val(resList[0].Text( ));
            // ignore if empty string
            if ( val.Length( ) && (!UpnpCdUtils::IsWhiteString( val )) )
                {
                TUriParser8 up;
                User::LeaveIfError( up.Parse( val ) );
                if ( up.Extract( EUriScheme ) == UpnpHTTP::KSchemeFile8 )
                    {
                    thumbSrcFile = up.GetFileNameL( ); // thumbnail will be created at the end of this function
                    CleanupStack::PushL( thumbSrcFile );// and the pointer will be poped 
                    }
                }
            }
        TInt nextId = iContentDirectoryDb->GetObjectIdL( );
        // handle resources
        for ( TInt i = 0; i < resList.Count( ); i++ )
            {
            HandleLocalResourcesL( resList[i], nextId );
            }
        }

    // if only one empty res add importUri
    if ( resList.Count( ) )
        {
        TPtrC8 resValue(resList[0].Text( ));
        if ( !resValue.Length( ) || UpnpCdUtils::IsWhiteString( resValue ) )
            {
            AddImportUriToElL( resList[0] );
            }
        }
    if ( !resList.Count( ) )
        {
        AddNewResTagL( aFragment.DocumentElement( ) );
        }
    // add to database
    TUpnpErrorCode ret = iContentDirectoryDb->InsertObjectL( aFragment,
        aContainer, aId );
    if ( ret == EUpnpOk )
        {
        PrepareAutoDestroyObjectL( aFragment.DocumentElement( ), *aId );
        ret = EHttpOk;
        }

    if ( thumbSrcFile )
        {
        CreateThumbnailL( *thumbSrcFile, *aId );
        CleanupStack::PopAndDestroy( thumbSrcFile );
        }
    CleanupStack::PopAndDestroy( &resList );
    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateThumbnailForResourceL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::PrepareAutoDestroyObjectL(
    TXmlEngElement aObject, TInt aObjId )
    {
    // check res
    RArray<TXmlEngElement> resList;
    CleanupClosePushL( resList );
    UpnpDomInterface::GetElementListL( aObject, resList, KRes );
    if ( resList.Count( ) > 0 )
        {
        // only first res is important
        TPtrC8 resValue(resList[0].Text( ));
        if ( !resValue.Length( ) || UpnpCdUtils::IsWhiteString( resValue ) )
            {
            TXmlEngAttr impUri = resList[0].AttributeNodeL( KImportUri( ) );
            // auto destroy
            CUpnpAutoDestroyObject* ado = CUpnpAutoDestroyObject::NewLC(
                this, aObjId, UpnpCdUtils::ResIdFromUriL( impUri.Value( ) ) );
            iAutoDestroyObjects->AppendL( ado );
            CleanupStack::Pop( ado );
            }
        }

    // clean up
    CleanupStack::PopAndDestroy( &resList );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateThumbnailForResourceL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::CreateThumbnailL( const TDesC& aSrcFile,
    TInt aObjId )
    {
    if ( iCreateThumbnails && IsThumbnailAvailableL( aSrcFile ) )
        {
        // thumbnail name
        HBufC* thumbName = CreateNameForThumbnailL( aSrcFile );
        CleanupStack::PushL( thumbName );

        // create thumbnail creator
        CUpnpThumbnailCreator* thCreator = CreateThumbnailCreatorL( aObjId ); // do not push it onto CleanupStack
        // ThumbnailCreator is created and added to iThumbnailCreators
        // but the creation process is not yet started,
        // therefore, not leaving code should be performed until the thCreator->CreateL method is called
        if ( thCreator )
            {
            // start creation process
            TRAPD( err, thCreator->CreateL( aSrcFile, *thumbName ) );
            if ( err )
                {
                RDebug::Print( _L( "Error while creating thumbnail, it won't be created. Removing from creator list." ) );
                RemoveThCreatorAndObjectIdLD( thCreator );
                }
            iEcomUsed = ETrue;
            }
        // clean up
        CleanupStack::PopAndDestroy( thumbName );
        }
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsThumbnailAvailableL
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsThumbnailAvailableL( const TDesC& aFile )
    {
    HBufC8* tmp = HBufC8::NewLC( aFile.Length( ) );
    tmp->Des().Copy( aFile );
    TBool ret = IsThumbnailAvailableL( *tmp );
    CleanupStack::PopAndDestroy( tmp );
    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsThumbnailAvailableL
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsThumbnailAvailableL( const TDesC8& aFile )
    {
    TBool result = EFalse;

    // get mime type for file
    HBufC8* mt = GetMimeTypeLC( aFile );
    TPtr8 mimeType(mt->Des( ));
    mimeType.LowerCase( );

    if ( !mimeType.Compare( KMT_IMAGE_JPEG( ) ) )
        {
        result = ETrue;
        }
    else if ( !mimeType.Compare( KMT_IMAGE_PNG( ) ) )
        {
        result = ETrue;
        }
    else if ( !mimeType.Compare( KMT_IMAGE_GIF( ) ) )
        {
        result = ETrue;
        }
    else if ( !mimeType.Compare( KMT_IMAGE_BMP( ) ) )
        {
        result = ETrue;
        }
    CleanupStack::PopAndDestroy( mt );

    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AddImportUriToElL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::AddImportUriToElL( TXmlEngElement aElement )
    {
    HBufC8* impUriVal = BuildImportUriShorterLC( );
    HBufC8* impUriValRandomize = HBufC8::NewLC( impUriVal->Des().Length( )+ KRandomRangeLength );
    HBufC8* number = UpnpCdUtils::RandomizeL( KRandomMax );
    CleanupStack::PushL( number );
    impUriValRandomize->Des().Copy( *impUriVal );
    impUriValRandomize->Des().Append( *number );
    aElement.AddNewAttributeL( KImportUri( ), *impUriValRandomize );
    // clean up
    CleanupStack::PopAndDestroy( number );
    CleanupStack::PopAndDestroy( impUriValRandomize );
    CleanupStack::PopAndDestroy( impUriVal );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AddNewResTagL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::AddNewResTagL( TXmlEngElement aObjEl )
    {
    TXmlEngElement item;
    UpnpDomInterface::GetElementL( aObjEl, item, KItem );

    // ignore if null
    if ( item.NotNull( ) )
        {
        TXmlEngElement newEl = item.AddNewElementL( KRes( ) );
        newEl.AddNewAttributeL( KprotocolInfo( ), KEmptyProtocolInfoVal8( ) );
        newEl.AddNewAttributeL( KProtInfoReqAtrSufPattern( ), KTrueValue8( ) );
        // add importUri
        AddImportUriToElL( newEl );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::BuildContentUriL
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::BuildContentUriL( const TDesC& aFileExt,
    TInt aObjectId )
    {
    TBuf8<KMaxIntegerLen> objectId;
    objectId.Num( aObjectId );
    return UpnpCdUtils::BuildContentUriL(
        iContentDirectoryDb->GetKeyForUriL( ), aFileExt, objectId );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::BuildImportUriL
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::BuildImportUriLC()
    {
    return UpnpCdUtils::BuildImportUriLC( iContentDirectoryDb->GetKeyForUriL( ) );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::BuildImportUriShorterLC
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::BuildImportUriShorterLC()
    {
    return UpnpCdUtils::BuildImportUriShorterLC( iContentDirectoryDb->GetKeyForUriL( ) );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::InsertRealIpAndPortL
// -----------------------------------------------------------------------------
void CUpnpContentDirectory::InsertRealIpAndPortL( TDes8& aString )
    {
    // prepare pettern
    HBufC8* pattern = HBufC8::NewLC( KHttpTag().Length( ) + KIpPortPlaceholder8().Length( ) );
    TPtr8 patternPtr(pattern->Des( ));
    patternPtr.Append( KHttpTag );
    patternPtr.Append( KIpPortPlaceholder8 );

    // repare address
    HBufC8* address = GetIpAndPortDes8L( );
    CleanupStack::PushL( address );

    TInt pos = aString.Find( patternPtr );

    while ( pos != KErrNotFound )
        {
        aString.Replace( pos + KHttpTag().Length( ), KIpPortPlaceholder8().Length( ), *address );
        pos = aString.Find( patternPtr );
        }

    // clean up
    CleanupStack::PopAndDestroy( address );
    CleanupStack::PopAndDestroy( pattern );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::InsertIpAndPortPlaceholderL
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::InsertIpAndPortPlaceholderL(
    const TDesC8& aString )
    {
    HBufC8* ipAndPort = GetIpAndPortDes8L( );
    CleanupStack::PushL( ipAndPort );

    HBufC8* ret = aString.AllocLC( );

    TInt pos = KErrNotFound;
    while ( (pos = ret->Find( *ipAndPort )) != KErrNotFound )
        {
        // realloc if too small
        if ( ipAndPort->Length( ) < KIpPortPlaceholder8().Length( ) )
            {
            HBufC8* tmp = ret->ReAllocL( ret->Length( )
                    + KIpPortPlaceholder8().Length( ) - ipAndPort->Length( ) );
            CleanupStack::Pop( ret );
            ret = tmp;
            CleanupStack::PushL( ret );
            }
        ret->Des().Replace( pos, ipAndPort->Length( ), KIpPortPlaceholder8 );
        }
    // clean up
    CleanupStack::Pop( ret );
    CleanupStack::PopAndDestroy( ipAndPort );

    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetAddress
// -----------------------------------------------------------------------------
TInetAddr CUpnpContentDirectory::GetAddress()
    {
    TInetAddr resourceServerAddress;    
    iHttpServerSession->GetAddress( resourceServerAddress );
    return resourceServerAddress;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AutoDestroyObjectList
// -----------------------------------------------------------------------------
CUpnpAutoDestroyObjectList* CUpnpContentDirectory::GetAutoDestroyObjectList()
    {
    return iAutoDestroyObjects;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetIpAndPortDes8L
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::GetIpAndPortDes8L()
    {
    TInetAddr resourceServerAddress = GetAddress();        
    
    TBuf<KMaxName> addrTmp;
    resourceServerAddress.Output( addrTmp );
    HBufC8* addr = UpnpString::FromUnicodeL( addrTmp );
    CleanupStack::PushL( addr );
    
    TInt portNo = resourceServerAddress.Port();
    TBuf8<KMaxName> port;
    port.Num( portNo );
    
    HBufC8* temp = HBufC8::NewLC( addr->Length( ) + KColon8().Length( ) + port.Length( ) );
    TPtr8 tempPtr( temp->Des() );
    tempPtr.Copy( *addr );
    tempPtr.Append( KColon8 );
    tempPtr.Append( port );

    CleanupStack::Pop( temp );
    CleanupStack::PopAndDestroy( addr );

    return temp;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetSearchCapabilitiesL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::GetSearchCapabilitiesL(
    CUpnpAction*& aAction )
    {
    aAction->SetArgumentL( KSearchCaps,
        StateVariableValue( KSearchCapsVariableName ) );
    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetSortCapabilitiesL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::GetSortCapabilitiesL(
    CUpnpAction*& aAction )
    {
    aAction->SetArgumentL( KSortCaps,
        StateVariableValue( KSortCapsVariableName ) );
    return EHttpOk;
    } 
 
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetSystemUpdateIdL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::GetSystemUpdateIdL(
    CUpnpAction*& aAction )
    {
    const TPtrC8 idValue = StateVariableValue( (TDesC8&)KSystemUpdateID );
    aAction->SetArgumentL( KId, idValue );
    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ImportResourceL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::ImportResourceL( CUpnpAction*& aAction )
    {
    if ( iTransferController->IsMaxImportExportTransfers( ) )
        {
        return ETransferBusy;
        }

    TPtrC8 src = aAction->ArgumentValue( (TDesC8&) KSourceURI );
    TPtrC8 dest = aAction->ArgumentValue( (TDesC8&) KDestinationURI );
    TUriParser8 srcParser;
    TUriParser8 dstParser;

    if ( !(dstParser.Parse( dest ) == 
          KErrNone && dstParser.Extract( EUriScheme ).CompareF( UpnpHTTP::KSchemeHTTP8 ) == 0 ) )
        {
        User::Leave( ENoDestinationResource );
        }

    // there are placeholders instead the real values in the database
    HBufC8* destBuf = InsertIpAndPortPlaceholderL( dest );
    CleanupStack::PushL( destBuf );

    TInt objId;
    // object existence
    if ( (objId
            = iContentDirectoryDb->GetObjIdByAttrL( KImportUri8, *destBuf ) )
            == KErrNotFound )
        {
        User::Leave( ENoDestinationResource );
        }
    // object restrictions
    if ( iContentDirectoryDb->CheckObjectRestrictionL( objId )
            == ERestrictedObject )
        {
        User::Leave( ERestrictedObject );
        }
    // parent restricions
    if ( iContentDirectoryDb->CheckParentRestrictionL( objId ) != EUpnpOk )
        {
        User::Leave( ERestrictedParentObject );
        }

    TInt destinationCut = dest.LocateReverse( '/' );
    if ( destinationCut < KErrNone )
        {
        User::Leave( EInvalidArgs );
        }

    HBufC* name = GetFileNameL( objId );
    CleanupStack::PushL( name );
    if ( !name )
        {
        User::Leave( ENoDestinationResource );
        }

    for ( TInt i( 0); i < iTransferController->iFileTransfers.Count( ) ; i++ )
        {
        if ( iTransferController->iFileTransfers[i]->ObjectId( ) == objId
                && iTransferController->iFileTransfers[i]->TransferState( )
                        == ETransferInProgress )
            {
            User::Leave( EDestinationAccess );
            }
        }

    HBufC8* name8 = UpnpString::FromUnicodeL( *name );
    CleanupStack::PushL( name8 );

    TPtr8 fileNamePtr(name8->Des( ) );

    HBufC16* fileNamePtr16 = UpnpString::ToUnicodeL( fileNamePtr );
    CleanupStack::PushL( fileNamePtr16 );
    TParse parseFilename;
    parseFilename.Set( fileNamePtr16->Des( ), NULL, NULL );
    HBufC16* diskNameTemp=parseFilename.Drive().Alloc( );
    HBufC16* diskName = diskNameTemp->ReAlloc( diskNameTemp->Des().Length( ) +
                                               KDiskPathElSep().Length( ) );
    CleanupStack::PushL( diskName );
    TPtr16 diskNamePtr = diskName->Des( );
    diskNamePtr.Append( KDiskPathElSep );
    if ( !BaflUtils::PathExists( iFs, diskNamePtr ) )
        {
        User::Leave( ENoDestinationResource );
        }

    UpnpString::ReplaceHttpCharacters( fileNamePtr );

    // forbidden chars
    UpnpCdUtils::ValidateFilePath( fileNamePtr );

    HBufC* targetPath = HBufC::NewMaxLC( fileNamePtr.Length( ) );
    TPtr targetPtr = targetPath->Des( );
    targetPtr.Copy( fileNamePtr );

    TInt transferid = CUpnpHttpMessage::NewSessionIdL( );
    iTransferHandler->DownloadFileL( transferid, src, targetPtr );

    CleanupStack::PopAndDestroy( targetPath );

    TransferStartL( dest );

    TBuf8<KMaxIntegerLen> tid;
    tid.Num( transferid );
    aAction->SetArgumentL( (TDesC8&)KTransferID, tid );

    CUpnpFileTransfer* transfer = CUpnpFileTransfer::NewLC( transferid,
        objId, CUpnpFileTransfer::EImport );

    transfer->SetTransferState(:: ETransferInProgress );

    // starting to get the number if import
    TPtrC8 dest1 = aAction->ArgumentValue( (TDesC8&) KDestinationURI );
    TInt posOfLastSlash = dest1.LocateReverse( '/' );
    if( posOfLastSlash != KErrNotFound )
        {
        dest1.Set( dest1.Mid( posOfLastSlash + 1 ) );
        // converting value
        TLex8 string( dest1 );
        TInt value( 0 );
        TInt error = string.Val( value );
        // conversion ok, we can add this to 
        if( error == KErrNone )
            {
            transfer->SetImportNumber( value );
            }
        }
    //add transfer to transfers list
    CleanupStack::Pop( transfer );
    iTransferController->iFileTransfers.Append( transfer );

    HBufC* fileName16 = UpnpString::ToUnicodeL( *name8 );
    CleanupStack::PushL( fileName16 );

    CUpnpFileTransferEvent* event = CUpnpFileTransferEvent::NewLC();
    event->SetProgressState( CUpnpFileTransferEvent::ECompleted );
    event->SetDirection( CUpnpFileTransferEvent::EIncoming );
    event->SetFilePathL( *fileName16 );
    event->SetContentDirectoryObjectId( objId );
    event->SetTransferId( transferid );
    CleanupStack::Pop( event );
    transfer->SetEvent( event );

    AddFileTransferToTransferIDsStateVariableL( transferid );
    // clean up
    CleanupStack::PopAndDestroy( fileName16 );
    CleanupStack::PopAndDestroy( diskName );
    CleanupStack::PopAndDestroy( fileNamePtr16 );
    CleanupStack::PopAndDestroy( name8 );
    CleanupStack::PopAndDestroy( name );
    CleanupStack::PopAndDestroy( destBuf );

    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ExportResourceL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::ExportResourceL( CUpnpAction*& aAction )
    {
    if ( iTransferController->IsMaxImportExportTransfers( ) )
        {
        return ETransferBusy;
        }
    HBufC8* srcBuf = aAction->ArgumentValue( KSourceURI ).AllocLC( );
    TPtr8 src(srcBuf->Des( ));
    UpnpString::ReplaceHttpCharacters( src );

    HBufC8* ipAndPort = GetIpAndPortDes8L( );
    CleanupStack::PushL( ipAndPort );
    UpnpCdUtils::ValidateSrcUriL( src, *ipAndPort );
    CleanupStack::PopAndDestroy( ipAndPort );

    TPtrC8 dest = aAction->ArgumentValue( KDestinationURI );

    // check src existence -----------------------------
    CUpnpResourcesBean* rscBean = NULL;
    TRAPD(
        error,
        rscBean
                = iContentDirectoryDb->GetResourceL( UpnpCdUtils::ResIdFromUriL( src ) ) );
    if ( error < 0 || !rscBean )
        {
        User::Leave( ENoSourceResource );
        }
    CleanupStack::PushL( rscBean );
    // check whether resource and src uri file names matches
    TPtrC rscPath(rscBean->Path( ) );

    if ( !BaflUtils::FileExists( iFs, rscPath ) )
        {
        User::Leave( ENoSourceResource );
        }

    TParse rscParse;
    rscParse.Set( rscPath, NULL, NULL );
    TPtrC rscFileName = rscParse.NameAndExt( );

    TBuf8<KMaxIntegerLen> objId;
    objId.Num( rscBean->ObjectId( ) );

    TPtrC rscFileExt = rscParse.Ext( );
    HBufC8* srcNoEsc = src.AllocLC( );
    TPtr8 srcNoEscPtr(srcNoEsc->Des( ));

    HBufC* srcPath = UpnpCdUtils::Des8ToDesLC( srcNoEscPtr );
    TPtr srcPathPtr(srcPath->Des( ) );

    TInt position = srcPathPtr.LocateReverse( '/' );
    HBufC* newFileName = HBufC::NewLC( KMaxIntegerLen + rscFileExt.Length( ) );
    newFileName->Des().Copy( objId );
    newFileName->Des().Append( rscFileExt );
    if ( position )
        {
        position = srcPathPtr.Length( )-position-1;
        TPtrC srcFilePtr = srcPathPtr.Right( position );
        if ( srcFilePtr.Compare( *newFileName ) )
            {
            User::Leave( ENoSourceResource );
            }
        }
    if ( srcPathPtr.Find( *newFileName ) == KErrNotFound )
        {
        User::Leave( ENoSourceResource );
        }
    // get mimeType = Content-Type in the header
    HBufC8* contentType = UpnpFileUtil::GetMimeTypeForFileL( *newFileName );
    TPtrC8 contentTypePtr(contentType->Des( ) );

    CleanupStack::PopAndDestroy( newFileName );
    CleanupStack::PushL( contentType );

    //checking number of slash in sourceURI 
    TInt numberOfSlash(0);
    position = srcPathPtr.LocateReverse( '/' );
    while ( position>0 )
        {
        numberOfSlash++;
        if ( numberOfSlash>KMaxSlashAmount )
            {
            User::Leave( ENoSourceResource );
            }
        srcPathPtr = srcPathPtr.Left( position );
        position = srcPathPtr.LocateReverse( '/' );
        }

    TInt transferid = CUpnpHttpMessage::NewSessionIdL( );
    iTransferHandler->UploadFileL( transferid, dest, rscPath, contentTypePtr );

    TBuf8<KMaxIntegerLen> tid;
    tid.Num( transferid );
    aAction->SetArgumentL( (TDesC8&)KTransferID, tid );

    TPtrC8 pert = UpnpCdUtils::ResIdFromUriDesL( src );

    TInt objectId = rscBean->ObjectId( );
    CUpnpFileTransfer* transfer = CUpnpFileTransfer::NewL( transferid,
        objectId, CUpnpFileTransfer::EExport );
    transfer->SetTransferState(:: ETransferInProgress);

    iTransferController->iFileTransfers.Append( transfer );

    CUpnpFileTransferEvent* event = CUpnpFileTransferEvent::NewLC();
    event->SetProgressState( CUpnpFileTransferEvent::ECompleted );
    event->SetDirection( CUpnpFileTransferEvent::EOutgoing );
    event->SetFilePathL( rscPath);
    event->SetContentDirectoryObjectId( objectId );
    event->SetTransferId( transferid );
    CleanupStack::Pop( event );
    transfer->SetEvent(event);

    AddFileTransferToTransferIDsStateVariableL( transferid );
    CleanupStack::PopAndDestroy( contentType );
    CleanupStack::PopAndDestroy( srcPath );
    CleanupStack::PopAndDestroy( srcNoEsc );
    CleanupStack::PopAndDestroy( rscBean );
    CleanupStack::PopAndDestroy( srcBuf );

    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::StopTransferResourceL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::StopTransferResourceL(
    CUpnpAction*& aAction )
    {
    TInt transferId;
    TInt err =
            UpnpString::StringToInt(
                (TDesC8&) aAction->ArgumentValue( (TDesC8&)KTransferID ),
                &transferId );
    if ( KErrNone != err )
        {
        User::Leave( ENoFileTransfer );
        }
    TUpnpErrorCode
            upnpErr(iTransferController->StopTransferResourceL( transferId ) );
    TransferCompletedL( transferId, KErrCancel );
    return upnpErr;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetTransferProgressL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::GetTransferProgressL(
    CUpnpAction*& aAction )
    {
    TUint transferId;
    TInt length( KErrNone );
    TInt totalLength( KErrNone );
    // TInt lenght is max 15 digits, KMaxInfoName is 16
    TBuf8<KMaxInfoName> res;

    TInt err = UpnpCdUtils::StringToTUint(
        (TDesC8&)aAction->ArgumentValue( (TDesC8&)KTransferID ), &transferId );

    if ( KErrNone != err )
        {
        User::Leave( EInvalidArgs );
        }
    if ( transferId > KMaxTInt )
        {
        User::Leave( ENoFileTransfer );
        }
    TInt transferFound = iTransferController->Transfer( transferId );
    if ( KErrNotFound == transferFound )
        {
        User::Leave( ENoFileTransfer );
        }

    switch ( (iTransferController->iFileTransfers[ transferFound ])->TransferState( ) )
        {
        case:: ETransferInProgress:
            {
            aAction->SetArgumentL( (TDesC8&)KTransferStatus, KInProgress );
            break;
            }
        case EStopped:
            {
            aAction->SetArgumentL( (TDesC8&)KTransferStatus, KStopped );
            break;
            }
        case EError:
            {
            aAction->SetArgumentL( (TDesC8&)KTransferStatus, KError );
            break;
            }
        case ECompleted:
            {
            aAction->SetArgumentL( (TDesC8&)KTransferStatus, KCompleted );
            break;
            }
        default:
            {
            break;
            }
        }
    length = (iTransferController->iFileTransfers[ transferFound ])->TransferLength();
    totalLength = (iTransferController->iFileTransfers[ transferFound ])->TransferTotal();

    res.Num( length );
    aAction->SetArgumentL( (TDesC8&)KTransferLength, res );
    res.Num( totalLength );
    aAction->SetArgumentL( (TDesC8&)KTransferTotal, res );
    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DeleteResourceL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::DeleteResourceL( CUpnpAction*& aAction )
    {
    TPtrC8 uri8(aAction->ArgumentValue( KResourceURI( ) ));

    if ( !uri8.Length( ) )
        User::Leave( ENoSourceResource );

    // replace http characters
    HBufC8* uri = uri8.AllocLC( );
    TPtr8 uriPtr(uri->Des( ));

    // ip placeholder
    HBufC8* internalUri = InsertIpAndPortPlaceholderL( uriPtr );
    CleanupStack::PushL( internalUri );
    // delete resource
    RArray<TInt> contIds;
    CleanupClosePushL( contIds );
    iContentDirectoryDb->DeleteResourceL( *internalUri, contIds );

    // updateIDs
    for ( TInt i = 0; i < contIds.Count( ); i++ )
        {
        TBuf8<KMaxIntegerLen> num;
        num.Num( contIds[i] );
        iStateHandler->IncreaseContainerUpdateIdL( num );
        }

    // systemUpdateId
    iStateHandler->IncreaseSystemUpdateIdL( );

    // clean up
    CleanupStack::PopAndDestroy( &contIds );
    CleanupStack::PopAndDestroy( internalUri );
    CleanupStack::PopAndDestroy( uri );

    return EHttpOk;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AddFileTransferL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::AddFileTransferToTransferIDsStateVariableL(
    TInt aTransferID )
    {
    TBuf8<KMaxIntegerLen> tid;
    tid.Format( UpnpCD::KOneNumber, aTransferID );
    TPtrC8 tmp = StateVariableValue( KTransferIDs( ) );
    HBufC8* buf = UpnpString::AddValueToCsvL( tmp, tid );
    CleanupStack::PushL( buf );
    SetStateVariableL( KTransferIDs( ), *buf, EFalse );
    CleanupStack::PopAndDestroy( buf );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::RemoveFileTransferL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::RemoveFileTransferFromTransferIDsStateVariableL(
    TInt aTransferID )
    {
    TBuf8<KMaxIntegerLen> tid;
    tid.Format( UpnpCD::KOneNumber, aTransferID );
    TPtrC8 tmp = StateVariableValue( KTransferIDs( ) );
    HBufC8* buf = UpnpString::RemoveFromCsvLC( tmp, tid );
    SetStateVariableL( KTransferIDs( ), *buf, EFalse );
    CleanupStack::PopAndDestroy( buf );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ContainerUpdateId
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::ContainerUpdateId( const TDesC8& aContainerID )
    {
    return iStateHandler->ContainerUpdateId( aContainerID );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateObjectL
// -----------------------------------------------------------------------------
//
TUpnpErrorCode CUpnpContentDirectory::CreateObjectL( CUpnpAction*& aAction )
    {
    SetExecutedAction( ECreateObjectAction );

    HBufC8* objNoDes(aAction->ArgumentValue(KContainerID()).AllocLC( ) );
    TPtr8 objNoPtr(objNoDes->Des( ));
    objNoPtr.TrimAll( );

    TInt objNo = KErrNotFound; // container id
    TInt error( KErrGeneral );

    // any container support
    if ( !objNoPtr.Compare( KAnyContainerIndicator8 ) )
        {
        objNo = KAnyContainerId;
        }
    else
        {
        // checking whether containerID has proper decimal value
        error = UpnpCdUtils::StringToInteger( objNoPtr, &objNo );
        if ( error != KErrNone )
            {
            User::Leave( ENoContainer );
            }

        TUpnpErrorCode err =
                iContentDirectoryDb->CheckObjectRestrictionL( objNo );
        if ( err != EUpnpOk )
            {
            CleanupStack::PopAndDestroy( objNoDes );
            if ( err == ENoSuchObject )
                err = ENoContainer;
            if ( err == ERestrictedObject )
                err = ERestrictedParentObject;
            return err;
            }
        }
    CleanupStack::PopAndDestroy( objNoDes );

    // now we have found the unrestricted parent container
    // let's inspect the element that should be added
    // decode "elements" argument of the create action
    const TDesC8& elem = (TDesC8&)aAction->ArgumentValue( KElements( ) );

    // check that we've got correctly formed xml
    if ( elem.FindF( KXmlNsDc( ) ) == KErrNotFound )
        {
        User::Leave( EBadMetadata );
        }

    HBufC8* trimmed = UpnpString::TrimLC( elem, EFalse );

    HBufC8* trimmedlf8 = UpnpString::StringReplaceL( *trimmed, KLF8,
        KNullString8 );
    CleanupStack::PushL( trimmedlf8 );
    // parse decoded buffer
    RXmlEngDocument fragment;
    TRAPD( xmlerr, fragment = XmlFragmentL( *trimmedlf8 ) );
    if ( xmlerr )
        {
        RDebug::Print( _L( "CUpnpContentDirectory::CreateObjectL ERROR IN XML" ) );
        User::Leave( xmlerr );
        }
    CleanupClosePushL( fragment );

    // if container, check the number of nested levels
    TXmlEngElement container;
    UpnpDomInterface::GetElementL( fragment.DocumentElement( ), container,
        KContainer );
    if ( container.NotNull( ) && !iContentDirectoryDb->CanBeNestedL( objNo ) )
        {
        User::Leave( ECannotProcess );
        }

    RArray<TXmlEngAttr> importUris;
    CleanupClosePushL( importUris );
    RArray<TXmlEngElement> ress;
    CleanupClosePushL( ress );

    TBool isLocal = aAction->Local( );

    // to avoid errors in validation process
    UpnpCdUtils::SetObjectIdL( UpnpCdUtils::GetObjectElementL( fragment ),
        objNo ); // value does not matter - it will be changed later
    UpnpCdUtils::SetContainerIdL( UpnpCdUtils::GetObjectElementL( fragment ),
        objNo );

    //created new object shouldn't have refID value
    if ( UpnpCdUtils::HasRefIdL( fragment ) )
        {
        User::Leave( EParameterMismatch );
        }

    // validate the new element
    iElementdb->ValidateNewObjectL( fragment.DocumentElement( ), ETrue,
        isLocal );

    // now we have fragment, lets add this to CD metadata
    TInt id( KErrNotFound );
    TUpnpErrorCode err = AddToMetaDbL( fragment, objNo, &id, isLocal );

    CleanupStack::PopAndDestroy( &ress );
    CleanupStack::PopAndDestroy( &importUris );

    ConstructCreateResultsetL( aAction, fragment, id );

    CleanupStack::PopAndDestroy( &fragment );
    CleanupStack::PopAndDestroy( trimmedlf8 );
    CleanupStack::PopAndDestroy( trimmed );

    if ( err == EHttpOk )
        {
        iStateHandler->IncreaseSystemUpdateIdL( );
        iStateHandler->IncreaseContainerUpdateIdL( 
                             ( TDesC8& )aAction->ArgumentValue( KContainerID ) );

        }
    return err;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::HandleLocalResourcesL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::HandleLocalResourcesL( TXmlEngElement aRes,
    TInt aObjectId )
    {
    // contentUri, contentPath          
    TUriParser8 up;
    TPtrC8 resVal = aRes.Text( );
    if ( resVal.Length( ) )
        {
        TPtrC8 resValCandidatePtr(resVal);

        // There should be no slash at the end of URI, if so -> leave occurs
        if ( resValCandidatePtr.Length( ) > 0 )
            {
            if ( !resValCandidatePtr.Right(1).Compare( KSlash8( ) ) )
                {
                User::Leave( EBadMetadata );
                }
            }

        User::LeaveIfError( up.Parse( resValCandidatePtr ) );

        // get schema
        TPtrC8 scheme(up.Extract( EUriScheme ));

        // only local sharing
        if ( !scheme.Compare( UpnpHTTP::KSchemeFile8 ) )
            {
            HBufC* fn = UpnpString::ToUnicodeL( resValCandidatePtr );
            CleanupStack::PushL( fn );

            TInt extPosition = fn->Des().LocateReverse( '.' );
            TPtrC ext;
            if ( extPosition>0 )
                ext.Set( fn->Des().Mid( extPosition ) );
            else
                ext.Set( KNullString );

            HBufC8* contentUri = BuildContentUriL( ext, aObjectId );
            CleanupStack::PushL( contentUri );

            HBufC* contentPath = up.GetFileNameL( );
            CleanupStack::PushL( contentPath );

            // update res tag
            aRes.SetTextL( *contentUri );

            // add resource to the database
            CUpnpResourcesBean* resBn = CUpnpResourcesBean::NewLC( );
            resBn->SetId( UpnpCdUtils::ResIdFromUriL( *contentUri ) );
            resBn->SetPathL( *contentPath );
            resBn->SetIsReadonly( ETrue );
            resBn->SetIsThumbnail( EFalse );

            iContentDirectoryDb->AddResourceL( resBn, aObjectId );

            // clean up
            CleanupStack::PopAndDestroy( resBn );
            CleanupStack::PopAndDestroy( contentPath );
            CleanupStack::PopAndDestroy( contentUri );
            CleanupStack::PopAndDestroy( fn );
            }
        // else -> ignore
        }
    // else -> ignore
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ConstructCreateResultsetL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::ConstructCreateResultsetL( CUpnpAction*& aAction,
    RXmlEngDocument aDocument, TInt aId )
    {
    TBuf8<KMaxIntegerLen> num;
    num.Num( aId );

    aAction->SetArgumentL( KObjectID, num );
    TXmlEngElement elem = aDocument.DocumentElement( );

    HBufC8* buf = CUpnpXmlContentFilter::SerializeLC( aDocument, elem );

    TPtr8 bufPtr(buf->Des( ));
    InsertRealIpAndPortL( bufPtr );
    HBufC8* encoded = UpnpCdUtils::EncodeXmlStringL( bufPtr );
    CleanupStack::PushL( encoded );

    aAction->SetArgumentL( KResult, *encoded );

    CleanupStack::PopAndDestroy( encoded );
    CleanupStack::PopAndDestroy( buf );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::XmlFragmentL
// -----------------------------------------------------------------------------
//
RXmlEngDocument CUpnpContentDirectory::XmlFragmentL( const TDesC8 &aBuffer )
    {
    //Create a parser
    RXmlEngDOMParser parser;
    User::LeaveIfError( parser.Open( iDOMImpl ) );
    CleanupClosePushL( parser );
    // DOM document
    RXmlEngDocument docTree;

    if ( aBuffer.FindF( KXmlNsDc( ) ) == KErrNotFound )
        {
        HBufC8* withDidl = HBufC8::NewLC( KDidlTag().Length( ) + aBuffer.Length( ) +
                                          KDidlEnd().Length( ) );
        withDidl->Des().Append( KDidlTag( ) );
        withDidl->Des().Append( aBuffer );
        withDidl->Des().Append( KDidlEnd( ) );

        docTree = parser.ParseL( *withDidl );
        CleanupStack::PopAndDestroy( withDidl );
        }
    else
        {
        docTree = parser.ParseL( aBuffer );
        }
    CleanupStack::PopAndDestroy( &parser );
    return docTree;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetMimeTypeLC
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::GetMimeTypeLC( const TDesC8& aFilename )
    {
    HBufC16* filename16 = UpnpString::ToUnicodeL( aFilename );
    CleanupStack::PushL( filename16 );
    HBufC8* mimetype = UpnpFileUtil::GetMimeTypeForFileL( *filename16 );
    if ( !mimetype )
        {
        mimetype = KNullString8().AllocL( );
        }
    CleanupStack::PopAndDestroy( filename16 );
    CleanupStack::PushL( mimetype );
    return mimetype;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ChangeFileNameWithExtensionL
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::ChangeFileNameWithExtensionL(
    TDesC8& aFilePath, const TDesC8& aMimeType )
    {

    HBufC8* temp = NULL;
    TInt position = aFilePath.LocateReverse( '.' );
    if ( position != KErrNotFound )
        {
        return temp;
        }
    if ( aMimeType == KNullDesC8 )
        {
        return temp;
        }

    HBufC8* ext = iMimeToExtMap->GetExtensionL( aMimeType );
    if ( ext == NULL )
        {
        return temp;
        }
    CleanupStack::PushL( ext );
    HBufC8* newFilename = HBufC8::NewLC( ext->Length( ) + 1
            + aFilePath.Length( ) );
    TPtr8 fileNamePtr(newFilename->Des( ) );
    fileNamePtr.Append( aFilePath );
    //fileNamePtr.Append( KDot8());
    fileNamePtr.Append( *ext );

    HBufC* oldFilename16 = HBufC::NewLC( aFilePath.Length( ) );
    TPtr oldFilename16Ptr(oldFilename16->Des( ));
    oldFilename16Ptr.Copy( aFilePath );

    HBufC* newFilename16 = HBufC::NewLC( newFilename->Length( ) );
    TPtr newFilename16Ptr(newFilename16->Des( ));
    newFilename16Ptr.Copy( *newFilename );

    TBool exists = BaflUtils::FileExists( iFs, *newFilename16 );
    if ( exists )
        {
        TInt error( KErrNone );
        TInt count( 0);
        _LIT( KUnderline, "_" );

        CleanupStack::PopAndDestroy( newFilename16 );
        newFilename16 = NULL;

        HBufC16* ext16 = HBufC16::NewLC( ext->Length( ) );
        ext16->Des().Copy( *ext );

        TBuf<KMaxIntegerLen> value;
        newFilename16 = HBufC16::NewLC( aFilePath.Length( ) + KMaxIntegerLen
                + ext16->Length( ) + KUnderline().Length( ) + KDot().Length( ) );
        for ( ;; )
            {
            // name_xxxxx.ext
            value.Num( count );

            newFilename16->Des().Copy( aFilePath );
            newFilename16->Des().Append( KUnderline );
            newFilename16->Des().Append( value );
            //adding dot is not not needed anymore
            newFilename16->Des().Append( *ext16 );

            RFile file;
            error = file.Open( iFs, *newFilename16, EFileShareExclusive );
            file.Close( );

            if ( error == KErrNotFound )
                {
                break;
                }
            else
                {
                count++;
                }
            }
        CleanupStack::Pop( newFilename16 );
        CleanupStack::PopAndDestroy( ext16 );
        CleanupStack::PushL( newFilename16 );
        }

    TInt result = iFs.Rename( *oldFilename16, *newFilename16 );
    if ( result == KErrNone )
        {
        temp = HBufC8::NewL( newFilename16->Length( ) );
        temp->Des().Copy( *newFilename16 );

        }
    CleanupStack::PopAndDestroy( newFilename16 );
    CleanupStack::PopAndDestroy( oldFilename16 );
    CleanupStack::PopAndDestroy( newFilename );
    CleanupStack::PopAndDestroy( ext );

    return temp;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateResTagWithDBRecoveyrL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::CreateResTagInternalWithDBRecoveryL(
    TInt aSessionId, TDesC8& aFilePath, HBufC8* aImportUri,
    TBool aOnlyThumbnail )
    {
    TInt result = 0;
    TRAPD( err, result = CreateResTagInternalL( aSessionId, aFilePath,
        aImportUri, aOnlyThumbnail ) );
    if ( err )
        {
        if ( DataBaseHasBeenRecoveredL( err ) )
            {
            TRAP( err, iContentDirectoryDb->CheckDatabaseL( ) );
            if ( err == KErrCorrupt )
                {
                err = iContentDirectoryDb->RecreateDatabaseFile( );
                User::LeaveIfError( err );
                }
            TRAP( err, result = CreateResTagInternalL( aSessionId, aFilePath,
                aImportUri, aOnlyThumbnail ) );
            if ( err == KErrCorrupt )
                {
                err = iContentDirectoryDb->RecreateDatabaseFile( );
                }
            }
        User::LeaveIfError( err );
        }
    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateResTagInternalL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::CreateResTagInternalL( TInt aSessionId,
    TDesC8& aFilePath, HBufC8* aImportUri, TBool aOnlyThumbnail )
    {
    TInt ret = KErrGeneral;
    HBufC8* number = UpnpCdUtils::RandomizeL( KRandomMax );
    CleanupStack::PushL( number );
    HBufC8* number2 = UpnpCdUtils::RandomizeL( KRandomMax );
    CleanupStack::PushL( number2 );
    HBufC8* importRandomize = HBufC8::NewLC( aImportUri->Des().Length( )+number->Des().Length( ) );
    importRandomize->Des().Copy( *aImportUri );
    importRandomize->Des().Replace( importRandomize->Length( ) - 4, 4, *number2 );
    importRandomize->Des().Append( *number );

    RXmlEngDocument obj;
    TInt objId = KErrNotFound;
    iContentDirectoryDb->GetObjectByAttrL( obj, &objId, KImportUri8,
        *aImportUri );
    CleanupClosePushL( obj );

    if ( !obj.NotNull( ) )
        {
        CleanupStack::PopAndDestroy( &obj );
        CleanupStack::PopAndDestroy( importRandomize );
        CleanupStack::PopAndDestroy( number2 );
        CleanupStack::PopAndDestroy( number );
        return ret;
        }

    HBufC8* mimeType = GetMimeTypeLC( aFilePath );
    // CheckFileName 
    HBufC8* newName = ChangeFileNameWithExtensionL( aFilePath, *mimeType );
    if ( !newName )
        {
        // renaming file failed, set the old  name
        newName = HBufC8::NewL( aFilePath.Length( ) );
        newName->Des().Copy( aFilePath );
        }
    CleanupStack::PushL( newName );

    TSize objectSize( 0, 0);

    //GetFileName
    HBufC16* filename16 = UpnpString::ToUnicodeL( *newName );
    CleanupStack::PushL( filename16 );

    if ( obj.NotNull( ) && !aOnlyThumbnail )
        {
        // if there is already a file related to this importUri delete it
        DeleteOldResourcesL( obj, *aImportUri, *filename16 );

        // set new contentUri
        TXmlEngElement objEl = obj.DocumentElement( );

        TPtrC8 fileNamePtr =
                newName->Mid( newName->LocateReverse( '\\' ) + 1 );

        TInt extPosition = fileNamePtr.LocateReverse( '.' );
        TPtrC8 ext;
        if ( extPosition>0 )
            ext.Set( fileNamePtr.Mid( extPosition ) );
        else
            ext.Set( KNullString8 );
        HBufC8* contUri = HBufC8::NewLC( importRandomize->Length( ) + KSlash().Length( ) +
                                         KMaxLongIntegerLen + ext.Length( ) );
        TPtr8 contUriPtr(contUri->Des( ));
        contUriPtr.Copy( *importRandomize );
        contUriPtr.Append( KSlash );

        TBuf8<KMaxLongIntegerLen> num;
        num.Num( objId );
        contUriPtr.Append( num );
        contUriPtr.Append( ext );

        TXmlEngElement resEl;
        UpnpDomInterface::GetDirectoryElementL( objEl, resEl, KRes( ),
            KImportUri8( ), aImportUri->Des( ) );
        resEl.SetTextL( contUriPtr );

        CleanupStack::PopAndDestroy( contUri );

        // set res@size  
        TXmlEngAttr size = resEl.AttributeNodeL( KSize( ) );
        if ( size.NotNull( ) )
            {
            SetResSizeL( size, *filename16 );
            }

        // set res@protocolInfo
        HBufC8* protocolInfo =
                ProtocolInfoFromMimeL( mimeType->Des( ), resEl );
        CleanupStack::PushL( protocolInfo );

        TXmlEngAttr protInf = resEl.AttributeNodeL( KprotocolInfo( ) );
        protInf.SetValueL( *protocolInfo );

        CleanupStack::PopAndDestroy( protocolInfo );

        CheckItemTypeForObjectL( obj, *mimeType );

        RemoveFileTransferFromTransferIDsStateVariableL( aSessionId );

        // update database
        iElementdb->ValidateNewObjectL( obj.DocumentElement( ), EFalse );
        iContentDirectoryDb->UpdateObjectL( objId, obj );

        // add resource
        CUpnpResourcesBean* resBn = CUpnpResourcesBean::NewLC( );
        resBn->SetId( UpnpCdUtils::ResIdFromUriL( *importRandomize ) );
        resBn->SetPathL( *newName );
        resBn->SetIsReadonly( EFalse );
        resBn->SetIsThumbnail( EFalse );
        iContentDirectoryDb->AddResourceL( resBn, objId );
        // clean up
        CleanupStack::PopAndDestroy( resBn );
        ret = KErrNone;
        }

    //send event to Media server      


    CUpnpFileTransferEvent* event =
            iTransferController->TransferL( aSessionId );

    if ( event )
        {
        event->SetFilePathL( *filename16 );
        //CleanupStack::Pop( event);
        //iEventObserver->FileTransferEvent( event );
        }

    // create thumbnail
    CreateThumbnailL( *filename16, objId );

    // clean up
    CleanupStack::PopAndDestroy( filename16 );
    CleanupStack::PopAndDestroy( newName );
    CleanupStack::PopAndDestroy( mimeType );
    CleanupStack::PopAndDestroy( &obj );
    CleanupStack::PopAndDestroy( importRandomize );
    CleanupStack::PopAndDestroy( number2 );
    CleanupStack::PopAndDestroy( number );

    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SetResSizeL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::SetResSizeL( TXmlEngAttr aSize,
    const TDesC& aFilePath )
    {
    // get file size
    RFile file;
    CleanupClosePushL( file );
    User::LeaveIfError( file.Open( iFs, aFilePath, EFileRead|EFileShareAny ) );
    TInt size;
    User::LeaveIfError( file.Size( size ) );

    // set size
    TBuf8<KMaxLongIntegerLen> num;
    num.Num( size );
    aSize.SetValueL( num );

    CleanupStack::PopAndDestroy( &file );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DeleteOldResourcesL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::DeleteOldResourcesL( RXmlEngDocument& aObj,
    const TDesC8& aImportUri, const TDesC& aNewFile )
    {
    // for main res tag delete only corresponding record in the resources table
    TXmlEngElement el;
    UpnpDomInterface::GetDirectoryElementL( aObj.DocumentElement( ), el,
        KImportUri8( ), aImportUri );
    if ( el.NotNull( ) ) //  should always be true
        {
        TPtrC8 resVal(UpnpDomInterface::GetElementValueL( el ));
        if ( resVal.Length( ) )
            {
            TInt64 resId = UpnpCdUtils::ResIdFromUriL( resVal ) ;
            // check src existence -----------------------------
            CUpnpResourcesBean* rscBean = NULL;
            rscBean = iContentDirectoryDb->GetResourceL( resId );
            TBool deletefile = ETrue;
            //checking if a new file is the same as the old one
            //if so, it means the old one was by chance deleted from the file system
            if ( rscBean )
                {
                TPtrC rscPath(rscBean->Path( ) );
                if ( !rscPath.Compare( aNewFile ) )
                    deletefile = EFalse;
                delete rscBean;
                }
            iContentDirectoryDb->DeleteResourceByResIdL( resId, deletefile );
            }

        }

    // destroy all other res tags   
    RArray<TXmlEngElement> elms;
    CleanupClosePushL( elms );
    UpnpDomInterface::GetElementListL( aObj.DocumentElement( ), elms, KRes );
    // for each element
    for ( TInt i=0; i < elms.Count( ); i++ )
        {
        TXmlEngAttr impUri(elms[i].AttributeNodeL( KImportUri( ) ) );
        if ( impUri.IsNull( ) && !el.IsSameNode( elms[i] ) )
            {
            TPtrC8 resVal(UpnpDomInterface::GetElementValueL( elms[i] ));
            if ( resVal.Length( ) )
                {
                iContentDirectoryDb->DeleteResourceByResIdL( 
                                                        UpnpCdUtils::ResIdFromUriL( resVal ) );
                }
            elms[i].Remove( );
            }
        }
    CleanupStack::PopAndDestroy( &elms );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateThumbnailCreatorL
// -----------------------------------------------------------------------------
//
CUpnpThumbnailCreator* CUpnpContentDirectory::CreateThumbnailCreatorL(
    TInt aObjectId )
    {
    CUpnpThumbnailCreator* thumbCreator = NULL;

    if ( iBitmapServerConnection == KErrNone )
        {
        //check if from the file THUMB can be created. 
        //create thumbnail 
        // in thumbnail save the information. 
        thumbCreator = CUpnpThumbnailCreator::NewLC( this );
        iThumbnailCreators.AppendL( thumbCreator );
        TInt index = iThumbnailCreators.Find( thumbCreator );
        User::LeaveIfError( index );
        iThObjectIds.Insert( aObjectId, index );
        CleanupStack::Pop( thumbCreator );
        }
    return thumbCreator;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::RemoveThCreatorAndObjectIdLD
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::RemoveThCreatorAndObjectIdLD(
    CUpnpThumbnailCreator* aThCreator )
    {
    TInt index = iThumbnailCreators.Find( aThCreator );
    if ( index == KErrNotFound )
        {
        RDebug::Print( _L( "There is no corresponding thCreator in list. Error situation." ) );
        delete aThCreator;
        return;
        }
    else
        {
        iThumbnailCreators.Remove( index );
        }
    if ( index < iThObjectIds.Count( ) )
        {
        iThObjectIds.Remove( index );
        }
    delete aThCreator;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetObjectIdFromThCreator
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::GetObjectIdFromThCreator(
    CUpnpThumbnailCreator* aThCreator )
    {
    TInt result = KErrNotFound;
    TInt index = iThumbnailCreators.Find( aThCreator );
    RDebug::Print( _L( "Whole number of objects. %d" ) ,
        iThObjectIds.Count( ) );
    if ( index < iThObjectIds.Count( ) )
        {
        result = iThObjectIds[index];
        }
    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NotifyThumbnailResultL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::NotifyThumbnailResultL(
    CUpnpThumbnailCreator* aThCreator, TInt aResult )
    {
    TInt result = aResult;
    RDebug::Print( _L( "Thumbnail has been created with result: %d" ),
        aResult );
    if ( aResult == KErrNone )
        {
        RXmlEngDocument obj;
        CleanupClosePushL( obj );
        TInt objectId = GetObjectIdFromThCreator( aThCreator );
        TInt err =
                iContentDirectoryDb->GetObjectL( objectId, obj, KAsterisk8 );
        if ( err == EUpnpOk )
            {
            // get item element
            TXmlEngElement objElement;
            UpnpDomInterface::GetElementL( obj.DocumentElement( ),
                objElement, KItem );

            // add new res tag
            TXmlEngElement thumbRes(objElement.AddNewElementL( KRes( ) ) );

            // add protocolInfo
            HBufC8* protocolInfo = ProtocolInfoFromMimeL( KThumbMimeType( ),
                JPEG_TN, ETrue, ETrue );
            CleanupStack::PushL( protocolInfo );
            thumbRes.AddNewAttributeL( KprotocolInfo( ), *protocolInfo );
            CleanupStack::PopAndDestroy( protocolInfo );

            // add contentUri
            HBufC8* contUri = BuildContentUriL( aThCreator->GetFileExt( ),
                objectId );
            CleanupStack::PushL( contUri );
            thumbRes.SetTextL( *contUri );

            // add new resource
            CUpnpResourcesBean* resBean = CUpnpResourcesBean::NewLC( );
            resBean->SetId( UpnpCdUtils::ResIdFromUriL( *contUri ) );
            resBean->SetPathL( aThCreator->GetPath( ) );
            resBean->SetIsReadonly( EFalse );
            resBean->SetIsThumbnail( ETrue );
            iContentDirectoryDb->AddResourceL( resBean, objectId );

            // update
            iElementdb->ValidateNewObjectL( obj.DocumentElement( ), EFalse );
            iContentDirectoryDb->UpdateObjectL( objectId, obj );
            RemoveThCreatorAndObjectIdLD( aThCreator );

            // clean up
            CleanupStack::PopAndDestroy( resBean );
            CleanupStack::PopAndDestroy( contUri );
            }
        else
            {
            // delete thumbnail file if exists
            iFs.Delete( aThCreator->GetPath( ) ); // ignore errors
            // remove thCreator and objectID from list 
            RemoveThCreatorAndObjectIdLD( aThCreator );
            result = err;
            }
        CleanupStack::PopAndDestroy( &obj );
        }
    else
        {
        // delete thumbnail file if exists
        iFs.Delete( aThCreator->GetPath( ) ); // ignore errors
        // remove thCreator and objectID from list 
        RemoveThCreatorAndObjectIdLD( aThCreator );
        }

    // notify
    if ( iThmbObs )
        {
        iThmbObs->NotifyThumbnailResultL( 0, result );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateResTagL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::CreateResTagL( TInt aSessionId,
    TDesC8& aFilePath, TInt aImportNumber, TBool aOnlyThumbnail )
    {
    HBufC8* importUri = UpnpCdUtils::BuildImportUriLC( aImportNumber );
    TInt ret = CreateResTagInternalWithDBRecoveryL( aSessionId, aFilePath,
        importUri, aOnlyThumbnail );
    CleanupStack::PopAndDestroy( importUri );
    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ProtocolInfoFromMimeLC
// -----------------------------------------------------------------------------
//
CUpnpDlnaProtocolInfo* CUpnpContentDirectory::CreateProtocolInfoFromMimeL(
    const TDesC8& aMimeType, TInt aAddInfo )
    {
    CUpnpProtocolInfoLocal* protInfo = CUpnpProtocolInfoLocal::NewL(
        aMimeType, aAddInfo );
    CleanupStack::PushL( protInfo );
    protInfo->SetThirdFieldL( aMimeType );
    CleanupStack::Pop( protInfo );
    return protInfo;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ProtocolInfoFromMimeL
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::ProtocolInfoFromMimeL(
    const TDesC8& aMimeType, TInt aAddInfo, TBool aOpRangeParam,
    TBool aCiParam /*= EFalse*/)
    {
    CUpnpDlnaProtocolInfo* protInfo = CreateProtocolInfoFromMimeL( aMimeType,
        aAddInfo );
    if ( aCiParam )
        {
        protInfo->SetCiParameter( ETrue );
        }
    if ( aOpRangeParam )
        {
        protInfo->SetOpParameterL( B_VAL, ETrue );
        }

    CleanupStack::PushL( protInfo );
    TPtrC8 protocolInfo = protInfo->ProtocolInfoL( );
    HBufC8* protocolInfoDes = protocolInfo.Alloc( );
    CleanupStack::PopAndDestroy( protInfo );
    return protocolInfoDes;
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ProtocolInfoFromMimeL
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::ProtocolInfoFromMimeL(
    const TDesC8& aMimeType, TXmlEngElement& aResEl )
    {
    HBufC8* result = NULL;
    const TDesC8& value = UpnpDomInterface::GetAttrValueL( aResEl,
        KprotocolInfo );
    if ( aMimeType.Length( ) > 0 )
        {
        if ( value.Length( ) )
            {
            CUpnpDlnaProtocolInfo* protocolInfo =
                    CUpnpDlnaProtocolInfo::NewL( (TDesC8&) value );
            CleanupStack::PushL( protocolInfo );
            TPtrC8 third = protocolInfo->ThirdField( );
            if ( !(aMimeType == third ) )
                {
                protocolInfo->SetThirdFieldL( (TDesC8&)aMimeType );
                protocolInfo->SetFourthFieldL( KAsterisk8( ) );
                }
            TPtrC8 protInfo = protocolInfo->ProtocolInfoL( );
            result = protInfo.Alloc( );
            CleanupStack::PopAndDestroy( protocolInfo );
            }
        }
    else
        {
        result = value.AllocL( );
        }
    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetFileNameL
// -----------------------------------------------------------------------------
//
HBufC* CUpnpContentDirectory::GetFileNameL( TInt aObjId )
    {
    TInt objId = aObjId;
    HBufC* result = NULL;
    RXmlEngDocument objDidl;
    iContentDirectoryDb->GetObjectL( objId, objDidl, KAsterisk8( ) );
    CleanupClosePushL( objDidl );
    TXmlEngElement obj = objDidl.DocumentElement().FirstChild().AsElement( );
    if ( obj.IsNull( ) )
        {
        CleanupStack::PopAndDestroy( &objDidl );
        return NULL;
        }

    // file name
    TXmlEngElement objTitle;
    UpnpDomInterface::GetElementL( obj, objTitle, KObjTiltleColName8( ) );
    if ( objTitle.IsNull( ) )
        {
        CleanupStack::PopAndDestroy( &objDidl );
        return NULL;
        }

    // mime type
    RArray<TXmlEngElement> reses;
    CleanupClosePushL( reses );
    UpnpDomInterface::GetElementListL( obj, reses, KRes );
    HBufC8* mimeType = NULL;
    for ( TInt i = 0; i < reses.Count( ); i++ )
        { // should be only one importUri
        TXmlEngAttr impUri;
        impUri = reses[i].AttributeNodeL( KImportUri );
        if ( impUri.NotNull( ) )
            {
            TXmlEngAttr prInfoAttr = reses[i].AttributeNodeL( KprotocolInfo );
            CUpnpDlnaProtocolInfo* prInfo =
                    CUpnpDlnaProtocolInfo::NewL( prInfoAttr.Value( ) );
            CleanupStack::PushL( prInfo );
            mimeType = prInfo->ThirdField().AllocL( );
            CleanupStack::PopAndDestroy( prInfo );
            break;
            }
        }
    CleanupStack::PopAndDestroy( &reses );

    TPtrC ext;
    if ( mimeType )
        {
        TPtrC8 mimeTypeCut( *mimeType);
        TInt position = mimeType->Des().Find( KSemicolon8 );
        if ( position != KErrNotFound )
            {
            mimeTypeCut.Set( mimeType->Des().Left( position ) );
            }

        const HBufC* tmp = iMimeToExtMap->Get( mimeTypeCut );
        if ( tmp )
            {
            ext.Set( tmp->Ptr( ), tmp->Length( ) ); // do not delete
            }
        delete mimeType;
        }

    result = HBufC::NewLC( objTitle.Value().Length( ) + ext.Length( ) );
    TPtr resPtr(result->Des( ) );
    HBufC* title = UpnpCdUtils::Des8ToDesLC( objTitle.Value( ) );

    resPtr.Copy( *title );

    TInt wholeNameLength = title->Des().LocateReverse( '.' );
    TInt extenLength = title->Length( )-wholeNameLength;
    TPtrC exten;
    if ( extenLength )
        {
        exten.Set( title->Right( extenLength ) );
        }

    if ( ext.CompareF( exten ) != 0 )
        {
        resPtr.Append( ext );
        }

    // forbidden chars
    UpnpCdUtils::ValidateFilePath( resPtr );

    HBufC* basePath = HBufC::NewL( iDownloadDir->Des().Length( ) + result->Des().Length( ) );
    basePath -> Des().Append( iDownloadDir->Des( ) );
    basePath -> Des().Append( result->Des( ) );

    CleanupStack::PopAndDestroy( title );
    CleanupStack::PopAndDestroy( result );
    CleanupStack::PopAndDestroy( &objDidl );

    if ( BaflUtils::FileExists( iFs, *basePath ) )
        {
        CleanupStack::PushL( basePath );
        HBufC* fileName = CreateFileNameL( basePath->Des( ) );
        CleanupStack::PopAndDestroy( basePath );
        return fileName;
        }

    return basePath;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetFileNameWithoutPathL
// -----------------------------------------------------------------------------
//
HBufC* CUpnpContentDirectory::GetFileNameWithoutPathL( TInt aObjId )
    {
    TInt objId = aObjId;
    HBufC* result = NULL;
    RXmlEngDocument objDidl;
    iContentDirectoryDb->GetObjectL( objId, objDidl, KAsterisk8( ) );
    CleanupClosePushL( objDidl );
    TXmlEngElement obj = objDidl.DocumentElement().FirstChild().AsElement( );
    if ( obj.IsNull( ) )
        {
        CleanupStack::PopAndDestroy( &objDidl );
        return NULL;
        }

    // file name
    TXmlEngElement objTitle;
    UpnpDomInterface::GetElementL( obj, objTitle, KObjTiltleColName8( ) );
    if ( objTitle.IsNull( ) )
        {
        CleanupStack::PopAndDestroy( &objDidl );
        return NULL;
        }

    // mime type
    RArray<TXmlEngElement> reses;
    CleanupClosePushL( reses );
    UpnpDomInterface::GetElementListL( obj, reses, KRes );
    HBufC8* mimeType = NULL;
    for ( TInt i = 0; i < reses.Count( ); i++ )
        { // should be only one importUri
        TXmlEngAttr impUri;
        impUri = reses[i].AttributeNodeL( KImportUri );
        if ( impUri.NotNull( ) )
            {
            TXmlEngAttr prInfoAttr = reses[i].AttributeNodeL( KprotocolInfo );
            CUpnpDlnaProtocolInfo* prInfo =
                    CUpnpDlnaProtocolInfo::NewL( prInfoAttr.Value( ) );
            CleanupStack::PushL( prInfo );
            mimeType = prInfo->ThirdField().AllocL( );
            CleanupStack::PopAndDestroy( prInfo );
            break;
            }
        }
    CleanupStack::PopAndDestroy( &reses );

    TPtrC ext;
    if ( mimeType )
        {
        TPtrC8 mimeTypeCut(*mimeType);
        TInt position = mimeType->Des().Find( KSemicolon8 );
        if ( position != KErrNotFound )
            {
            mimeTypeCut.Set( mimeType->Des().Left( position ) );
            }

        const HBufC* tmp = iMimeToExtMap->Get( mimeTypeCut );
        if ( tmp )
            {
            ext.Set( tmp->Ptr( ), tmp->Length( ) ); // do not delete
            }
        delete mimeType;
        }

    result = HBufC::NewLC( objTitle.Value().Length( ) + ext.Length( ) );
    TPtr resPtr(result->Des( ));
    HBufC* title = UpnpCdUtils::Des8ToDesLC( objTitle.Value( ) );

    resPtr.Copy( *title );

    TInt wholeNameLength = title->Des().LocateReverse( '.' );
    TInt extenLength = title->Length( )-wholeNameLength;
    TPtrC exten;
    if ( extenLength )
        {
        exten.Set( title->Right( extenLength ) );
        }

    if ( ext.CompareF( exten )!=0 )
        resPtr.Append( ext );

    // forbidden chars
    UpnpCdUtils::ValidateFilePath( resPtr );

    // clean up
    CleanupStack::PopAndDestroy( title );
    CleanupStack::Pop( result );
    CleanupStack::PopAndDestroy( &objDidl );
    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateFileNameL
// -----------------------------------------------------------------------------
//
HBufC* CUpnpContentDirectory::CreateFileNameL( const TDesC16& aFileName )
    {
    const TInt KMaxSameFileNames = 10000;
    TParse parseFilename;
    parseFilename.Set( aFileName, NULL, NULL );

    // orginal file + underscore + number 
    HBufC* name = HBufC::NewLC( aFileName.Length( ) + KMaxIntegerLen );
    TPtr namePtr(name->Des( ) );

    for ( TInt count = 1; count < KMaxSameFileNames; count++ )
        {
        TBuf<KMaxIntegerLen> value;
        value.Num( count );

        namePtr.Append( parseFilename.DriveAndPath( ) );
        namePtr.Append( parseFilename.Name( ) );
        namePtr.Append( KUndersc( ) );
        namePtr.Append( value );
        namePtr.Append( parseFilename.Ext( ) );

        if ( !BaflUtils::FileExists( iFs, namePtr ) )
            {
            break;
            }
        namePtr.Zero( );
        }

    CleanupStack::Pop( name );
    return name;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetTitleForUriL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::GetTitleForUriL( TInt aObjectId, TPtr& aValue )
    {
    HBufC* result = GetFileNameWithoutPathL( aObjectId );
    TPtr des = result->Des( );
    UpnpCdUtils::ValidateFilePath( des );
    if ( result == NULL )
        {
        return;
        }
    aValue.Copy( *result );
    delete result;
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CheckImportUriL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::CheckImportUriL( const TDesC8& aImportUri )
    {
    TInt objId = KErrNotFound;

    // http characters  
    HBufC8* dest8 = HBufC8::NewLC( aImportUri.Length( ) );
    TPtr8 dest8Ptr(dest8->Des( ));
    dest8Ptr.Copy( aImportUri );

    UpnpString::ReplaceHttpCharacters( dest8Ptr );

    // ip and port placeholder
    HBufC8* dest = InsertIpAndPortPlaceholderL( dest8Ptr );
    CleanupStack::PushL( dest );

    objId = iContentDirectoryDb->GetObjIdByAttrLikeL( KImportUri8, *dest );

    // clean up
    CleanupStack::PopAndDestroy( dest );
    CleanupStack::PopAndDestroy( dest8 );

    return objId;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateAddressValueLC
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::CreateAddressValueLC()
    {

    HBufC8* result = NULL;

    CBufFlat* resBuf = CBufFlat::NewL( KMaxName );
    CleanupStack::PushL( resBuf );

    UpnpString::AppendStringL( *resBuf, KHttpTag( ) );
    UpnpString::AppendStringL( *resBuf, KIpPortPlaceholder8( ) );

    result = HBufC8::NewL( resBuf->Size( ) );
    TPtr8 resultPtr(result->Des( ));
    resultPtr.Copy( resBuf->Ptr( 0 ) );
    CleanupStack::PopAndDestroy( resBuf );
    CleanupStack::PushL( result );
    return result;
    // path 
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetImportUriLC
// -----------------------------------------------------------------------------
//
HBufC8* CUpnpContentDirectory::GetImportUriLC( CUpnpHttpMessage* aMessage )
    {
    TPtrC8 path = aMessage->SenderPathFromHeader( );
    if ( path.Find( KHttpTag ) == KErrNotFound )
        {
        HBufC8* serverAddr = CreateAddressValueLC( );
        HBufC8* result =
                HBufC8::NewL( serverAddr->Length( ) + path.Length( ) );
        TPtr8 resultPtr(result->Des( ) );
        resultPtr.Append( *serverAddr );
        resultPtr.Append( path );
        CleanupStack::PopAndDestroy( serverAddr );
        CleanupStack::PushL( result );
        return result;
        }
    else
        {
        HBufC8* pathHBuf = InsertIpAndPortPlaceholderL( path );
        CleanupStack::PushL( pathHBuf );
        return pathHBuf;
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetProtocolInfoByImportUriL
// -----------------------------------------------------------------------------
//
CUpnpDlnaProtocolInfo* CUpnpContentDirectory::GetProtocolInfoByImportUriL(
    const TDesC8& aImportUri )
    {
    TPtrC8 importUri;
    importUri.Set( UpdateImportUriL( aImportUri ) );

    CUpnpDlnaProtocolInfo* protocolInfo = NULL;
    // check restriction - cannot export to the restricted object
    TInt objId = iContentDirectoryDb->
    GetObjIdByAttrLikeL( KImportUri8, importUri );

    if ( objId < 0 )
        {
        User::Leave( ENoSuchObject );
        }

    if ( iContentDirectoryDb->
    CheckObjectRestrictionL( objId ) == ERestrictedObject )
        {
        User::Leave( ERestrictedObject );
        }
    // parent restricions
    if ( iContentDirectoryDb->CheckParentRestrictionL( objId ) != EUpnpOk )
        {
        User::Leave( ERestrictedParentObject );
        }
    else
        {
        HBufC8* protInfoBuf = iContentDirectoryDb->
        GetProtocolInfoByImportUriL( importUri );

        if ( protInfoBuf )
            {
            CleanupStack::PushL( protInfoBuf );
            protocolInfo = CUpnpDlnaProtocolInfo::NewL( protInfoBuf->Des( ) );
            CleanupStack::PopAndDestroy( protInfoBuf );
            }
        }
    return protocolInfo;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::UpdateImportUriL
// -----------------------------------------------------------------------------
//
TPtrC8 CUpnpContentDirectory::UpdateImportUriL( const TDesC8& aImportUri )
    {
    HBufC8* portAndIp =  GetIpAndPortDes8L();
    CleanupStack::PushL( portAndIp );

    TPtrC8 importUri;
    importUri.Set( aImportUri );
    
    TInt index = aImportUri.Find( *portAndIp );
    if ( index > 0 )
        {
        importUri.Set( aImportUri.Mid( index + portAndIp->Des().Length() ) );
        }
                
    CleanupStack::PopAndDestroy( portAndIp );
    
    //--- replaceing e.g '/0000000004' -> '0000000004'   
    index = importUri.Find( KSlash8() );
	// importUri must begins with '/'
    if ( !index )
        {
        importUri.Set( importUri.Mid( index + 1 ) );        
        }
     else
        {
        User::Leave( ENoSuchObject );         
        }   
    //----------------------------------------
    
    if ( importUri.Length() < KMaxIntegerLen )
        {
        User::Leave(ENoSuchObject);        
        }
    
    // Check if all signs in uri are digits
    TLex8 lex( importUri );
    for( TInt i( 0 ); i < importUri.Length(); i++ )
        {
        if ( !( lex.Get() ).IsDigit() ) 
            {
            User::Leave( ENoSuchObject ); 
            }
        }    
    return importUri; 
    }
    
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetProtocolInfoL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::GetProtocolInfoL( const TDesC8& aContentUri,
    CUpnpDlnaProtocolInfo*& aProtocolInfo )
    {
    HBufC8 *buf = InsertIpAndPortPlaceholderL( aContentUri );
    CleanupStack::PushL( buf );
    TInt err = iContentDirectoryDb->GetProtocolInfoL( buf->Des( ),
        aProtocolInfo );
    CleanupStack::PopAndDestroy( buf );
    return err;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::FindSharedFolderL
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::FindSharedFolderL( const TDesC& aUrlPath,
    const TDesC& aFileName, HBufC*& aSystemPath )
    {
    TInt ret = KErrNotFound;
    aSystemPath = NULL;
    if ( aUrlPath.Length( ) )
        {
        // validate the path string
        if ( IsValidUrlPath( aUrlPath ) )
            {
            // get resource id
            TLex lexer(aUrlPath);
            TInt64 resId;
            if ( !lexer.Val( resId ) )
                {
                // get resource
                CUpnpResourcesBean* resBn = iContentDirectoryDb->
                GetResourceL( resId );
                if ( resBn )
                    {
                    CleanupStack::PushL( resBn );
                    aSystemPath = resBn->Path().AllocL( );
                    TInt objectId = resBn->ObjectId( );
                    CleanupStack::PopAndDestroy( resBn );

                    // make sure that systam path points to the wanted file
                    TParse fp;
                    fp.Set( *aSystemPath, 0, 0 );
                    HBufC* tmp = aFileName.AllocLC( );
                    TPtr tmpPtr(tmp->Des( ));
                    UpnpString::ReplaceHttpCharactersL( tmpPtr );
                    TPtrC ext = fp.Ext( );
                    HBufC* file = HBufC::NewLC( KMaxIntegerLen
                            + ext.Length( ) );
                    TBuf<KMaxIntegerLen> num;
                    num.Num( objectId );
                    file->Des().Append( num );
                    file->Des().Append( ext );

                    if ( file->Des( ) == tmpPtr )
                        {
                        ret = KErrNone;
                        }
                    CleanupStack::PopAndDestroy( file );
                    CleanupStack::PopAndDestroy( tmp );
                    }
                }
            }
        }
    else
        { // default download dir
        aSystemPath = iDownloadDir->AllocL( );
        }

    return ret;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsValidUrlPathL
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsValidUrlPath( const TDesC& aUrlPath )
    {
    TInt ret = ETrue;
    if ( (aUrlPath.Length( ) != KMaxIntegerLen + KRandomRangeLength)
            && (aUrlPath.Length( ) != KMaxIntegerLen + KRandomRangeLength
                    + KRandomRangeLength) )
        {
        ret = EFalse;
        }
    else
        {
        for ( TInt i = 0; i < aUrlPath.Length( ); i++ )
            if ( aUrlPath[i] < '0' || aUrlPath[i] > '9' )
                {
                ret = EFalse;
                break;
                }
        }

    return ret;
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetItemTypeFromMimeTypeLC
// -----------------------------------------------------------------------------
HBufC8* CUpnpContentDirectory::GetItemTypeFromMimeTypeLC(
    const TDesC8& aMimeType )
    {
    HBufC8* result = NULL;
    if ( aMimeType.Compare( KNullDesC8( ) ) == 0 )
        {
        return result;
        }
    TInt indexOfSlash = aMimeType.Find( KSlash8( ) );
    if ( indexOfSlash < KErrNone )
        {
        return result;
        }
    TPtrC8 firstValue = aMimeType.Left( indexOfSlash );
    if ( firstValue.Compare( KImageMime( ) ) == 0 )
        {
        result = KObjectClassImageItem().AllocLC( );
        }
    else if ( firstValue.Compare( KTextMime( ) ) == 0 )
        {
        result = KObjectClassTextItem().AllocLC( );
        }
    else if ( firstValue.Compare( KVideoMime( ) ) == 0 )
        {
        result = KObjectClassVideoItem().AllocLC( );
        }
    else if ( firstValue.Compare( KAudioMime( ) ) == 0 )
        {
        result = KObjectClassAudioItem().AllocLC( );
        }
    return result;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::GetItemTypeFromMimeTypeLC
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::CheckItemTypeForObjectL( RXmlEngDocument& aObj,
    const TDesC8& aMimeType )
    {
    //  temporary disable because of mime-type recognition problem 
    HBufC8* itemType = GetItemTypeFromMimeTypeLC( aMimeType );
    if ( !itemType )
        {
        return;
        }
    TXmlEngElement obj = aObj.DocumentElement( );
    TXmlEngElement objClass;
    UpnpDomInterface::GetElementL( obj, objClass, KObjClassColName8 );
    TPtrC8 classValue(UpnpDomInterface::GetElementValueL( objClass ));
    if ( classValue.Compare( itemType->Des( ) ) < 0 )
        {
        objClass.SetTextL( *itemType );
        }
    CleanupStack::PopAndDestroy( itemType );

    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SetDownloadDirectoryL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::SetDownloadDirectoryL( const TDesC& aDownloadDir )
    {
    // perform necessary changes in database
    iContentDirectoryDb->NewMediaDirectoryL( *iDownloadDir );

    // alloc new string
    delete iDownloadDir;
    iDownloadDir = NULL;
    TPtrC last = aDownloadDir.Right( 1 );
    if ( last.Compare( KDiskPathElSep )!=0 )
        {
        iDownloadDir = HBufC::NewL( aDownloadDir.Length( )+ KDiskPathElSep().Length( ) );
        iDownloadDir->Des().Copy( aDownloadDir );
        iDownloadDir->Des().Append( KDiskPathElSep );
        }
    else
        {
        iDownloadDir = HBufC::NewL( aDownloadDir.Length( ) );
        iDownloadDir->Des().Copy( aDownloadDir );
        }
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SetThumbnailDirectoryL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::SetThumbnailDirectoryL( const TDesC& aDownloadDir )
    {
    // perform necessary changes in database
    iContentDirectoryDb->NewMediaDirectoryL( *iThumbDir );

    // alloc new string
    delete iThumbDir;
    iThumbDir = NULL;
    iThumbDir = aDownloadDir.AllocL( );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::HandleDbError
// -----------------------------------------------------------------------------
//
TInt CUpnpContentDirectory::HandleDbError( TInt aError )
    {
    return iContentDirectoryDb->HandleDbError( aError );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DataBaseHasBeenRecoveredL
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::DataBaseHasBeenRecoveredL( TInt aError )
    {
    TInt err = aError;
    if ( err == KErrCorrupt )
        {
        err = HandleDbError( err );
        }
    return (err == KErrNone && aError == KErrCorrupt ) ? ETrue : EFalse;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsDbOrDiskProblemL
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsDbOrDiskProblemL( CUpnpAction* aAction )
    {
    TBool noSpace = SysUtil::DiskSpaceBelowCriticalLevelL( &iFs,
        KMinDiskSpace, EDriveC );
    TInt error( KErrNone );
    if ( !noSpace )
        {
        if ( !IsDbCreated() )
            {
            error = HandleDbError( KErrCorrupt );
            }
        }
    if ( noSpace || error != KErrNone )
        {
        DoSendActionL( aAction, ECannotProcess );
        return ETrue;
        }
    return EFalse;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsDbCreated
// -----------------------------------------------------------------------------
//
TBool CUpnpContentDirectory::IsDbCreated()
    {
    return iContentDirectoryDb->IsDbCreated( );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::CreateNameForThumbnailL
// -----------------------------------------------------------------------------
//
HBufC* CUpnpContentDirectory::CreateNameForThumbnailL( const TDesC& aFileName )
    {
    // only name
    TParse fp;
    User::LeaveIfError( fp.Set( aFileName, 0, 0 ) );
    TFileName bareName = fp.Name( );
    // full name
    User::LeaveIfError( fp.Set( bareName, iThumbDir, &KDefaultThumbExtension ) );
    TFileName fullName = fp.FullName( );

    //check if exists
    TUint ignored;
    TInt q = 0;
    while ( iFs.Att( fullName, ignored ) == KErrNone )
        {
        q++;
        TBuf<KMaxIntegerLen> num;
        num.Num( q );
        TFileName tmpName;
        tmpName.Copy( bareName );
        tmpName.Append( KUndersc );
        tmpName.Append( num );
        fp.Set( tmpName, iThumbDir, &KDefaultThumbExtension );
        fullName = fp.FullName( );
        }

    return fullName.AllocL( );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AutoDestroyEventL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::AutoDestroyEventL( TInt aObjId, TBool aDeleteObj )
    {
    if ( !ValidateObjectL( aObjId ) )
        {
        return;
        }

    if ( aDeleteObj )
        {
        TBuf8<KMaxIntegerLen> containerID;
        containerID.Num( iContentDirectoryDb->GetParentIdL( aObjId ) );
        RArray<TInt> refList;
        CleanupClosePushL( refList );
        iContentDirectoryDb->DeleteObjectL( aObjId, refList, ETrue );

        // supporting ContainerUpdateIDs behaviour
        iStateHandler->IncreaseSystemUpdateIdL( );
        iStateHandler->IncreaseContainerUpdateIdL( containerID );
        for ( TInt i(0); i<refList.Count( ); i++ )
            {
            iStateHandler->IncreaseSystemUpdateIdL( );
            containerID.Num( refList[i] );
            iStateHandler->IncreaseContainerUpdateIdL( containerID );
            }

        // clean up
        CleanupStack::PopAndDestroy( &refList );
        }
    iAutoDestroyObjects->RemoveAndDestroyL( iAutoDestroyObjects->FindObjIndexByObjId( aObjId ) );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::HttpTransferEventReceivedL
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::HttpTransferEventReceivedL( CUpnpHttpMessage& aHttpMsg )
    {
    switch ( aHttpMsg.Type( ) )
        {
        case ETransferStart:
            {
            TransferStartL( aHttpMsg.SenderPathFromHeader( ) );

            CUpnpFileTransfer::TTransferType type;
            TInt objectid(0);

            if ( aHttpMsg.Method().Find( KHttpGet ) == 0 )
                {
                objectid = iContentDirectoryDb->GetObjIdByAttrL( KImportUri8,
                    aHttpMsg.SenderPathFromHeader( ) );
                type = CUpnpFileTransfer::EImport;
                }
            else
                {
                objectid = iContentDirectoryDb->GetObjIdByAttrLikeL(
                    KImportUri8, aHttpMsg.SenderPathFromHeader( ) );
                type = CUpnpFileTransfer::EUpload;

                }
            CUpnpFileTransfer* transfer = CUpnpFileTransfer::NewLC(
                aHttpMsg.SessionId( ), objectid, type );

            transfer->SetTransferState(:: ETransferInProgress);
            transfer->SetImportNumber(UpnpCdUtils::ResIdFromUriL(
                    aHttpMsg.SenderPathFromHeader()));

            iTransferController->iFileTransfers.Append(transfer);
            CleanupStack::Pop( transfer );

            iTransferController->AddIncomingTransferInternalL(&aHttpMsg);
            break;
            }
        case ETransferError:
            {
            iTransferController->TransferFailL( &aHttpMsg );
            break;
            }
        default:
        break;
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ImportComplete
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::TransferProgress( TInt aId, TInt aBytes,
    TInt aTotalBytes )
    {
    TInt transferId = iTransferController->Transfer( aId );
    if ( transferId != KErrNotFound )
        {
        (iTransferController->iFileTransfers[ transferId ])->SetTransferLength( aBytes );
        (iTransferController->iFileTransfers[ transferId ])->SetTransferTotal( aTotalBytes );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::TransferStartL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::TransferStartL( const TDesC8& aImpUri )
    {
    TInt index = iAutoDestroyObjects->FindObjIndexByResId( UpnpCdUtils::ResIdFromUriL( aImpUri ) );
    if ( index != KErrNotFound )
        {
        (*iAutoDestroyObjects)[index]->SetTransferStartedL( ETrue );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::TransferCompleteL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::TransferCompleteL( TInt aResId, TInt aObjId )
    {
    TInt index = iAutoDestroyObjects->FindObjIndexByResId( aResId );
    if ( index != KErrNotFound )
        {
        iAutoDestroyObjects->RemoveAndDestroyL( index );
        }

    if ( (aObjId>=0)&&(aResId>=0)
            &&(iContentDirectoryDb->GetParentIdL( aObjId )>=0) )
        {
        TBuf8<KMaxIntegerLen> containerID;
        containerID.Num( iContentDirectoryDb->GetParentIdL( aObjId ) );
        iStateHandler->IncreaseSystemUpdateIdL( );
        iStateHandler->IncreaseContainerUpdateIdL( containerID );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NotifyTransferFailL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::NotifyTransferFailL( TInt aSessionId,
    TInt aStatusCode )
    {
    CUpnpFileTransferEvent* event =
            iTransferController->RemoveTransferLC( aSessionId );
    if ( event )
        {
        event->SetProgressState( CUpnpFileTransferEvent::EFailed );
        event->SetErrorCode( aStatusCode );
        CleanupStack::Pop( event );
        iEventObserver->FileTransferEvent( event );
        }

    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NotifyTransferStoppedL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::NotifyTransferStoppedL( TInt aSessionId,
    CUpnpFileTransfer::TTransferType aType )
    {
    CUpnpFileTransferEvent* event =
            iTransferController->RemoveTransferLC( aSessionId );
    if ( event )
        {
        event->SetProgressState( CUpnpFileTransferEvent::EStopped );
        if ( aType == CUpnpFileTransfer::EImport )
            {
            event->SetDirection( CUpnpFileTransferEvent::EIncoming );
            }
        else
            {
            event->SetDirection( CUpnpFileTransferEvent::EOutgoing );
            }

        CleanupStack::Pop( event );
        iEventObserver->FileTransferEvent( event );
        }

    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NotifyOutgoingTransferL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::NotifyOutgoingTransferL( TInt aSessionId )
    {
    CUpnpFileTransferEvent* event =
            iTransferController->RemoveTransferLC( aSessionId );
    if ( event )
        {
        CleanupStack::Pop( event );
        //send event to Media Server        
        iEventObserver->FileTransferEvent( event );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SetSender
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::SetSender( MUpnpCdsSender* aSender )
    {
    iSender = aSender;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoSendActionL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::DoSendActionL( CUpnpAction* aAction,
    TUpnpErrorCode aError )
    {
    iSender->SendL( aAction, aError );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoSendActionL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::DoSendMessageL( CUpnpHttpMessage* aMessage )
    {
    iSender->SendL( aMessage );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SendActionL
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::SendActionL( CUpnpAction* aAction,
    TUpnpErrorCode aError )
    {
    SendL( aAction, aError );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::DoSendActionL
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::SendMessageL( CUpnpHttpMessage* aMessage )
    {
    SendL( aMessage );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::StateVariableEvented
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::StateVariableEvented( const TDesC8& aVariableName )
    {
    iStateHandler->StateVariableEvented( aVariableName );
    }
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::StateHandler
// -----------------------------------------------------------------------------
//
CUpnpStateHandler* CUpnpContentDirectory::StateHandler()
    {
    return iStateHandler;
    }

// helper functions
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ExecutedAction
// -----------------------------------------------------------------------------
//
TCurrentAction CUpnpContentDirectory::ExecutedAction()
    {
    return iCurrentAction;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::SetExecutedAction
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::SetExecutedAction( TCurrentAction aAction )
    {
    iCurrentAction = aAction;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::HttpResponseReceivedL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::HttpResponseReceivedL( TInt aSessionId,
    TInt aStatusCode )
    {
    iTransferController->HttpResponseReceivedL( aSessionId, aStatusCode );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::EventObserver
// -----------------------------------------------------------------------------
//
MUpnpContentDirectoryEventObserver* CUpnpContentDirectory::EventObserver()
    {
    return iEventObserver;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ContentDirectoryDb
// -----------------------------------------------------------------------------
//
CUpnpContentDirectoryDb* CUpnpContentDirectory::ContentDirectoryDb()
    {
    return iContentDirectoryDb;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::IsObjectExistL
// -----------------------------------------------------------------------------
//    
TBool CUpnpContentDirectory::IsObjectExistL( TInt aObjectId )
    {
    if ( iContentDirectoryDb->CheckObjectRestrictionL( aObjectId )
            == ENoSuchObject )
        {
        return EFalse;
        }
    else
        {
        return ETrue;
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::ValidateObjectL
// -----------------------------------------------------------------------------
//   
TBool CUpnpContentDirectory::ValidateObjectL( TInt aObjectId )
    {
    //removes from autodestroy array orphaned objects
    TInt i(0);
    TInt index(0);
    while ( i < iAutoDestroyObjects->Count( ) )
        {
        TInt parentID( iContentDirectoryDb->GetParentIdL(
                        ( *iAutoDestroyObjects )[ i ]->GetObjId( ) ) );
        if ( parentID < 0 )
            {
            index = iAutoDestroyObjects->FindObjIndexByObjId( (
                                             *iAutoDestroyObjects )[ i ]->GetObjId( ) );
            iAutoDestroyObjects->RemoveAndDestroyL( index );
            continue;
            }
        i++;
        }

    //checks if given object exists
    if ( !IsObjectExistL( aObjectId ) )
        {
        index = iAutoDestroyObjects->FindObjIndexByObjId( aObjectId );
        if ( index != KErrNotFound )
            {
            iAutoDestroyObjects->RemoveAndDestroyL( index );
            }
        }

    //cheks if given object exists in autodestroy array
    index = iAutoDestroyObjects->FindObjIndexByObjId( aObjectId );
    if ( index != KErrNotFound )
        {
        return ETrue;
        }

    return EFalse;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::TransferHandler
// -----------------------------------------------------------------------------
//
MUpnpTransferInterface* CUpnpContentDirectory::TransferHandler()
    {
    return iTransferHandler;
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::TransferCompletedL
// -----------------------------------------------------------------------------
//    
void CUpnpContentDirectory::TransferCompletedL( TInt aKey, TInt aResultCode )
    {
    HttpResponseReceivedL( aKey, aResultCode );
    if ( aResultCode == EHttpOk )
        {
        TInt transferid = iTransferController->Transfer( aKey );
        if ( transferid > KErrNotFound )
            {
            TInt
                    len =
                            iTransferController->iFileTransfers[transferid]->TransferTotal( );
            iTransferController->iFileTransfers[transferid]->SetTransferLength( len );
            }
        }
    }
    
// -----------------------------------------------------------------------------
// CUpnpContentDirectory::NewTransactionL
// -----------------------------------------------------------------------------
//
EXPORT_C void CUpnpContentDirectory::NewTransactionL(
        const TDesC8& aMethod, const TDesC8& aUri, 
        const TInetAddr& aSender, CUpnpHttpServerTransaction*& aResultTrans )
    {
    iDlnaFilter->NewTransactionL( aMethod, aUri, aSender, aResultTrans );
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::HttpEventLD
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::HttpEventLD( CUpnpHttpMessage* aMessage )
    {
    if ( aMessage )
        {
        CleanupStack::PushL( aMessage );
        if( aMessage->Type() >= ETransferStart )
            {
            HttpTransferEventReceivedL( *aMessage );
            }
        else
            {
            UnknownHttpEventReceivedL( *aMessage );
            }
        CleanupStack::PopAndDestroy( aMessage );
        }
    }

// -----------------------------------------------------------------------------
// CUpnpContentDirectory::AddressChangeL
// -----------------------------------------------------------------------------
//
void CUpnpContentDirectory::AddressChangeL()
    {
    iHttpServerSession->Stop();
    iHttpServerSession->StartL();        
    }

//End of File