userlibandfileserver/fileserver/sfat/sl_mnt.cpp
changeset 15 4122176ea935
parent 0 a41df078684a
equal deleted inserted replaced
0:a41df078684a 15:4122176ea935
    17 
    17 
    18 /**
    18 /**
    19  @file
    19  @file
    20  @internalTechnology
    20  @internalTechnology
    21 */
    21 */
       
    22 
       
    23 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    25 //!!
       
    26 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
       
    27 //!!
       
    28 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    29 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    30 
    22 
    31 
    23 #include "sl_std.h"
    32 #include "sl_std.h"
    24 #include "sl_cache.h"
    33 #include "sl_cache.h"
    25 #include "sl_leafdir_cache.h"
    34 #include "sl_leafdir_cache.h"
    26 #include "sl_dir_cache.h"
    35 #include "sl_dir_cache.h"
   211     {
   220     {
   212 
   221 
   213     if(!CheckVolumeTheSame())
   222     if(!CheckVolumeTheSame())
   214         User::Leave(KErrGeneral);
   223         User::Leave(KErrGeneral);
   215 
   224 
   216 	//-- get drive capabilities
   225     //-- get drive capabilities
   217     TLocalDriveCapsV2Buf capsBuf;
   226     TLocalDriveCapsV2Buf capsBuf;
   218 	User::LeaveIfError(LocalDrive()->Caps(capsBuf));
   227     User::LeaveIfError(LocalDrive()->Caps(capsBuf));
   219 
   228 
   220     //-- the volume is the same as it was on original MountL()
   229     //-- the volume is the same as it was on original MountL()
   221     //-- 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.
   230     //-- 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.
   222     DoDismount();
   231     DoDismount();
   223 
   232 
   298     Reset the last leaf dir or invalidate leaf dir cache if leaf dir cache is
   307     Reset the last leaf dir or invalidate leaf dir cache if leaf dir cache is
   299     instantiated.
   308     instantiated.
   300 */
   309 */
   301 
   310 
   302 void CFatMountCB::InvalidateLeafDirCache()
   311 void CFatMountCB::InvalidateLeafDirCache()
   303 	{
   312     {
   304     if (iLeafDirCache)
   313     if (iLeafDirCache)
   305     	{
   314         {
   306         iLeafDirCache->Reset();
   315         iLeafDirCache->Reset();
   307     	}
   316         }
   308     else
   317     else
   309     	{
   318         {
   310         User::Free(iLastLeafDir);
   319         User::Free(iLastLeafDir);
   311         iLastLeafDir=NULL;
   320         iLastLeafDir=NULL;
   312     	}
   321         }
   313 	}
   322     }
   314 
   323 
   315 //-------------------------------------------------------------------------------------------------------------------
   324 //-------------------------------------------------------------------------------------------------------------------
   316 
   325 
   317 /**
   326 /**
   318     Delete mount's caches
   327     Delete mount's caches
   543         if(ReadOnly() && aOperation == RFs::EFinal_RW)
   552         if(ReadOnly() && aOperation == RFs::EFinal_RW)
   544             {
   553             {
   545             User::Leave(KErrAccessDenied); //-- can't override RO flag
   554             User::Leave(KErrAccessDenied); //-- can't override RO flag
   546             }
   555             }
   547 
   556 
   548 		(void)LocalDrive()->Finalise(ETrue);
   557         (void)LocalDrive()->Finalise(ETrue);
   549 
   558 
   550         if(aOperation == RFs::EFinal_RO)
   559         if(aOperation == RFs::EFinal_RO)
   551             {
   560             {
   552             SetReadOnly(ETrue);
   561             SetReadOnly(ETrue);
   553             return;
   562             return;
   641     //-- if the client sets aVolume.iVolSizeAsync flag there, RFs::Volume() will be asynchronous, i.e the _current_ number of free clusters
   650     //-- if the client sets aVolume.iVolSizeAsync flag there, RFs::Volume() will be asynchronous, i.e the _current_ number of free clusters
   642     //-- will be returned.
   651     //-- will be returned.
   643     const TBool bSyncOp = !aVolume.iVolSizeAsync;
   652     const TBool bSyncOp = !aVolume.iVolSizeAsync;
   644     aVolume.iVolSizeAsync = EFalse; //-- reset this flag in order it not to be reused on the client side
   653     aVolume.iVolSizeAsync = EFalse; //-- reset this flag in order it not to be reused on the client side
   645 
   654 
   646 	__PRINT2(_L("CFatMountCB::VolumeL() drv:%d, synch:%d"), DriveNumber(), bSyncOp);
   655     __PRINT2(_L("CFatMountCB::VolumeL() drv:%d, synch:%d"), DriveNumber(), bSyncOp);
   647     const TDriveInfo& drvInfo=aVolume.iDrive;
   656     const TDriveInfo& drvInfo=aVolume.iDrive;
   648 
   657 
   649 #if defined(__EPOC32__)
   658 #if defined(__EPOC32__)
   650     // if RAM drive, cap size according to HAL.
   659     // if RAM drive, cap size according to HAL.
   651     if (drvInfo.iType==EMediaRam)
   660     if (drvInfo.iType==EMediaRam)
   716 
   725 
   717     __ASSERT_ALWAYS(aName.Length()<=KVolumeLabelSize,User::Leave(KErrBadName));
   726     __ASSERT_ALWAYS(aName.Length()<=KVolumeLabelSize,User::Leave(KErrBadName));
   718 
   727 
   719     TBuf8<KVolumeLabelSize> buf8(KVolumeLabelSize);
   728     TBuf8<KVolumeLabelSize> buf8(KVolumeLabelSize);
   720     buf8.Zero();
   729     buf8.Zero();
   721 	LocaleUtils::ConvertFromUnicodeL(buf8, aName, TFatUtilityFunctions::EOverflowActionLeave);
   730     LocaleUtils::ConvertFromUnicodeL(buf8, aName, TFatUtilityFunctions::EOverflowActionLeave);
   722 	aName.Zero();
   731     aName.Zero();
   723 	LocaleUtils::ConvertToUnicodeL(aName, buf8); // adjust aName (which may contain more underscores after this line than before)
   732     LocaleUtils::ConvertToUnicodeL(aName, buf8); // adjust aName (which may contain more underscores after this line than before)
   724 
   733 
   725     const TInt lengthOfBuf8=buf8.Length();
   734     const TInt lengthOfBuf8=buf8.Length();
   726     // Pad to end with spaces if not empty.
   735     // Pad to end with spaces if not empty.
   727     if (lengthOfBuf8>0 && lengthOfBuf8<KVolumeLabelSize)
   736     if (lengthOfBuf8>0 && lengthOfBuf8<KVolumeLabelSize)
   728         {
   737         {
   771     TFileName fileName;
   780     TFileName fileName;
   772     TEntryPos startPos;
   781     TEntryPos startPos;
   773     TFatDirEntry startEntry;
   782     TFatDirEntry startEntry;
   774     
   783     
   775     TRAPD(ret,DoFindL(name,KEntryAttMaskSupported,
   784     TRAPD(ret,DoFindL(name,KEntryAttMaskSupported,
   776 			    		startPos,startEntry,dumPos,dumEntry,
   785                         startPos,startEntry,dumPos,dumEntry,
   777 			    		fileName,KErrNotFound,
   786                         fileName,KErrNotFound,
   778 			    		&iFileCreationHelper,
   787                         &iFileCreationHelper,
   779 			    		leafDir));
   788                         leafDir));
   780 
   789 
   781     if (ret!=KErrNotFound && ret!=KErrNone)
   790     if (ret!=KErrNotFound && ret!=KErrNone)
   782         User::Leave(ret);
   791         User::Leave(ret);
   783     if (ret!=KErrNotFound)
   792     if (ret!=KErrNotFound)
   784         {
   793         {
   788             User::Leave(KErrAccessDenied);
   797             User::Leave(KErrAccessDenied);
   789         }
   798         }
   790     TShortName shortName;
   799     TShortName shortName;
   791 
   800 
   792     if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
   801     if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
   793     	{
   802         {
   794     	GenerateShortNameL(dirPos.iCluster,name,shortName,ETrue);
   803         GenerateShortNameL(dirPos.iCluster,name,shortName,ETrue);
   795     	}
   804         }
   796 
   805 
   797     TInt numEntries=1;
   806     TInt numEntries=1;
   798     if (isOriginalNameLegal==EFalse)
   807     if (isOriginalNameLegal==EFalse)
   799         numEntries=NumberOfVFatEntries(name.Length());
   808         numEntries=NumberOfVFatEntries(name.Length());
   800     dumPos=dirPos;
   809     dumPos=dirPos;
   801 
   810 
   802     if (iFileCreationHelper.IsNewEntryPosFound())
   811     if (iFileCreationHelper.IsNewEntryPosFound())
   803     	{
   812         {
   804     	dumPos = iFileCreationHelper.EntryAddingPos();
   813         dumPos = iFileCreationHelper.EntryAddingPos();
   805     	}
   814         }
   806 
   815 
   807     AddDirEntryL(dumPos,numEntries);    //  Directory entry in leaf directory
   816     AddDirEntryL(dumPos,numEntries);    //  Directory entry in leaf directory
   808     TInt startCluster;
   817     TInt startCluster;
   809     FOREVER
   818     FOREVER
   810         {
   819         {
   821         }
   830         }
   822     TFatDirEntry fatDirEntry;
   831     TFatDirEntry fatDirEntry;
   823     fatDirEntry.SetName(shortName);
   832     fatDirEntry.SetName(shortName);
   824     fatDirEntry.SetAttributes(KEntryAttDir);
   833     fatDirEntry.SetAttributes(KEntryAttDir);
   825     TTime now;
   834     TTime now;
   826 	now.UniversalTime();
   835     now.UniversalTime();
   827     fatDirEntry.SetTime(now, TimeOffset());
   836     fatDirEntry.SetTime(now, TimeOffset());
   828     fatDirEntry.SetCreateTime(now, TimeOffset());
   837     fatDirEntry.SetCreateTime(now, TimeOffset());
   829     fatDirEntry.SetStartCluster(startCluster);
   838     fatDirEntry.SetStartCluster(startCluster);
   830     fatDirEntry.SetSize(0);
   839     fatDirEntry.SetSize(0);
   831     if (isOriginalNameLegal)
   840     if (isOriginalNameLegal)
   862     //-- copy "." directory entry to the buffer
   871     //-- copy "." directory entry to the buffer
   863 
   872 
   864     //-- "." directory entry
   873     //-- "." directory entry
   865     TFatDirEntry entry;
   874     TFatDirEntry entry;
   866     TTime now;
   875     TTime now;
   867 	now.UniversalTime();
   876     now.UniversalTime();
   868     entry.SetTime(now, TimeOffset() );
   877     entry.SetTime(now, TimeOffset() );
   869     entry.SetAttributes(KEntryAttDir);
   878     entry.SetAttributes(KEntryAttDir);
   870     entry.SetCurrentDirectory();
   879     entry.SetCurrentDirectory();
   871     entry.SetStartCluster(aStartCluster);
   880     entry.SetStartCluster(aStartCluster);
   872     Mem::Copy(&buf[0],&entry,KSizeOfFatDirEntry);
   881     Mem::Copy(&buf[0],&entry,KSizeOfFatDirEntry);
   924     MoveToDosEntryL(dosEntryPos,dosEntry);
   933     MoveToDosEntryL(dosEntryPos,dosEntry);
   925     if (!IsDirectoryEmptyL(StartCluster(dosEntry)))
   934     if (!IsDirectoryEmptyL(StartCluster(dosEntry)))
   926         User::Leave(KErrInUse);
   935         User::Leave(KErrInUse);
   927     // Remove the directory from cache before erasing
   936     // Remove the directory from cache before erasing
   928     if(iLeafDirCache && iLeafDirCache->CacheCount() > 0)
   937     if(iLeafDirCache && iLeafDirCache->CacheCount() > 0)
   929     	{
   938         {
   930     	iLeafDirCache->RemoveDirL(StartCluster(dosEntry));
   939         iLeafDirCache->RemoveDirL(StartCluster(dosEntry));
   931     	}
   940         }
   932 
   941 
   933     EraseDirEntryL(dirEntryPos,dirEntry);
   942     EraseDirEntryL(dirEntryPos,dirEntry);
   934     FAT().FreeClusterListL(StartCluster(dosEntry));
   943     FAT().FreeClusterListL(StartCluster(dosEntry));
   935     FAT().FlushL();
   944     FAT().FlushL();
   936     }
   945     }
   999     @param   aNewName           a new entry name
  1008     @param   aNewName           a new entry name
  1000     @param   aMode              specifies renaming / replacing
  1009     @param   aMode              specifies renaming / replacing
  1001     @param   aNewDosEntryPos    on exit contains new entry Pos.
  1010     @param   aNewDosEntryPos    on exit contains new entry Pos.
  1002 */
  1011 */
  1003 void CFatMountCB::DoRenameOrReplaceL(const TDesC& aOldName, const TDesC& aNewName, TRenMode aMode, TEntryPos& aNewName_DosEntryPos)
  1012 void CFatMountCB::DoRenameOrReplaceL(const TDesC& aOldName, const TDesC& aNewName, TRenMode aMode, TEntryPos& aNewName_DosEntryPos)
  1004 	{
  1013     {
  1005     __PRINT3(_L("CFatMountCB::DoRenameOrReplaceL() mode:%d old:%S, new:%S"), aMode, &aOldName, &aNewName);
  1014     __PRINT3(_L("CFatMountCB::DoRenameOrReplaceL() mode:%d old:%S, new:%S"), aMode, &aOldName, &aNewName);
  1006 
  1015 
  1007     const TBool namesAreIdentical = FileNamesIdentical(aOldName, aNewName); //-- this is case-insensitive.
  1016     const TBool namesAreIdentical = FileNamesIdentical(aOldName, aNewName); //-- this is case-insensitive.
  1008     const TBool renameMode = (aMode == EModeRename);
  1017     const TBool renameMode = (aMode == EModeRename);
  1009     const TBool replaceMode = !renameMode;
  1018     const TBool replaceMode = !renameMode;
  1052     TFileName fileName;
  1061     TFileName fileName;
  1053     iFileCreationHelper.InitialiseL(ptrNewName);
  1062     iFileCreationHelper.InitialiseL(ptrNewName);
  1054     TFatDirEntry startEntry;
  1063     TFatDirEntry startEntry;
  1055 
  1064 
  1056     TRAP(nRes, DoFindL(ptrNewName, KEntryAttMaskSupported,
  1065     TRAP(nRes, DoFindL(ptrNewName, KEntryAttMaskSupported,
  1057 	    		newName_VFatEntryPos, startEntry, aNewName_DosEntryPos, newName_DosEntry,
  1066                 newName_VFatEntryPos, startEntry, aNewName_DosEntryPos, newName_DosEntry,
  1058 	    		fileName, KErrNotFound,
  1067                 fileName, KErrNotFound,
  1059 	    		&iFileCreationHelper,
  1068                 &iFileCreationHelper,
  1060 	    		leafDir));
  1069                 leafDir));
  1061 
  1070 
  1062     if (nRes!=KErrNone && nRes!=KErrNotFound)
  1071     if (nRes!=KErrNone && nRes!=KErrNotFound)
  1063         User::Leave(nRes);
  1072         User::Leave(nRes);
  1064 
  1073 
  1065     const TBool newFileExists = (nRes == KErrNone); //-- ETrue if 'aNewName' file exists.
  1074     const TBool newFileExists = (nRes == KErrNone); //-- ETrue if 'aNewName' file exists.
  1066     const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
  1075     const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
  1067 
  1076 
  1068     if(renameMode && newFileExists)
  1077     if(renameMode && newFileExists)
  1069     	{
  1078         {
  1070         if(!namesAreIdentical)
  1079         if(!namesAreIdentical)
  1071         {
  1080         {
  1072         if ((newName_DosEntry.Attributes()&KEntryAttDir) != (oldName_DosEntry.Attributes()&KEntryAttDir))
  1081         if ((newName_DosEntry.Attributes()&KEntryAttDir) != (oldName_DosEntry.Attributes()&KEntryAttDir))
  1073         	{
  1082             {
  1074         	User::Leave(KErrAccessDenied); 	//-- leave with KErrAccessDenied if it is trying to rename a file
  1083             User::Leave(KErrAccessDenied);  //-- leave with KErrAccessDenied if it is trying to rename a file
  1075         									//		to a dir or vice versa.
  1084                                             //      to a dir or vice versa.
  1076         	}
  1085             }
  1077         User::Leave(KErrAlreadyExists); //-- can't rename file if the file with 'aNewName' already exists
  1086         User::Leave(KErrAlreadyExists); //-- can't rename file if the file with 'aNewName' already exists
  1078         }
  1087         }
  1079         else
  1088         else
  1080         	{
  1089             {
  1081             if(!bNewNameIsVFAT && !bOldNameIsVFAT)
  1090             if(!bNewNameIsVFAT && !bOldNameIsVFAT)
  1082                 return; //-- renaming DOS name to itself
  1091                 return; //-- renaming DOS name to itself
  1083         	}
  1092             }
  1084         //-- allow renaming entry to itself. "namesAreIdentical" is case-insensitive. use case: "FILE" -> "File"
  1093         //-- allow renaming entry to itself. "namesAreIdentical" is case-insensitive. use case: "FILE" -> "File"
  1085     	}
  1094         }
  1086 
  1095 
  1087     //---------------------------------------------------------------------------------------------------------------------------
  1096     //---------------------------------------------------------------------------------------------------------------------------
  1088 
  1097 
  1089     if(replaceMode && newFileExists)
  1098     if(replaceMode && newFileExists)
  1090     	{
  1099         {
  1091         //---------------------------------------------------------------------------------------------------------------------------
  1100         //---------------------------------------------------------------------------------------------------------------------------
  1092         //-- replace contents of the 'aNewName' with 'aOldName' and remove 'aOldName' entries.
  1101         //-- replace contents of the 'aNewName' with 'aOldName' and remove 'aOldName' entries.
  1093 
  1102 
  1094         //-- check if we are still trying to replace the file with itself, probably using short name alias
  1103         //-- check if we are still trying to replace the file with itself, probably using short name alias
  1095         if(aNewName_DosEntryPos == oldName_DosEntryPos)
  1104         if(aNewName_DosEntryPos == oldName_DosEntryPos)
  1102         newName_DosEntry.SetSize(oldName_DosEntry.Size());
  1111         newName_DosEntry.SetSize(oldName_DosEntry.Size());
  1103         newName_DosEntry.SetTime(oldName_DosEntry.Time(TTimeIntervalSeconds(0)), TTimeIntervalSeconds(0));
  1112         newName_DosEntry.SetTime(oldName_DosEntry.Time(TTimeIntervalSeconds(0)), TTimeIntervalSeconds(0));
  1104         newName_DosEntry.SetAttributes(oldName_DosEntry.Attributes());
  1113         newName_DosEntry.SetAttributes(oldName_DosEntry.Attributes());
  1105 
  1114 
  1106             if(IsRuggedFSys())
  1115             if(IsRuggedFSys())
  1107             	{
  1116                 {
  1108             	//-- Note 1.
  1117                 //-- Note 1.
  1109                 //-- set a special Id in reserved section for old and new entries.
  1118                 //-- set a special Id in reserved section for old and new entries.
  1110                 //-- if write fails before the old entry gets erased, we will have 2 entries pointing to the same clusterchain.
  1119                 //-- if write fails before the old entry gets erased, we will have 2 entries pointing to the same clusterchain.
  1111                 //-- ScanDrive is responsible for fixing this situation by erasing entry with ID KReservedIdOldEntry.
  1120                 //-- ScanDrive is responsible for fixing this situation by erasing entry with ID KReservedIdOldEntry.
  1112                 //-- note that  SetRuggedFatEntryId() uses "LastAccessTime" DOS FAT entry field to store the ID.
  1121                 //-- note that  SetRuggedFatEntryId() uses "LastAccessTime" DOS FAT entry field to store the ID.
  1113                 //-- in normal situation this field isn't used, though Windows checkdisk can chack its validiy.
  1122                 //-- in normal situation this field isn't used, though Windows checkdisk can chack its validiy.
  1114                 //-- KReservedIdNewEntry == 0x0000 that corresponds to year 1980.
  1123                 //-- KReservedIdNewEntry == 0x0000 that corresponds to year 1980.
  1115 
  1124 
  1116 	            newName_DosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
  1125                 newName_DosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
  1117 	            oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
  1126                 oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
  1118 	            WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
  1127                 WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
  1119                 }
  1128                 }
  1120 
  1129 
  1121         //-- write 'aNewName' DOS dir. entry data back
  1130         //-- write 'aNewName' DOS dir. entry data back
  1122         WriteDirEntryL(aNewName_DosEntryPos, newName_DosEntry);
  1131         WriteDirEntryL(aNewName_DosEntryPos, newName_DosEntry);
  1123 
  1132 
  1128         FAT().FreeClusterListL(newNameStartCluster);
  1137         FAT().FreeClusterListL(newNameStartCluster);
  1129 
  1138 
  1130         if(IsRuggedFSys())
  1139         if(IsRuggedFSys())
  1131             FAT().FlushL();
  1140             FAT().FlushL();
  1132 
  1141 
  1133     	}
  1142         }
  1134     else //if(replaceMode && newFileExists)
  1143     else //if(replaceMode && newFileExists)
  1135     	{
  1144         {
  1136         //---------------------------------------------------------------------------------------------------------------------------
  1145         //---------------------------------------------------------------------------------------------------------------------------
  1137         //-- Renaming 'aOldName' to 'aNewName': add 'aNewName' entry set and remove 'aOldName' entryset
  1146         //-- Renaming 'aOldName' to 'aNewName': add 'aNewName' entry set and remove 'aOldName' entryset
  1138 
  1147 
  1139         TFatDirEntry newDosEntry = oldName_DosEntry;
  1148         TFatDirEntry newDosEntry = oldName_DosEntry;
  1140         //-- generate short name for the 'aNewName' entryset and make new DOS entry
  1149         //-- generate short name for the 'aNewName' entryset and make new DOS entry
  1141         if(bNewNameIsVFAT)
  1150         if(bNewNameIsVFAT)
  1142         	{//-- need to generate a short name for VFAT entryset DOS entry
  1151             {//-- need to generate a short name for VFAT entryset DOS entry
  1143             TShortName shortName;
  1152             TShortName shortName;
  1144 
  1153 
  1145 		    if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1154             if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1146 		    	{
  1155                 {
  1147 		        GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
  1156                 GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
  1148 		    	}
  1157                 }
  1149 
  1158 
  1150             newDosEntry.SetName(shortName);
  1159             newDosEntry.SetName(shortName);
  1151         	}
  1160             }
  1152         else
  1161         else
  1153         	{//-- just use 'aNewName' as DOS name.
  1162             {//-- just use 'aNewName' as DOS name.
  1154             TBuf8<KFatDirNameSize+1> tmp; //-- the name may be "XXXXXXXX.YYY"
  1163             TBuf8<KFatDirNameSize+1> tmp; //-- the name may be "XXXXXXXX.YYY"
  1155             tmp.Copy(ptrNewName);
  1164             tmp.Copy(ptrNewName);
  1156             newDosEntry.SetName(DosNameToStdFormat(tmp));
  1165             newDosEntry.SetName(DosNameToStdFormat(tmp));
  1157         	}
  1166             }
  1158 
  1167 
  1159         if(IsRuggedFSys())
  1168         if(IsRuggedFSys())
  1160         	{//-- the the note(1) above
  1169             {//-- the the note(1) above
  1161             newDosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
  1170             newDosEntry.SetRuggedFatEntryId(KReservedIdNewEntry);
  1162             oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
  1171             oldName_DosEntry.SetRuggedFatEntryId(KReservedIdOldEntry);
  1163             WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
  1172             WriteDirEntryL(oldName_DosEntryPos, oldName_DosEntry);
  1164         	}
  1173             }
  1165 
  1174 
  1166         //-- add new entryset to the directory
  1175         //-- add new entryset to the directory
  1167         aNewName_DosEntryPos.iPos = 0;
  1176         aNewName_DosEntryPos.iPos = 0;
  1168         aNewName_DosEntryPos.iCluster = aNewName_ParentDirPos.Cluster();
  1177         aNewName_DosEntryPos.iCluster = aNewName_ParentDirPos.Cluster();
  1169 
  1178 
  1170 	    if (iFileCreationHelper.IsNewEntryPosFound())
  1179         if (iFileCreationHelper.IsNewEntryPosFound())
  1171 	    	{
  1180             {
  1172 	    	aNewName_DosEntryPos = iFileCreationHelper.EntryAddingPos();
  1181             aNewName_DosEntryPos = iFileCreationHelper.EntryAddingPos();
  1173 	    	}
  1182             }
  1174 
  1183 
  1175         if(bNewNameIsVFAT)
  1184         if(bNewNameIsVFAT)
  1176         	{
  1185             {
  1177             const TInt numEntries = NumberOfVFatEntries(ptrNewName.Length());
  1186             const TInt numEntries = NumberOfVFatEntries(ptrNewName.Length());
  1178             AddDirEntryL(aNewName_DosEntryPos, numEntries);
  1187             AddDirEntryL(aNewName_DosEntryPos, numEntries);
  1179             WriteDirEntryL(aNewName_DosEntryPos, newDosEntry, ptrNewName);
  1188             WriteDirEntryL(aNewName_DosEntryPos, newDosEntry, ptrNewName);
  1180             }
  1189             }
  1181         else
  1190         else
  1187         //-- erase old entryset.
  1196         //-- erase old entryset.
  1188         EraseDirEntryL(oldName_FirstEntryPos, oldName_FirstEntry);
  1197         EraseDirEntryL(oldName_FirstEntryPos, oldName_FirstEntry);
  1189 
  1198 
  1190         //-- if we have renamed (moved) a directory, need to update its pointer to parent directory ('..' entry)
  1199         //-- if we have renamed (moved) a directory, need to update its pointer to parent directory ('..' entry)
  1191         if((newDosEntry.Attributes() & KEntryAttDir))
  1200         if((newDosEntry.Attributes() & KEntryAttDir))
  1192         	{
  1201             {
  1193             TEntryPos parentPtrEntPos(StartCluster(newDosEntry), 1*KSizeOfFatDirEntry);
  1202             TEntryPos parentPtrEntPos(StartCluster(newDosEntry), 1*KSizeOfFatDirEntry);
  1194 
  1203 
  1195             TFatDirEntry chFatEnt;
  1204             TFatDirEntry chFatEnt;
  1196             ReadDirEntryL(parentPtrEntPos, chFatEnt);
  1205             ReadDirEntryL(parentPtrEntPos, chFatEnt);
  1197 
  1206 
  1198             const TUint parentDirStartCluster_Old = StartCluster(chFatEnt);
  1207             const TUint parentDirStartCluster_Old = StartCluster(chFatEnt);
  1199                   TUint parentDirStartCluster_New = aNewName_ParentDirPos.Cluster();
  1208                   TUint parentDirStartCluster_New = aNewName_ParentDirPos.Cluster();
  1200 
  1209 
  1201             if(parentDirStartCluster_New == RootClusterNum() && parentDirStartCluster_New != 0)
  1210             if(parentDirStartCluster_New == RootClusterNum() && parentDirStartCluster_New != 0)
  1202             	{//-- we are in the root directory. for some reason, '..' entries of the directories in the root dir.
  1211                 {//-- we are in the root directory. for some reason, '..' entries of the directories in the root dir.
  1203             	//-- must have starting cluster 0
  1212                 //-- must have starting cluster 0
  1204                 parentDirStartCluster_New = 0;
  1213                 parentDirStartCluster_New = 0;
  1205             	}
  1214                 }
  1206 
  1215 
  1207             if(parentDirStartCluster_Old != parentDirStartCluster_New)
  1216             if(parentDirStartCluster_Old != parentDirStartCluster_New)
  1208             	{
  1217                 {
  1209                 chFatEnt.SetStartCluster(parentDirStartCluster_New);
  1218                 chFatEnt.SetStartCluster(parentDirStartCluster_New);
  1210                 WriteDirEntryL(parentPtrEntPos, chFatEnt);
  1219                 WriteDirEntryL(parentPtrEntPos, chFatEnt);
  1211             	}
  1220                 }
  1212             // Invalidate leaf dir cache as it is hard to track the dir structure changes now
  1221             // Invalidate leaf dir cache as it is hard to track the dir structure changes now
  1213             if (iLeafDirCache)
  1222             if (iLeafDirCache)
  1214             	{
  1223                 {
  1215                 iLeafDirCache->Reset();
  1224                 iLeafDirCache->Reset();
  1216             	}
  1225                 }
  1217         	}
  1226             }
  1218     	}//else if(replaceMode && newFileExists)
  1227         }//else if(replaceMode && newFileExists)
  1219 
  1228 
  1220     iFileCreationHelper.Close();
  1229     iFileCreationHelper.Close();
  1221 	}
  1230     }
  1222 
  1231 
  1223 //-----------------------------------------------------------------------------------------
  1232 //-----------------------------------------------------------------------------------------
  1224 
  1233 
  1225 /**
  1234 /**
  1226     Rename 'aOldName' file/directory to 'aNewName'
  1235     Rename 'aOldName' file/directory to 'aNewName'
  1297     entryPos.iPos=0;
  1306     entryPos.iPos=0;
  1298     TEntryPos startPos;
  1307     TEntryPos startPos;
  1299     TFatDirEntry startEntry;
  1308     TFatDirEntry startEntry;
  1300 
  1309 
  1301     DoFindL(fullName.Mid(namePos),KEntryAttMaskSupported,
  1310     DoFindL(fullName.Mid(namePos),KEntryAttMaskSupported,
  1302     		startPos,startEntry,entryPos,entry,
  1311             startPos,startEntry,entryPos,entry,
  1303     		fileName,KErrNotFound,
  1312             fileName,KErrNotFound,
  1304     		NULL,
  1313             NULL,
  1305     		leafDir);
  1314             leafDir);
  1306 
  1315 
  1307 
  1316 
  1308     anEntry.iAtt=entry.Attributes();
  1317     anEntry.iAtt=entry.Attributes();
  1309     anEntry.iSize=entry.Size();
  1318     anEntry.iSize=entry.Size();
  1310     anEntry.iModified=entry.Time(TimeOffset());
  1319     anEntry.iModified=entry.Time(TimeOffset());
  1311 
  1320 
  1312 	if (fileName.Length()==0)
  1321     if (fileName.Length()==0)
  1313         {
  1322         {
  1314         TBuf8<0x20> dosName(DosNameFromStdFormat(entry.Name()));
  1323         TBuf8<0x20> dosName(DosNameFromStdFormat(entry.Name()));
  1315         LocaleUtils::ConvertToUnicodeL(fileName,dosName);
  1324         LocaleUtils::ConvertToUnicodeL(fileName,dosName);
  1316         }
  1325         }
  1317     if ((TUint)anEntry.iSize>=sizeof(TCheckedUid))
  1326     if ((TUint)anEntry.iSize>=sizeof(TCheckedUid))
  1346         att|=setAttMask;
  1355         att|=setAttMask;
  1347         att&=(~aClearAttMask);
  1356         att&=(~aClearAttMask);
  1348         firstEntry.SetAttributes(att);
  1357         firstEntry.SetAttributes(att);
  1349         }
  1358         }
  1350     if (aSetAttMask&KEntryAttModified)
  1359     if (aSetAttMask&KEntryAttModified)
  1351 		{
  1360         {
  1352 		firstEntry.SetTime(aTime,TimeOffset());
  1361         firstEntry.SetTime(aTime,TimeOffset());
  1353 		}
  1362         }
  1354     WriteDirEntryL(firstEntryPos,firstEntry);
  1363     WriteDirEntryL(firstEntryPos,firstEntry);
  1355     }
  1364     }
  1356 
  1365 
  1357 //-----------------------------------------------------------------------------------------
  1366 //-----------------------------------------------------------------------------------------
  1358 
  1367 
  1429     TPtrC name(fullName.Mid(nPos));
  1438     TPtrC name(fullName.Mid(nPos));
  1430     TInt ret = KErrNone;
  1439     TInt ret = KErrNone;
  1431 
  1440 
  1432     iFileCreationHelper.Close();
  1441     iFileCreationHelper.Close();
  1433     if (anOpen == EFileCreate || anOpen == EFileReplace)
  1442     if (anOpen == EFileCreate || anOpen == EFileReplace)
  1434     	{
  1443         {
  1435     	iFileCreationHelper.InitialiseL(name);
  1444         iFileCreationHelper.InitialiseL(name);
  1436         TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos,&iFileCreationHelper));
  1445         TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos,&iFileCreationHelper));
  1437     	}
  1446         }
  1438     else
  1447     else
  1439         {
  1448         {
  1440         TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos));
  1449         TRAP(ret,FindEntryStartL(fullName,KEntryAttMaskSupported,firstEntry,firstEntryPos));
  1441         }
  1450         }
  1442 
  1451 
  1462             User::Leave(KErrNotFound);
  1471             User::Leave(KErrNotFound);
  1463 
  1472 
  1464         //-- here we try to either create or replace file
  1473         //-- here we try to either create or replace file
  1465         CheckWritableL();
  1474         CheckWritableL();
  1466 
  1475 
  1467     	TLeafDirData leafDir;
  1476         TLeafDirData leafDir;
  1468 
  1477 
  1469         TInt numEntries = iFileCreationHelper.NumOfAddingEntries();
  1478         TInt numEntries = iFileCreationHelper.NumOfAddingEntries();
  1470         TShortName shortName;
  1479         TShortName shortName;
  1471         if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1480         if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1472         	{
  1481             {
  1473             firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
  1482             firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
  1474             GenerateShortNameL(firstEntryPos.iCluster,name,shortName,ETrue);
  1483             GenerateShortNameL(firstEntryPos.iCluster,name,shortName,ETrue);
  1475         	}
  1484             }
  1476 
  1485 
  1477         if (iFileCreationHelper.IsNewEntryPosFound())
  1486         if (iFileCreationHelper.IsNewEntryPosFound())
  1478 	    	{
  1487             {
  1479 	    	firstEntryPos = iFileCreationHelper.EntryAddingPos();
  1488             firstEntryPos = iFileCreationHelper.EntryAddingPos();
  1480 	    	}
  1489             }
  1481         else
  1490         else
  1482         	{
  1491             {
  1483         	firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
  1492             firstEntryPos.iCluster=FindLeafDirL(fullName.Left(nPos), leafDir);
  1484         	firstEntryPos.iPos=0;
  1493             firstEntryPos.iPos=0;
  1485         	}
  1494             }
  1486 
  1495 
  1487         AddDirEntryL(firstEntryPos,numEntries);
  1496         AddDirEntryL(firstEntryPos,numEntries);
  1488         firstEntry.InitZ();
  1497         firstEntry.InitZ();
  1489         firstEntry.SetName(shortName);
  1498         firstEntry.SetName(shortName);
  1490         firstEntry.SetStartCluster(0);
  1499         firstEntry.SetStartCluster(0);
  1491 
  1500 
  1492         TTime now;
  1501         TTime now;
  1493 		now.UniversalTime();
  1502         now.UniversalTime();
  1494         firstEntry.SetCreateTime(now, TimeOffset() );
  1503         firstEntry.SetCreateTime(now, TimeOffset() );
  1495 
  1504 
  1496         if (iFileCreationHelper.IsTrgNameLegalDosName())
  1505         if (iFileCreationHelper.IsTrgNameLegalDosName())
  1497             WriteDirEntryL(firstEntryPos,firstEntry);
  1506             WriteDirEntryL(firstEntryPos,firstEntry);
  1498         else
  1507         else
  1555 
  1564 
  1556         TFileName fileName;
  1565         TFileName fileName;
  1557         TEntryPos startPos;
  1566         TEntryPos startPos;
  1558         TFatDirEntry startEntry;
  1567         TFatDirEntry startEntry;
  1559         DoFindL(dirPath.Mid(dirPos),
  1568         DoFindL(dirPath.Mid(dirPos),
  1560         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1569                 KEntryAttMatchMask|KEntryAttMatchExclusive,
  1561         		startPos, startEntry, dosEntryPos, dosEntry,
  1570                 startPos, startEntry, dosEntryPos, dosEntry,
  1562         		fileName, KErrPathNotFound,
  1571                 fileName, KErrPathNotFound,
  1563         		NULL,
  1572                 NULL,
  1564         		leafDir);
  1573                 leafDir);
  1565 
  1574 
  1566 
  1575 
  1567         }
  1576         }
  1568 
  1577 
  1569     TPtrC matchName(dirName.Mid(namePos+1));
  1578     TPtrC matchName(dirName.Mid(namePos+1));
  1859     TLex lex(aName);
  1868     TLex lex(aName);
  1860     TInt r;
  1869     TInt r;
  1861     TEntryPos entryPos(RootIndicator(),0);
  1870     TEntryPos entryPos(RootIndicator(),0);
  1862 
  1871 
  1863     if (iLeafDirCache == NULL)
  1872     if (iLeafDirCache == NULL)
  1864     	{
  1873         {
  1865         TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
  1874         TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
  1866         TInt namelen=aName.Length();
  1875         TInt namelen=aName.Length();
  1867         if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
  1876         if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
  1868             {
  1877             {
  1869             if (leaflen==namelen)
  1878             if (leaflen==namelen)
  1870                 return(iLastLeafDirCluster);
  1879                 return(iLastLeafDirCluster);
  1871             lex.Inc(leaflen-1);
  1880             lex.Inc(leaflen-1);
  1872             entryPos.iCluster=iLastLeafDirCluster;
  1881             entryPos.iCluster=iLastLeafDirCluster;
  1873             }
  1882             }
  1874     	}
  1883         }
  1875     else
  1884     else
  1876     	{
  1885         {
  1877         // Skip root directory
  1886         // Skip root directory
  1878         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1887         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1879         	{
  1888             {
  1880         	TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1889             TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1881         	if (err == KErrNone)
  1890             if (err == KErrNone)
  1882         		{
  1891                 {
  1883         		ASSERT(aLeafDir.iClusterNum > 0);
  1892                 ASSERT(aLeafDir.iClusterNum > 0);
  1884         		return aLeafDir.iClusterNum;
  1893                 return aLeafDir.iClusterNum;
  1885         		}
  1894                 }
  1886         	else if (err != KErrNotFound)
  1895             else if (err != KErrNotFound)
  1887         		{
  1896                 {
  1888         		User::LeaveIfError(err);
  1897                 User::LeaveIfError(err);
  1889         		}
  1898                 }
  1890         	}
  1899             }
  1891     	}
  1900         }
  1892 
  1901 
  1893     FOREVER
  1902     FOREVER
  1894         {
  1903         {
  1895         lex.Inc(); // Skip path delimiter
  1904         lex.Inc(); // Skip path delimiter
  1896         lex.Mark();
  1905         lex.Mark();
  1904 
  1913 
  1905         TFileName fileName;
  1914         TFileName fileName;
  1906         TEntryPos startPos;
  1915         TEntryPos startPos;
  1907         TFatDirEntry startEntry;
  1916         TFatDirEntry startEntry;
  1908         DoFindL(lex.MarkedToken(),
  1917         DoFindL(lex.MarkedToken(),
  1909         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1918                 KEntryAttMatchMask|KEntryAttMatchExclusive,
  1910         		startPos, startEntry, entryPos, entry,
  1919                 startPos, startEntry, entryPos, entry,
  1911         		fileName, KErrPathNotFound,
  1920                 fileName, KErrPathNotFound,
  1912         		NULL,
  1921                 NULL,
  1913         		aLeafDir);
  1922                 aLeafDir);
  1914 
  1923 
  1915 
  1924 
  1916         entryPos.iCluster=StartCluster(entry);
  1925         entryPos.iCluster=StartCluster(entry);
  1917         entryPos.iPos=0;
  1926         entryPos.iPos=0;
  1918         }
  1927         }
  1919 
  1928 
  1920     if (iLeafDirCache == NULL)
  1929     if (iLeafDirCache == NULL)
  1921     	{
  1930         {
  1922         AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
  1931         AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
  1923         ((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
  1932         ((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
  1924     	}
  1933         }
  1925     else
  1934     else
  1926     	{
  1935         {
  1927         if (aName.Length() > 1)
  1936         if (aName.Length() > 1)
  1928         	{
  1937             {
  1929         	aLeafDir = TLeafDirData(entryPos.iCluster);
  1938             aLeafDir = TLeafDirData(entryPos.iCluster);
  1930             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1939             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1931         	}
  1940             }
  1932     	}
  1941         }
  1933 
  1942 
  1934     return entryPos.iCluster;
  1943     return entryPos.iCluster;
  1935     }
  1944     }
  1936 
  1945 
  1937 //-----------------------------------------------------------------------------------------
  1946 //-----------------------------------------------------------------------------------------
  1950     @param  aFileCreationHelper       a helper package for file creations
  1959     @param  aFileCreationHelper       a helper package for file creations
  1951 
  1960 
  1952     @return ETrue if the specified name is found in the cache. In this case aStartEntryPos, aStartEntry, aDosEntryPos, aDosEntry, aFileName will contain valid values
  1961     @return ETrue if the specified name is found in the cache. In this case aStartEntryPos, aStartEntry, aDosEntryPos, aDosEntry, aFileName will contain valid values
  1953 */
  1962 */
  1954 TBool CFatMountCB::DoRummageDirCacheL(const TUint anAtt, TEntryPos& aStartEntryPos,  
  1963 TBool CFatMountCB::DoRummageDirCacheL(const TUint anAtt, TEntryPos& aStartEntryPos,  
  1955 										TFatDirEntry& aStartEntry,	TEntryPos& aDosEntryPos,
  1964                                         TFatDirEntry& aStartEntry,  TEntryPos& aDosEntryPos,
  1956 										TFatDirEntry& aDosEntry,	TDes& aFileName,
  1965                                         TFatDirEntry& aDosEntry,    TDes& aFileName,
  1957 										const TFindHelper& aAuxParam,
  1966                                         const TFindHelper& aAuxParam,
  1958 										XFileCreationHelper* aFileCreationHelper,
  1967                                         XFileCreationHelper* aFileCreationHelper,
  1959 										const TLeafDirData& aLeafDir) const
  1968                                         const TLeafDirData& aLeafDir) const
  1960 	{
  1969     {
  1961     TBool bCacheMatchFound = EFalse;
  1970     TBool bCacheMatchFound = EFalse;
  1962 
  1971 
  1963     //-- get an interface to the Dir. cache
  1972     //-- get an interface to the Dir. cache
  1964     MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  1973     MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  1965     ASSERT(pDirCache);
  1974     ASSERT(pDirCache);
  1976 
  1985 
  1977     const TUint32 clSize = 1 << ClusterSizeLog2(); //-- media cluster size
  1986     const TUint32 clSize = 1 << ClusterSizeLog2(); //-- media cluster size
  1978     const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
  1987     const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
  1979     const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2;  //-- maximal number of dir entries that can be in the cache
  1988     const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2;  //-- maximal number of dir entries that can be in the cache
  1980 
  1989 
  1981     const TUint	  pageSzLog2 = pDirCache->PageSizeInBytesLog2();
  1990     const TUint   pageSzLog2 = pDirCache->PageSizeInBytesLog2();
  1982     TBool ScanMRUPageFirst 	= EFalse;
  1991     TBool ScanMRUPageFirst  = EFalse;
  1983 	TBool MRUPageScanned 	= EFalse;
  1992     TBool MRUPageScanned    = EFalse;
  1984 
  1993 
  1985 	// if MRU pos is availale, start with MRU page
  1994     // if MRU pos is availale, start with MRU page
  1986 	if (aLeafDir.iMRUPos.Cluster())
  1995     if (aLeafDir.iMRUPos.Cluster())
  1987     	{
  1996         {
  1988     	ScanMRUPageFirst = ETrue;
  1997         ScanMRUPageFirst = ETrue;
  1989     	DosEntryPos1 = aLeafDir.iMRUPos;
  1998         DosEntryPos1 = aLeafDir.iMRUPos;
  1990     	}
  1999         }
  1991 
  2000 
  1992 	TInt numFound = 0;
  2001     TInt numFound = 0;
  1993 	TEntryPos startPos = DosEntryPos1;
  2002     TEntryPos startPos = DosEntryPos1;
  1994 	TInt clusterNum = DosEntryPos1.iCluster;
  2003     TInt clusterNum = DosEntryPos1.iCluster;
  1995 
  2004 
  1996     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  2005     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  1997         {//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
  2006         {//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
  1998          //-- that can be cached. Helps to avoid problems with infinite (looped) directories
  2007          //-- that can be cached. Helps to avoid problems with infinite (looped) directories
  1999 
  2008 
  2000         if (IsEndOfClusterCh(DosEntryPos1.iCluster))
  2009         if (IsEndOfClusterCh(DosEntryPos1.iCluster))
  2001         	{
  2010             {
  2002         	// refer back to the last stored cluster position
  2011             // refer back to the last stored cluster position
  2003         	//  note aFileCreationHelper may not be initialised for file opening operations
  2012             //  note aFileCreationHelper may not be initialised for file opening operations
  2004         	if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && clusterNum != DosEntryPos1.iCluster)
  2013             if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && clusterNum != DosEntryPos1.iCluster)
  2005         		{
  2014                 {
  2006         	    TEntryPos dummyPos(clusterNum, clSize - KSizeOfFatDirEntry);
  2015                 TEntryPos dummyPos(clusterNum, clSize - KSizeOfFatDirEntry);
  2007         	    aFileCreationHelper->SetEntryAddingPos(dummyPos);
  2016                 aFileCreationHelper->SetEntryAddingPos(dummyPos);
  2008         		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2017                 aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2009         		}
  2018                 }
  2010 
  2019 
  2011         	if (ScanMRUPageFirst && !MRUPageScanned)
  2020             if (ScanMRUPageFirst && !MRUPageScanned)
  2012         		{
  2021                 {
  2013             	DosEntryPos1 = aDosEntryPos;
  2022                 DosEntryPos1 = aDosEntryPos;
  2014             	MRUPageScanned = ETrue;
  2023                 MRUPageScanned = ETrue;
  2015             	continue;
  2024                 continue;
  2016         		}
  2025                 }
  2017             break; //-- this was the last cluster in this directory
  2026             break; //-- this was the last cluster in this directory
  2018         	}
  2027             }
  2019 
  2028 
  2020         const TUint32 pageStartPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2029         const TUint32 pageStartPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2021     	DosEntryPos1.iPos = pageStartPos;
  2030         DosEntryPos1.iPos = pageStartPos;
  2022         TBool	PassedPageBoundary = EFalse;
  2031         TBool   PassedPageBoundary = EFalse;
  2023 
  2032 
  2024         const TInt64  entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
  2033         const TInt64  entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
  2025         const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos, nCachedLinPos); //-- indicates if entryLinPos is cached
  2034         const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos, nCachedLinPos); //-- indicates if entryLinPos is cached
  2026         if(cachePageSz)
  2035         if(cachePageSz)
  2027             {//-- current page is in the directory cache
  2036             {//-- current page is in the directory cache
  2043                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2052                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2044                 if(nErr != KErrNone)
  2053                 if(nErr != KErrNone)
  2045                     break;
  2054                     break;
  2046 
  2055 
  2047                 if(DosEntry1.IsEndOfDirectory())
  2056                 if(DosEntry1.IsEndOfDirectory())
  2048                 	{
  2057                     {
  2049                 	if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2058                     if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2050 		            	{
  2059                         {
  2051 		            	// note it is impossible to be at the end of the cluster chain here.
  2060                         // note it is impossible to be at the end of the cluster chain here.
  2052 	            		aFileCreationHelper->SetEntryAddingPos(DosEntryPos1);
  2061                         aFileCreationHelper->SetEntryAddingPos(DosEntryPos1);
  2053 	            		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2062                         aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2054 		            	}
  2063                         }
  2055 
  2064 
  2056                 	if (ScanMRUPageFirst && !MRUPageScanned)
  2065                     if (ScanMRUPageFirst && !MRUPageScanned)
  2057                 		{
  2066                         {
  2058                     	break;
  2067                         break;
  2059                 		}
  2068                         }
  2060 
  2069 
  2061                 	// if (!ScanMRUPageFirst || ScanMRUPageFirst && MRUPageScanned)
  2070                     // if (!ScanMRUPageFirst || ScanMRUPageFirst && MRUPageScanned)
  2062                     goto Exit; //-- this was the last entry in this directory, no reason to look further
  2071                     goto Exit; //-- this was the last entry in this directory, no reason to look further
  2063                 	}
  2072                     }
  2064 
  2073 
  2065                 if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2074                 if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2066 		        	{
  2075                     {
  2067 		            if (!DosEntry1.IsErased() && !DosEntry1.IsGarbage())
  2076                     if (!DosEntry1.IsErased() && !DosEntry1.IsGarbage())
  2068 		            	{
  2077                         {
  2069 		            	numFound = 0;
  2078                         numFound = 0;
  2070 		            	}
  2079                         }
  2071 		            else
  2080                     else
  2072 		            	{
  2081                         {
  2073 		            	if (numFound == 0)
  2082                         if (numFound == 0)
  2074 		            		{
  2083                             {
  2075 		            		startPos = DosEntryPos1;
  2084                             startPos = DosEntryPos1;
  2076 		            		}
  2085                             }
  2077 		            	numFound++;
  2086                         numFound++;
  2078 		            	if (numFound == aFileCreationHelper->NumOfAddingEntries())
  2087                         if (numFound == aFileCreationHelper->NumOfAddingEntries())
  2079 		            		{
  2088                             {
  2080 		            		aFileCreationHelper->SetEntryAddingPos(startPos);
  2089                             aFileCreationHelper->SetEntryAddingPos(startPos);
  2081 		            		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2090                             aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2082 		            		}
  2091                             }
  2083 		            	}
  2092                         }
  2084 		        	}
  2093                     }
  2085                 if(MatchEntryAtt(DosEntry1.Attributes(),anAtt))
  2094                 if(MatchEntryAtt(DosEntry1.Attributes(),anAtt))
  2086                     {//-- FAT or VFAT dir entry is extracted and attributes match. Compare names then.
  2095                     {//-- FAT or VFAT dir entry is extracted and attributes match. Compare names then.
  2087 
  2096 
  2088                     if(StartEntry1.IsVFatEntry())
  2097                     if(StartEntry1.IsVFatEntry())
  2089                         {//-- extracted entry is VFAT one, name can be in UNICODE
  2098                         {//-- extracted entry is VFAT one, name can be in UNICODE
  2090 
  2099 
  2091                         // we only check short name candidates for long file names with VFAT entries,
  2100                         // we only check short name candidates for long file names with VFAT entries,
  2092                         //  if it is a valid dos name, it will be checked by default
  2101                         //  if it is a valid dos name, it will be checked by default
  2093                         // note here target name is always fully specified
  2102                         // note here target name is always fully specified
  2094                         if (aFileCreationHelper && aFileCreationHelper->IsInitialised())
  2103                         if (aFileCreationHelper && aFileCreationHelper->IsInitialised())
  2095                         	{
  2104                             {
  2096                         	aFileCreationHelper->CheckShortNameCandidates(DosEntry1.Name().Ptr());
  2105                             aFileCreationHelper->CheckShortNameCandidates(DosEntry1.Name().Ptr());
  2097                         	}
  2106                             }
  2098 
  2107 
  2099                         TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
  2108                         TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
  2100 
  2109 
  2101                         if(ptrAssembledName.MatchF(aAuxParam.iTargetName) != KErrNotFound)
  2110                         if(ptrAssembledName.MatchF(aAuxParam.iTargetName) != KErrNotFound)
  2102                             {//-- found match in cache
  2111                             {//-- found match in cache
  2145 
  2154 
  2146                 // if we are still in the same cluster, check the page boundary by
  2155                 // if we are still in the same cluster, check the page boundary by
  2147                 /// exam how many entries we have scanned within the cluster
  2156                 /// exam how many entries we have scanned within the cluster
  2148                 const TUint entriesLooked =  ((DosEntryPos1.iPos + KSizeOfFatDirEntry)- pageStartPos) >> KSizeOfFatDirEntryLog2;
  2157                 const TUint entriesLooked =  ((DosEntryPos1.iPos + KSizeOfFatDirEntry)- pageStartPos) >> KSizeOfFatDirEntryLog2;
  2149                 if(entriesLooked > nEntries)
  2158                 if(entriesLooked > nEntries)
  2150                 	{
  2159                     {
  2151                 	PassedPageBoundary = ETrue;
  2160                     PassedPageBoundary = ETrue;
  2152                     break;
  2161                     break;
  2153                 	}
  2162                     }
  2154 
  2163 
  2155 
  2164 
  2156                 // move to next entry before scanning next file
  2165                 // move to next entry before scanning next file
  2157                 TRAP(nErr,MoveToNextEntryL(DosEntryPos1));
  2166                 TRAP(nErr,MoveToNextEntryL(DosEntryPos1));
  2158                 if(nErr != KErrNone)
  2167                 if(nErr != KErrNone)
  2164                     DosEntryPos1.iCluster = clSave;
  2173                     DosEntryPos1.iCluster = clSave;
  2165                     break;
  2174                     break;
  2166                     }
  2175                     }
  2167 
  2176 
  2168                 if (entriesLooked + 1 > nEntries)
  2177                 if (entriesLooked + 1 > nEntries)
  2169                 	{
  2178                     {
  2170                 	PassedPageBoundary = ETrue;
  2179                     PassedPageBoundary = ETrue;
  2171                     break;
  2180                     break;
  2172                 	}
  2181                     }
  2173 
  2182 
  2174                 } //for(;;)
  2183                 } //for(;;)
  2175 
  2184 
  2176             } //if(iRawDisk->PosCached(...))
  2185             } //if(iRawDisk->PosCached(...))
  2177 
  2186 
  2181 
  2190 
  2182         // if MRU page is not cached or
  2191         // if MRU page is not cached or
  2183         // we scan MRU page first and it is not scanned yet, then this must be the MRU page,
  2192         // we scan MRU page first and it is not scanned yet, then this must be the MRU page,
  2184         //  we now start to scan from the beginning
  2193         //  we now start to scan from the beginning
  2185         if (ScanMRUPageFirst && !MRUPageScanned)
  2194         if (ScanMRUPageFirst && !MRUPageScanned)
  2186         	{
  2195             {
  2187         	MRUPageScanned = ETrue;
  2196             MRUPageScanned = ETrue;
  2188         	DosEntryPos1 = aDosEntryPos;
  2197             DosEntryPos1 = aDosEntryPos;
  2189         	DosEntryPos1.iPos = 0;
  2198             DosEntryPos1.iPos = 0;
  2190         	continue;
  2199             continue;
  2191         	}
  2200             }
  2192 
  2201 
  2193         // if we just finished scanning a page and still in the same cluster, then we crossed page
  2202         // if we just finished scanning a page and still in the same cluster, then we crossed page
  2194         // 	boundary, continue with next page.
  2203         //  boundary, continue with next page.
  2195         // note: although we are in the 'next page' already, this page might not be cached, so we need to
  2204         // note: although we are in the 'next page' already, this page might not be cached, so we need to
  2196         //  check it via pDirCache->PosCached(entryLinPos, nCachedLinPos) and scan it properly.
  2205         //  check it via pDirCache->PosCached(entryLinPos, nCachedLinPos) and scan it properly.
  2197         if (PassedPageBoundary)
  2206         if (PassedPageBoundary)
  2198         	{
  2207             {
  2199         	DosEntryPos1.iPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2208             DosEntryPos1.iPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2200         	PassedPageBoundary = EFalse;
  2209             PassedPageBoundary = EFalse;
  2201         	continue;
  2210             continue;
  2202         	}
  2211             }
  2203 
  2212 
  2204         //-- try to move to the next cluster of the directory file
  2213         //-- try to move to the next cluster of the directory file
  2205 
  2214 
  2206         if(DosEntryPos1.Cluster() < KFatFirstSearchCluster)  //-- small trick to get rid of TRAPping GetNextClusterL()
  2215         if(DosEntryPos1.Cluster() < KFatFirstSearchCluster)  //-- small trick to get rid of TRAPping GetNextClusterL()
  2207             break;
  2216             break;
  2249 
  2258 
  2250         const TInt64  mruPos = MakeLinAddrL(aDosEntryPos);
  2259         const TInt64  mruPos = MakeLinAddrL(aDosEntryPos);
  2251         
  2260         
  2252         pDirCache->MakePageMRU(mruPos);
  2261         pDirCache->MakePageMRU(mruPos);
  2253 
  2262 
  2254     	// only update the leaf dir cache when the original cache index is provided
  2263         // only update the leaf dir cache when the original cache index is provided
  2255     	if (aLeafDir.iClusterNum)
  2264         if (aLeafDir.iClusterNum)
  2256     		{
  2265             {
  2257             iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDir.iClusterNum, aStartEntryPos));
  2266             iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDir.iClusterNum, aStartEntryPos));
  2258     		}
  2267             }
  2259         }
  2268         }
  2260     return bCacheMatchFound;
  2269     return bCacheMatchFound;
  2261     }
  2270     }
  2262 
  2271 
  2263 //-----------------------------------------------------------------------------------------
  2272 //-----------------------------------------------------------------------------------------
  2306 const TInt KShortNameCandidatesNum = 4;
  2315 const TInt KShortNameCandidatesNum = 4;
  2307 /**
  2316 /**
  2308 Constructor of XFileCreationHelper class
  2317 Constructor of XFileCreationHelper class
  2309 */
  2318 */
  2310 CFatMountCB::XFileCreationHelper::XFileCreationHelper()
  2319 CFatMountCB::XFileCreationHelper::XFileCreationHelper()
  2311 	{
  2320     {
  2312     isInitialised = EFalse;
  2321     isInitialised = EFalse;
  2313 	}
  2322     }
  2314 
  2323 
  2315 /**
  2324 /**
  2316 Destructor of XFileCreationHelper class
  2325 Destructor of XFileCreationHelper class
  2317 */
  2326 */
  2318 CFatMountCB::XFileCreationHelper::~XFileCreationHelper()
  2327 CFatMountCB::XFileCreationHelper::~XFileCreationHelper()
  2319 	{
  2328     {
  2320 	Close();
  2329     Close();
  2321 	}
  2330     }
  2322 
  2331 
  2323 /**
  2332 /**
  2324 Initialises a TFileCreationHelper object, generate a short name candidate pool.
  2333 Initialises a TFileCreationHelper object, generate a short name candidate pool.
  2325 
  2334 
  2326 @param	aTargetName	Target file name for the potential new file.
  2335 @param  aTargetName Target file name for the potential new file.
  2327 @post	TFileCreationHelper is fully initialised.
  2336 @post   TFileCreationHelper is fully initialised.
  2328 */
  2337 */
  2329 void CFatMountCB::XFileCreationHelper::InitialiseL(const TDesC& aTargetName)
  2338 void CFatMountCB::XFileCreationHelper::InitialiseL(const TDesC& aTargetName)
  2330 	{
  2339     {
  2331     // close before use, to avoid memory leak
  2340     // close before use, to avoid memory leak
  2332 	Close();
  2341     Close();
  2333 
  2342 
  2334     iTargetName.Set(aTargetName);
  2343     iTargetName.Set(aTargetName);
  2335 	// generates short name candidate(s)
  2344     // generates short name candidate(s)
  2336     TInt count = 1;
  2345     TInt count = 1;
  2337     while (count <= KShortNameCandidatesNum)
  2346     while (count <= KShortNameCandidatesNum)
  2338 		{
  2347         {
  2339 		TShortName shortNameCandidate = DoGenerateShortNameL(aTargetName, count, ETrue);
  2348         TShortName shortNameCandidate = DoGenerateShortNameL(aTargetName, count, ETrue);
  2340 		TInt err = iShortNameCandidates.Append(shortNameCandidate);
  2349         TInt err = iShortNameCandidates.Append(shortNameCandidate);
  2341 		User::LeaveIfError(err);
  2350         User::LeaveIfError(err);
  2342 
  2351 
  2343 		if (count == -1)	// No tilde and number is needed
  2352         if (count == -1)    // No tilde and number is needed
  2344 			{
  2353             {
  2345 			break;
  2354             break;
  2346 			}
  2355             }
  2347 		else
  2356         else
  2348 			count++;
  2357             count++;
  2349 		}
  2358         }
  2350 
  2359 
  2351     // calculate number of new entries needed
  2360     // calculate number of new entries needed
  2352     iNumOfAddingEntries = 1;
  2361     iNumOfAddingEntries = 1;
  2353     isTrgNameLegalDosName = IsLegalDosName(aTargetName, EFalse, EFalse, EFalse, EFalse, ETrue);
  2362     isTrgNameLegalDosName = IsLegalDosName(aTargetName, EFalse, EFalse, EFalse, EFalse, ETrue);
  2354     if (!isTrgNameLegalDosName)
  2363     if (!isTrgNameLegalDosName)
  2355     	iNumOfAddingEntries = (TUint16) NumberOfVFatEntries(iTargetName.Length());
  2364         iNumOfAddingEntries = (TUint16) NumberOfVFatEntries(iTargetName.Length());
  2356 
  2365 
  2357     isNewEntryPosFound = EFalse;
  2366     isNewEntryPosFound = EFalse;
  2358     isInitialised = ETrue;
  2367     isInitialised = ETrue;
  2359     }
  2368     }
  2360 
  2369 
  2361 /**
  2370 /**
  2362 Close function of XFileCreationHelper class
  2371 Close function of XFileCreationHelper class
  2363 */
  2372 */
  2364 void CFatMountCB::XFileCreationHelper::Close()
  2373 void CFatMountCB::XFileCreationHelper::Close()
  2365 	{
  2374     {
  2366 	iShortNameCandidates.Close();
  2375     iShortNameCandidates.Close();
  2367 	isInitialised = EFalse;
  2376     isInitialised = EFalse;
  2368 	}
  2377     }
  2369 
  2378 
  2370 /**
  2379 /**
  2371 Validates short name candidates. If the input dos entry name is found in the short name
  2380 Validates short name candidates. If the input dos entry name is found in the short name
  2372  candidate pool, the corresponding short name candidate will be removed from the pool.
  2381  candidate pool, the corresponding short name candidate will be removed from the pool.
  2373 
  2382 
  2374 @param	apDosEntryName	An existing short name, to compare with the candidates.
  2383 @param  apDosEntryName  An existing short name, to compare with the candidates.
  2375 @pre 	Object should be initialised
  2384 @pre    Object should be initialised
  2376 */
  2385 */
  2377 void CFatMountCB::XFileCreationHelper::CheckShortNameCandidates(const TUint8* apDosEntryName)
  2386 void CFatMountCB::XFileCreationHelper::CheckShortNameCandidates(const TUint8* apDosEntryName)
  2378     {
  2387     {
  2379     ASSERT(isInitialised);
  2388     ASSERT(isInitialised);
  2380     if (!isInitialised)
  2389     if (!isInitialised)
  2381     	return;
  2390         return;
  2382 
  2391 
  2383     if (iShortNameCandidates.Count() > 0)
  2392     if (iShortNameCandidates.Count() > 0)
  2384     	{
  2393         {
  2385     	for (TInt i = 0; i < iShortNameCandidates.Count(); i++)
  2394         for (TInt i = 0; i < iShortNameCandidates.Count(); i++)
  2386     		{
  2395             {
  2387     		if (Mem::Compare(iShortNameCandidates[i].Ptr(), KFatDirNameSize, apDosEntryName, KFatDirNameSize) == 0)
  2396             if (Mem::Compare(iShortNameCandidates[i].Ptr(), KFatDirNameSize, apDosEntryName, KFatDirNameSize) == 0)
  2388     			{
  2397                 {
  2389     			iShortNameCandidates.Remove(i);
  2398                 iShortNameCandidates.Remove(i);
  2390     			break;
  2399                 break;
  2391     			}
  2400                 }
  2392     		}
  2401             }
  2393     	}
  2402         }
  2394     }
  2403     }
  2395 
  2404 
  2396 /**
  2405 /**
  2397 Gets a validated short name from the short name candidate pool.
  2406 Gets a validated short name from the short name candidate pool.
  2398 
  2407 
  2399 @param	aShortName	On return, contains a validated short name if found, otherwise zeroed.
  2408 @param  aShortName  On return, contains a validated short name if found, otherwise zeroed.
  2400 @return	TInt		Returns KErrNone if a validated short name found successfully,
  2409 @return TInt        Returns KErrNone if a validated short name found successfully,
  2401  					 else KErrNotFound is returned.
  2410                      else KErrNotFound is returned.
  2402  					Returns KErrNotReady if object is not initialised.
  2411                     Returns KErrNotReady if object is not initialised.
  2403 @pre 	Object should be initialised
  2412 @pre    Object should be initialised
  2404 */
  2413 */
  2405 TInt CFatMountCB::XFileCreationHelper::GetValidatedShortName(TShortName& aShortName) const
  2414 TInt CFatMountCB::XFileCreationHelper::GetValidatedShortName(TShortName& aShortName) const
  2406 	{
  2415     {
  2407 	aShortName.Zero();
  2416     aShortName.Zero();
  2408 
  2417 
  2409 	ASSERT(isInitialised);
  2418     ASSERT(isInitialised);
  2410 	if (!isInitialised)
  2419     if (!isInitialised)
  2411 		return KErrNotReady;
  2420         return KErrNotReady;
  2412 
  2421 
  2413 	if (iShortNameCandidates.Count() > 0)
  2422     if (iShortNameCandidates.Count() > 0)
  2414 		{
  2423         {
  2415 		aShortName.Copy(iShortNameCandidates[0]);
  2424         aShortName.Copy(iShortNameCandidates[0]);
  2416 		return KErrNone;
  2425         return KErrNone;
  2417 		}
  2426         }
  2418 
  2427 
  2419 	return KErrNotFound;
  2428     return KErrNotFound;
  2420 	}
  2429     }
  2421 
  2430 
  2422 //-----------------------------------------------------------------------------------------
  2431 //-----------------------------------------------------------------------------------------
  2423 
  2432 
  2424 
  2433 
  2425 /**
  2434 /**
  2431     @param  aStartEntry     on return will contain first VFAT dir entry
  2440     @param  aStartEntry     on return will contain first VFAT dir entry
  2432     @param  aDosEntryPos    the search will start from this position of dir entry, on return it will contain result DOS entry position, last one for VFAT case
  2441     @param  aDosEntryPos    the search will start from this position of dir entry, on return it will contain result DOS entry position, last one for VFAT case
  2433     @param  aDosEntry       on return will contain DOS dir entry (the last one for VFAT case)
  2442     @param  aDosEntry       on return will contain DOS dir entry (the last one for VFAT case)
  2434     @param  aFileName       in the case of VFAT entry and on success here will be returned a long filename
  2443     @param  aFileName       in the case of VFAT entry and on success here will be returned a long filename
  2435     @param  anError         This function might leave with this given error code
  2444     @param  anError         This function might leave with this given error code
  2436 	@param  aFileCreationHelper       a helper package for file creations
  2445     @param  aFileCreationHelper       a helper package for file creations
  2437 
  2446 
  2438     @return ETrue if extracted entry is VFAT one, EFalse, if it's old DOS-style one
  2447     @return ETrue if extracted entry is VFAT one, EFalse, if it's old DOS-style one
  2439     @leave  can leave with anError code on error or if the search has reached the end of directory (!)
  2448     @leave  can leave with anError code on error or if the search has reached the end of directory (!)
  2440 */
  2449 */
  2441 TBool CFatMountCB::DoFindL(const TDesC& aTrgtName,TUint anAtt,
  2450 TBool CFatMountCB::DoFindL(const TDesC& aTrgtName,TUint anAtt,
  2442 						TEntryPos& aStartEntryPos,TFatDirEntry& aStartEntry,
  2451                         TEntryPos& aStartEntryPos,TFatDirEntry& aStartEntry,
  2443 						TEntryPos& aDosEntryPos,TFatDirEntry& aDosEntry,
  2452                         TEntryPos& aDosEntryPos,TFatDirEntry& aDosEntry,
  2444 						TDes& aFileName,TInt anError,
  2453                         TDes& aFileName,TInt anError,
  2445 						XFileCreationHelper* aFileCreationHelper,
  2454                         XFileCreationHelper* aFileCreationHelper,
  2446 						const TLeafDirData& aLeafDirData) const
  2455                         const TLeafDirData& aLeafDirData) const
  2447 	{
  2456     {
  2448     // check that the entry position to be read next is not past the end of the
  2457     // check that the entry position to be read next is not past the end of the
  2449     // root directory. If this is the case then when GetDirEntryL(..) is called
  2458     // root directory. If this is the case then when GetDirEntryL(..) is called
  2450     // this will lead to MakeLinAddr(..) leaving with KErrDirFull.
  2459     // this will lead to MakeLinAddr(..) leaving with KErrDirFull.
  2451 
  2460 
  2452     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2461     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2517     // we need to scan ahead from the mru pos then come back to beginning, if startcluster is provided
  2526     // we need to scan ahead from the mru pos then come back to beginning, if startcluster is provided
  2518     TBool scanAhead = EFalse;
  2527     TBool scanAhead = EFalse;
  2519     // if we have a starting cluster number (and it's not root directory in FAT16/12 case)&&
  2528     // if we have a starting cluster number (and it's not root directory in FAT16/12 case)&&
  2520     //  we found a lastScanned entry's cluster (and it's not root directory in FAT16/12 case)&&
  2529     //  we found a lastScanned entry's cluster (and it's not root directory in FAT16/12 case)&&
  2521     // if we don't have a starting cluster number, we draw back to original scanning algorithm
  2530     // if we don't have a starting cluster number, we draw back to original scanning algorithm
  2522     if (!IsRootDir(aDosEntryPos) 			// we don't do forward scanning for root dir &
  2531     if (!IsRootDir(aDosEntryPos)            // we don't do forward scanning for root dir &
  2523     		&& aLeafDirData.iClusterNum != 0 	// if we have a starting cluster number &
  2532             && aLeafDirData.iClusterNum != 0    // if we have a starting cluster number &
  2524     		&& aLeafDirData.iMRUPos.Cluster() != 0) 	// if we have a starting cluster number &
  2533             && aLeafDirData.iMRUPos.Cluster() != 0)     // if we have a starting cluster number &
  2525     	{
  2534         {
  2526     	scanAhead = ETrue;
  2535         scanAhead = ETrue;
  2527     	aDosEntryPos = aLeafDirData.iMRUPos;
  2536         aDosEntryPos = aLeafDirData.iMRUPos;
  2528     	}
  2537         }
  2529 
  2538 
  2530     TInt numFound = 0;
  2539     TInt numFound = 0;
  2531     TEntryPos startPos = aDosEntryPos;
  2540     TEntryPos startPos = aDosEntryPos;
  2532     TInt clustNum = aDosEntryPos.Cluster();
  2541     TInt clustNum = aDosEntryPos.Cluster();
  2533 
  2542 
  2534     for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
  2543     for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
  2535     	{
  2544         {
  2536     	// if we are not scanning ahead, we don't need this outer for loop
  2545         // if we are not scanning ahead, we don't need this outer for loop
  2537     	if (!scanAhead)
  2546         if (!scanAhead)
  2538     		scanCnt++;
  2547             scanCnt++;
  2539 
  2548 
  2540     	TBool found = EFalse;
  2549         TBool found = EFalse;
  2541 
  2550 
  2542         FOREVER //FOREVER2 -- walk through all directory entries in the current directory until find a match or directory end
  2551         FOREVER //FOREVER2 -- walk through all directory entries in the current directory until find a match or directory end
  2543             {
  2552             {
  2544 	        //-- read full directory entry starting from aDosEntryPos. On return aFileName may contain assembled long filename (if the entry is VFAT)
  2553             //-- read full directory entry starting from aDosEntryPos. On return aFileName may contain assembled long filename (if the entry is VFAT)
  2545 	        //-- aDosEntry will contain a DOS entry of the directory entry we have read.
  2554             //-- aDosEntry will contain a DOS entry of the directory entry we have read.
  2546 	        aStartEntryPos=aDosEntryPos;
  2555             aStartEntryPos=aDosEntryPos;
  2547 	        User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, aStartEntry, aFileName));
  2556             User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, aStartEntry, aFileName));
  2548 
  2557 
  2549 	        if (aDosEntry.IsEndOfDirectory())
  2558             if (aDosEntry.IsEndOfDirectory())
  2550 	            {//-- the end of directory reached.
  2559                 {//-- the end of directory reached.
  2551 
  2560 
  2552 	            // if new entry position for adding has not been found yet.
  2561                 // if new entry position for adding has not been found yet.
  2553 	            // note aFileCreationHelper may not be initialised for pure file opening operations
  2562                 // note aFileCreationHelper may not be initialised for pure file opening operations
  2554 	            if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2563                 if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2555 	            	{
  2564                     {
  2556 	            	// if MoveToNextEntryL have gone to the next cluster which is the end of cluster chain,
  2565                     // if MoveToNextEntryL have gone to the next cluster which is the end of cluster chain,
  2557 	            	//  we pass the last scanned entry position to AddDirEntryL
  2566                     //  we pass the last scanned entry position to AddDirEntryL
  2558 	            	if (IsEndOfClusterCh(aDosEntryPos.iCluster))
  2567                     if (IsEndOfClusterCh(aDosEntryPos.iCluster))
  2559 	            		{
  2568                         {
  2560 	            	    TInt clusterSize=1<<ClusterSizeLog2();
  2569                         TInt clusterSize=1<<ClusterSizeLog2();
  2561 	            	    TEntryPos dummyPos(clustNum, clusterSize - KSizeOfFatDirEntry);
  2570                         TEntryPos dummyPos(clustNum, clusterSize - KSizeOfFatDirEntry);
  2562 	            	    aFileCreationHelper->SetEntryAddingPos(dummyPos);
  2571                         aFileCreationHelper->SetEntryAddingPos(dummyPos);
  2563 	            		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2572                         aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2564 	            		}
  2573                         }
  2565 	            	// or we reached the end of the directory.
  2574                     // or we reached the end of the directory.
  2566 	            	else
  2575                     else
  2567 	            		{
  2576                         {
  2568 	            		aFileCreationHelper->SetEntryAddingPos(aDosEntryPos);
  2577                         aFileCreationHelper->SetEntryAddingPos(aDosEntryPos);
  2569 	            		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2578                         aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2570 	            		}
  2579                         }
  2571 	            	}
  2580                     }
  2572 
  2581 
  2573 	            // if we are scanning ahead and this is the first scanning, we break out to restart scanning
  2582                 // if we are scanning ahead and this is the first scanning, we break out to restart scanning
  2574 	            if (scanAhead && scanCnt == 1)
  2583                 if (scanAhead && scanCnt == 1)
  2575 	            	{
  2584                     {
  2576 	            	break; // from FOREVER, restart scanning
  2585                     break; // from FOREVER, restart scanning
  2577 	            	}
  2586                     }
  2578 
  2587 
  2579 	            // if (!scanAhead || scanAhead && scanCnt == 2)
  2588                 // if (!scanAhead || scanAhead && scanCnt == 2)
  2580 	            User::Leave(anError);
  2589                 User::Leave(anError);
  2581 	            }
  2590                 }
  2582 
  2591 
  2583 
  2592 
  2584 	        // entry space searching for potential new file/directory creation
  2593             // entry space searching for potential new file/directory creation
  2585 	        if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2594             if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && !aFileCreationHelper->IsNewEntryPosFound())
  2586 	        	{
  2595                 {
  2587 	            if (!aDosEntry.IsErased() && !aDosEntry.IsGarbage())
  2596                 if (!aDosEntry.IsErased() && !aDosEntry.IsGarbage())
  2588 	            	{
  2597                     {
  2589 	            	numFound = 0;
  2598                     numFound = 0;
  2590 	            	}
  2599                     }
  2591 	            else
  2600                 else
  2592 	            	{
  2601                     {
  2593 	            	if (numFound == 0)
  2602                     if (numFound == 0)
  2594 	            		{
  2603                         {
  2595 	            		startPos = aDosEntryPos;
  2604                         startPos = aDosEntryPos;
  2596 	            		}
  2605                         }
  2597 	            	numFound++;
  2606                     numFound++;
  2598 	            	if (numFound == aFileCreationHelper->NumOfAddingEntries())
  2607                     if (numFound == aFileCreationHelper->NumOfAddingEntries())
  2599 	            		{
  2608                         {
  2600 	            		aFileCreationHelper->SetEntryAddingPos(startPos);
  2609                         aFileCreationHelper->SetEntryAddingPos(startPos);
  2601 	            		aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2610                         aFileCreationHelper->SetIsNewEntryPosFound(ETrue);
  2602 	            		}
  2611                         }
  2603 	            	}
  2612                     }
  2604 	        	}
  2613                 }
  2605 
  2614 
  2606 
  2615 
  2607 	        if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
  2616             if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
  2608 	            if (aDosEntry.IsErased())
  2617                 if (aDosEntry.IsErased())
  2609 	                {
  2618                     {
  2610 	                User::Leave(anError);//Allows maximum number of entries in root directory
  2619                     User::Leave(anError);//Allows maximum number of entries in root directory
  2611 	                }
  2620                     }
  2612 
  2621 
  2613 
  2622 
  2614 	        const TBool bFileNameEntry = !aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage();
  2623             const TBool bFileNameEntry = !aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage();
  2615 
  2624 
  2616 	        if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(), anAtt))
  2625             if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(), anAtt))
  2617 	            {//-- we have read a filename entry and entry's attributes match required; compare names then.
  2626                 {//-- we have read a filename entry and entry's attributes match required; compare names then.
  2618 
  2627 
  2619 	            if (trgNameIsWildCard)
  2628                 if (trgNameIsWildCard)
  2620 	            	{
  2629                     {
  2621 	            	found = ETrue;
  2630                     found = ETrue;
  2622 	            	break; //-- we were looking for '*' or '*.*', so will be satisfied with any current file name.
  2631                     break; //-- we were looking for '*' or '*.*', so will be satisfied with any current file name.
  2623 	            	}
  2632                     }
  2624 
  2633 
  2625 
  2634 
  2626 	            if (aStartEntry.IsVFatEntry())
  2635                 if (aStartEntry.IsVFatEntry())
  2627 	                {//-- we've read a VFAT entry, aFileName is supposed to contain long filename, aDosEntry - DOS entry for this name.
  2636                     {//-- we've read a VFAT entry, aFileName is supposed to contain long filename, aDosEntry - DOS entry for this name.
  2628 	                 //-- note: aFileName.Length() may be 0, while DOS entry (short name is OK) in the case of orphaned VFAT entries
  2637                      //-- note: aFileName.Length() may be 0, while DOS entry (short name is OK) in the case of orphaned VFAT entries
  2629 
  2638 
  2630 
  2639 
  2631 	                // we only check short name candidates for long file names with VFAT entries,
  2640                     // we only check short name candidates for long file names with VFAT entries,
  2632 	                //  if it is a valid dos name, it will be checked by default
  2641                     //  if it is a valid dos name, it will be checked by default
  2633 	                // note, for file creation cases, target name will be always fully specified
  2642                     // note, for file creation cases, target name will be always fully specified
  2634 	                if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && trgNameFullySpecified)
  2643                     if (aFileCreationHelper && aFileCreationHelper->IsInitialised() && trgNameFullySpecified)
  2635 		            	 {
  2644                          {
  2636 		            	 aFileCreationHelper->CheckShortNameCandidates(aDosEntry.Name().Ptr());
  2645                          aFileCreationHelper->CheckShortNameCandidates(aDosEntry.Name().Ptr());
  2637 		            	 }
  2646                          }
  2638 
  2647 
  2639 	                //-- discard trailing dots from aFileName if present
  2648                     //-- discard trailing dots from aFileName if present
  2640 	                 TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
  2649                      TPtrC ptrAssembledName = RemoveTrailingDots(aFileName);
  2641 
  2650 
  2642 	                 if(ptrAssembledName.MatchF(trgtNameNoDot) != KErrNotFound)
  2651                      if(ptrAssembledName.MatchF(trgtNameNoDot) != KErrNotFound)
  2643 	                	 {
  2652                          {
  2644 						 found = ETrue;
  2653                          found = ETrue;
  2645 	                	 break; //-- OK, found a match.
  2654                          break; //-- OK, found a match.
  2646 	                	 }
  2655                          }
  2647 	                 else if (trgNameFullySpecified)
  2656                      else if (trgNameFullySpecified)
  2648 	                	 {
  2657                          {
  2649 	                	 //-- long name assembled by GetDirEntry() doesn't match the target. But if he target name is fully specified,
  2658                          //-- long name assembled by GetDirEntry() doesn't match the target. But if he target name is fully specified,
  2650 	                	 //-- we need to compare corresponding DOS entries, because VFAT entries may be damaged, while DOS ones are OK.
  2659                          //-- we need to compare corresponding DOS entries, because VFAT entries may be damaged, while DOS ones are OK.
  2651 	                     findHelper.InitialiseL(trgtNameNoDot);
  2660                          findHelper.InitialiseL(trgtNameNoDot);
  2652 
  2661 
  2653 	                     if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
  2662                          if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
  2654 	                    	 {
  2663                              {
  2655 							 found = ETrue;
  2664                              found = ETrue;
  2656 	                    	 break; //-- DOS entries match, success.
  2665                              break; //-- DOS entries match, success.
  2657 	                    	 }
  2666                              }
  2658 	                	 }
  2667                          }
  2659 	                 else if (!trgNameFullySpecified)
  2668                      else if (!trgNameFullySpecified)
  2660 	                	 {//-- target name contains wildcards, we need to use MatchF with dos name
  2669                          {//-- target name contains wildcards, we need to use MatchF with dos name
  2661 	                     TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
  2670                          TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
  2662 	                     TBuf<0x20>  dosName;
  2671                          TBuf<0x20>  dosName;
  2663 	                     LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
  2672                          LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
  2664 	                     if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
  2673                          if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
  2665 	                    	 {
  2674                              {
  2666 							 found = ETrue;
  2675                              found = ETrue;
  2667 							 break;
  2676                              break;
  2668 	                    	 }
  2677                              }
  2669 	                	 }
  2678                          }
  2670 
  2679 
  2671 
  2680 
  2672 	                }
  2681                     }
  2673 	            else //if (aStartEntry.IsVFatEntry())
  2682                 else //if (aStartEntry.IsVFatEntry())
  2674 	                {//-- we've read a legacy FAT entry, so compare DOS entries
  2683                     {//-- we've read a legacy FAT entry, so compare DOS entries
  2675 	                findHelper.InitialiseL(trgtNameNoDot);
  2684                     findHelper.InitialiseL(trgtNameNoDot);
  2676 
  2685 
  2677 	                if(findHelper.TrgtNameIsLegalDos())
  2686                     if(findHelper.TrgtNameIsLegalDos())
  2678 	                    {//-- we are looking for a legal DOS name
  2687                         {//-- we are looking for a legal DOS name
  2679 	                    if(trgNameFullySpecified)
  2688                         if(trgNameFullySpecified)
  2680 	                        {//-- if the target name is fully specified, we can yse binary comparison of the DOS entries
  2689                             {//-- if the target name is fully specified, we can yse binary comparison of the DOS entries
  2681 	                        if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
  2690                             if(findHelper.MatchDosEntryName(aDosEntry.Name().Ptr()))
  2682 	                        	{
  2691                                 {
  2683 								found = ETrue;
  2692                                 found = ETrue;
  2684 	                            break;
  2693                                 break;
  2685 	                        	}
  2694                                 }
  2686 	                        }
  2695                             }
  2687 	                    else
  2696                         else
  2688 	                        {//-- target name contains wildcards, we neeed to use MatchF
  2697                             {//-- target name contains wildcards, we neeed to use MatchF
  2689 	                        TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
  2698                             TBuf8<0x20> dosName8(DosNameFromStdFormat(aDosEntry.Name()));
  2690 	                        TBuf<0x20>  dosName;
  2699                             TBuf<0x20>  dosName;
  2691 	                        LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
  2700                             LocaleUtils::ConvertToUnicodeL(dosName, dosName8); //-- convert DOS name to unicode (implies locale settings)
  2692 	                        if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
  2701                             if (dosName.MatchF(trgtNameNoDot)!=KErrNotFound)
  2693 	                        	{
  2702                                 {
  2694 								found = ETrue;
  2703                                 found = ETrue;
  2695 	                            break;
  2704                                 break;
  2696 	                        	}
  2705                                 }
  2697 
  2706 
  2698 	                        }
  2707                             }
  2699 	                    } //if(findHelper.TrgtNameIsLegalDos())
  2708                         } //if(findHelper.TrgtNameIsLegalDos())
  2700 
  2709 
  2701 	                } //else if (aStartEntry.IsVFatEntry())
  2710                     } //else if (aStartEntry.IsVFatEntry())
  2702 
  2711 
  2703 	            } //if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(),anAtt))
  2712                 } //if (bFileNameEntry && MatchEntryAtt(aDosEntry.Attributes(),anAtt))
  2704 
  2713 
  2705 
  2714 
  2706 	        // record previous cluster number
  2715             // record previous cluster number
  2707 	        clustNum = aDosEntryPos.iCluster;
  2716             clustNum = aDosEntryPos.iCluster;
  2708 
  2717 
  2709 	        // this is the 2nd scanning and we have just passed the pos we started.
  2718             // this is the 2nd scanning and we have just passed the pos we started.
  2710 	        if (scanAhead && scanCnt == 2)
  2719             if (scanAhead && scanCnt == 2)
  2711 	        	{
  2720                 {
  2712 	        	if (aDosEntryPos.Cluster() == aLeafDirData.iMRUPos.Cluster()
  2721                 if (aDosEntryPos.Cluster() == aLeafDirData.iMRUPos.Cluster()
  2713 	        			&& aDosEntryPos.Pos() >= aLeafDirData.iMRUPos.Pos())
  2722                         && aDosEntryPos.Pos() >= aLeafDirData.iMRUPos.Pos())
  2714 	        		{
  2723                     {
  2715 	        		User::Leave(anError);
  2724                     User::Leave(anError);
  2716 	        		}
  2725                     }
  2717 	        	}
  2726                 }
  2718 
  2727 
  2719 
  2728 
  2720 	        MoveToNextEntryL(aDosEntryPos); //-- goto the next entry in the directory
  2729             MoveToNextEntryL(aDosEntryPos); //-- goto the next entry in the directory
  2721 
  2730 
  2722 	        if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2731             if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2723 	            {
  2732                 {
  2724 	            User::Leave(anError);//Allows maximum number of entries in root directory
  2733                 User::Leave(anError);//Allows maximum number of entries in root directory
  2725 	            }
  2734                 }
  2726 
  2735 
  2727 
  2736 
  2728 	        if (!scanAhead || scanCnt == 2)
  2737             if (!scanAhead || scanCnt == 2)
  2729 	        	{
  2738                 {
  2730 		        if (aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
  2739                 if (aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
  2731 		            DoCheckFatForLoopsL(aDosEntryPos.iCluster,previousCluster,changePreviousCluster,count);
  2740                     DoCheckFatForLoopsL(aDosEntryPos.iCluster,previousCluster,changePreviousCluster,count);
  2732 
  2741 
  2733 		        previousPosition=aDosEntryPos.iPos;
  2742                 previousPosition=aDosEntryPos.iPos;
  2734 	        	}
  2743                 }
  2735 	    	}	// FOREVER -- the actual scanning is done inside this loop
  2744             }   // FOREVER -- the actual scanning is done inside this loop
  2736 
  2745 
  2737 
  2746 
  2738         if (found)
  2747         if (found)
  2739         	{
  2748             {
  2740         	break;
  2749             break;
  2741         	}
  2750             }
  2742 
  2751 
  2743         // if not found:
  2752         // if not found:
  2744     	// if we have not found in the first scanning and we are doing scanning ahead,
  2753         // if we have not found in the first scanning and we are doing scanning ahead,
  2745         //  we need to go back to the starting pos of this dir and scan from start until
  2754         //  we need to go back to the starting pos of this dir and scan from start until
  2746         //  we reach lastscannedPos
  2755         //  we reach lastscannedPos
  2747         if (scanAhead && scanCnt == 1)
  2756         if (scanAhead && scanCnt == 1)
  2748         	{
  2757             {
  2749         	aDosEntryPos = TEntryPos(aLeafDirData.iClusterNum, 0);
  2758             aDosEntryPos = TEntryPos(aLeafDirData.iClusterNum, 0);
  2750         	continue;
  2759             continue;
  2751         	}
  2760             }
  2752         else
  2761         else
  2753         	{
  2762             {
  2754         	// there are only two exits: either found or reached end of dir in the 1st scanning
  2763             // there are only two exits: either found or reached end of dir in the 1st scanning
  2755         	ASSERT(0);
  2764             ASSERT(0);
  2756         	break;
  2765             break;
  2757         	}
  2766             }
  2758     	} // for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
  2767         } // for (TInt scanCnt = 1; scanCnt <= 2; ++scanCnt)
  2759 
  2768 
  2760     //---------------------------------------------------
  2769     //---------------------------------------------------
  2761     if (iRawDisk->DirCacheInterface() && aDosEntryPos.Cluster())
  2770     if (iRawDisk->DirCacheInterface() && aDosEntryPos.Cluster())
  2762     	{
  2771         {
  2763     	TInt64 mruPos = MakeLinAddrL(aDosEntryPos);
  2772         TInt64 mruPos = MakeLinAddrL(aDosEntryPos);
  2764         iRawDisk->DirCacheInterface()->MakePageMRU(mruPos);
  2773         iRawDisk->DirCacheInterface()->MakePageMRU(mruPos);
  2765 
  2774 
  2766     	// only update the leaf dir cache when the original cache index is provided
  2775         // only update the leaf dir cache when the original cache index is provided
  2767     	if (aLeafDirData.iClusterNum)
  2776         if (aLeafDirData.iClusterNum)
  2768     		{
  2777             {
  2769             iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDirData.iClusterNum, aDosEntryPos));
  2778             iLeafDirCache->UpdateMRUPos(TLeafDirData(aLeafDirData.iClusterNum, aDosEntryPos));
  2770             }
  2779             }
  2771     	}
  2780         }
  2772 
  2781 
  2773     return (aStartEntry.IsVFatEntry());
  2782     return (aStartEntry.IsVFatEntry());
  2774     }
  2783     }
  2775 
  2784 
  2776 //-----------------------------------------------------------------------------------------
  2785 //-----------------------------------------------------------------------------------------
  2830 
  2839 
  2831     __PRINT(_L("CFatMountCB::FindDosNameL()"));
  2840     __PRINT(_L("CFatMountCB::FindDosNameL()"));
  2832     TEntryPos startPos;
  2841     TEntryPos startPos;
  2833     TFatDirEntry startEntry;
  2842     TFatDirEntry startEntry;
  2834 
  2843 
  2835     TLeafDirData leafDir;			// leaf dir data is zero initialized, no scannig ahead
  2844     TLeafDirData leafDir;           // leaf dir data is zero initialized, no scannig ahead
  2836     DoFindL(aName,anAtt,startPos,startEntry,aDosEntryPos,aDosEntry,aFileName,anError,NULL,leafDir);
  2845     DoFindL(aName,anAtt,startPos,startEntry,aDosEntryPos,aDosEntry,aFileName,anError,NULL,leafDir);
  2837     }
  2846     }
  2838 //-----------------------------------------------------------------------------------------
  2847 //-----------------------------------------------------------------------------------------
  2839 
  2848 
  2840 void CFatMountCB::AddDirEntryL(TEntryPos& aPos,TInt aNumOfEntries)
  2849 void CFatMountCB::AddDirEntryL(TEntryPos& aPos,TInt aNumOfEntries)
  3189     dosEntryPos.iCluster=FindLeafDirL(RemoveTrailingDots(aName).Left(namePos), leafDir);
  3198     dosEntryPos.iCluster=FindLeafDirL(RemoveTrailingDots(aName).Left(namePos), leafDir);
  3190     dosEntryPos.iPos=0;
  3199     dosEntryPos.iPos=0;
  3191     TEntryPos startPos;
  3200     TEntryPos startPos;
  3192     TFatDirEntry startEntry;
  3201     TFatDirEntry startEntry;
  3193     DoFindL(RemoveTrailingDots(aName).Mid(namePos),KEntryAttMaskSupported,
  3202     DoFindL(RemoveTrailingDots(aName).Mid(namePos),KEntryAttMaskSupported,
  3194     		startPos,startEntry,dosEntryPos,dosEntry,
  3203             startPos,startEntry,dosEntryPos,dosEntry,
  3195     		fileName,KErrNotFound,
  3204             fileName,KErrNotFound,
  3196     		NULL,
  3205             NULL,
  3197     		leafDir);
  3206             leafDir);
  3198 
  3207 
  3199 //  Check that reading from aPos for aLength lies within the file
  3208 //  Check that reading from aPos for aLength lies within the file
  3200 //  if aPos is within the file, and aLength is too long, read up to EOF
  3209 //  if aPos is within the file, and aLength is too long, read up to EOF
  3201 //  If aPos is beyond the end of the file, return a zero length descriptor
  3210 //  If aPos is beyond the end of the file, return a zero length descriptor
  3202 
  3211 
  3203 	TUint32 fileSize = dosEntry.Size();
  3212     TUint32 fileSize = dosEntry.Size();
  3204 	if ((TUint)aPos>=fileSize)
  3213     if ((TUint)aPos>=fileSize)
  3205         User::Leave(KErrEof);
  3214         User::Leave(KErrEof);
  3206 
  3215 
  3207     if ((TUint)(aPos+aLength)>fileSize)
  3216     if ((TUint)(aPos+aLength)>fileSize)
  3208         aLength=fileSize-aPos;
  3217         aLength=fileSize-aPos;
  3209 
  3218 
  3210     TInt cluster=StartCluster(dosEntry);
  3219     TInt cluster=StartCluster(dosEntry);
  3211 	TInt pos = aPos;
  3220     TInt pos = aPos;
  3212 
  3221 
  3213     TInt endCluster;
  3222     TInt endCluster;
  3214     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3223     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3215 	TInt readTotal = 0;
  3224     TInt readTotal = 0;
  3216 
  3225 
  3217 	// Total number of clusters in file
  3226     // Total number of clusters in file
  3218     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3227     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3219 
  3228 
  3220 	// Read data
  3229     // Read data
  3221     FOREVER
  3230     FOREVER
  3222         {
  3231         {
  3223 		//  Get the maximum number of clusters that can be read contiguously
  3232         //  Get the maximum number of clusters that can be read contiguously
  3224         TInt clusterListLen=FAT().CountContiguousClustersL(cluster,endCluster,maxClusters);
  3233         TInt clusterListLen=FAT().CountContiguousClustersL(cluster,endCluster,maxClusters);
  3225         __ASSERT_DEBUG(clusterListLen>0,Fault(EReadFileSectionFailed));
  3234         __ASSERT_DEBUG(clusterListLen>0,Fault(EReadFileSectionFailed));
  3226 
  3235 
  3227 		//  If start position within this block, then read some data
  3236         //  If start position within this block, then read some data
  3228         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3237         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3229             {
  3238             {
  3230 			//  Read the remaining length or the entire cluster block whichever is smaller
  3239             //  Read the remaining length or the entire cluster block whichever is smaller
  3231 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3240             TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3232 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3241             __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3233 			TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
  3242             TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
  3234 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal);
  3243             iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal);
  3235 			readTotal += readLength;
  3244             readTotal += readLength;
  3236 
  3245 
  3237 			if (readTotal == aLength)
  3246             if (readTotal == aLength)
  3238 				return;
  3247                 return;
  3239 
  3248 
  3240 			pos += readLength;
  3249             pos += readLength;
  3241 			}
  3250             }
  3242 
  3251 
  3243 		// Get the next cluster in file
  3252         // Get the next cluster in file
  3244 		pos-=(clusterListLen<<ClusterSizeLog2());
  3253         pos-=(clusterListLen<<ClusterSizeLog2());
  3245 #if defined(_DEBUG)
  3254 #if defined(_DEBUG)
  3246 		TBool remainingClusters=
  3255         TBool remainingClusters=
  3247 #endif
  3256 #endif
  3248 			((CFatMountCB*)this)->FAT().GetNextClusterL(endCluster);
  3257             ((CFatMountCB*)this)->FAT().GetNextClusterL(endCluster);
  3249 		__ASSERT_DEBUG(remainingClusters,Fault(EReadFileSectionFailed));
  3258         __ASSERT_DEBUG(remainingClusters,Fault(EReadFileSectionFailed));
  3250 		cluster=endCluster;
  3259         cluster=endCluster;
  3251 		}
  3260         }
  3252     }
  3261     }
  3253 
  3262 
  3254 
  3263 
  3255 //-----------------------------------------------------------------------------------------
  3264 //-----------------------------------------------------------------------------------------
  3256 
  3265 
  3269 // Write aLength of data from thread relative descriptor to disk
  3278 // Write aLength of data from thread relative descriptor to disk
  3270 //
  3279 //
  3271     {
  3280     {
  3272     CheckWritableL();
  3281     CheckWritableL();
  3273 
  3282 
  3274 	//-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
  3283     //-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case.
  3275     FAT().RequestRawWriteAccess(aPos, aLength);
  3284     FAT().RequestRawWriteAccess(aPos, aLength);
  3276 
  3285 
  3277     iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset);
  3286     iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset);
  3278     //-- Note: FAT directory cache will be invalidated in MountL()
  3287     //-- Note: FAT directory cache will be invalidated in MountL()
  3279     }
  3288     }
  3571             TRAP(r,aMessage.WriteL(2,pVal,0));
  3580             TRAP(r,aMessage.WriteL(2,pVal,0));
  3572             if(r!=KErrNone)
  3581             if(r!=KErrNone)
  3573                 return(r);
  3582                 return(r);
  3574             break;
  3583             break;
  3575             }
  3584             }
  3576 		case ELocalTimeForRemovableMediaOn:
  3585         case ELocalTimeForRemovableMediaOn:
  3577 			{
  3586             {
  3578 			FatFileSystem().SetUseLocalTime(ETrue);
  3587             FatFileSystem().SetUseLocalTime(ETrue);
  3579 			break;
  3588             break;
  3580 			}
  3589             }
  3581 		case ELocalTimeForRemovableMediaOff:
  3590         case ELocalTimeForRemovableMediaOff:
  3582 			{
  3591             {
  3583 			FatFileSystem().SetUseLocalTime(EFalse);
  3592             FatFileSystem().SetUseLocalTime(EFalse);
  3584 			break;
  3593             break;
  3585 			}
  3594             }
  3586 		case ELocalTimeUsedOnRemovableMedia:
  3595         case ELocalTimeUsedOnRemovableMedia:
  3587 			{
  3596             {
  3588 			TBool flag = FatFileSystem().GetUseLocalTime();
  3597             TBool flag = FatFileSystem().GetUseLocalTime();
  3589 			TPckgC<TBool> flagPckg(flag);
  3598             TPckgC<TBool> flagPckg(flag);
  3590 			TInt r = aMessage.Write(2, flagPckg);
  3599             TInt r = aMessage.Write(2, flagPckg);
  3591 			if(r!=KErrNone)
  3600             if(r!=KErrNone)
  3592 				return r;
  3601                 return r;
  3593 			break;
  3602             break;
  3594 			}
  3603             }
  3595 		case ECreationTime:
  3604         case ECreationTime:
  3596 			{
  3605             {
  3597 			CheckStateConsistentL();
  3606             CheckStateConsistentL();
  3598 
  3607 
  3599 			TEntryPos firstEntryPos(RootIndicator(),0);
  3608             TEntryPos firstEntryPos(RootIndicator(),0);
  3600 			TFatDirEntry firstEntry;
  3609             TFatDirEntry firstEntry;
  3601 			//RFs::ControlIO restricts you to use narrow descriptors
  3610             //RFs::ControlIO restricts you to use narrow descriptors
  3602 			//so convert narrow back to wide.
  3611             //so convert narrow back to wide.
  3603 			TBuf8<KMaxPath> fileNameNarrow;
  3612             TBuf8<KMaxPath> fileNameNarrow;
  3604 			aMessage.Read(2, fileNameNarrow);
  3613             aMessage.Read(2, fileNameNarrow);
  3605 
  3614 
  3606 			TFileName fileNameWide;
  3615             TFileName fileNameWide;
  3607 			fileNameWide.Copy(fileNameNarrow);
  3616             fileNameWide.Copy(fileNameNarrow);
  3608 
  3617 
  3609 			//find the long file name entry
  3618             //find the long file name entry
  3610 			TRAPD(r, FindEntryStartL(fileNameWide,KEntryAttMaskSupported,firstEntry,firstEntryPos) );
  3619             TRAPD(r, FindEntryStartL(fileNameWide,KEntryAttMaskSupported,firstEntry,firstEntryPos) );
  3611 			if(r!=KErrNone)
  3620             if(r!=KErrNone)
  3612               return(r);
  3621               return(r);
  3613 			//Find the corresponding 8.3 short name entry, for metadata
  3622             //Find the corresponding 8.3 short name entry, for metadata
  3614 			MoveToDosEntryL(firstEntryPos,firstEntry);
  3623             MoveToDosEntryL(firstEntryPos,firstEntry);
  3615 			TTime creationTime=0;
  3624             TTime creationTime=0;
  3616 			TPckg<TTime> timePckg(creationTime);
  3625             TPckg<TTime> timePckg(creationTime);
  3617 			SFatDirEntry* sEntry = reinterpret_cast<SFatDirEntry*>(firstEntry.iData);
  3626             SFatDirEntry* sEntry = reinterpret_cast<SFatDirEntry*>(firstEntry.iData);
  3618 			creationTime = DosTimeToTTime(sEntry->iTimeC, sEntry->iDateC);
  3627             creationTime = DosTimeToTTime(sEntry->iTimeC, sEntry->iDateC);
  3619 			r = aMessage.Write(3, timePckg);
  3628             r = aMessage.Write(3, timePckg);
  3620 			if(r!=KErrNone)
  3629             if(r!=KErrNone)
  3621 				return r;
  3630                 return r;
  3622 			break;
  3631             break;
  3623 			}
  3632             }
  3624 		case EDisableFATDirCache:
  3633         case EDisableFATDirCache:
  3625 			{
  3634             {
  3626 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3635             MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3627 		    TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
  3636             TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
  3628 		    pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
  3637             pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
  3629 			break;
  3638             break;
  3630 			}
  3639             }
  3631 		case EDumpFATDirCache:
  3640         case EDumpFATDirCache:
  3632 			{
  3641             {
  3633 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3642             MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3634 		    TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
  3643             TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
  3635 		    pDirCache->Control(KEDumpFATDirCache, 0, NULL);
  3644             pDirCache->Control(KEDumpFATDirCache, 0, NULL);
  3636 			break;
  3645             break;
  3637 			}
  3646             }
  3638 		case EFATDirCacheInfo:
  3647         case EFATDirCacheInfo:
  3639 			{
  3648             {
  3640 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3649             MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3641 		    TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
  3650             TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
  3642 		    pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
  3651             pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
  3643 			break;
  3652             break;
  3644 			}
  3653             }
  3645 
  3654 
  3646 
  3655 
  3647         default: return(KErrNotSupported);
  3656         default: return(KErrNotSupported);
  3648         }
  3657         }
  3649     return(KErrNone);
  3658     return(KErrNone);
  3660 //
  3669 //
  3661 // lock media device
  3670 // lock media device
  3662 //
  3671 //
  3663     {
  3672     {
  3664     __PRINT(_L("CFatMountCB::Lock"));
  3673     __PRINT(_L("CFatMountCB::Lock"));
  3665 	TInt r=CreateDrive(Drive().DriveNumber());
  3674     TInt r=CreateDrive(Drive().DriveNumber());
  3666     if (r!=KErrNone)
  3675     if (r!=KErrNone)
  3667         return r;
  3676         return r;
  3668 
  3677 
  3669     TBusLocalDrive* local;
  3678     TBusLocalDrive* local;
  3670     r=LocalDrive()->GetLocalDrive(local);
  3679     r=LocalDrive()->GetLocalDrive(local);
  3687 //
  3696 //
  3688 // Unlock media device
  3697 // Unlock media device
  3689 //
  3698 //
  3690     {
  3699     {
  3691     __PRINT(_L("CFatMountCB::Unlock"));
  3700     __PRINT(_L("CFatMountCB::Unlock"));
  3692 	TInt r=CreateDrive(Drive().DriveNumber());
  3701     TInt r=CreateDrive(Drive().DriveNumber());
  3693     if (r!=KErrNone)
  3702     if (r!=KErrNone)
  3694         return r;
  3703         return r;
  3695 
  3704 
  3696     TBusLocalDrive* local;
  3705     TBusLocalDrive* local;
  3697     r=LocalDrive()->GetLocalDrive(local);
  3706     r=LocalDrive()->GetLocalDrive(local);
  3714 //
  3723 //
  3715 // Clear password from media device
  3724 // Clear password from media device
  3716 //
  3725 //
  3717     {
  3726     {
  3718     __PRINT(_L("CFatMountCB::ClearPassword"));
  3727     __PRINT(_L("CFatMountCB::ClearPassword"));
  3719 	TInt r=CreateDrive(Drive().DriveNumber());
  3728     TInt r=CreateDrive(Drive().DriveNumber());
  3720     if (r!=KErrNone)
  3729     if (r!=KErrNone)
  3721         return r;
  3730         return r;
  3722 
  3731 
  3723     TBusLocalDrive* local;
  3732     TBusLocalDrive* local;
  3724     r=LocalDrive()->GetLocalDrive(local);
  3733     r=LocalDrive()->GetLocalDrive(local);
  3742 // Forcibly erase the password from a media device
  3751 // Forcibly erase the password from a media device
  3743 //
  3752 //
  3744     {
  3753     {
  3745     __PRINT(_L("CFatMountCB::ErasePassword"));
  3754     __PRINT(_L("CFatMountCB::ErasePassword"));
  3746 
  3755 
  3747 	TInt r=CreateDrive(Drive().DriveNumber());
  3756     TInt r=CreateDrive(Drive().DriveNumber());
  3748     if (r!=KErrNone)
  3757     if (r!=KErrNone)
  3749         return r;
  3758         return r;
  3750 
  3759 
  3751     TBusLocalDrive* local;
  3760     TBusLocalDrive* local;
  3752     r=LocalDrive()->GetLocalDrive(local);
  3761     r=LocalDrive()->GetLocalDrive(local);
  3774 //
  3783 //
  3775 // Force a remount of the drive
  3784 // Force a remount of the drive
  3776 //
  3785 //
  3777     {
  3786     {
  3778     __PRINT(_L("CFatMountCB::ForceRemountDrive"));
  3787     __PRINT(_L("CFatMountCB::ForceRemountDrive"));
  3779 	TInt r=CreateDrive(Drive().DriveNumber());
  3788     TInt r=CreateDrive(Drive().DriveNumber());
  3780     if (r==KErrNone)
  3789     if (r==KErrNone)
  3781 		r=LocalDrive()->SetMountInfo(aMountInfo,aMountInfoMessageHandle);
  3790         r=LocalDrive()->SetMountInfo(aMountInfo,aMountInfoMessageHandle);
  3782     if (r==KErrNone)
  3791     if (r==KErrNone)
  3783         r=LocalDrive()->ForceRemount(aFlags);
  3792         r=LocalDrive()->ForceRemount(aFlags);
  3784     return(r);
  3793     return(r);
  3785     }
  3794     }
  3786 
  3795 
  3904             TFatDirEntry fatDirEntry;
  3913             TFatDirEntry fatDirEntry;
  3905             fatDirEntry.SetName(aNewName);
  3914             fatDirEntry.SetName(aNewName);
  3906             fatDirEntry.SetAttributes(KEntryAttVolume);
  3915             fatDirEntry.SetAttributes(KEntryAttVolume);
  3907 
  3916 
  3908             TTime now;
  3917             TTime now;
  3909 			now.UniversalTime();
  3918             now.UniversalTime();
  3910 			fatDirEntry.SetTime(now, TimeOffset() );
  3919             fatDirEntry.SetTime(now, TimeOffset() );
  3911             fatDirEntry.SetStartCluster(0);
  3920             fatDirEntry.SetStartCluster(0);
  3912             fatDirEntry.SetSize(0);
  3921             fatDirEntry.SetSize(0);
  3913             WriteDirEntryL(dirPos, fatDirEntry);
  3922             WriteDirEntryL(dirPos, fatDirEntry);
  3914             FAT().FlushL();
  3923             FAT().FlushL();
  3915             }
  3924             }
  4050         temp = currentPos>>ClusterSizeLog2();
  4059         temp = currentPos>>ClusterSizeLog2();
  4051         if ( (currentPos) && ( (currentPos) == (temp<<ClusterSizeLog2()) ) )
  4060         if ( (currentPos) && ( (currentPos) == (temp<<ClusterSizeLog2()) ) )
  4052             {
  4061             {
  4053             if (!FAT().GetNextClusterL(aPos.iCluster))
  4062             if (!FAT().GetNextClusterL(aPos.iCluster))
  4054                 {
  4063                 {
  4055 				__PRINT(_L("CFatMountCB::BlockMapReadFromClusterListL corrupt#1"))
  4064                 __PRINT(_L("CFatMountCB::BlockMapReadFromClusterListL corrupt#1"))
  4056                 User::Leave(KErrCorrupt);
  4065                 User::Leave(KErrCorrupt);
  4057                 }
  4066                 }
  4058             }
  4067             }
  4059         clusterRelativePos = ClusterRelativePos( aPos.iPos );
  4068         clusterRelativePos = ClusterRelativePos( aPos.iPos );
  4060         maxClusters = ((aLength + clusterRelativePos - 1)>>ClusterSizeLog2())+1;
  4069         maxClusters = ((aLength + clusterRelativePos - 1)>>ClusterSizeLog2())+1;
  4284 //
  4293 //
  4285 // Walk the FAT, returns error if find an unterminated list or
  4294 // Walk the FAT, returns error if find an unterminated list or
  4286 // lists that merge.
  4295 // lists that merge.
  4287 //
  4296 //
  4288 TInt CFatMountCB::CheckDisk()
  4297 TInt CFatMountCB::CheckDisk()
  4289 	{
  4298     {
  4290 
  4299 
  4291     __PRINT1(_L("CFatMountCB::CheckDisk() drv:%d"), DriveNumber());
  4300     __PRINT1(_L("CFatMountCB::CheckDisk() drv:%d"), DriveNumber());
  4292 
  4301 
  4293     if(!ConsistentState())
  4302     if(!ConsistentState())
  4294         return KErrCorrupt;
  4303         return KErrCorrupt;
  4466 
  4475 
  4467     TInt nRes;
  4476     TInt nRes;
  4468 
  4477 
  4469     if(LockStatus()!=0)
  4478     if(LockStatus()!=0)
  4470         {
  4479         {
  4471 		__PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
  4480         __PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
  4472         return KErrInUse;
  4481         return KErrInUse;
  4473         }
  4482         }
  4474 
  4483 
  4475     if(iRamDrive)
  4484     if(iRamDrive)
  4476         {//-- Do not check internal RAM drive
  4485         {//-- Do not check internal RAM drive
  4513 a null offset is returned.
  4522 a null offset is returned.
  4514 
  4523 
  4515 @return The offset in seconds that timestamps on the filesystem have, relative to UTC.
  4524 @return The offset in seconds that timestamps on the filesystem have, relative to UTC.
  4516 */
  4525 */
  4517 TTimeIntervalSeconds CFatMountCB::TimeOffset() const
  4526 TTimeIntervalSeconds CFatMountCB::TimeOffset() const
  4518 	{
  4527     {
  4519     if((Drive().Att() & KDriveAttRemovable) && FatFileSystem().GetUseLocalTime() )
  4528     if((Drive().Att() & KDriveAttRemovable) && FatFileSystem().GetUseLocalTime() )
  4520 	    {
  4529         {
  4521         return User::UTCOffset();
  4530         return User::UTCOffset();
  4522         }
  4531         }
  4523 	else
  4532     else
  4524         {
  4533         {
  4525         return TTimeIntervalSeconds(0);
  4534         return TTimeIntervalSeconds(0);
  4526         }
  4535         }
  4527 	}
  4536     }
  4528 
  4537 
  4529 
  4538 
  4530 
  4539 
  4531 
  4540 
  4532 //-----------------------------------------------------------------------------------------
  4541 //-----------------------------------------------------------------------------------------