metadataengine/server/src/mdsserver.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Metadata main server class*
       
    15 */
       
    16 
       
    17 // INCLUDE FILES
       
    18 #include "mdsserver.h"
       
    19 #include "mdscommoninternal.h"
       
    20 #include "mdsserversession.h"
       
    21 #include "mdsdbconnectionpool.h"
       
    22 #include "mdssqldbmaintenance.h"
       
    23 #include "mdssqliteconnection.h"
       
    24 #include "mdsnotifier.h"
       
    25 #include "mdsobjectlocklist.h"
       
    26 #include "mdslogger.h"
       
    27 #include "mdsmaintenanceengine.h"
       
    28 #include "mdsmanipulationengine.h"
       
    29 #include "mdsclausebuffer.h"
       
    30 #include "mdebackuprestorewatcher.h"
       
    31 #include "mdsschema.h"
       
    32 #include "mdcserializationbuffer.h"
       
    33 #include <f32file.h>
       
    34 
       
    35 __DEFINE_LOGGER
       
    36 
       
    37 const TInt64 KDiskSpaceGarbageCollectorThreshold = 1024*1024; // 1 MB
       
    38 const TInt64 KDiskFullThreshold = 1024*50; // 50 kB
       
    39 
       
    40 _LIT( KSchema, "schema.mde" );
       
    41 _LIT( KDefaultImportProfile, "defaultimportfile.mde" );
       
    42 _LIT( KBackupRegistration, "backup_registration.xml" );
       
    43 _LIT( KSchemaPath, "z:\\private\\200009F3\\schema.mde" );
       
    44 _LIT( KDefaultImportProfilePath, "z:\\private\\200009F3\\defaultimportfile.mde" );
       
    45 _LIT( KBackupRegistrationPath, "z:\\private\\200009F3\\backup_registration.xml" );
       
    46 
       
    47 // ========================= MdS POLICY ==================================
       
    48 
       
    49 const TUint KMdsRangeCount = EUnknownMdEServRqst + 1;
       
    50 
       
    51 const TInt KMdsRanges[KMdsRangeCount] = 
       
    52     {
       
    53     EShutdown,          	// shut down the session
       
    54     EAdd,					// add items
       
    55     ERemove,				// remove items
       
    56     EFind,              	// finds in sync
       
    57     EAsyncFind,         	// finds asynchronously
       
    58     EContinueAsyncFind, 	// continues existing asynchronous find, fetches next set
       
    59     ECancelFind,        	// cancels asynchronous find
       
    60     ECancelObject,      	// cancels opened object
       
    61     ECheckObject,           // get object's "base" values
       
    62     EUpdate,		      	// update items
       
    63     ERegister,          	// registers an object to be notified
       
    64     EListen,            	// listens for events for a registered profile
       
    65     EUnregister,        	// unregisters for no more notifications
       
    66     EGetData,           	// (transfers data server->client)
       
    67     EImportMetadata,    	// starts metadata importing
       
    68     EAsyncImportMetadata,	// starts asynchronous metadata importing
       
    69     EExportMetadata,		// starts metadata exporting
       
    70     EAsyncExportMetadata,	// starts asynchronous metadata exporting
       
    71     EImportSchema,      	// starts schema importing
       
    72     EAddRelationDef,		// Add relation def
       
    73     EAddEventDef,		    // Add event def
       
    74     EAddMemoryCard,
       
    75     EGetMemoryCard,
       
    76     ECheckMemoryCard,
       
    77     ESetMedia,
       
    78     EGetMedia,
       
    79     EGetPresentMedias,
       
    80     ESetFileToPresent,
       
    81     ESetFilesToPresent,
       
    82     ESetFilesToNotPresent,
       
    83     ERemoveFilesNotPresent,
       
    84     EGetSchemaVersion,
       
    85     ESetObjectToPresentByGuid, 
       
    86     ESetHarvestingPrioritizationChunk,
       
    87     EAddHarvestingPrioritizationObserver,
       
    88     ECancelHarvestingPrioritizationObserver,
       
    89     EChangePath, 
       
    90     ESetPending,
       
    91     EResetPending,
       
    92     EGetPendingCount,
       
    93     EGetPending,
       
    94     EResetDB,
       
    95     EChangeMediaId,
       
    96     EUnknownMdEServRqst     // handle for unknown requests
       
    97     };
       
    98 
       
    99 const TUint8 KMdsElementsIndex[KMdsRangeCount] = 
       
   100     {
       
   101     CPolicyServer::ECustomCheck,    // EShutdown
       
   102     CPolicyServer::ECustomCheck,    // EAdd
       
   103     CPolicyServer::ECustomCheck,    // ERemove
       
   104     CPolicyServer::ECustomCheck,    // EFind
       
   105     CPolicyServer::ECustomCheck,    // EAsyncFind
       
   106     CPolicyServer::ECustomCheck,    // EContinueAsyncFind
       
   107     CPolicyServer::ECustomCheck,    // ECancelFind
       
   108     CPolicyServer::ECustomCheck,    // ECancelObject
       
   109     CPolicyServer::ECustomCheck,    // ECheckObject
       
   110     CPolicyServer::ECustomCheck,    // EUpdate
       
   111     CPolicyServer::ECustomCheck,    // ERegister
       
   112     CPolicyServer::ECustomCheck,    // EListen
       
   113     CPolicyServer::ECustomCheck,    // EUnregister
       
   114     CPolicyServer::ECustomCheck,    // EGetData
       
   115     CPolicyServer::ECustomCheck,    // EImportMetadata
       
   116     CPolicyServer::ECustomCheck,    // EAsyncImportMetadata
       
   117     CPolicyServer::ECustomCheck,    // EExportMetadata
       
   118     CPolicyServer::ECustomCheck,    // EAsyncExportMetadata
       
   119     CPolicyServer::ECustomCheck,    // EImportSchema
       
   120     CPolicyServer::ECustomCheck,	// EAddRelationDef
       
   121     CPolicyServer::ECustomCheck,	// EAddEventDef
       
   122     CPolicyServer::ECustomCheck, 	// EAddMemoryCard
       
   123     CPolicyServer::ECustomCheck, 	// EGetMemoryCard
       
   124     CPolicyServer::ECustomCheck, 	// ECheckMemoryCard
       
   125     CPolicyServer::ECustomCheck, 	// ESetMedia
       
   126     CPolicyServer::ECustomCheck, 	// EGetMedia
       
   127     CPolicyServer::ECustomCheck, 	// EGetPresentMedias
       
   128     CPolicyServer::ECustomCheck, 	// ESetFileToPresent
       
   129     CPolicyServer::ECustomCheck, 	// ESetFilesToPresent
       
   130     CPolicyServer::ECustomCheck, 	// ESetFilesToNotPresent
       
   131     CPolicyServer::ECustomCheck, 	// ERemoveFilesNotPresent
       
   132     CPolicyServer::ECustomCheck, 	// EGetSchemaVersion
       
   133     CPolicyServer::ECustomCheck, 	// ESetObjectToPresentByGuid
       
   134     CPolicyServer::ECustomCheck, 	// ESetHarvestingPrioritizationChunk
       
   135     CPolicyServer::ECustomCheck, 	// EAddHarvestingPrioritizationObserver
       
   136     CPolicyServer::ECustomCheck, 	// ECancelHarvestingPrioritizationObserver
       
   137     CPolicyServer::ECustomCheck, 	// EChangePath
       
   138     CPolicyServer::ECustomCheck, 	// ESetPending
       
   139     CPolicyServer::ECustomCheck, 	// EResetPending
       
   140     CPolicyServer::ECustomCheck, 	// EGetPendingCount
       
   141     CPolicyServer::ECustomCheck, 	// EGetPending
       
   142     CPolicyServer::ECustomCheck, 	// EResetDB
       
   143     CPolicyServer::ECustomCheck, 	// EChangeMediaId
       
   144     CPolicyServer::ENotSupported	// EUnknownMdEServRqst
       
   145     };
       
   146 
       
   147 
       
   148 const CPolicyServer::TPolicy KMdsPolicy =
       
   149     {
       
   150     CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
       
   151     KMdsRangeCount,                   
       
   152     KMdsRanges,
       
   153     KMdsElementsIndex,
       
   154     NULL //mdsElements
       
   155     };
       
   156 
       
   157 
       
   158 CPolicyServer::TCustomResult CMdSServer::CustomSecurityCheckL(
       
   159         const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/ )
       
   160     {
       
   161     CPolicyServer::TCustomResult securityCheckResult = EFail;
       
   162     switch ( aMsg.Function() )
       
   163         {
       
   164         case EAdd:
       
   165         case ERemove:
       
   166         case ECancelObject:
       
   167         case EUpdate:
       
   168         case EImportMetadata:
       
   169         case EAsyncImportMetadata:
       
   170         case EAddRelationDef:
       
   171         case EAddEventDef:
       
   172         case EImportSchema:
       
   173         case ESetObjectToPresentByGuid:
       
   174             {
       
   175             if( aMsg.HasCapability( ECapabilityWriteDeviceData ) )
       
   176                 {
       
   177                 securityCheckResult = EPass;
       
   178                 }
       
   179             }
       
   180             break;
       
   181 
       
   182         case ERegister:
       
   183         case EListen:
       
   184         case EUnregister:
       
   185         case EFind:
       
   186         case EAsyncFind:
       
   187         case EContinueAsyncFind:
       
   188         case ECancelFind:    
       
   189         case EGetData:
       
   190         case ECheckObject:
       
   191             {
       
   192             securityCheckResult = EPass;
       
   193             }
       
   194             break;
       
   195             
       
   196         case EExportMetadata:
       
   197         case EAsyncExportMetadata:
       
   198         case EGetSchemaVersion:
       
   199             {
       
   200             if( aMsg.HasCapability( ECapabilityReadUserData ) || 
       
   201             	aMsg.HasCapability( ECapabilityReadDeviceData ) )
       
   202                 {
       
   203                 securityCheckResult = EPass;
       
   204                 }
       
   205             }
       
   206         	break;
       
   207         	
       
   208         // Only for internal MdS usage
       
   209         case EAddMemoryCard:
       
   210     	case EGetMemoryCard:
       
   211         case ECheckMemoryCard:
       
   212         case ESetMedia:
       
   213         case EGetMedia:
       
   214         case EGetPresentMedias:
       
   215     	case ESetFileToPresent:
       
   216     	case ESetFilesToPresent:
       
   217     	case ESetFilesToNotPresent:
       
   218     	case ERemoveFilesNotPresent:
       
   219     	case ESetHarvestingPrioritizationChunk:
       
   220     	case EAddHarvestingPrioritizationObserver:
       
   221     	case ECancelHarvestingPrioritizationObserver:
       
   222     	case EChangePath:
       
   223     	case EChangeMediaId:
       
   224     	case ESetPending:
       
   225     	case EResetPending:
       
   226     	case EGetPendingCount:
       
   227     	case EGetPending:
       
   228     	case EResetDB:
       
   229     		{
       
   230             if( aMsg.HasCapability( ECapabilityDiskAdmin ) )
       
   231                 {
       
   232                 securityCheckResult = EPass;
       
   233                 }
       
   234     		}
       
   235         	break;
       
   236         	
       
   237         default:
       
   238             {
       
   239             securityCheckResult = EFail;
       
   240             }
       
   241         }
       
   242 
       
   243     return securityCheckResult;
       
   244     }
       
   245 
       
   246 CPolicyServer::TCustomResult CMdSServer::CustomFailureActionL(
       
   247         const RMessage2& /*aMsg*/, TInt /*aAction*/, const TSecurityInfo& /*aMissing*/)
       
   248     {
       
   249     // Not used
       
   250     return EFail;
       
   251     }
       
   252 
       
   253 
       
   254 // ========================= MEMBER FUNCTIONS ==================================
       
   255 void CMdSServer::HandleDiskSpaceNotificationL( TDiskSpaceDirection aDiskSpaceDirection )
       
   256 	{
       
   257 	// skip db cleaning if drive's free space is over limit or
       
   258 	// backup or restore is running
       
   259 	if( MMdSDiskSpaceNotifierObserver::EMore == aDiskSpaceDirection ||
       
   260 		iBackupOrRestoreRunning )
       
   261 		{
       
   262 		return;
       
   263 		}
       
   264 
       
   265 	// delete only objects which are in "not present" state and
       
   266 	// object was not located in last (count = KMemoryCardLimit) 
       
   267 	// inserted memory cards and object doesn't have any relations
       
   268 	_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 ?);" );
       
   269 
       
   270 	const TInt KMaxLenghtForNamespaceIdsAsText = 4 * KMaxUintValueLength;
       
   271 	CMdsClauseBuffer* clause = CMdsClauseBuffer::NewLC( 
       
   272 			KMemoryCardCleanup.iTypeLength + KMaxLenghtForNamespaceIdsAsText );
       
   273 	
       
   274 	clause->BufferL().Format( KMemoryCardCleanup, 
       
   275 		KDefaultNamespaceDefId, 
       
   276 		KDefaultNamespaceDefId, 
       
   277 		KDefaultNamespaceDefId, 
       
   278 		KDefaultNamespaceDefId );
       
   279 	
       
   280 	RRowData variables;
       
   281     CleanupClosePushL( variables );
       
   282 
       
   283 	_LIT( KMemoryCardKey, "MC" );
       
   284 	const TInt KMemoryCardLimit = 1;
       
   285 	const TInt KObjectCleanupLimit = 1024;
       
   286 	
       
   287 	variables.AppendL( TColumn( EMdEObjectFlagNotPresent ) );
       
   288 	variables.AppendL( TColumn( KMemoryCardKey ) );
       
   289 	variables.AppendL( TColumn( KMemoryCardLimit ) );
       
   290 	variables.AppendL( TColumn( KObjectCleanupLimit ) );
       
   291 	
       
   292 	TInt rowCount = iDefaultDBConnection->ExecuteL( clause->ConstBufferL(), variables );
       
   293 
       
   294 	CleanupStack::PopAndDestroy( 2, clause ); // variables, clause
       
   295 	}
       
   296 
       
   297 
       
   298 void CMdSServer::HandleDiskSpaceError(TInt /*aError*/)
       
   299 	{
       
   300 	}
       
   301 
       
   302 
       
   303 CMdSServer* CMdSServer::NewL()
       
   304     {
       
   305     CMdSServer* MdSServer = CMdSServer::NewLC();
       
   306     CleanupStack::Pop( MdSServer );
       
   307     return MdSServer;
       
   308     }
       
   309 
       
   310 
       
   311 CMdSServer* CMdSServer::NewLC()
       
   312     {
       
   313     CMdSServer* MdSServer = new ( ELeave ) CMdSServer( CActive::EPriorityStandard );
       
   314     CleanupStack::PushL( MdSServer );
       
   315     MdSServer->ConstructL();
       
   316     return MdSServer;
       
   317     }
       
   318 
       
   319 
       
   320 void CMdSServer::ConstructL()
       
   321     {
       
   322     __INIT_LOGGER;
       
   323     StartL( KMdSServerName );
       
   324     __LOGLB( ELogAlways, "Server start" );
       
   325     
       
   326     CheckInitSriptL();
       
   327     
       
   328     iLockList = CMdSObjectLockList::NewL();
       
   329     CMdSSqLiteConnection* conn = CMdSSqLiteConnection::NewLC();
       
   330     iDefaultDBConnection = conn;
       
   331     MMdSDbConnectionPool::SetDefaultDB( conn );
       
   332 
       
   333     CMdSMaintenanceEngine::InitConnectionL();
       
   334     CleanupStack::Pop( conn );
       
   335 
       
   336     iNotifier = CMdSNotifier::NewL();
       
   337 
       
   338     InitializeL();
       
   339 
       
   340     iDiskSpaceGarbageCollectorNotifier = 
       
   341     	CMdSDiskSpaceNotifierAO::NewL( *this, 
       
   342     								   KDiskSpaceGarbageCollectorThreshold,
       
   343     								   KMdsSqlDbDefaultName );
       
   344     
       
   345     iDiskFullNotifier = 
       
   346     	CMdSDiskSpaceNotifierAO::NewL( *this, 
       
   347     									KDiskFullThreshold,
       
   348     									KMdsSqlDbDefaultName );
       
   349 
       
   350     // Create a backup & restore watcher and add this server as its observer.								   
       
   351     iBURWatcher = CMdEBackupRestoreWatcherAO::NewL(*this);
       
   352     
       
   353     // create shutdown observer
       
   354     iShutdownObserver = CMDSShutdownObserver::NewL( *this );
       
   355     iShutdown = EFalse;    
       
   356     }
       
   357 
       
   358 void CMdSServer::InitializeL()
       
   359     {
       
   360     iMaintenance = CMdSMaintenanceEngine::NewL();
       
   361 
       
   362     iSchema = CMdsSchema::NewL();
       
   363 
       
   364     iManipulate = CMdSManipulationEngine::NewL( *iSchema, *iNotifier, 
       
   365         *iLockList );
       
   366 
       
   367     iMaintenance->InstallL( *iManipulate, *iSchema );
       
   368     }
       
   369 
       
   370 void CMdSServer::DeInitializeL()
       
   371     {
       
   372     if ( iMaintenance )
       
   373     	{
       
   374     	delete iMaintenance;
       
   375     	iMaintenance = NULL;
       
   376     	}
       
   377     if ( iManipulate )
       
   378     	{
       
   379     	delete iManipulate;
       
   380     	iManipulate = NULL;
       
   381     	}
       
   382     if ( iSchema )
       
   383     	{
       
   384     	delete iSchema;
       
   385     	iSchema = NULL;
       
   386     	}
       
   387     }
       
   388 
       
   389 TInt CMdSServer::ResetDBL()
       
   390 	{
       
   391 	DeInitializeL();
       
   392 
       
   393 	CMdSMaintenanceEngine::DeleteDatabase();
       
   394 	CMdSMaintenanceEngine::InitConnectionL();
       
   395 	
       
   396     InitializeL();
       
   397 	return KErrNone;
       
   398 	}
       
   399 
       
   400 CMdSServer::CMdSServer( TInt aPriority ) : 
       
   401 	CPolicyServer(aPriority, KMdsPolicy), 
       
   402 	iBackupOrRestoreRunning( EFalse ),
       
   403 	iHarvestingPrioritizationSerializationBuffer( NULL )
       
   404     {
       
   405     iServerErrorStatus = KErrNone;
       
   406     }
       
   407 
       
   408 
       
   409 CMdSServer::~CMdSServer()
       
   410     {
       
   411     
       
   412     iShutdown = ETrue;
       
   413     
       
   414 	delete iBURWatcher;
       
   415 	delete iDiskSpaceGarbageCollectorNotifier;
       
   416 	delete iDiskFullNotifier;
       
   417     delete iManipulate;
       
   418     delete iSchema;
       
   419     delete iNotifier;
       
   420     delete iLockList;
       
   421     delete iMaintenance;
       
   422     delete iDefaultDBConnection;
       
   423 
       
   424     delete iHarvestingPrioritizationSerializationBuffer;
       
   425 	iHarvestingPrioritizationChunk.Close();
       
   426 	
       
   427 	delete iShutdownObserver;
       
   428 
       
   429     __LOGLB( ELogAlways, "Server stop" );
       
   430     __DESTROY_LOGGER;
       
   431     }
       
   432 
       
   433 
       
   434 CSession2* CMdSServer::NewSessionL( const TVersion& aVersion, const RMessage2& /*aMessage*/ ) const
       
   435     {
       
   436     // Check we are the right version
       
   437     if ( !User::QueryVersionSupported( TVersion( KMdSServMajorVersionNumber,
       
   438                                                  KMdSServMinorVersionNumber,
       
   439                                                  KMdSServBuildVersionNumber ),
       
   440                                        aVersion ) )
       
   441         {
       
   442         User::Leave( KErrNotSupported );
       
   443         }
       
   444 
       
   445 	if ( iShutdownObserver->UpdateInProgress() )
       
   446         {
       
   447         __LOGLB( ELogAlways, "CMdSServer::NewSessionL: iad update in progress: KErrLocked");
       
   448         User::Leave(KErrLocked);
       
   449         }
       
   450 
       
   451     if ( iServerErrorStatus != KErrNone )
       
   452         {
       
   453         // leave with the same error code that the server has
       
   454         User::Leave ( iServerErrorStatus );
       
   455         }
       
   456 
       
   457     __LOGLB( ELogAlways, "New Session" );
       
   458     // Make new session
       
   459     return CMdSServerSession::NewL( *const_cast<CMdSServer*> ( this ) );
       
   460     }
       
   461 
       
   462 
       
   463 void CMdSServer::IncrementSessions()
       
   464     {
       
   465     iSessionCount++;
       
   466     }
       
   467 
       
   468 
       
   469 void CMdSServer::DecrementSessions()
       
   470     {
       
   471     iSessionCount--;
       
   472     if ( iSessionCount <= 0 )
       
   473         {        
       
   474         if (!iShutdown)
       
   475             {
       
   476             CActiveScheduler::Stop();
       
   477             iShutdown = ETrue;
       
   478             }
       
   479         }
       
   480     }
       
   481 
       
   482 CMdsSchema& CMdSServer::Schema()
       
   483     {
       
   484     return *iSchema;
       
   485     }
       
   486 
       
   487 CMdSObjectLockList& CMdSServer::LockList()
       
   488     {
       
   489     return *iLockList;
       
   490     }
       
   491 
       
   492 CMdSNotifier& CMdSServer::Notifier()
       
   493     {
       
   494     return *iNotifier;
       
   495     }
       
   496 
       
   497 CMdSMaintenanceEngine& CMdSServer::Maintenance()
       
   498     {
       
   499     return *iMaintenance;
       
   500     }
       
   501 
       
   502 CMdSManipulationEngine& CMdSServer::Manipulate()
       
   503     {
       
   504     return *iManipulate;
       
   505     }
       
   506 
       
   507 TBool CMdSServer::DiskFull() const
       
   508 	{
       
   509 	return iDiskFullNotifier->DiskFull();
       
   510 	}
       
   511    
       
   512 TBool CMdSServer::BackupOrRestoreRunning() const
       
   513 	{
       
   514 	return iBackupOrRestoreRunning;
       
   515 	}
       
   516     
       
   517 // -----------------------------------------------------------------------------
       
   518 // CMdSServer::ShutdownNotification
       
   519 // -----------------------------------------------------------------------------
       
   520 //
       
   521 void CMdSServer::ShutdownNotification()
       
   522     {
       
   523 
       
   524     
       
   525     if (!iShutdown)
       
   526         {    
       
   527         CActiveScheduler::Stop();
       
   528         iShutdown = ETrue;
       
   529         }
       
   530     
       
   531     }
       
   532 
       
   533 // -----------------------------------------------------------------------------
       
   534 // CMdSServer::ShutdownNotification
       
   535 // -----------------------------------------------------------------------------
       
   536 //
       
   537 void CMdSServer::RestartNotification()
       
   538     {
       
   539     }
       
   540 
       
   541 
       
   542 TInt CMdSServer::SetHarvestingPrioritizationChunkL( const RMessagePtr2 aMessage, TInt aParam )
       
   543 	{
       
   544 	// if there happens to be old chunk, close it
       
   545 	iHarvestingPrioritizationChunk.Close();
       
   546 
       
   547 	TInt error = iHarvestingPrioritizationChunk.Open( aMessage, aParam, EFalse );
       
   548 
       
   549 	if( error != KErrNone )
       
   550 		{
       
   551 		return error;
       
   552 		}
       
   553 
       
   554 	if( iHarvestingPrioritizationSerializationBuffer )
       
   555 		{
       
   556 		delete iHarvestingPrioritizationSerializationBuffer;
       
   557 		iHarvestingPrioritizationSerializationBuffer = NULL;
       
   558 		}
       
   559 
       
   560 	iHarvestingPrioritizationSerializationBuffer = 
       
   561 		CMdCSerializationBuffer::NewL( 
       
   562 			iHarvestingPrioritizationChunk.Base(), 
       
   563 			iHarvestingPrioritizationChunk.Size() );
       
   564 	
       
   565 	iHarvestingPrioritizationLocked = EFalse;
       
   566 
       
   567 	return KErrNone;
       
   568 	}
       
   569 
       
   570 TInt CMdSServer::AddHarvestingPrioritizationObserver( RMessagePtr2 aMessage )
       
   571 	{
       
   572 	if( iHarvestingPrioritizationObserver.IsNull() )
       
   573 		{
       
   574 		iHarvestingPrioritizationLocked = EFalse;
       
   575 
       
   576 		iHarvestingPrioritizationObserver = aMessage;
       
   577 
       
   578 		// reserve space for harvesting prioritization URI count
       
   579 		iHarvestingPrioritizationLimit = CMdCSerializationBuffer::KRequiredSizeForTInt32;
       
   580 		iHarvestingPrioritizationUriCount = 0;
       
   581 		
       
   582 		return KErrNone;
       
   583 		}
       
   584 	else
       
   585 	    {
       
   586         RThread clientThread;
       
   587         iHarvestingPrioritizationObserver.Client( clientThread );
       
   588         TExitType exitType = clientThread.ExitType();
       
   589         clientThread.Close();
       
   590         if( EExitPending != exitType )
       
   591             {
       
   592             iHarvestingPrioritizationLocked = EFalse;
       
   593 
       
   594             iHarvestingPrioritizationObserver = aMessage;
       
   595 
       
   596             // reserve space for harvesting prioritization URI count
       
   597             iHarvestingPrioritizationLimit = CMdCSerializationBuffer::KRequiredSizeForTInt32;
       
   598             iHarvestingPrioritizationUriCount = 0;
       
   599         
       
   600             return KErrNone;
       
   601             }
       
   602 	    }
       
   603 
       
   604 	return KErrAlreadyExists;
       
   605 	}
       
   606 
       
   607 TInt CMdSServer::CancelHarvestingPrioritizationObserver()
       
   608 	{	
       
   609 	iHarvestingPrioritizationLocked = EFalse;
       
   610 
       
   611 	if( iHarvestingPrioritizationObserver.IsNull() )
       
   612 		{
       
   613 		return KErrNotFound;
       
   614 		}
       
   615 	
       
   616 	NotifyHarvestingPrioritizationObserver( KErrCancel );
       
   617 	return KErrNone;
       
   618 	}
       
   619 
       
   620 TBool CMdSServer::ReserveSpaceHarvestingPrioritizationUri( const TDesC16& aUri )
       
   621 	{
       
   622 	if( !iHarvestingPrioritizationLocked && 
       
   623 		iHarvestingPrioritizationObserver.IsNull() == EFalse && 
       
   624 		iHarvestingPrioritizationSerializationBuffer )
       
   625 		{
       
   626 		// reserve space for URI offset and URI
       
   627 		const TInt reserveSpace = 
       
   628 			CMdCSerializationBuffer::KRequiredSizeForTUint32 + 
       
   629 			CMdCSerializationBuffer::RequiredSize( aUri );
       
   630 
       
   631 		const TInt maxBufferSize = 
       
   632 			iHarvestingPrioritizationSerializationBuffer->Size();
       
   633 
       
   634 		// check if buffer has enough space for the new URI
       
   635 		if( maxBufferSize >= ( iHarvestingPrioritizationLimit + reserveSpace ) )
       
   636 			{			
       
   637 			iHarvestingPrioritizationLimit += reserveSpace;
       
   638 			iHarvestingPrioritizationUriCount++;
       
   639 			return ETrue;
       
   640 			}
       
   641 		// if buffer doesn't have enough space for the new uri, 
       
   642 		// discard current URI and all following URIs
       
   643 		else
       
   644 			{
       
   645 			iHarvestingPrioritizationLimit = maxBufferSize;
       
   646 			return EFalse;
       
   647 			}
       
   648 		}
       
   649 	return EFalse;
       
   650 	}
       
   651 
       
   652 TBool CMdSServer::StartAddingHarvestingPrioritizationUrisL()
       
   653 	{
       
   654 	if( !iHarvestingPrioritizationLocked && 
       
   655 		iHarvestingPrioritizationObserver.IsNull() == EFalse && 
       
   656 		iHarvestingPrioritizationSerializationBuffer )
       
   657 		{
       
   658 		iHarvestingPrioritizationLocked = ETrue;
       
   659 
       
   660 		// add URI count to harvesting prioritization buffer
       
   661 		iHarvestingPrioritizationSerializationBuffer->PositionL( 0 );
       
   662 		iHarvestingPrioritizationSerializationBuffer->InsertL( 
       
   663 			iHarvestingPrioritizationUriCount );
       
   664 
       
   665 		iHarvestingPrioritizationBufferUriCount = 0;
       
   666 
       
   667 		// set URI offset to position of the first URI
       
   668 		iHarvestingPrioritizationBufferUriOffset = 
       
   669 			CMdCSerializationBuffer::KRequiredSizeForTInt32 + 
       
   670 			CMdCSerializationBuffer::KRequiredSizeForTUint32 * 
       
   671 			iHarvestingPrioritizationUriCount;
       
   672 
       
   673 		return ETrue;
       
   674 		}
       
   675 
       
   676 	return EFalse;
       
   677 	}
       
   678 
       
   679 TBool CMdSServer::AddHarvestingPrioritizationUriL( TDesC16& aUri )
       
   680 	{
       
   681 	if( iHarvestingPrioritizationObserver.IsNull() == EFalse && 
       
   682 		iHarvestingPrioritizationSerializationBuffer )
       
   683 		{
       
   684 		const TUint32 offset = 
       
   685 			CMdCSerializationBuffer::KRequiredSizeForTInt32 + 
       
   686 			CMdCSerializationBuffer::KRequiredSizeForTUint32 * 
       
   687 			iHarvestingPrioritizationBufferUriCount;
       
   688 
       
   689 		iHarvestingPrioritizationSerializationBuffer->PositionL( offset );
       
   690 		iHarvestingPrioritizationSerializationBuffer->InsertL( 
       
   691 			iHarvestingPrioritizationBufferUriOffset );
       
   692 
       
   693 		// move to URI offset, insert URI and get new URI offset
       
   694 		iHarvestingPrioritizationSerializationBuffer->PositionL( 
       
   695 			iHarvestingPrioritizationBufferUriOffset );
       
   696 		iHarvestingPrioritizationBufferUriOffset = 
       
   697 			iHarvestingPrioritizationSerializationBuffer->InsertL( aUri );
       
   698 
       
   699 		iHarvestingPrioritizationBufferUriCount++;
       
   700 		
       
   701 		return ETrue;
       
   702 		}
       
   703 	return EFalse;
       
   704 	}
       
   705 
       
   706 void CMdSServer::NotifyHarvestingPrioritizationObserver( TInt aStatus ) const
       
   707 	{
       
   708 	if( !iHarvestingPrioritizationObserver.IsNull() )
       
   709 		{
       
   710 	    RThread clientThread;
       
   711 	    iHarvestingPrioritizationObserver.Client( clientThread );
       
   712 	    TExitType exitType = clientThread.ExitType();
       
   713 	    if( EExitPending == exitType )
       
   714 	        {
       
   715 	        iHarvestingPrioritizationObserver.Complete( aStatus );
       
   716 	        }
       
   717 	    clientThread.Close();
       
   718 		}
       
   719 	}
       
   720 
       
   721 TInt CMdSServer::RunError( TInt aError )
       
   722     {
       
   723     __LOG1( ELogAlways, "Server::RunError %d", aError );
       
   724 
       
   725     if ( aError == KErrBadDescriptor )
       
   726         {
       
   727         // A bad descriptor error implies a badly programmed client,
       
   728         // so panic it; otherwise report the error to the client
       
   729         PanicClient( Message(), KErrBadDescriptor );
       
   730         }
       
   731     else
       
   732         {
       
   733         Message().Complete( aError );
       
   734         }
       
   735 
       
   736     // The leave will result in an early return from CServer::RunL(), skipping
       
   737     // the call to request another message. So do that now in order to keep the
       
   738     // server running.
       
   739     ReStart();
       
   740 
       
   741     return KErrNone;    // Handled the error fully
       
   742     }
       
   743 
       
   744 
       
   745 
       
   746 void CMdSServer::PanicClient( const RMessage2& aMessage, TInt aPanic )
       
   747     {
       
   748     __LOG1( ELogAlways, "Server::PanicClient %d", aPanic );
       
   749     aMessage.Panic( KMetadataEngine, aPanic );
       
   750     }
       
   751 
       
   752 
       
   753 void CMdSServer::PanicServer( TMetadataPanic aPanic )
       
   754     {
       
   755     __LOG1( ELogAlways, "Server::PanicServer %d", aPanic );
       
   756     MMdCCommon::Panic( aPanic );
       
   757     }
       
   758 
       
   759 void CMdSServer::ThreadFunctionL()
       
   760     {
       
   761     User::LeaveIfError(User::RenameThread(KMdSServerName));
       
   762     // Construct active scheduler
       
   763     CActiveScheduler* activeScheduler = new ( ELeave ) CActiveScheduler;
       
   764     CleanupStack::PushL( activeScheduler );
       
   765 
       
   766     // Install active scheduler
       
   767     // We don't need to check whether an active scheduler is already installed
       
   768     // as this is a new thread, so there won't be one
       
   769     CActiveScheduler::Install( activeScheduler );
       
   770 
       
   771     // Construct our server
       
   772     CMdSServer::NewLC();    // Anonymous
       
   773 
       
   774     RProcess::Rendezvous(KErrNone);
       
   775 
       
   776     // Start handling requests
       
   777     CActiveScheduler::Start();
       
   778 
       
   779     CleanupStack::PopAndDestroy( 2, activeScheduler ); 
       
   780     }
       
   781 
       
   782 
       
   783 TInt CMdSServer::ThreadFunction( TAny* /*aNone*/ )
       
   784     {
       
   785     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   786     if ( !( cleanupStack ) )
       
   787         {
       
   788         PanicServer( ECreateTrapCleanup );
       
   789         }
       
   790 
       
   791     TRAPD( err, ThreadFunctionL() );
       
   792     if ( err != KErrNone )
       
   793         {
       
   794         PanicServer( ESrvCreateServer );
       
   795         }
       
   796 
       
   797     delete cleanupStack;
       
   798     cleanupStack = NULL;
       
   799 
       
   800     return KErrNone;
       
   801     }
       
   802     
       
   803 
       
   804 // Backup & restore methods
       
   805 void CMdSServer::HandleBackup()
       
   806 	{
       
   807 	iBackupOrRestoreRunning = ETrue;
       
   808 	
       
   809 	// Free resources for back up.
       
   810 	iManipulate->GarbageCollector().Pause();
       
   811 	
       
   812 	// disconnect all DB connections
       
   813 	CMdSMaintenanceEngine::CloseDatabase();
       
   814 	}
       
   815 
       
   816 void CMdSServer::HandleRestore()
       
   817 	{
       
   818 	iBackupOrRestoreRunning = ETrue;
       
   819 
       
   820 	// Free resources for restore.
       
   821 	iManipulate->GarbageCollector().Pause();
       
   822 
       
   823 	// disconnect all DB connections
       
   824 	CMdSMaintenanceEngine::CloseDatabase();
       
   825 	
       
   826 	// Currently trust that device will reboot after restore.
       
   827 	}
       
   828 
       
   829 void CMdSServer::ResumeOperation()
       
   830 	{
       
   831 	iBackupOrRestoreRunning = EFalse;
       
   832 
       
   833 	// Resume normal operation after back up.
       
   834 
       
   835 	// restore all DB connections
       
   836 	TRAPD( error, CMdSMaintenanceEngine::InitConnectionL() );
       
   837 
       
   838 	// if setting back DB connections fails 
       
   839 	// something very bad has happened during backup or restore
       
   840 	if( KErrNone != error )
       
   841 		{
       
   842 		MMdCCommon::Panic( EServerBackupOrRestore );
       
   843 		}
       
   844 
       
   845 	// Restore resources
       
   846 	iManipulate->GarbageCollector().Resume();
       
   847 	}
       
   848 
       
   849 void CMdSServer::CheckInitSriptL()
       
   850     {
       
   851     RFs fs;
       
   852     User::LeaveIfError( fs.Connect() );
       
   853     CleanupClosePushL( fs );
       
   854     
       
   855     RFileReadStream tmpFile;
       
   856     TInt err( KErrNone );
       
   857     TBuf<KMaxFileName> privatePath;
       
   858     TBuf<KMaxFileName> schema;
       
   859     TBuf<KMaxFileName> defaultImportProfile;
       
   860     TBuf<KMaxFileName> backupRegistration;
       
   861     
       
   862     fs.PrivatePath( privatePath );
       
   863     
       
   864     schema.Copy( privatePath );
       
   865     schema.Append( KSchema );
       
   866     
       
   867     defaultImportProfile.Copy( privatePath );
       
   868     defaultImportProfile.Append( KDefaultImportProfile );
       
   869     
       
   870     backupRegistration.Copy( privatePath );
       
   871     backupRegistration.Append( KBackupRegistration );
       
   872     
       
   873     CFileMan* fileMan = CFileMan::NewL( fs );
       
   874     CleanupStack::PushL( fileMan);
       
   875             
       
   876     err = tmpFile.Open( fs, schema, EFileRead | EFileShareAny );
       
   877     __LOG1( ELogAlways, "open schema.mde %d", err );
       
   878     tmpFile.Close();
       
   879     if ( err != KErrNone )
       
   880         {
       
   881         if ( err == KErrNotFound )
       
   882             {
       
   883             // Path found but not schema.mde, copy schema.m
       
   884             const TInt error = fileMan->Copy( KSchemaPath, schema, CFileMan::EOverWrite );
       
   885             __LOG1( ELogAlways, "copy schema.mde %d", error );
       
   886             }
       
   887         else if ( err == KErrPathNotFound)
       
   888             {
       
   889             // Create private dir
       
   890             fs.CreatePrivatePath( EDriveC );
       
   891             
       
   892             // Copy schema.mde
       
   893             const TInt error = fileMan->Copy( KSchemaPath, schema, CFileMan::EOverWrite );
       
   894             __LOG1( ELogAlways, "copy schema.mde %d", error );
       
   895             }    
       
   896         }
       
   897 
       
   898     err = tmpFile.Open( fs, defaultImportProfile, EFileRead | EFileShareAny );
       
   899     __LOG1( ELogAlways, "open defaultimportprofile.mde %d", err );
       
   900     tmpFile.Close();
       
   901     if ( err != KErrNone )
       
   902         {
       
   903         if ( err == KErrNotFound )
       
   904             {
       
   905             // Path found but not schema.mde, copy schema.m
       
   906             const TInt error1 = fileMan->Copy( KDefaultImportProfilePath, defaultImportProfile, CFileMan::EOverWrite );
       
   907             __LOG1( ELogAlways, "copy defaultimportprofile.mde %d", error1 );
       
   908             }
       
   909         else if ( err == KErrPathNotFound)
       
   910             {
       
   911             // Create private dir
       
   912             fs.CreatePrivatePath( EDriveC );
       
   913              
       
   914             // Copy schema.mde
       
   915             const TInt error1 = fileMan->Copy( KDefaultImportProfilePath, defaultImportProfile, CFileMan::EOverWrite );
       
   916             __LOG1( ELogAlways, "copy defaultimportprofile.mde %d", error1 );
       
   917             }    
       
   918         }    
       
   919     
       
   920     err = tmpFile.Open( fs, backupRegistration, EFileRead | EFileShareAny );
       
   921     __LOG1( ELogAlways, "open backup_registration.xml %d", err );
       
   922     tmpFile.Close();
       
   923     if ( err != KErrNone )
       
   924         {
       
   925         if ( err == KErrNotFound )
       
   926             {
       
   927             // Path found but not schema.mde, copy schema.m
       
   928             const TInt error2 = fileMan->Copy( KBackupRegistrationPath, backupRegistration, CFileMan::EOverWrite );
       
   929             __LOG1( ELogAlways, "copy backup_registration.xml %d", error2 );
       
   930             }
       
   931         else if ( err == KErrPathNotFound)
       
   932             {
       
   933             // Create private dir
       
   934             fs.CreatePrivatePath( EDriveC );
       
   935             
       
   936             // Copy schema.mde
       
   937             const TInt error2 = fileMan->Copy( KBackupRegistrationPath, backupRegistration, CFileMan::EOverWrite );
       
   938             __LOG1( ELogAlways, "copy backup_registration.xml %d", error2 );
       
   939             }    
       
   940         }   
       
   941 
       
   942     CleanupStack::PopAndDestroy( 2 ); //fileman, fs
       
   943     }
       
   944 
       
   945 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   946 
       
   947 TInt E32Main()
       
   948     {
       
   949     __UHEAP_MARK;
       
   950  	CTrapCleanup* cleanup=CTrapCleanup::New();
       
   951  	TInt result = KErrNoMemory;
       
   952  	if (cleanup)
       
   953  		{
       
   954  		TRAP(result, CMdSServer::ThreadFunctionL());
       
   955 		delete cleanup;
       
   956  		}
       
   957     __UHEAP_MARKEND;
       
   958  	return result;
       
   959     }
       
   960     
       
   961 // End of File
       
   962