metadataengine/server/src/mdsserver.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
--- /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
+