| sl@0 |      1 | // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
 | 
| sl@0 |      2 | // All rights reserved.
 | 
| sl@0 |      3 | // This component and the accompanying materials are made available
 | 
| sl@0 |      4 | // under the terms of the License "Eclipse Public License v1.0"
 | 
| sl@0 |      5 | // which accompanies this distribution, and is available
 | 
| sl@0 |      6 | // at the URL "http://www.eclipse.org/legal/epl-v10.html".
 | 
| sl@0 |      7 | //
 | 
| sl@0 |      8 | // Initial Contributors:
 | 
| sl@0 |      9 | // Nokia Corporation - initial contribution.
 | 
| sl@0 |     10 | //
 | 
| sl@0 |     11 | // Contributors:
 | 
| sl@0 |     12 | //
 | 
| sl@0 |     13 | // Description:
 | 
| sl@0 |     14 | //
 | 
| sl@0 |     15 | 
 | 
| sl@0 |     16 | #include <e32std.h>
 | 
| sl@0 |     17 | #include <e32std_private.h>
 | 
| sl@0 |     18 | #include "sr_rofs.h"
 | 
| sl@0 |     19 | #include <rofs.h>
 | 
| sl@0 |     20 | #include <e32hal.h>
 | 
| sl@0 |     21 | 
 | 
| sl@0 |     22 | void CRofs::Panic( TPanic aPanic )
 | 
| sl@0 |     23 | 	{
 | 
| sl@0 |     24 | 	_LIT( KCategory, "ROFSFSY" );
 | 
| sl@0 |     25 | 	User::Panic( KCategory, aPanic );
 | 
| sl@0 |     26 | 	}
 | 
| sl@0 |     27 | 
 | 
| sl@0 |     28 | #ifdef _USE_TRUE_LRU_CACHE
 | 
| sl@0 |     29 | 
 | 
| sl@0 |     30 | 
 | 
| sl@0 |     31 | //***********************************************************
 | 
| sl@0 |     32 | //* Data Read Cache for Rofs
 | 
| sl@0 |     33 | //***********************************************************
 | 
| sl@0 |     34 | 
 | 
| sl@0 |     35 | TCacheSegment::TCacheSegment()
 | 
| sl@0 |     36 | //
 | 
| sl@0 |     37 | // Constructor
 | 
| sl@0 |     38 | //
 | 
| sl@0 |     39 | 	: iPos(-1)
 | 
| sl@0 |     40 | 	{}
 | 
| sl@0 |     41 | 
 | 
| sl@0 |     42 | void TCacheSegment::Set(TInt aPos)
 | 
| sl@0 |     43 | //
 | 
| sl@0 |     44 | // Set the diskPos of the data cached
 | 
| sl@0 |     45 | //
 | 
| sl@0 |     46 | 	{
 | 
| sl@0 |     47 | 	iPos=aPos;
 | 
| sl@0 |     48 | 	}
 | 
| sl@0 |     49 | 
 | 
| sl@0 |     50 | //***********************************************************
 | 
| sl@0 |     51 | CRofsLruCache::CRofsLruCache(CRofsMountCB* aMount, TInt64 aMediaSize)
 | 
| sl@0 |     52 | //
 | 
| sl@0 |     53 | // Least recently used data cache
 | 
| sl@0 |     54 | //
 | 
| sl@0 |     55 | 	: iQue(_FOFF(TCacheSegment,iLink)), iMediaSize(aMediaSize)
 | 
| sl@0 |     56 | 	{
 | 
| sl@0 |     57 | 	iMount=aMount;
 | 
| sl@0 |     58 | 	__PRINT(_L("CLruCache::CLruCache()"));
 | 
| sl@0 |     59 | 	}
 | 
| sl@0 |     60 | 
 | 
| sl@0 |     61 | CRofsLruCache::~CRofsLruCache()
 | 
| sl@0 |     62 | //
 | 
| sl@0 |     63 | // Free all data segments
 | 
| sl@0 |     64 | //
 | 
| sl@0 |     65 | 	{
 | 
| sl@0 |     66 | 	__PRINT(_L("CLruCache::~CLruCache()"));
 | 
| sl@0 |     67 | 
 | 
| sl@0 |     68 | 	TDblQueIter<TCacheSegment> iter(iQue);
 | 
| sl@0 |     69 | 	while((TCacheSegment*)iter)
 | 
| sl@0 |     70 | 		{
 | 
| sl@0 |     71 | 		User::Free(iter++);
 | 
| sl@0 |     72 | 		}
 | 
| sl@0 |     73 | 	}
 | 
| sl@0 |     74 | 
 | 
| sl@0 |     75 | TUint8* CRofsLruCache::Find(TInt aPos, TInt aLength)
 | 
| sl@0 |     76 | //
 | 
| sl@0 |     77 | // Find aPos in the cache or return NULL
 | 
| sl@0 |     78 | //
 | 
| sl@0 |     79 | 	{
 | 
| sl@0 |     80 | 	__PRINT(_L("CLruCache::Find()"));
 | 
| sl@0 |     81 | 
 | 
| sl@0 |     82 | 	TDblQueIter<TCacheSegment> iter(iQue);
 | 
| sl@0 |     83 | 	TCacheSegment* data;
 | 
| sl@0 |     84 | 	while((data=iter++)!=NULL)		//need to do a range check here
 | 
| sl@0 |     85 | 		{
 | 
| sl@0 |     86 | 		if(data->iPos < 0)
 | 
| sl@0 |     87 | 			continue;
 | 
| sl@0 |     88 | 		const TInt KEndOfSegment= data->iPos+ KSizeOfSegment;
 | 
| sl@0 |     89 | 		if(data->iPos <= aPos && (KEndOfSegment >=aPos))
 | 
| sl@0 |     90 | 			{
 | 
| sl@0 |     91 | 			if((aPos+aLength) > (KEndOfSegment))
 | 
| sl@0 |     92 | 				{
 | 
| sl@0 |     93 | 				data->iLink.Deque();
 | 
| sl@0 |     94 | 				iQue.AddLast(*data);
 | 
| sl@0 |     95 | 				return(NULL);
 | 
| sl@0 |     96 | 				}
 | 
| sl@0 |     97 | 			if(!iQue.IsFirst(data)) 
 | 
| sl@0 |     98 | 				{
 | 
| sl@0 |     99 | 				data->iLink.Deque(); 
 | 
| sl@0 |    100 | 				iQue.AddFirst(*data); 
 | 
| sl@0 |    101 | 				}
 | 
| sl@0 |    102 | 			return(&data->Data()[aPos-data->iPos]);
 | 
| sl@0 |    103 | 			}
 | 
| sl@0 |    104 | 		}
 | 
| sl@0 |    105 | 	// If we got here, it means that we don't have it in cache at all 
 | 
| sl@0 |    106 | 	return(NULL);
 | 
| sl@0 |    107 | 		
 | 
| sl@0 |    108 | 	}
 | 
| sl@0 |    109 | 
 | 
| sl@0 |    110 | 
 | 
| sl@0 |    111 | TUint8* CRofsLruCache::ReadL(TInt aPos, TInt aLength)
 | 
| sl@0 |    112 | //
 | 
| sl@0 |    113 | // Find aPos in the cache or read the data
 | 
| sl@0 |    114 | //
 | 
| sl@0 |    115 | 	{
 | 
| sl@0 |    116 | 	// Remember for Big size Nand the size of page can increase to 2K. Need to add this feature?
 | 
| sl@0 |    117 | 	__PRINT(_L("CLruCache::ReadL()"));
 | 
| sl@0 |    118 | 	
 | 
| sl@0 |    119 | 	
 | 
| sl@0 |    120 | 	// Search the cache 
 | 
| sl@0 |    121 | 	TUint8* res=Find(aPos, aLength);
 | 
| sl@0 |    122 | 	if (res)
 | 
| sl@0 |    123 | 		return(res); 
 | 
| sl@0 |    124 | 	
 | 
| sl@0 |    125 | 	// Didn't find in the cache, read data from media 	 
 | 
| sl@0 |    126 | 	// Align to page boundaries
 | 
| sl@0 |    127 | 	TInt pagePos = aPos & ~(KPageSize-1);
 | 
| sl@0 |    128 | 	
 | 
| sl@0 |    129 | 	// Read from media
 | 
| sl@0 |    130 | 	// Buffer to accomodate two page of data. 
 | 
| sl@0 |    131 | 	// We won't cache any read bigger than one page
 | 
| sl@0 |    132 | 	// Check if we have any segment available
 | 
| sl@0 |    133 | 	TCacheSegment* seg= iQue.Last();
 | 
| sl@0 |    134 | 	seg->iLink.Deque();
 | 
| sl@0 |    135 | 	seg->Set(pagePos);
 | 
| sl@0 |    136 | 	iQue.AddFirst(*seg);
 | 
| sl@0 |    137 | 
 | 
| sl@0 |    138 | 	// ensure we don't read past end of media
 | 
| sl@0 |    139 | 	TInt cacheLen = (TInt) Min(iMediaSize -  pagePos, KSizeOfSegment);
 | 
| sl@0 |    140 | 	TPtr8 dataBuf((seg->Data()), cacheLen);
 | 
| sl@0 |    141 | 	TInt ret = iMount->LocalDrive()->Read(pagePos,cacheLen,dataBuf);
 | 
| sl@0 |    142 | 
 | 
| sl@0 |    143 | 	if (ret!=KErrNone)
 | 
| sl@0 |    144 | 		{
 | 
| sl@0 |    145 | 		User::Leave(ret);
 | 
| sl@0 |    146 | 		}
 | 
| sl@0 |    147 | 
 | 
| sl@0 |    148 | 	return(&dataBuf[aPos & (KPageSize-1)]);
 | 
| sl@0 |    149 | 	}
 | 
| sl@0 |    150 | 
 | 
