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