userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
branchRCL_3
changeset 22 2f92ad2dc5db
parent 20 597aaf25e343
child 41 0ffb4e86fcc9
equal deleted inserted replaced
21:e7d2d738d3c2 22:2f92ad2dc5db
   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 
  1360     WriteDirEntryL(firstEntryPos,firstEntry);
  1355     WriteDirEntryL(firstEntryPos,firstEntry);
  1361     }
  1356     }
  1362 
  1357 
  1363 //-----------------------------------------------------------------------------------------
  1358 //-----------------------------------------------------------------------------------------
  1364 
  1359 
  1365 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
  1366 //
  1361 //
  1367 // Check one fat cluster for loops.
  1362 // Check one fat cluster for loops.
  1368 //
  1363 //
  1369     {
  1364     {
  1370 
  1365 
  1386 //
  1381 //
  1387 // Check for loops
  1382 // Check for loops
  1388 //
  1383 //
  1389     {
  1384     {
  1390 
  1385 
  1391     TInt cluster=StartCluster(anEntry);
  1386     TUint32 cluster = StartCluster(anEntry);
  1392     if (cluster==0 && anEntry.Size()==0)
  1387     if (cluster==0 && anEntry.Size()==0)
  1393         return;
  1388         return;
  1394 
  1389 
  1395     TInt previousCluster=cluster;
  1390     TUint32 previousCluster=cluster;
  1396     TInt changePreviousCluster=1;
  1391     TUint32 changePreviousCluster=1;
  1397     TInt count=0;
  1392     TUint32 count=0;
  1398 
  1393 
  1399 
  1394 
  1400     for(;;)
  1395     for(;;)
  1401         {
  1396         {
  1402         if ((TUint)cluster < KFatFirstSearchCluster || (!IsEndOfClusterCh(cluster) && (TUint)cluster>MaxClusterNumber()))
  1397         if ((TUint)cluster < KFatFirstSearchCluster || (!IsEndOfClusterCh(cluster) && (TUint)cluster>MaxClusterNumber()))
  1504         else
  1499         else
  1505             WriteDirEntryL(firstEntryPos,firstEntry,name);
  1500             WriteDirEntryL(firstEntryPos,firstEntry,name);
  1506         }
  1501         }
  1507 
  1502 
  1508     CFatFileCB& file=(*((CFatFileCB*)aFile));
  1503     CFatFileCB& file=(*((CFatFileCB*)aFile));
  1509     file.SetL(firstEntry,(TShare)(aMode&KFileShareMask),firstEntryPos);
  1504     file.SetupL(firstEntry, firstEntryPos);
       
  1505 
  1510     if (anOpen==EFileReplace && file.Size())
  1506     if (anOpen==EFileReplace && file.Size())
  1511         {
  1507         {
  1512         file.SetSizeL(0);
  1508         file.SetSizeL(0);
  1513         file.SetSize(0);
  1509         }
  1514         }
  1510 
  1515     if (file.IsSeekIndex()==EFalse)
       
  1516         file.CreateSeekIndex();
       
  1517     if (anOpen==EFileReplace || anOpen==EFileCreate)
  1511     if (anOpen==EFileReplace || anOpen==EFileCreate)
  1518         file.SetArchiveAttribute();
  1512         file.SetArchiveAttribute();
  1519 
  1513 
  1520     if(!IsRuggedFSys())
  1514     if(!IsRuggedFSys())
  1521         FAT().FlushL();
  1515         FAT().FlushL();
  1580 
  1574 
  1581     }
  1575     }
  1582 
  1576 
  1583 //-----------------------------------------------------------------------------------------
  1577 //-----------------------------------------------------------------------------------------
  1584 
  1578 
  1585 TBool CFatMountCB::IsDirectoryEmptyL(TInt aCluster)
       
  1586 //
  1579 //
  1587 // Check aCluster contains no directory entries other than . and ..
  1580 // Check aCluster contains no directory entries other than . and ..
  1588 //
  1581 //
       
  1582 TBool CFatMountCB::IsDirectoryEmptyL(TUint32 aCluster)
  1589     {
  1583     {
  1590 
  1584 
  1591     __PRINT(_L("CFatMountCB::IsDirectoryEmptyL"));
  1585     __PRINT(_L("CFatMountCB::IsDirectoryEmptyL"));
  1592     TEntryPos dirEntryPos(aCluster,0);
  1586     TEntryPos dirEntryPos(aCluster,0);
  1593     TFatDirEntry dirEntry;
  1587     TFatDirEntry dirEntry;
  1611 //-----------------------------------------------------------------------------------------
  1605 //-----------------------------------------------------------------------------------------
  1612 
  1606 
  1613 /**
  1607 /**
  1614     Overwrite as many contiguous file clusters as possible.
  1608     Overwrite as many contiguous file clusters as possible.
  1615 */
  1609 */
  1616 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)
  1617     {
  1611     {
  1618 
  1612 
  1619     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1613     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
  1620     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1614     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
  1621 
  1615 
  1622     TInt endCluster=0;
  1616     TUint32 endCluster=0;
  1623 
  1617 
  1624     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1618     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1625     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1619     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1626     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1620     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1627     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1621     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1643     r = iRawDisk->GetLastErrorInfo(errinf);
  1637     r = iRawDisk->GetLastErrorInfo(errinf);
  1644 
  1638 
  1645     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
  1646         {
  1640         {
  1647 
  1641 
  1648         const TInt badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
  1642         const TUint32 badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
  1649               TInt goodcluster = FAT().AllocateSingleClusterL(badcluster);
  1643               TUint32 goodcluster = FAT().AllocateSingleClusterL(badcluster);
  1650 
  1644 
  1651         //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.
  1652         TInt cluster = aPos.iCluster;
  1646         TUint32 cluster = aPos.iCluster;
  1653         if ( (aPos.iPos) && ((aPos.iPos)==((aPos.iPos >> ClusterSizeLog2())<<ClusterSizeLog2())))
  1647         if ( (aPos.iPos) && ((aPos.iPos)==((aPos.iPos >> ClusterSizeLog2())<<ClusterSizeLog2())))
  1654             cluster--;
  1648             cluster--;
  1655 
  1649 
  1656         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))
  1657             { //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.
  1740     User::Leave(KErrCorrupt);
  1734     User::Leave(KErrCorrupt);
  1741     }
  1735     }
  1742 
  1736 
  1743 //-----------------------------------------------------------------------------------------
  1737 //-----------------------------------------------------------------------------------------
  1744 
  1738 
  1745 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)
  1746 //
  1740 //
  1747 // Overwrite cluster list.
  1741 // Overwrite cluster list.
  1748 //
  1742 //
  1749     {
  1743     {
  1750 
  1744 
  1785 //
  1779 //
  1786     {
  1780     {
  1787 
  1781 
  1788     __PRINT(_L("CFatMountCB::DoReadFromClusterListL"));
  1782     __PRINT(_L("CFatMountCB::DoReadFromClusterListL"));
  1789 
  1783 
  1790     TInt endCluster=0;
  1784     TUint32 endCluster=0;
  1791 
  1785 
  1792     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1786     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1793     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1787     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1794     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1788     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1795     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1789     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1858 // Navigate the path to find the leaf directory.
  1852 // Navigate the path to find the leaf directory.
  1859 // Returns the startcluster of data for the directory found.
  1853 // Returns the startcluster of data for the directory found.
  1860 //
  1854 //
  1861     {
  1855     {
  1862 
  1856 
  1863     __PRINT(_L("CFatMountCB::FindLeafDirL"));
  1857     __PRINT2(_L("CFatMountCB::FindLeafDirL drv:%d, dir:%S"),DriveNumber() ,&aLeafDir);
  1864 
  1858 
  1865     TLex lex(aName);
  1859     TLex lex(aName);
  1866     TInt r;
  1860     TInt r;
  1867     TEntryPos entryPos(RootIndicator(),0);
  1861     TEntryPos entryPos(RootIndicator(),0);
  1868 
  1862 
  1869     if (iLeafDirCache == NULL)
  1863     ASSERT(iLeafDirCache);
  1870     	{
  1864 
  1871         TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
       
  1872         TInt namelen=aName.Length();
       
  1873         if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
       
  1874             {
       
  1875             if (leaflen==namelen)
       
  1876                 return(iLastLeafDirCluster);
       
  1877             lex.Inc(leaflen-1);
       
  1878             entryPos.iCluster=iLastLeafDirCluster;
       
  1879             }
       
  1880     	}
       
  1881     else
       
  1882     	{
       
  1883         // Skip root directory
       
  1884         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1865         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
  1885         	{
  1866         	{
  1886         	TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1867         const TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
  1887         	if (err == KErrNone)
  1868         	if (err == KErrNone)
  1888         		{
  1869         		{
  1889         		ASSERT(aLeafDir.iClusterNum > 0);
  1870         	ASSERT(ClusterNumberValid(aLeafDir.iClusterNum)); 
  1890         		return aLeafDir.iClusterNum;
  1871         		return aLeafDir.iClusterNum;
  1891         		}
  1872         		}
  1892         	else if (err != KErrNotFound)
  1873         	else if (err != KErrNotFound)
  1893         		{
  1874         		{
  1894         		User::LeaveIfError(err);
  1875         		User::LeaveIfError(err);
  1895         		}
  1876         		}
  1896         	}
  1877         	}
  1897     	}
  1878 
  1898 
  1879     TFatDirEntry entry;
  1899     FOREVER
  1880     TFileName fileName;
       
  1881     TEntryPos startPos;
       
  1882     TFatDirEntry startEntry;
       
  1883 
       
  1884     for(;;)
  1900         {
  1885         {
  1901         lex.Inc(); // Skip path delimiter
  1886         lex.Inc(); // Skip path delimiter
  1902         lex.Mark();
  1887         lex.Mark();
  1903         r=lex.Remainder().Locate(KPathDelimiter);
  1888         r=lex.Remainder().Locate(KPathDelimiter);
       
  1889         
  1904         if (r==KErrNotFound)
  1890         if (r==KErrNotFound)
  1905             r=lex.Remainder().Length();
  1891             r=lex.Remainder().Length();
       
  1892         
  1906         if (r==0) // End of the path
  1893         if (r==0) // End of the path
  1907             break;
  1894             break;
       
  1895         
  1908         lex.Inc(r); // Set the token length
  1896         lex.Inc(r); // Set the token length
  1909         TFatDirEntry entry;
  1897         
  1910 
  1898         
  1911         TFileName fileName;
       
  1912         TEntryPos startPos;
       
  1913         TFatDirEntry startEntry;
       
  1914         DoFindL(lex.MarkedToken(),
  1899         DoFindL(lex.MarkedToken(),
  1915         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1900         		KEntryAttMatchMask|KEntryAttMatchExclusive,
  1916         		startPos, startEntry, entryPos, entry,
  1901         		startPos, startEntry, entryPos, entry,
  1917         		fileName, KErrPathNotFound,
  1902         		fileName, KErrPathNotFound,
  1918         		NULL,
  1903         		NULL,
  1919         		aLeafDir);
  1904         		aLeafDir);
  1920 
  1905 
  1921 
  1906 
  1922         entryPos.iCluster=StartCluster(entry);
  1907         entryPos.iCluster=StartCluster(entry);
  1923         entryPos.iPos=0;
  1908         entryPos.iPos=0;
  1924         }
  1909         }// for(;;)
  1925 
  1910 
  1926     if (iLeafDirCache == NULL)
       
  1927     	{
       
  1928         AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
       
  1929         ((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
       
  1930     	}
       
  1931     else
       
  1932     	{
       
  1933         if (aName.Length() > 1)
  1911         if (aName.Length() > 1)
  1934         	{
  1912         	{
  1935         	aLeafDir = TLeafDirData(entryPos.iCluster);
  1913         	aLeafDir = TLeafDirData(entryPos.iCluster);
  1936             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1914             iLeafDirCache->AddToCacheL(aName, aLeafDir);
  1937         	}
  1915         	}
  1938     	}
       
  1939 
  1916 
  1940     return entryPos.iCluster;
  1917     return entryPos.iCluster;
  1941     }
  1918     }
  1942 
  1919 
  1943 //-----------------------------------------------------------------------------------------
  1920 //-----------------------------------------------------------------------------------------
  1993     	DosEntryPos1 = aLeafDir.iMRUPos;
  1970     	DosEntryPos1 = aLeafDir.iMRUPos;
  1994     	}
  1971     	}
  1995 
  1972 
  1996 	TInt numFound = 0;
  1973 	TInt numFound = 0;
  1997 	TEntryPos startPos = DosEntryPos1;
  1974 	TEntryPos startPos = DosEntryPos1;
  1998 	TInt clusterNum = DosEntryPos1.iCluster;
  1975 	TUint32 clusterNum = DosEntryPos1.iCluster;
  1999 
  1976 
  2000     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  1977     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
  2001         {//-- 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
  2002          //-- 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
  2003 
  1980 
  2039             //-- 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)
  2040             /// until it reaches the next page
  2017             /// until it reaches the next page
  2041             for(;;)
  2018             for(;;)
  2042                 {
  2019                 {
  2043                 StartEntryPos1 = DosEntryPos1;
  2020                 StartEntryPos1 = DosEntryPos1;
  2044                 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
  2045 
  2022 
  2046                 //-- 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.
  2047                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2024                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
  2048                 if(nErr != KErrNone)
  2025                 if(nErr != KErrNone)
  2049                     break;
  2026                     break;
  2458     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2435     if (IsRootDir(aDosEntryPos)&&(aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
  2459         User::Leave(anError);//Allows maximum number of entries in root directory
  2436         User::Leave(anError);//Allows maximum number of entries in root directory
  2460 
  2437 
  2461     __PRINT2(_L("CFatMountCB::DoFindL() drv:%d, %S"),Drive().DriveNumber(),&aTrgtName);
  2438     __PRINT2(_L("CFatMountCB::DoFindL() drv:%d, %S"),Drive().DriveNumber(),&aTrgtName);
  2462 
  2439 
  2463     TInt previousCluster=aDosEntryPos.iCluster;
  2440     TUint32 previousCluster=aDosEntryPos.iCluster;
  2464     TUint previousPosition=aDosEntryPos.iPos;
  2441     TUint previousPosition=aDosEntryPos.iPos;
  2465     TInt changePreviousCluster=1;
  2442     TUint32 changePreviousCluster=1;
  2466     TInt count=0;
  2443     TUint32 count=0;
  2467 
  2444 
  2468     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
  2469     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
  2470 
  2447 
  2471 
  2448 
  2946 
  2923 
  2947 /**
  2924 /**
  2948     Zero fill a cluster
  2925     Zero fill a cluster
  2949     @param  aCluster cluster number to zero-fill
  2926     @param  aCluster cluster number to zero-fill
  2950 */
  2927 */
  2951 void CFatMountCB::ZeroDirClusterL(TInt aCluster)
  2928 void CFatMountCB::ZeroDirClusterL(TUint32 aCluster)
  2952     {
  2929     {
  2953 
  2930 
  2954     __PRINT1(_L("CFatMountCB::ZeroDirClusterL %d"),aCluster);
  2931     __PRINT1(_L("CFatMountCB::ZeroDirClusterL %d"),aCluster);
  2955 
  2932 
  2956     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
  2933     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
  3163     }
  3140     }
  3164 
  3141 
  3165 //-----------------------------------------------------------------------------------------
  3142 //-----------------------------------------------------------------------------------------
  3166 
  3143 
  3167 /** Read the Uid of the entry starting at aCluster */
  3144 /** Read the Uid of the entry starting at aCluster */
  3168 void CFatMountCB::ReadUidL(TInt aCluster,TEntry& anEntry) const
  3145 void CFatMountCB::ReadUidL(TUint32 aCluster,TEntry& anEntry) const
  3169     {
  3146     {
  3170 
  3147 
  3171     __PRINT1(_L("CFatMountCB::ReadUidL(%d)"), aCluster);
  3148     __PRINT1(_L("CFatMountCB::ReadUidL(%d)"), aCluster);
  3172 
  3149 
  3173     if((TUint)aCluster < KFatFirstSearchCluster || (TUint)aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3150     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3174         User::Leave(KErrCorrupt);
  3151         User::Leave(KErrCorrupt);
  3175 
  3152 
  3176     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3153     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3177     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3154     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3178     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3155     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3225         User::Leave(KErrEof);
  3202         User::Leave(KErrEof);
  3226 
  3203 
  3227     if ((TUint)(aPos+aLength)>fileSize)
  3204     if ((TUint)(aPos+aLength)>fileSize)
  3228         aLength=fileSize-aPos;
  3205         aLength=fileSize-aPos;
  3229 
  3206 
  3230     TInt cluster=StartCluster(dosEntry);
  3207     TUint32 cluster=StartCluster(dosEntry);
  3231 	TInt pos = aPos;
  3208 	TInt pos = aPos;
  3232 
  3209 
  3233     TInt endCluster;
  3210     TUint32 endCluster;
  3234     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3211     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
  3235 	TInt readTotal = 0;
  3212 	TInt readTotal = 0;
  3236 
  3213 
  3237 	// Total number of clusters in file
  3214 	// Total number of clusters in file
  3238     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3215     TInt maxClusters=((fileSize+clusterSize-1)>>ClusterSizeLog2());
  3344             }
  3321             }
  3345     }
  3322     }
  3346 
  3323 
  3347 //-----------------------------------------------------------------------------------------
  3324 //-----------------------------------------------------------------------------------------
  3348 
  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 */
  3349 void CFatMountCB::WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry)
  3332 void CFatMountCB::WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry)
  3350 //
  3333     {
  3351 // Write a FAT directory entry to disk.
  3334 
  3352 // Assumes sufficient space has been created for it by AddDirEntry.
  3335     __PRINT2(_L("CFatMountCB::WriteDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
  3353 //
       
  3354     {
       
  3355 
       
  3356     __PRINT(_L("CFatMountCB::WriteDirEntryL"));
       
  3357 
  3336 
  3358     //-- use special interface to access FAT directory file
  3337     //-- use special interface to access FAT directory file
  3359     DirWriteL(aPos,TPtrC8((TUint8*)&aDirEntry,KSizeOfFatDirEntry));
  3338     DirWriteL(aPos,TPtrC8((TUint8*)&aDirEntry,KSizeOfFatDirEntry));
  3360     }
  3339     }
  3361 
  3340 
  3362 //-----------------------------------------------------------------------------------------
  3341 //-----------------------------------------------------------------------------------------
  3363 
  3342 
       
  3343 /**
       
  3344     Mark a dir entry as erased
       
  3345     @param  aPos dir. entry position 
       
  3346 */
  3364 void CFatMountCB::EraseDirEntryL(const TEntryPos& aPos)
  3347 void CFatMountCB::EraseDirEntryL(const TEntryPos& aPos)
  3365 //
  3348     {
  3366 // Mark a dir entry as erased
  3349     __PRINT2(_L("CFatMountCB::EraseDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
  3367 //
       
  3368     {
       
  3369 
       
  3370     __PRINT(_L("CFatMountCB::EraseDirEntryL"));
       
  3371     if(!iLeafDirCache && iLastLeafDir)
       
  3372         iLastLeafDir->Des().SetLength(0);
       
  3373 
  3350 
  3374     //-- use special interface to access FAT directory file
  3351     //-- use special interface to access FAT directory file
  3375     DirWriteL(aPos,TPtrC8((TUint8*)&KEntryErasedMarker,sizeof(TUint8)));
  3352     DirWriteL(aPos,TPtrC8((TUint8*)&KEntryErasedMarker,sizeof(TUint8)));
  3376     }
  3353     }
  3377 
  3354 
  3378 //-----------------------------------------------------------------------------------------
  3355 //-----------------------------------------------------------------------------------------
  3379 
  3356 
       
  3357 /**
       
  3358     Read a FAT directory entry 
       
  3359     @param  aPos        dir. entry position 
       
  3360     @param  aDirEntry   entry data
       
  3361 */
  3380 void CFatMountCB::ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const
  3362 void CFatMountCB::ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const
  3381 //
       
  3382 // Read a FAT directory entry to disk
       
  3383 //
       
  3384     {
  3363     {
  3385 
  3364 
  3386 //  __PRINT(_L("CFatMountCB::ReadDirEntryL"));
  3365 //  __PRINT(_L("CFatMountCB::ReadDirEntryL"));
  3387     if (IsEndOfClusterCh(aPos.iCluster))
  3366     if (IsEndOfClusterCh(aPos.iCluster))
  3388         {
  3367         {
  3523 /**
  3502 /**
  3524     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.
  3525     This method is called for rugged FAT only.
  3504     This method is called for rugged FAT only.
  3526     for parameters see CFatTable::ExtendClusterListL
  3505     for parameters see CFatTable::ExtendClusterListL
  3527 */
  3506 */
  3528 void CFatMountCB::ExtendClusterListZeroedL(TInt aNumber,TInt& aCluster)
  3507 void CFatMountCB::ExtendClusterListZeroedL(TUint32 aNumber, TUint32& aCluster)
  3529     {
  3508     {
  3530     __PRINT(_L("CFatMountCB::ExtendClusterListZeroedL"));
  3509     __PRINT(_L("CFatMountCB::ExtendClusterListZeroedL"));
  3531     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
  3510     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
  3532 
  3511 
  3533     while(aNumber && FAT().GetNextClusterL(aCluster))
  3512     while(aNumber && FAT().GetNextClusterL(aCluster))
  3959         {
  3938         {
  3960         __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: abort, exceeds root"));
  3939         __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: abort, exceeds root"));
  3961         User::Leave(KErrNotFound); // Allows maximum number of entries in root directory
  3940         User::Leave(KErrNotFound); // Allows maximum number of entries in root directory
  3962         }
  3941         }
  3963 
  3942 
  3964     TInt previousCluster= aDosEntryPos.iCluster;
  3943     TUint32 previousCluster= aDosEntryPos.iCluster;
  3965     TUint previousPosition= aDosEntryPos.iPos;
  3944     TUint previousPosition= aDosEntryPos.iPos;
  3966     TInt changePreviousCluster=1;
  3945     TUint32 changePreviousCluster=1;
  3967     TInt count=0;
  3946     TUint32 count=0;
  3968 
  3947 
  3969     TFatDirEntry startEntry;
  3948     TFatDirEntry startEntry;
  3970     TFileName dummyLongName;
  3949     TFileName dummyLongName;
  3971 
  3950 
  3972     FOREVER
  3951     FOREVER
  4052     TBlockMapEntry blockMapEntry;
  4031     TBlockMapEntry blockMapEntry;
  4053 
  4032 
  4054     TUint i = 0;
  4033     TUint i = 0;
  4055     TInt clusterRelativePos;
  4034     TInt clusterRelativePos;
  4056     TInt maxClusters;
  4035     TInt maxClusters;
  4057     TInt endCluster;
  4036     TUint32 endCluster;
  4058     TInt clusterListLen;
  4037     TInt clusterListLen;
  4059     TInt readLength;
  4038     TInt readLength;
  4060     TInt temp;
  4039     TInt temp;
  4061     TInt currentPos;
  4040     TInt currentPos;
  4062     TLocalDriveCapsBuf caps;
  4041     TLocalDriveCapsBuf caps;
  4203          //-- leave itself means a problem
  4182          //-- leave itself means a problem
  4204         chkDskRes = CScanDrive::EUnknownError;
  4183         chkDskRes = CScanDrive::EUnknownError;
  4205         }
  4184         }
  4206 
  4185 
  4207     delete pScnDrv;
  4186     delete pScnDrv;
       
  4187     pScnDrv = NULL;
  4208 
  4188 
  4209     if(chkDskRes != KErrNone)
  4189     if(chkDskRes != KErrNone)
  4210         {
  4190         {
  4211         __PRINT2(_L("CFatMountCB::CheckDisk() drv:%d, result:%d"), DriveNumber(), chkDskRes);
  4191         __PRINT2(_L("CFatMountCB::CheckDisk() drv:%d, result:%d"), DriveNumber(), chkDskRes);
  4212         }
  4192         }
  4232 
  4212 
  4233     TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::EScanAndFix));
  4213     TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::EScanAndFix));
  4234 
  4214 
  4235     const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4215     const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4236     delete pScnDrv;
  4216     delete pScnDrv;
  4237 
  4217     pScnDrv = NULL;
  4238 
  4218 
  4239     if(bNeedFatRemount)
  4219     if(bNeedFatRemount)
  4240         {//-- ScanDrive found and probably fixed some errors.
  4220         {//-- ScanDrive found and probably fixed some errors.
  4241         // ensure cached fat and free cluster count are updated
  4221         // ensure cached fat and free cluster count are updated
  4242         DoDismount(); //-- dismount
  4222         DoDismount(); //-- dismount