| sl@0 |    151 | CRofsLruCache* CRofsLruCache::New(TInt aSegmentSize, CRofsMountCB* aMount, TInt64 aMediaSize)
 | 
| sl@0 |    152 | //
 | 
| sl@0 |    153 | // Create an LruList and one segment
 | 
| sl@0 |    154 | //
 | 
| sl@0 |    155 | 	{
 | 
| sl@0 |    156 | 	__PRINT(_L("CRofsLruCache::New()"));
 | 
| sl@0 |    157 | 	CRofsLruCache* lru=new CRofsLruCache(aMount, aMediaSize);
 | 
| sl@0 |    158 | 	if (lru==NULL)
 | 
| sl@0 |    159 | 		return(NULL);
 | 
| sl@0 |    160 | 	for(TInt i=0; i<KSizeOfCacheInPages;i++)
 | 
| sl@0 |    161 | 		{
 | 
| sl@0 |    162 | 		TCacheSegment* seg=(TCacheSegment*)User::Alloc(aSegmentSize+sizeof(TCacheSegment));
 | 
| sl@0 |    163 | 		if (seg==NULL)
 | 
| sl@0 |    164 | 			{
 | 
| sl@0 |    165 | 			delete lru;
 | 
| sl@0 |    166 | 			return(NULL);
 | 
| sl@0 |    167 | 			}
 | 
| sl@0 |    168 | 		Mem::FillZ(seg,aSegmentSize+sizeof(TCacheSegment));
 | 
| sl@0 |    169 | 		*seg=TCacheSegment();
 | 
| sl@0 |    170 | 		lru->iQue.AddFirst(*seg);
 | 
| sl@0 |    171 | 		}
 | 
| sl@0 |    172 | 	return(lru);
 | 
| sl@0 |    173 | 	}
 | 
| sl@0 |    174 | 
 | 
| sl@0 |    175 | //***********************************************************
 | 
| sl@0 |    176 | //* Mount object
 | 
| sl@0 |    177 | //***********************************************************
 | 
| sl@0 |    178 | 
 | 
| sl@0 |    179 | 
 | 
| sl@0 |    180 | void CRofsMountCB::CacheReadL(TInt aPos, TInt aLength,const TAny* aDes,TInt anOffset, const RMessagePtr2& aMessage) const
 | 
| sl@0 |    181 | //
 | 
| sl@0 |    182 | //	Do a cached read if possible else read from media and insert to cache
 | 
| sl@0 |    183 | //
 | 
| sl@0 |    184 | 	{
 | 
| sl@0 |    185 | 
 | 
| sl@0 |    186 | 	__PRINT2(_L("CRofsMountCB::CacheReadL TAny* Pos 0x%x, Len %d"),aPos,aLength);
 | 
| sl@0 |    187 | 	// Don't cache anything more than a page long or if readinf into a file server cache buffer!
 | 
| sl@0 |    188 | 	if (((KSizeOfSegment/2) < aLength) || (aMessage.Handle() == KLocalMessageHandle))
 | 
| sl@0 |    189 | 		{
 | 
| sl@0 |    190 | 		TInt ret = LocalDrive()->Read(aPos,aLength,aDes, aMessage.Handle(), anOffset);
 | 
| sl@0 |    191 | 		if (ret!=KErrNone)
 | 
| sl@0 |    192 | 			{
 | 
| sl@0 |    193 | 			User::Leave(ret);
 | 
| sl@0 |    194 | 			}
 | 
| sl@0 |    195 | 		}
 | 
| sl@0 |    196 | 	else
 | 
| sl@0 |    197 | 		{
 | 
| sl@0 |    198 | 		TUint8* data =iDataCache->ReadL(aPos, aLength);	//added length to enable cache to fill in the blanks
 | 
| sl@0 |    199 | 		TPtrC8 buf(data,aLength);			//return buffer
 | 
| sl@0 |    200 | 		aMessage.WriteL(0,buf,anOffset);
 | 
| sl@0 |    201 | 		}
 | 
| sl@0 |    202 | 	}
 | 
| sl@0 |    203 | 
 | 
| sl@0 |    204 | #endif
 | 
| sl@0 |    205 | 
 | 
| sl@0 |    206 | CRofsMountCB::CRofsMountCB()
 | 
| sl@0 |    207 | //
 | 
| sl@0 |    208 | // Constructor
 | 
| sl@0 |    209 | //
 | 
| sl@0 |    210 | 	{
 | 
| sl@0 |    211 | 	}
 | 
| sl@0 |    212 | 
 | 
| sl@0 |    213 | void CRofsMountCB::Dismounted()
 | 
| sl@0 |    214 | //
 | 
| sl@0 |    215 | // Dummy implementation of pure virtual function
 | 
| sl@0 |    216 | //
 | 
| sl@0 |    217 | 	{}
 | 
| sl@0 |    218 | 
 | 
| sl@0 |    219 | 
 | 
| sl@0 |    220 | void CRofsMountCB::MountL(TBool /*aForceMount*/)
 | 
| sl@0 |    221 | //
 | 
| sl@0 |    222 | // Mount a media. 
 | 
| sl@0 |    223 | // Only allowed to leave with KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
 | 
| sl@0 |    224 | //
 | 
| sl@0 |    225 | 	{
 | 
| sl@0 |    226 | 
 | 
| sl@0 |    227 | 	// create the local drive
 | 
| sl@0 |    228 | 	TInt r=CreateLocalDrive(GetLocalDrive(Drive().DriveNumber()));
 | 
| sl@0 |    229 | 	User::LeaveIfError(r);
 | 
| sl@0 |    230 | 	
 | 
| sl@0 |    231 | 	iUniqueID=0;
 | 
| sl@0 |    232 | 	
 | 
| sl@0 |    233 | 	TLocalDriveCapsV2Buf caps;
 | 
| sl@0 |    234 | 	User::LeaveIfError(LocalDrive()->Caps(caps));
 | 
| sl@0 |    235 | 	iMediaSize = caps().iSize;
 | 
| sl@0 |    236 | 
 | 
| sl@0 |    237 | 	// Read ROFS image header
 | 
| sl@0 |    238 | 	r = LocalDrive()->Read( 0, sizeof(TRofsHeader), iHeader );
 | 
| sl@0 |    239 | 	__PRINT1(_L("CRofsMountCB::MountL, Reading Header %d"), r);
 | 
| sl@0 |    240 | 	if( KErrNone != r )
 | 
| sl@0 |    241 | 		{
 | 
| sl@0 |    242 | 		User::Leave( KErrNotReady );
 | 
| sl@0 |    243 | 		}
 | 
| sl@0 |    244 | 
 | 
| sl@0 |    245 | 	r = CheckHeader();
 | 
| sl@0 |    246 | 	__PRINT1(_L("CRofsMountCB::MountL, Check Header %d"), r);
 | 
| sl@0 |    247 | 	User::LeaveIfError( r );
 | 
| sl@0 |    248 | 	
 | 
| sl@0 |    249 | 	r=CheckExtension();
 | 
| sl@0 |    250 | 	__PRINT1(_L("CRofsMountCB::MountL, Check Extension %d"), r);
 | 
| sl@0 |    251 | 	if(r!=KErrNone && r!=KErrNotFound)
 | 
| sl@0 |    252 | 		User::Leave(r);
 | 
| sl@0 |    253 | 
 | 
| sl@0 |    254 | 	//
 | 
| sl@0 |    255 | 	// Construct the directory cache
 | 
| sl@0 |    256 | 	//
 | 
| sl@0 |    257 | 	iDirectoryCache = new(ELeave) CDirectoryCache( *this, *LocalDrive(), iHeader() );
 | 
| sl@0 |    258 | 	iDirectoryCache->ConstructL();
 | 
| sl@0 |    259 | 
 | 
| sl@0 |    260 | #ifdef _USE_TRUE_LRU_CACHE
 | 
| sl@0 |    261 | 	//
 | 
| sl@0 |    262 | 	// Construct the data cache
 | 
| sl@0 |    263 | 	//
 | 
| sl@0 |    264 | 	iDataCache = CRofsLruCache::New(KSizeOfSegment,this, iMediaSize);
 | 
| sl@0 |    265 | 	if(!iDataCache)
 | 
| sl@0 |    266 | 		User::Leave(KErrNoMemory);
 | 
| sl@0 |    267 | #endif
 | 
| sl@0 |    268 | 
 | 
| sl@0 |    269 | 	_LIT( KVolumeName, "Rofs" );
 | 
| sl@0 |    270 | 	SetVolumeName( TPtrC(KVolumeName).AllocL() );
 | 
| sl@0 |    271 | 	__PRINT(_L("CRofsMountCB::MountL, End of Mount"));
 | 
| sl@0 |    272 | 	}
 | 
| sl@0 |    273 | 
 | 
| sl@0 |    274 | 
 | 
| sl@0 |    275 | LOCAL_D TBool IsOverlapping( TUint aBase1, TUint aSize1, TUint aBase2, TUint aSize2 )
 | 
| sl@0 |    276 | //
 | 
| sl@0 |    277 | //	Check files and directories are not overlapping
 | 
| sl@0 |    278 | //
 | 
| sl@0 |    279 | 	{
 | 
| sl@0 |    280 | 	TUint end1 = aBase1 + aSize1 - 1;
 | 
| sl@0 |    281 | 	TUint end2 = aBase2 + aSize2 -1;
 | 
| sl@0 |    282 | 
 | 
| sl@0 |    283 | 	if( aBase1 == aBase2 || end1 < aBase1 || end2 < aBase2 )
 | 
| sl@0 |    284 | 		{
 | 
| sl@0 |    285 | 		return ETrue;	// not necessarily overlapping, but they wrap which is an error
 | 
| sl@0 |    286 | 		}
 | 
| sl@0 |    287 | 
 | 
| sl@0 |    288 | 	if( end1 < aBase2 || end2 < aBase1 )
 | 
| sl@0 |    289 | 		{
 | 
| sl@0 |    290 | 		return EFalse;
 | 
| sl@0 |    291 | 		}
 | 
| sl@0 |    292 | 
 | 
| sl@0 |    293 | 	return ETrue;
 | 
| sl@0 |    294 | 	}
 | 
