diff -r a41df078684a -r 4122176ea935 userlibandfileserver/fileserver/sfat/sl_mnt.cpp --- 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 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 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<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<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()); - // 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<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<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<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 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 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 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 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 timePckg(creationTime); - SFatDirEntry* sEntry = reinterpret_cast(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 timePckg(creationTime); + SFatDirEntry* sEntry = reinterpret_cast(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); } - } + }