Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 const TInt KMajorVersionNumber=1;
20 const TInt KMinorVersionNumber=1;
22 _LIT(KRofsName,"Rofs");
25 _LIT(KRomName,"Win32");
30 _LIT(KCompositeName,"Composite");
33 static void Fault(TCompFault aFault)
35 // Report a fault in the composite file system.
38 User::Panic(_L("COMPFILESYS"),aFault);
42 CCompFileSystem::CCompFileSystem()
44 __PRINT1(_L("CCompFileSystem()[0x%x]"), this);
48 CCompFileSystem::~CCompFileSystem()
50 __PRINT1(_L("~CCompFileSystem()[0x%x]"),this);
53 iMount->NullCompFileSystem();
58 TInt CCompFileSystem::Install()
60 // Install the file system
63 __PRINT1(_L("CCompFileSystem::Install()[0x%x]"), this);
64 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber);
65 return(SetName(&KCompositeName));
69 CMountCB* CCompFileSystem::NewMountL() const
71 // Create a new mount control block
74 __PRINT1(_L("CCompFileSystem::NewMountL()[0x%x]"), this);
76 // Composite FS is a singleton, and can only have one mount.
77 // If it already exists, just return the existin one.
80 ((CCompFileSystem*)this)->iMount = new(ELeave) CCompMountCB((CCompFileSystem *)this);
81 TRAPD(err,iMount->NewRomMountL());
89 __PRINT1(_L(" created CCompMountCB:0x%x"),iMount);
95 CFileCB* CCompFileSystem::NewFileL() const
100 __PRINT(_L("CCompFileSystem::NewFileL()"));
101 CFileCB* pFile=new(ELeave) CCompFileCB;
102 __PRINT1(_L("file at 0x%x"),pFile);
107 CDirCB* CCompFileSystem::NewDirL() const
109 // create a new directory lister
112 __PRINT(_L("CCompFileSystem::NewDirL()"));
114 CCompDirCB* pDir=new (ELeave) CCompDirCB;
116 CleanupStack::PushL(pDir);
118 TInt count = iMount->iMounts.Count();
121 for(TInt idx=0; idx<count; idx++)
123 TRAPD(err, r=pDir->iDirs.Append(iMount->iMounts[idx].iFs->NewDirL()));
124 if(err!= KErrNone || r != KErrNone)
127 User::Leave(err == KErrNone ? r : err);
131 CleanupStack::Pop(pDir);
133 __PRINT1(_L("dir at 0x%x"),pDir);
138 CFormatCB* CCompFileSystem::NewFormatL() const
140 // Create a new media formatter
143 User::Leave(KErrAccessDenied);
148 void CCompFileSystem::DriveInfo(TDriveInfo& anInfo,TInt /*aDriveNumber*/) const
153 __PRINT(_L("CCompFileSystem::DriveInfo()"));
154 anInfo.iMediaAtt=KMediaAttWriteProtected;
155 anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal;
156 anInfo.iType=EMediaRom;
160 TInt CCompFileSystem::DefaultPath(TDes& /*aPath*/) const
162 // Return the initial default path.
165 Fault(ECompFsDefaultPath);
170 CFileSystem* CCompFileSystem::NewL()
175 __PRINT(_L("CCompFileSystem::NewL()"));
176 CCompFileSystem* pFs = new(ELeave) CCompFileSystem;
178 __PRINT1(_L("CompFs=0x%x"),pFs);
182 CCompMountCB::~CCompMountCB()
187 __PRINT1(_L("~CCompMountCB() this=0x%x"),this);
190 for(TInt mount=iMounts.Count(); mount--;)
191 iMounts[mount].iMount->Close();
197 iFileSystem->NullMount();
201 void CCompMountCB::NewRomMountL()
203 // Creates a new ROM mount, and adds it to the list.
206 CFileSystem* romFs= GetFileSystem(KRomName);
209 User::Leave(KErrNotFound);
212 CMountCB* romMount = romFs->NewMountL();
213 User::LeaveIfError(iMounts.Append(TCompMount(romFs,romMount)));
218 void CCompMountCB::MountL(TBool aForceMount)
220 // Mount a media. Only allowed to leave with KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown.
224 __PRINT(_L("CCompMountCB::MountL()"));
226 RomMount()->SetDrive(&Drive());
227 RomMount()->MountL(aForceMount);
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
234 // (There would be little point mounting it with only one FS)
236 if (iMounts.Count()==1)
238 CFileSystem* rofsFs = GetFileSystem(KRofsName);
240 User::Leave(KErrUnknown);
242 AddFsToCompositeMount(rofsFs);
245 SetVolumeName(_L("RomDrive").AllocL());
248 for(TInt mount=iMounts.Count(); mount--;)
249 iSize+= iMounts[mount].iMount->Size();
251 // no need to update iUniqueID since 0 in both rom and rofs
255 TInt CCompMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
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.
264 case CMountCB::EFileAccessor:
265 ((CMountCB::MFileAccessor*&) aInterface) = this;
268 case EAddFsToCompositeMount:
269 return(AddFsToCompositeMount((CFileSystem*) aInput));
271 case CMountCB::ELocalBufferSupport:
273 CCompFileCB* file = (CCompFileCB*) aInput;
274 return file?file->TrueFile()->Mount().LocalBufferSupport():KErrNone;
278 return (CMountCB::GetInterface(aInterfaceId,aInterface,aInput));
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.
286 TInt CCompMountCB::AddFsToCompositeMount(CFileSystem* aFileSystem)
288 __PRINT1(_L("CCompMountCB::AddFsToCompositeMount(0x%x)"), aFileSystem);
290 CMountCB* newMount=NULL;
291 TRAPD(err,newMount = aFileSystem->NewMountL());
294 newMount->InitL(Drive(), aFileSystem);
295 TRAP(err,newMount->MountL(EFalse));
298 err = iMounts.Append(TCompMount(aFileSystem,newMount));
302 TInt r = newMount->AddToCompositeMount(iMounts.Count()-1);
304 if(r == KErrNotSupported)
315 TInt CCompMountCB::ReMount()
317 // Try and remount this media.
324 void CCompMountCB::Dismounted()
326 // Dummy implementation of pure virtual function
331 void CCompMountCB::VolumeL(TVolumeInfo& aVolume) const
334 // Return the volume info.
337 __PRINT(_L("CCompMountCB::VolumeL()"));
342 void CCompMountCB::SetVolumeL(TDes& /*aName*/)
345 // Set the volume label.
348 User::Leave(KErrAccessDenied);
351 void CCompMountCB::MkDirL(const TDesC& /*aName*/)
356 User::Leave(KErrAccessDenied);
359 void CCompMountCB::RmDirL(const TDesC& /*aName*/)
361 // Remove a directory.
364 User::Leave(KErrAccessDenied);
367 void CCompMountCB::DeleteL(const TDesC& /*aName*/)
372 User::Leave(KErrAccessDenied);
375 void CCompMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
377 // Rename a file or directory.
380 User::Leave(KErrAccessDenied);
383 void CCompMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/)
388 User::Leave(KErrAccessDenied);
392 void CCompMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const
394 // Get entry details.
397 __PRINT(_L("CCompMountCB::EntryL()"));
398 TInt lesserErr = KErrNone;
399 TInt err = KErrPathNotFound;
400 TInt idx = iMounts.Count();
402 // Look for entry on each mount, until it finds one, starting at the top.
405 TRAP(err, iMounts[idx].iMount->EntryL(aName,anEntry));
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))
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))
421 User::Leave(lesserErr?lesserErr:err);
425 void CCompMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
427 // Set entry details.
430 User::Leave(KErrAccessDenied);
434 static TInt InitFile(CFileCB* aCompFile, CFileCB* aTrueFile,CMountCB* aRealMount,TUint8 aQueOffset)
436 // Initialise the true file object with values set in the composite file object
440 TRAPD(r,aTrueFile->InitL(&aCompFile->Drive(),&aCompFile->Drive(),aCompFile->FileName().Des().AllocL() ) );
444 aTrueFile->SetMount(aRealMount);
445 aTrueFile->SetShare(aCompFile->Share());
446 r=aTrueFile->Mount().Open();
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);
457 void CCompMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile)
459 // Open a file on the current mount.
462 __PRINT1(_L("CCompMountCB::FileOpenL() %S"), &aName);
465 TInt err = KErrPathNotFound;
466 TInt lesserErr = KErrNone;
467 CFileCB* pTrueFile = NULL;
468 TInt idx = iMounts.Count();
470 // Look for file on each mount, until it finds one, starting at the top.
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);
479 TRAP(err, mount->FileOpenL(aName,aMode,anOpen,pTrueFile));
481 __PRINT2(_L("opening file on mount %d [err=%d]"),idx,err);
483 // If success, stop looking.
487 // Not opened, so use Close() to cause file object to be deleted
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))
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)
505 User::Leave(lesserErr?lesserErr:err);
507 aFile->SetSize(pTrueFile->Size());
508 aFile->SetAtt(pTrueFile->Att());
509 aFile->SetModified(pTrueFile->Modified());
510 ((CCompFileCB*)aFile)->SetTrueFile(pTrueFile);
514 TInt CCompMountCB::GetFileUniqueId(const TDesC& /* aName */, TInt64& aUniqueId)
516 // Get unique identifier for the file - for Composite File System will just return zero
517 aUniqueId = MAKE_TINT64(0,0);
521 TInt CCompMountCB::Spare3(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
523 return KErrNotSupported;
526 TInt CCompMountCB::Spare2(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
528 return KErrNotSupported;
531 TInt CCompMountCB::Spare1(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/)
533 return KErrNotSupported;
538 static void SetAtt(CDirCB* aDir,TUint8 aOffset,TUint aValue)
543 TUint8* pA=(TUint8*)aDir+aOffset;
548 static void SetUid(CDirCB* aDir,TUint8 aOffset,TUidType aValue)
553 TUint8* pU=(TUint8*)aDir+aOffset;
554 *(TUidType*)pU=aValue;
558 TInt CCompDirCB::InitDir(CDirCB* aTrg,CMountCB* aMount)
563 TRAPD(r,aTrg->InitL(&Drive()));
566 aTrg->SetMount(aMount);
567 r=aTrg->Mount().Open();
570 aTrg->SetMount(NULL);
573 SetAtt(aTrg,(TUint8)((TUint8*)&iAtt-(TUint8*)this),iAtt);
574 SetUid(aTrg,(TUint8)((TUint8*)&iUidType-(TUint8*)this),iUidType);
575 aTrg->Mount().DecLock();
580 void CCompMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir)
582 // Open a directory on the current mount.
585 __PRINT(_L("CCompMountCB::DirOpenL()"));
586 CCompDirCB* pD=(CCompDirCB*)aDir;
587 pD->iMatch=aName.AllocL();
589 TInt err = KErrPathNotFound;
590 TInt idx = iMounts.Count();
591 TBool anyFound = EFalse;
592 pD->iCurrentDir = -1;
594 while(idx) // Open dir on every mount it exists.
597 CDirCB* theDir = pD->iDirs[idx];
598 CMountCB* theMount = iMounts[idx].iMount;
599 err = pD->InitDir(theDir, theMount);
601 TRAP(err, theMount->DirOpenL(aName,theDir));
608 pD->iCurrentDir = idx;
613 pD->iDirs[idx]->Close(); // deletes object
614 pD->iDirs[idx] = NULL;
616 if (err == KErrPathHidden)
618 // Dont look for anythng below this hidden dir.
621 else if (err != KErrPathNotFound)
623 // An unexpected error - make it report this to caller!
629 // If we broke before bottom, close the remaining
632 pD->iDirs[idx]->Close();
633 pD->iDirs[idx] = NULL;
636 // If we didnt find anythng at all, or some other error, leave.
643 void CCompMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aTrg*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const
645 // Read up to aLength data directly
648 User::Leave(KErrAccessDenied);
652 void CCompMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/)
654 // Write aLength data
657 User::Leave(KErrAccessDenied);
661 void CCompMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/)
663 // Return the short name associated with aLongName
664 // Assumes all rom names are 8.3
667 User::Leave(KErrNotSupported);
671 void CCompMountCB::GetLongNameL(const TDesC& /*aShortName*/,TDes& /*aLongName*/)
673 // Return the short name associated with aLongName
674 // Assumes all rom names are 8.3
677 User::Leave(KErrNotSupported);
681 void CCompMountCB::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
683 // Return the address of the file if it is in rom
686 __PRINT(_L("CCompMountCB::IsFileInRom()"));
689 TInt idx = iMounts.Count();
693 TRAPD(r,iMounts[idx].iMount->EntryL(aFileName,entry));
696 // File exists on mount, check whether it is rom-based
697 iMounts[idx].iMount->IsFileInRom(aFileName,aFileStart);
700 else if(r != KErrNotFound && r != KErrPathNotFound)
708 void CCompMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
710 // Starting from aPos, read aLength bytes of a file into a Trg,
711 // regardless of lock state
714 __PRINT(_L("CCompMountCB::ReadSectionL()"));
715 TInt lesserErr = KErrNone;
716 TInt err = KErrPathNotFound;
717 TInt idx = iMounts.Count();
719 // Look for file on each mount, until it finds one, starting at the top.
722 TRAP(err, iMounts[idx].iMount->ReadSectionL(aName,aPos,aTrg,aLength,aMessage));
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))
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))
738 User::Leave(lesserErr?lesserErr:err);
742 CCompFileCB::CCompFileCB()
746 CCompFileCB::~CCompFileCB()
748 __PRINT1(_L("~CCompFileCB()[0x%x]"),this);
754 void CCompFileCB::RenameL(const TDesC& /*aNewName*/)
759 User::Leave(KErrAccessDenied);
763 void CCompFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage)
765 // Read from the file.
768 __PRINT(_L("CCompFileCB::ReadL()"));
769 TrueFile()->ReadL(aPos,aLength,aDes,aMessage);
773 void CCompFileCB::WriteL(TInt /*aPos*/,TInt& /*aLength*/,const TAny* /*aDes*/,const RMessagePtr2& /*aMessage*/)
775 // Write to the file.
778 User::Leave(KErrAccessDenied);
782 TInt CCompFileCB::Address(TInt& aPos) const
784 // Return address of the file at aPos
787 __PRINT(_L("CCompFileCB::Address()"));
788 return(TrueFile()->Address(aPos));
792 void CCompFileCB::SetSizeL(TInt /*aSize*/)
794 // Set the file size.
797 User::Leave(KErrAccessDenied);
801 void CCompFileCB::SetEntryL(const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/)
803 // Set the entry's attributes and modified time.
806 User::Leave(KErrAccessDenied);
810 void CCompFileCB::FlushDataL()
812 // Commit any buffered date to the media.
815 User::Leave(KErrAccessDenied);
819 void CCompFileCB::FlushAllL()
821 // Commit any buffered date to the media.
824 User::Leave(KErrAccessDenied);
828 TInt CCompFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
831 return TrueFile()->GetInterface(aInterfaceId, aInterface, aInput);
833 return KErrNotSupported;
837 CCompDirCB::CCompDirCB()
844 CCompDirCB::~CCompDirCB()
849 __PRINT1(_L("~CCompDirCB() [0x%x]"),this);
850 for(TInt dir=iDirs.Count(); dir--;)
860 void CCompDirCB::ReadL(TEntry& anEntry)
862 // Reads the next directory entry.
865 __PRINT(_L("CCompDirCB::ReadL()"));
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);
879 User::Leave(KErrEof);
881 TFileName match(*iMatch);
882 TInt namePos=match.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter
883 TPtrC dirName=match.Left(namePos);
889 CDirCB* theDir = iDirs[iCurrentDir];
892 FOREVER // loop until we can read no more (EOF or other err)
893 // If non-duplicate entry found, it returns.
895 TRAP(err, theDir->ReadL(anEntry));
900 __PRINT2(_L("CCompDirCB:: ReadL got = '%S' from dir %d"),&anEntry.iName, iCurrentDir);
903 filename+=anEntry.iName;
905 if (!IsDuplicate(filename))
909 // We have either reached EOF for CurrentDir or encounted an error.
911 __PRINT1(_L("CCompDirCB:: ReadL err = %d"),err);
920 while (iCurrentDir--);
922 User::Leave(KErrEof);
926 TBool CCompDirCB::IsDuplicate(TFileName& aFilename)
928 // Is used by ReadL to determine if a file name read is a duplicate of
929 // a filename already read bit it.
932 RArray<TCompMount> &mounts = ((CCompMountCB*)&Mount())->iMounts;
933 TInt count = mounts.Count();
935 __PRINT1(_L("theMount->iMounts.Count() = %d"),count);
937 for (TInt idx = iCurrentDir+1; idx < count; idx++)
939 TRAPD(r, mounts[idx].iMount->EntryL(aFilename,tmpEntry));
941 if ((r == KErrNone) || (r == KErrHidden) || (r == KErrPathHidden))
943 __PRINT1(_L("CCompDirCB:: Duplicate (r=%d)"),r);
951 void CCompDirCB::StoreLongEntryNameL(const TDesC& aName)
953 // Stores the Long Entry Name
956 __ASSERT_ALWAYS(iCurrentDir >= 0 && iDirs[iCurrentDir] != NULL, Fault(ECompDirStoreLongEntryNameL));
957 iDirs[iCurrentDir]->StoreLongEntryNameL(aName);
963 EXPORT_C CFileSystem* CreateFileSystem()
965 // Create a new file system
968 return(CCompFileSystem::NewL());