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 |