--- a/userlibandfileserver/fileserver/sfat/sl_mnt.cpp Mon Oct 19 15:55:17 2009 +0100
+++ b/userlibandfileserver/fileserver/sfat/sl_mnt.cpp Mon Dec 21 16:14:42 2009 +0000
@@ -20,6 +20,15 @@
@internalTechnology
*/
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!
+//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
+//!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
#include "sl_std.h"
#include "sl_cache.h"
#include "sl_leafdir_cache.h"
@@ -213,9 +222,9 @@
if(!CheckVolumeTheSame())
User::Leave(KErrGeneral);
- //-- get drive capabilities
+ //-- get drive capabilities
TLocalDriveCapsV2Buf capsBuf;
- User::LeaveIfError(LocalDrive()->Caps(capsBuf));
+ User::LeaveIfError(LocalDrive()->Caps(capsBuf));
//-- the volume is the same as it was on original MountL()
//-- we need to re-initialize for the case when the media was removed, FAT or directory structure changed on other device and the media returned back.
@@ -300,17 +309,17 @@
*/
void CFatMountCB::InvalidateLeafDirCache()
- {
+ {
if (iLeafDirCache)
- {
+ {
iLeafDirCache->Reset();
- }
+ }
else
- {
+ {
User::Free(iLastLeafDir);
iLastLeafDir=NULL;
- }
- }
+ }
+ }
//-------------------------------------------------------------------------------------------------------------------
@@ -545,7 +554,7 @@
User::Leave(KErrAccessDenied); //-- can't override RO flag
}
- (void)LocalDrive()->Finalise(ETrue);
+ (void)LocalDrive()->Finalise(ETrue);
if(aOperation == RFs::EFinal_RO)
{
@@ -643,7 +652,7 @@
const TBool bSyncOp = !aVolume.iVolSizeAsync;
aVolume.iVolSizeAsync = EFalse; //-- reset this flag in order it not to be reused on the client side
- __PRINT2(_L("CFatMountCB::VolumeL() drv:%d, synch:%d"), DriveNumber(), bSyncOp);
+ __PRINT2(_L("CFatMountCB::VolumeL() drv:%d, synch:%d"), DriveNumber(), bSyncOp);
const TDriveInfo& drvInfo=aVolume.iDrive;
#if defined(__EPOC32__)
@@ -718,9 +727,9 @@
TBuf8<KVolumeLabelSize> buf8(KVolumeLabelSize);
buf8.Zero();
- LocaleUtils::ConvertFromUnicodeL(buf8, aName, TFatUtilityFunctions::EOverflowActionLeave);
- aName.Zero();
- LocaleUtils::ConvertToUnicodeL(aName, buf8); // adjust aName (which may contain more underscores after this line than before)
+ LocaleUtils::ConvertFromUnicodeL(buf8, aName, TFatUtilityFunctions::EOverflowActionLeave);
+ aName.Zero();
+ LocaleUtils::ConvertToUnicodeL(aName, buf8); // adjust aName (which may contain more underscores after this line than before)
const TInt lengthOfBuf8=buf8.Length();
// Pad to end with spaces if not empty.
@@ -773,10 +782,10 @@
TFatDirEntry startEntry;
TRAPD(ret,DoFindL(name,KEntryAttMaskSupported,
- startPos,startEntry,dumPos,dumEntry,
- fileName,KErrNotFound,
- &iFileCreationHelper,
- leafDir));
+ startPos,startEntry,dumPos,dumEntry,
+ fileName,KErrNotFound,
+ &iFileCreationHelper,
+ leafDir));
if (ret!=KErrNotFound && ret!=KErrNone)
User::Leave(ret);
@@ -790,9 +799,9 @@
TShortName shortName;
if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
- {
- GenerateShortNameL(dirPos.iCluster,name,shortName,ETrue);
- }
+ {
+ GenerateShortNameL(dirPos.iCluster,name,shortName,ETrue);
+ }
TInt numEntries=1;
if (isOriginalNameLegal==EFalse)
@@ -800,9 +809,9 @@
dumPos=dirPos;
if (iFileCreationHelper.IsNewEntryPosFound())
- {
- dumPos = iFileCreationHelper.EntryAddingPos();
- }
+ {
+ dumPos = iFileCreationHelper.EntryAddingPos();
+ }
AddDirEntryL(dumPos,numEntries); // Directory entry in leaf directory
TInt startCluster;
@@ -823,7 +832,7 @@
fatDirEntry.SetName(shortName);
fatDirEntry.SetAttributes(KEntryAttDir);
TTime now;
- now.UniversalTime();
+ now.UniversalTime();
fatDirEntry.SetTime(now, TimeOffset());
fatDirEntry.SetCreateTime(now, TimeOffset());
fatDirEntry.SetStartCluster(startCluster);
@@ -864,7 +873,7 @@
//-- "." directory entry
TFatDirEntry entry;
TTime now;
- now.UniversalTime();
+ now.UniversalTime();
entry.SetTime(now, TimeOffset() );
entry.SetAttributes(KEntryAttDir);
entry.SetCurrentDirectory();
@@ -926,9 +935,9 @@
User::Leave(KErrInUse);
// Remove the directory from cache before erasing
if(iLeafDirCache && iLeafDirCache->CacheCount() > 0)
- {
- iLeafDirCache->RemoveDirL(StartCluster(dosEntry));
- }
+ {
+ iLeafDirCache->RemoveDirL(StartCluster(dosEntry));
+ }
EraseDirEntryL(dirEntryPos,dirEntry);
FAT().FreeClusterListL(StartCluster(dosEntry));
@@ -1001,7 +1010,7 @@
@param aNewDosEntryPos on exit contains new entry Pos.
*/
void CFatMountCB::DoRenameOrReplaceL(const TDesC& aOldName, const TDesC& aNewName, TRenMode aMode, TEntryPos& aNewName_DosEntryPos)
- {
+ {
__PRINT3(_L("CFatMountCB::DoRenameOrReplaceL() mode:%d old:%S, new:%S"), aMode, &aOldName, &aNewName);
const TBool namesAreIdentical = FileNamesIdentical(aOldName, aNewName); //-- this is case-insensitive.
@@ -1054,10 +1063,10 @@
TFatDirEntry startEntry;
TRAP(nRes, DoFindL(ptrNewName, KEntryAttMaskSupported,
- newName_VFatEntryPos, startEntry, aNewName_DosEntryPos, newName_DosEntry,
- fileName, KErrNotFound,
- &iFileCreationHelper,
- leafDir));
+ newName_VFatEntryPos, startEntry, aNewName_DosEntryPos, newName_DosEntry,
+ fileName, KErrNotFound,
+ &iFileCreationHelper,
+ leafDir));
if (nRes!=KErrNone && nRes!=KErrNotFound)
User::Leave(nRes);
@@ -1066,28 +1075,28 @@
const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
if(renameMode && newFileExists)
- {
+ {
if(!namesAreIdentical)
{
if ((newName_DosEntry.Attributes()&KEntryAttDir) != (oldName_DosEntry.Attributes()&KEntryAttDir))
- {
- User::Leave(KErrAccessDenied); //-- leave with KErrAccessDenied if it is trying to rename a file
- // to a dir or vice versa.
- }
+ {
+ User::Leave(KErrAccessDenied); //-- leave with KErrAccessDenied if it is trying to rename a file
+ // to a dir or vice versa.
+ }
User::Leave(KErrAlreadyExists); //-- can't rename file if the file with 'aNewName' already exists
}
else
- {
+ {
if(!bNewNameIsVFAT && !bOldNameIsVFAT)
return; //-- renaming DOS name to itself
- }
+ }
//-- allow renaming entry to itself. "namesAreIdentical" is case-insensitive. use case: "FILE" -> "File"
- }
+ }
//---------------------------------------------------------------------------------------------------------------------------
if(replaceMode && newFileExists)
- {
+ {
//---------------------------------------------------------------------------------------------------------------------------
//-- replace contents of the 'aNewName' with 'aOldName' and remove 'aOldName' entries.
@@ -1104,8 +1113,8 @@
newName_DosEntry.SetAttributes(oldName_DosEntry.Attributes());
if(IsRuggedFSys())
- {
- //-- Note 1.
+ {
+ //-- Note 1.
//-- set a special Id in reserved section for old and new entries.
//-- if write fails before the old entry gets erased, we will have 2 entries pointing to the same clusterchain.
//-- ScanDrive is responsible for fixing this situation by erasing entry with ID KReservedIdOldEntry.
@@ -1113,9 +1122,9 @@
//-- in normal situation this field isn't used, though Windows checkdisk can chack its validiy.
//-- KReservedIdNewEntry == 0x0000 that corresponds to year 1980.
- newName_DosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
- oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
- WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
+ newName_DosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
+ oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
+ WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
}
//-- write 'aNewName' DOS dir. entry data back
@@ -1130,50 +1139,50 @@
if(IsRuggedFSys())
FAT().FlushL();
- }
+ }
else //if(replaceMode && newFileExists)
- {
+ {
//---------------------------------------------------------------------------------------------------------------------------
//-- Renaming 'aOldName' to 'aNewName': add 'aNewName' entry set and remove 'aOldName' entryset
TFatDirEntry newDosEntry = oldName_DosEntry;
//-- generate short name for the 'aNewName' entryset and make new DOS entry
if(bNewNameIsVFAT)
- {//-- need to generate a short name for VFAT entryset DOS entry
+ {//-- need to generate a short name for VFAT entryset DOS entry
TShortName shortName;
- if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
- {
- GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
- }
+ if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
+ {
+ GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
+ }
newDosEntry.SetName(shortName);
- }
+ }
else
- {//-- just use 'aNewName' as DOS name.
+ {//-- just use 'aNewName' as DOS name.
TBuf8<KFatDirNameSize+1> tmp; //-- the name may be "XXXXXXXX.YYY"
tmp.Copy(ptrNewName);
newDosEntry.SetName(DosNameToStdFormat(tmp));
- }
+ }
if(IsRuggedFSys())
- {//-- the the note(1) above
+ {//-- the the note(1) above
newDosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
- }
+ }
//-- add new entryset to the directory
aNewName_DosEntryPos.iPos = 0;
aNewName_DosEntryPos.iCluster = aNewName_ParentDirPos.Cluster();
- if (iFileCreationHelper.IsNewEntryPosFound())
- {
- aNewName_DosEntryPos = iFileCreationHelper.EntryAddingPos();
- }
+ if (iFileCreationHelper.IsNewEntryPosFound())
+ {
+ aNewName_DosEntryPos = iFileCreationHelper.EntryAddingPos();
+ }
if(bNewNameIsVFAT)
- {
+ {
const TInt numEntries = NumberOfVFatEntries(ptrNewName.Length());
AddDirEntryL(aNewName_DosEntryPos, numEntries);
WriteDirEntryL(aNewName_DosEntryPos, newDosEntry, ptrNewName);
@@ -1189,7 +1198,7 @@
//-- if we have renamed (moved) a directory, need to update its pointer to parent directory ('..' entry)
if((newDosEntry.Attributes() & KEntryAttDir))
- {
+ {
TEntryPos parentPtrEntPos(StartCluster(newDosEntry), 1*KSizeOfFatDirEntry);
TFatDirEntry chFatEnt;
@@ -1199,26 +1208,26 @@
TUint parentDirStartCluster_New = aNewName_ParentDirPos.Cluster();
if(parentDirStartCluster_New == RootClusterNum() && parentDirStartCluster_New != 0)
- {//-- we are in the root directory. for some reason, '..' entries of the directories in the root dir.
- //-- must have starting cluster 0
+ {//-- we are in the root directory. for some reason, '..' entries of the directories in the root dir.
+ //-- must have starting cluster 0
parentDirStartCluster_New = 0;
- }
+ }
if(parentDirStartCluster_Old != parentDirStartCluster_New)
- {
+ {
chFatEnt.SetStartCluster(parentDirStartCluster_New);
WriteDirEntryL(parentPtrEntPos, chFatEnt);
- }
+ }
// Invalidate leaf dir cache as it is hard to track the dir structure changes now
if (iLeafDirCache)
- {
+ {
iLeafDirCache->Reset();
- }
- }
- }//else if(replaceMode && newFileExists)
+ }
+ }
+ }//else if(replaceMode && newFileExists)
iFileCreationHelper.Close();
- }
+ }
//-----------------------------------------------------------------------------------------
@@ -1299,17 +1308,17 @@
TFatDirEntry startEntry;
DoFindL(fullName.Mid(namePos),KEntryAttMaskSupported,
- startPos,startEntry,entryPos,entry,
- fileName,KErrNotFound,
- NULL,
- leafDir);
+ startPos,startEntry,entryPos,entry,
+ fileName,KErrNotFound,
+ NULL,
+ leafDir);
anEntry.iAtt=entry.Attributes();
anEntry.iSize=entry.Size();
anEntry.iModified=entry.Time(TimeOffset());
- if (fileName.Length()==0)
+ if (fileName.Length()==0)
{
TBuf8<0x20> dosName(DosNameFromStdFormat(entry.Name()));
LocaleUtils::ConvertToUnicodeL(fileName,dosName);
@@ -1348,9 +1357,9 @@
firstEntry.SetAttributes(att);
}
if (aSetAttMask&KEntryAttModified)
- {
- firstEntry.SetTime(aTime,TimeOffset());
- }
+ {
+ firstEntry.SetTime(aTime,TimeOffset());
+ }
WriteDirEntryL(firstEntryPos,firstEntry);
}
@@ -1431,10 +1440,10 @@
iFileCreationHelper.Close();
if (anOpen == EFileCreate || anOpen == EFileReplace)
- {
- iFileCreationHelper.InitialiseL(name);
+ {
+ iFileCreationHelper.InitialiseL(name);
TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos,&iFileCreationHelper));
- }
+ }
else
{
TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos));
@@ -1464,25 +1473,25 @@
//-- here we try to either create or replace file
CheckWritableL();
- TLeafDirData leafDir;
+ TLeafDirData leafDir;
TInt numEntries = iFileCreationHelper.NumOfAddingEntries();
TShortName shortName;
if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
- {
+ {
firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
GenerateShortNameL(firstEntryPos.iCluster,name,shortName,ETrue);
- }
+ }
if (iFileCreationHelper.IsNewEntryPosFound())
- {
- firstEntryPos = iFileCreationHelper.EntryAddingPos();
- }
+ {
+ firstEntryPos = iFileCreationHelper.EntryAddingPos();
+ }
else
- {
- firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
- firstEntryPos.iPos=0;
- }
+ {
+ firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
+ firstEntryPos.iPos=0;
+ }
AddDirEntryL(firstEntryPos,numEntries);
firstEntry.InitZ();
@@ -1490,7 +1499,7 @@
firstEntry.SetStartCluster(0);
TTime now;
- now.UniversalTime();
+ now.UniversalTime();
firstEntry.SetCreateTime(now, TimeOffset() );
if (iFileCreationHelper.IsTrgNameLegalDosName())
@@ -1557,11 +1566,11 @@
TEntryPos startPos;
TFatDirEntry startEntry;
DoFindL(dirPath.Mid(dirPos),
- KEntryAttMatchMask|KEntryAttMatchExclusive,
- startPos, startEntry, dosEntryPos, dosEntry,
- fileName, KErrPathNotFound,
- NULL,
- leafDir);
+ KEntryAttMatchMask|KEntryAttMatchExclusive,
+ startPos, startEntry, dosEntryPos, dosEntry,
+ fileName, KErrPathNotFound,
+ NULL,
+ leafDir);
}
@@ -1861,7 +1870,7 @@
TEntryPos entryPos(RootIndicator(),0);
if (iLeafDirCache == NULL)
- {
+ {
TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
TInt namelen=aName.Length();
if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
@@ -1871,24 +1880,24 @@
lex.Inc(leaflen-1);
entryPos.iCluster=iLastLeafDirCluster;
}
- }
+ }
else
- {
+ {
// Skip root directory
if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
- {
- TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
- if (err == KErrNone)
- {
- ASSERT(aLeafDir.iClusterNum > 0);
- return aLeafDir.iClusterNum;
- }
- else if (err != KErrNotFound)
- {
- User::LeaveIfError(err);
- }
- }
- }
+ {
+ TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
+ if (err == KErrNone)
+ {
+ ASSERT(aLeafDir.iClusterNum > 0);
+ return aLeafDir.iClusterNum;
+ }
+ else if (err != KErrNotFound)
+ {
+ User::LeaveIfError(err);
+ }
+ }
+ }
FOREVER
{
@@ -1906,11 +1915,11 @@
TEntryPos startPos;
TFatDirEntry startEntry;
DoFindL(lex.MarkedToken(),
- KEntryAttMatchMask|KEntryAttMatchExclusive,
- startPos, startEntry, entryPos, entry,
- fileName, KErrPathNotFound,
- NULL,
- aLeafDir);
+ KEntryAttMatchMask|KEntryAttMatchExclusive,
+ startPos, startEntry, entryPos, entry,
+ fileName, KErrPathNotFound,
+ NULL,
+ aLeafDir);
entryPos.iCluster=StartCluster(entry);
@@ -1918,18 +1927,18 @@
}
if (iLeafDirCache == NULL)
- {
+ {
AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
- }
+ }
else
- {
+ {
if (aName.Length() > 1)
- {
- aLeafDir = TLeafDirData(entryPos.iCluster);
+ {
+ aLeafDir = TLeafDirData(entryPos.iCluster);
iLeafDirCache->AddToCacheL(aName, aLeafDir);
- }
- }
+ }
+ }
return entryPos.iCluster;
}
@@ -1952,12 +1961,12 @@
@return ETrue if the specified name is found in the cache. In this case aStartEntryPos, aStartEntry, aDosEntryPos, aDosEntry, aFileName will contain valid values
*/
TBool CFatMountCB::DoRummageDirCacheL(const TUint anAtt, TEntryPos& aStartEntryPos,
- TFatDirEntry& aStartEntry, TEntryPos& aDosEntryPos,
- TFatDirEntry& aDosEntry, TDes& aFileName,
- const TFindHelper& aAuxParam,
- XFileCreationHelper* aFileCreationHelper,
- const TLeafDirData& aLeafDir) const
- {
+ TFatDirEntry& aStartEntry, TEntryPos& aDosEntryPos,
+ TFatDirEntry& aDosEntry, TDes& aFileName,
+ const TFindHelper& aAuxParam,
+ XFileCreationHelper* aFileCreationHelper,
+ const TLeafDirData& aLeafDir) const
+ {
TBool bCacheMatchFound = EFalse;
//-- get an interface to the Dir. cache
@@ -1978,48 +1987,48 @@
const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2; //-- maximal number of dir entries that can be in the cache
- const TUint pageSzLog2 = pDirCache->PageSizeInBytesLog2();
- TBool ScanMRUPageFirst = EFalse;
- TBool MRUPageScanned = EFalse;
-
- // if MRU pos is availale, start with MRU page
- if (aLeafDir.iMRUPos.Cluster())
- {
- ScanMRUPageFirst = ETrue;
- DosEntryPos1 = aLeafDir.iMRUPos;
- }
-
- TInt numFound = 0;
- TEntryPos startPos = DosEntryPos1;
- TInt clusterNum = DosEntryPos1.iCluster;
+ const TUint pageSzLog2 = pDirCache->PageSizeInBytesLog2();
+ TBool ScanMRUPageFirst = EFalse;
+ TBool MRUPageScanned = EFalse;
+
+ // if MRU pos is availale, start with MRU page
+ if (aLeafDir.iMRUPos.Cluster())
+ {
+ ScanMRUPageFirst = ETrue;
+ DosEntryPos1 = aLeafDir.iMRUPos;
+ }
+
+ TInt numFound = 0;
+ TEntryPos startPos = DosEntryPos1;
+ TInt clusterNum = DosEntryPos1.iCluster;
for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
{//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
//-- that can be cached. Helps to avoid problems with infinite (looped) directories
if (IsEndOfClusterCh(DosEntryPos1.iCluster))
- {
- // refer back to the last stored cluster position
- // note aFileCreationHelper may not be initialised for file opening operations
- if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && clusterNum != DosEntryPos1.iCluster)
- {
- TEntryPos dummyPos(clusterNum, clSize - KSizeOfFatDirEntry);
- aFileCreationHelper->SetEntryAddingPos(dummyPos);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
-
- if (ScanMRUPageFirst && !MRUPageScanned)
- {
- DosEntryPos1 = aDosEntryPos;
- MRUPageScanned = ETrue;
- continue;
- }
+ {
+ // refer back to the last stored cluster position
+ // note aFileCreationHelper may not be initialised for file opening operations
+ if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && clusterNum != DosEntryPos1.iCluster)
+ {
+ TEntryPos dummyPos(clusterNum, clSize - KSizeOfFatDirEntry);
+ aFileCreationHelper->SetEntryAddingPos(dummyPos);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+
+ if (ScanMRUPageFirst && !MRUPageScanned)
+ {
+ DosEntryPos1 = aDosEntryPos;
+ MRUPageScanned = ETrue;
+ continue;
+ }
break; //-- this was the last cluster in this directory
- }
+ }
const TUint32 pageStartPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
- DosEntryPos1.iPos = pageStartPos;
- TBool PassedPageBoundary = EFalse;
+ DosEntryPos1.iPos = pageStartPos;
+ TBool PassedPageBoundary = EFalse;
const TInt64 entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos, nCachedLinPos); //-- indicates if entryLinPos is cached
@@ -2045,43 +2054,43 @@
break;
if(DosEntry1.IsEndOfDirectory())
- {
- if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
- {
- // note it is impossible to be at the end of the cluster chain here.
- aFileCreationHelper->SetEntryAddingPos(DosEntryPos1);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
-
- if (ScanMRUPageFirst && !MRUPageScanned)
- {
- break;
- }
-
- // if (!ScanMRUPageFirst || ScanMRUPageFirst && MRUPageScanned)
+ {
+ if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
+ {
+ // note it is impossible to be at the end of the cluster chain here.
+ aFileCreationHelper->SetEntryAddingPos(DosEntryPos1);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+
+ if (ScanMRUPageFirst && !MRUPageScanned)
+ {
+ break;
+ }
+
+ // if (!ScanMRUPageFirst || ScanMRUPageFirst && MRUPageScanned)
goto Exit; //-- this was the last entry in this directory, no reason to look further
- }
+ }
if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
- {
- if (!DosEntry1.IsErased() && !DosEntry1.IsGarbage())
- {
- numFound = 0;
- }
- else
- {
- if (numFound == 0)
- {
- startPos = DosEntryPos1;
- }
- numFound++;
- if (numFound == aFileCreationHelper->NumOfAddingEntries())
- {
- aFileCreationHelper->SetEntryAddingPos(startPos);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
- }
- }
+ {
+ if (!DosEntry1.IsErased() && !DosEntry1.IsGarbage())
+ {
+ numFound = 0;
+ }
+ else
+ {
+ if (numFound == 0)
+ {
+ startPos = DosEntryPos1;
+ }
+ numFound++;
+ if (numFound == aFileCreationHelper->NumOfAddingEntries())
+ {
+ aFileCreationHelper->SetEntryAddingPos(startPos);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+ }
+ }
if(MatchEntryAtt(DosEntry1.Attributes(),anAtt))
{//-- FAT or VFAT dir entry is extracted and attributes match. Compare names then.
@@ -2092,9 +2101,9 @@
// if it is a valid dos name, it will be checked by default
// note here target name is always fully specified
if (aFileCreationHelper && aFileCreationHelper->IsInitialised())
- {
- aFileCreationHelper->CheckShortNameCandidates(DosEntry1.Name().Ptr());
- }
+ {
+ aFileCreationHelper->CheckShortNameCandidates(DosEntry1.Name().Ptr());
+ }
TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
@@ -2147,10 +2156,10 @@
/// exam how many entries we have scanned within the cluster
const TUint entriesLooked = ((DosEntryPos1.iPos + KSizeOfFatDirEntry)- pageStartPos) >> KSizeOfFatDirEntryLog2;
if(entriesLooked > nEntries)
- {
- PassedPageBoundary = ETrue;
+ {
+ PassedPageBoundary = ETrue;
break;
- }
+ }
// move to next entry before scanning next file
@@ -2166,10 +2175,10 @@
}
if (entriesLooked + 1 > nEntries)
- {
- PassedPageBoundary = ETrue;
+ {
+ PassedPageBoundary = ETrue;
break;
- }
+ }
} //for(;;)
@@ -2183,23 +2192,23 @@
// we scan MRU page first and it is not scanned yet, then this must be the MRU page,
// we now start to scan from the beginning
if (ScanMRUPageFirst && !MRUPageScanned)
- {
- MRUPageScanned = ETrue;
- DosEntryPos1 = aDosEntryPos;
- DosEntryPos1.iPos = 0;
- continue;
- }
+ {
+ MRUPageScanned = ETrue;
+ DosEntryPos1 = aDosEntryPos;
+ DosEntryPos1.iPos = 0;
+ continue;
+ }
// if we just finished scanning a page and still in the same cluster, then we crossed page
- // boundary, continue with next page.
+ // boundary, continue with next page.
// note: although we are in the 'next page' already, this page might not be cached, so we need to
// check it via pDirCache->PosCached(entryLinPos, nCachedLinPos) and scan it properly.
if (PassedPageBoundary)
- {
- DosEntryPos1.iPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
- PassedPageBoundary = EFalse;
- continue;
- }
+ {
+ DosEntryPos1.iPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
+ PassedPageBoundary = EFalse;
+ continue;
+ }
//-- try to move to the next cluster of the directory file
@@ -2251,11 +2260,11 @@
pDirCache->MakePageMRU(mruPos);
- // only update the leaf dir cache when the original cache index is provided
- if (aLeafDir.iClusterNum)
- {
+ // only update the leaf dir cache when the original cache index is provided
+ if (aLeafDir.iClusterNum)
+ {
iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDir.iClusterNum, aStartEntryPos));
- }
+ }
}
return bCacheMatchFound;
}
@@ -2308,51 +2317,51 @@
Constructor of XFileCreationHelper class
*/
CFatMountCB::XFileCreationHelper::XFileCreationHelper()
- {
+ {
isInitialised = EFalse;
- }
+ }
/**
Destructor of XFileCreationHelper class
*/
CFatMountCB::XFileCreationHelper::~XFileCreationHelper()
- {
- Close();
- }
+ {
+ Close();
+ }
/**
Initialises a TFileCreationHelper object, generate a short name candidate pool.
-@param aTargetName Target file name for the potential new file.
-@post TFileCreationHelper is fully initialised.
+@param aTargetName Target file name for the potential new file.
+@post TFileCreationHelper is fully initialised.
*/
void CFatMountCB::XFileCreationHelper::InitialiseL(const TDesC& aTargetName)
- {
+ {
// close before use, to avoid memory leak
- Close();
+ Close();
iTargetName.Set(aTargetName);
- // generates short name candidate(s)
+ // generates short name candidate(s)
TInt count = 1;
while (count <= KShortNameCandidatesNum)
- {
- TShortName shortNameCandidate = DoGenerateShortNameL(aTargetName, count, ETrue);
- TInt err = iShortNameCandidates.Append(shortNameCandidate);
- User::LeaveIfError(err);
-
- if (count == -1) // No tilde and number is needed
- {
- break;
- }
- else
- count++;
- }
+ {
+ TShortName shortNameCandidate = DoGenerateShortNameL(aTargetName, count, ETrue);
+ TInt err = iShortNameCandidates.Append(shortNameCandidate);
+ User::LeaveIfError(err);
+
+ if (count == -1) // No tilde and number is needed
+ {
+ break;
+ }
+ else
+ count++;
+ }
// calculate number of new entries needed
iNumOfAddingEntries = 1;
isTrgNameLegalDosName = IsLegalDosName(aTargetName, EFalse, EFalse, EFalse, EFalse, ETrue);
if (!isTrgNameLegalDosName)
- iNumOfAddingEntries = (TUint16) NumberOfVFatEntries(iTargetName.Length());
+ iNumOfAddingEntries = (TUint16) NumberOfVFatEntries(iTargetName.Length());
isNewEntryPosFound = EFalse;
isInitialised = ETrue;
@@ -2362,62 +2371,62 @@
Close function of XFileCreationHelper class
*/
void CFatMountCB::XFileCreationHelper::Close()
- {
- iShortNameCandidates.Close();
- isInitialised = EFalse;
- }
+ {
+ iShortNameCandidates.Close();
+ isInitialised = EFalse;
+ }
/**
Validates short name candidates. If the input dos entry name is found in the short name
candidate pool, the corresponding short name candidate will be removed from the pool.
-@param apDosEntryName An existing short name, to compare with the candidates.
-@pre Object should be initialised
+@param apDosEntryName An existing short name, to compare with the candidates.
+@pre Object should be initialised
*/
void CFatMountCB::XFileCreationHelper::CheckShortNameCandidates(const TUint8* apDosEntryName)
{
ASSERT(isInitialised);
if (!isInitialised)
- return;
+ return;
if (iShortNameCandidates.Count() > 0)
- {
- for (TInt i = 0; i < iShortNameCandidates.Count(); i++)
- {
- if (Mem::Compare(iShortNameCandidates[i].Ptr(), KFatDirNameSize, apDosEntryName, KFatDirNameSize) == 0)
- {
- iShortNameCandidates.Remove(i);
- break;
- }
- }
- }
+ {
+ for (TInt i = 0; i < iShortNameCandidates.Count(); i++)
+ {
+ if (Mem::Compare(iShortNameCandidates[i].Ptr(), KFatDirNameSize, apDosEntryName, KFatDirNameSize) == 0)
+ {
+ iShortNameCandidates.Remove(i);
+ break;
+ }
+ }
+ }
}
/**
Gets a validated short name from the short name candidate pool.
-@param aShortName On return, contains a validated short name if found, otherwise zeroed.
-@return TInt Returns KErrNone if a validated short name found successfully,
- else KErrNotFound is returned.
- Returns KErrNotReady if object is not initialised.
-@pre Object should be initialised
+@param aShortName On return, contains a validated short name if found, otherwise zeroed.
+@return TInt Returns KErrNone if a validated short name found successfully,
+ else KErrNotFound is returned.
+ Returns KErrNotReady if object is not initialised.
+@pre Object should be initialised
*/
TInt CFatMountCB::XFileCreationHelper::GetValidatedShortName(TShortName& aShortName) const
- {
- aShortName.Zero();
-
- ASSERT(isInitialised);
- if (!isInitialised)
- return KErrNotReady;
-
- if (iShortNameCandidates.Count() > 0)
- {
- aShortName.Copy(iShortNameCandidates[0]);
- return KErrNone;
- }
-
- return KErrNotFound;
- }
+ {
+ aShortName.Zero();
+
+ ASSERT(isInitialised);
+ if (!isInitialised)
+ return KErrNotReady;
+
+ if (iShortNameCandidates.Count() > 0)
+ {
+ aShortName.Copy(iShortNameCandidates[0]);
+ return KErrNone;
+ }
+
+ return KErrNotFound;
+ }
//-----------------------------------------------------------------------------------------
@@ -2433,18 +2442,18 @@
@param aDosEntry on return will contain DOS dir entry (the last one for VFAT case)
@param aFileName in the case of VFAT entry and on success here will be returned a long filename
@param anError This function might leave with this given error code
- @param aFileCreationHelper a helper package for file creations
+ @param aFileCreationHelper a helper package for file creations
@return ETrue if extracted entry is VFAT one, EFalse, if it's old DOS-style one
@leave can leave with anError code on error or if the search has reached the end of directory (!)
*/
TBool CFatMountCB::DoFindL(const TDesC& aTrgtName,TUint anAtt,
- TEntryPos& aStartEntryPos,TFatDirEntry& aStartEntry,
- TEntryPos& aDosEntryPos,TFatDirEntry& aDosEntry,
- TDes& aFileName,TInt anError,
- XFileCreationHelper* aFileCreationHelper,
- const TLeafDirData& aLeafDirData) const
- {
+ TEntryPos& aStartEntryPos,TFatDirEntry& aStartEntry,
+ TEntryPos& aDosEntryPos,TFatDirEntry& aDosEntry,
+ TDes& aFileName,TInt anError,
+ XFileCreationHelper* aFileCreationHelper,
+ const TLeafDirData& aLeafDirData) const
+ {
// check that the entry position to be read next is not past the end of the
// root directory. If this is the case then when GetDirEntryL(..) is called
// this will lead to MakeLinAddr(..) leaving with KErrDirFull.
@@ -2519,256 +2528,256 @@
// if we have a starting cluster number (and it's not root directory in FAT16/12 case)&&
// we found a lastScanned entry's cluster (and it's not root directory in FAT16/12 case)&&
// if we don't have a starting cluster number, we draw back to original scanning algorithm
- if (!IsRootDir(aDosEntryPos) // we don't do forward scanning for root dir &
- && aLeafDirData.iClusterNum != 0 // if we have a starting cluster number &
- && aLeafDirData.iMRUPos.Cluster() != 0) // if we have a starting cluster number &
- {
- scanAhead = ETrue;
- aDosEntryPos = aLeafDirData.iMRUPos;
- }
+ if (!IsRootDir(aDosEntryPos) // we don't do forward scanning for root dir &
+ && aLeafDirData.iClusterNum != 0 // if we have a starting cluster number &
+ && aLeafDirData.iMRUPos.Cluster() != 0) // if we have a starting cluster number &
+ {
+ scanAhead = ETrue;
+ aDosEntryPos = aLeafDirData.iMRUPos;
+ }
TInt numFound = 0;
TEntryPos startPos = aDosEntryPos;
TInt clustNum = aDosEntryPos.Cluster();
for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
- {
- // if we are not scanning ahead, we don't need this outer for loop
- if (!scanAhead)
- scanCnt++;
-
- TBool found = EFalse;
+ {
+ // if we are not scanning ahead, we don't need this outer for loop
+ if (!scanAhead)
+ scanCnt++;
+
+ TBool found = EFalse;
FOREVER //FOREVER2 -- walk through all directory entries in the current directory until find a match or directory end
{
- //-- read full directory entry starting from aDosEntryPos. On return aFileName may contain assembled long filename (if the entry is VFAT)
- //-- aDosEntry will contain a DOS entry of the directory entry we have read.
- aStartEntryPos=aDosEntryPos;
- User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, aStartEntry, aFileName));
-
- if (aDosEntry.IsEndOfDirectory())
- {//-- the end of directory reached.
-
- // if new entry position for adding has not been found yet.
- // note aFileCreationHelper may not be initialised for pure file opening operations
- if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
- {
- // if MoveToNextEntryL have gone to the next cluster which is the end of cluster chain,
- // we pass the last scanned entry position to AddDirEntryL
- if (IsEndOfClusterCh(aDosEntryPos.iCluster))
- {
- TInt clusterSize=1<<ClusterSizeLog2();
- TEntryPos dummyPos(clustNum, clusterSize - KSizeOfFatDirEntry);
- aFileCreationHelper->SetEntryAddingPos(dummyPos);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
- // or we reached the end of the directory.
- else
- {
- aFileCreationHelper->SetEntryAddingPos(aDosEntryPos);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
- }
-
- // if we are scanning ahead and this is the first scanning, we break out to restart scanning
- if (scanAhead && scanCnt == 1)
- {
- break; // from FOREVER, restart scanning
- }
-
- // if (!scanAhead || scanAhead && scanCnt == 2)
- User::Leave(anError);
- }
-
-
- // entry space searching for potential new file/directory creation
- if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
- {
- if (!aDosEntry.IsErased() && !aDosEntry.IsGarbage())
- {
- numFound = 0;
- }
- else
- {
- if (numFound == 0)
- {
- startPos = aDosEntryPos;
- }
- numFound++;
- if (numFound == aFileCreationHelper->NumOfAddingEntries())
- {
- aFileCreationHelper->SetEntryAddingPos(startPos);
- aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
- }
- }
- }
-
-
- if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
- if (aDosEntry.IsErased())
- {
- User::Leave(anError);//Allows maximum number of entries in root directory
- }
-
-
- const TBool bFileNameEntry = !aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage();
-
- if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(), anAtt))
- {//-- we have read a filename entry and entry's attributes match required; compare names then.
-
- if (trgNameIsWildCard)
- {
- found = ETrue;
- break; //-- we were looking for '*' or '*.*', so will be satisfied with any current file name.
- }
-
-
- if (aStartEntry.IsVFatEntry())
- {//-- we've read a VFAT entry, aFileName is supposed to contain long filename, aDosEntry - DOS entry for this name.
- //-- note: aFileName.Length() may be 0, while DOS entry (short name is OK) in the case of orphaned VFAT entries
-
-
- // we only check short name candidates for long file names with VFAT entries,
- // if it is a valid dos name, it will be checked by default
- // note, for file creation cases, target name will be always fully specified
- if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && trgNameFullySpecified)
- {
- aFileCreationHelper->CheckShortNameCandidates(aDosEntry.Name().Ptr());
- }
-
- //-- discard trailing dots from aFileName if present
- TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
-
- if(ptrAssembledName.MatchF(trgtNameNoDot) != KErrNotFound)
- {
- found = ETrue;
- break; //-- OK, found a match.
- }
- else if (trgNameFullySpecified)
- {
- //-- long name assembled by GetDirEntry() doesn't match the target. But if he target name is fully specified,
- //-- we need to compare corresponding DOS entries, because VFAT entries may be damaged, while DOS ones are OK.
- findHelper.InitialiseL(trgtNameNoDot);
-
- if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
- {
- found = ETrue;
- break; //-- DOS entries match, success.
- }
- }
- else if (!trgNameFullySpecified)
- {//-- target name contains wildcards, we need to use MatchF with dos name
- TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
- TBuf<0x20> dosName;
- LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
- if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
- {
- found = ETrue;
- break;
- }
- }
-
-
- }
- else //if (aStartEntry.IsVFatEntry())
- {//-- we've read a legacy FAT entry, so compare DOS entries
- findHelper.InitialiseL(trgtNameNoDot);
-
- if(findHelper.TrgtNameIsLegalDos())
- {//-- we are looking for a legal DOS name
- if(trgNameFullySpecified)
- {//-- if the target name is fully specified, we can yse binary comparison of the DOS entries
- if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
- {
- found = ETrue;
- break;
- }
- }
- else
- {//-- target name contains wildcards, we neeed to use MatchF
- TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
- TBuf<0x20> dosName;
- LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
- if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
- {
- found = ETrue;
- break;
- }
-
- }
- } //if(findHelper.TrgtNameIsLegalDos())
-
- } //else if (aStartEntry.IsVFatEntry())
-
- } //if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(),anAtt))
-
-
- // record previous cluster number
- clustNum = aDosEntryPos.iCluster;
-
- // this is the 2nd scanning and we have just passed the pos we started.
- if (scanAhead && scanCnt == 2)
- {
- if (aDosEntryPos.Cluster() == aLeafDirData.iMRUPos.Cluster()
- && aDosEntryPos.Pos() >= aLeafDirData.iMRUPos.Pos())
- {
- User::Leave(anError);
- }
- }
-
-
- MoveToNextEntryL(aDosEntryPos); //-- goto the next entry in the directory
-
- if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
- {
- User::Leave(anError);//Allows maximum number of entries in root directory
- }
-
-
- if (!scanAhead || scanCnt == 2)
- {
- if (aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
- DoCheckFatForLoopsL(aDosEntryPos.iCluster,previousCluster,changePreviousCluster,count);
-
- previousPosition=aDosEntryPos.iPos;
- }
- } // FOREVER -- the actual scanning is done inside this loop
+ //-- read full directory entry starting from aDosEntryPos. On return aFileName may contain assembled long filename (if the entry is VFAT)
+ //-- aDosEntry will contain a DOS entry of the directory entry we have read.
+ aStartEntryPos=aDosEntryPos;
+ User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, aStartEntry, aFileName));
+
+ if (aDosEntry.IsEndOfDirectory())
+ {//-- the end of directory reached.
+
+ // if new entry position for adding has not been found yet.
+ // note aFileCreationHelper may not be initialised for pure file opening operations
+ if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
+ {
+ // if MoveToNextEntryL have gone to the next cluster which is the end of cluster chain,
+ // we pass the last scanned entry position to AddDirEntryL
+ if (IsEndOfClusterCh(aDosEntryPos.iCluster))
+ {
+ TInt clusterSize=1<<ClusterSizeLog2();
+ TEntryPos dummyPos(clustNum, clusterSize - KSizeOfFatDirEntry);
+ aFileCreationHelper->SetEntryAddingPos(dummyPos);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+ // or we reached the end of the directory.
+ else
+ {
+ aFileCreationHelper->SetEntryAddingPos(aDosEntryPos);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+ }
+
+ // if we are scanning ahead and this is the first scanning, we break out to restart scanning
+ if (scanAhead && scanCnt == 1)
+ {
+ break; // from FOREVER, restart scanning
+ }
+
+ // if (!scanAhead || scanAhead && scanCnt == 2)
+ User::Leave(anError);
+ }
+
+
+ // entry space searching for potential new file/directory creation
+ if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
+ {
+ if (!aDosEntry.IsErased() && !aDosEntry.IsGarbage())
+ {
+ numFound = 0;
+ }
+ else
+ {
+ if (numFound == 0)
+ {
+ startPos = aDosEntryPos;
+ }
+ numFound++;
+ if (numFound == aFileCreationHelper->NumOfAddingEntries())
+ {
+ aFileCreationHelper->SetEntryAddingPos(startPos);
+ aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
+ }
+ }
+ }
+
+
+ if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
+ if (aDosEntry.IsErased())
+ {
+ User::Leave(anError);//Allows maximum number of entries in root directory
+ }
+
+
+ const TBool bFileNameEntry = !aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage();
+
+ if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(), anAtt))
+ {//-- we have read a filename entry and entry's attributes match required; compare names then.
+
+ if (trgNameIsWildCard)
+ {
+ found = ETrue;
+ break; //-- we were looking for '*' or '*.*', so will be satisfied with any current file name.
+ }
+
+
+ if (aStartEntry.IsVFatEntry())
+ {//-- we've read a VFAT entry, aFileName is supposed to contain long filename, aDosEntry - DOS entry for this name.
+ //-- note: aFileName.Length() may be 0, while DOS entry (short name is OK) in the case of orphaned VFAT entries
+
+
+ // we only check short name candidates for long file names with VFAT entries,
+ // if it is a valid dos name, it will be checked by default
+ // note, for file creation cases, target name will be always fully specified
+ if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && trgNameFullySpecified)
+ {
+ aFileCreationHelper->CheckShortNameCandidates(aDosEntry.Name().Ptr());
+ }
+
+ //-- discard trailing dots from aFileName if present
+ TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
+
+ if(ptrAssembledName.MatchF(trgtNameNoDot) != KErrNotFound)
+ {
+ found = ETrue;
+ break; //-- OK, found a match.
+ }
+ else if (trgNameFullySpecified)
+ {
+ //-- long name assembled by GetDirEntry() doesn't match the target. But if he target name is fully specified,
+ //-- we need to compare corresponding DOS entries, because VFAT entries may be damaged, while DOS ones are OK.
+ findHelper.InitialiseL(trgtNameNoDot);
+
+ if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
+ {
+ found = ETrue;
+ break; //-- DOS entries match, success.
+ }
+ }
+ else if (!trgNameFullySpecified)
+ {//-- target name contains wildcards, we need to use MatchF with dos name
+ TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
+ TBuf<0x20> dosName;
+ LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
+ if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
+ {
+ found = ETrue;
+ break;
+ }
+ }
+
+
+ }
+ else //if (aStartEntry.IsVFatEntry())
+ {//-- we've read a legacy FAT entry, so compare DOS entries
+ findHelper.InitialiseL(trgtNameNoDot);
+
+ if(findHelper.TrgtNameIsLegalDos())
+ {//-- we are looking for a legal DOS name
+ if(trgNameFullySpecified)
+ {//-- if the target name is fully specified, we can yse binary comparison of the DOS entries
+ if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ else
+ {//-- target name contains wildcards, we neeed to use MatchF
+ TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
+ TBuf<0x20> dosName;
+ LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
+ if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
+ {
+ found = ETrue;
+ break;
+ }
+
+ }
+ } //if(findHelper.TrgtNameIsLegalDos())
+
+ } //else if (aStartEntry.IsVFatEntry())
+
+ } //if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(),anAtt))
+
+
+ // record previous cluster number
+ clustNum = aDosEntryPos.iCluster;
+
+ // this is the 2nd scanning and we have just passed the pos we started.
+ if (scanAhead && scanCnt == 2)
+ {
+ if (aDosEntryPos.Cluster() == aLeafDirData.iMRUPos.Cluster()
+ && aDosEntryPos.Pos() >= aLeafDirData.iMRUPos.Pos())
+ {
+ User::Leave(anError);
+ }
+ }
+
+
+ MoveToNextEntryL(aDosEntryPos); //-- goto the next entry in the directory
+
+ if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
+ {
+ User::Leave(anError);//Allows maximum number of entries in root directory
+ }
+
+
+ if (!scanAhead || scanCnt == 2)
+ {
+ if (aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
+ DoCheckFatForLoopsL(aDosEntryPos.iCluster,previousCluster,changePreviousCluster,count);
+
+ previousPosition=aDosEntryPos.iPos;
+ }
+ } // FOREVER -- the actual scanning is done inside this loop
if (found)
- {
- break;
- }
+ {
+ break;
+ }
// if not found:
- // if we have not found in the first scanning and we are doing scanning ahead,
+ // if we have not found in the first scanning and we are doing scanning ahead,
// we need to go back to the starting pos of this dir and scan from start until
// we reach lastscannedPos
if (scanAhead && scanCnt == 1)
- {
- aDosEntryPos = TEntryPos(aLeafDirData.iClusterNum, 0);
- continue;
- }
+ {
+ aDosEntryPos = TEntryPos(aLeafDirData.iClusterNum, 0);
+ continue;
+ }
else
- {
- // there are only two exits: either found or reached end of dir in the 1st scanning
- ASSERT(0);
- break;
- }
- } // for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
+ {
+ // there are only two exits: either found or reached end of dir in the 1st scanning
+ ASSERT(0);
+ break;
+ }
+ } // for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
//---------------------------------------------------
if (iRawDisk->DirCacheInterface() && aDosEntryPos.Cluster())
- {
- TInt64 mruPos = MakeLinAddrL(aDosEntryPos);
+ {
+ TInt64 mruPos = MakeLinAddrL(aDosEntryPos);
iRawDisk->DirCacheInterface()->MakePageMRU(mruPos);
- // only update the leaf dir cache when the original cache index is provided
- if (aLeafDirData.iClusterNum)
- {
+ // only update the leaf dir cache when the original cache index is provided
+ if (aLeafDirData.iClusterNum)
+ {
iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDirData.iClusterNum, aDosEntryPos));
}
- }
+ }
return (aStartEntry.IsVFatEntry());
}
@@ -2832,7 +2841,7 @@
TEntryPos startPos;
TFatDirEntry startEntry;
- TLeafDirData leafDir; // leaf dir data is zero initialized, no scannig ahead
+ TLeafDirData leafDir; // leaf dir data is zero initialized, no scannig ahead
DoFindL(aName,anAtt,startPos,startEntry,aDosEntryPos,aDosEntry,aFileName,anError,NULL,leafDir);
}
//-----------------------------------------------------------------------------------------
@@ -3191,64 +3200,64 @@
TEntryPos startPos;
TFatDirEntry startEntry;
DoFindL(RemoveTrailingDots(aName).Mid(namePos),KEntryAttMaskSupported,
- startPos,startEntry,dosEntryPos,dosEntry,
- fileName,KErrNotFound,
- NULL,
- leafDir);
+ startPos,startEntry,dosEntryPos,dosEntry,
+ fileName,KErrNotFound,
+ NULL,
+ leafDir);
// Check that reading from aPos for aLength lies within the file
// if aPos is within the file, and aLength is too long, read up to EOF
// If aPos is beyond the end of the file, return a zero length descriptor
- TUint32 fileSize = dosEntry.Size();
- if ((TUint)aPos>=fileSize)
+ TUint32 fileSize = dosEntry.Size();
+ if ((TUint)aPos>=fileSize)
User::Leave(KErrEof);
if ((TUint)(aPos+aLength)>fileSize)
aLength=fileSize-aPos;
TInt cluster=StartCluster(dosEntry);
- TInt pos = aPos;
+ TInt pos = aPos;
TInt endCluster;
TInt clusterSize=1<<ClusterSizeLog2(); // Size of file clusters
- TInt readTotal = 0;
-
- // Total number of clusters in file
+ TInt readTotal = 0;
+
+ // Total number of clusters in file
TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
- // Read data
+ // Read data
FOREVER
{
- // Get the maximum number of clusters that can be read contiguously
+ // Get the maximum number of clusters that can be read contiguously
TInt clusterListLen=FAT().CountContiguousClustersL(cluster,endCluster,maxClusters);
__ASSERT_DEBUG(clusterListLen>0,Fault(EReadFileSectionFailed));
- // If start position within this block, then read some data
+ // If start position within this block, then read some data
if (pos<(clusterListLen<<ClusterSizeLog2()))
{
- // Read the remaining length or the entire cluster block whichever is smaller
- TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
- __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
- TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
- iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal);
- readTotal += readLength;
-
- if (readTotal == aLength)
- return;
-
- pos += readLength;
- }
-
- // Get the next cluster in file
- pos-=(clusterListLen<<ClusterSizeLog2());
+ // Read the remaining length or the entire cluster block whichever is smaller
+ TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
+ __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
+ TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
+ iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal);
+ readTotal += readLength;
+
+ if (readTotal == aLength)
+ return;
+
+ pos += readLength;
+ }
+
+ // Get the next cluster in file
+ pos-=(clusterListLen<<ClusterSizeLog2());
#if defined(_DEBUG)
- TBool remainingClusters=
+ TBool remainingClusters=
#endif
- ((CFatMountCB*)this)->FAT().GetNextClusterL(endCluster);
- __ASSERT_DEBUG(remainingClusters,Fault(EReadFileSectionFailed));
- cluster=endCluster;
- }
+ ((CFatMountCB*)this)->FAT().GetNextClusterL(endCluster);
+ __ASSERT_DEBUG(remainingClusters,Fault(EReadFileSectionFailed));
+ cluster=endCluster;
+ }
}
@@ -3271,7 +3280,7 @@
{
CheckWritableL();
- //-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
+ //-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
FAT().RequestRawWriteAccess(aPos, aLength);
iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset);
@@ -3573,75 +3582,75 @@
return(r);
break;
}
- case ELocalTimeForRemovableMediaOn:
- {
- FatFileSystem().SetUseLocalTime(ETrue);
- break;
- }
- case ELocalTimeForRemovableMediaOff:
- {
- FatFileSystem().SetUseLocalTime(EFalse);
- break;
- }
- case ELocalTimeUsedOnRemovableMedia:
- {
- TBool flag = FatFileSystem().GetUseLocalTime();
- TPckgC<TBool> flagPckg(flag);
- TInt r = aMessage.Write(2, flagPckg);
- if(r!=KErrNone)
- return r;
- break;
- }
- case ECreationTime:
- {
- CheckStateConsistentL();
-
- TEntryPos firstEntryPos(RootIndicator(),0);
- TFatDirEntry firstEntry;
- //RFs::ControlIO restricts you to use narrow descriptors
- //so convert narrow back to wide.
- TBuf8<KMaxPath> fileNameNarrow;
- aMessage.Read(2, fileNameNarrow);
-
- TFileName fileNameWide;
- fileNameWide.Copy(fileNameNarrow);
-
- //find the long file name entry
- TRAPD(r, FindEntryStartL(fileNameWide,KEntryAttMaskSupported,firstEntry,firstEntryPos) );
- if(r!=KErrNone)
+ case ELocalTimeForRemovableMediaOn:
+ {
+ FatFileSystem().SetUseLocalTime(ETrue);
+ break;
+ }
+ case ELocalTimeForRemovableMediaOff:
+ {
+ FatFileSystem().SetUseLocalTime(EFalse);
+ break;
+ }
+ case ELocalTimeUsedOnRemovableMedia:
+ {
+ TBool flag = FatFileSystem().GetUseLocalTime();
+ TPckgC<TBool> flagPckg(flag);
+ TInt r = aMessage.Write(2, flagPckg);
+ if(r!=KErrNone)
+ return r;
+ break;
+ }
+ case ECreationTime:
+ {
+ CheckStateConsistentL();
+
+ TEntryPos firstEntryPos(RootIndicator(),0);
+ TFatDirEntry firstEntry;
+ //RFs::ControlIO restricts you to use narrow descriptors
+ //so convert narrow back to wide.
+ TBuf8<KMaxPath> fileNameNarrow;
+ aMessage.Read(2, fileNameNarrow);
+
+ TFileName fileNameWide;
+ fileNameWide.Copy(fileNameNarrow);
+
+ //find the long file name entry
+ TRAPD(r, FindEntryStartL(fileNameWide,KEntryAttMaskSupported,firstEntry,firstEntryPos) );
+ if(r!=KErrNone)
return(r);
- //Find the corresponding 8.3 short name entry, for metadata
- MoveToDosEntryL(firstEntryPos,firstEntry);
- TTime creationTime=0;
- TPckg<TTime> timePckg(creationTime);
- SFatDirEntry* sEntry = reinterpret_cast<SFatDirEntry*>(firstEntry.iData);
- creationTime = DosTimeToTTime(sEntry->iTimeC, sEntry->iDateC);
- r = aMessage.Write(3, timePckg);
- if(r!=KErrNone)
- return r;
- break;
- }
- case EDisableFATDirCache:
- {
- MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
- TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
- pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
- break;
- }
- case EDumpFATDirCache:
- {
- MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
- TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
- pDirCache->Control(KEDumpFATDirCache, 0, NULL);
- break;
- }
- case EFATDirCacheInfo:
- {
- MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
- TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
- pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
- break;
- }
+ //Find the corresponding 8.3 short name entry, for metadata
+ MoveToDosEntryL(firstEntryPos,firstEntry);
+ TTime creationTime=0;
+ TPckg<TTime> timePckg(creationTime);
+ SFatDirEntry* sEntry = reinterpret_cast<SFatDirEntry*>(firstEntry.iData);
+ creationTime = DosTimeToTTime(sEntry->iTimeC, sEntry->iDateC);
+ r = aMessage.Write(3, timePckg);
+ if(r!=KErrNone)
+ return r;
+ break;
+ }
+ case EDisableFATDirCache:
+ {
+ MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
+ TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
+ pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
+ break;
+ }
+ case EDumpFATDirCache:
+ {
+ MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
+ TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
+ pDirCache->Control(KEDumpFATDirCache, 0, NULL);
+ break;
+ }
+ case EFATDirCacheInfo:
+ {
+ MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
+ TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
+ pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
+ break;
+ }
default: return(KErrNotSupported);
@@ -3662,7 +3671,7 @@
//
{
__PRINT(_L("CFatMountCB::Lock"));
- TInt r=CreateDrive(Drive().DriveNumber());
+ TInt r=CreateDrive(Drive().DriveNumber());
if (r!=KErrNone)
return r;
@@ -3689,7 +3698,7 @@
//
{
__PRINT(_L("CFatMountCB::Unlock"));
- TInt r=CreateDrive(Drive().DriveNumber());
+ TInt r=CreateDrive(Drive().DriveNumber());
if (r!=KErrNone)
return r;
@@ -3716,7 +3725,7 @@
//
{
__PRINT(_L("CFatMountCB::ClearPassword"));
- TInt r=CreateDrive(Drive().DriveNumber());
+ TInt r=CreateDrive(Drive().DriveNumber());
if (r!=KErrNone)
return r;
@@ -3744,7 +3753,7 @@
{
__PRINT(_L("CFatMountCB::ErasePassword"));
- TInt r=CreateDrive(Drive().DriveNumber());
+ TInt r=CreateDrive(Drive().DriveNumber());
if (r!=KErrNone)
return r;
@@ -3776,9 +3785,9 @@
//
{
__PRINT(_L("CFatMountCB::ForceRemountDrive"));
- TInt r=CreateDrive(Drive().DriveNumber());
+ TInt r=CreateDrive(Drive().DriveNumber());
if (r==KErrNone)
- r=LocalDrive()->SetMountInfo(aMountInfo,aMountInfoMessageHandle);
+ r=LocalDrive()->SetMountInfo(aMountInfo,aMountInfoMessageHandle);
if (r==KErrNone)
r=LocalDrive()->ForceRemount(aFlags);
return(r);
@@ -3906,8 +3915,8 @@
fatDirEntry.SetAttributes(KEntryAttVolume);
TTime now;
- now.UniversalTime();
- fatDirEntry.SetTime(now, TimeOffset() );
+ now.UniversalTime();
+ fatDirEntry.SetTime(now, TimeOffset() );
fatDirEntry.SetStartCluster(0);
fatDirEntry.SetSize(0);
WriteDirEntryL(dirPos, fatDirEntry);
@@ -4052,7 +4061,7 @@
{
if (!FAT().GetNextClusterL(aPos.iCluster))
{
- __PRINT(_L("CFatMountCB::BlockMapReadFromClusterListL corrupt#1"))
+ __PRINT(_L("CFatMountCB::BlockMapReadFromClusterListL corrupt#1"))
User::Leave(KErrCorrupt);
}
}
@@ -4286,7 +4295,7 @@
// lists that merge.
//
TInt CFatMountCB::CheckDisk()
- {
+ {
__PRINT1(_L("CFatMountCB::CheckDisk() drv:%d"), DriveNumber());
@@ -4468,7 +4477,7 @@
if(LockStatus()!=0)
{
- __PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
+ __PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
return KErrInUse;
}
@@ -4515,16 +4524,16 @@
@return The offset in seconds that timestamps on the filesystem have, relative to UTC.
*/
TTimeIntervalSeconds CFatMountCB::TimeOffset() const
- {
+ {
if((Drive().Att() & KDriveAttRemovable) && FatFileSystem().GetUseLocalTime() )
- {
+ {
return User::UTCOffset();
}
- else
+ else
{
return TTimeIntervalSeconds(0);
}
- }
+ }