// Copyright (c) 2001-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:+ −
//+ −
+ −
//#define __BACKUP_LOGGING+ −
+ −
#ifdef __BACKUP_LOGGING+ −
#define _BACKUPLOG( a ) RFileLogger::WriteFormat(_L("msgs"),_L("backup.txt"),EFileLoggingModeAppend, a ); + −
#define _BACKUPLOGERR( a, b ) RFileLogger::WriteFormat(_L("msgs"),_L("backup.txt"),EFileLoggingModeAppend, a , b); + −
#else+ −
#define _BACKUPLOG( a )+ −
#define _BACKUPLOGERR( a, b )+ −
#endif+ −
+ −
#include "CMsvBackupHandler.h"+ −
#include "MSVSERV.H"+ −
#include "MSVSTD.H"+ −
#include "msvdbadapter.h"+ −
#include "msvindexadapter.h"+ −
#include <msvapi.h>+ −
#include <e32base.h>+ −
#include <e32property.h>+ −
#include <connect/sbdefs.h>+ −
+ −
#if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)+ −
_LIT(KDBFileNamePath,"\\messaging.db");+ −
#else+ −
_LIT(KDBFileNamePath,"\\private\\10281e17\\[1000484B]messaging.db");+ −
#endif+ −
+ −
CMsvBackupHandler* CMsvBackupHandler::NewL(CMsvServer& aServer)+ −
{+ −
CMsvBackupHandler* self=new (ELeave) CMsvBackupHandler(aServer);+ −
CleanupStack::PushL(self);+ −
self->ConstructL();+ −
CleanupStack::Pop(self);+ −
return(self);+ −
}+ −
+ −
CMsvBackupHandler::CMsvBackupHandler(CMsvServer& aServer) : iServer(aServer)+ −
{+ −
}+ −
+ −
CMsvBackupHandler::~CMsvBackupHandler()+ −
{+ −
_BACKUPLOG(_L("backup handler ending\r\n"));+ −
+ −
// Unregister ourselves with backup server+ −
if (iBackup)+ −
{+ −
iBackup->DeregisterFile(iFileName);+ −
delete iBackup;+ −
}+ −
}+ −
+ −
void CMsvBackupHandler::ConstructL()+ −
{+ −
_BACKUPLOG(_L("Backup handler started\r\n"))+ −
+ −
TParse parse;+ −
+ −
RFs fs;+ −
CleanupClosePushL(fs);+ −
User::LeaveIfError(fs.Connect());+ −
TPtrC driveName = TDriveUnit(MessageServer::CurrentDriveL(fs)).Name();+ −
iFileName = KDBFileNamePath;+ −
parse.Set(iFileName, &driveName, NULL);+ −
CleanupStack::PopAndDestroy(); // fs+ −
iFileName=parse.FullName();+ −
iState=EHaveLock;+ −
+ −
// Create backup session+ −
iBackup = CBaBackupSessionWrapper::NewL();+ −
+ −
// Register with the backup server+ −
iBackup->RegisterFileL(iFileName, *this);+ −
// All done+ −
_BACKUPLOGERR(_L("File Registered with Backup Server: \"%S\"\r\n"), &iFileName);+ −
}+ −
+ −
+ −
TBool CMsvBackupHandler::Locked()+ −
{+ −
if(iState==EHaveLock) + −
{+ −
return(EFalse);+ −
}+ −
else + −
{+ −
return(ETrue);+ −
}+ −
}+ −
+ −
#ifdef __BACKUP_LOGGING+ −
void CMsvBackupHandler::ChangeFileLockL(const TDesC& aFileAffected, TFileLockFlags aFlags)+ −
#else+ −
void CMsvBackupHandler::ChangeFileLockL(const TDesC& /*aFileAffected*/, TFileLockFlags aFlags)+ −
#endif+ −
{+ −
_BACKUPLOG(_L("Got backup event\r\n"))+ −
_BACKUPLOGERR(_L("File affected: \"%S\"\r\n"), &aFileAffected);+ −
+ −
switch(aFlags)+ −
{+ −
case ETakeLock: // this state gives me the lock back after it has been taken away from me.+ −
{+ −
_BACKUPLOG(_L("Take lock\r\n"))+ −
if(iState==EReleasedForBackup)+ −
{+ −
iState=EHaveLock;+ −
_BACKUPLOG(_L("from backup\r\n"))+ −
+ −
+ −
//Change error state to none+ −
iServer.Context().IndexAdapter()->SetErrorState(KErrNone);+ −
+ −
//Change State+ −
iServer.SetStartupState(EMsvNullNotification);+ −
+ −
_BACKUPLOG(_L("Reloading context\r\n"))+ −
ReloadContextL();+ −
}+ −
else if(iState==EReleasedForRestore)+ −
{+ −
// Reload context will result in this object being deleted+ −
// therefore this is no longer valid;+ −
iState=EHaveLock; + −
//reload as its a new db after restore+ −
ReloadContextL();+ −
}+ −
else+ −
{+ −
_BACKUPLOG(_L("bad state\r\n"))+ −
__ASSERT_DEBUG(EFalse,PanicServer(EMsvBackupHandlerInUnkownState));+ −
}+ −
break;+ −
}+ −
case EReleaseLockNoAccess:+ −
{+ −
// please release the lock and don't read or write to the file+ −
_BACKUPLOG(_L("release no access\r\n"))+ −
+ −
// Need to find whether this file lock release request is due to a restore happening. + −
// It is possible that the file system may need us to release our locks for some other + −
// purpose such as formatting an MMC card.+ −
TInt backupRestoreState = 0;+ −
+ −
RProperty property;+ −
TInt err = property.Get(KUidSystemCategory, conn::KUidBackupRestoreKey, backupRestoreState);+ −
property.Close();+ −
User::LeaveIfError(err);+ −
+ −
_BACKUPLOGERR(_L("backupRestoreStateValue: \"0x%08x\"\r\n"), backupRestoreState);+ −
+ −
if ((backupRestoreState & conn::EBURRestoreFull) || (backupRestoreState & conn::EBURRestorePartial))+ −
{+ −
// This means they will be restoring the file so I will+ −
// have to cope with a new index when I get the lock back.+ −
if(DetachFromFile(KMsvIndexRestore)!=EFalse)+ −
{+ −
_BACKUPLOG(_L("A genuine restore is happening\r\n"))+ −
iState=EReleasedForRestore;+ −
}+ −
}+ −
else+ −
{+ −
// Not a restore operation, so no need to reload the index when + −
// I get the lock back.+ −
// Use KMsvIndexRestore to tell the index not to write anything to disk + −
// while the file system is locked...+ −
if(DetachFromFile(KMsvIndexRestore)!=EFalse) + −
{+ −
// ...but use EReleasedForBackup here so that we don't reload the index from disk+ −
// when we get the ETakeLock notification - this would overwrite any index+ −
// changes that have happened while the file system was locked, which we want to + −
// keep if the file system was locked for any reason other than Restore.+ −
_BACKUPLOG(_L("File system detached for read and write, but not for a restore\r\n"))+ −
iState=EReleasedForBackup;+ −
}+ −
}+ −
+ −
_BACKUPLOG(_L("released for no access\r\n"))+ −
break;+ −
}+ −
case EReleaseLockReadOnly:+ −
{+ −
// please release the lock and don't write to the file, I won't read+ −
// or write but I also assume the file is being backed up and therefore+ −
// the same index will be there when I have finished.+ −
_BACKUPLOG(_L("release no read only\r\n"))+ −
if(DetachFromFile(KMsvIndexBackup)!=EFalse)+ −
{+ −
iState=EReleasedForBackup;+ −
}+ −
_BACKUPLOG(_L("released for read only\r\n"))+ −
break;+ −
}+ −
default:+ −
{+ −
_BACKUPLOG(_L("bad event\r\n"))+ −
__ASSERT_DEBUG(EFalse,PanicServer(EMsvBackupObserverGotUnknownEvent));+ −
break;+ −
}+ −
}+ −
};+ −
+ −
+ −
TBool CMsvBackupHandler::DetachFromFile(TInt aErrorState)+ −
{+ −
// if the context is currently in an error state don't do anything,+ −
// the current implications of this are that when the disk is removed+ −
// or the wrong disk is in the drive and we are asked to release a lock+ −
// on the file we won't.+ −
_BACKUPLOG(_L("detach to file\r\n"))+ −
+ −
TInt error = KErrNone;+ −
error = iServer.Context().IndexAdapter()->ErrorState();+ −
+ −
if(error == KErrNone)+ −
{+ −
_BACKUPLOG(_L("context good for closing\r\n"))+ −
_BACKUPLOG(_L("closing\r\n"))+ −
+ −
#if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)+ −
TUint currDriveIndex = CMsvPreferredDriveList::GetDriveList()->CurrentDriveIndex();+ −
TDriveNumber currDriveNum = CMsvPreferredDriveList::GetDriveList()->CurrentDriveNumber();+ −
+ −
// Flush Cache. This will also detach the DB.+ −
TRAP(error, iServer.Context().IndexAdapter()->RemoveDriveL(KCurrentDriveId, currDriveIndex, EFalse));+ −
if(error)+ −
return(EFalse);+ −
// current drive is detached from DB, so cannot access any entries from Database, so will+ −
// assing iDbAdpter pointer to temporary iTempDbAdapter pointer and assin NULL to iDbAdpter.+ −
iServer.Context().IndexAdapter()->BackupDbAdpter();+ −
TRAP(error, CMsvPreferredDriveList::GetDriveList()->UpdateDriveIdL(currDriveIndex, KCurrentDriveId));+ −
if(error)+ −
return(EFalse);+ −
#else+ −
iEntry.iSize = iServer.Context().IndexAdapter()->GetDbAdapter()->Size();+ −
iServer.Context().IndexAdapter()->DeleteDbAdapter();+ −
#endif // #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)+ −
+ −
_BACKUPLOG(_L("closed\r\n"))+ −
+ −
iServer.Context().IndexAdapter()->SetErrorState(aErrorState); + −
iServer.SetStartupState(EMsvMediaUnavailable);+ −
return(ETrue);+ −
}+ −
else+ −
{+ −
return(EFalse);+ −
}+ −
}+ −
+ −
+ −
+ −
// CreateIndexL will result in this object being deleted+ −
// so this is no longer valid+ −
void CMsvBackupHandler::ReloadContextL()+ −
{+ −
#if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)+ −
// for attaching current drive to main Database, assign iDbAdpter with iTempDbAdapter.+ −
iServer.Context().IndexAdapter()->RestoreDbAdpter();+ −
iServer.Context().IndexAdapter()->ReloadCacheL();+ −
#else+ −
iServer.CreateIndexL(ETrue);+ −
#endif+ −
}+ −
+ −