sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include "srvres.h"
sl@0: #include "cachemgr.h"
sl@0: #include "obsrvr_noc.h"
sl@0: #include <bautils.h> // BaflUtils::GetSystemDrive
sl@0: #ifdef SYMBIAN_BAFL_SYSUTIL
sl@0: #include <bafl/sysutil.h>
sl@0: #endif
sl@0: RFs TServerResources::iFs;
sl@0: 
sl@0: HBufC* TServerResources::iRomDirectory;
sl@0: HBufC* TServerResources::iDataDirectory;
sl@0: HBufC* TServerResources::iInstallDirectory;
sl@0: HBufC* TServerResources::iBURDirectory;
sl@0: 
sl@0: 
sl@0: HBufC* TServerResources::iIniExt;
sl@0: HBufC* TServerResources::iCreExt;
sl@0: HBufC* TServerResources::iTrnsExt;
sl@0: 
sl@0: TUint8 TServerResources::iPersistsVersion;
sl@0: 
sl@0: RArray<TOwnerIdMapping> TServerResources::iOwnerIdLookUpTable;
sl@0: 
sl@0: CRepositoryCacheManager* TServerResources::iCacheManager;
sl@0: CObservable* TServerResources::iObserver;
sl@0: 
sl@0: 
sl@0: #ifdef __CENTREP_SERVER_PERFTEST__
sl@0: TCentRepPerfTest TServerResources::iPerfTestMgr;
sl@0: #endif
sl@0: #ifdef __CENTREP_SERVER_MEMTEST__
sl@0: TInt32 TServerResources::iMemTestData[KMemBufMaxEntry];
sl@0: TInt32 TServerResources::iMemTestDataCount = 0;
sl@0: #endif //__CENTREP_SERVER_MEMTEST__
sl@0: 
sl@0: TTime TServerResources::CentrepFileTimeStampL(TUid aUid, TCentRepLocation aLocation)
sl@0: 	{
sl@0: 	TEntry entry;
sl@0: 	HBufC* fileName(NULL);
sl@0: 	TServerResources::CreateRepositoryFileNameLC(fileName,aUid,aLocation,ECre);
sl@0: 	TInt err=TServerResources::iFs.Entry(fileName->Des(), entry);
sl@0:    	CleanupStack::PopAndDestroy(fileName);
sl@0: 
sl@0: 	if(err==KErrNone)
sl@0: 		{
sl@0: 		return entry.iModified;
sl@0: 		}
sl@0: 		
sl@0: 	TServerResources::CreateRepositoryFileNameLC(fileName,aUid,aLocation,EIni);
sl@0: 	User::LeaveIfError(TServerResources::iFs.Entry(fileName->Des(), entry));
sl@0:    	CleanupStack::PopAndDestroy(fileName);
sl@0:    			   					  
sl@0: 	return entry.iModified;
sl@0: 	}
sl@0: 	
sl@0: TBool TServerResources::CentrepFileExistsL(TUid aUid, TCentRepLocation aLocation, TCentRepFileType aType)
sl@0: 	{
sl@0: 	HBufC* fileName(NULL);
sl@0: 	TServerResources::CreateRepositoryFileNameLC(fileName,aUid,aLocation,aType);
sl@0: 	TEntry entry;
sl@0: 	TInt err=TServerResources::iFs.Entry(fileName->Des(), entry);
sl@0:    	CleanupStack::PopAndDestroy(fileName);		   					  
sl@0:  	
sl@0:  	TBool r=EFalse;
sl@0:  	
sl@0:  	if(err==KErrNone)
sl@0:  		{
sl@0:  		r=ETrue;
sl@0:  		}
sl@0:  	else if(err==KErrNotFound)
sl@0:  		{
sl@0:  		r=EFalse;
sl@0:  		}
sl@0:  	// Looking for a file on a composite file system may return KErrPathNotFound when 
sl@0:  	// the ROM file doesn't exist, so check for this return code as well.
sl@0:  	else if((aLocation==ERom) && (err== KErrPathNotFound))
sl@0:   		{
sl@0:  		r=EFalse;
sl@0:  		}
sl@0:  	else
sl@0:  		{
sl@0:  		User::Leave(err);
sl@0:  		}
sl@0:  #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
sl@0:  	//only for ROM we still have to consider for multiple ROFS presence	
sl@0: 	if (aLocation==ERom && r==EFalse)
sl@0: 		{
sl@0: 		//if not still have to check for multi rofs, it might be the case that first file is already mangled
sl@0: 		TMultiRofsList find(aUid);
sl@0: 		TLinearOrder<TMultiRofsList> sort_order(CObservable::CompareUid);		
sl@0: 					
sl@0: 		TInt index=iObserver->GetMultiRofsList().FindInOrder(find,sort_order);		
sl@0: 		if (index!=KErrNotFound)	
sl@0: 			r=ETrue;
sl@0: 		}
sl@0: #endif		
sl@0:   	return r;	 
sl@0: 	}
sl@0: 
sl@0: TBool TServerResources::CentrepFileExistsL(TUid aUid, TCentRepLocation aLocation)
sl@0: 	{
sl@0: 	return( CentrepFileExistsL( aUid, aLocation, EIni) || CentrepFileExistsL( aUid, aLocation, ECre));
sl@0: 	}
sl@0: 	
sl@0: TBool TServerResources::InstallFileExistsL(TUid aUid)
sl@0: 	{
sl@0: 	return CentrepFileExistsL(aUid, EInstall);
sl@0: 	}
sl@0: 
sl@0: TBool TServerResources::RomFileExistsL(TUid aUid)
sl@0: 	{
sl@0: 	return CentrepFileExistsL(aUid, ERom);
sl@0: 	}
sl@0: 	
sl@0: TBool TServerResources::PersistsFileExistsL(TUid aUid)
sl@0: 	{
sl@0: 	return CentrepFileExistsL(aUid, EPersists);
sl@0: 	}	
sl@0: 
sl@0: #ifdef SYMBIAN_BAFL_SYSUTIL
sl@0: TInt TServerResources::GetTextFromFile( const TDesC& aFilename, TDes8& aValue)
sl@0:     {
sl@0: 
sl@0:     TInt err = KErrNone;
sl@0:     RFile file;
sl@0:     err = file.Open( iFs, aFilename,
sl@0:                      EFileRead | EFileStreamText | EFileShareReadersOnly );
sl@0:     if (err != KErrNone)
sl@0:         {
sl@0:         return err;
sl@0:         }
sl@0: 
sl@0:     err = file.Read(aValue);
sl@0:     
sl@0:     file.Close();
sl@0: 
sl@0:     return err;
sl@0:     }
sl@0: #endif		
sl@0: void TServerResources::DeleteCentrepFileL(TUid aUid, TCentRepLocation aLocation, TCentRepFileType aType)
sl@0: 	{
sl@0: 	HBufC* fileName(NULL);
sl@0: 	TServerResources::CreateRepositoryFileNameLC(fileName,aUid,aLocation,aType);
sl@0: 	if(CentrepFileExistsL( aUid, aLocation, aType))	
sl@0: 		{
sl@0: 		User::LeaveIfError(TServerResources::iFs.Delete(fileName->Des()));
sl@0: 		}
sl@0: 	CleanupStack::PopAndDestroy(fileName);	 
sl@0: 	}	
sl@0: 
sl@0: void TServerResources::CreateRepositoryFileNameLC(HBufC*& aFullFileName,
sl@0: 												  TUid aUid,
sl@0:                                                   TCentRepLocation aLocation,
sl@0:                                                   TCentRepFileType aFileType)
sl@0:     {
sl@0: 	TServerResources::CreateRepositoryFileNameL(aFullFileName,aUid,aLocation,aFileType);
sl@0: 	CleanupStack::PushL(aFullFileName);
sl@0:     }
sl@0: /**
sl@0: Generic routine for creating a full repository file name.
sl@0: aFullFileName is created on the heap and it is caller responsibility
sl@0: to delete it. 
sl@0: */
sl@0: void TServerResources::CreateRepositoryFileNameL(HBufC*& aFullFileName,
sl@0: 												  TUid aUid,
sl@0:                                                   TCentRepLocation aLocation,
sl@0:                                                   TCentRepFileType aFileType)
sl@0:     {
sl@0:     const TInt KExtLen = 4;
sl@0:     const TInt KDirLen = 40;
sl@0:     const TInt KUidLen = 8;
sl@0: 
sl@0:     TBuf<KDirLen> directory;
sl@0:     TBuf<KExtLen> ext;
sl@0: 
sl@0: 	//path
sl@0: 	switch (aLocation)
sl@0: 	    {
sl@0: 	    case EPersists:
sl@0: 	        {
sl@0: 	        directory.Copy(iDataDirectory->Des());
sl@0: 	        }
sl@0: 	    	break;
sl@0: 	    case EInstall:
sl@0: 	        {
sl@0: 	        directory.Copy(iInstallDirectory->Des());
sl@0: 	        }
sl@0: 	    	break;
sl@0: 	    case ERom:
sl@0: 	        {
sl@0: 	        if (iRomDirectory)
sl@0: 	        	{
sl@0: 	        	directory.Copy(iRomDirectory->Des());	        	
sl@0: 	        	}
sl@0: 			else
sl@0: 				{
sl@0: 				User::Leave(KErrNotFound); //CentRep ROM directory is empty or doesn't exist at all
sl@0: 				}
sl@0: 	        }
sl@0: 	    	break;
sl@0: 	    default:
sl@0: 	        User::Leave(KErrNotFound); //should never get here
sl@0: 	    }
sl@0: 	    
sl@0:     //file name	    
sl@0: 	TBuf<KUidLen> name;
sl@0: 	name.NumFixedWidth(aUid.iUid, EHex, KUidLen);
sl@0: 
sl@0: 	//extension
sl@0:     switch (aFileType)
sl@0:         {
sl@0:         case ECre:
sl@0:             {
sl@0:             ext.Copy(iCreExt->Des());
sl@0:             }
sl@0:             break;
sl@0:         case EIni:
sl@0:             {
sl@0:             ext.Copy(iIniExt->Des());
sl@0:             }
sl@0:             break;
sl@0:         case ETmp:
sl@0: 	    	{
sl@0: 	    	ext.Copy(iTrnsExt->Des());
sl@0: 	    	}
sl@0: 	    	break;
sl@0:         default:
sl@0: 	        User::Leave(KErrNotFound); //should never get here
sl@0:         }
sl@0: 
sl@0:     TBuf<KMaxFileName>  fullFileName;
sl@0:     fullFileName.Append(directory);
sl@0:     fullFileName.Append(name);
sl@0:     fullFileName.Append(ext);
sl@0:     //allocates memory on the heap. It is caller's resposibility to delete aFullFileName
sl@0:     aFullFileName = fullFileName.AllocL(); 
sl@0:     }
sl@0: 
sl@0: void TServerResources::InitialiseL()
sl@0: 	{
sl@0: #ifndef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
sl@0: 	iPersistsVersion = KPersistFormatVersion;	// Version 0 of persists
sl@0: #else
sl@0: 	iPersistsVersion = KPersistFormatSupportsIndMetaIndicator;
sl@0: #endif	
sl@0: 	User::LeaveIfError(iFs.Connect());
sl@0: 
sl@0: 	// get system drive
sl@0: 	_LIT(KDriveMask, "_:");
sl@0: 	TDriveName systemDrive(KDriveMask);
sl@0: 	systemDrive[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
sl@0: 		
sl@0: 	_LIT(KRomDrive, "z:");			// This may not always be z:
sl@0: 	_LIT(KPersistsDir, "persists\\");
sl@0: 	_LIT(KBURDir, "bur\\");
sl@0: 
sl@0: 	
sl@0: 	// File extensions
sl@0: 	
sl@0: 	_LIT(KIniFileExtension, ".txt");
sl@0: 	_LIT(KExternalizedPersistsFileExt, ".cre");
sl@0: 	_LIT(KTransactFileExt, ".tmp");
sl@0: 
sl@0: 	const TInt KMaxExtLength=4;
sl@0: 	
sl@0: 	iIniExt=HBufC::NewL(KMaxExtLength);
sl@0: 	iCreExt=HBufC::NewL(KMaxExtLength);
sl@0: 	iTrnsExt=HBufC::NewL(KMaxExtLength);
sl@0: 
sl@0: 	iIniExt->Des().Copy(KIniFileExtension);
sl@0: 	iCreExt->Des().Copy(KExternalizedPersistsFileExt);
sl@0: 	iTrnsExt->Des().Copy(KTransactFileExt);
sl@0: 	
sl@0: 	TBuf<KMaxFileName> path;
sl@0: 	User::LeaveIfError(iFs.PrivatePath(path));
sl@0: 
sl@0: 	const TInt pathLen = path.Length();
sl@0: 	
sl@0: 	//
sl@0: 	// ROM-drive cenrep directory
sl@0: 	//
sl@0: 	iRomDirectory = HBufC::NewL(KRomDrive().Length()+pathLen);
sl@0: 	TPtr ptr(iRomDirectory->Des());
sl@0: 	ptr.Append(KRomDrive);
sl@0: 	ptr.Append(path);
sl@0: 	// If the ROM directory does not exist (very unlikely) we set iRomDirectory to zero.
sl@0: 	TEntry fsEntry;
sl@0: 	if(iFs.Entry(*iRomDirectory, fsEntry)!=KErrNone || !fsEntry.IsDir())
sl@0: 		{
sl@0: 		delete iRomDirectory;
sl@0: 		iRomDirectory = NULL;
sl@0: 		}
sl@0: 
sl@0: 	//
sl@0: 	// Cenrep install directory
sl@0: 	//
sl@0: 	iInstallDirectory = HBufC::NewL(systemDrive.Length()+pathLen);
sl@0: 	ptr.Set(iInstallDirectory->Des());
sl@0: 	ptr.Append(systemDrive);
sl@0: 	ptr.Append(path);
sl@0: 	TInt r = iFs.MkDirAll(*iInstallDirectory);
sl@0: 	if(r!=KErrNone && r!=KErrAlreadyExists)
sl@0: 		{
sl@0: 		User::Leave(r);		
sl@0: 		}
sl@0: 	//
sl@0: 	// Writeable-drive data directory
sl@0: 	//
sl@0: 
sl@0: 	iDataDirectory = HBufC::NewL(systemDrive.Length()+pathLen+KPersistsDir().Length());
sl@0: 	ptr.Set(iDataDirectory->Des());
sl@0: 	ptr.Append(systemDrive);
sl@0: 	ptr.Append(path);
sl@0: 	ptr.Append(KPersistsDir);
sl@0: 	
sl@0: 	r = iFs.MkDirAll(*iDataDirectory);
sl@0: 	if(r!=KErrNone && r!=KErrAlreadyExists)
sl@0: 		User::Leave(r);
sl@0: 
sl@0: 	//
sl@0: 	// Writeable-drive backup/restore directory
sl@0: 	//
sl@0: 	iBURDirectory = HBufC::NewL(systemDrive.Length()+pathLen+KBURDir().Length());
sl@0: 	ptr.Set(iBURDirectory->Des());
sl@0: 	ptr.Append(systemDrive);
sl@0: 	ptr.Append(path);
sl@0: 	ptr.Append(KBURDir);
sl@0: 	
sl@0: 	r = iFs.MkDirAll(*iBURDirectory);
sl@0: 	if(r!=KErrNone && r!=KErrAlreadyExists)
sl@0: 		User::Leave(r);
sl@0: 
sl@0: #ifdef SYMBIAN_BAFL_SYSUTIL	
sl@0: 	//
sl@0: 	// romversion directory
sl@0: 	//
sl@0: 	_LIT(KRomCache,"romversion\\");
sl@0: 	HBufC* romVersionDir = HBufC::NewLC(systemDrive.Length()+pathLen+KRomCache().Length());
sl@0: 	
sl@0: 	ptr.Set(romVersionDir->Des());
sl@0: 	ptr.Append(systemDrive);
sl@0: 	ptr.Append(path);
sl@0: 	ptr.Append(KRomCache);
sl@0: 	
sl@0: 	r = iFs.MkDirAll(*romVersionDir);
sl@0: 	if(r!=KErrNone && r!=KErrAlreadyExists)
sl@0: 		User::Leave(r);
sl@0: 	CleanupStack::PopAndDestroy();//romVersionDir
sl@0: #endif
sl@0: 	//
sl@0: 	// Cache Manager 
sl@0: 	//
sl@0: 	iCacheManager = CRepositoryCacheManager::NewLC(iFs);
sl@0: 	CleanupStack::Pop();
sl@0: 	
sl@0: 	// Observer
sl@0: 	iObserver = CObservable::NewLC();
sl@0: 	CleanupStack::Pop();
sl@0: 	
sl@0: 	iOwnerIdLookUpTable.Reset();
sl@0: 
sl@0: 	}
sl@0: 
sl@0: void TServerResources::Close()
sl@0: 	{
sl@0: 	delete iObserver;
sl@0: 	delete iCacheManager;
sl@0: 	delete iInstallDirectory;
sl@0: 	delete iDataDirectory;
sl@0: 	delete iRomDirectory;
sl@0: 	delete iBURDirectory;
sl@0: 	delete iIniExt;
sl@0: 	delete iCreExt;
sl@0: 	delete iTrnsExt;
sl@0: 	iFs.Close();
sl@0: 
sl@0: 	iCacheManager=NULL;
sl@0: 	iInstallDirectory=NULL;
sl@0: 	iDataDirectory=NULL;
sl@0: 	iRomDirectory=NULL;
sl@0: 	iBURDirectory=NULL;	
sl@0: 	iIniExt=NULL;	
sl@0: 	iCreExt=NULL;	
sl@0: 	iTrnsExt=NULL;	
sl@0: 	
sl@0: 	iOwnerIdLookUpTable.Close() ;
sl@0: 	}
sl@0: 	
sl@0: TInt TServerResources::GetUid(TEntry& aEntry, TUid& aUid)
sl@0: 	{
sl@0: 		const TInt KUidLen = 8;
sl@0: 		TPtrC uidPtr = aEntry.iName.Des().LeftTPtr(KUidLen);
sl@0: 		TLex  lex=uidPtr;
sl@0: 		TUint32 uidValue;
sl@0: 
sl@0: 		if (lex.Val(uidValue, EHex) == KErrNone)
sl@0: 			{
sl@0: 			aUid = TUid::Uid(uidValue);
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			return KErrNotFound;
sl@0: 			}
sl@0: 			
sl@0: 	return KErrNone;
sl@0: 	}
sl@0: 
sl@0: TInt TOwnerIdMapping::CompareUids (const TOwnerIdMapping& aOwnerIdMapping1, const TOwnerIdMapping& aOwnerIdMapping2) 
sl@0: 	{
sl@0: 	if (aOwnerIdMapping1.iRepUid < aOwnerIdMapping2.iRepUid)
sl@0: 		return -1 ;
sl@0: 	else if (aOwnerIdMapping1.iRepUid > aOwnerIdMapping2.iRepUid)
sl@0: 		return 1 ;
sl@0: 	else
sl@0: 		return 0 ;
sl@0: 	}
sl@0: 		
sl@0: 
sl@0: #ifdef __CENTREP_SERVER_MEMTEST__
sl@0: 
sl@0: void TServerResources::StopRecordTimerResult()
sl@0: 	{
sl@0: 	iMemTestDataCount = KMemBufMaxEntry;
sl@0: 	}
sl@0: 
sl@0: //aLocation: location where the memory reading is done (a method specifier)
sl@0: //aIdentifier: identifier of the memory reading (e.g. repository id, 10th reading etc)
sl@0: void TServerResources::RecordTimerResult(TMemTestLocationIdentifier aLocation, TInt32 aIdentifier)
sl@0: 	{
sl@0: 	if(iMemTestDataCount+6 > KMemBufMaxEntry)
sl@0: 		{
sl@0: 		if(iMemTestDataCount+3 <= KMemBufMaxEntry)
sl@0: 			{
sl@0: 			iMemTestData[iMemTestDataCount++] = static_cast<TInt32>(KMagicMemTestOutOfBounds);
sl@0: 			iMemTestData[iMemTestDataCount++] = static_cast<TInt32>(KMagicMemTestOutOfBounds);
sl@0: 			iMemTestData[iMemTestDataCount++] = static_cast<TInt32>(KMagicMemTestOutOfBounds);
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		RHeap& heap = User::Heap();
sl@0: 		TInt biggestBlock;
sl@0: 		
sl@0: 		iMemTestData[iMemTestDataCount++] = aLocation;
sl@0: 		iMemTestData[iMemTestDataCount++] = aIdentifier;
sl@0: 		iMemTestData[iMemTestDataCount++] = static_cast<TInt32>(heap.Size() - heap.Available(biggestBlock));
sl@0: 		}
sl@0: 	}
sl@0: 	
sl@0: void TServerResources::StartRecordTimerResult()
sl@0: 	{
sl@0: 	iMemTestDataCount = 0;
sl@0: 	}
sl@0: 	
sl@0: #endif //__CENTREP_SERVER_MEMTEST__