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