| sl@0 |    295 | 
 | 
| sl@0 |    296 | TInt CRofsMountCB::CheckExtension() 
 | 
| sl@0 |    297 | //
 | 
| sl@0 |    298 | //	Check for a Rofs extension and the end of the primary rofs image
 | 
| sl@0 |    299 | //
 | 
| sl@0 |    300 | 	{
 | 
| sl@0 |    301 | 	__PRINT(_L("CRofsMountCB::CheckExtension, Looking for Extension"));
 | 
| sl@0 |    302 | 	const TUint8 KRofsHeaderId[4] = {'R', 'O', 'F', 'x' };
 | 
| sl@0 |    303 | 	const TRofsHeader& h = ((CRofsMountCB*)this)->iHeader();
 | 
| sl@0 |    304 | 
 | 
| sl@0 |    305 | 	//check there is possibly enough room to have an extension
 | 
| sl@0 |    306 | 	if( MAKE_TINT64(0,h.iMaxImageSize) + sizeof(TRofsHeader) >= iMediaSize )
 | 
| sl@0 |    307 | 		{
 | 
| sl@0 |    308 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, media size too small for extension %x"), I64LOW(iMediaSize) );
 | 
| sl@0 |    309 | 		return KErrNotFound;
 | 
| sl@0 |    310 | 		}
 | 
| sl@0 |    311 | 	
 | 
| sl@0 |    312 | 	TPckgBuf<TRofsHeader> phExt;
 | 
| sl@0 |    313 | 	TInt r = LocalDrive()->Read((TInt)h.iMaxImageSize, sizeof(TRofsHeader), phExt);
 | 
| sl@0 |    314 | 	if( KErrNone != r )
 | 
| sl@0 |    315 | 		return r;		
 | 
| sl@0 |    316 | 
 | 
| sl@0 |    317 | 	const TRofsHeader& hExt = phExt();
 | 
| sl@0 |    318 | 	if( 0 != Mem::Compare( KRofsHeaderId, 4, hExt.iIdentifier, 4 ) )
 | 
| sl@0 |    319 | 		{
 | 
| sl@0 |    320 | 		__PRINT(_L("CRofsMountCB::CheckExtension, [ROFx] ID missing"));
 | 
| sl@0 |    321 | 		return KErrNotFound;
 | 
| sl@0 |    322 | 		}
 | 
| sl@0 |    323 | 
 | 
| sl@0 |    324 | 	if( hExt.iRofsFormatVersion < KEarliestSupportedFormatVersion
 | 
| sl@0 |    325 | 		|| hExt.iRofsFormatVersion > KLatestSupportedFormatVersion )
 | 
| sl@0 |    326 | 		{
 | 
| sl@0 |    327 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, unsupported version %x"), h.iRofsFormatVersion );
 | 
| sl@0 |    328 | 		return KErrNotSupported;
 | 
| sl@0 |    329 | 		}
 | 
| sl@0 |    330 | 
 | 
| sl@0 |    331 | 	if( MAKE_TINT64(0,hExt.iImageSize) > iMediaSize )
 | 
| sl@0 |    332 | 		{
 | 
| sl@0 |    333 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, image size overflow %x"), h.iImageSize );
 | 
| sl@0 |    334 | 		return KErrCorrupt;
 | 
| sl@0 |    335 | 		}
 | 
| sl@0 |    336 | 
 | 
| sl@0 |    337 | 	if( MAKE_TINT64(0,hExt.iDirTreeOffset) > iMediaSize )
 | 
| sl@0 |    338 | 		{
 | 
| sl@0 |    339 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, dir tree offset %x out-of-range"), h.iDirTreeOffset );
 | 
| sl@0 |    340 | 		return KErrCorrupt;
 | 
| sl@0 |    341 | 		}
 | 
| sl@0 |    342 | 
 | 
| sl@0 |    343 | 	if( MAKE_TINT64(0,hExt.iDirTreeOffset) + hExt.iDirTreeSize > iMediaSize )
 | 
| sl@0 |    344 | 		{
 | 
| sl@0 |    345 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, dir tree size %x overflow"), h.iDirTreeSize );
 | 
| sl@0 |    346 | 		return KErrCorrupt;
 | 
| sl@0 |    347 | 		}
 | 
| sl@0 |    348 | 
 | 
| sl@0 |    349 | 	if( MAKE_TINT64(0,hExt.iDirFileEntriesOffset) > iMediaSize )
 | 
| sl@0 |    350 | 		{
 | 
| sl@0 |    351 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, file entries offset %x out-of-range"), h.iDirFileEntriesOffset );
 | 
| sl@0 |    352 | 		return KErrCorrupt;
 | 
| sl@0 |    353 | 		}
 | 
| sl@0 |    354 | 
 | 
| sl@0 |    355 | 	if( MAKE_TINT64(0,hExt.iDirFileEntriesOffset) + MAKE_TINT64(0,h.iDirFileEntriesSize) > iMediaSize )
 | 
| sl@0 |    356 | 		{
 | 
| sl@0 |    357 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, file entries size %x overflow"), h.iDirFileEntriesSize );
 | 
| sl@0 |    358 | 		return KErrCorrupt;
 | 
| sl@0 |    359 | 		}
 | 
| sl@0 |    360 | 
 | 
| sl@0 |    361 | 	if( IsOverlapping( hExt.iDirTreeOffset, hExt.iDirTreeSize,
 | 
| sl@0 |    362 | 		hExt.iDirFileEntriesOffset, hExt.iDirFileEntriesSize ) )
 | 
| sl@0 |    363 | 		{
 | 
| sl@0 |    364 | 		__PRINT1(_L("CRofsMountCB::CheckExtension, dir & file entries overlap"), h.iDirTreeSize );
 | 
| sl@0 |    365 | 		return KErrCorrupt;
 | 
| sl@0 |    366 | 		}
 | 
| sl@0 |    367 | 	Mem::Copy(&iHeader, &phExt, sizeof(TRofsHeader));
 | 
| sl@0 |    368 | 
 | 
| sl@0 |    369 | 	__PRINT(_L("CRofsMountCB::CheckExtension, Valid Extension found"));
 | 
| sl@0 |    370 | 	return KErrNone;
 | 
| sl@0 |    371 | 	}
 | 
| sl@0 |    372 | 
 | 
| sl@0 |    373 | TInt CRofsMountCB::CheckHeader() const
 | 
| sl@0 |    374 | //
 | 
| sl@0 |    375 | // Returns KErrNone if the TRofsHeader looks ok, KErrCorrupt if not
 | 
| sl@0 |    376 | //
 | 
| sl@0 |    377 | 	{
 | 
| sl@0 |    378 | 	const TUint8 KRofsHeaderId[4] = {'R', 'O', 'F', 'S' };
 | 
| sl@0 |    379 | 
 | 
| sl@0 |    380 | 	// nasty cast required until TPckgBuf gains a const accessor member
 | 
| sl@0 |    381 | 	const TRofsHeader& h = ((CRofsMountCB*)this)->iHeader();
 | 
| sl@0 |    382 | 	if( 0 != Mem::Compare( KRofsHeaderId, 4, h.iIdentifier, 4 ) )
 | 
| sl@0 |    383 | 		{
 | 
| sl@0 |    384 | 		__PRINT(_L("CRofsMountCB::CheckHeader, [ROFS] ID missing"));
 | 
| sl@0 |    385 | 		return KErrCorrupt;
 | 
| sl@0 |    386 | 		}
 | 
| sl@0 |    387 | 
 | 
| sl@0 |    388 | 	if( h.iRofsFormatVersion < KEarliestSupportedFormatVersion
 | 
| sl@0 |    389 | 		|| h.iRofsFormatVersion > KLatestSupportedFormatVersion )
 | 
| sl@0 |    390 | 		{
 | 
| sl@0 |    391 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, unsupported version %x"), h.iRofsFormatVersion );
 | 
| sl@0 |    392 | 		return KErrNotSupported;
 | 
| sl@0 |    393 | 		}
 | 
| sl@0 |    394 | 
 | 
| sl@0 |    395 | 	if( MAKE_TINT64(0,h.iImageSize) > iMediaSize )
 | 
| sl@0 |    396 | 		{
 | 
| sl@0 |    397 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, image size overflow %x"), h.iImageSize );
 | 
| sl@0 |    398 | 		return KErrCorrupt;
 | 
| sl@0 |    399 | 		}
 | 
| sl@0 |    400 | 
 | 
| sl@0 |    401 | 	if( MAKE_TINT64(0,h.iDirTreeOffset) > iMediaSize )
 | 
| sl@0 |    402 | 		{
 | 
| sl@0 |    403 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, dir tree offset %x out-of-range"), h.iDirTreeOffset );
 | 
| sl@0 |    404 | 		return KErrCorrupt;
 | 
| sl@0 |    405 | 		}
 | 
| sl@0 |    406 | 
 | 
| sl@0 |    407 | 	if(TInt64(h.iDirTreeOffset + h.iDirTreeSize) > iMediaSize )
 | 
| sl@0 |    408 | 		{
 | 
| sl@0 |    409 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, dir tree size %x overflow"), h.iDirTreeSize );
 | 
| sl@0 |    410 | 		return KErrCorrupt;
 | 
| sl@0 |    411 | 		}
 | 
| sl@0 |    412 | 
 | 
| sl@0 |    413 | 	if( MAKE_TINT64(0,h.iDirFileEntriesOffset) > iMediaSize )
 | 
| sl@0 |    414 | 		{
 | 
| sl@0 |    415 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, file entries offset %x out-of-range"), h.iDirFileEntriesOffset );
 | 
| sl@0 |    416 | 		return KErrCorrupt;
 | 
| sl@0 |    417 | 		}
 | 
| sl@0 |    418 | 
 | 
| sl@0 |    419 | 	if( TInt64(h.iDirFileEntriesOffset + h.iDirFileEntriesSize) > iMediaSize )
 | 
| sl@0 |    420 | 		{
 | 
| sl@0 |    421 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, file entries size %x overflow"), h.iDirFileEntriesSize );
 | 
| sl@0 |    422 | 		return KErrCorrupt;
 | 
| sl@0 |    423 | 		}
 | 
| sl@0 |    424 | 
 | 
| sl@0 |    425 | 	if( IsOverlapping( h.iDirTreeOffset, h.iDirTreeSize,
 | 
| sl@0 |    426 | 		h.iDirFileEntriesOffset, h.iDirFileEntriesSize ) )
 | 
| sl@0 |    427 | 		{
 | 
| sl@0 |    428 | 		__PRINT1(_L("CRofsMountCB::CheckHeader, dir & file entries overlap"), h.iDirTreeSize );
 | 
| sl@0 |    429 | 		return KErrCorrupt;
 | 
| sl@0 |    430 | 		}
 | 
| sl@0 |    431 | 
 | 
| sl@0 |    432 | 	return KErrNone;
 | 
| sl@0 |    433 | 	}
 | 
