--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/scomp/sc_comp.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,971 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "sc_std.h"
+
+
+const TInt KMajorVersionNumber=1;
+const TInt KMinorVersionNumber=1;
+
+_LIT(KRofsName,"Rofs");
+
+#ifdef __WINS__
+_LIT(KRomName,"Win32");
+#else
+_LIT(KRomName,"Rom");
+#endif
+
+_LIT(KCompositeName,"Composite");
+
+
+static void Fault(TCompFault aFault)
+//
+// Report a fault in the composite file system.
+//
+ {
+ User::Panic(_L("COMPFILESYS"),aFault);
+ }
+
+
+CCompFileSystem::CCompFileSystem()
+ {
+ __PRINT1(_L("CCompFileSystem()[0x%x]"), this);
+ }
+
+
+CCompFileSystem::~CCompFileSystem()
+ {
+ __PRINT1(_L("~CCompFileSystem()[0x%x]"),this);
+ if (iMount)
+ {
+ iMount->NullCompFileSystem();
+ }
+ }
+
+
+TInt CCompFileSystem::Install()
+//
+// Install the file system
+//
+ {
+ __PRINT1(_L("CCompFileSystem::Install()[0x%x]"), this);
+ iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
+ return(SetName(&KCompositeName));
+ }
+
+
+CMountCB* CCompFileSystem::NewMountL() const
+//
+// Create a new mount control block
+//
+ {
+ __PRINT1(_L("CCompFileSystem::NewMountL()[0x%x]"), this);
+
+ // Composite FS is a singleton, and can only have one mount.
+ // If it already exists, just return the existin one.
+ if (iMount == NULL)
+ {
+ ((CCompFileSystem*)this)->iMount = new(ELeave) CCompMountCB((CCompFileSystem *)this);
+ TRAPD(err,iMount->NewRomMountL());
+ if(err!=KErrNone)
+ {
+ iMount->Close();
+ User::Leave(err);
+ }
+ }
+
+ __PRINT1(_L(" created CCompMountCB:0x%x"),iMount);
+
+ return (iMount);
+ }
+
+
+CFileCB* CCompFileSystem::NewFileL() const
+//
+// Create a new file
+//
+ {
+ __PRINT(_L("CCompFileSystem::NewFileL()"));
+ CFileCB* pFile=new(ELeave) CCompFileCB;
+ __PRINT1(_L("file at 0x%x"),pFile);
+ return(pFile);
+ }
+
+
+CDirCB* CCompFileSystem::NewDirL() const
+//
+// create a new directory lister
+//
+ {
+ __PRINT(_L("CCompFileSystem::NewDirL()"));
+
+ CCompDirCB* pDir=new (ELeave) CCompDirCB;
+
+ CleanupStack::PushL(pDir);
+
+ TInt count = iMount->iMounts.Count();
+ TInt r=KErrNone;
+
+ for(TInt idx=0; idx<count; idx++)
+ {
+ TRAPD(err, r=pDir->iDirs.Append(iMount->iMounts[idx].iFs->NewDirL()));
+ if(err!= KErrNone || r != KErrNone)
+ {
+ pDir->Close();
+ User::Leave(err == KErrNone ? r : err);
+ }
+ }
+
+ CleanupStack::Pop(pDir);
+
+ __PRINT1(_L("dir at 0x%x"),pDir);
+ return(pDir);
+ }
+
+
+CFormatCB* CCompFileSystem::NewFormatL() const
+//
+// Create a new media formatter
+//
+ {
+ User::Leave(KErrAccessDenied);
+ return(NULL);
+ }
+
+
+void CCompFileSystem::DriveInfo(TDriveInfo& anInfo,TInt /*aDriveNumber*/) const
+//
+// Return drive info
+//
+ {
+ __PRINT(_L("CCompFileSystem::DriveInfo()"));
+ anInfo.iMediaAtt=KMediaAttWriteProtected;
+ anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
+ anInfo.iType=EMediaRom;
+ }
+
+
+TInt CCompFileSystem::DefaultPath(TDes& /*aPath*/) const
+//
+// Return the initial default path.
+//
+ {
+ Fault(ECompFsDefaultPath);
+ return(KErrNone);
+ }
+
+
+CFileSystem* CCompFileSystem::NewL()
+//
+//
+//
+ {
+ __PRINT(_L("CCompFileSystem::NewL()"));
+ CCompFileSystem* pFs = new(ELeave) CCompFileSystem;
+
+ __PRINT1(_L("CompFs=0x%x"),pFs);
+ return (pFs);
+ }
+
+CCompMountCB::~CCompMountCB()
+//
+//
+//
+ {
+ __PRINT1(_L("~CCompMountCB() this=0x%x"),this);
+
+
+ for(TInt mount=iMounts.Count(); mount--;)
+ iMounts[mount].iMount->Close();
+
+ iMounts.Close();
+
+ if (iFileSystem)
+ {
+ iFileSystem->NullMount();
+ }
+ }
+
+void CCompMountCB::NewRomMountL()
+//
+// Creates a new ROM mount, and adds it to the list.
+//
+{
+ CFileSystem* romFs= GetFileSystem(KRomName);
+ if(!romFs)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ CMountCB* romMount = romFs->NewMountL();
+ User::LeaveIfError(iMounts.Append(TCompMount(romFs,romMount)));
+}
+
+
+
+void CCompMountCB::MountL(TBool aForceMount)
+//
+// Mount a media. Only allowed to leave with KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
+//
+//
+ {
+ __PRINT(_L("CCompMountCB::MountL()"));
+ // First mount rom
+ RomMount()->SetDrive(&Drive());
+ RomMount()->MountL(aForceMount);
+
+ // Mounts count starts at 1, as ROMFS starts in slot one.
+ // If its still 1 on mount, then no mounts have been added.
+ // To maintain compatibility with the previous version of this API,
+ // (where you couldn't specifically add mounts) in this case we mount
+ // ROFS by default.
+ // (There would be little point mounting it with only one FS)
+
+ if (iMounts.Count()==1)
+ {
+ CFileSystem* rofsFs = GetFileSystem(KRofsName);
+ if(!rofsFs)
+ User::Leave(KErrUnknown);
+
+ AddFsToCompositeMount(rofsFs);
+ }
+
+ SetVolumeName(_L("RomDrive").AllocL());
+
+ // combine sizes
+ for(TInt mount=iMounts.Count(); mount--;)
+ iSize+= iMounts[mount].iMount->Size();
+
+ // no need to update iUniqueID since 0 in both rom and rofs
+ }
+
+
+ TInt CCompMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
+ {
+ // aInterfaceId : If EAddFsToCompositeMount, method mounts a media and adds to CompFS.
+ // : Local drive mapping for this mount's drive (CompFS's)
+ // should be alterd to indicate the local drive to be added.
+ // aIntput : CFileSystem* for the mount to be added.
+ // aInterFace : Unused.
+ switch(aInterfaceId)
+ {
+ case CMountCB::EFileAccessor:
+ ((CMountCB::MFileAccessor*&) aInterface) = this;
+ return KErrNone;
+
+ case EAddFsToCompositeMount:
+ return(AddFsToCompositeMount((CFileSystem*) aInput));
+
+ case CMountCB::ELocalBufferSupport:
+ {
+ CCompFileCB* file = (CCompFileCB*) aInput;
+ return file?file->TrueFile()->Mount().LocalBufferSupport():KErrNone;
+ }
+
+ default:
+ return (CMountCB::GetInterface(aInterfaceId,aInterface,aInput));
+ }
+ }
+
+/**
+ Mounts a media with the provided filesystem and adds to the composite mount.
+ Local drive mapping for this mount's drive (CompFS's) should be altered to indicate the local drive to be added.
+*/
+TInt CCompMountCB::AddFsToCompositeMount(CFileSystem* aFileSystem)
+ {
+ __PRINT1(_L("CCompMountCB::AddFsToCompositeMount(0x%x)"), aFileSystem);
+
+ CMountCB* newMount=NULL;
+ TRAPD(err,newMount = aFileSystem->NewMountL());
+ if (err==KErrNone)
+ {
+ newMount->InitL(Drive(), aFileSystem);
+ TRAP(err,newMount->MountL(EFalse));
+ if (err==KErrNone)
+ {
+ err = iMounts.Append(TCompMount(aFileSystem,newMount));
+ if (err!=KErrNone)
+ return err;
+
+ TInt r = newMount->AddToCompositeMount(iMounts.Count()-1);
+
+ if(r == KErrNotSupported)
+ r = KErrNone;
+
+ return r;
+ }
+
+ }
+
+ return err;
+ }
+
+TInt CCompMountCB::ReMount()
+//
+// Try and remount this media.
+//
+ {
+ return(0);
+ }
+
+
+void CCompMountCB::Dismounted()
+//
+// Dummy implementation of pure virtual function
+//
+ {}
+
+
+void CCompMountCB::VolumeL(TVolumeInfo& aVolume) const
+//
+//
+// Return the volume info.
+//
+ {
+ __PRINT(_L("CCompMountCB::VolumeL()"));
+ aVolume.iFree=0;
+ }
+
+
+void CCompMountCB::SetVolumeL(TDes& /*aName*/)
+//
+//
+// Set the volume label.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+void CCompMountCB::MkDirL(const TDesC& /*aName*/)
+//
+// Make a directory.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+void CCompMountCB::RmDirL(const TDesC& /*aName*/)
+//
+// Remove a directory.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+void CCompMountCB::DeleteL(const TDesC& /*aName*/)
+//
+// Delete a file.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+void CCompMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
+//
+// Rename a file or directory.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+void CCompMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
+//
+// Atomic replace.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
+//
+// Get entry details.
+//
+ {
+ __PRINT(_L("CCompMountCB::EntryL()"));
+ TInt lesserErr = KErrNone;
+ TInt err = KErrPathNotFound;
+ TInt idx = iMounts.Count();
+
+ // Look for entry on each mount, until it finds one, starting at the top.
+ while(idx--)
+ {
+ TRAP(err, iMounts[idx].iMount->EntryL(aName,anEntry));
+
+ // There will often be more then one error encountered when trying
+ // to find an entry. If the entry is not found on any mount, but it
+ // did find its path, it should not return a path error.
+ // To ensure this, the last non-path related error must be remembered.
+ if ((err != KErrPathNotFound) && (err != KErrPathHidden))
+ lesserErr=err;
+
+ // It can stop looking for the entry when it either finds it
+ // or discovers its hidden. (ie An error other then NotFound)
+ if((err != KErrNotFound) && (err != KErrPathNotFound))
+ break;
+ }
+
+ if (err!=KErrNone)
+ User::Leave(lesserErr?lesserErr:err);
+ }
+
+
+void CCompMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
+//
+// Set entry details.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+static TInt InitFile(CFileCB* aCompFile, CFileCB* aTrueFile,CMountCB* aRealMount,TUint8 aQueOffset)
+//
+// Initialise the true file object with values set in the composite file object
+// by TDrive
+//
+ {
+ TRAPD(r,aTrueFile->InitL(&aCompFile->Drive(),&aCompFile->Drive(),aCompFile->FileName().Des().AllocL() ) );
+ if(r!=KErrNone)
+ return(r);
+
+ aTrueFile->SetMount(aRealMount);
+ aTrueFile->SetShare(aCompFile->Share());
+ r=aTrueFile->Mount().Open();
+ if(r==KErrNone)
+ {
+ // destructor for CFileCB only calls close on the mount if iMountLink set
+ TDblQue<CFileCB>* pQue=(TDblQue<CFileCB>*)((TUint8*)aRealMount+aQueOffset);
+ pQue->AddLast(*aTrueFile);
+ }
+ return(r);
+ }
+
+
+void CCompMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
+//
+// Open a file on the current mount.
+//
+ {
+ __PRINT1(_L("CCompMountCB::FileOpenL() %S"), &aName);
+
+
+ TInt err = KErrPathNotFound;
+ TInt lesserErr = KErrNone;
+ CFileCB* pTrueFile = NULL;
+ TInt idx = iMounts.Count();
+
+ // Look for file on each mount, until it finds one, starting at the top.
+ while(idx--)
+ {
+ CMountCB* mount = iMounts[idx].iMount;
+ pTrueFile = iMounts[idx].iFs->NewFileL();
+ TUint8 offset=(TUint8)(((TUint8*)&iMountQ-(TUint8*)this));
+ err = InitFile(aFile,pTrueFile,mount,offset);
+
+ if(err == KErrNone)
+ TRAP(err, mount->FileOpenL(aName,aMode,anOpen,pTrueFile));
+
+ __PRINT2(_L("opening file on mount %d [err=%d]"),idx,err);
+
+ // If success, stop looking.
+ if (err == KErrNone)
+ break;
+
+ // Not opened, so use Close() to cause file object to be deleted
+ pTrueFile->Close();
+
+ // If the file is not found on any mount, but it did find its path,
+ // it should not return a path error.
+ // To ensure this, the last non-path related error must be remembered.
+ if ((err != KErrPathNotFound) && (err != KErrPathHidden))
+ lesserErr=err;
+
+ // Stop search if error other than file cannot be found.
+ // A common error for this will be one of the hidden errors.
+ // Note that for these, the lesser error calculation above
+ // is still needed for these.
+ if(err != KErrNotFound && err != KErrPathNotFound)
+ break;
+ }
+
+ if (err!=KErrNone)
+ User::Leave(lesserErr?lesserErr:err);
+
+ aFile->SetSize(pTrueFile->Size());
+ aFile->SetAtt(pTrueFile->Att());
+ aFile->SetModified(pTrueFile->Modified());
+ ((CCompFileCB*)aFile)->SetTrueFile(pTrueFile);
+ }
+
+
+TInt CCompMountCB::GetFileUniqueId(const TDesC& /* aName */, TInt64& aUniqueId)
+ {
+ // Get unique identifier for the file - for Composite File System will just return zero
+ aUniqueId = MAKE_TINT64(0,0);
+ return KErrNone;
+ }
+
+TInt CCompMountCB::Spare3(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCompMountCB::Spare2(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCompMountCB::Spare1(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
+ {
+ return KErrNotSupported;
+ }
+
+
+
+static void SetAtt(CDirCB* aDir,TUint8 aOffset,TUint aValue)
+//
+//
+//
+ {
+ TUint8* pA=(TUint8*)aDir+aOffset;
+ *(TUint*)pA=aValue;
+ }
+
+
+static void SetUid(CDirCB* aDir,TUint8 aOffset,TUidType aValue)
+//
+//
+//
+ {
+ TUint8* pU=(TUint8*)aDir+aOffset;
+ *(TUidType*)pU=aValue;
+ }
+
+
+TInt CCompDirCB::InitDir(CDirCB* aTrg,CMountCB* aMount)
+//
+//
+//
+ {
+ TRAPD(r,aTrg->InitL(&Drive()));
+ if(r!=KErrNone)
+ return(r);
+ aTrg->SetMount(aMount);
+ r=aTrg->Mount().Open();
+ if(r!=KErrNone)
+ {
+ aTrg->SetMount(NULL);
+ return(r);
+ }
+ SetAtt(aTrg,(TUint8)((TUint8*)&iAtt-(TUint8*)this),iAtt);
+ SetUid(aTrg,(TUint8)((TUint8*)&iUidType-(TUint8*)this),iUidType);
+ aTrg->Mount().DecLock();
+ return(KErrNone);
+ }
+
+
+void CCompMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
+//
+// Open a directory on the current mount.
+//
+ {
+ __PRINT(_L("CCompMountCB::DirOpenL()"));
+ CCompDirCB* pD=(CCompDirCB*)aDir;
+ pD->iMatch=aName.AllocL();
+
+ TInt err = KErrPathNotFound;
+ TInt idx = iMounts.Count();
+ TBool anyFound = EFalse;
+ pD->iCurrentDir = -1;
+
+ while(idx) // Open dir on every mount it exists.
+ {
+ idx--;
+ CDirCB* theDir = pD->iDirs[idx];
+ CMountCB* theMount = iMounts[idx].iMount;
+ err = pD->InitDir(theDir, theMount);
+ if(err == KErrNone)
+ TRAP(err, theMount->DirOpenL(aName,theDir));
+
+ if(err == KErrNone)
+ {
+ if(!anyFound)
+ {
+ anyFound = ETrue;
+ pD->iCurrentDir = idx;
+ }
+ continue;
+ }
+
+ pD->iDirs[idx]->Close(); // deletes object
+ pD->iDirs[idx] = NULL;
+
+ if (err == KErrPathHidden)
+ {
+ // Dont look for anythng below this hidden dir.
+ break;
+ }
+ else if (err != KErrPathNotFound)
+ {
+ // An unexpected error - make it report this to caller!
+ anyFound = EFalse;
+ break;
+ }
+ }
+
+ // If we broke before bottom, close the remaining
+ while (idx--)
+ {
+ pD->iDirs[idx]->Close();
+ pD->iDirs[idx] = NULL;
+ }
+
+ // If we didnt find anythng at all, or some other error, leave.
+ if(!anyFound)
+ User::Leave(err);
+
+ }
+
+
+void CCompMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aTrg*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
+//
+// Read up to aLength data directly
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
+//
+// Write aLength data
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/)
+//
+// Return the short name associated with aLongName
+// Assumes all rom names are 8.3
+//
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+
+void CCompMountCB::GetLongNameL(const TDesC& /*aShortName*/,TDes& /*aLongName*/)
+//
+// Return the short name associated with aLongName
+// Assumes all rom names are 8.3
+//
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+
+void CCompMountCB::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
+//
+// Return the address of the file if it is in rom
+//
+ {
+ __PRINT(_L("CCompMountCB::IsFileInRom()"));
+ TEntry entry;
+ aFileStart=NULL;
+ TInt idx = iMounts.Count();
+
+ while(idx--)
+ {
+ TRAPD(r,iMounts[idx].iMount->EntryL(aFileName,entry));
+ if(r==KErrNone)
+ {
+ // File exists on mount, check whether it is rom-based
+ iMounts[idx].iMount->IsFileInRom(aFileName,aFileStart);
+ break;
+ }
+ else if(r != KErrNotFound && r != KErrPathNotFound)
+ {
+ break;
+ }
+ }
+ }
+
+
+void CCompMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
+//
+// Starting from aPos, read aLength bytes of a file into a Trg,
+// regardless of lock state
+//
+ {
+ __PRINT(_L("CCompMountCB::ReadSectionL()"));
+ TInt lesserErr = KErrNone;
+ TInt err = KErrPathNotFound;
+ TInt idx = iMounts.Count();
+
+ // Look for file on each mount, until it finds one, starting at the top.
+ while(idx--)
+ {
+ TRAP(err, iMounts[idx].iMount->ReadSectionL(aName,aPos,aTrg,aLength,aMessage));
+
+ // If the file is not found on any mount, but it did find its path,
+ // it should not return a path error.
+ // To ensure this, the last non-path related error must be remembered.
+ if ((err != KErrPathNotFound) && (err != KErrPathHidden))
+ lesserErr=err;
+
+ // Break if file was found, it was hidden, or some unexpected error
+ // (ie break if file or pathe not found)
+ // Note: If hidden, lesserErr calulation above still needed.
+ if ((err != KErrNotFound) && (err != KErrPathNotFound))
+ break;
+ }
+
+ if (err!=KErrNone)
+ User::Leave(lesserErr?lesserErr:err);
+ }
+
+
+CCompFileCB::CCompFileCB()
+ {}
+
+
+CCompFileCB::~CCompFileCB()
+ {
+ __PRINT1(_L("~CCompFileCB()[0x%x]"),this);
+ if(TrueFile())
+ TrueFile()->Close();
+ }
+
+
+void CCompFileCB::RenameL(const TDesC& /*aNewName*/)
+//
+// Rename the file.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
+//
+// Read from the file.
+//
+ {
+ __PRINT(_L("CCompFileCB::ReadL()"));
+ TrueFile()->ReadL(aPos,aLength,aDes,aMessage);
+ }
+
+
+void CCompFileCB::WriteL(TInt /*aPos*/,TInt& /*aLength*/,const TAny* /*aDes*/,const RMessagePtr2& /*aMessage*/)
+//
+// Write to the file.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+TInt CCompFileCB::Address(TInt& aPos) const
+//
+// Return address of the file at aPos
+//
+ {
+ __PRINT(_L("CCompFileCB::Address()"));
+ return(TrueFile()->Address(aPos));
+ }
+
+
+void CCompFileCB::SetSizeL(TInt /*aSize*/)
+//
+// Set the file size.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompFileCB::SetEntryL(const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
+//
+// Set the entry's attributes and modified time.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompFileCB::FlushDataL()
+//
+// Commit any buffered date to the media.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+void CCompFileCB::FlushAllL()
+//
+// Commit any buffered date to the media.
+//
+ {
+ User::Leave(KErrAccessDenied);
+ }
+
+
+TInt CCompFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
+ {
+ if (TrueFile())
+ return TrueFile()->GetInterface(aInterfaceId, aInterface, aInput);
+ else
+ return KErrNotSupported;
+ }
+
+
+CCompDirCB::CCompDirCB()
+//
+//
+//
+ {}
+
+
+CCompDirCB::~CCompDirCB()
+//
+//
+//
+ {
+ __PRINT1(_L("~CCompDirCB() [0x%x]"),this);
+ for(TInt dir=iDirs.Count(); dir--;)
+ {
+ if (iDirs[dir])
+ iDirs[dir]->Close();
+ }
+ iDirs.Close();
+ delete iMatch;
+ }
+
+
+void CCompDirCB::ReadL(TEntry& anEntry)
+//
+// Reads the next directory entry.
+//
+ {
+ __PRINT(_L("CCompDirCB::ReadL()"));
+
+ if(Pending())
+ {
+ CDirCB* pDir = iDirs[iCurrentDir];
+ pDir->SetPending(ETrue);
+ TRAPD(r,pDir->ReadL(anEntry));
+ __ASSERT_ALWAYS(r!=KErrEof,Fault(ECompDirReadPending));
+ SetPending(pDir->Pending());
+ User::LeaveIfError(r);
+ return;
+ }
+
+ if(iCurrentDir < 0)
+ User::Leave(KErrEof);
+
+ TFileName match(*iMatch);
+ TInt namePos=match.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
+ TPtrC dirName=match.Left(namePos);
+ TFileName filename;
+ TInt err;
+
+ do
+ {
+ CDirCB* theDir = iDirs[iCurrentDir];
+ if(theDir)
+ {
+ FOREVER // loop until we can read no more (EOF or other err)
+ // If non-duplicate entry found, it returns.
+ {
+ TRAP(err, theDir->ReadL(anEntry));
+
+ if(err != KErrNone)
+ break;
+
+ __PRINT2(_L("CCompDirCB:: ReadL got = '%S' from dir %d"),&anEntry.iName, iCurrentDir);
+
+ filename=dirName;
+ filename+=anEntry.iName;
+
+ if (!IsDuplicate(filename))
+ return;
+ }
+
+ // We have either reached EOF for CurrentDir or encounted an error.
+
+ __PRINT1(_L("CCompDirCB:: ReadL err = %d"),err);
+
+ if(err != KErrEof)
+ {
+ User::Leave(err);
+ }
+ }
+ }
+
+ while (iCurrentDir--);
+
+ User::Leave(KErrEof);
+ }
+
+
+TBool CCompDirCB::IsDuplicate(TFileName& aFilename)
+//
+// Is used by ReadL to determine if a file name read is a duplicate of
+// a filename already read bit it.
+//
+ {
+ RArray<TCompMount> &mounts = ((CCompMountCB*)&Mount())->iMounts;
+ TInt count = mounts.Count();
+ TEntry tmpEntry;
+ __PRINT1(_L("theMount->iMounts.Count() = %d"),count);
+
+ for (TInt idx = iCurrentDir+1; idx < count; idx++)
+ {
+ TRAPD(r, mounts[idx].iMount->EntryL(aFilename,tmpEntry));
+
+ if ((r == KErrNone) || (r == KErrHidden) || (r == KErrPathHidden))
+ {
+ __PRINT1(_L("CCompDirCB:: Duplicate (r=%d)"),r);
+ return (ETrue);
+ }
+ }
+ return (EFalse);
+ }
+
+
+void CCompDirCB::StoreLongEntryNameL(const TDesC& aName)
+//
+// Stores the Long Entry Name
+//
+ {
+ __ASSERT_ALWAYS(iCurrentDir >= 0 && iDirs[iCurrentDir] != NULL, Fault(ECompDirStoreLongEntryNameL));
+ iDirs[iCurrentDir]->StoreLongEntryNameL(aName);
+ }
+
+
+extern "C" {
+
+EXPORT_C CFileSystem* CreateFileSystem()
+//
+// Create a new file system
+//
+ {
+ return(CCompFileSystem::NewL());
+ }
+}
+