userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
    24 #include "sl_cache.h"
    24 #include "sl_cache.h"
    25 #include "sl_leafdir_cache.h"
    25 #include "sl_leafdir_cache.h"
    26 #include "sl_dir_cache.h"
    26 #include "sl_dir_cache.h"
    27 #include "sl_scandrv.h"
    27 #include "sl_scandrv.h"
    28 #include <hal.h>
    28 #include <hal.h>
    29 #include <f32dbg.h>
       
    30 
    29 
    31 TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively);
    30 TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively);
    32 
    31 
    33 
    32 
    34 //-----------------------------------------------------------------------------------------
    33 //-----------------------------------------------------------------------------------------
   549             }
   548             }
   550 
   549 
   551         return;
   550         return;
   552         }
   551         }
   553 
   552 
   554     if(Locked())
   553     if(LockStatus() != 0)
   555         {//-- can't finalise the volume if it has opened disk access objects, like Format or RawAccess
   554         {//-- can't finalise the volume if it has opened objects and not in the consistent state.
       
   555          //-- Theoretically, we can finalise the mount if we have files opened only for read, but at present,
       
   556          //-- it's impossible to detect such situation.
   556         User::Leave(KErrInUse);
   557         User::Leave(KErrInUse);
   557         }
   558         }
   558 
   559 
   559     if(State() != EInit_R && State() != EInit_W)
   560     if(State() != EInit_R && State() != EInit_W)
   560         {//-- can't finalise the mount because it can be in an inconsistent state; e.g. corrupt.
   561         {//-- can't finalise the mount because it can be in an inconsistent state; e.g. corrupt.
   609 /**
   610 /**
   610 @return ETrue if "VolumeClean" flag is supported i.e. this is not FAT12
   611 @return ETrue if "VolumeClean" flag is supported i.e. this is not FAT12
   611 */
   612 */
   612 TBool CFatMountCB::VolCleanFlagSupported() const
   613 TBool CFatMountCB::VolCleanFlagSupported() const
   613     {
   614     {
   614     const TFatType fatType=FatType();
   615         const TFatType fatType=FatType();
   615 
   616 
   616     ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32);
   617         ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32);
   617     return (fatType != EFat12);
   618         return (fatType != EFat12);
   618     }
       
   619 
       
   620 
       
   621 //-----------------------------------------------------------------------------------------
       
   622 /**
       
   623     @return Volume size in bytes according to the number of usable clusters.
       
   624     This approach is not applicable to RAM drive, because its size isn't fixed and can be adjusted by the system.
       
   625 */
       
   626 TUint64 CFatMountCB::VolumeSizeInBytes() const
       
   627     {
       
   628     ASSERT(ConsistentState());
       
   629     ASSERT(!iRamDrive);
       
   630     return ((TUint64)UsableClusters()) << ClusterSizeLog2();
       
   631     }
   619     }
   632 
   620 
   633 //-----------------------------------------------------------------------------------------
   621 //-----------------------------------------------------------------------------------------
   634 
   622 
   635 
   623 
   690 
   678 
   691 #endif
   679 #endif
   692 
   680 
   693 
   681 
   694     const TUint32 freeClusters = FAT().NumberOfFreeClusters(bSyncOp);
   682     const TUint32 freeClusters = FAT().NumberOfFreeClusters(bSyncOp);
       
   683 
       
   684     __PRINT1(_L("CFatMountCB::VolumeL() free clusters:%d"), freeClusters);
       
   685 
   695     aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2();
   686     aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2();
   696     __PRINT1(_L("CFatMountCB::VolumeL() free clusters:%d"), freeClusters);
   687 
   697 
   688     if (drvInfo.iType==EMediaRam)
   698 
       
   699     if(drvInfo.iType==EMediaRam)
       
   700         {//-- a special case. RAM drive size is variable and adjustable. It should be calculated from aVolume.iFree and CMountCB::iFree
       
   701         ASSERT(iRamDrive);
       
   702         aVolume.iSize=aVolume.iFree+iSize;
   689         aVolume.iSize=aVolume.iFree+iSize;
   703         aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc
   690 
   704         aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2();  //-- round down to cluster size
   691     aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc
   705         }
   692     aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2();  //-- round down to cluster size
   706     else
       
   707         {//-- normal case; the volume size is determined by amount of usable clusters
       
   708         aVolume.iSize = VolumeSizeInBytes();
       
   709         }
       
   710 
   693 
   711     }
   694     }
   712 
   695 
   713 
   696 
   714 //-----------------------------------------------------------------------------------------
   697 //-----------------------------------------------------------------------------------------
  1637 
  1620 
  1638     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1621     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1639     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1622     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1640     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1623     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1641     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1624     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1642     TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
  1625     TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
  1643 
  1626 
  1644     TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag));
  1627     TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag));
  1645 
  1628 
  1646     if(r == KErrNone) // Write succeded
  1629     if(r == KErrNone) // Write succeded
  1647         {
  1630         {
  1668             cluster--;
  1651             cluster--;
  1669 
  1652 
  1670         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1653         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
  1671             { //Copy the contents already present in this cluster to new cluster allocated.
  1654             { //Copy the contents already present in this cluster to new cluster allocated.
  1672             const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2());
  1655             const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2());
  1673             dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
  1656             dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
  1674 
  1657 
  1675 
  1658 
  1676             //-- Allocate the buffer required to copy the contents from bad cluster
  1659             //-- Allocate the buffer required to copy the contents from bad cluster
  1677             RBuf8 clustBuf;
  1660             RBuf8 clustBuf;
  1678             CleanupClosePushL(clustBuf);
  1661             CleanupClosePushL(clustBuf);
  1697 
  1680 
  1698             FOREVER
  1681             FOREVER
  1699                 {
  1682                 {
  1700                 //Calculate and copy the contents to new cluster.
  1683                 //Calculate and copy the contents to new cluster.
  1701                 aPos.iCluster = goodcluster;
  1684                 aPos.iCluster = goodcluster;
  1702                 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
  1685                 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
  1703 
  1686 
  1704                 r = LocalDrive()->Write(dataStart, clustBuf);
  1687                 r = LocalDrive()->Write(dataStart, clustBuf);
  1705                 if(r == KErrNone)
  1688                 if(r == KErrNone)
  1706                     { // Copied contents to new cluster so fix up the chain and mark the cluster as bad.
  1689                     { // Copied contents to new cluster so fix up the chain and mark the cluster as bad.
  1707                     FAT().WriteL(goodcluster, FAT().ReadL(badcluster));
  1690                     FAT().WriteL(goodcluster, FAT().ReadL(badcluster));
  1805 
  1788 
  1806     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1789     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
  1807     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1790     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
  1808     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1791     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
  1809     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1792     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
  1810     const TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
  1793     const TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
  1811 
  1794 
  1812     TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag));
  1795     TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag));
  1813 
  1796 
  1814     if(r == KErrNone) // Read succeded
  1797     if(r == KErrNone) // Read succeded
  1815         {
  1798         {
  3169 
  3152 
  3170     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3153     if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
  3171         User::Leave(KErrCorrupt);
  3154         User::Leave(KErrCorrupt);
  3172 
  3155 
  3173     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3156     TBuf8<sizeof(TCheckedUid)> uidBuf;
  3174     iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
  3157     iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf);
  3175     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3158     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
  3176     TCheckedUid uid(uidBuf);
  3159     TCheckedUid uid(uidBuf);
  3177     anEntry.iType=uid.UidType();
  3160     anEntry.iType=uid.UidType();
  3178     }
  3161     }
  3179 
  3162 
  3245         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3228         if (pos<(clusterListLen<<ClusterSizeLog2()))
  3246             {
  3229             {
  3247 			//  Read the remaining length or the entire cluster block whichever is smaller
  3230 			//  Read the remaining length or the entire cluster block whichever is smaller
  3248 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3231 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
  3249 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3232 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
  3250 			TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
  3233 			TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos;
  3251 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0);
  3234 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0);
  3252 			readTotal += readLength;
  3235 			readTotal += readLength;
  3253 
  3236 
  3254 			if (readTotal == aLength)
  3237 			if (readTotal == aLength)
  3255 				return;
  3238 				return;
  3449 
  3432 
  3450     //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos);
  3433     //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos);
  3451     if (!IsRootDir(aPos))
  3434     if (!IsRootDir(aPos))
  3452         {
  3435         {
  3453         TInt relPos=ClusterRelativePos(aPos.iPos);
  3436         TInt relPos=ClusterRelativePos(aPos.iPos);
  3454         return FAT().DataPositionInBytes(aPos.iCluster)+relPos;
  3437         return FAT().DataPositionInBytesL(aPos.iCluster)+relPos;
  3455         }
  3438         }
  3456     if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd())
  3439     if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd())
  3457         User::Leave(KErrDirFull); // Past last root dir entry
  3440         User::Leave(KErrDirFull); // Past last root dir entry
  3458     return StartOfRootDirInBytes()+aPos.iPos;
  3441     return StartOfRootDirInBytes()+aPos.iPos;
  3459     }
  3442     }
  3641 			break;
  3624 			break;
  3642 			}
  3625 			}
  3643 		case EDisableFATDirCache:
  3626 		case EDisableFATDirCache:
  3644 			{
  3627 			{
  3645 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3628 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3646 		    TUint32 KEDisableFATDirCache = MWTCacheInterface::EDisableCache;
  3629 		    TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
  3647 		    pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
  3630 		    pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
  3648 			break;
  3631 			break;
  3649 			}
  3632 			}
  3650 		case EDumpFATDirCache:
  3633 		case EDumpFATDirCache:
  3651 			{
  3634 			{
  3652 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3635 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3653 		    if (pDirCache)
  3636 		    TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
  3654 		        {
  3637 		    pDirCache->Control(KEDumpFATDirCache, 0, NULL);
  3655 	            TUint32 KEDumpFATDirCache = MWTCacheInterface::EDumpCache;
       
  3656 	            pDirCache->Control(KEDumpFATDirCache, 0, NULL);
       
  3657 		        }
       
  3658 			break;
  3638 			break;
  3659 			}
  3639 			}
  3660 		case EFATDirCacheInfo:
  3640 		case EFATDirCacheInfo:
  3661 			{
  3641 			{
  3662 			MWTCacheInterface* pDCache = iRawDisk->DirCacheInterface();
  3642 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
  3663 		    if (pDCache)
  3643 		    TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
  3664 		        {
  3644 		    pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
  3665 	            TUint32 KEFATDirCacheInfo = MWTCacheInterface::ECacheInfo;
  3645 			break;
  3666 	            TDirCacheInfo aInfo;
       
  3667 	            TInt r = pDCache->Control(KEFATDirCacheInfo, 0, static_cast<TAny*>(&aInfo));
       
  3668 	            if (r == KErrNone)
       
  3669 	                {
       
  3670 	                TPckgBuf<TDirCacheInfo> pkgBuf(aInfo);
       
  3671 	                r = aMessage.Write(2,pkgBuf);
       
  3672 	                }
       
  3673                 return r;
       
  3674 		        }
       
  3675 		    return KErrNotSupported;
       
  3676 			}
  3646 			}
  3677 
  3647 
  3678 
  3648 
  3679         default: return(KErrNotSupported);
  3649         default: return(KErrNotSupported);
  3680         }
  3650         }
  4098         r = LocalDrive()->Caps(caps);
  4068         r = LocalDrive()->Caps(caps);
  4099         if ( r != KErrNone )
  4069         if ( r != KErrNone )
  4100             User::LeaveIfError(r);
  4070             User::LeaveIfError(r);
  4101         if ( caps().iType&EMediaRam )
  4071         if ( caps().iType&EMediaRam )
  4102             {
  4072             {
  4103             realPosition = FAT().DataPositionInBytes( aPos.iCluster );
  4073             realPosition = FAT().DataPositionInBytesL( aPos.iCluster );
  4104             aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2());
  4074             aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2());
  4105             blockMapEntry.SetStartBlock( aPos.iCluster );
  4075             blockMapEntry.SetStartBlock( aPos.iCluster );
  4106             }
  4076             }
  4107         else
  4077         else
  4108             blockMapEntry.SetStartBlock( aPos.iCluster - 2);
  4078             blockMapEntry.SetStartBlock( aPos.iCluster - 2);
  4211     const TBool bProblemsFound = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4181     const TBool bProblemsFound = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
  4212     
  4182     
  4213     if(bProblemsFound && chkDskRes == CScanDrive::ENoErrors)
  4183     if(bProblemsFound && chkDskRes == CScanDrive::ENoErrors)
  4214         {//-- ScanDrive in this mode can leave unexpectedly without setting an error code that is returned by ProblemsDiscovered();
  4184         {//-- ScanDrive in this mode can leave unexpectedly without setting an error code that is returned by ProblemsDiscovered();
  4215          //-- leave itself means a problem
  4185          //-- leave itself means a problem
  4216         chkDskRes = nScnDrvRes == KErrNone ? CScanDrive::EUnknownError : (CScanDrive::TGenericError) nScnDrvRes;
  4186         chkDskRes = CScanDrive::EUnknownError;
  4217         }
  4187         }
  4218 
  4188 
  4219     delete pScnDrv;
  4189     delete pScnDrv;
  4220     pScnDrv = NULL;
  4190     pScnDrv = NULL;
  4221 
  4191 
  4291         return KErrCorrupt;
  4261         return KErrCorrupt;
  4292 
  4262 
  4293     TInt nRes;
  4263     TInt nRes;
  4294 
  4264 
  4295     if(LockStatus()!=0)
  4265     if(LockStatus()!=0)
  4296         {//-- can't run if the volume has opened objects, like files, directories, formats etc.
  4266         {
  4297 		__PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
  4267 		__PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
  4298         return KErrInUse;
  4268         return KErrInUse;
  4299         }
  4269         }
  4300 
  4270 
  4301     if(iRamDrive)
  4271     if(iRamDrive)