| sl@0 |    434 | 
 | 
| sl@0 |    435 | 
 | 
| sl@0 |    436 | TInt CRofsMountCB::ReMount()
 | 
| sl@0 |    437 | //
 | 
| sl@0 |    438 | // Try and remount this media.
 | 
| sl@0 |    439 | //
 | 
| sl@0 |    440 | 	{
 | 
| sl@0 |    441 | 
 | 
| sl@0 |    442 | 	CRofs::Panic( CRofs::EPanicRemountNotSupported );
 | 
| sl@0 |    443 | 	return(0);
 | 
| sl@0 |    444 | 	}
 | 
| sl@0 |    445 | 
 | 
| sl@0 |    446 | void CRofsMountCB::VolumeL(TVolumeInfo& aVolume) const
 | 
| sl@0 |    447 | //
 | 
| sl@0 |    448 | // Return the volume info.
 | 
| sl@0 |    449 | //
 | 
| sl@0 |    450 | 	{
 | 
| sl@0 |    451 | 
 | 
| sl@0 |    452 | 	aVolume.iFree=0;
 | 
| sl@0 |    453 | 	}
 | 
| sl@0 |    454 | 
 | 
| sl@0 |    455 | 
 | 
| sl@0 |    456 | void CRofsMountCB::SetVolumeL(TDes& /*aName*/)
 | 
| sl@0 |    457 | //
 | 
| sl@0 |    458 | // Set the volume label.
 | 
| sl@0 |    459 | //
 | 
| sl@0 |    460 | 	{
 | 
| sl@0 |    461 | 
 | 
| sl@0 |    462 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    463 | 	}
 | 
| sl@0 |    464 | 
 | 
| sl@0 |    465 | void CRofsMountCB::MkDirL(const TDesC& /*aName*/)
 | 
| sl@0 |    466 | //
 | 
| sl@0 |    467 | // Make a directory.
 | 
| sl@0 |    468 | //
 | 
| sl@0 |    469 | 	{
 | 
| sl@0 |    470 | 
 | 
| sl@0 |    471 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    472 | 	}
 | 
| sl@0 |    473 | 
 | 
| sl@0 |    474 | void CRofsMountCB::RmDirL(const TDesC& /*aName*/)
 | 
| sl@0 |    475 | //
 | 
| sl@0 |    476 | // Remove a directory.
 | 
| sl@0 |    477 | //
 | 
| sl@0 |    478 | 	{
 | 
| sl@0 |    479 | 
 | 
| sl@0 |    480 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    481 | 	}
 | 
| sl@0 |    482 | 
 | 
| sl@0 |    483 | void CRofsMountCB::DeleteL(const TDesC& /*aName*/)
 | 
| sl@0 |    484 | //
 | 
| sl@0 |    485 | // Delete a file.
 | 
| sl@0 |    486 | //
 | 
| sl@0 |    487 | 	{
 | 
| sl@0 |    488 | 
 | 
| sl@0 |    489 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    490 | 	}
 | 
| sl@0 |    491 | 
 | 
| sl@0 |    492 | void CRofsMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*aNewName*/)
 | 
| sl@0 |    493 | //
 | 
| sl@0 |    494 | // Rename a file or directory.
 | 
| sl@0 |    495 | //
 | 
| sl@0 |    496 | 	{
 | 
| sl@0 |    497 | 
 | 
| sl@0 |    498 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    499 | 	}
 | 
| sl@0 |    500 | 
 | 
| sl@0 |    501 | void CRofsMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*aNewName*/)
 | 
| sl@0 |    502 | //
 | 
| sl@0 |    503 | // Atomic replace.
 | 
| sl@0 |    504 | //
 | 
| sl@0 |    505 | 	{
 | 
| sl@0 |    506 | 
 | 
| sl@0 |    507 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    508 | 	}
 | 
| sl@0 |    509 | 
 | 
| sl@0 |    510 | void CRofsMountCB::EntryL(const TDesC& aName,TEntry& aEntry) const
 | 
| sl@0 |    511 | //
 | 
| sl@0 |    512 | // Get entry details.
 | 
| sl@0 |    513 | //
 | 
| sl@0 |    514 | 	{
 | 
| sl@0 |    515 | 	const TRofsDir* dir;
 | 
| sl@0 |    516 | 	const TRofsEntry* entry = NULL;
 | 
| sl@0 |    517 | 	iDirectoryCache->FindGeneralEntryL( aName, KEntryAttMaskSupported, dir, entry);
 | 
| sl@0 |    518 | 	aEntry.iAtt = entry->iAtt;
 | 
| sl@0 |    519 | 	aEntry.iSize = entry->iFileSize;
 | 
| sl@0 |    520 | 	aEntry.iModified = ((TPckgBuf<TRofsHeader>&)(iHeader))().iTime;
 | 
| sl@0 |    521 | 	aEntry.iName.Des().Copy( CDirectoryCache::NameAddress(entry), entry->iNameLength);
 | 
| sl@0 |    522 | 	ReadUidL( entry->iFileAddress, aEntry, (TRofsEntry*)entry );
 | 
| sl@0 |    523 | 	}
 | 
| sl@0 |    524 | 
 | 
| sl@0 |    525 | void CRofsMountCB::ReadUidL( TUint /*aMediaOffset*/, TEntry& aEntry, TRofsEntry* aRofsEntry) const
 | 
| sl@0 |    526 | //
 | 
| sl@0 |    527 | // Internal function to read a uid if present.
 | 
| sl@0 |    528 | //
 | 
| sl@0 |    529 | 	{
 | 
| sl@0 |    530 | 
 | 
| sl@0 |    531 | 	TBuf8<sizeof(TCheckedUid)> uidBuf;
 | 
| sl@0 |    532 | 	uidBuf.SetLength(sizeof(TCheckedUid));
 | 
| sl@0 |    533 | 	Mem::Copy(&uidBuf[0], &aRofsEntry->iUids[0],sizeof(TCheckedUid));
 | 
| sl@0 |    534 | 
 | 
| sl@0 |    535 | 	TCheckedUid uid(uidBuf);
 | 
| sl@0 |    536 | 	aEntry.iType = uid.UidType();
 | 
| sl@0 |    537 | 	}
 | 
| sl@0 |    538 | 
 | 
| sl@0 |    539 | void CRofsMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aMask*/,TUint /*aVal*/)
 | 
| sl@0 |    540 | //
 | 
| sl@0 |    541 | // Set entry details.
 | 
| sl@0 |    542 | //
 | 
| sl@0 |    543 | 	{
 | 
| sl@0 |    544 | 
 | 
| sl@0 |    545 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    546 | 	}
 | 
| sl@0 |    547 | 
 | 
| sl@0 |    548 | void CRofsMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen aOpen,CFileCB* aFile)
 | 
| sl@0 |    549 | //
 | 
| sl@0 |    550 | // Open a file on the current mount.
 | 
| sl@0 |    551 | //
 | 
| sl@0 |    552 | 	{
 | 
| sl@0 |    553 | 
 | 
| sl@0 |    554 | 	if ( aMode & EFileWrite )
 | 
| sl@0 |    555 | 		{
 | 
| sl@0 |    556 | 		User::Leave(KErrAccessDenied);
 | 
| sl@0 |    557 | 		}
 | 
| sl@0 |    558 | 
 | 
| sl@0 |    559 | 	if( EFileOpen != aOpen )
 | 
| sl@0 |    560 | 		{
 | 
| sl@0 |    561 | 		User::Leave(KErrAccessDenied);
 | 
| sl@0 |    562 | 		}
 | 
| sl@0 |    563 | 
 | 
| sl@0 |    564 | 	const TRofsEntry* entry;
 | 
| sl@0 |    565 | 	iDirectoryCache->FindFileEntryL(aName, entry);
 | 
| sl@0 |    566 | 
 | 
| sl@0 |    567 | 	CRofsFileCB& file=(*((CRofsFileCB*)aFile));
 | 
| sl@0 |    568 | 	file.SetSize( entry->iFileSize );
 | 
| sl@0 |    569 | 	file.SetAtt( entry->iAtt );
 | 
| sl@0 |    570 | 	file.SetAttExtra( entry->iAttExtra );
 | 
| sl@0 |    571 | 	file.SetModified( iHeader().iTime );
 | 
| sl@0 |    572 | 	file.SetMediaBase( entry->iFileAddress );
 | 
| sl@0 |    573 | 	}
 | 
| sl@0 |    574 | 
 | 
