--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsserver.cpp Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,962 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Metadata main server class*
+*/
+
+// INCLUDE FILES
+#include "mdsserver.h"
+#include "mdscommoninternal.h"
+#include "mdsserversession.h"
+#include "mdsdbconnectionpool.h"
+#include "mdssqldbmaintenance.h"
+#include "mdssqliteconnection.h"
+#include "mdsnotifier.h"
+#include "mdsobjectlocklist.h"
+#include "mdslogger.h"
+#include "mdsmaintenanceengine.h"
+#include "mdsmanipulationengine.h"
+#include "mdsclausebuffer.h"
+#include "mdebackuprestorewatcher.h"
+#include "mdsschema.h"
+#include "mdcserializationbuffer.h"
+#include <f32file.h>
+
+__DEFINE_LOGGER
+
+const TInt64 KDiskSpaceGarbageCollectorThreshold = 1024*1024; // 1 MB
+const TInt64 KDiskFullThreshold = 1024*50; // 50 kB
+
+_LIT( KSchema, "schema.mde" );
+_LIT( KDefaultImportProfile, "defaultimportfile.mde" );
+_LIT( KBackupRegistration, "backup_registration.xml" );
+_LIT( KSchemaPath, "z:\\private\\200009F3\\schema.mde" );
+_LIT( KDefaultImportProfilePath, "z:\\private\\200009F3\\defaultimportfile.mde" );
+_LIT( KBackupRegistrationPath, "z:\\private\\200009F3\\backup_registration.xml" );
+
+// ========================= MdS POLICY ==================================
+
+const TUint KMdsRangeCount = EUnknownMdEServRqst + 1;
+
+const TInt KMdsRanges[KMdsRangeCount] =
+ {
+ EShutdown, // shut down the session
+ EAdd, // add items
+ ERemove, // remove items
+ EFind, // finds in sync
+ EAsyncFind, // finds asynchronously
+ EContinueAsyncFind, // continues existing asynchronous find, fetches next set
+ ECancelFind, // cancels asynchronous find
+ ECancelObject, // cancels opened object
+ ECheckObject, // get object's "base" values
+ EUpdate, // update items
+ ERegister, // registers an object to be notified
+ EListen, // listens for events for a registered profile
+ EUnregister, // unregisters for no more notifications
+ EGetData, // (transfers data server->client)
+ EImportMetadata, // starts metadata importing
+ EAsyncImportMetadata, // starts asynchronous metadata importing
+ EExportMetadata, // starts metadata exporting
+ EAsyncExportMetadata, // starts asynchronous metadata exporting
+ EImportSchema, // starts schema importing
+ EAddRelationDef, // Add relation def
+ EAddEventDef, // Add event def
+ EAddMemoryCard,
+ EGetMemoryCard,
+ ECheckMemoryCard,
+ ESetMedia,
+ EGetMedia,
+ EGetPresentMedias,
+ ESetFileToPresent,
+ ESetFilesToPresent,
+ ESetFilesToNotPresent,
+ ERemoveFilesNotPresent,
+ EGetSchemaVersion,
+ ESetObjectToPresentByGuid,
+ ESetHarvestingPrioritizationChunk,
+ EAddHarvestingPrioritizationObserver,
+ ECancelHarvestingPrioritizationObserver,
+ EChangePath,
+ ESetPending,
+ EResetPending,
+ EGetPendingCount,
+ EGetPending,
+ EResetDB,
+ EChangeMediaId,
+ EUnknownMdEServRqst // handle for unknown requests
+ };
+
+const TUint8 KMdsElementsIndex[KMdsRangeCount] =
+ {
+ CPolicyServer::ECustomCheck, // EShutdown
+ CPolicyServer::ECustomCheck, // EAdd
+ CPolicyServer::ECustomCheck, // ERemove
+ CPolicyServer::ECustomCheck, // EFind
+ CPolicyServer::ECustomCheck, // EAsyncFind
+ CPolicyServer::ECustomCheck, // EContinueAsyncFind
+ CPolicyServer::ECustomCheck, // ECancelFind
+ CPolicyServer::ECustomCheck, // ECancelObject
+ CPolicyServer::ECustomCheck, // ECheckObject
+ CPolicyServer::ECustomCheck, // EUpdate
+ CPolicyServer::ECustomCheck, // ERegister
+ CPolicyServer::ECustomCheck, // EListen
+ CPolicyServer::ECustomCheck, // EUnregister
+ CPolicyServer::ECustomCheck, // EGetData
+ CPolicyServer::ECustomCheck, // EImportMetadata
+ CPolicyServer::ECustomCheck, // EAsyncImportMetadata
+ CPolicyServer::ECustomCheck, // EExportMetadata
+ CPolicyServer::ECustomCheck, // EAsyncExportMetadata
+ CPolicyServer::ECustomCheck, // EImportSchema
+ CPolicyServer::ECustomCheck, // EAddRelationDef
+ CPolicyServer::ECustomCheck, // EAddEventDef
+ CPolicyServer::ECustomCheck, // EAddMemoryCard
+ CPolicyServer::ECustomCheck, // EGetMemoryCard
+ CPolicyServer::ECustomCheck, // ECheckMemoryCard
+ CPolicyServer::ECustomCheck, // ESetMedia
+ CPolicyServer::ECustomCheck, // EGetMedia
+ CPolicyServer::ECustomCheck, // EGetPresentMedias
+ CPolicyServer::ECustomCheck, // ESetFileToPresent
+ CPolicyServer::ECustomCheck, // ESetFilesToPresent
+ CPolicyServer::ECustomCheck, // ESetFilesToNotPresent
+ CPolicyServer::ECustomCheck, // ERemoveFilesNotPresent
+ CPolicyServer::ECustomCheck, // EGetSchemaVersion
+ CPolicyServer::ECustomCheck, // ESetObjectToPresentByGuid
+ CPolicyServer::ECustomCheck, // ESetHarvestingPrioritizationChunk
+ CPolicyServer::ECustomCheck, // EAddHarvestingPrioritizationObserver
+ CPolicyServer::ECustomCheck, // ECancelHarvestingPrioritizationObserver
+ CPolicyServer::ECustomCheck, // EChangePath
+ CPolicyServer::ECustomCheck, // ESetPending
+ CPolicyServer::ECustomCheck, // EResetPending
+ CPolicyServer::ECustomCheck, // EGetPendingCount
+ CPolicyServer::ECustomCheck, // EGetPending
+ CPolicyServer::ECustomCheck, // EResetDB
+ CPolicyServer::ECustomCheck, // EChangeMediaId
+ CPolicyServer::ENotSupported // EUnknownMdEServRqst
+ };
+
+
+const CPolicyServer::TPolicy KMdsPolicy =
+ {
+ CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
+ KMdsRangeCount,
+ KMdsRanges,
+ KMdsElementsIndex,
+ NULL //mdsElements
+ };
+
+
+CPolicyServer::TCustomResult CMdSServer::CustomSecurityCheckL(
+ const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/ )
+ {
+ CPolicyServer::TCustomResult securityCheckResult = EFail;
+ switch ( aMsg.Function() )
+ {
+ case EAdd:
+ case ERemove:
+ case ECancelObject:
+ case EUpdate:
+ case EImportMetadata:
+ case EAsyncImportMetadata:
+ case EAddRelationDef:
+ case EAddEventDef:
+ case EImportSchema:
+ case ESetObjectToPresentByGuid:
+ {
+ if( aMsg.HasCapability( ECapabilityWriteDeviceData ) )
+ {
+ securityCheckResult = EPass;
+ }
+ }
+ break;
+
+ case ERegister:
+ case EListen:
+ case EUnregister:
+ case EFind:
+ case EAsyncFind:
+ case EContinueAsyncFind:
+ case ECancelFind:
+ case EGetData:
+ case ECheckObject:
+ {
+ securityCheckResult = EPass;
+ }
+ break;
+
+ case EExportMetadata:
+ case EAsyncExportMetadata:
+ case EGetSchemaVersion:
+ {
+ if( aMsg.HasCapability( ECapabilityReadUserData ) ||
+ aMsg.HasCapability( ECapabilityReadDeviceData ) )
+ {
+ securityCheckResult = EPass;
+ }
+ }
+ break;
+
+ // Only for internal MdS usage
+ case EAddMemoryCard:
+ case EGetMemoryCard:
+ case ECheckMemoryCard:
+ case ESetMedia:
+ case EGetMedia:
+ case EGetPresentMedias:
+ case ESetFileToPresent:
+ case ESetFilesToPresent:
+ case ESetFilesToNotPresent:
+ case ERemoveFilesNotPresent:
+ case ESetHarvestingPrioritizationChunk:
+ case EAddHarvestingPrioritizationObserver:
+ case ECancelHarvestingPrioritizationObserver:
+ case EChangePath:
+ case EChangeMediaId:
+ case ESetPending:
+ case EResetPending:
+ case EGetPendingCount:
+ case EGetPending:
+ case EResetDB:
+ {
+ if( aMsg.HasCapability( ECapabilityDiskAdmin ) )
+ {
+ securityCheckResult = EPass;
+ }
+ }
+ break;
+
+ default:
+ {
+ securityCheckResult = EFail;
+ }
+ }
+
+ return securityCheckResult;
+ }
+
+CPolicyServer::TCustomResult CMdSServer::CustomFailureActionL(
+ const RMessage2& /*aMsg*/, TInt /*aAction*/, const TSecurityInfo& /*aMissing*/)
+ {
+ // Not used
+ return EFail;
+ }
+
+
+// ========================= MEMBER FUNCTIONS ==================================
+void CMdSServer::HandleDiskSpaceNotificationL( TDiskSpaceDirection aDiskSpaceDirection )
+ {
+ // skip db cleaning if drive's free space is over limit or
+ // backup or restore is running
+ if( MMdSDiskSpaceNotifierObserver::EMore == aDiskSpaceDirection ||
+ iBackupOrRestoreRunning )
+ {
+ return;
+ }
+
+ // delete only objects which are in "not present" state and
+ // object was not located in last (count = KMemoryCardLimit)
+ // inserted memory cards and object doesn't have any relations
+ _LIT( KMemoryCardCleanup, "DELETE FROM Object%u WHERE ObjectId IN(SELECT ObjectId FROM Object%u WHERE((Flags&?) AND (MediaId NOT IN(SELECT DISTINCT Value FROM MdE_Preferences WHERE Key=? ORDER BY ExtraValue DESC LIMIT ?)) AND (ObjectId NOT IN(SELECT DISTINCT LeftObjectId FROM Relations%u)) AND (ObjectId NOT IN(SELECT DISTINCT RightObjectId FROM Relations%u))) ORDER BY LastModifiedDate ASC LIMIT ?);" );
+
+ const TInt KMaxLenghtForNamespaceIdsAsText = 4 * KMaxUintValueLength;
+ CMdsClauseBuffer* clause = CMdsClauseBuffer::NewLC(
+ KMemoryCardCleanup.iTypeLength + KMaxLenghtForNamespaceIdsAsText );
+
+ clause->BufferL().Format( KMemoryCardCleanup,
+ KDefaultNamespaceDefId,
+ KDefaultNamespaceDefId,
+ KDefaultNamespaceDefId,
+ KDefaultNamespaceDefId );
+
+ RRowData variables;
+ CleanupClosePushL( variables );
+
+ _LIT( KMemoryCardKey, "MC" );
+ const TInt KMemoryCardLimit = 1;
+ const TInt KObjectCleanupLimit = 1024;
+
+ variables.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
+ variables.AppendL( TColumn( KMemoryCardKey ) );
+ variables.AppendL( TColumn( KMemoryCardLimit ) );
+ variables.AppendL( TColumn( KObjectCleanupLimit ) );
+
+ TInt rowCount = iDefaultDBConnection->ExecuteL( clause->ConstBufferL(), variables );
+
+ CleanupStack::PopAndDestroy( 2, clause ); // variables, clause
+ }
+
+
+void CMdSServer::HandleDiskSpaceError(TInt /*aError*/)
+ {
+ }
+
+
+CMdSServer* CMdSServer::NewL()
+ {
+ CMdSServer* MdSServer = CMdSServer::NewLC();
+ CleanupStack::Pop( MdSServer );
+ return MdSServer;
+ }
+
+
+CMdSServer* CMdSServer::NewLC()
+ {
+ CMdSServer* MdSServer = new ( ELeave ) CMdSServer( CActive::EPriorityStandard );
+ CleanupStack::PushL( MdSServer );
+ MdSServer->ConstructL();
+ return MdSServer;
+ }
+
+
+void CMdSServer::ConstructL()
+ {
+ __INIT_LOGGER;
+ StartL( KMdSServerName );
+ __LOGLB( ELogAlways, "Server start" );
+
+ CheckInitSriptL();
+
+ iLockList = CMdSObjectLockList::NewL();
+ CMdSSqLiteConnection* conn = CMdSSqLiteConnection::NewLC();
+ iDefaultDBConnection = conn;
+ MMdSDbConnectionPool::SetDefaultDB( conn );
+
+ CMdSMaintenanceEngine::InitConnectionL();
+ CleanupStack::Pop( conn );
+
+ iNotifier = CMdSNotifier::NewL();
+
+ InitializeL();
+
+ iDiskSpaceGarbageCollectorNotifier =
+ CMdSDiskSpaceNotifierAO::NewL( *this,
+ KDiskSpaceGarbageCollectorThreshold,
+ KMdsSqlDbDefaultName );
+
+ iDiskFullNotifier =
+ CMdSDiskSpaceNotifierAO::NewL( *this,
+ KDiskFullThreshold,
+ KMdsSqlDbDefaultName );
+
+ // Create a backup & restore watcher and add this server as its observer.
+ iBURWatcher = CMdEBackupRestoreWatcherAO::NewL(*this);
+
+ // create shutdown observer
+ iShutdownObserver = CMDSShutdownObserver::NewL( *this );
+ iShutdown = EFalse;
+ }
+
+void CMdSServer::InitializeL()
+ {
+ iMaintenance = CMdSMaintenanceEngine::NewL();
+
+ iSchema = CMdsSchema::NewL();
+
+ iManipulate = CMdSManipulationEngine::NewL( *iSchema, *iNotifier,
+ *iLockList );
+
+ iMaintenance->InstallL( *iManipulate, *iSchema );
+ }
+
+void CMdSServer::DeInitializeL()
+ {
+ if ( iMaintenance )
+ {
+ delete iMaintenance;
+ iMaintenance = NULL;
+ }
+ if ( iManipulate )
+ {
+ delete iManipulate;
+ iManipulate = NULL;
+ }
+ if ( iSchema )
+ {
+ delete iSchema;
+ iSchema = NULL;
+ }
+ }
+
+TInt CMdSServer::ResetDBL()
+ {
+ DeInitializeL();
+
+ CMdSMaintenanceEngine::DeleteDatabase();
+ CMdSMaintenanceEngine::InitConnectionL();
+
+ InitializeL();
+ return KErrNone;
+ }
+
+CMdSServer::CMdSServer( TInt aPriority ) :
+ CPolicyServer(aPriority, KMdsPolicy),
+ iBackupOrRestoreRunning( EFalse ),
+ iHarvestingPrioritizationSerializationBuffer( NULL )
+ {
+ iServerErrorStatus = KErrNone;
+ }
+
+
+CMdSServer::~CMdSServer()
+ {
+
+ iShutdown = ETrue;
+
+ delete iBURWatcher;
+ delete iDiskSpaceGarbageCollectorNotifier;
+ delete iDiskFullNotifier;
+ delete iManipulate;
+ delete iSchema;
+ delete iNotifier;
+ delete iLockList;
+ delete iMaintenance;
+ delete iDefaultDBConnection;
+
+ delete iHarvestingPrioritizationSerializationBuffer;
+ iHarvestingPrioritizationChunk.Close();
+
+ delete iShutdownObserver;
+
+ __LOGLB( ELogAlways, "Server stop" );
+ __DESTROY_LOGGER;
+ }
+
+
+CSession2* CMdSServer::NewSessionL( const TVersion& aVersion, const RMessage2& /*aMessage*/ ) const
+ {
+ // Check we are the right version
+ if ( !User::QueryVersionSupported( TVersion( KMdSServMajorVersionNumber,
+ KMdSServMinorVersionNumber,
+ KMdSServBuildVersionNumber ),
+ aVersion ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ if ( iShutdownObserver->UpdateInProgress() )
+ {
+ __LOGLB( ELogAlways, "CMdSServer::NewSessionL: iad update in progress: KErrLocked");
+ User::Leave(KErrLocked);
+ }
+
+ if ( iServerErrorStatus != KErrNone )
+ {
+ // leave with the same error code that the server has
+ User::Leave ( iServerErrorStatus );
+ }
+
+ __LOGLB( ELogAlways, "New Session" );
+ // Make new session
+ return CMdSServerSession::NewL( *const_cast<CMdSServer*> ( this ) );
+ }
+
+
+void CMdSServer::IncrementSessions()
+ {
+ iSessionCount++;
+ }
+
+
+void CMdSServer::DecrementSessions()
+ {
+ iSessionCount--;
+ if ( iSessionCount <= 0 )
+ {
+ if (!iShutdown)
+ {
+ CActiveScheduler::Stop();
+ iShutdown = ETrue;
+ }
+ }
+ }
+
+CMdsSchema& CMdSServer::Schema()
+ {
+ return *iSchema;
+ }
+
+CMdSObjectLockList& CMdSServer::LockList()
+ {
+ return *iLockList;
+ }
+
+CMdSNotifier& CMdSServer::Notifier()
+ {
+ return *iNotifier;
+ }
+
+CMdSMaintenanceEngine& CMdSServer::Maintenance()
+ {
+ return *iMaintenance;
+ }
+
+CMdSManipulationEngine& CMdSServer::Manipulate()
+ {
+ return *iManipulate;
+ }
+
+TBool CMdSServer::DiskFull() const
+ {
+ return iDiskFullNotifier->DiskFull();
+ }
+
+TBool CMdSServer::BackupOrRestoreRunning() const
+ {
+ return iBackupOrRestoreRunning;
+ }
+
+// -----------------------------------------------------------------------------
+// CMdSServer::ShutdownNotification
+// -----------------------------------------------------------------------------
+//
+void CMdSServer::ShutdownNotification()
+ {
+
+
+ if (!iShutdown)
+ {
+ CActiveScheduler::Stop();
+ iShutdown = ETrue;
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMdSServer::ShutdownNotification
+// -----------------------------------------------------------------------------
+//
+void CMdSServer::RestartNotification()
+ {
+ }
+
+
+TInt CMdSServer::SetHarvestingPrioritizationChunkL( const RMessagePtr2 aMessage, TInt aParam )
+ {
+ // if there happens to be old chunk, close it
+ iHarvestingPrioritizationChunk.Close();
+
+ TInt error = iHarvestingPrioritizationChunk.Open( aMessage, aParam, EFalse );
+
+ if( error != KErrNone )
+ {
+ return error;
+ }
+
+ if( iHarvestingPrioritizationSerializationBuffer )
+ {
+ delete iHarvestingPrioritizationSerializationBuffer;
+ iHarvestingPrioritizationSerializationBuffer = NULL;
+ }
+
+ iHarvestingPrioritizationSerializationBuffer =
+ CMdCSerializationBuffer::NewL(
+ iHarvestingPrioritizationChunk.Base(),
+ iHarvestingPrioritizationChunk.Size() );
+
+ iHarvestingPrioritizationLocked = EFalse;
+
+ return KErrNone;
+ }
+
+TInt CMdSServer::AddHarvestingPrioritizationObserver( RMessagePtr2 aMessage )
+ {
+ if( iHarvestingPrioritizationObserver.IsNull() )
+ {
+ iHarvestingPrioritizationLocked = EFalse;
+
+ iHarvestingPrioritizationObserver = aMessage;
+
+ // reserve space for harvesting prioritization URI count
+ iHarvestingPrioritizationLimit = CMdCSerializationBuffer::KRequiredSizeForTInt32;
+ iHarvestingPrioritizationUriCount = 0;
+
+ return KErrNone;
+ }
+ else
+ {
+ RThread clientThread;
+ iHarvestingPrioritizationObserver.Client( clientThread );
+ TExitType exitType = clientThread.ExitType();
+ clientThread.Close();
+ if( EExitPending != exitType )
+ {
+ iHarvestingPrioritizationLocked = EFalse;
+
+ iHarvestingPrioritizationObserver = aMessage;
+
+ // reserve space for harvesting prioritization URI count
+ iHarvestingPrioritizationLimit = CMdCSerializationBuffer::KRequiredSizeForTInt32;
+ iHarvestingPrioritizationUriCount = 0;
+
+ return KErrNone;
+ }
+ }
+
+ return KErrAlreadyExists;
+ }
+
+TInt CMdSServer::CancelHarvestingPrioritizationObserver()
+ {
+ iHarvestingPrioritizationLocked = EFalse;
+
+ if( iHarvestingPrioritizationObserver.IsNull() )
+ {
+ return KErrNotFound;
+ }
+
+ NotifyHarvestingPrioritizationObserver( KErrCancel );
+ return KErrNone;
+ }
+
+TBool CMdSServer::ReserveSpaceHarvestingPrioritizationUri( const TDesC16& aUri )
+ {
+ if( !iHarvestingPrioritizationLocked &&
+ iHarvestingPrioritizationObserver.IsNull() == EFalse &&
+ iHarvestingPrioritizationSerializationBuffer )
+ {
+ // reserve space for URI offset and URI
+ const TInt reserveSpace =
+ CMdCSerializationBuffer::KRequiredSizeForTUint32 +
+ CMdCSerializationBuffer::RequiredSize( aUri );
+
+ const TInt maxBufferSize =
+ iHarvestingPrioritizationSerializationBuffer->Size();
+
+ // check if buffer has enough space for the new URI
+ if( maxBufferSize >= ( iHarvestingPrioritizationLimit + reserveSpace ) )
+ {
+ iHarvestingPrioritizationLimit += reserveSpace;
+ iHarvestingPrioritizationUriCount++;
+ return ETrue;
+ }
+ // if buffer doesn't have enough space for the new uri,
+ // discard current URI and all following URIs
+ else
+ {
+ iHarvestingPrioritizationLimit = maxBufferSize;
+ return EFalse;
+ }
+ }
+ return EFalse;
+ }
+
+TBool CMdSServer::StartAddingHarvestingPrioritizationUrisL()
+ {
+ if( !iHarvestingPrioritizationLocked &&
+ iHarvestingPrioritizationObserver.IsNull() == EFalse &&
+ iHarvestingPrioritizationSerializationBuffer )
+ {
+ iHarvestingPrioritizationLocked = ETrue;
+
+ // add URI count to harvesting prioritization buffer
+ iHarvestingPrioritizationSerializationBuffer->PositionL( 0 );
+ iHarvestingPrioritizationSerializationBuffer->InsertL(
+ iHarvestingPrioritizationUriCount );
+
+ iHarvestingPrioritizationBufferUriCount = 0;
+
+ // set URI offset to position of the first URI
+ iHarvestingPrioritizationBufferUriOffset =
+ CMdCSerializationBuffer::KRequiredSizeForTInt32 +
+ CMdCSerializationBuffer::KRequiredSizeForTUint32 *
+ iHarvestingPrioritizationUriCount;
+
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+TBool CMdSServer::AddHarvestingPrioritizationUriL( TDesC16& aUri )
+ {
+ if( iHarvestingPrioritizationObserver.IsNull() == EFalse &&
+ iHarvestingPrioritizationSerializationBuffer )
+ {
+ const TUint32 offset =
+ CMdCSerializationBuffer::KRequiredSizeForTInt32 +
+ CMdCSerializationBuffer::KRequiredSizeForTUint32 *
+ iHarvestingPrioritizationBufferUriCount;
+
+ iHarvestingPrioritizationSerializationBuffer->PositionL( offset );
+ iHarvestingPrioritizationSerializationBuffer->InsertL(
+ iHarvestingPrioritizationBufferUriOffset );
+
+ // move to URI offset, insert URI and get new URI offset
+ iHarvestingPrioritizationSerializationBuffer->PositionL(
+ iHarvestingPrioritizationBufferUriOffset );
+ iHarvestingPrioritizationBufferUriOffset =
+ iHarvestingPrioritizationSerializationBuffer->InsertL( aUri );
+
+ iHarvestingPrioritizationBufferUriCount++;
+
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+void CMdSServer::NotifyHarvestingPrioritizationObserver( TInt aStatus ) const
+ {
+ if( !iHarvestingPrioritizationObserver.IsNull() )
+ {
+ RThread clientThread;
+ iHarvestingPrioritizationObserver.Client( clientThread );
+ TExitType exitType = clientThread.ExitType();
+ if( EExitPending == exitType )
+ {
+ iHarvestingPrioritizationObserver.Complete( aStatus );
+ }
+ clientThread.Close();
+ }
+ }
+
+TInt CMdSServer::RunError( TInt aError )
+ {
+ __LOG1( ELogAlways, "Server::RunError %d", aError );
+
+ if ( aError == KErrBadDescriptor )
+ {
+ // A bad descriptor error implies a badly programmed client,
+ // so panic it; otherwise report the error to the client
+ PanicClient( Message(), KErrBadDescriptor );
+ }
+ else
+ {
+ Message().Complete( aError );
+ }
+
+ // The leave will result in an early return from CServer::RunL(), skipping
+ // the call to request another message. So do that now in order to keep the
+ // server running.
+ ReStart();
+
+ return KErrNone; // Handled the error fully
+ }
+
+
+
+void CMdSServer::PanicClient( const RMessage2& aMessage, TInt aPanic )
+ {
+ __LOG1( ELogAlways, "Server::PanicClient %d", aPanic );
+ aMessage.Panic( KMetadataEngine, aPanic );
+ }
+
+
+void CMdSServer::PanicServer( TMetadataPanic aPanic )
+ {
+ __LOG1( ELogAlways, "Server::PanicServer %d", aPanic );
+ MMdCCommon::Panic( aPanic );
+ }
+
+void CMdSServer::ThreadFunctionL()
+ {
+ User::LeaveIfError(User::RenameThread(KMdSServerName));
+ // Construct active scheduler
+ CActiveScheduler* activeScheduler = new ( ELeave ) CActiveScheduler;
+ CleanupStack::PushL( activeScheduler );
+
+ // Install active scheduler
+ // We don't need to check whether an active scheduler is already installed
+ // as this is a new thread, so there won't be one
+ CActiveScheduler::Install( activeScheduler );
+
+ // Construct our server
+ CMdSServer::NewLC(); // Anonymous
+
+ RProcess::Rendezvous(KErrNone);
+
+ // Start handling requests
+ CActiveScheduler::Start();
+
+ CleanupStack::PopAndDestroy( 2, activeScheduler );
+ }
+
+
+TInt CMdSServer::ThreadFunction( TAny* /*aNone*/ )
+ {
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if ( !( cleanupStack ) )
+ {
+ PanicServer( ECreateTrapCleanup );
+ }
+
+ TRAPD( err, ThreadFunctionL() );
+ if ( err != KErrNone )
+ {
+ PanicServer( ESrvCreateServer );
+ }
+
+ delete cleanupStack;
+ cleanupStack = NULL;
+
+ return KErrNone;
+ }
+
+
+// Backup & restore methods
+void CMdSServer::HandleBackup()
+ {
+ iBackupOrRestoreRunning = ETrue;
+
+ // Free resources for back up.
+ iManipulate->GarbageCollector().Pause();
+
+ // disconnect all DB connections
+ CMdSMaintenanceEngine::CloseDatabase();
+ }
+
+void CMdSServer::HandleRestore()
+ {
+ iBackupOrRestoreRunning = ETrue;
+
+ // Free resources for restore.
+ iManipulate->GarbageCollector().Pause();
+
+ // disconnect all DB connections
+ CMdSMaintenanceEngine::CloseDatabase();
+
+ // Currently trust that device will reboot after restore.
+ }
+
+void CMdSServer::ResumeOperation()
+ {
+ iBackupOrRestoreRunning = EFalse;
+
+ // Resume normal operation after back up.
+
+ // restore all DB connections
+ TRAPD( error, CMdSMaintenanceEngine::InitConnectionL() );
+
+ // if setting back DB connections fails
+ // something very bad has happened during backup or restore
+ if( KErrNone != error )
+ {
+ MMdCCommon::Panic( EServerBackupOrRestore );
+ }
+
+ // Restore resources
+ iManipulate->GarbageCollector().Resume();
+ }
+
+void CMdSServer::CheckInitSriptL()
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ RFileReadStream tmpFile;
+ TInt err( KErrNone );
+ TBuf<KMaxFileName> privatePath;
+ TBuf<KMaxFileName> schema;
+ TBuf<KMaxFileName> defaultImportProfile;
+ TBuf<KMaxFileName> backupRegistration;
+
+ fs.PrivatePath( privatePath );
+
+ schema.Copy( privatePath );
+ schema.Append( KSchema );
+
+ defaultImportProfile.Copy( privatePath );
+ defaultImportProfile.Append( KDefaultImportProfile );
+
+ backupRegistration.Copy( privatePath );
+ backupRegistration.Append( KBackupRegistration );
+
+ CFileMan* fileMan = CFileMan::NewL( fs );
+ CleanupStack::PushL( fileMan);
+
+ err = tmpFile.Open( fs, schema, EFileRead | EFileShareAny );
+ __LOG1( ELogAlways, "open schema.mde %d", err );
+ tmpFile.Close();
+ if ( err != KErrNone )
+ {
+ if ( err == KErrNotFound )
+ {
+ // Path found but not schema.mde, copy schema.m
+ const TInt error = fileMan->Copy( KSchemaPath, schema, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy schema.mde %d", error );
+ }
+ else if ( err == KErrPathNotFound)
+ {
+ // Create private dir
+ fs.CreatePrivatePath( EDriveC );
+
+ // Copy schema.mde
+ const TInt error = fileMan->Copy( KSchemaPath, schema, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy schema.mde %d", error );
+ }
+ }
+
+ err = tmpFile.Open( fs, defaultImportProfile, EFileRead | EFileShareAny );
+ __LOG1( ELogAlways, "open defaultimportprofile.mde %d", err );
+ tmpFile.Close();
+ if ( err != KErrNone )
+ {
+ if ( err == KErrNotFound )
+ {
+ // Path found but not schema.mde, copy schema.m
+ const TInt error1 = fileMan->Copy( KDefaultImportProfilePath, defaultImportProfile, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy defaultimportprofile.mde %d", error1 );
+ }
+ else if ( err == KErrPathNotFound)
+ {
+ // Create private dir
+ fs.CreatePrivatePath( EDriveC );
+
+ // Copy schema.mde
+ const TInt error1 = fileMan->Copy( KDefaultImportProfilePath, defaultImportProfile, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy defaultimportprofile.mde %d", error1 );
+ }
+ }
+
+ err = tmpFile.Open( fs, backupRegistration, EFileRead | EFileShareAny );
+ __LOG1( ELogAlways, "open backup_registration.xml %d", err );
+ tmpFile.Close();
+ if ( err != KErrNone )
+ {
+ if ( err == KErrNotFound )
+ {
+ // Path found but not schema.mde, copy schema.m
+ const TInt error2 = fileMan->Copy( KBackupRegistrationPath, backupRegistration, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy backup_registration.xml %d", error2 );
+ }
+ else if ( err == KErrPathNotFound)
+ {
+ // Create private dir
+ fs.CreatePrivatePath( EDriveC );
+
+ // Copy schema.mde
+ const TInt error2 = fileMan->Copy( KBackupRegistrationPath, backupRegistration, CFileMan::EOverWrite );
+ __LOG1( ELogAlways, "copy backup_registration.xml %d", error2 );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); //fileman, fs
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup=CTrapCleanup::New();
+ TInt result = KErrNoMemory;
+ if (cleanup)
+ {
+ TRAP(result, CMdSServer::ThreadFunctionL());
+ delete cleanup;
+ }
+ __UHEAP_MARKEND;
+ return result;
+ }
+
+// End of File
+