diff -r 000000000000 -r 7f85d04be362 upnpmediaserver/contentdirectoryservice/src/upnpcontentdirectory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnpmediaserver/contentdirectoryservice/src/upnpcontentdirectory.cpp Thu Dec 17 08:52:00 2009 +0200 @@ -0,0 +1,3726 @@ +/** @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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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* array = + reinterpret_cast*>(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 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 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 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 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 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 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& 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 refList; + CleanupClosePushL( refList ); + + TBuf8 containerID; + containerID.Num( iContentDirectoryDb->GetParentIdL( objId ) ); + + iContentDirectoryDb->DeleteObjectL( objId, refList, ETrue ); + + iStateHandler->IncreaseSystemUpdateIdL( ); + iStateHandler->IncreaseContainerUpdateIdL( containerID ); + + for ( TInt i(0); iIncreaseSystemUpdateIdL( ); + 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 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 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 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 addrTmp; + resourceServerAddress.Output( addrTmp ); + HBufC8* addr = UpnpString::FromUnicodeL( addrTmp ); + CleanupStack::PushL( addr ); + + TInt portNo = resourceServerAddress.Port(); + TBuf8 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 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 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 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 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 contIds; + CleanupClosePushL( contIds ); + iContentDirectoryDb->DeleteResourceL( *internalUri, contIds ); + + // updateIDs + for ( TInt i = 0; i < contIds.Count( ); i++ ) + { + TBuf8 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 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 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 importUris; + CleanupClosePushL( importUris ); + RArray 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 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 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 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 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 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 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 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 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 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 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 containerID; + containerID.Num( iContentDirectoryDb->GetParentIdL( aObjId ) ); + RArray refList; + CleanupClosePushL( refList ); + iContentDirectoryDb->DeleteObjectL( aObjId, refList, ETrue ); + + // supporting ContainerUpdateIDs behaviour + iStateHandler->IncreaseSystemUpdateIdL( ); + iStateHandler->IncreaseContainerUpdateIdL( containerID ); + for ( TInt i(0); iIncreaseSystemUpdateIdL( ); + 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 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