| sl@0 |    575 | void CRofsMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
 | 
| sl@0 |    576 | //
 | 
| sl@0 |    577 | // Open a directory on the current mount.
 | 
| sl@0 |    578 | //
 | 
| sl@0 |    579 | 	{
 | 
| sl@0 |    580 | 
 | 
| sl@0 |    581 |     TFileName fileName=aName;
 | 
| sl@0 |    582 |     TInt namePos=aName.LocateReverse(KPathDelimiter)+1; // Exclude path delimiter
 | 
| sl@0 |    583 |     if (namePos==aName.Length())
 | 
| sl@0 |    584 |         {
 | 
| sl@0 |    585 | 		fileName+=_L("*");
 | 
| sl@0 |    586 | 		}
 | 
| sl@0 |    587 | 
 | 
| sl@0 |    588 | 	const TRofsDir* dir;
 | 
| sl@0 |    589 | 	iDirectoryCache->FindDirectoryEntryL( fileName.Left(namePos), dir );
 | 
| sl@0 |    590 | 	
 | 
| sl@0 |    591 | 	CRofsDirCB& dirCB=(*((CRofsDirCB*)aDir));
 | 
| sl@0 |    592 | 	dirCB.SetDir( dir, fileName.Mid(namePos), iHeader().iTime );
 | 
| sl@0 |    593 | 	dirCB.SetCache( iDirectoryCache );
 | 
| sl@0 |    594 | 	}
 | 
| sl@0 |    595 | 
 | 
| sl@0 |    596 | void CRofsMountCB::RawReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt anOffset,const RMessagePtr2& aMessage) const
 | 
| sl@0 |    597 | //
 | 
| sl@0 |    598 | // Read up to aLength data directly from the media
 | 
| sl@0 |    599 | //
 | 
| sl@0 |    600 | 	{
 | 
| sl@0 |    601 | 	if (aPos >= iMediaSize || aPos < 0 )
 | 
| sl@0 |    602 | 		{
 | 
| sl@0 |    603 | 		if (aMessage.Handle() == KLocalMessageHandle)
 | 
| sl@0 |    604 | 			((TPtr8* )aTrg)->SetLength(0);
 | 
| sl@0 |    605 | 		else
 | 
| sl@0 |    606 | 			aMessage.WriteL(0,TPtrC8(NULL,0),anOffset);
 | 
| sl@0 |    607 | 		}
 | 
| sl@0 |    608 | 	else
 | 
| sl@0 |    609 | 		{
 | 
| sl@0 |    610 | 		TInt len=Min( (TInt)(I64LOW(iMediaSize)-I64LOW(aPos)),aLength);
 | 
| sl@0 |    611 | 
 | 
| sl@0 |    612 | #ifdef _USE_TRUE_LRU_CACHE
 | 
| sl@0 |    613 | 
 | 
| sl@0 |    614 | 		__PRINT2(_L("ROFS::RawReadL() pos=%d len=%d"),aPos, aLength);
 | 
| sl@0 |    615 | 		CacheReadL( I64LOW(aPos), len, aTrg, anOffset, aMessage );
 | 
| sl@0 |    616 | #else
 | 
| sl@0 |    617 | 		TInt r = LocalDrive()->Read( aPos, len, aTrg, aMessage.Handle(), anOffset );
 | 
| sl@0 |    618 | 		User::LeaveIfError( r );
 | 
| sl@0 |    619 | #endif
 | 
| sl@0 |    620 | 		}
 | 
| sl@0 |    621 | 	}
 | 
| sl@0 |    622 | 
 | 
| sl@0 |    623 | void CRofsMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
 | 
| sl@0 |    624 | //
 | 
| sl@0 |    625 | // Write aLength data to ROM (?)
 | 
| sl@0 |    626 | //
 | 
| sl@0 |    627 | 	{
 | 
| sl@0 |    628 | 
 | 
| sl@0 |    629 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    630 | 	}
 | 
| sl@0 |    631 | 
 | 
| sl@0 |    632 | 
 | 
| sl@0 |    633 | void CRofsMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
 | 
| sl@0 |    634 | 	//
 | 
| sl@0 |    635 | 	// Note: this function will need some modification to support compresed files
 | 
| sl@0 |    636 | 	//
 | 
| sl@0 |    637 | 	{
 | 
| sl@0 |    638 | 
 | 
| sl@0 |    639 | 	__PRINT(_L("CRofsMountCB::ReadSectionL"));
 | 
| sl@0 |    640 | 			
 | 
| sl@0 |    641 | 	const TRofsEntry* entry;
 | 
| sl@0 |    642 | 	iDirectoryCache->FindFileEntryL(aName, entry);
 | 
| sl@0 |    643 | 
 | 
| sl@0 |    644 | 	TInt size = entry->iFileSize;
 | 
| sl@0 |    645 | 	TInt len = 0;	// initialise to stop a warning
 | 
| sl@0 |    646 | 	if ( size >= (aPos+aLength) )
 | 
| sl@0 |    647 | 		{
 | 
| sl@0 |    648 | 		len = aLength;
 | 
| sl@0 |    649 | 		}
 | 
| sl@0 |    650 | 	else if ( size > aPos )
 | 
| sl@0 |    651 | 		{
 | 
| sl@0 |    652 | 		len=(size-aPos);
 | 
| sl@0 |    653 | 		}
 | 
| sl@0 |    654 | 	else
 | 
| sl@0 |    655 | 		{
 | 
| sl@0 |    656 | 		User::Leave(KErrEof);
 | 
| sl@0 |    657 | 		}
 | 
| sl@0 |    658 | 	
 | 
| sl@0 |    659 | 	TInt64 pos64( (TUint)entry->iFileAddress);
 | 
| sl@0 |    660 | 	pos64 += aPos;
 | 
| sl@0 |    661 | 
 | 
| sl@0 |    662 | #ifdef _USE_TRUE_LRU_CACHE
 | 
| sl@0 |    663 | 
 | 
| sl@0 |    664 | 	__PRINT2(_L("ROFS::ReadSectionL() pos=%d len=%d"),I64LOW(pos64), aLength);
 | 
| sl@0 |    665 | 	CacheReadL( I64LOW(pos64), len, aTrg, 0, aMessage );
 | 
| sl@0 |    666 | #else
 | 
| sl@0 |    667 | 	TInt r = LocalDrive()->Read( pos64, len, aTrg, aMessage.Handle(), 0 );
 | 
| sl@0 |    668 | 	User::LeaveIfError( r );
 | 
| sl@0 |    669 | #endif
 | 
| sl@0 |    670 | 	}
 | 
| sl@0 |    671 | 
 | 
| sl@0 |    672 | 
 | 
| sl@0 |    673 | void CRofsMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/)
 | 
| sl@0 |    674 | //
 | 
| sl@0 |    675 | // Return the short name associated with aLongName
 | 
| sl@0 |    676 | // Assumes all rom names are 8.3
 | 
| sl@0 |    677 | //
 | 
| sl@0 |    678 | 	{
 | 
| sl@0 |    679 | 
 | 
| sl@0 |    680 | 	User::Leave(KErrNotSupported);
 | 
| sl@0 |    681 | 	}
 | 
| sl@0 |    682 | 
 | 
| sl@0 |    683 | void CRofsMountCB::GetLongNameL(const TDesC& /*aShortName*/,TDes& /*aLongName*/)
 | 
| sl@0 |    684 | //
 | 
| sl@0 |    685 | // Return the short name associated with aLongName
 | 
| sl@0 |    686 | // Assumes all rom names are 8.3
 | 
| sl@0 |    687 | //
 | 
| sl@0 |    688 | 	{
 | 
| sl@0 |    689 | 
 | 
| sl@0 |    690 | 	User::Leave(KErrNotSupported);
 | 
| sl@0 |    691 | 	}	
 | 
| sl@0 |    692 | 
 | 
| sl@0 |    693 | 
 | 
| sl@0 |    694 | TInt CRofsMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) 
 | 
| sl@0 |    695 | 	{
 | 
| sl@0 |    696 | 	TInt r= KErrNone;
 | 
| sl@0 |    697 | 	switch(aInterfaceId)
 | 
| sl@0 |    698 | 		{
 | 
| sl@0 |    699 | 		case (CMountCB::EFileAccessor):
 | 
| sl@0 |    700 | 			((CMountCB::MFileAccessor*&) aInterface) = this;
 | 
| sl@0 |    701 | 			break;
 | 
| sl@0 |    702 | 
 | 
| sl@0 |    703 | 		case CMountCB::ELocalBufferSupport:
 | 
| sl@0 |    704 | 			return LocalDrive()->LocalBufferSupport();
 | 
| sl@0 |    705 | 
 | 
| sl@0 |    706 | 		case (CMountCB::EAddToCompositeMount):
 | 
| sl@0 |    707 | 			iMountId = (TUint8)((TInt)aInput);
 | 
| sl@0 |    708 | 			break;
 | 
| sl@0 |    709 | 
 | 
| sl@0 |    710 | 		default:
 | 
| sl@0 |    711 | 			r=KErrNotSupported;
 | 
| sl@0 |    712 | 		}
 | 
| sl@0 |    713 | 	return r;
 | 
| sl@0 |    714 | 	}
 | 
| sl@0 |    715 | 
 | 
| sl@0 |    716 | TInt CRofsMountCB::GetFileUniqueId(const TDesC& aName, TInt64& aUniqueId)
 | 
| sl@0 |    717 | 	{
 | 
| sl@0 |    718 | 	// Get unique identifier for the file
 | 
| sl@0 |    719 | 	const TRofsEntry* entry=NULL;
 | 
| sl@0 |    720 | 	TInt err;
 | 
| sl@0 |    721 | 	TRAP(err,iDirectoryCache->FindFileEntryL(aName, entry));
 | 
| sl@0 |    722 | 	if(err!=KErrNone)
 | 
| sl@0 |    723 | 		return err;
 | 
| sl@0 |    724 | 	aUniqueId = MAKE_TINT64(0,entry->iFileAddress);
 | 
| sl@0 |    725 | 	return KErrNone;
 | 
| sl@0 |    726 | 	}
 | 
