userlibandfileserver/fileserver/scomp/sc_comp.cpp
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     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