userlibandfileserver/fileserver/sfat/sl_file.cpp
changeset 2 4122176ea935
parent 0 a41df078684a
equal deleted inserted replaced
0:a41df078684a 2:4122176ea935
    13 // Description:
    13 // Description:
    14 // f32\sfat\sl_file.cpp
    14 // f32\sfat\sl_file.cpp
    15 // 
    15 // 
    16 //
    16 //
    17 
    17 
       
    18 
       
    19 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    20 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    21 //!!
       
    22 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
       
    23 //!!
       
    24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    25 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    26 
       
    27 
    18 #include "sl_std.h"
    28 #include "sl_std.h"
    19 #include "sl_cache.h"
    29 #include "sl_cache.h"
    20 #include <e32math.h>
    30 #include <e32math.h>
    21 
    31 
    22 const TInt KSeekIndexSize=128; // Cache 128 clusters
    32 const TInt KSeekIndexSize=128; // Cache 128 clusters
    23 const TInt KSeekIndexSizeLog2=7;
    33 const TInt KSeekIndexSizeLog2=7;
    24 const TInt KFirstClusterNum=2;
    34 const TInt KFirstClusterNum=2;
    25 
    35 
    26 CFatFileCB::CFatFileCB()
    36 CFatFileCB::CFatFileCB()
    27 	{
    37     {
    28 
    38 
    29 	__PRINT1(_L("CFatFileCB created 0x%x"),this);
    39     __PRINT1(_L("CFatFileCB created 0x%x"),this);
    30 	}
    40     }
    31 
    41 
    32 CFatFileCB::~CFatFileCB()
    42 CFatFileCB::~CFatFileCB()
    33 	{
    43     {
    34 	__PRINT1(_L("CFatFileCB deleted 0x%x"),this);
    44     __PRINT1(_L("CFatFileCB deleted 0x%x"),this);
    35 
    45 
    36     //-- a nasty trick to find out if the CFatFileCB is in consistent state on the moment of destruction.
    46     //-- a nasty trick to find out if the CFatFileCB is in consistent state on the moment of destruction.
    37     //-- Because of OOM conditions CFatFileCB might not be fully constructed and to be deleted, while FlushAll()
    47     //-- Because of OOM conditions CFatFileCB might not be fully constructed and to be deleted, while FlushAll()
    38     //-- implies valid iMount.
    48     //-- implies valid iMount.
    39     const CMountCB* pMount  = &Mount();
    49     const CMountCB* pMount  = &Mount();
    42         if (iAtt&KEntryAttModified)
    52         if (iAtt&KEntryAttModified)
    43             TRAP_IGNORE(FlushAllL());
    53             TRAP_IGNORE(FlushAllL());
    44         }
    54         }
    45 
    55 
    46     delete[] iSeekIndex;
    56     delete[] iSeekIndex;
    47 	}
    57     }
    48 
    58 
    49 
    59 
    50 void CFatFileCB::CreateSeekIndex()
    60 void CFatFileCB::CreateSeekIndex()
    51 //
    61 //
    52 // Create a seek index
    62 // Create a seek index
    53 //
    63 //
    54 	{
    64     {
    55 
    65 
    56 	iSeekIndex = new TUint32[KSeekIndexSize];
    66     iSeekIndex = new TUint32[KSeekIndexSize];
    57 	if (iSeekIndex == NULL)
    67     if (iSeekIndex == NULL)
    58 		return;
    68         return;
    59 
    69 
    60 	Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize);
    70     Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize);
    61 
    71 
    62 	iSeekIndexSize=CalcSeekIndexSize(Size());
    72     iSeekIndexSize=CalcSeekIndexSize(Size());
    63 	}
    73     }
    64 
    74 
    65 TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset)
    75 TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset)
    66 //
    76 //
    67 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster
    77 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster
    68 // Return aNewRelCluster-aCurrentPos.iCluster
    78 // Return aNewRelCluster-aCurrentPos.iCluster
    69 //
    79 //
    70 	{
    80     {
    71 	TInt clusterOffset=aClusterOffset;
    81     TInt clusterOffset=aClusterOffset;
    72 	TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1;
    82     TInt seekPos=(aNewRelCluster>>iSeekIndexSize)-1;
    73 	__ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall));
    83     __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall));
    74 
    84 
    75 	while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0)
    85     while(seekPos>=0 && iSeekIndex[seekPos]==0 && clusterOffset!=0)
    76 		{
    86         {
    77 		seekPos--;
    87         seekPos--;
    78 		clusterOffset--;
    88         clusterOffset--;
    79 		}
    89         }
    80 	if (clusterOffset==0) // Counted back to the current cluster
    90     if (clusterOffset==0) // Counted back to the current cluster
    81 		return(aClusterOffset);
    91         return(aClusterOffset);
    82 	if (seekPos<0)
    92     if (seekPos<0)
    83 		{
    93         {
    84 		iCurrentPos.iCluster=iStartCluster;
    94         iCurrentPos.iCluster=iStartCluster;
    85 		return(aNewRelCluster);
    95         return(aNewRelCluster);
    86 		}
    96         }
    87 
    97 
    88 	iCurrentPos.iCluster=iSeekIndex[seekPos];
    98     iCurrentPos.iCluster=iSeekIndex[seekPos];
    89 	return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize));
    99     return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize));
    90 	}
   100     }
    91 
   101 
    92 void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster)
   102 void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster)
    93 //
   103 //
    94 // Sets a value in the seekindex
   104 // Sets a value in the seekindex
    95 //
   105 //
    96 	{
   106     {
    97 
   107 
    98 	TInt seekPos=(aRelCluster>>iSeekIndexSize)-1;
   108     TInt seekPos=(aRelCluster>>iSeekIndexSize)-1;
    99 	__ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall));
   109     __ASSERT_DEBUG(seekPos<KSeekIndexSize,Fault(EFatFileSeekIndexTooSmall));
   100 	__ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2));
   110     __ASSERT_DEBUG(seekPos>=0,Fault(EFatFileSeekIndexTooSmall2));
   101 	iSeekIndex[seekPos] = aStoredCluster;
   111     iSeekIndex[seekPos] = aStoredCluster;
   102 	}
   112     }
   103 
   113 
   104 TBool CFatFileCB::IsSeekBackwards(TUint aPos)
   114 TBool CFatFileCB::IsSeekBackwards(TUint aPos)
   105 //
   115 //
   106 // Return true if aPos<currentPos
   116 // Return true if aPos<currentPos
   107 //
   117 //
   108 	{
   118     {
   109 	
   119     
   110 	TUint cluster=iCurrentPos.iCluster<<ClusterSizeLog2();
   120     TUint cluster=iCurrentPos.iCluster<<ClusterSizeLog2();
   111 	TInt offset=ClusterRelativePos(iCurrentPos.iPos);
   121     TInt offset=ClusterRelativePos(iCurrentPos.iPos);
   112 	TUint currentPos=cluster+offset;
   122     TUint currentPos=cluster+offset;
   113 	return(aPos<currentPos);
   123     return(aPos<currentPos);
   114 	}
   124     }
   115 
   125 
   116 void CFatFileCB::CheckPosL(TUint aPos)
   126 void CFatFileCB::CheckPosL(TUint aPos)
   117 //
   127 //
   118 // Check that the file is positioned correctly.
   128 // Check that the file is positioned correctly.
   119 // If aPos<currentPos attempt to guess the new position.
   129 // If aPos<currentPos attempt to guess the new position.
   120 //
   130 //
   121 	{
   131     {
   122 	__PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos);
   132     __PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos);
   123 	if (aPos==iCurrentPos.iPos)
   133     if (aPos==iCurrentPos.iPos)
   124 		return;
   134         return;
   125     __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd));
   135     __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd));
   126 
   136 
   127 	if (iFileSizeModified && IsSeekBackwards(aPos))
   137     if (iFileSizeModified && IsSeekBackwards(aPos))
   128 		FlushDataL(); 
   138         FlushDataL(); 
   129 	
   139     
   130 	TUint newRelCluster=aPos>>ClusterSizeLog2();
   140     TUint newRelCluster=aPos>>ClusterSizeLog2();
   131 	if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) )
   141     if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) )
   132 		newRelCluster--;
   142         newRelCluster--;
   133 	TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2();
   143     TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2();
   134 	if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) )
   144     if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) )
   135 		oldRelCluster--;	
   145         oldRelCluster--;    
   136 	TInt clusterOffset=newRelCluster-oldRelCluster;
   146     TInt clusterOffset=newRelCluster-oldRelCluster;
   137 	TInt oldCluster=iCurrentPos.iCluster;
   147     TInt oldCluster=iCurrentPos.iCluster;
   138 	iCurrentPos.iPos=aPos;
   148     iCurrentPos.iPos=aPos;
   139 	if (clusterOffset==0)
   149     if (clusterOffset==0)
   140 		return;
   150         return;
   141 	TInt seekOffset=clusterOffset;
   151     TInt seekOffset=clusterOffset;
   142 	if (iSeekIndex!=NULL)
   152     if (iSeekIndex!=NULL)
   143 		{ // Can alter iCurrentPos.iCluster
   153         { // Can alter iCurrentPos.iCluster
   144 		seekOffset=SeekToPosition(newRelCluster,seekOffset);
   154         seekOffset=SeekToPosition(newRelCluster,seekOffset);
   145 		if (seekOffset==0)
   155         if (seekOffset==0)
   146 			return;
   156             return;
   147 		}
   157         }
   148 	if (clusterOffset==-1 && seekOffset!=1)
   158     if (clusterOffset==-1 && seekOffset!=1)
   149 		{ // Check previous cluster
   159         { // Check previous cluster
   150 		TInt cluster=oldCluster-1;
   160         TInt cluster=oldCluster-1;
   151 		if (FAT().GetNextClusterL(cluster) && cluster==oldCluster)
   161         if (FAT().GetNextClusterL(cluster) && cluster==oldCluster)
   152 			{
   162             {
   153             iCurrentPos.iCluster=oldCluster-1;
   163             iCurrentPos.iCluster=oldCluster-1;
   154 			return;
   164             return;
   155 			}
   165             }
   156 		}
   166         }
   157 	if (seekOffset<0)
   167     if (seekOffset<0)
   158 		{
   168         {
   159 		seekOffset=newRelCluster;
   169         seekOffset=newRelCluster;
   160 		iCurrentPos.iCluster=iStartCluster;
   170         iCurrentPos.iCluster=iStartCluster;
   161 		}
   171         }
   162 	while (seekOffset--)
   172     while (seekOffset--)
   163 		{
   173         {
   164         if (!FAT().GetNextClusterL(iCurrentPos.iCluster))
   174         if (!FAT().GetNextClusterL(iCurrentPos.iCluster))
   165             {
   175             {
   166             __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1"));
   176             __PRINT(_L("CFatFileCB::CheckPosL() corrupt#1"));
   167             User::Leave(KErrCorrupt);
   177             User::Leave(KErrCorrupt);
   168             }
   178             }
   169         TInt cluster=newRelCluster-seekOffset;
   179         TInt cluster=newRelCluster-seekOffset;
   170 		if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster)
   180         if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster)
   171 			SetSeekIndexValueL(cluster,iCurrentPos.iCluster);
   181             SetSeekIndexValueL(cluster,iCurrentPos.iCluster);
   172 		}
   182         }
   173 	}
   183     }
   174 
   184 
   175 void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos)
   185 void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos)
   176 //
   186 //
   177 // Initialize FileCB from entry data
   187 // Initialize FileCB from entry data
   178 //
   188 //
   179 	{
   189     {
   180 
   190 
   181 	__PRINT(_L("CFatFileCB::SetL"));
   191     __PRINT(_L("CFatFileCB::SetL"));
   182 	SetSize(aFatDirEntry.Size()); 
   192     SetSize(aFatDirEntry.Size()); 
   183 	iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry);
   193     iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry);
   184 	iStartCluster=iCurrentPos.iCluster;
   194     iStartCluster=iCurrentPos.iCluster;
   185 	iCurrentPos.iPos=0;
   195     iCurrentPos.iPos=0;
   186 	iAtt=aFatDirEntry.Attributes();
   196     iAtt=aFatDirEntry.Attributes();
   187 	iModified= aFatDirEntry.Time(FatMount().TimeOffset());
   197     iModified= aFatDirEntry.Time(FatMount().TimeOffset());
   188 	iShare=aShare;
   198     iShare=aShare;
   189 	iFileDirPos=aPos;
   199     iFileDirPos=aPos;
   190 
   200 
   191     SetMaxSupportedSize(KMaxSupportedFatFileSize);
   201     SetMaxSupportedSize(KMaxSupportedFatFileSize);
   192 	}
   202     }
   193 
   203 
   194 //-----------------------------------------------------------------------------
   204 //-----------------------------------------------------------------------------
   195 // from CFileCB::MExtendedFileInterface
   205 // from CFileCB::MExtendedFileInterface
   196 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset)
   206 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset)
   197 	{
   207     {
   198 	__PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength);
   208     __PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength);
   199 	
   209     
   200     if((TUint64)aPos > KMaxSupportedFatFileSize-1)
   210     if((TUint64)aPos > KMaxSupportedFatFileSize-1)
   201         User::Leave(KErrNotSupported);  //-- max. position in the file is 0xFFFFFFFE
   211         User::Leave(KErrNotSupported);  //-- max. position in the file is 0xFFFFFFFE
   202 
   212 
   203     FatMount().CheckStateConsistentL();
   213     FatMount().CheckStateConsistentL();
   204     
   214     
   205 	CheckPosL(I64LOW(aPos));
   215     CheckPosL(I64LOW(aPos));
   206 	
   216     
   207 	const TUint startPos = iCurrentPos.iPos;
   217     const TUint startPos = iCurrentPos.iPos;
   208 	const TUint curSize  = (TUint)Size();
   218     const TUint curSize  = (TUint)Size();
   209 	const TUint length   = (TUint)aLength;
   219     const TUint length   = (TUint)aLength;
   210 	
   220     
   211 	if((startPos + length > curSize) || (startPos > startPos + length) )
   221     if((startPos + length > curSize) || (startPos > startPos + length) )
   212 		aLength=curSize-startPos;
   222         aLength=curSize-startPos;
   213 	
   223     
   214     FatMount().ReadFromClusterListL(iCurrentPos,aLength,aDes,aMessage,aOffset);
   224     FatMount().ReadFromClusterListL(iCurrentPos,aLength,aDes,aMessage,aOffset);
   215 	aLength=iCurrentPos.iPos-startPos;
   225     aLength=iCurrentPos.iPos-startPos;
   216 	}
   226     }
   217 
   227 
   218 
   228 
   219 void CFatFileCB::ReadL(TInt aFilePos,TInt& aLength,const TAny* aTrg,const RMessagePtr2& aMessage)
   229 void CFatFileCB::ReadL(TInt aFilePos,TInt& aLength,const TAny* aTrg,const RMessagePtr2& aMessage)
   220 	{
   230     {
   221 	ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0);
   231     ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0);
   222 	}
   232     }
   223 
   233 
   224 //-----------------------------------------------------------------------------
   234 //-----------------------------------------------------------------------------
   225 // from CFileCB::MExtendedFileInterface
   235 // from CFileCB::MExtendedFileInterface
   226 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset)
   236 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset)
   227 	{
   237     {
   228 	__PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength);
   238     __PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength);
   229 	// FAT supports 32 bits only for file size
   239     // FAT supports 32 bits only for file size
   230    	TUint64 endPos = aPos + aLength;
   240     TUint64 endPos = aPos + aLength;
   231    	if(endPos > KMaxSupportedFatFileSize)
   241     if(endPos > KMaxSupportedFatFileSize)
   232    		User::Leave(KErrNotSupported);
   242         User::Leave(KErrNotSupported);
   233    	
   243     
   234     FatMount().CheckStateConsistentL();
   244     FatMount().CheckStateConsistentL();
   235     FatMount().CheckWritableL();
   245     FatMount().CheckWritableL();
   236     const TUint pos = I64LOW(aPos);
   246     const TUint pos = I64LOW(aPos);
   237   	CheckPosL(pos);
   247     CheckPosL(pos);
   238   	
   248     
   239 	const TUint startCluster = (TUint)iStartCluster;
   249     const TUint startCluster = (TUint)iStartCluster;
   240 	const TUint length       = (TUint)aLength;
   250     const TUint length       = (TUint)aLength;
   241 	
   251     
   242 	endPos = iCurrentPos.iPos + length; 
   252     endPos = iCurrentPos.iPos + length; 
   243 	if ((endPos           > (TUint)Size()) ||
   253     if ((endPos           > (TUint)Size()) ||
   244 	    (iCurrentPos.iPos > endPos)         ) // Overflow condition 
   254         (iCurrentPos.iPos > endPos)         ) // Overflow condition 
   245 		DoSetSizeL(iCurrentPos.iPos+length,EFalse);
   255         DoSetSizeL(iCurrentPos.iPos+length,EFalse);
   246    	
   256     
   247 	TUint startPos=iCurrentPos.iPos;
   257     TUint startPos=iCurrentPos.iPos;
   248 	TInt badcluster=0;
   258     TInt badcluster=0;
   249 	TInt goodcluster=0;
   259     TInt goodcluster=0;
   250    	
   260     
   251 	TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster));
   261     TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster));
   252    	
   262     
   253 	if (ret == KErrCorrupt || ret == KErrDied)
   263     if (ret == KErrCorrupt || ret == KErrDied)
   254 		{
   264         {
   255         if(startCluster == 0)
   265         if(startCluster == 0)
   256 			{ //Empty File, revert all the clusters allocated.
   266             { //Empty File, revert all the clusters allocated.
   257 			TInt cluster = iStartCluster;
   267             TInt cluster = iStartCluster;
   258 			iStartCluster = 0;
   268             iStartCluster = 0;
   259 			SetSize(0);
   269             SetSize(0);
   260 			FlushAllL();
   270             FlushAllL();
   261 
   271 
   262 			iCurrentPos.iCluster = 0;
   272             iCurrentPos.iCluster = 0;
   263 			iCurrentPos.iPos = 0;
   273             iCurrentPos.iPos = 0;
   264 
   274 
   265 			FAT().FreeClusterListL(cluster);
   275             FAT().FreeClusterListL(cluster);
   266 			FAT().FlushL();
   276             FAT().FlushL();
   267 			}
   277             }
   268 		else
   278         else
   269 			{ //Calculate the clusters required based on file size, revert extra clusters if allocated.
   279             { //Calculate the clusters required based on file size, revert extra clusters if allocated.
   270 			const TUint curSize = (TUint)Size();
   280             const TUint curSize = (TUint)Size();
   271 			TUint ClustersNeeded = curSize >> ClusterSizeLog2();
   281             TUint ClustersNeeded = curSize >> ClusterSizeLog2();
   272 			if(curSize > (ClustersNeeded << ClusterSizeLog2()))
   282             if(curSize > (ClustersNeeded << ClusterSizeLog2()))
   273 				{
   283                 {
   274 				ClustersNeeded++;
   284                 ClustersNeeded++;
   275 				}
   285                 }
   276 
   286 
   277 			TInt cluster = iStartCluster;
   287             TInt cluster = iStartCluster;
   278 			while(--ClustersNeeded)
   288             while(--ClustersNeeded)
   279 				{
   289                 {
   280 				FAT().GetNextClusterL(cluster);
   290                 FAT().GetNextClusterL(cluster);
   281 				}
   291                 }
   282                 
   292                 
   283 			iCurrentPos.iCluster = cluster;
   293             iCurrentPos.iCluster = cluster;
   284 
   294 
   285 			if (FAT().GetNextClusterL(cluster))
   295             if (FAT().GetNextClusterL(cluster))
   286 				{
   296                 {
   287 				FAT().FreeClusterListL(cluster);
   297                 FAT().FreeClusterListL(cluster);
   288 				}
   298                 }
   289 
   299 
   290 			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
   300             FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
   291 			FAT().FlushL();
   301             FAT().FlushL();
   292 			}
   302             }
   293 		}
   303         }
   294 
   304 
   295 	User::LeaveIfError(ret);
   305     User::LeaveIfError(ret);
   296 
   306 
   297 	if(badcluster != 0)
   307     if(badcluster != 0)
   298 		{
   308         {
   299 		if(iStartCluster == badcluster)
   309         if(iStartCluster == badcluster)
   300 			{
   310             {
   301 			iStartCluster = goodcluster;
   311             iStartCluster = goodcluster;
   302 			FlushStartClusterL();
   312             FlushStartClusterL();
   303 			}
   313             }
   304 		else
   314         else
   305 			{
   315             {
   306 			TInt aCluster = iStartCluster;
   316             TInt aCluster = iStartCluster;
   307 			do
   317             do
   308 				{
   318                 {
   309                 if((TUint)badcluster == FAT().ReadL(aCluster))
   319                 if((TUint)badcluster == FAT().ReadL(aCluster))
   310 					{
   320                     {
   311 					FAT().WriteL(aCluster, goodcluster);
   321                     FAT().WriteL(aCluster, goodcluster);
   312 					FAT().FlushL();
   322                     FAT().FlushL();
   313 					break;
   323                     break;
   314 					}
   324                     }
   315 				}
   325                 }
   316 			while(FAT().GetNextClusterL(aCluster));
   326             while(FAT().GetNextClusterL(aCluster));
   317 			}
   327             }
   318 		}
   328         }
   319 	aLength=iCurrentPos.iPos-startPos;
   329     aLength=iCurrentPos.iPos-startPos;
   320 
   330 
   321 	if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size())
   331     if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size())
   322 		{
   332         {
   323 		WriteFileSizeL(pos+aLength);
   333         WriteFileSizeL(pos+aLength);
   324 		}
   334         }
   325 
   335 
   326 	}
   336     }
   327 
   337 
   328 
   338 
   329 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage)
   339 void CFatFileCB::WriteL(TInt aFilePos,TInt& aLength,const TAny* aSrc,const RMessagePtr2& aMessage)
   330 	{
   340     {
   331 	WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0);
   341     WriteL(TInt64(aFilePos),aLength,(TDesC8*) aSrc,aMessage, 0);
   332 	}
   342     }
   333 
   343 
   334 
   344 
   335 
   345 
   336 //-----------------------------------------------------------------------------
   346 //-----------------------------------------------------------------------------
   337 
   347 
   338 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize)
   348 void CFatFileCB::ResizeIndex(TInt aNewMult,TUint aNewSize)
   339 //
   349 //
   340 // Resize the seek index to accomodate a larger or smaller filesize
   350 // Resize the seek index to accomodate a larger or smaller filesize
   341 // Assumes KSeekIndexSize is a power of 2.
   351 // Assumes KSeekIndexSize is a power of 2.
   342 //
   352 //
   343 	{
   353     {
   344 
   354 
   345 	TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult);
   355     TInt maxNewIndex=aNewSize>>(ClusterSizeLog2()+aNewMult);
   346 
   356 
   347 
   357 
   348 	TInt    index=0;
   358     TInt    index=0;
   349 	TInt	indexEnd=KSeekIndexSize;
   359     TInt    indexEnd=KSeekIndexSize;
   350 	TInt	newValEnd=maxNewIndex;
   360     TInt    newValEnd=maxNewIndex;
   351 
   361 
   352 	if (iSeekIndexSize<aNewMult)
   362     if (iSeekIndexSize<aNewMult)
   353 		{
   363         {
   354 		TInt newVal=index;
   364         TInt newVal=index;
   355 		TInt step=1<<(aNewMult-iSeekIndexSize);
   365         TInt step=1<<(aNewMult-iSeekIndexSize);
   356 		index+=step-1;
   366         index+=step-1;
   357 		while(index<indexEnd && newVal<newValEnd)
   367         while(index<indexEnd && newVal<newValEnd)
   358 			{
   368             {
   359 			iSeekIndex[newVal] =  iSeekIndex[index];
   369             iSeekIndex[newVal] =  iSeekIndex[index];
   360 			newVal++;
   370             newVal++;
   361 			index+=step;
   371             index+=step;
   362 			}
   372             }
   363 		while(newVal<indexEnd)
   373         while(newVal<indexEnd)
   364 			iSeekIndex[newVal++] =  0;
   374             iSeekIndex[newVal++] =  0;
   365 		}
   375         }
   366 	else
   376     else
   367 		{
   377         {
   368 		TInt diffSize = iSeekIndexSize-aNewMult;
   378         TInt diffSize = iSeekIndexSize-aNewMult;
   369 		TInt oldVal=(KSeekIndexSize>>diffSize) - 1;
   379         TInt oldVal=(KSeekIndexSize>>diffSize) - 1;
   370 		TInt newVal=indexEnd-1;
   380         TInt newVal=indexEnd-1;
   371 		TInt skip=(1<<diffSize)-1;
   381         TInt skip=(1<<diffSize)-1;
   372 
   382 
   373 		if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2)
   383         if ((iSeekIndexSize - aNewMult) > KSeekIndexSizeLog2)
   374 			{
   384             {
   375             ClearIndex(0); //-- Invalidate every entry.
   385             ClearIndex(0); //-- Invalidate every entry.
   376 			}
   386             }
   377 		else
   387         else
   378 			{
   388             {
   379 			while(newVal>=index)
   389             while(newVal>=index)
   380 				{
   390                 {
   381 
   391 
   382 				iSeekIndex[newVal--] =  iSeekIndex[oldVal--];
   392                 iSeekIndex[newVal--] =  iSeekIndex[oldVal--];
   383 
   393 
   384 
   394 
   385 				for(TInt i=skip;i>0;i--)
   395                 for(TInt i=skip;i>0;i--)
   386 					{	
   396                     {   
   387 					iSeekIndex[newVal--] = 0;
   397                     iSeekIndex[newVal--] = 0;
   388 
   398 
   389 					}
   399                     }
   390 				}
   400                 }
   391 			}
   401             }
   392 		}
   402         }
   393 	iSeekIndexSize=aNewMult;
   403     iSeekIndexSize=aNewMult;
   394 	}
   404     }
   395 
   405 
   396 
   406 
   397 /**
   407 /**
   398     Zero freed clusters in the index
   408     Zero freed clusters in the index
   399 
   409 
   400     @param  aNewSize new size of the file that the index corresponds to.
   410     @param  aNewSize new size of the file that the index corresponds to.
   401             if = 0  all existing index will be zero filled
   411             if = 0  all existing index will be zero filled
   402 */ 
   412 */ 
   403 void CFatFileCB::ClearIndex(TUint aNewSize)
   413 void CFatFileCB::ClearIndex(TUint aNewSize)
   404 	{
   414     {
   405 
   415 
   406 	if (!iSeekIndex)
   416     if (!iSeekIndex)
   407 	    return;
   417         return;
   408 
   418 
   409     if(aNewSize==0)
   419     if(aNewSize==0)
   410     	{
   420         {
   411     	//-- zero fill all the array
   421         //-- zero fill all the array
   412         Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32));
   422         Mem::FillZ(iSeekIndex, KSeekIndexSize*sizeof(TUint32));
   413 		return;
   423         return;
   414     	}
   424         }
   415 
   425 
   416 	// Files that fill up a cluster exactly do not have a trailing empty
   426     // Files that fill up a cluster exactly do not have a trailing empty
   417 	// cluster. So the entry for that position must also be invalidated
   427     // cluster. So the entry for that position must also be invalidated
   418 	aNewSize--;
   428     aNewSize--;
   419 	TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2());
   429     TInt firstInvalidIndex=aNewSize>>(iSeekIndexSize+ClusterSizeLog2());
   420 		
   430         
   421 	TInt indexLen=KSeekIndexSize-firstInvalidIndex;
   431     TInt indexLen=KSeekIndexSize-firstInvalidIndex;
   422 
   432 
   423 	Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32));
   433     Mem::FillZ(iSeekIndex+firstInvalidIndex, indexLen * sizeof(TUint32));
   424 	}
   434     }
   425 
   435 
   426 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize)
   436 TInt CFatFileCB::CalcSeekIndexSize(TUint aSize)
   427 //
   437 //
   428 // Find the nearest power of 2 > aSize
   438 // Find the nearest power of 2 > aSize
   429 //
   439 //
   430 	{
   440     {
   431 	TInt count = 0;
   441     TInt count = 0;
   432 	const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128
   442     const TUint indexSize=KSeekIndexSize<<ClusterSizeLog2();//KSeekIndexSize=128
   433 	if (aSize<=indexSize)
   443     if (aSize<=indexSize)
   434 	  return(count);
   444       return(count);
   435 	
   445     
   436 	while((aSize>>=1)>0)
   446     while((aSize>>=1)>0)
   437 		{
   447         {
   438 		count++;
   448         count++;
   439 		}
   449         }
   440 	return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1);
   450     return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1);
   441 	}
   451     }
   442 
   452 
   443 //-----------------------------------------------------------------------------
   453 //-----------------------------------------------------------------------------
   444 
   454 
   445 void CFatFileCB::SetSizeL(TInt64 aSize)
   455 void CFatFileCB::SetSizeL(TInt64 aSize)
   446 	{
   456     {
   447 	__PRINT(_L("CFatFileCB::SetSizeL"));
   457     __PRINT(_L("CFatFileCB::SetSizeL"));
   448 	
   458     
   449 	// FAT supports 32 bits only for file size
   459     // FAT supports 32 bits only for file size
   450 	if (I64HIGH(aSize))
   460     if (I64HIGH(aSize))
   451 		User::Leave(KErrNotSupported);
   461         User::Leave(KErrNotSupported);
   452 
   462 
   453 	if(FatMount().IsRuggedFSys())
   463     if(FatMount().IsRuggedFSys())
   454 		DoSetSizeL(I64LOW(aSize),ETrue);
   464         DoSetSizeL(I64LOW(aSize),ETrue);
   455 	else
   465     else
   456 		DoSetSizeL(I64LOW(aSize),EFalse);
   466         DoSetSizeL(I64LOW(aSize),EFalse);
   457 	}
   467     }
   458 
   468 
   459 
   469 
   460 void CFatFileCB::SetSizeL(TInt aSize)
   470 void CFatFileCB::SetSizeL(TInt aSize)
   461 //
   471 //
   462 // Envelope function around DoSetSizeL to enable aSize to
   472 // Envelope function around DoSetSizeL to enable aSize to
   463 // be written to disk for rugged fat file system
   473 // be written to disk for rugged fat file system
   464 //
   474 //
   465 	{
   475     {
   466 	SetSizeL(TInt64(aSize));
   476     SetSizeL(TInt64(aSize));
   467 	}
   477     }
   468 
   478 
   469 void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite)
   479 void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite)
   470 //
   480 //
   471 // Extend or truncate the file.
   481 // Extend or truncate the file.
   472 // Expects the modified attribute and iSize are set afterwards.
   482 // Expects the modified attribute and iSize are set afterwards.
   473 // Does not alter iCurrentPos, the current file position.
   483 // Does not alter iCurrentPos, the current file position.
   474 // Writes size of file to disk if aIsSizeWrite set
   484 // Writes size of file to disk if aIsSizeWrite set
   475 //
   485 //
   476 	{
   486     {
   477 	__PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite);
   487     __PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite);
   478 
   488 
   479     FatMount().CheckStateConsistentL();
   489     FatMount().CheckStateConsistentL();
   480     FatMount().CheckWritableL();
   490     FatMount().CheckWritableL();
   481 
   491 
   482 	
   492     
   483 	// Can not change the file size if it is clamped
   493     // Can not change the file size if it is clamped
   484 	if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0)
   494     if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0)
   485 		User::Leave(KErrInUse);
   495         User::Leave(KErrInUse);
   486 	
   496     
   487 	iFileSizeModified=ETrue;
   497     iFileSizeModified=ETrue;
   488 
   498 
   489 	TInt newIndexMult=CalcSeekIndexSize(aSize);
   499     TInt newIndexMult=CalcSeekIndexSize(aSize);
   490 	if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize)
   500     if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize)
   491 		ResizeIndex(newIndexMult,aSize);
   501         ResizeIndex(newIndexMult,aSize);
   492 	if (aSize == 0)
   502     if (aSize == 0)
   493 		{
   503         {
   494 		if (Size() != 0)
   504         if (Size() != 0)
   495 			{
   505             {
   496             ClearIndex(0); //-- clear seek index array
   506             ClearIndex(0); //-- clear seek index array
   497 			TInt cluster=iStartCluster;
   507             TInt cluster=iStartCluster;
   498 			iStartCluster = 0;
   508             iStartCluster = 0;
   499 			SetSize(0);
   509             SetSize(0);
   500 			FlushAllL();
   510             FlushAllL();
   501 			CheckPosL(0);
   511             CheckPosL(0);
   502 			FAT().FreeClusterListL(cluster);
   512             FAT().FreeClusterListL(cluster);
   503 			FAT().FlushL();
   513             FAT().FlushL();
   504 			}
   514             }
   505 		return;
   515         return;
   506 		}
   516         }
   507 	if (aSize<(TUint)Size())
   517     if (aSize<(TUint)Size())
   508 		{
   518         {
   509 		if(aIsSizeWrite)		// write file size if decreasing
   519         if(aIsSizeWrite)        // write file size if decreasing
   510 				WriteFileSizeL(aSize);
   520                 WriteFileSizeL(aSize);
   511 		CheckPosL(aSize);
   521         CheckPosL(aSize);
   512 		TInt cluster=iCurrentPos.iCluster;
   522         TInt cluster=iCurrentPos.iCluster;
   513 		if (FAT().GetNextClusterL(cluster))
   523         if (FAT().GetNextClusterL(cluster))
   514 			{
   524             {
   515 			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
   525             FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
   516 			FAT().FreeClusterListL(cluster);
   526             FAT().FreeClusterListL(cluster);
   517 			}
   527             }
   518 		ClearIndex(aSize);
   528         ClearIndex(aSize);
   519 		FAT().FlushL();
   529         FAT().FlushL();
   520 		return;
   530         return;
   521 		}
   531         }
   522 	
   532     
   523 	TUint newSize=aSize>>ClusterSizeLog2();	//	Number of clusters we now need
   533     TUint newSize=aSize>>ClusterSizeLog2(); //  Number of clusters we now need
   524 	if (aSize > (newSize<<ClusterSizeLog2()))
   534     if (aSize > (newSize<<ClusterSizeLog2()))
   525 		newSize++;	//	File size is not an exact multiple of cluster size
   535         newSize++;  //  File size is not an exact multiple of cluster size
   526 					//	Increment the number of clusters required to accomodate tail
   536                     //  Increment the number of clusters required to accomodate tail
   527 	
   537     
   528 	if (iStartCluster==0)
   538     if (iStartCluster==0)
   529 		{
   539         {
   530         //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
   540         //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
   531         ClearIndex(0); //-- clear seek index array
   541         ClearIndex(0); //-- clear seek index array
   532         TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint());
   542         TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint());
   533 		FAT().FlushL();
   543         FAT().FlushL();
   534 		iCurrentPos.iCluster=tempStartCluster;
   544         iCurrentPos.iCluster=tempStartCluster;
   535 		iStartCluster=tempStartCluster;
   545         iStartCluster=tempStartCluster;
   536 		SetSize(aSize);
   546         SetSize(aSize);
   537 		FlushAllL();
   547         FlushAllL();
   538 		}
   548         }
   539 	else
   549     else
   540 		{
   550         {
   541 		const TUint curSize = (TUint)Size(); 
   551         const TUint curSize = (TUint)Size(); 
   542 		TUint oldSize=curSize>>ClusterSizeLog2();	//	Number of clusters we had previously
   552         TUint oldSize=curSize>>ClusterSizeLog2();   //  Number of clusters we had previously
   543 		if (curSize>(oldSize<<ClusterSizeLog2()))
   553         if (curSize>(oldSize<<ClusterSizeLog2()))
   544 			oldSize++;
   554             oldSize++;
   545 	
   555     
   546 		TInt newClusters=newSize-oldSize;	//	Number of clusters we need to prepare
   556         TInt newClusters=newSize-oldSize;   //  Number of clusters we need to prepare
   547 		if (newClusters)
   557         if (newClusters)
   548 			{
   558             {
   549 			TEntryPos currentPos=iCurrentPos;
   559             TEntryPos currentPos=iCurrentPos;
   550 			CheckPosL(Size());
   560             CheckPosL(Size());
   551 			FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
   561             FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
   552 			iCurrentPos=currentPos;
   562             iCurrentPos=currentPos;
   553 			}
   563             }
   554 		FAT().FlushL();
   564         FAT().FlushL();
   555 		if(aIsSizeWrite)			// write file size if increasing
   565         if(aIsSizeWrite)            // write file size if increasing
   556 			WriteFileSizeL(aSize);
   566             WriteFileSizeL(aSize);
   557 		}
   567         }
   558 	}
   568     }
   559 
   569 
   560 //-----------------------------------------------------------------------------
   570 //-----------------------------------------------------------------------------
   561 /**
   571 /**
   562     Set the entry's attributes and modified time.
   572     Set the entry's attributes and modified time.
   563 */
   573 */
   564 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
   574 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
   565 	{
   575     {
   566 	__PRINT(_L("CFatFileCB::SetEntryL"));
   576     __PRINT(_L("CFatFileCB::SetEntryL"));
   567     
   577     
   568     FatMount().CheckStateConsistentL();
   578     FatMount().CheckStateConsistentL();
   569     FatMount().CheckWritableL();
   579     FatMount().CheckWritableL();
   570 
   580 
   571 	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
   581     TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
   572 	if (setAttMask|aClearAttMask)
   582     if (setAttMask|aClearAttMask)
   573 		{
   583         {
   574 		iAtt|=setAttMask;
   584         iAtt|=setAttMask;
   575 		iAtt&=(~aClearAttMask);
   585         iAtt&=(~aClearAttMask);
   576 		}
   586         }
   577 	if (aSetAttMask&KEntryAttModified)
   587     if (aSetAttMask&KEntryAttModified)
   578 		iModified=aTime;
   588         iModified=aTime;
   579 	iAtt|=KEntryAttModified;
   589     iAtt|=KEntryAttModified;
   580 	}
   590     }
   581 
   591 
   582 /**
   592 /**
   583     This is a RuggedFAT - specific method. Writes file size to the corresponding field of this
   593     This is a RuggedFAT - specific method. Writes file size to the corresponding field of this
   584     file direcrory entry.
   594     file direcrory entry.
   585 */
   595 */
   586 void CFatFileCB::WriteFileSizeL(TUint aSize)
   596 void CFatFileCB::WriteFileSizeL(TUint aSize)
   587 	{
   597     {
   588 	__PRINT(_L("CFatFileCB::WriteFileSizeL"));
   598     __PRINT(_L("CFatFileCB::WriteFileSizeL"));
   589 	TEntryPos entryPos=iFileDirPos;
   599     TEntryPos entryPos=iFileDirPos;
   590 	entryPos.iPos+=_FOFF(SFatDirEntry,iSize);
   600     entryPos.iPos+=_FOFF(SFatDirEntry,iSize);
   591 	TPtrC8 size((TUint8*)&aSize,sizeof(TUint));
   601     TPtrC8 size((TUint8*)&aSize,sizeof(TUint));
   592 	
   602     
   593     //-- use directory cache when dealing with directories
   603     //-- use directory cache when dealing with directories
   594     FatMount().DirWriteL(entryPos,size);
   604     FatMount().DirWriteL(entryPos,size);
   595 	iFileSizeModified=EFalse;
   605     iFileSizeModified=EFalse;
   596     }
   606     }
   597 
   607 
   598 //-----------------------------------------------------------------------------
   608 //-----------------------------------------------------------------------------
   599 /** 
   609 /** 
   600     Flush file size, attributes, time etc. to the media.
   610     Flush file size, attributes, time etc. to the media.
   601     It doesn't matter if whole directory entry is being written of only part of it. Anyway, a single DOS
   611     It doesn't matter if whole directory entry is being written of only part of it. Anyway, a single DOS
   602     dir. entry always fits into 1 sector.
   612     dir. entry always fits into 1 sector.
   603 */
   613 */
   604 void CFatFileCB::FlushDataL()
   614 void CFatFileCB::FlushDataL()
   605 	{
   615     {
   606 	__PRINT(_L("CFatFileCB::FlushDataL"));
   616     __PRINT(_L("CFatFileCB::FlushDataL"));
   607     FlushAllL();
   617     FlushAllL();
   608 	}
   618     }
   609 
   619 
   610 //-----------------------------------------------------------------------------
   620 //-----------------------------------------------------------------------------
   611 /** 
   621 /** 
   612     Flush the fide directory entry data: files size, attributes, time etc. 
   622     Flush the fide directory entry data: files size, attributes, time etc. 
   613 */
   623 */
   614 void CFatFileCB::FlushAllL()
   624 void CFatFileCB::FlushAllL()
   615 	{
   625     {
   616 	__PRINT(_L("CFatFileCB::FlushAllL()"));
   626     __PRINT(_L("CFatFileCB::FlushAllL()"));
   617 
   627 
   618     if (Mount().IsCurrentMount()==EFalse)
   628     if (Mount().IsCurrentMount()==EFalse)
   619 		User::Leave(KErrDisMounted);
   629         User::Leave(KErrDisMounted);
   620 
   630 
   621     FatMount().CheckStateConsistentL();
   631     FatMount().CheckStateConsistentL();
   622     FatMount().CheckWritableL();
   632     FatMount().CheckWritableL();
   623 
   633 
   624 	TFatDirEntry entry;
   634     TFatDirEntry entry;
   625 	FatMount().ReadDirEntryL(iFileDirPos,entry);
   635     FatMount().ReadDirEntryL(iFileDirPos,entry);
   626 	__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   636     __ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   627 	entry.SetAttributes(iAtt&KEntryAttMaskSupported);
   637     entry.SetAttributes(iAtt&KEntryAttMaskSupported);
   628 	entry.SetSize(Size());
   638     entry.SetSize(Size());
   629 	entry.SetTime(iModified, FatMount().TimeOffset());
   639     entry.SetTime(iModified, FatMount().TimeOffset());
   630 	entry.SetStartCluster(iStartCluster);
   640     entry.SetStartCluster(iStartCluster);
   631 
   641 
   632 	TBool setNotify = FatMount().GetNotifyUser();
   642     TBool setNotify = FatMount().GetNotifyUser();
   633 	if(setNotify)
   643     if(setNotify)
   634 		{
   644         {
   635 		FatMount().SetNotifyOff();	// do not launch a notifier
   645         FatMount().SetNotifyOff();  // do not launch a notifier
   636 		}
   646         }
   637 
   647 
   638 	TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry));
   648     TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry));
   639 	
   649     
   640 	if(setNotify)
   650     if(setNotify)
   641 		{
   651         {
   642 		FatMount().SetNotifyOn();
   652         FatMount().SetNotifyOn();
   643 		}
   653         }
   644 
   654 
   645 	User::LeaveIfError(ret);
   655     User::LeaveIfError(ret);
   646 	iAtt&=(~KEntryAttModified);
   656     iAtt&=(~KEntryAttModified);
   647 	iFileSizeModified=EFalse;
   657     iFileSizeModified=EFalse;
   648 	}
   658     }
   649 
   659 
   650 //-----------------------------------------------------------------------------
   660 //-----------------------------------------------------------------------------
   651 
   661 
   652 /**
   662 /**
   653     Rename already opened file.
   663     Rename already opened file.
   654     @param  aNewName new file name; all trailing dots from the name will be removed
   664     @param  aNewName new file name; all trailing dots from the name will be removed
   655 */
   665 */
   656 void CFatFileCB::RenameL(const TDesC& aNewName)
   666 void CFatFileCB::RenameL(const TDesC& aNewName)
   657 	{
   667     {
   658     __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName);
   668     __PRINT2(_L("CFatFileCB::RenameL[0x%x], name:%S"),this, &aNewName);
   659 
   669 
   660     FatMount().CheckStateConsistentL();
   670     FatMount().CheckStateConsistentL();
   661     FatMount().CheckWritableL();
   671     FatMount().CheckWritableL();
   662 
   672 
   663     const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name
   673     const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name
   664 
   674 
   665 
   675 
   666 	FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos);
   676     FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos);
   667 	
   677     
   668     AllocBufferL(iFileName, fileName);
   678     AllocBufferL(iFileName, fileName);
   669 	
   679     
   670 	if(!FatMount().IsRuggedFSys())
   680     if(!FatMount().IsRuggedFSys())
   671 		FAT().FlushL();
   681         FAT().FlushL();
   672 	}
   682     }
   673 
   683 
   674 
   684 
   675 //***********************************************************
   685 //***********************************************************
   676 //* BlockMap interface
   686 //* BlockMap interface
   677 //***********************************************************
   687 //***********************************************************
   678 	
   688     
   679 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos)
   689 TInt CFatFileCB::BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos)
   680 //
   690 //
   681 // Retrieves the block map of a given section of the file, in the FAT file system.
   691 // Retrieves the block map of a given section of the file, in the FAT file system.
   682 //	
   692 //  
   683 	{
   693     {
   684 	__PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos);
   694     __PRINT2(_L("CFatFileCB::BlockMap aStartPos=%ld aEndPos=%ld"), aStartPos, aEndPos);
   685 	
   695     
   686 	if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) )
   696     if ( I64HIGH(aStartPos) || I64HIGH(aEndPos) )
   687 		return KErrNotSupported;
   697         return KErrNotSupported;
   688 
   698 
   689     TUint startPos = I64LOW(aStartPos);
   699     TUint startPos = I64LOW(aStartPos);
   690 	TUint endPos = I64LOW(aEndPos);
   700     TUint endPos = I64LOW(aEndPos);
   691 
   701 
   692 	// aEndPos will always be >=0 at this point
   702     // aEndPos will always be >=0 at this point
   693 	const TUint length = endPos - startPos;
   703     const TUint length = endPos - startPos;
   694 	
   704     
   695 	// Store the position of cluster zero in aInfo
   705     // Store the position of cluster zero in aInfo
   696 	CFatMountCB& fatMount = FatMount();
   706     CFatMountCB& fatMount = FatMount();
   697 
   707 
   698 	TInt drvNo=-1;
   708     TInt drvNo=-1;
   699 	TBusLocalDrive* locDrv;
   709     TBusLocalDrive* locDrv;
   700 	if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives))
   710     if((fatMount.LocalDrive()->GetLocalDrive(locDrv)==KErrNone) && ((drvNo=GetLocalDriveNumber(locDrv))>=0) && (drvNo<KMaxLocalDrives))
   701 		aInfo.iLocalDriveNumber=drvNo;
   711         aInfo.iLocalDriveNumber=drvNo;
   702 	else
   712     else
   703 		return KErrNotSupported;
   713         return KErrNotSupported;
   704 
   714 
   705 	// Fetch the address of cluster 0
   715     // Fetch the address of cluster 0
   706 	aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytes(KFirstClusterNum);
   716     aInfo.iStartBlockAddress = fatMount.FAT().DataPositionInBytes(KFirstClusterNum);
   707 
   717 
   708 	TRAPD(r, CheckPosL(startPos));
   718     TRAPD(r, CheckPosL(startPos));
   709 	if (r != KErrNone)
   719     if (r != KErrNone)
   710 		return r;
   720         return r;
   711 
   721 
   712 	aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos);
   722     aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos);
   713 	aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2();
   723     aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2();
   714 	const TUint myStartPos = iCurrentPos.iPos;
   724     const TUint myStartPos = iCurrentPos.iPos;
   715 	if ( myStartPos + length > (TUint)Size())
   725     if ( myStartPos + length > (TUint)Size())
   716 		return KErrArgument;
   726         return KErrArgument;
   717 
   727 
   718 	TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo));
   728     TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo));
   719 	if (r != KErrNone)
   729     if (r != KErrNone)
   720 		return r;
   730         return r;
   721 
   731 
   722 	aStartPos = iCurrentPos.iPos;
   732     aStartPos = iCurrentPos.iPos;
   723 	if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length)))
   733     if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length)))
   724 		return KErrCompletion;
   734         return KErrCompletion;
   725 	else
   735     else
   726 		return KErrNone;
   736         return KErrNone;
   727 	}
   737     }
   728 
   738 
   729 
   739 
   730 
   740 
   731 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   741 TInt CFatFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   732 	{
   742     {
   733 	switch(aInterfaceId)
   743     switch(aInterfaceId)
   734 		{
   744         {
   735 		case EExtendedFileInterface:
   745         case EExtendedFileInterface:
   736 			((CFileCB::MExtendedFileInterface*&) aInterface) = this;
   746             ((CFileCB::MExtendedFileInterface*&) aInterface) = this;
   737 			return KErrNone;
   747             return KErrNone;
   738 
   748 
   739 		case EBlockMapInterface:
   749         case EBlockMapInterface:
   740 			aInterface = (CFileCB::MBlockMapInterface*) this;
   750             aInterface = (CFileCB::MBlockMapInterface*) this;
   741 			return KErrNone;
   751             return KErrNone;
   742 
   752 
   743 		case EGetLocalDrive:
   753         case EGetLocalDrive:
   744 			return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface);
   754             return FatMount().LocalDrive()->GetLocalDrive((TBusLocalDrive*&) aInterface);
   745 
   755 
   746 		default:
   756         default:
   747 			return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
   757             return CFileCB::GetInterface(aInterfaceId,aInterface,aInput);
   748 		}
   758         }
   749 	}
   759     }
   750 
   760 
   751 
   761 
   752 
   762 
   753 
   763 
   754 /**
   764 /**
   755     Overwrites file's start cluster (iStartCluster) in its directory entry.
   765     Overwrites file's start cluster (iStartCluster) in its directory entry.
   756 */
   766 */
   757 void CFatFileCB::FlushStartClusterL()
   767 void CFatFileCB::FlushStartClusterL()
   758 	{
   768     {
   759 	__PRINT(_L("CFatFileCB::FlushStartClusterL"));
   769     __PRINT(_L("CFatFileCB::FlushStartClusterL"));
   760 
   770 
   761     CFatMountCB& mount = FatMount();
   771     CFatMountCB& mount = FatMount();
   762     TFatDirEntry dirEntry;
   772     TFatDirEntry dirEntry;
   763     
   773     
   764     mount.ReadDirEntryL(iFileDirPos, dirEntry);      //-- read this file's dir. entry
   774     mount.ReadDirEntryL(iFileDirPos, dirEntry);      //-- read this file's dir. entry
   765     dirEntry.SetStartCluster(iStartCluster);         //-- set new start cluster
   775     dirEntry.SetStartCluster(iStartCluster);         //-- set new start cluster
   766     mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back
   776     mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back
   767 	}
   777     }
   768 
   778 
   769 
   779 
   770 
   780 
   771 
   781 
   772 
   782