| sl@0 |    727 | 
 | 
| sl@0 |    728 | TInt CRofsMountCB::Spare3(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
 | 
| sl@0 |    729 | 	{
 | 
| sl@0 |    730 | 	return KErrNotSupported;
 | 
| sl@0 |    731 | 	}
 | 
| sl@0 |    732 | 
 | 
| sl@0 |    733 | TInt CRofsMountCB::Spare2(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
 | 
| sl@0 |    734 | 	{
 | 
| sl@0 |    735 | 	return KErrNotSupported;
 | 
| sl@0 |    736 | 	}
 | 
| sl@0 |    737 | 
 | 
| sl@0 |    738 | TInt CRofsMountCB::Spare1(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
 | 
| sl@0 |    739 | 	{
 | 
| sl@0 |    740 | 	return KErrNotSupported;
 | 
| sl@0 |    741 | 	}
 | 
| sl@0 |    742 | 
 | 
| sl@0 |    743 | 
 | 
| sl@0 |    744 | //***********************************************************
 | 
| sl@0 |    745 | //* File object
 | 
| sl@0 |    746 | //***********************************************************
 | 
| sl@0 |    747 | 
 | 
| sl@0 |    748 | 
 | 
| sl@0 |    749 | 
 | 
| sl@0 |    750 | CRofsFileCB::CRofsFileCB()
 | 
| sl@0 |    751 | //
 | 
| sl@0 |    752 | // Constructor
 | 
| sl@0 |    753 | //
 | 
| sl@0 |    754 | 	{
 | 
| sl@0 |    755 | 	}
 | 
| sl@0 |    756 | 
 | 
| sl@0 |    757 | 
 | 
| sl@0 |    758 | void CRofsFileCB::ReadL(TInt64 aPos,TInt& aLength,TDes8* aDes,const RMessagePtr2& aMessage, TInt aOffset)
 | 
| sl@0 |    759 | //
 | 
| sl@0 |    760 | // Read from the file.
 | 
| sl@0 |    761 | //
 | 
| sl@0 |    762 | 	{
 | 
| sl@0 |    763 | 	__PRINT(_L("CRofsFileCB::ReadL"));
 | 
| sl@0 |    764 | 
 | 
| sl@0 |    765 | 	// for now, convert pos to a TInt
 | 
| sl@0 |    766 | 	if (aPos > KMaxTInt)
 | 
| sl@0 |    767 | 		User::Leave(KErrNotSupported);
 | 
| sl@0 |    768 | 	TInt pos = (TInt) aPos;
 | 
| sl@0 |    769 | 	
 | 
| sl@0 |    770 | 	if (pos>=iSize)
 | 
| sl@0 |    771 | 		{
 | 
| sl@0 |    772 | 		if (aMessage.Handle() == KLocalMessageHandle)
 | 
| sl@0 |    773 | 			((TPtr8* )aDes)->SetLength(0);
 | 
| sl@0 |    774 | 		else
 | 
| sl@0 |    775 | 			aMessage.WriteL(0,TPtrC8(NULL,0),aOffset);
 | 
| sl@0 |    776 | 		aLength=0;
 | 
| sl@0 |    777 | 		}
 | 
| sl@0 |    778 | 	else
 | 
| sl@0 |    779 | 		{
 | 
| sl@0 |    780 | 		TInt len=Min((iSize-pos),aLength);
 | 
| sl@0 |    781 | 
 | 
| sl@0 |    782 | #ifdef _USE_TRUE_LRU_CACHE
 | 
| sl@0 |    783 | 
 | 
| sl@0 |    784 | 		__PRINT2(_L("ROFS::ReadL() pos=%d len=%d"),pos, len);
 | 
| sl@0 |    785 | 		RofsMount().CacheReadL( pos + iMediaBase, len, aDes, aOffset, aMessage );
 | 
| sl@0 |    786 | #else
 | 
| sl@0 |    787 | 		TInt r = RofsMount().LocalDrive()->Read( pos + iMediaBase, len, aDes, aMessage.Handle(),aOffset) ;
 | 
| sl@0 |    788 | 		User::LeaveIfError( r );
 | 
| sl@0 |    789 | #endif
 | 
| sl@0 |    790 | 		aLength=len;
 | 
| sl@0 |    791 | 		}
 | 
| sl@0 |    792 | 	}
 | 
| sl@0 |    793 | 
 | 
| sl@0 |    794 | void CRofsFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
 | 
| sl@0 |    795 | 	{
 | 
| sl@0 |    796 | 	ReadL(TInt64(aPos),aLength,(TDes8*) aDes,aMessage, 0);
 | 
| sl@0 |    797 | 	}
 | 
| sl@0 |    798 | 
 | 
| sl@0 |    799 | void CRofsFileCB::WriteL(TInt64 /*aPos*/,TInt& /*aLength*/,const TDesC8* /*aDes*/,const RMessagePtr2& /*aMessage*/, TInt /*aOffset*/)
 | 
| sl@0 |    800 | //
 | 
| sl@0 |    801 | // Write to the file.
 | 
| sl@0 |    802 | //
 | 
| sl@0 |    803 | 	{
 | 
| sl@0 |    804 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    805 | 	}
 | 
| sl@0 |    806 | 
 | 
| sl@0 |    807 | void CRofsFileCB::WriteL(TInt /*aPos*/,TInt& /*aLength*/,const TAny* /*aDes*/,const RMessagePtr2& /*aMessage*/)
 | 
| sl@0 |    808 | 	{
 | 
| sl@0 |    809 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    810 | 	}
 | 
| sl@0 |    811 | 
 | 
| sl@0 |    812 | void CRofsFileCB::RenameL(const TDesC& /*aDes*/)
 | 
| sl@0 |    813 | //
 | 
| sl@0 |    814 | // Rename the file.
 | 
| sl@0 |    815 | //
 | 
| sl@0 |    816 | 	{
 | 
| sl@0 |    817 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    818 | 	}
 | 
| sl@0 |    819 | 
 | 
| sl@0 |    820 | void CRofsFileCB::SetSizeL(TInt64 /*aSize*/)
 | 
| sl@0 |    821 | //
 | 
| sl@0 |    822 | // Set the file size.
 | 
| sl@0 |    823 | //
 | 
| sl@0 |    824 | 	{
 | 
| sl@0 |    825 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    826 | 	}
 | 
| sl@0 |    827 | 
 | 
| sl@0 |    828 | void CRofsFileCB::SetSizeL(TInt /*aSize*/)
 | 
| sl@0 |    829 | //
 | 
| sl@0 |    830 | // Set the file size.
 | 
| sl@0 |    831 | //
 | 
| sl@0 |    832 | 	{
 | 
| sl@0 |    833 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    834 | 	}
 | 
| sl@0 |    835 | 
 | 
| sl@0 |    836 | void CRofsFileCB::SetEntryL(const TTime& /*aTime*/,TUint /*aMask*/,TUint /*aVal*/)
 | 
| sl@0 |    837 | //
 | 
| sl@0 |    838 | // Set the entry's attributes and modified time.
 | 
| sl@0 |    839 | //
 | 
| sl@0 |    840 | 	{
 | 
| sl@0 |    841 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    842 | 	}
 | 
| sl@0 |    843 | 
 | 
| sl@0 |    844 | void CRofsFileCB::FlushAllL()
 | 
| sl@0 |    845 | //
 | 
| sl@0 |    846 | // Commit any buffered date to the media.
 | 
| sl@0 |    847 | //
 | 
| sl@0 |    848 | 	{
 | 
| sl@0 |    849 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    850 | 	}
 | 
| sl@0 |    851 | 
 | 
| sl@0 |    852 | void CRofsFileCB::FlushDataL()
 | 
| sl@0 |    853 | //
 | 
| sl@0 |    854 | // Commit any buffered date to the media.
 | 
| sl@0 |    855 | //
 | 
| sl@0 |    856 | 	{
 | 
| sl@0 |    857 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |    858 | 	}
 | 
| sl@0 |    859 | 
 | 
| sl@0 |    860 | 
 | 
| sl@0 |    861 | 
 | 
| sl@0 |    862 | //***********************************************************
 | 
| sl@0 |    863 | //* Directory object
 | 
| sl@0 |    864 | //***********************************************************
 | 
| sl@0 |    865 | 
 | 
| sl@0 |    866 | 
 | 
| sl@0 |    867 | CRofsDirCB::CRofsDirCB()
 | 
| sl@0 |    868 | //
 | 
| sl@0 |    869 | // Constructor
 | 
| sl@0 |    870 | //
 | 
| sl@0 |    871 | 	{
 | 
| sl@0 |    872 | 	}
 | 
| sl@0 |    873 | 
 | 
| sl@0 |    874 | 
 | 
| sl@0 |    875 | CRofsDirCB::~CRofsDirCB()
 | 
| sl@0 |    876 | //
 | 
| sl@0 |    877 | // Destruct
 | 
| sl@0 |    878 | //
 | 
| sl@0 |    879 | 	{
 | 
| sl@0 |    880 | 	delete iMatch;
 | 
| sl@0 |    881 | 	}
 | 
| sl@0 |    882 | 
 | 
| sl@0 |    883 | TBool CRofsDirCB::MatchUid()
 | 
| sl@0 |    884 | 	{
 | 
| sl@0 |    885 | 	return (iUidType[0]!=TUid::Null() || iUidType[1]!=TUid::Null() || iUidType[2]!=TUid::Null());
 | 
| sl@0 |    886 | 	}
 | 
| sl@0 |    887 | 
 | 
| sl@0 |    888 | LOCAL_C TBool CompareUid(const TUidType& aUidTrg, const TUidType& aUidSuitor)
 | 
| sl@0 |    889 | //
 | 
| sl@0 |    890 | // Compare the suitor to the target pattern
 | 
| sl@0 |    891 | //
 | 
| sl@0 |    892 | 	{
 | 
| sl@0 |    893 | 	
 | 
| sl@0 |    894 | 	if (aUidTrg[0]!=TUid::Null() && aUidTrg[0]!=aUidSuitor[0])
 | 
| sl@0 |    895 | 		return(EFalse);
 | 
| sl@0 |    896 | 	if (aUidTrg[1]!=TUid::Null() && aUidTrg[1]!=aUidSuitor[1])
 | 
| sl@0 |    897 | 		return(EFalse);
 | 
| sl@0 |    898 | 	if (aUidTrg[2]!=TUid::Null() && aUidTrg[2]!=aUidSuitor[2])
 | 
| sl@0 |    899 | 		return(EFalse);
 | 
| sl@0 |    900 | 	return(ETrue);
 | 
| sl@0 |    901 | 	}
 | 
| sl@0 |    902 | 
 | 
| sl@0 |    903 | 
 | 
| sl@0 |    904 | void CRofsDirCB::SetDir( const TRofsDir* aDir, const TDesC& aName, TInt64& aTimeStamp )
 | 
| sl@0 |    905 | //
 | 
| sl@0 |    906 | // Set the directory and entry that we are on after open.
 | 
| sl@0 |    907 | //
 | 
| sl@0 |    908 | 	{
 | 
| sl@0 |    909 |     iDir = aDir;
 | 
| sl@0 |    910 | 	iTimeStamp = aTimeStamp;
 | 
| sl@0 |    911 | 	iNext = NULL;
 | 
| sl@0 |    912 | 	iMatch = aName.AllocL();
 | 
| sl@0 |    913 | 	iPending = EFalse;
 | 
| sl@0 |    914 | 	}
 | 
| sl@0 |    915 | 
 | 
| sl@0 |    916 | 
 | 
| sl@0 |    917 | 
 | 
| sl@0 |    918 | void CRofsDirCB::ReadL(TEntry& aEntry)
 | 
| sl@0 |    919 | //
 | 
| sl@0 |    920 | // Read the next entry from the directory.
 | 
| sl@0 |    921 | //
 | 
| sl@0 |    922 | 	{
 | 
| sl@0 |    923 | 	__ASSERT_DEBUG( NULL != iCache, CRofs::Panic( CRofs::EPanicDirCacheNull ));
 | 
| sl@0 |    924 | 
 | 
| sl@0 |    925 | 	FOREVER
 | 
| sl@0 |    926 | 		{
 | 
| sl@0 |    927 | 		if (!iPending)
 | 
| sl@0 |    928 | 			{
 | 
| sl@0 |    929 | 			TInt err;
 | 
| sl@0 |    930 | 			do
 | 
| sl@0 |    931 | 				{
 | 
| sl@0 |    932 | 				// skip past all hidden files so they don't appear in the directory listing
 | 
| sl@0 |    933 | 				TRAP(err, iCache->GetNextMatchingL( *iMatch, iAtt, iDir, iNext, KErrEof, EFalse ));
 | 
| sl@0 |    934 | 				}
 | 
| sl@0 |    935 | 			while(KErrHidden == err);
 | 
| sl@0 |    936 | 			User::LeaveIfError(err);
 | 
| sl@0 |    937 | 			}
 | 
| sl@0 |    938 | 		iPending=EFalse;
 | 
| sl@0 |    939 | 
 | 
| sl@0 |    940 | 		// copy out the entry data
 | 
| sl@0 |    941 | 		if((~iNext->iAttExtra & (KEntryAttUnique >> 23))!=0)
 | 
| sl@0 |    942 | 			{
 | 
| sl@0 |    943 | 			iEntry.iName.Des().Copy( CDirectoryCache::NameAddress(iNext), iNext->iNameLength );
 | 
| sl@0 |    944 | 			iEntry.iName.Des().AppendFormat(_L("[%02x-00]"), iCache->GetMountId());
 | 
| sl@0 |    945 | 			}
 | 
| sl@0 |    946 | 		else
 | 
| sl@0 |    947 | 			{
 | 
| sl@0 |    948 | 			iEntry.iName.Des().Copy( CDirectoryCache::NameAddress(iNext), iNext->iNameLength );
 | 
| sl@0 |    949 | 			}
 | 
| sl@0 |    950 | 		iEntry.iAtt = iNext->iAtt;
 | 
| sl@0 |    951 | 		iEntry.iSize = iNext->iFileSize;
 | 
| sl@0 |    952 | 		iEntry.iModified = iTimeStamp;
 | 
| sl@0 |    953 | 		aEntry = iEntry;
 | 
| sl@0 |    954 | 		if (MatchUid())
 | 
| sl@0 |    955 | 			{
 | 
| sl@0 |    956 | 			static_cast<CRofsMountCB&>(Mount()).ReadUidL(iNext->iFileAddress, aEntry, (TRofsEntry*)iNext );
 | 
| sl@0 |    957 | 			if (CompareUid(iUidType, aEntry.iType))
 | 
| sl@0 |    958 | 				{
 | 
| sl@0 |    959 | 				break;
 | 
| sl@0 |    960 | 				}
 | 
| sl@0 |    961 | 			}
 | 
| sl@0 |    962 | 		else
 | 
| sl@0 |    963 | 			{
 | 
| sl@0 |    964 | 			break;
 | 
| sl@0 |    965 | 			}
 | 
| sl@0 |    966 | 		}
 | 
| sl@0 |    967 | 	if ( (iAtt & KEntryAttAllowUid) && (aEntry.iAtt & KEntryAttDir)==0 && !MatchUid() )
 | 
| sl@0 |    968 | 		{
 | 
| sl@0 |    969 | 		static_cast<CRofsMountCB&>(Mount()).ReadUidL( iNext->iFileAddress, aEntry, (TRofsEntry*)iNext );
 | 
| sl@0 |    970 | 		}
 | 
| sl@0 |    971 | 	}
 | 
| sl@0 |    972 | 
 | 
| sl@0 |    973 | 
 | 
| sl@0 |    974 | //***********************************************************
 | 
| sl@0 |    975 | //* Filesystem factory object
 | 
| sl@0 |    976 | //***********************************************************
 | 
| sl@0 |    977 | 
 | 
| sl@0 |    978 | CRofs::CRofs()
 | 
| sl@0 |    979 | //
 | 
| sl@0 |    980 | // Constructor
 | 
| sl@0 |    981 | //
 | 
| sl@0 |    982 | 	{
 | 
| sl@0 |    983 | 	}
 | 
| sl@0 |    984 | 
 | 
| sl@0 |    985 | CRofs::~CRofs()
 | 
| sl@0 |    986 | //
 | 
| sl@0 |    987 | // Destruct
 | 
| sl@0 |    988 | //
 | 
| sl@0 |    989 | 	{
 | 
| sl@0 |    990 | 	}
 | 
| sl@0 |    991 | 
 | 
| sl@0 |    992 | TInt CRofs::Install()
 | 
| sl@0 |    993 | //
 | 
| sl@0 |    994 | // Install the file system.
 | 
| sl@0 |    995 | //
 | 
| sl@0 |    996 | 	{
 | 
| sl@0 |    997 | 	iVersion=TVersion(KF32MajorVersionNumber,KF32MinorVersionNumber,KF32BuildVersionNumber);
 | 
| sl@0 |    998 |     _LIT( KFileSystemName, "rofs");
 | 
| sl@0 |    999 | 
 | 
| sl@0 |   1000 | 	TDriveInfoV1Buf driveInfo;
 | 
| sl@0 |   1001 | 	TInt r=UserHal::DriveInfo(driveInfo);
 | 
| sl@0 |   1002 | 	if( KErrNone == r )
 | 
| sl@0 |   1003 | 		{
 | 
| sl@0 |   1004 | 		iTotalSupportedDrives = driveInfo().iTotalSupportedDrives;
 | 
| sl@0 |   1005 | 		r = SetName(&KFileSystemName);
 | 
| sl@0 |   1006 | 		}
 | 
| sl@0 |   1007 | 	return r;
 | 
| sl@0 |   1008 | 	}
 | 
| sl@0 |   1009 | 
 | 
| sl@0 |   1010 | CMountCB* CRofs::NewMountL() const
 | 
| sl@0 |   1011 | //
 | 
| sl@0 |   1012 | // Create a new mount control block.
 | 
| sl@0 |   1013 | //
 | 
| sl@0 |   1014 | 	{
 | 
| sl@0 |   1015 | 	return new(ELeave) CRofsMountCB();
 | 
| sl@0 |   1016 | 	}
 | 
| sl@0 |   1017 | 
 | 
| sl@0 |   1018 | CFileCB* CRofs::NewFileL() const
 | 
| sl@0 |   1019 | //
 | 
| sl@0 |   1020 | // Create a new file.
 | 
| sl@0 |   1021 | //
 | 
| sl@0 |   1022 | 	{
 | 
| sl@0 |   1023 | 	return new(ELeave) CRofsFileCB();
 | 
| sl@0 |   1024 | 	}
 | 
| sl@0 |   1025 | 
 | 
| sl@0 |   1026 | CDirCB* CRofs::NewDirL() const
 | 
| sl@0 |   1027 | //
 | 
| sl@0 |   1028 | // Create a new directory lister.
 | 
| sl@0 |   1029 | //
 | 
| sl@0 |   1030 | 	{
 | 
| sl@0 |   1031 | 	return new(ELeave) CRofsDirCB();
 | 
| sl@0 |   1032 | 	}
 | 
| sl@0 |   1033 | 
 | 
| sl@0 |   1034 | CFormatCB* CRofs::NewFormatL() const
 | 
| sl@0 |   1035 | //
 | 
| sl@0 |   1036 | // Create a new media formatter.
 | 
| sl@0 |   1037 | //
 | 
| sl@0 |   1038 | 	{
 | 
| sl@0 |   1039 | 	User::Leave(KErrAccessDenied);
 | 
| sl@0 |   1040 | 	return(NULL);
 | 
| sl@0 |   1041 | 	}
 | 
| sl@0 |   1042 | 
 | 
| sl@0 |   1043 | 
 | 
| sl@0 |   1044 | 
 | 
| sl@0 |   1045 | void CRofs::DriveInfo(TDriveInfo& anInfo,TInt aDriveNumber) const
 | 
| sl@0 |   1046 | //
 | 
| sl@0 |   1047 | // Return the drive info. iDriveAtt is already set.
 | 
| sl@0 |   1048 | //
 | 
| sl@0 |   1049 | 	{
 | 
| sl@0 |   1050 |     TLocalDriveCapsV2Buf localDriveCaps;
 | 
| sl@0 |   1051 | 	(void)GetLocalDrive(aDriveNumber).Caps(localDriveCaps);
 | 
| sl@0 |   1052 | 	// ignore return as Caps always returns valid Media and Drive attributes
 | 
| sl@0 |   1053 | 	anInfo.iMediaAtt = localDriveCaps().iMediaAtt | KMediaAttWriteProtected;
 | 
| sl@0 |   1054 | 	anInfo.iType     = localDriveCaps().iType;
 | 
| sl@0 |   1055 |     anInfo.iDriveAtt = localDriveCaps().iDriveAtt | KDriveAttInternal | KDriveAttLocal;
 | 
| sl@0 |   1056 | 
 | 
| sl@0 |   1057 | 	}
 | 
| sl@0 |   1058 | 
 | 
| sl@0 |   1059 | 
 | 
| sl@0 |   1060 | TInt CRofs::DefaultPath(TDes& aPath) const
 | 
| sl@0 |   1061 | //
 | 
| sl@0 |   1062 | // Return the initial default path.
 | 
| sl@0 |   1063 | //
 | 
| sl@0 |   1064 | 	{
 | 
| sl@0 |   1065 | 
 | 
| sl@0 |   1066 | 	aPath=_L("?:\\");
 | 
| sl@0 |   1067 | 	aPath[0] = (TUint8) RFs::GetSystemDriveChar();
 | 
| sl@0 |   1068 | 	return(KErrNone);
 | 
| sl@0 |   1069 | 	}
 | 
| sl@0 |   1070 | 
 | 
| sl@0 |   1071 | 
 | 
| sl@0 |   1072 | 
 | 
| sl@0 |   1073 | CRofs* CRofs::New()
 | 
| sl@0 |   1074 | //
 | 
| sl@0 |   1075 | // Create a ROFS filesystem
 | 
| sl@0 |   1076 | //
 | 
| sl@0 |   1077 | 	{
 | 
| sl@0 |   1078 | 	CRofs* fsys=new CRofs();
 | 
| sl@0 |   1079 | 	return fsys;
 | 
| sl@0 |   1080 | 	}
 | 
| sl@0 |   1081 | 
 | 
| sl@0 |   1082 | 
 | 
| sl@0 |   1083 | 
 | 
| sl@0 |   1084 | 
 | 
| sl@0 |   1085 | extern "C" {
 | 
| sl@0 |   1086 | EXPORT_C CFileSystem* CreateFileSystem()
 | 
| sl@0 |   1087 | //
 | 
| sl@0 |   1088 | // Create a new file system
 | 
| sl@0 |   1089 | //
 | 
| sl@0 |   1090 | 	{
 | 
| sl@0 |   1091 | 	return(CRofs::New());
 | 
| sl@0 |   1092 | 	}
 | 
| sl@0 |   1093 | }
 | 
| sl@0 |   1094 | 
 | 
| sl@0 |   1095 | //***********************************************************
 | 
| sl@0 |   1096 | //* BlockMap interface
 | 
| sl@0 |   1097 | //***********************************************************
 | 
| sl@0 |   1098 | 	
 | 
| sl@0 |   1099 | 
 | 
| sl@0 |   1100 | TInt CRofsFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos)
 | 
| sl@0 |   1101 | //	
 | 
| sl@0 |   1102 | // Retrieves the block map of a given section of the file, in the ROFS file system.
 | 
| sl@0 |   1103 | //	
 | 
| sl@0 |   1104 | 	{
 | 
| sl@0 |   1105 | 	__PRINT2(_L("CRofsFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos);
 | 
| sl@0 |   1106 | 	TInt64 mediaBase = iMediaBase;
 | 
| sl@0 |   1107 | 	TInt size = iSize;
 | 
| sl@0 |   1108 | 
 | 
| sl@0 |   1109 | 	// Make a TBlockMapEntry object, copy the start position and the length of the blockmap entry
 | 
| sl@0 |   1110 | 	TBlockMapEntry blockMapEntry;
 | 
| sl@0 |   1111 | 	if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) )
 | 
| sl@0 |   1112 | 		return KErrNotSupported;
 | 
| sl@0 |   1113 | 
 | 
| sl@0 |   1114 |     TInt startPos = I64LOW(aStartPos);
 | 
| sl@0 |   1115 | 	TInt endPos = I64LOW(aEndPos);
 | 
| sl@0 |   1116 | 
 | 
| sl@0 |   1117 | 	if((endPos-startPos)>size)
 | 
| sl@0 |   1118 | 		return KErrArgument;
 | 
| sl@0 |   1119 | 
 | 
| sl@0 |   1120 | 	TInt drvNo=-1;
 | 
| sl@0 |   1121 | 	TBusLocalDrive* locDrv;
 | 
| sl@0 |   1122 | 	if((RofsMount().LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives))
 | 
| sl@0 |   1123 | 		aInfo.iLocalDriveNumber=drvNo;
 | 
| sl@0 |   1124 | 	else
 | 
| sl@0 |   1125 | 		return KErrNotSupported;
 | 
| sl@0 |   1126 | 
 | 
| sl@0 |   1127 | 	TLocalDriveCapsV4Buf caps;
 | 
| sl@0 |   1128 | 	TUint blockSz = 0;
 | 
| sl@0 |   1129 | 	if((RofsMount().LocalDrive()->Caps(caps)==KErrNone) && caps().iFileSystemId==KDriveFileSysROFS)
 | 
| sl@0 |   1130 | 		blockSz = caps().iNumBytesMain;
 | 
| sl@0 |   1131 | 	else
 | 
| sl@0 |   1132 | 		return KErrNotSupported;
 | 
| sl@0 |   1133 | 
 | 
| sl@0 |   1134 | 	TUint len = 0;
 | 
| sl@0 |   1135 | 	if ( endPos >= size )
 | 
| sl@0 |   1136 | 		len = size-startPos;
 | 
| sl@0 |   1137 | 	else
 | 
| sl@0 |   1138 | 		len = endPos-startPos;
 | 
| sl@0 |   1139 | 
 | 
| sl@0 |   1140 | 	TUint numBlocks = 0;
 | 
| sl@0 |   1141 | 	TUint stBlockNr = (TUint) ((mediaBase + startPos)/blockSz);		// start block number (counts from 0)
 | 
| sl@0 |   1142 | 	TUint stBlockAddr = stBlockNr*blockSz;					// address of start block
 | 
| sl@0 |   1143 | 	
 | 
| sl@0 |   1144 | 	while((stBlockAddr + numBlocks*blockSz) < (mediaBase + startPos + len))		// accumulate contiguous blocks until we pass the end of the region
 | 
| sl@0 |   1145 | 		numBlocks++;
 | 
| sl@0 |   1146 | 
 | 
| sl@0 |   1147 | 	blockMapEntry.SetNumberOfBlocks( numBlocks );
 | 
| sl@0 |   1148 | 	blockMapEntry.SetStartBlock( stBlockNr );
 | 
| sl@0 |   1149 | 	aInfo.iStartBlockAddress = 0;							// start of partition = block 0
 | 
| sl@0 |   1150 | 	aInfo.iBlockGranularity = blockSz;
 | 
| sl@0 |   1151 | 	aInfo.iBlockStartOffset = (TUint) ((mediaBase + startPos)%blockSz);	// offset within first block to start of region
 | 
| sl@0 |   1152 | 	// Then put it into the descriptor iMap within the structure aInfo of type SBlockMapInfo
 | 
| sl@0 |   1153 | 	TPckg<TBlockMapEntry> entry(blockMapEntry);
 | 
| sl@0 |   1154 | 	aInfo.iMap.Append(entry);
 | 
| sl@0 |   1155 | 
 | 
| sl@0 |   1156 | 	return KErrCompletion;
 | 
| sl@0 |   1157 | 	}
 | 
| sl@0 |   1158 | 
 | 
| sl@0 |   1159 | TInt CRofsFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
 | 
| sl@0 |   1160 | //
 | 
| sl@0 |   1161 | // 
 | 
| sl@0 |   1162 | //
 | 
| sl@0 |   1163 | 	{
 | 
| sl@0 |   1164 | 	switch(aInterfaceId)
 | 
| sl@0 |   1165 | 		{
 | 
| sl@0 |   1166 | 		case EBlockMapInterface:
 | 
| sl@0 |   1167 | 			aInterface = (CFileCB::MBlockMapInterface*) this;
 | 
| sl@0 |   1168 | 			return KErrNone;
 | 
| sl@0 |   1169 | 
 | 
| sl@0 |   1170 | 		case EGetLocalDrive:
 | 
| sl@0 |   1171 | 			return (RofsMount()).LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface);
 | 
| sl@0 |   1172 | 
 | 
| sl@0 |   1173 | 		default:
 | 
| sl@0 |   1174 | 			return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
 | 
| sl@0 |   1175 | 		}
 | 
| sl@0 |   1176 | 	}
 |