messagingfw/msgsrvnstore/server/src/CMsvBackupHandler.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 //#define __BACKUP_LOGGING
       
    17 
       
    18 #ifdef __BACKUP_LOGGING
       
    19 	#define _BACKUPLOG( a ) RFileLogger::WriteFormat(_L("msgs"),_L("backup.txt"),EFileLoggingModeAppend, a );	
       
    20 	#define _BACKUPLOGERR( a, b ) RFileLogger::WriteFormat(_L("msgs"),_L("backup.txt"),EFileLoggingModeAppend, a , b);	
       
    21 #else
       
    22 	#define _BACKUPLOG( a )
       
    23 	#define _BACKUPLOGERR( a, b )
       
    24 #endif
       
    25 
       
    26 #include "CMsvBackupHandler.h"
       
    27 #include "MSVSERV.H"
       
    28 #include "MSVSTD.H"
       
    29 #include "msvdbadapter.h"
       
    30 #include "msvindexadapter.h"
       
    31 #include <msvapi.h>
       
    32 #include <e32base.h>
       
    33 #include <e32property.h>
       
    34 #include <connect/sbdefs.h>
       
    35 
       
    36 #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
       
    37 _LIT(KDBFileNamePath,"\\messaging.db");
       
    38 #else
       
    39 _LIT(KDBFileNamePath,"\\private\\10281e17\\[1000484B]messaging.db");
       
    40 #endif
       
    41 
       
    42 CMsvBackupHandler* CMsvBackupHandler::NewL(CMsvServer& aServer)
       
    43 	{
       
    44 	CMsvBackupHandler* self=new (ELeave) CMsvBackupHandler(aServer);
       
    45 	CleanupStack::PushL(self);
       
    46 	self->ConstructL();
       
    47 	CleanupStack::Pop(self);
       
    48 	return(self);
       
    49 	}
       
    50 
       
    51 CMsvBackupHandler::CMsvBackupHandler(CMsvServer& aServer) : iServer(aServer)
       
    52 	{
       
    53 	}
       
    54 
       
    55 CMsvBackupHandler::~CMsvBackupHandler()
       
    56 	{
       
    57 	_BACKUPLOG(_L("backup handler ending\r\n"));
       
    58 
       
    59 	// Unregister ourselves with backup server
       
    60 	if (iBackup)
       
    61 		{
       
    62 		iBackup->DeregisterFile(iFileName);
       
    63 		delete iBackup;
       
    64 		}
       
    65 	}
       
    66 
       
    67 void CMsvBackupHandler::ConstructL()
       
    68 	{
       
    69 	_BACKUPLOG(_L("Backup handler started\r\n"))
       
    70 
       
    71 	TParse parse;
       
    72 
       
    73 	RFs fs;
       
    74 	CleanupClosePushL(fs);
       
    75 	User::LeaveIfError(fs.Connect());
       
    76 	TPtrC driveName = TDriveUnit(MessageServer::CurrentDriveL(fs)).Name();
       
    77 	iFileName = KDBFileNamePath;
       
    78 	parse.Set(iFileName, &driveName, NULL);
       
    79 	CleanupStack::PopAndDestroy();		// fs
       
    80 	iFileName=parse.FullName();
       
    81 	iState=EHaveLock;
       
    82 
       
    83 	// Create backup session
       
    84 	iBackup = CBaBackupSessionWrapper::NewL();
       
    85 	
       
    86 	// Register with the backup server
       
    87 	iBackup->RegisterFileL(iFileName, *this);
       
    88 	// All done
       
    89 	_BACKUPLOGERR(_L("File Registered with Backup Server: \"%S\"\r\n"), &iFileName);
       
    90 	}
       
    91 
       
    92 
       
    93 TBool CMsvBackupHandler::Locked()
       
    94 	{
       
    95 	if(iState==EHaveLock) 
       
    96 		{
       
    97 		return(EFalse);
       
    98 		}
       
    99 	else 
       
   100 		{
       
   101 		return(ETrue);
       
   102 		}
       
   103 	}
       
   104 
       
   105 #ifdef __BACKUP_LOGGING
       
   106 void CMsvBackupHandler::ChangeFileLockL(const TDesC& aFileAffected, TFileLockFlags aFlags)
       
   107 #else
       
   108 void CMsvBackupHandler::ChangeFileLockL(const TDesC& /*aFileAffected*/, TFileLockFlags aFlags)
       
   109 #endif
       
   110 	{
       
   111 	_BACKUPLOG(_L("Got backup event\r\n"))
       
   112 	_BACKUPLOGERR(_L("File affected: \"%S\"\r\n"), &aFileAffected);
       
   113 	
       
   114 	switch(aFlags)
       
   115 		{
       
   116 		case ETakeLock: // this state gives me the lock back after it has been taken away from me.
       
   117 			{
       
   118 			_BACKUPLOG(_L("Take lock\r\n"))
       
   119 			if(iState==EReleasedForBackup)
       
   120 				{
       
   121 				iState=EHaveLock;
       
   122 				_BACKUPLOG(_L("from backup\r\n"))
       
   123 
       
   124 
       
   125 				//Change error state to none
       
   126 				iServer.Context().IndexAdapter()->SetErrorState(KErrNone);
       
   127 				
       
   128 				//Change State
       
   129 				iServer.SetStartupState(EMsvNullNotification);
       
   130 
       
   131 				_BACKUPLOG(_L("Reloading context\r\n"))
       
   132 				ReloadContextL();
       
   133 				}
       
   134 			else if(iState==EReleasedForRestore)
       
   135 				{
       
   136 				// Reload context will result in this object being deleted
       
   137 				// therefore this is no longer valid;
       
   138 				iState=EHaveLock;							
       
   139 				//reload as its a new db after restore
       
   140 				ReloadContextL();
       
   141 				}
       
   142 			else
       
   143 				{
       
   144 				_BACKUPLOG(_L("bad state\r\n"))
       
   145 				__ASSERT_DEBUG(EFalse,PanicServer(EMsvBackupHandlerInUnkownState));
       
   146 				}
       
   147 			break;
       
   148 			}
       
   149 		case EReleaseLockNoAccess:
       
   150 			{
       
   151 			// please release the lock and don't read or write to the file
       
   152 			_BACKUPLOG(_L("release no access\r\n"))
       
   153 		
       
   154 			// Need to find whether this file lock release request is due to a restore happening.  
       
   155 			// It is possible that the file system may need us to release our locks for some other 
       
   156 			// purpose such as formatting an MMC card.
       
   157 			TInt backupRestoreState = 0;
       
   158 			
       
   159 			RProperty property;
       
   160 			TInt err = property.Get(KUidSystemCategory, conn::KUidBackupRestoreKey, backupRestoreState);
       
   161 			property.Close();
       
   162 			User::LeaveIfError(err);
       
   163 			
       
   164 			_BACKUPLOGERR(_L("backupRestoreStateValue: \"0x%08x\"\r\n"), backupRestoreState);
       
   165 
       
   166 			if ((backupRestoreState & conn::EBURRestoreFull) || (backupRestoreState & conn::EBURRestorePartial))
       
   167 				{
       
   168 				// This means they will be restoring the file so I will
       
   169 				// have to cope with a new index when I get the lock back.
       
   170 				if(DetachFromFile(KMsvIndexRestore)!=EFalse)
       
   171 					{
       
   172 					_BACKUPLOG(_L("A genuine restore is happening\r\n"))
       
   173 					iState=EReleasedForRestore;
       
   174 					}
       
   175 				}
       
   176 			else
       
   177 				{
       
   178 				// Not a restore operation, so no need to reload the index when 
       
   179 				// I get the lock back.
       
   180 				// Use KMsvIndexRestore to tell the index not to write anything to disk 
       
   181 				// while the file system is locked...
       
   182 				if(DetachFromFile(KMsvIndexRestore)!=EFalse) 
       
   183 					{
       
   184 					// ...but use EReleasedForBackup here so that we don't reload the index from disk
       
   185 					// when we get the ETakeLock notification - this would overwrite any index
       
   186 					// changes that have happened while the file system was locked, which we want to 
       
   187 					// keep if the file system was locked for any reason other than Restore.
       
   188 					_BACKUPLOG(_L("File system detached for read and write, but not for a restore\r\n"))
       
   189 					iState=EReleasedForBackup;
       
   190 					}
       
   191 				}
       
   192 
       
   193 			_BACKUPLOG(_L("released for no access\r\n"))
       
   194 			break;
       
   195 			}
       
   196 		case EReleaseLockReadOnly:
       
   197 			{
       
   198 			// please release the lock and don't write to the file, I won't read
       
   199 			// or write but I also assume the file is being backed up and therefore
       
   200 			// the same index will be there when I have finished.
       
   201 			_BACKUPLOG(_L("release no read only\r\n"))
       
   202 			if(DetachFromFile(KMsvIndexBackup)!=EFalse)
       
   203 				{
       
   204 				iState=EReleasedForBackup;
       
   205 				}
       
   206 			_BACKUPLOG(_L("released for read only\r\n"))
       
   207 			break;
       
   208 			}
       
   209 		default:
       
   210 			{
       
   211 			_BACKUPLOG(_L("bad event\r\n"))
       
   212 			__ASSERT_DEBUG(EFalse,PanicServer(EMsvBackupObserverGotUnknownEvent));
       
   213 			break;
       
   214 			}
       
   215 		}
       
   216 	};
       
   217 
       
   218 
       
   219 TBool CMsvBackupHandler::DetachFromFile(TInt aErrorState)
       
   220 	{
       
   221 	// if the context is currently in an error state don't do anything,
       
   222 	// the current implications of this are that when the disk is removed
       
   223 	// or the wrong disk is in the drive and we are asked to release a lock
       
   224 	// on the file we won't.
       
   225 	_BACKUPLOG(_L("detach to file\r\n"))
       
   226 	
       
   227 	TInt error = KErrNone;
       
   228 	error = iServer.Context().IndexAdapter()->ErrorState();
       
   229 	
       
   230 	if(error == KErrNone)
       
   231 		{
       
   232 		_BACKUPLOG(_L("context good for closing\r\n"))
       
   233 		_BACKUPLOG(_L("closing\r\n"))
       
   234 		
       
   235 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   236 		TUint currDriveIndex = CMsvPreferredDriveList::GetDriveList()->CurrentDriveIndex();
       
   237 		TDriveNumber currDriveNum = CMsvPreferredDriveList::GetDriveList()->CurrentDriveNumber();
       
   238 			
       
   239 		// Flush Cache. This will also detach the DB.
       
   240 		TRAP(error, iServer.Context().IndexAdapter()->RemoveDriveL(KCurrentDriveId, currDriveIndex, EFalse));
       
   241 		if(error)
       
   242 			return(EFalse);
       
   243 		// current drive is detached from DB, so cannot access any entries from Database, so will
       
   244 		// assing iDbAdpter pointer to temporary iTempDbAdapter pointer and assin NULL to iDbAdpter.
       
   245 		iServer.Context().IndexAdapter()->BackupDbAdpter();
       
   246 		TRAP(error, CMsvPreferredDriveList::GetDriveList()->UpdateDriveIdL(currDriveIndex, KCurrentDriveId));
       
   247 		if(error)
       
   248 			return(EFalse);
       
   249 #else
       
   250 		iEntry.iSize = 	iServer.Context().IndexAdapter()->GetDbAdapter()->Size();
       
   251 		iServer.Context().IndexAdapter()->DeleteDbAdapter();
       
   252 #endif		// #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   253 		
       
   254 		_BACKUPLOG(_L("closed\r\n"))
       
   255 
       
   256 		iServer.Context().IndexAdapter()->SetErrorState(aErrorState);	
       
   257 		iServer.SetStartupState(EMsvMediaUnavailable);
       
   258 		return(ETrue);
       
   259 		}
       
   260 	else
       
   261 		{
       
   262 		return(EFalse);
       
   263 		}
       
   264 	}
       
   265 
       
   266 
       
   267 
       
   268 // CreateIndexL will result in this object being deleted
       
   269 // so this is no longer valid
       
   270 void CMsvBackupHandler::ReloadContextL()
       
   271 	{
       
   272 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   273 	// for attaching current drive to main Database, assign iDbAdpter with iTempDbAdapter.
       
   274 	iServer.Context().IndexAdapter()->RestoreDbAdpter();
       
   275 	iServer.Context().IndexAdapter()->ReloadCacheL();
       
   276 #else
       
   277 	iServer.CreateIndexL(ETrue);
       
   278 #endif
       
   279 	}
       
   280