os/kernelhwsrv/userlibandfileserver/fileserver/scomp/sc_comp.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2003-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 "sc_std.h"
    17 
    18 
    19 const TInt KMajorVersionNumber=1;
    20 const TInt KMinorVersionNumber=1;
    21 
    22 _LIT(KRofsName,"Rofs");
    23 
    24 #ifdef __WINS__
    25 _LIT(KRomName,"Win32");
    26 #else
    27 _LIT(KRomName,"Rom");
    28 #endif
    29 
    30 _LIT(KCompositeName,"Composite");
    31 
    32 
    33 static void Fault(TCompFault aFault)
    34 //
    35 // Report a fault in the composite file system.
    36 //
    37 	{
    38 	User::Panic(_L("COMPFILESYS"),aFault);
    39 	}
    40 
    41 
    42 CCompFileSystem::CCompFileSystem()
    43 	{
    44 	__PRINT1(_L("CCompFileSystem()[0x%x]"), this);
    45 	}
    46 
    47 
    48 CCompFileSystem::~CCompFileSystem()
    49 	{
    50 	__PRINT1(_L("~CCompFileSystem()[0x%x]"),this);
    51 	if (iMount)
    52 		{
    53 		iMount->NullCompFileSystem();
    54 		}
    55 	}
    56 
    57 
    58 TInt CCompFileSystem::Install()
    59 //
    60 // Install the file system
    61 //
    62 	{
    63 	__PRINT1(_L("CCompFileSystem::Install()[0x%x]"), this);
    64 	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
    65 	return(SetName(&KCompositeName));
    66 	}
    67 
    68 
    69 CMountCB* CCompFileSystem::NewMountL() const
    70 //
    71 // Create a new mount control block
    72 //
    73 	{
    74 	__PRINT1(_L("CCompFileSystem::NewMountL()[0x%x]"), this);
    75 	
    76  	// Composite FS is a singleton, and can only have one mount.
    77  	// If it already exists, just return the existin one.
    78  	if (iMount == NULL)
    79  		{
    80  		((CCompFileSystem*)this)->iMount = new(ELeave) CCompMountCB((CCompFileSystem *)this);
    81 		TRAPD(err,iMount->NewRomMountL());
    82 		if(err!=KErrNone)
    83 			{
    84 			iMount->Close();
    85 			User::Leave(err);
    86 			}
    87  		}
    88 
    89 	__PRINT1(_L("  created CCompMountCB:0x%x"),iMount);
    90 
    91 	return (iMount);
    92 	}
    93 
    94 
    95 CFileCB* CCompFileSystem::NewFileL() const
    96 //
    97 // Create a new file
    98 //
    99 	{
   100 	__PRINT(_L("CCompFileSystem::NewFileL()"));
   101 	CFileCB* pFile=new(ELeave) CCompFileCB;
   102 	__PRINT1(_L("file at 0x%x"),pFile);
   103 	return(pFile);
   104 	}
   105 
   106 
   107 CDirCB* CCompFileSystem::NewDirL() const
   108 //
   109 // create a new directory lister
   110 //
   111 	{
   112 	__PRINT(_L("CCompFileSystem::NewDirL()"));
   113 	
   114 	CCompDirCB* pDir=new (ELeave) CCompDirCB;
   115 	
   116 	CleanupStack::PushL(pDir);
   117 	
   118 	TInt count = iMount->iMounts.Count();
   119     TInt  r=KErrNone;
   120     
   121 	for(TInt idx=0; idx<count; idx++)
   122 		{
   123 	    TRAPD(err, r=pDir->iDirs.Append(iMount->iMounts[idx].iFs->NewDirL()));
   124 		if(err!= KErrNone || r != KErrNone)
   125 			{
   126 			pDir->Close();
   127 			User::Leave(err == KErrNone ? r : err);
   128 			}
   129         }
   130 
   131 	CleanupStack::Pop(pDir);
   132   
   133     __PRINT1(_L("dir at 0x%x"),pDir);
   134 	return(pDir);		
   135 	}
   136 
   137 
   138 CFormatCB* CCompFileSystem::NewFormatL() const
   139 //
   140 // Create a new media formatter
   141 //
   142 	{
   143 	User::Leave(KErrAccessDenied);
   144 	return(NULL);
   145 	}
   146 
   147 
   148 void CCompFileSystem::DriveInfo(TDriveInfo& anInfo,TInt /*aDriveNumber*/) const
   149 //
   150 // Return drive info
   151 //
   152 	{
   153 	__PRINT(_L("CCompFileSystem::DriveInfo()"));
   154 	anInfo.iMediaAtt=KMediaAttWriteProtected;
   155 	anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
   156 	anInfo.iType=EMediaRom;
   157 	}
   158 
   159 
   160 TInt CCompFileSystem::DefaultPath(TDes& /*aPath*/) const
   161 //
   162 // Return the initial default path.
   163 //
   164 	{
   165 	Fault(ECompFsDefaultPath);
   166 	return(KErrNone);
   167 	}
   168 
   169 
   170 CFileSystem* CCompFileSystem::NewL()
   171 //
   172 //
   173 //
   174 	{
   175 	__PRINT(_L("CCompFileSystem::NewL()"));
   176 	CCompFileSystem* pFs = new(ELeave) CCompFileSystem;
   177 
   178 	__PRINT1(_L("CompFs=0x%x"),pFs);
   179 	return (pFs);
   180 	}
   181 
   182 CCompMountCB::~CCompMountCB()
   183 //
   184 //
   185 //
   186 	{
   187   	__PRINT1(_L("~CCompMountCB() this=0x%x"),this);
   188   
   189 	
   190 	for(TInt mount=iMounts.Count(); mount--;)
   191 		iMounts[mount].iMount->Close();
   192 		
   193 	iMounts.Close();
   194 
   195 	if (iFileSystem)
   196 		{
   197 		iFileSystem->NullMount();
   198 		}
   199 	}
   200 
   201 void CCompMountCB::NewRomMountL()
   202 //
   203 // Creates a new ROM mount, and adds it to the list.
   204 //
   205 {
   206 	CFileSystem* romFs= GetFileSystem(KRomName);
   207 	if(!romFs)
   208 		{
   209 		User::Leave(KErrNotFound);
   210 		}
   211 
   212 	CMountCB* romMount = romFs->NewMountL();	    	
   213     User::LeaveIfError(iMounts.Append(TCompMount(romFs,romMount)));
   214 }
   215 	
   216 
   217 
   218 void CCompMountCB::MountL(TBool aForceMount)
   219 //
   220 // Mount a media. Only allowed to leave with KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
   221 //
   222 //
   223 	{
   224 	__PRINT(_L("CCompMountCB::MountL()"));
   225 	// First mount rom
   226 	RomMount()->SetDrive(&Drive());
   227 	RomMount()->MountL(aForceMount);
   228 
   229 	// Mounts count starts at 1, as ROMFS starts in slot one.
   230 	// If its still 1 on mount, then no mounts have been added.
   231 	// To maintain compatibility with the previous version of this API,
   232 	// (where you couldn't specifically add mounts) in this case we mount
   233 	// ROFS by default.  
   234 	// (There would be little point mounting it with only one FS)
   235 	
   236 	if (iMounts.Count()==1) 
   237 		{
   238 		CFileSystem* rofsFs = GetFileSystem(KRofsName);
   239 		if(!rofsFs)
   240 			User::Leave(KErrUnknown);
   241 		
   242 		AddFsToCompositeMount(rofsFs);
   243 		}
   244 
   245 	SetVolumeName(_L("RomDrive").AllocL());
   246 	
   247 	// combine sizes
   248 	for(TInt mount=iMounts.Count(); mount--;)
   249 		iSize+= iMounts[mount].iMount->Size();
   250 		
   251 	// no need to update iUniqueID since 0 in both rom and rofs
   252 	}
   253 
   254 
   255  TInt CCompMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) 
   256 	{
   257 	// aInterfaceId	: If EAddFsToCompositeMount, method mounts a media and adds to CompFS.
   258 	//				: Local drive mapping for this mount's drive (CompFS's) 
   259 	//				  should be alterd to indicate the local drive to be added.
   260 	// aIntput    	: CFileSystem* for the mount to be added.
   261 	// aInterFace	: Unused.
   262 	switch(aInterfaceId)
   263 		{
   264 		case CMountCB::EFileAccessor:
   265 			((CMountCB::MFileAccessor*&) aInterface) = this;
   266 			return KErrNone;
   267 
   268 		case EAddFsToCompositeMount:
   269 			return(AddFsToCompositeMount((CFileSystem*) aInput));
   270 
   271 		case CMountCB::ELocalBufferSupport:
   272 			{
   273 			CCompFileCB* file = (CCompFileCB*) aInput;
   274 			return file?file->TrueFile()->Mount().LocalBufferSupport():KErrNone;
   275 			}
   276 
   277 		default:
   278 			return (CMountCB::GetInterface(aInterfaceId,aInterface,aInput));
   279 		}
   280 	}
   281 
   282 /**
   283     Mounts a media with the provided filesystem and adds to the composite mount.  
   284     Local drive mapping for this mount's drive (CompFS's) should be altered to indicate the local drive to be added.
   285 */
   286 TInt CCompMountCB::AddFsToCompositeMount(CFileSystem* aFileSystem)
   287  	{
   288  	__PRINT1(_L("CCompMountCB::AddFsToCompositeMount(0x%x)"), aFileSystem);
   289     
   290     CMountCB* newMount=NULL;
   291 	TRAPD(err,newMount = aFileSystem->NewMountL());
   292 	if (err==KErrNone)
   293 		{
   294         newMount->InitL(Drive(), aFileSystem);
   295         TRAP(err,newMount->MountL(EFalse));
   296 		if (err==KErrNone)
   297 			{
   298 		    err = iMounts.Append(TCompMount(aFileSystem,newMount));
   299             if (err!=KErrNone) 
   300             return err;	
   301 
   302 			TInt r = newMount->AddToCompositeMount(iMounts.Count()-1);
   303 
   304 			if(r == KErrNotSupported)
   305 				r = KErrNone;
   306              
   307             return r;	
   308 			}
   309 	
   310 		}
   311 	
   312     return err;
   313  	}
   314 
   315 TInt CCompMountCB::ReMount()
   316 //
   317 // Try and remount this media.
   318 //
   319 	{
   320 	return(0);
   321 	}
   322 
   323 
   324 void CCompMountCB::Dismounted()
   325 //
   326 // Dummy implementation of pure virtual function
   327 //
   328 	{}
   329 
   330 	
   331 void CCompMountCB::VolumeL(TVolumeInfo& aVolume) const
   332 //
   333 //
   334 // Return the volume info.
   335 //
   336 	{
   337 	__PRINT(_L("CCompMountCB::VolumeL()"));
   338 	aVolume.iFree=0;
   339 	}
   340 
   341 
   342 void CCompMountCB::SetVolumeL(TDes& /*aName*/)
   343 //
   344 //
   345 // Set the volume label.
   346 //
   347 	{
   348 	User::Leave(KErrAccessDenied);
   349 	}
   350 
   351 void CCompMountCB::MkDirL(const TDesC& /*aName*/)
   352 //
   353 // Make a directory.
   354 //
   355 	{
   356 	User::Leave(KErrAccessDenied);
   357 	}
   358 
   359 void CCompMountCB::RmDirL(const TDesC& /*aName*/)
   360 //
   361 // Remove a directory.
   362 //
   363 	{
   364 	User::Leave(KErrAccessDenied);
   365 	}
   366 
   367 void CCompMountCB::DeleteL(const TDesC& /*aName*/)
   368 //
   369 // Delete a file.
   370 //
   371 	{
   372 	User::Leave(KErrAccessDenied);
   373 	}
   374 
   375 void CCompMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
   376 //
   377 // Rename a file or directory.
   378 //
   379 	{
   380 	User::Leave(KErrAccessDenied);
   381 	}
   382 
   383 void CCompMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
   384 //
   385 // Atomic replace.
   386 //
   387 	{
   388 	User::Leave(KErrAccessDenied);
   389 	}
   390 
   391 
   392 void CCompMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
   393 //
   394 // Get entry details.
   395 //
   396 	{
   397 	__PRINT(_L("CCompMountCB::EntryL()"));
   398 	TInt lesserErr = KErrNone;
   399 	TInt err = KErrPathNotFound;
   400 	TInt idx = iMounts.Count();
   401 	
   402 	// Look for entry on each mount, until it finds one, starting at the top.
   403 	while(idx--)
   404 		{
   405 		TRAP(err, iMounts[idx].iMount->EntryL(aName,anEntry));
   406 		
   407 		// There will often be more then one error encountered when trying
   408 		// to find an entry.  If the entry is not found on any mount, but it
   409 		// did find its path, it should not return a path error.
   410 		// To ensure this, the last non-path related error must be remembered.
   411 		if ((err != KErrPathNotFound) && (err != KErrPathHidden))
   412 			lesserErr=err;
   413 		
   414 		// It can stop looking for the entry when it either finds it
   415 		// or discovers its hidden. (ie An error other then NotFound)
   416 		if((err != KErrNotFound) && (err != KErrPathNotFound))
   417 			break;
   418 		}
   419 		
   420 	if (err!=KErrNone)
   421 		User::Leave(lesserErr?lesserErr:err);
   422 	}
   423 
   424 
   425 void CCompMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
   426 //
   427 // Set entry details.
   428 //
   429 	{
   430 	User::Leave(KErrAccessDenied);
   431 	}
   432 
   433 
   434 static TInt InitFile(CFileCB* aCompFile, CFileCB* aTrueFile,CMountCB* aRealMount,TUint8 aQueOffset)
   435 //
   436 // Initialise the true file object with values set in the composite file object
   437 // by TDrive
   438 //
   439 	{
   440     TRAPD(r,aTrueFile->InitL(&aCompFile->Drive(),&aCompFile->Drive(),aCompFile->FileName().Des().AllocL() ) );
   441 	if(r!=KErrNone)
   442 		return(r);
   443 	
   444 	aTrueFile->SetMount(aRealMount);
   445 	aTrueFile->SetShare(aCompFile->Share());
   446 	r=aTrueFile->Mount().Open();
   447 	if(r==KErrNone)
   448 		{
   449 		// destructor for CFileCB only calls close on the mount if iMountLink set
   450 		TDblQue<CFileCB>* pQue=(TDblQue<CFileCB>*)((TUint8*)aRealMount+aQueOffset);
   451 		pQue->AddLast(*aTrueFile);
   452 		}
   453 	return(r);
   454 	}
   455 
   456 
   457 void CCompMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
   458 //
   459 // Open a file on the current mount.
   460 //
   461 	{
   462 	__PRINT1(_L("CCompMountCB::FileOpenL() %S"), &aName);
   463 
   464 
   465 	TInt err = KErrPathNotFound;
   466 	TInt lesserErr = KErrNone;
   467 	CFileCB* pTrueFile = NULL;
   468 	TInt idx = iMounts.Count();
   469 	
   470 	// Look for file on each mount, until it finds one, starting at the top.
   471 	while(idx--)
   472 		{
   473 		CMountCB* mount = iMounts[idx].iMount;
   474 		pTrueFile = iMounts[idx].iFs->NewFileL();
   475 		TUint8 offset=(TUint8)(((TUint8*)&iMountQ-(TUint8*)this));
   476 		err = InitFile(aFile,pTrueFile,mount,offset);
   477 
   478 		if(err == KErrNone)
   479 			TRAP(err, mount->FileOpenL(aName,aMode,anOpen,pTrueFile));
   480 
   481 		__PRINT2(_L("opening file on mount %d [err=%d]"),idx,err);
   482 
   483 		// If success, stop looking.
   484 		if (err == KErrNone)
   485 			break;
   486 
   487 		// Not opened, so use Close() to cause file object to be deleted
   488 		pTrueFile->Close();
   489 		
   490 		// If the file is not found on any mount, but it did find its path,
   491 		// it should not return a path error.
   492 		// To ensure this, the last non-path related error must be remembered.
   493 		if ((err != KErrPathNotFound) && (err != KErrPathHidden))
   494 			lesserErr=err;
   495 		
   496 		// Stop search if error other than file cannot be found.
   497 		// A common error for this will be one of the hidden errors.
   498 		// Note that for these, the lesser error calculation above
   499 		// is still needed for these. 
   500 		if(err != KErrNotFound && err != KErrPathNotFound)
   501 			break;
   502 		}
   503 
   504 	if (err!=KErrNone)
   505 		User::Leave(lesserErr?lesserErr:err);
   506 
   507 	aFile->SetSize(pTrueFile->Size());
   508 	aFile->SetAtt(pTrueFile->Att());
   509 	aFile->SetModified(pTrueFile->Modified());
   510 	((CCompFileCB*)aFile)->SetTrueFile(pTrueFile);
   511 	}
   512 
   513 
   514 TInt CCompMountCB::GetFileUniqueId(const TDesC& /* aName */, TInt64& aUniqueId)
   515 	{
   516 	// Get unique identifier for the file - for Composite File System will just return zero
   517 	aUniqueId = MAKE_TINT64(0,0);
   518 	return KErrNone;
   519 	}
   520 
   521 TInt CCompMountCB::Spare3(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
   522 	{
   523 	return KErrNotSupported;
   524 	}
   525 
   526 TInt CCompMountCB::Spare2(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
   527 	{
   528 	return KErrNotSupported;
   529 	}
   530 
   531 TInt CCompMountCB::Spare1(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
   532 	{
   533 	return KErrNotSupported;
   534 	}
   535 
   536 
   537 
   538 static void SetAtt(CDirCB* aDir,TUint8 aOffset,TUint aValue)
   539 //
   540 //
   541 //
   542 	{	
   543 	TUint8* pA=(TUint8*)aDir+aOffset;
   544 	*(TUint*)pA=aValue;	
   545 	}
   546 
   547 	
   548 static void SetUid(CDirCB* aDir,TUint8 aOffset,TUidType aValue)
   549 //
   550 //
   551 //
   552 	{
   553 	TUint8* pU=(TUint8*)aDir+aOffset;
   554 	*(TUidType*)pU=aValue;
   555 	}
   556 
   557 
   558 TInt CCompDirCB::InitDir(CDirCB* aTrg,CMountCB* aMount)
   559 //
   560 //
   561 //
   562 	{
   563 	TRAPD(r,aTrg->InitL(&Drive()));
   564 	if(r!=KErrNone)
   565 		return(r);
   566 	aTrg->SetMount(aMount);
   567 	r=aTrg->Mount().Open();
   568 	if(r!=KErrNone)
   569 		{
   570 		aTrg->SetMount(NULL);
   571 		return(r);
   572 		}
   573 	SetAtt(aTrg,(TUint8)((TUint8*)&iAtt-(TUint8*)this),iAtt);
   574 	SetUid(aTrg,(TUint8)((TUint8*)&iUidType-(TUint8*)this),iUidType);
   575 	aTrg->Mount().DecLock();
   576 	return(KErrNone);
   577 	}
   578 
   579 
   580 void CCompMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
   581 //
   582 // Open a directory on the current mount.
   583 //
   584 	{
   585 	__PRINT(_L("CCompMountCB::DirOpenL()"));
   586 	CCompDirCB* pD=(CCompDirCB*)aDir;
   587 	pD->iMatch=aName.AllocL();
   588 
   589 	TInt err = KErrPathNotFound;
   590 	TInt idx = iMounts.Count();
   591 	TBool anyFound = EFalse;
   592 	pD->iCurrentDir = -1;
   593 
   594 	while(idx) // Open dir on every mount it exists.
   595 		{
   596 		idx--;
   597 		CDirCB* theDir = pD->iDirs[idx];
   598 		CMountCB* theMount = iMounts[idx].iMount;
   599 		err = pD->InitDir(theDir, theMount);
   600 		if(err == KErrNone)
   601 			TRAP(err, theMount->DirOpenL(aName,theDir));
   602 
   603 		if(err == KErrNone)
   604 			{
   605 			if(!anyFound)
   606 				{
   607 				anyFound = ETrue;
   608 				pD->iCurrentDir = idx;
   609 				}
   610 			continue;
   611 			}
   612 			
   613 		pD->iDirs[idx]->Close(); // deletes object
   614 		pD->iDirs[idx] = NULL;
   615 
   616 		if (err == KErrPathHidden)
   617 			{
   618 			// Dont look for anythng below this hidden dir.
   619 			break;
   620 			}
   621 		else if (err != KErrPathNotFound)
   622 			{
   623 			// An unexpected error - make it report this to caller!
   624 			anyFound = EFalse;
   625 			break;
   626 			}
   627 		}
   628 
   629 	// If we broke before bottom, close the remaining
   630 	while (idx--)
   631 		{
   632 		pD->iDirs[idx]->Close();
   633 		pD->iDirs[idx] = NULL;
   634 		}
   635 	
   636 	// If we didnt find anythng at all, or some other error, leave.
   637 	if(!anyFound) 
   638 		User::Leave(err);
   639 
   640 	}
   641 
   642 	
   643 void CCompMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aTrg*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
   644 //
   645 // Read up to aLength data directly
   646 //
   647 	{
   648 	User::Leave(KErrAccessDenied);
   649 	}
   650 
   651 
   652 void CCompMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
   653 //
   654 // Write aLength data
   655 //
   656 	{
   657 	User::Leave(KErrAccessDenied);
   658 	}
   659 	
   660 	
   661 void CCompMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/)
   662 //
   663 // Return the short name associated with aLongName
   664 // Assumes all rom names are 8.3
   665 //
   666 	{
   667 	User::Leave(KErrNotSupported);
   668 	}
   669 
   670 
   671 void CCompMountCB::GetLongNameL(const TDesC& /*aShortName*/,TDes& /*aLongName*/)
   672 //
   673 // Return the short name associated with aLongName
   674 // Assumes all rom names are 8.3
   675 //
   676 	{
   677 	User::Leave(KErrNotSupported);
   678 	}	
   679 
   680 
   681 void CCompMountCB::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
   682 //
   683 // Return the address of the file if it is in rom
   684 //
   685 	{
   686 	__PRINT(_L("CCompMountCB::IsFileInRom()"));
   687 	TEntry entry;
   688 	aFileStart=NULL;
   689 	TInt idx = iMounts.Count();
   690 
   691 	while(idx--)
   692 		{
   693 		TRAPD(r,iMounts[idx].iMount->EntryL(aFileName,entry));
   694 		if(r==KErrNone)
   695 			{
   696 			// File exists on mount, check whether it is rom-based
   697 			iMounts[idx].iMount->IsFileInRom(aFileName,aFileStart);
   698 			break;
   699 			}
   700 		else if(r != KErrNotFound && r != KErrPathNotFound)
   701 			{
   702 			break;
   703 			}	
   704 		}
   705 	}
   706 
   707 
   708 void CCompMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
   709 //
   710 //	Starting from aPos, read aLength bytes of a file into a Trg, 
   711 //	regardless of lock state
   712 //
   713 	{
   714 	__PRINT(_L("CCompMountCB::ReadSectionL()"));
   715 	TInt lesserErr = KErrNone;
   716 	TInt err = KErrPathNotFound;
   717 	TInt idx = iMounts.Count();
   718 	
   719 	 // Look for file on each mount, until it finds one, starting at the top.
   720 	while(idx--)
   721 		{
   722 		TRAP(err, iMounts[idx].iMount->ReadSectionL(aName,aPos,aTrg,aLength,aMessage));
   723 		
   724 		// If the file is not found on any mount, but it did find its path,
   725 		// it should not return a path error.
   726 		// To ensure this, the last non-path related error must be remembered.
   727 		if ((err != KErrPathNotFound) && (err != KErrPathHidden))
   728 			lesserErr=err;
   729 			
   730 		// Break if file was found, it was hidden, or some unexpected error
   731 		// (ie break if file or pathe not found)
   732 		// Note: If hidden, lesserErr calulation above still needed.
   733 		if ((err != KErrNotFound) && (err != KErrPathNotFound))
   734 			break;
   735 		}
   736 		
   737 	if (err!=KErrNone)
   738 		User::Leave(lesserErr?lesserErr:err);
   739 	}
   740 
   741 
   742 CCompFileCB::CCompFileCB()
   743 	{}
   744 
   745 
   746 CCompFileCB::~CCompFileCB()
   747 	{
   748 	__PRINT1(_L("~CCompFileCB()[0x%x]"),this);
   749 	if(TrueFile())
   750 		TrueFile()->Close();
   751 	}
   752 
   753 
   754 void CCompFileCB::RenameL(const TDesC& /*aNewName*/)
   755 //
   756 // Rename the file.
   757 //
   758 	{
   759 	User::Leave(KErrAccessDenied);
   760 	}
   761 
   762 
   763 void CCompFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
   764 //
   765 // Read from the file.
   766 //
   767 	{
   768 	__PRINT(_L("CCompFileCB::ReadL()"));
   769 	TrueFile()->ReadL(aPos,aLength,aDes,aMessage);
   770 	}
   771 
   772 
   773 void CCompFileCB::WriteL(TInt /*aPos*/,TInt& /*aLength*/,const TAny* /*aDes*/,const RMessagePtr2& /*aMessage*/)
   774 //
   775 // Write to the file.
   776 //
   777 	{
   778 	User::Leave(KErrAccessDenied);
   779 	}
   780 
   781 
   782 TInt CCompFileCB::Address(TInt& aPos) const
   783 //
   784 // Return address of the file at aPos
   785 //
   786 	{
   787 	__PRINT(_L("CCompFileCB::Address()"));
   788 	return(TrueFile()->Address(aPos));
   789 	}
   790 
   791 
   792 void CCompFileCB::SetSizeL(TInt /*aSize*/)
   793 //
   794 // Set the file size.
   795 //
   796 	{
   797 	User::Leave(KErrAccessDenied);
   798 	}
   799 
   800 
   801 void CCompFileCB::SetEntryL(const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
   802 //
   803 // Set the entry's attributes and modified time.
   804 //
   805 	{
   806 	User::Leave(KErrAccessDenied);
   807 	}
   808 
   809 
   810 void CCompFileCB::FlushDataL()
   811 //
   812 // Commit any buffered date to the media.
   813 //
   814 	{
   815 	User::Leave(KErrAccessDenied);
   816 	}
   817 
   818 
   819 void CCompFileCB::FlushAllL()
   820 //
   821 // Commit any buffered date to the media.
   822 //
   823 	{
   824 	User::Leave(KErrAccessDenied);
   825 	}
   826 
   827 
   828 TInt CCompFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   829 	{
   830 	if (TrueFile())
   831 	return TrueFile()->GetInterface(aInterfaceId, aInterface, aInput);
   832 	else
   833 		return KErrNotSupported;
   834 	}
   835 
   836 
   837 CCompDirCB::CCompDirCB()
   838 //
   839 //
   840 //
   841 	{}
   842 
   843 
   844 CCompDirCB::~CCompDirCB()
   845 //
   846 //
   847 //
   848 	{
   849 	__PRINT1(_L("~CCompDirCB() [0x%x]"),this);
   850 	for(TInt dir=iDirs.Count(); dir--;)
   851 		{
   852 		if (iDirs[dir])
   853 			iDirs[dir]->Close();
   854 		}
   855 	iDirs.Close();
   856 	delete iMatch;
   857 	}
   858 
   859 
   860 void CCompDirCB::ReadL(TEntry& anEntry)
   861 //
   862 // Reads the next directory entry.
   863 //
   864 	{
   865 	__PRINT(_L("CCompDirCB::ReadL()"));
   866 
   867 	if(Pending())
   868 		{
   869 		CDirCB* pDir = iDirs[iCurrentDir];
   870 		pDir->SetPending(ETrue);
   871 		TRAPD(r,pDir->ReadL(anEntry));
   872 		__ASSERT_ALWAYS(r!=KErrEof,Fault(ECompDirReadPending));
   873 		SetPending(pDir->Pending());
   874 		User::LeaveIfError(r);
   875 		return;
   876 		}
   877 	
   878 	if(iCurrentDir < 0)
   879 		User::Leave(KErrEof);
   880 
   881 	TFileName match(*iMatch);
   882 	TInt namePos=match.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
   883 	TPtrC dirName=match.Left(namePos);
   884 	TFileName filename;
   885 	TInt err;
   886 
   887 	do
   888 		{
   889 		CDirCB* theDir = iDirs[iCurrentDir];
   890 		if(theDir)
   891 			{
   892 			FOREVER // loop until we can read no more (EOF or other err)
   893 					// If non-duplicate entry found, it returns.
   894 				{
   895 				TRAP(err, theDir->ReadL(anEntry));
   896 
   897 				if(err != KErrNone)
   898 					break;
   899 				
   900 				__PRINT2(_L("CCompDirCB:: ReadL got = '%S' from dir %d"),&anEntry.iName, iCurrentDir);
   901 
   902 				filename=dirName;
   903 				filename+=anEntry.iName;
   904 				
   905 				if (!IsDuplicate(filename))
   906 					return;
   907 				}
   908 				
   909 			// We have either reached EOF for CurrentDir or encounted an error.
   910 			
   911 			__PRINT1(_L("CCompDirCB:: ReadL err = %d"),err);
   912 			
   913 			if(err != KErrEof)
   914 				{
   915 				User::Leave(err);
   916 				}
   917 			}
   918 		}
   919 
   920 	while (iCurrentDir--);
   921 		
   922 	User::Leave(KErrEof);
   923 	}
   924 
   925 
   926 TBool CCompDirCB::IsDuplicate(TFileName& aFilename)
   927 //
   928 // Is used by ReadL to determine if a file name read is a duplicate of
   929 // a filename already read bit it.
   930 //
   931 	{	
   932 	RArray<TCompMount>	&mounts = ((CCompMountCB*)&Mount())->iMounts;	
   933 	TInt count = mounts.Count();
   934 	TEntry tmpEntry;
   935 	__PRINT1(_L("theMount->iMounts.Count() = %d"),count);
   936 	
   937 	for (TInt idx = iCurrentDir+1; idx < count; idx++)
   938 		{
   939 		TRAPD(r, mounts[idx].iMount->EntryL(aFilename,tmpEntry));
   940 		
   941 		if ((r == KErrNone) || (r == KErrHidden) || (r == KErrPathHidden))
   942 			{
   943 			__PRINT1(_L("CCompDirCB:: Duplicate (r=%d)"),r);
   944 			return (ETrue);
   945 			}
   946 		}		
   947 	return (EFalse);
   948 	}
   949 
   950 
   951 void CCompDirCB::StoreLongEntryNameL(const TDesC& aName)
   952 //
   953 // Stores the Long Entry Name
   954 //
   955 	{
   956 	__ASSERT_ALWAYS(iCurrentDir >= 0 && iDirs[iCurrentDir] != NULL, Fault(ECompDirStoreLongEntryNameL));
   957 	iDirs[iCurrentDir]->StoreLongEntryNameL(aName);
   958 	}
   959 
   960 
   961 extern "C" {
   962 
   963 EXPORT_C CFileSystem* CreateFileSystem()
   964 //
   965 // Create a new file system
   966 //
   967 	{
   968 	return(CCompFileSystem::NewL());
   969 	}
   970 }
   971