userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
changeset 90 947f0dc9f7a8
parent 36 538db54a451d
child 140 2ac1c5c27758
equal deleted inserted replaced
52:2d65c2f76d7b 90:947f0dc9f7a8
   301 void CFatMountCB::InvalidateLeafDirCache()
   301 void CFatMountCB::InvalidateLeafDirCache()
   302 	{
   302 	{
   303     if (iLeafDirCache)
   303     if (iLeafDirCache)
   304     	{
   304     	{
   305         iLeafDirCache->Reset();
   305         iLeafDirCache->Reset();
   306     	}
       
   307     else
       
   308     	{
       
   309         User::Free(iLastLeafDir);
       
   310         iLastLeafDir=NULL;
       
   311     	}
   306     	}
   312 	}
   307 	}
   313 
   308 
   314 //-------------------------------------------------------------------------------------------------------------------
   309 //-------------------------------------------------------------------------------------------------------------------
   315 
   310 
   841     Setup 1st cluster of the new directory
   836     Setup 1st cluster of the new directory
   842 
   837 
   843     @param  aStartCluster   this entry start cluster number
   838     @param  aStartCluster   this entry start cluster number
   844     @param  aParentCluster  parent entry start cluster number
   839     @param  aParentCluster  parent entry start cluster number
   845 */
   840 */
   846 void CFatMountCB::InitializeFirstDirClusterL(TInt aStartCluster,TInt aParentCluster)
   841 void CFatMountCB::InitializeFirstDirClusterL(TUint32 aStartCluster, TUint32 aParentCluster)
   847     {
   842     {
   848     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
   843     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
   849     const TUint32 KMaxBufSz = KClusterSz;           //-- max. nuffer size is a cluster
   844     const TUint32 KMaxBufSz = KClusterSz;           //-- max. nuffer size is a cluster
   850     const TUint32 KMinBufSz = 1<<SectorSizeLog2();  //-- min. buffer size is 1 sector (for OOM case)
   845     const TUint32 KMinBufSz = 1<<SectorSizeLog2();  //-- min. buffer size is 1 sector (for OOM case)
   851 
   846 
  1062         User::Leave(nRes);
  1057         User::Leave(nRes);
  1063 
  1058 
  1064     const TBool newFileExists = (nRes == KErrNone); //-- ETrue if 'aNewName' file exists.
  1059     const TBool newFileExists = (nRes == KErrNone); //-- ETrue if 'aNewName' file exists.
  1065     const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
  1060     const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
  1066 
  1061 
       
  1062     if(!newFileExists)
       
  1063     {//-- invalidate directory iterators if aNewName doesn't exist
       
  1064         newName_VFatEntryPos.SetEndOfDir();
       
  1065         aNewName_DosEntryPos.SetEndOfDir();
       
  1066     }
       
  1067 
       
  1068 
  1067     if(renameMode && newFileExists)
  1069     if(renameMode && newFileExists)
  1068     	{
  1070     	{
  1069         if(!namesAreIdentical)
  1071         if(!namesAreIdentical)
  1070         {
  1072         {
  1071         if ((newName_DosEntry.Attributes()&KEntryAttDir) != (oldName_DosEntry.Attributes()&KEntryAttDir))
  1073         if ((newName_DosEntry.Attributes()&KEntryAttDir) != (oldName_DosEntry.Attributes()&KEntryAttDir))
  1141         	{//-- need to generate a short name for VFAT entryset DOS entry
  1143         	{//-- need to generate a short name for VFAT entryset DOS entry
  1142             TShortName shortName;
  1144             TShortName shortName;
  1143 
  1145 
  1144 		    if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1146 		    if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
  1145 		    	{
  1147 		    	{
  1146 		        GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
  1148 		        GenerateShortNameL(aNewName_ParentDirPos.Cluster(), ptrNewName, shortName); 
  1147 		    	}
  1149 		    	}
  1148 
  1150 
  1149             newDosEntry.SetName(shortName);
  1151             newDosEntry.SetName(shortName);
  1150         	}
  1152         	}
  1151         else
  1153         else
  1353     WriteDirEntryL(firstEntryPos,firstEntry);
  1355     WriteDirEntryL(firstEntryPos,firstEntry);
  1354     }
  1356     }
  1355 
  1357 
  1356 //-----------------------------------------------------------------------------------------
  1358 //-----------------------------------------------------------------------------------------
  1357 
  1359 
  1358 void CFatMountCB::DoCheckFatForLoopsL(TInt aCluster, TInt& aPreviousCluster, TInt& aChangePreviousCluster, TInt& aCount) const
  1360 void CFatMountCB::DoCheckFatForLoopsL(TUint32 aCluster, TUint32& aPreviousCluster, TUint32& aChangePreviousCluster, TUint32& aCount) const
  1359 //
  1361 //
  1360 // Check one fat cluster for loops.
  1362 // Check one fat cluster for loops.
  1361 //
  1363 //
  1362     {
  1364     {
  1363 
  1365 
  1379 //
  1381 //
  1380 // Check for loops
  1382 // Check for loops
  1381 //
  1383 //
  1382     {
  1384     {
  1383 
  1385 
  1384     TInt cluster=StartCluster(anEntry);
  1386     TUint32 cluster = StartCluster(anEntry);
  1385     if (cluster==0 && anEntry.Size()==0)
  1387     if (cluster==0 && anEntry.Size()==0)
  1386         return;
  1388         return;
  1387 
  1389 
  1388     TInt previousCluster=cluster;
  1390     TUint32 previousCluster=cluster;
  1389     TInt changePreviousCluster=1;
  1391     TUint32 changePreviousCluster=1;
  1390     TInt count=0;
  1392     TUint32 count=0;
  1391 
  1393 
  1392 
  1394 
  1393     for(;;)
  1395     for(;;)
  1394         {
  1396         {
  1395         if ((TUint)cluster < KFatFirstSearchCluster || (!IsEndOfClusterCh(cluster) && (TUint)cluster>MaxClusterNumber()))
  1397         if ((TUint)cluster < KFatFirstSearchCluster || (!IsEndOfClusterCh(cluster) && (TUint)cluster>MaxClusterNumber()))
  1497         else
  1499         else
  1498             WriteDirEntryL(firstEntryPos,firstEntry,name);
  1500             WriteDirEntryL(firstEntryPos,firstEntry,name);
  1499         }
  1501         }
  1500 
  1502 
  1501     CFatFileCB& file=(*((CFatFileCB*)aFile));
  1503     CFatFileCB& file=(*((CFatFileCB*)aFile));
  1502     file.SetL(firstEntry,(TShare)(aMode&KFileShareMask),firstEntryPos);
  1504     file.SetupL(firstEntry, firstEntryPos);
       
  1505 
  1503     if (anOpen==EFileReplace && file.Size())
  1506     if (anOpen==EFileReplace && file.Size())
  1504         {
  1507         {
  1505         file.SetSizeL(0);
  1508         file.SetSizeL(0);
  1506         file.SetSize(0);
  1509         }
  1507         }
  1510 
  1508     if (file.IsSeekIndex()==EFalse)
       
  1509         file.CreateSeekIndex();
       
  1510     if (anOpen==EFileReplace || anOpen==EFileCreate)
  1511     if (anOpen==EFileReplace || anOpen==EFileCreate)
  1511         file.SetArchiveAttribute();
  1512         file.SetArchiveAttribute();
  1512 
  1513 
  1513     if(!IsRuggedFSys())
  1514     if(!IsRuggedFSys())
  1514         FAT().FlushL();
  1515         FAT().FlushL();
  1573 
  1574 
  1574     }
  1575     }
  1575 
  1576 
  1576 //-----------------------------------------------------------------------------------------
  1577 //-----------------------------------------------------------------------------------------
  1577 
  1578 
  1578 TBool CFatMountCB::IsDirectoryEmptyL(TInt aCluster)
       
  1579 //
  1579 //
  1580 // Check aCluster contains no directory entries other than . and ..
  1580 // Check aCluster contains no directory entries other than . and ..
  1581 //
  1581 //
       
  1582 TBool CFatMountCB::IsDirectoryEmptyL(TUint32 aCluster)
  1582     {
  1583     {
  1583 
  1584 
  1584     __PRINT(_L("CFatMountCB::IsDirectoryEmptyL"));
  1585     __PRINT(_L("CFatMountCB::IsDirectoryEmptyL"));
  1585     TEntryPos dirEntryPos(aCluster,0);
  1586     TEntryPos dirEntryPos(aCluster,0);
  1586     TFatDirEntry dirEntry;
  1587     TFatDirEntry dirEntry;
  1604 //-----------------------------------------------------------------------------------------
  1605 //-----------------------------------------------------------------------------------------
  1605 
  1606 
  1606 /**
  1607 /**
  1607     Overwrite as many contiguous file clusters as possible.
  1608     Overwrite as many contiguous file clusters as possible.
  1608 */
  1609 */
  1609 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt aLastcluster, TInt &aBadcluster, TInt &aGoodcluster)
  1610 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster)
  1610     {
  1611     {
  1611 
  1612 
  1612     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1613     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1613     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1614     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1614 
  1615 
  1615     TInt endCluster=0;
  1616     TUint32 endCluster=0;
  1616 
  1617 
  1617     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1618     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1618     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1619     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1619     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1620     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1620     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1621     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1636     r = iRawDisk->GetLastErrorInfo(errinf);
  1637     r = iRawDisk->GetLastErrorInfo(errinf);
  1637 
  1638 
  1638     if(r == KErrNone && errinf().iReasonCode == TErrorInfo::EBadSector) // GetLastErrorInfo succeded and Last Error was caused by bad sector
  1639     if(r == KErrNone && errinf().iReasonCode == TErrorInfo::EBadSector) // GetLastErrorInfo succeded and Last Error was caused by bad sector
  1639         {
  1640         {
  1640 
  1641 
  1641         const TInt badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
  1642         const TUint32 badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
  1642               TInt goodcluster = FAT().AllocateSingleClusterL(badcluster);
  1643               TUint32 goodcluster = FAT().AllocateSingleClusterL(badcluster);
  1643 
  1644 
  1644         //Calculate cluster number to check whether this write started at the beginning of new cluster or middle of previous cluster.
  1645         //Calculate cluster number to check whether this write started at the beginning of new cluster or middle of previous cluster.
  1645         TInt cluster = aPos.iCluster;
  1646         TUint32 cluster = aPos.iCluster;
  1646         if ( (aPos.iPos) && ((aPos.iPos)==((aPos.iPos >> ClusterSizeLog2())<<ClusterSizeLog2())))
  1647         if ( (aPos.iPos) && ((aPos.iPos)==((aPos.iPos >> ClusterSizeLog2())<<ClusterSizeLog2())))
  1647             cluster--;
  1648             cluster--;
  1648 
  1649 
  1649         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1650         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1650             { //Copy the contents already present in this cluster to new cluster allocated.
  1651             { //Copy the contents already present in this cluster to new cluster allocated.
  1733     User::Leave(KErrCorrupt);
  1734     User::Leave(KErrCorrupt);
  1734     }
  1735     }
  1735 
  1736 
  1736 //-----------------------------------------------------------------------------------------
  1737 //-----------------------------------------------------------------------------------------
  1737 
  1738 
  1738 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt &aBadcluster, TInt& aGoodcluster)
  1739 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster)
  1739 //
  1740 //
  1740 // Overwrite cluster list.
  1741 // Overwrite cluster list.
  1741 //
  1742 //
  1742     {
  1743     {
  1743 
  1744 
  1778 //
  1779 //
  1779     {
  1780     {
  1780 
  1781 
  1781     __PRINT(_L("CFatMountCB::DoReadFromClusterListL"));
  1782     __PRINT(_L("CFatMountCB::DoReadFromClusterListL"));
  1782 
  1783 
  1783     TInt endCluster=0;
  1784     TUint32 endCluster=0;
  1784 
  1785 
  1785     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1786     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1786     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1787     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1787     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1788     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1788     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1789     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1851 // Navigate the path to find the leaf directory.
  1852 // Navigate the path to find the leaf directory.
  1852 // Returns the startcluster of data for the directory found.
  1853 // Returns the startcluster of data for the directory found.
  1853 //
  1854 //
  1854     {
  1855     {
  1855 
  1856 
  1856     __PRINT(_L("CFatMountCB::FindLeafDirL"));
  1857     __PRINT2(_L("CFatMountCB::FindLeafDirL drv:%d, dir:%S"),DriveNumber() ,&aLeafDir);
  1857 
  1858 
  1858     TLex lex(aName);
  1859     TLex lex(aName);
  1859     TInt r;
  1860     TInt r;
  1860     TEntryPos entryPos(RootIndicator(),0);
  1861     TEntryPos entryPos(RootIndicator(),0);
  1861 
  1862 
  1862     if (iLeafDirCache == NULL)
  1863     ASSERT(iLeafDirCache);
  1863     	{
  1864 
  1864         TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
       
  1865         TInt namelen=aName.Length();
       
  1866         if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
       
  1867             {
       
  1868             if (leaflen==namelen)
       
  1869                 return(iLastLeafDirCluster);
       
  1870             lex.Inc(leaflen-1);
       
  1871             entryPos.iCluster=iLastLeafDirCluster;
       
  1872             }
       
  1873     	}
       
  1874     else
       
  1875     	{
       
  1876         // Skip root directory
       
  1877         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1865         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1878         	{
  1866         	{
  1879         	TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1867         const TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1880         	if (err == KErrNone)
  1868         	if (err == KErrNone)
  1881         		{
  1869         		{
  1882         		ASSERT(aLeafDir.iClusterNum > 0);
  1870         	ASSERT(ClusterNumberValid(aLeafDir.iClusterNum)); 
  1883         		return aLeafDir.iClusterNum;
  1871         		return aLeafDir.iClusterNum;
  1884         		}
  1872         		}
  1885         	else if (err != KErrNotFound)
  1873         	else if (err != KErrNotFound)
  1886         		{
  1874         		{
  1887         		User::LeaveIfError(err);
  1875         		User::LeaveIfError(err);
  1888         		}
  1876         		}
  1889         	}
  1877         	}
  1890     	}
  1878 
  1891 
  1879     TFatDirEntry entry;
  1892     FOREVER
  1880     TFileName fileName;
       
  1881     TEntryPos startPos;
       
  1882     TFatDirEntry startEntry;
       
  1883 
       
  1884     for(;;)
  1893         {
  1885         {
  1894         lex.Inc(); // Skip path delimiter
  1886         lex.Inc(); // Skip path delimiter
  1895         lex.Mark();
  1887         lex.Mark();
  1896         r=lex.Remainder().Locate(KPathDelimiter);
  1888         r=lex.Remainder().Locate(KPathDelimiter);
       
  1889         
  1897         if (r==KErrNotFound)
  1890         if (r==KErrNotFound)
  1898             r=lex.Remainder().Length();
  1891             r=lex.Remainder().Length();
       
  1892         
  1899         if (r==0) // End of the path
  1893         if (r==0) // End of the path
  1900             break;
  1894             break;
       
  1895         
  1901         lex.Inc(r); // Set the token length
  1896         lex.Inc(r); // Set the token length
  1902         TFatDirEntry entry;
  1897         
  1903 
  1898         
  1904         TFileName fileName;
       
  1905         TEntryPos startPos;
       
  1906         TFatDirEntry startEntry;
       
  1907         DoFindL(lex.MarkedToken(),
  1899         DoFindL(lex.MarkedToken(),
  1908         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1900         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1909         		startPos, startEntry, entryPos, entry,
  1901         		startPos, startEntry, entryPos, entry,
  1910         		fileName, KErrPathNotFound,
  1902         		fileName, KErrPathNotFound,
  1911         		NULL,
  1903         		NULL,
  1912         		aLeafDir);
  1904         		aLeafDir);
  1913 
  1905 
  1914 
  1906 
  1915         entryPos.iCluster=StartCluster(entry);
  1907         entryPos.iCluster=StartCluster(entry);
  1916         entryPos.iPos=0;
  1908         entryPos.iPos=0;
  1917         }
  1909         }// for(;;)
  1918 
  1910 
  1919     if (iLeafDirCache == NULL)
       
  1920     	{
       
  1921         AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
       
  1922         ((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
       
  1923     	}
       
  1924     else
       
  1925     	{
       
  1926         if (aName.Length() > 1)
  1911         if (aName.Length() > 1)
  1927         	{
  1912         	{
  1928         	aLeafDir = TLeafDirData(entryPos.iCluster);
  1913         	aLeafDir = TLeafDirData(entryPos.iCluster);
  1929             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1914             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1930         	}
  1915         	}
  1931     	}
       
  1932 
  1916 
  1933     return entryPos.iCluster;
  1917     return entryPos.iCluster;
  1934     }
  1918     }
  1935 
  1919 
  1936 //-----------------------------------------------------------------------------------------
  1920 //-----------------------------------------------------------------------------------------
  1969     TEntryPos       StartEntryPos1(aStartEntryPos);
  1953     TEntryPos       StartEntryPos1(aStartEntryPos);
  1970     TEntryPos       DosEntryPos1(aDosEntryPos);
  1954     TEntryPos       DosEntryPos1(aDosEntryPos);
  1971     TFatDirEntry    StartEntry1(aStartEntry);
  1955     TFatDirEntry    StartEntry1(aStartEntry);
  1972     TFatDirEntry    DosEntry1(aDosEntry);
  1956     TFatDirEntry    DosEntry1(aDosEntry);
  1973 
  1957 
  1974     TInt64          nCachedLinPos;
       
  1975 
       
  1976     const TUint32 clSize = 1 << ClusterSizeLog2(); //-- media cluster size
  1958     const TUint32 clSize = 1 << ClusterSizeLog2(); //-- media cluster size
  1977     const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
  1959     const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
  1978     const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2;  //-- maximal number of dir entries that can be in the cache
  1960     const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2;  //-- maximal number of dir entries that can be in the cache
  1979 
  1961 
  1980     const TUint	  pageSzLog2 = pDirCache->PageSizeInBytesLog2();
  1962     const TUint	  pageSzLog2 = pDirCache->PageSizeInBytesLog2();
  1988     	DosEntryPos1 = aLeafDir.iMRUPos;
  1970     	DosEntryPos1 = aLeafDir.iMRUPos;
  1989     	}
  1971     	}
  1990 
  1972 
  1991 	TInt numFound = 0;
  1973 	TInt numFound = 0;
  1992 	TEntryPos startPos = DosEntryPos1;
  1974 	TEntryPos startPos = DosEntryPos1;
  1993 	TInt clusterNum = DosEntryPos1.iCluster;
  1975 	TUint32 clusterNum = DosEntryPos1.iCluster;
  1994 
  1976 
  1995     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  1977     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  1996         {//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
  1978         {//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
  1997          //-- that can be cached. Helps to avoid problems with infinite (looped) directories
  1979          //-- that can be cached. Helps to avoid problems with infinite (looped) directories
  1998 
  1980 
  2019         const TUint32 pageStartPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2001         const TUint32 pageStartPos = CalculatePageOffsetInCluster(DosEntryPos1.iPos, pageSzLog2);
  2020     	DosEntryPos1.iPos = pageStartPos;
  2002     	DosEntryPos1.iPos = pageStartPos;
  2021         TBool	PassedPageBoundary = EFalse;
  2003         TBool	PassedPageBoundary = EFalse;
  2022 
  2004 
  2023         const TInt64  entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
  2005         const TInt64  entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
  2024         const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos, nCachedLinPos); //-- indicates if entryLinPos is cached
  2006         const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos); //-- indicates if entryLinPos is cached
  2025         if(cachePageSz)
  2007         if(cachePageSz)
  2026             {//-- current page is in the directory cache
  2008             {//-- current page is in the directory cache
  2027              //__PRINT2(_L("#-!! CFatMountCB::DoRummageDirCacheL() Searching cl:%d, lin Pos:%X"),DosEntryPos1.iCluster,(TUint32)entryLinPos);
  2009              //__PRINT2(_L("#-!! CFatMountCB::DoRummageDirCacheL() Searching cl:%d, lin Pos:%X"),DosEntryPos1.iCluster,(TUint32)entryLinPos);
  2028 
  2010 
  2029             //-- search to the end of the cached page.
  2011             //-- search to the end of the cached page.
  2034             //-- extract dir entries from the cached page and see if they match given name (aName)
  2016             //-- extract dir entries from the cached page and see if they match given name (aName)
  2035             /// until it reaches the next page
  2017             /// until it reaches the next page
  2036             for(;;)
  2018             for(;;)
  2037                 {
  2019                 {
  2038                 StartEntryPos1 = DosEntryPos1;
  2020                 StartEntryPos1 = DosEntryPos1;
  2039                 TInt clSave = DosEntryPos1.iCluster; //-- need to save current cluster number because GetDirEntry() & MoveToNextEntryL() can change it
  2021                 TUint32 clSave = DosEntryPos1.iCluster; //-- need to save current cluster number because GetDirEntry() & MoveToNextEntryL() can change it
  2040 
  2022 
  2041                 //-- get directory entry from the cache. We know that the DosEntryPos1 is cached.
  2023                 //-- get directory entry from the cache. We know that the DosEntryPos1 is cached.
  2042                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2024                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2043                 if(nErr != KErrNone)
  2025                 if(nErr != KErrNone)
  2044                     break;
  2026                     break;
  2453     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2435     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2454         User::Leave(anError);//Allows maximum number of entries in root directory
  2436         User::Leave(anError);//Allows maximum number of entries in root directory
  2455 
  2437 
  2456     __PRINT2(_L("CFatMountCB::DoFindL() drv:%d, %S"),Drive().DriveNumber(),&aTrgtName);
  2438     __PRINT2(_L("CFatMountCB::DoFindL() drv:%d, %S"),Drive().DriveNumber(),&aTrgtName);
  2457 
  2439 
  2458     TInt previousCluster=aDosEntryPos.iCluster;
  2440     TUint32 previousCluster=aDosEntryPos.iCluster;
  2459     TUint previousPosition=aDosEntryPos.iPos;
  2441     TUint previousPosition=aDosEntryPos.iPos;
  2460     TInt changePreviousCluster=1;
  2442     TUint32 changePreviousCluster=1;
  2461     TInt count=0;
  2443     TUint32 count=0;
  2462 
  2444 
  2463     TBool trgNameIsWildCard     = EFalse; //-- ETrue if the name we are looking for is a wildcard
  2445     TBool trgNameIsWildCard     = EFalse; //-- ETrue if the name we are looking for is a wildcard
  2464     TBool trgNameFullySpecified = ETrue;  //-- ETrue if the name we are looking for doesn't contain wildcards
  2446     TBool trgNameFullySpecified = ETrue;  //-- ETrue if the name we are looking for doesn't contain wildcards
  2465 
  2447 
  2466 
  2448 
  2941 
  2923 
  2942 /**
  2924 /**
  2943     Zero fill a cluster
  2925     Zero fill a cluster
  2944     @param  aCluster cluster number to zero-fill
  2926     @param  aCluster cluster number to zero-fill
  2945 */
  2927 */
  2946 void CFatMountCB::ZeroDirClusterL(TInt aCluster)
  2928 void CFatMountCB::ZeroDirClusterL(TUint32 aCluster)
  2947     {
  2929     {
  2948 
  2930 
  2949     __PRINT1(_L("CFatMountCB::ZeroDirClusterL %d"),aCluster);
  2931     __PRINT1(_L("CFatMountCB::ZeroDirClusterL %d"),aCluster);
  2950 
  2932 
  2951     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
  2933     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
  3033 
  3015 
  3034     aLongFileName.SetLength(nameLen);
  3016     aLongFileName.SetLength(nameLen);
  3035 
  3017 
  3036     const TUint8 entryCheckSum = aDosEntry.CheckSum(); //-- check sum from the 1st VFat entry
  3018     const TUint8 entryCheckSum = aDosEntry.CheckSum(); //-- check sum from the 1st VFat entry
  3037 
  3019 
       
  3020     TUint nameChunkOffset = KMaxVFatEntryName*(count-1);
       
  3021 
  3038     while (count--)
  3022     while (count--)
  3039         {
  3023         {
  3040         TPtr fileNamePtr(&aLongFileName[0]+KMaxVFatEntryName*count,aLongFileName.Length()-KMaxVFatEntryName*count);
  3024         TPtr fileNamePtr(&aLongFileName[0]+nameChunkOffset, aLongFileName.Length()-nameChunkOffset);
  3041         fileNamePtr.Copy(vBuf);
  3025         fileNamePtr.Copy(vBuf);
  3042         if (count==0)
  3026         if (count==0)
  3043             break; //-- all VFat entries read, only DOS entry remained
  3027             break; //-- all VFat entries read, only DOS entry remained
       
  3028         
       
  3029         ASSERT(nameChunkOffset >= (TUint)KMaxVFatEntryName);
       
  3030         nameChunkOffset-=KMaxVFatEntryName;
  3044 
  3031 
  3045         MoveToNextEntryL(aPos);
  3032         MoveToNextEntryL(aPos);
  3046         ReadDirEntryL(aPos,aDosEntry);
  3033         ReadDirEntryL(aPos,aDosEntry);
  3047 
  3034 
  3048         //-- check if it is correct VFat entry.
  3035         //-- check if it is correct VFat entry.
  3153     }
  3140     }
  3154 
  3141 
  3155 //-----------------------------------------------------------------------------------------
  3142 //-----------------------------------------------------------------------------------------
  3156 
  3143 
  3157 /** Read the Uid of the entry starting at aCluster */
  3144 /** Read the Uid of the entry starting at aCluster */
  3158 void CFatMountCB::ReadUidL(TInt aCluster,TEntry& anEntry) const
  3145 void CFatMountCB::ReadUidL(TUint32 aCluster,TEntry& anEntry) const
  3159     {
  3146     {
  3160 
  3147 
  3161     __PRINT1(_L("CFatMountCB::ReadUidL(%d)"), aCluster);
  3148     __PRINT1(_L("CFatMountCB::ReadUidL(%d)"), aCluster);
  3162 
  3149 
  3163     if((TUint)aCluster < KFatFirstSearchCluster || (TUint)aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3150     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3164         User::Leave(KErrCorrupt);
  3151         User::Leave(KErrCorrupt);
  3165 
  3152 
  3166     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3153     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3167     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3154     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3168     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3155     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3215         User::Leave(KErrEof);
  3202         User::Leave(KErrEof);
  3216 
  3203 
  3217     if ((TUint)(aPos+aLength)>fileSize)
  3204     if ((TUint)(aPos+aLength)>fileSize)
  3218         aLength=fileSize-aPos;
  3205         aLength=fileSize-aPos;
  3219 
  3206 
  3220     TInt cluster=StartCluster(dosEntry);
  3207     TUint32 cluster=StartCluster(dosEntry);
  3221 	TInt pos = aPos;
  3208 	TInt pos = aPos;
  3222 
  3209 
  3223     TInt endCluster;
  3210     TUint32 endCluster;
  3224     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3211     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3225 	TInt readTotal = 0;
  3212 	TInt readTotal = 0;
  3226 
  3213 
  3227 	// Total number of clusters in file
  3214 	// Total number of clusters in file
  3228     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3215     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3334             }
  3321             }
  3335     }
  3322     }
  3336 
  3323 
  3337 //-----------------------------------------------------------------------------------------
  3324 //-----------------------------------------------------------------------------------------
  3338 
  3325 
       
  3326 /**
       
  3327     Write a FAT directory entry to disk. Assumes sufficient space has been created for it by AddDirEntry.
       
  3328 
       
  3329     @param  aPos        dir. entry position 
       
  3330     @param  aDirEntry   entry data
       
  3331 */
  3339 void CFatMountCB::WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry)
  3332 void CFatMountCB::WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry)
  3340 //
  3333     {
  3341 // Write a FAT directory entry to disk.
  3334 
  3342 // Assumes sufficient space has been created for it by AddDirEntry.
  3335     __PRINT2(_L("CFatMountCB::WriteDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
  3343 //
       
  3344     {
       
  3345 
       
  3346     __PRINT(_L("CFatMountCB::WriteDirEntryL"));
       
  3347 
  3336 
  3348     //-- use special interface to access FAT directory file
  3337     //-- use special interface to access FAT directory file
  3349     DirWriteL(aPos,TPtrC8((TUint8*)&aDirEntry,KSizeOfFatDirEntry));
  3338     DirWriteL(aPos,TPtrC8((TUint8*)&aDirEntry,KSizeOfFatDirEntry));
  3350     }
  3339     }
  3351 
  3340 
  3352 //-----------------------------------------------------------------------------------------
  3341 //-----------------------------------------------------------------------------------------
  3353 
  3342 
       
  3343 /**
       
  3344     Mark a dir entry as erased
       
  3345     @param  aPos dir. entry position 
       
  3346 */
  3354 void CFatMountCB::EraseDirEntryL(const TEntryPos& aPos)
  3347 void CFatMountCB::EraseDirEntryL(const TEntryPos& aPos)
  3355 //
  3348     {
  3356 // Mark a dir entry as erased
  3349     __PRINT2(_L("CFatMountCB::EraseDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
  3357 //
       
  3358     {
       
  3359 
       
  3360     __PRINT(_L("CFatMountCB::EraseDirEntryL"));
       
  3361     if(!iLeafDirCache && iLastLeafDir)
       
  3362         iLastLeafDir->Des().SetLength(0);
       
  3363 
  3350 
  3364     //-- use special interface to access FAT directory file
  3351     //-- use special interface to access FAT directory file
  3365     DirWriteL(aPos,TPtrC8((TUint8*)&KEntryErasedMarker,sizeof(TUint8)));
  3352     DirWriteL(aPos,TPtrC8((TUint8*)&KEntryErasedMarker,sizeof(TUint8)));
  3366     }
  3353     }
  3367 
  3354 
  3368 //-----------------------------------------------------------------------------------------
  3355 //-----------------------------------------------------------------------------------------
  3369 
  3356 
       
  3357 /**
       
  3358     Read a FAT directory entry 
       
  3359     @param  aPos        dir. entry position 
       
  3360     @param  aDirEntry   entry data
       
  3361 */
  3370 void CFatMountCB::ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const
  3362 void CFatMountCB::ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const
  3371 //
       
  3372 // Read a FAT directory entry to disk
       
  3373 //
       
  3374     {
  3363     {
  3375 
  3364 
  3376 //  __PRINT(_L("CFatMountCB::ReadDirEntryL"));
  3365 //  __PRINT(_L("CFatMountCB::ReadDirEntryL"));
  3377     if (IsEndOfClusterCh(aPos.iCluster))
  3366     if (IsEndOfClusterCh(aPos.iCluster))
  3378         {
  3367         {
  3513 /**
  3502 /**
  3514     Extend a file or directory, zeroing cluster chain and flushing after every write to FAT.
  3503     Extend a file or directory, zeroing cluster chain and flushing after every write to FAT.
  3515     This method is called for rugged FAT only.
  3504     This method is called for rugged FAT only.
  3516     for parameters see CFatTable::ExtendClusterListL
  3505     for parameters see CFatTable::ExtendClusterListL
  3517 */
  3506 */
  3518 void CFatMountCB::ExtendClusterListZeroedL(TInt aNumber,TInt& aCluster)
  3507 void CFatMountCB::ExtendClusterListZeroedL(TUint32 aNumber, TUint32& aCluster)
  3519     {
  3508     {
  3520     __PRINT(_L("CFatMountCB::ExtendClusterListZeroedL"));
  3509     __PRINT(_L("CFatMountCB::ExtendClusterListZeroedL"));
  3521     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
  3510     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
  3522 
  3511 
  3523     while(aNumber && FAT().GetNextClusterL(aCluster))
  3512     while(aNumber && FAT().GetNextClusterL(aCluster))
  3949         {
  3938         {
  3950         __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: abort, exceeds root"));
  3939         __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: abort, exceeds root"));
  3951         User::Leave(KErrNotFound); // Allows maximum number of entries in root directory
  3940         User::Leave(KErrNotFound); // Allows maximum number of entries in root directory
  3952         }
  3941         }
  3953 
  3942 
  3954     TInt previousCluster= aDosEntryPos.iCluster;
  3943     TUint32 previousCluster= aDosEntryPos.iCluster;
  3955     TUint previousPosition= aDosEntryPos.iPos;
  3944     TUint previousPosition= aDosEntryPos.iPos;
  3956     TInt changePreviousCluster=1;
  3945     TUint32 changePreviousCluster=1;
  3957     TInt count=0;
  3946     TUint32 count=0;
  3958 
  3947 
  3959     TFatDirEntry startEntry;
  3948     TFatDirEntry startEntry;
  3960     TFileName dummyLongName;
  3949     TFileName dummyLongName;
  3961 
  3950 
  3962     FOREVER
  3951     FOREVER
  3963         {
  3952         {
  3964 #ifdef _DEBUG
       
  3965         const TInt e= GetDirEntry(aDosEntryPos, aDosEntry, startEntry, dummyLongName);
       
  3966         __PRINT1(_L("CFatMountCB::FindVolumeLabelFileL: GetDir %d"), e);
       
  3967         User::LeaveIfError(e);
       
  3968 #else
       
  3969         User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, startEntry, dummyLongName));
  3953         User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, startEntry, dummyLongName));
  3970 #endif
  3954 
  3971         if(aDosEntry.IsEndOfDirectory())
  3955         if(aDosEntry.IsEndOfDirectory())
  3972             {
  3956             {
  3973             __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: end of dir"));
  3957             __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: end of dir"));
  3974             User::Leave(KErrNotFound);
  3958             User::Leave(KErrNotFound);
  3975             }
  3959             }
       
  3960 
  3976         if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
  3961         if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
  3977             {
  3962             {
  3978             if(aDosEntry.IsErased())
  3963             if(aDosEntry.IsErased())
  3979                 {
  3964                 {
  3980                 __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: erased end of root"));
  3965                 __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: erased end of root"));
  3981                 User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
  3966                 User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
  3982                 }
  3967                 }
  3983             }
  3968             }
       
  3969 
  3984         if(!aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage())
  3970         if(!aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage())
  3985             {
  3971             {
  3986             if(aDosEntry.Attributes() & KEntryAttVolume)
  3972             if(aDosEntry.Attributes() & KEntryAttVolume)
  3987                 {
  3973                 {
  3988                 aLabel = aDosEntry.Name();
  3974                 aLabel = aDosEntry.Name();
  3989 #ifdef _DEBUG
       
  3990                 dummyLongName.Copy(aLabel);
  3975                 dummyLongName.Copy(aLabel);
  3991                 __PRINT1(_L("-CFatMountCB::FindVolumeLabelFileL: found [%S]"), &dummyLongName);
  3976                 __PRINT1(_L("-CFatMountCB::FindVolumeLabelFileL: found [%S]"), &dummyLongName);
  3992 #endif
       
  3993                 break;
  3977                 break;
  3994                 }
  3978                 }
  3995             }
  3979             }
       
  3980         
  3996         MoveToNextEntryL(aDosEntryPos);
  3981         MoveToNextEntryL(aDosEntryPos);
       
  3982         
  3997         if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  3983         if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  3998             {
  3984             {
  3999             __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: passed end of root"));
  3985             __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: Not found"));
  4000             User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
  3986             User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
  4001             }
  3987             }
       
  3988         
  4002         if(aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
  3989         if(aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
  4003             {
  3990             {
  4004             DoCheckFatForLoopsL(aDosEntryPos.iCluster, previousCluster, changePreviousCluster, count);
  3991             DoCheckFatForLoopsL(aDosEntryPos.iCluster, previousCluster, changePreviousCluster, count);
  4005             }
  3992             }
       
  3993 
  4006         previousPosition=aDosEntryPos.iPos;
  3994         previousPosition=aDosEntryPos.iPos;
  4007         }
  3995         }
  4008     }
  3996     }
  4009 
  3997 
  4010 //-----------------------------------------------------------------------------------------
  3998 //-----------------------------------------------------------------------------------------
  4043     TBlockMapEntry blockMapEntry;
  4031     TBlockMapEntry blockMapEntry;
  4044 
  4032 
  4045     TUint i = 0;
  4033     TUint i = 0;
  4046     TInt clusterRelativePos;
  4034     TInt clusterRelativePos;
  4047     TInt maxClusters;
  4035     TInt maxClusters;
  4048     TInt endCluster;
  4036     TUint32 endCluster;
  4049     TInt clusterListLen;
  4037     TInt clusterListLen;
  4050     TInt readLength;
  4038     TInt readLength;
  4051     TInt temp;
  4039     TInt temp;
  4052     TInt currentPos;
  4040     TInt currentPos;
  4053     TLocalDriveCapsBuf caps;
  4041     TLocalDriveCapsBuf caps;
  4194          //-- leave itself means a problem
  4182          //-- leave itself means a problem
  4195         chkDskRes = CScanDrive::EUnknownError;
  4183         chkDskRes = CScanDrive::EUnknownError;
  4196         }
  4184         }
  4197 
  4185 
  4198     delete pScnDrv;
  4186     delete pScnDrv;
       
  4187     pScnDrv = NULL;
  4199 
  4188 
  4200     if(chkDskRes != KErrNone)
  4189     if(chkDskRes != KErrNone)
  4201         {
  4190         {
  4202         __PRINT2(_L("CFatMountCB::CheckDisk() drv:%d, result:%d"), DriveNumber(), chkDskRes);
  4191         __PRINT2(_L("CFatMountCB::CheckDisk() drv:%d, result:%d"), DriveNumber(), chkDskRes);
  4203         }
  4192         }
  4223 
  4212 
  4224     TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::EScanAndFix));
  4213     TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::EScanAndFix));
  4225 
  4214 
  4226     const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4215     const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4227     delete pScnDrv;
  4216     delete pScnDrv;
  4228 
  4217     pScnDrv = NULL;
  4229 
  4218 
  4230     if(bNeedFatRemount)
  4219     if(bNeedFatRemount)
  4231         {//-- ScanDrive found and probably fixed some errors.
  4220         {//-- ScanDrive found and probably fixed some errors.
  4232         // ensure cached fat and free cluster count are updated
  4221         // ensure cached fat and free cluster count are updated
  4233         DoDismount(); //-- dismount
  4222         DoDismount(); //-- dismount