userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
branchRCL_3
changeset 43 c1f20ce4abcf
parent 42 a179b74831c9
child 44 3e88ff8f41d5
--- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp	Thu Aug 19 11:14:22 2010 +0300
+++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp	Tue Aug 31 16:34:26 2010 +0300
@@ -26,6 +26,7 @@
 #include "sl_dir_cache.h"
 #include "sl_scandrv.h"
 #include <hal.h>
+#include <f32dbg.h>
 
 TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively);
 
@@ -550,10 +551,8 @@
         return;
         }
 
-    if(LockStatus() != 0)
-        {//-- can't finalise the volume if it has opened objects and not in the consistent state.
-         //-- Theoretically, we can finalise the mount if we have files opened only for read, but at present,
-         //-- it's impossible to detect such situation.
+    if(Locked())
+        {//-- can't finalise the volume if it has opened disk access objects, like Format or RawAccess
         User::Leave(KErrInUse);
         }
 
@@ -612,10 +611,23 @@
 */
 TBool CFatMountCB::VolCleanFlagSupported() const
     {
-        const TFatType fatType=FatType();
-
-        ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32);
-        return (fatType != EFat12);
+    const TFatType fatType=FatType();
+
+    ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32);
+    return (fatType != EFat12);
+    }
+
+
+//-----------------------------------------------------------------------------------------
+/**
+    @return Volume size in bytes according to the number of usable clusters.
+    This approach is not applicable to RAM drive, because its size isn't fixed and can be adjusted by the system.
+*/
+TUint64 CFatMountCB::VolumeSizeInBytes() const
+    {
+    ASSERT(ConsistentState());
+    ASSERT(!iRamDrive);
+    return ((TUint64)UsableClusters()) << ClusterSizeLog2();
     }
 
 //-----------------------------------------------------------------------------------------
@@ -680,16 +692,21 @@
 
 
     const TUint32 freeClusters = FAT().NumberOfFreeClusters(bSyncOp);
-
+    aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2();
     __PRINT1(_L("CFatMountCB::VolumeL() free clusters:%d"), freeClusters);
 
-    aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2();
-
-    if (drvInfo.iType==EMediaRam)
+
+    if(drvInfo.iType==EMediaRam)
+        {//-- a special case. RAM drive size is variable and adjustable. It should be calculated from aVolume.iFree and CMountCB::iFree
+        ASSERT(iRamDrive);
         aVolume.iSize=aVolume.iFree+iSize;
-
-    aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc
-    aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2();  //-- round down to cluster size
+        aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc
+        aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2();  //-- round down to cluster size
+        }
+    else
+        {//-- normal case; the volume size is determined by amount of usable clusters
+        aVolume.iSize = VolumeSizeInBytes();
+        }
 
     }
 
@@ -1622,7 +1639,7 @@
     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
     const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
-    TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
+    TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
 
     TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag));
 
@@ -1653,7 +1670,7 @@
         if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster))
             { //Copy the contents already present in this cluster to new cluster allocated.
             const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2());
-            dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
+            dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead));
 
 
             //-- Allocate the buffer required to copy the contents from bad cluster
@@ -1682,7 +1699,7 @@
                 {
                 //Calculate and copy the contents to new cluster.
                 aPos.iCluster = goodcluster;
-                dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
+                dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead);
 
                 r = LocalDrive()->Write(dataStart, clustBuf);
                 if(r == KErrNone)
@@ -1790,7 +1807,7 @@
     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
     const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters);
     const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos);
-    const TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos;
+    const TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos;
 
     TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag));
 
@@ -3154,7 +3171,7 @@
         User::Leave(KErrCorrupt);
 
     TBuf8<sizeof(TCheckedUid)> uidBuf;
-    iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf);
+    iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf);
     __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed));
     TCheckedUid uid(uidBuf);
     anEntry.iType=uid.UidType();
@@ -3230,7 +3247,7 @@
 			//  Read the remaining length or the entire cluster block whichever is smaller
 			TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos);
 			__ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed));
-			TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos;
+			TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos;
 			iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0);
 			readTotal += readLength;
 
@@ -3434,7 +3451,7 @@
     if (!IsRootDir(aPos))
         {
         TInt relPos=ClusterRelativePos(aPos.iPos);
-        return FAT().DataPositionInBytesL(aPos.iCluster)+relPos;
+        return FAT().DataPositionInBytes(aPos.iCluster)+relPos;
         }
     if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd())
         User::Leave(KErrDirFull); // Past last root dir entry
@@ -3626,23 +3643,36 @@
 		case EDisableFATDirCache:
 			{
 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
-		    TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache;
+		    TUint32 KEDisableFATDirCache = MWTCacheInterface::EDisableCache;
 		    pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL);
 			break;
 			}
 		case EDumpFATDirCache:
 			{
 		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
-		    TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache;
-		    pDirCache->Control(KEDumpFATDirCache, 0, NULL);
+		    if (pDirCache)
+		        {
+	            TUint32 KEDumpFATDirCache = MWTCacheInterface::EDumpCache;
+	            pDirCache->Control(KEDumpFATDirCache, 0, NULL);
+		        }
 			break;
 			}
 		case EFATDirCacheInfo:
 			{
-		    MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface();
-		    TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo;
-		    pDirCache->Control(KEFATDirCacheInfo, 0, NULL);
-			break;
+			MWTCacheInterface* pDCache = iRawDisk->DirCacheInterface();
+		    if (pDCache)
+		        {
+	            TUint32 KEFATDirCacheInfo = MWTCacheInterface::ECacheInfo;
+	            TDirCacheInfo aInfo;
+	            TInt r = pDCache->Control(KEFATDirCacheInfo, 0, static_cast<TAny*>(&aInfo));
+	            if (r == KErrNone)
+	                {
+	                TPckgBuf<TDirCacheInfo> pkgBuf(aInfo);
+	                r = aMessage.Write(2,pkgBuf);
+	                }
+                return r;
+		        }
+		    return KErrNotSupported;
 			}
 
 
@@ -4070,7 +4100,7 @@
             User::LeaveIfError(r);
         if ( caps().iType&EMediaRam )
             {
-            realPosition = FAT().DataPositionInBytesL( aPos.iCluster );
+            realPosition = FAT().DataPositionInBytes( aPos.iCluster );
             aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2());
             blockMapEntry.SetStartBlock( aPos.iCluster );
             }
@@ -4183,7 +4213,7 @@
     if(bProblemsFound && chkDskRes == CScanDrive::ENoErrors)
         {//-- ScanDrive in this mode can leave unexpectedly without setting an error code that is returned by ProblemsDiscovered();
          //-- leave itself means a problem
-        chkDskRes = CScanDrive::EUnknownError;
+        chkDskRes = nScnDrvRes == KErrNone ? CScanDrive::EUnknownError : (CScanDrive::TGenericError) nScnDrvRes;
         }
 
     delete pScnDrv;
@@ -4263,7 +4293,7 @@
     TInt nRes;
 
     if(LockStatus()!=0)
-        {
+        {//-- can't run if the volume has opened objects, like files, directories, formats etc.
 		__PRINT(_L("CFatMountCB::ScanDrive() locked!\n"));
         return KErrInUse;
         }