userlibandfileserver/fileserver/sfat32/sl_file.cpp
branchRCL_3
changeset 22 2f92ad2dc5db
parent 2 4122176ea935
child 41 0ffb4e86fcc9
equal deleted inserted replaced
21:e7d2d738d3c2 22:2f92ad2dc5db
    23 const TInt KSeekIndexSizeLog2=7;
    23 const TInt KSeekIndexSizeLog2=7;
    24 const TInt KFirstClusterNum=2;
    24 const TInt KFirstClusterNum=2;
    25 
    25 
    26 CFatFileCB::CFatFileCB()
    26 CFatFileCB::CFatFileCB()
    27 	{
    27 	{
    28 
       
    29 	__PRINT1(_L("CFatFileCB created 0x%x"),this);
    28 	__PRINT1(_L("CFatFileCB created 0x%x"),this);
    30 	}
    29 	}
    31 
    30 
    32 CFatFileCB::~CFatFileCB()
    31 CFatFileCB::~CFatFileCB()
    33 	{
    32 	{
    34 	__PRINT1(_L("CFatFileCB deleted 0x%x"),this);
    33 	__PRINT1(_L("~CFatFileCB deleted 0x%x"),this);
    35 
    34 
    36     //-- a nasty trick to find out if the CFatFileCB is in consistent state on the moment of destruction.
    35     //-- 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()
    36     //-- Because of OOM conditions CFatFileCB might not be fully constructed and to be deleted, while FlushAll()
    38     //-- implies valid iMount.
    37     //-- implies valid iMount.
    39     const CMountCB* pMount  = &Mount();
    38     const CMountCB* pMount  = &Mount();
    40     if(pMount)
    39     if(pMount)
    41         {//-- do some finalisation work if CMountCB is valid
    40         {//-- do some finalisation work if CMountCB is valid
    42         if (iAtt&KEntryAttModified)
    41         if(FileAttModified())
       
    42             {
       
    43             IndicateFileTimeModified(ETrue); //-- this will force writing file modification time to the media on Flush
    43             TRAP_IGNORE(FlushAllL());
    44             TRAP_IGNORE(FlushAllL());
       
    45         }
    44         }
    46         }
    45 
    47 
    46     delete[] iSeekIndex;
    48     delete[] iSeekIndex;
    47 	}
    49 	}
    48 
    50 
    57 	if (iSeekIndex == NULL)
    59 	if (iSeekIndex == NULL)
    58 		return;
    60 		return;
    59 
    61 
    60 	Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize);
    62 	Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize);
    61 
    63 
    62 	iSeekIndexSize=CalcSeekIndexSize(Size());
    64 	iSeekIndexSize=CalcSeekIndexSize(FCB_FileSize());
    63 	}
    65 	}
    64 
    66 
    65 TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset)
    67 TInt CFatFileCB::SeekToPosition(TUint aNewRelCluster, TUint aClusterOffset)
    66 //
    68 //
    67 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster
    69 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster
    68 // Return aNewRelCluster-aCurrentPos.iCluster
    70 // Return aNewRelCluster-aCurrentPos.iCluster
    69 //
    71 //
    70 	{
    72 	{
    79 		}
    81 		}
    80 	if (clusterOffset==0) // Counted back to the current cluster
    82 	if (clusterOffset==0) // Counted back to the current cluster
    81 		return(aClusterOffset);
    83 		return(aClusterOffset);
    82 	if (seekPos<0)
    84 	if (seekPos<0)
    83 		{
    85 		{
    84 		iCurrentPos.iCluster=iStartCluster;
    86 		iCurrentPos.iCluster=FCB_StartCluster();
    85 		return(aNewRelCluster);
    87 		return(aNewRelCluster);
    86 		}
    88 		}
    87 
    89 
    88 	iCurrentPos.iCluster=iSeekIndex[seekPos];
    90 	iCurrentPos.iCluster=iSeekIndex[seekPos];
    89 	return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize));
    91 	return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize));
    90 	}
    92 	}
    91 
    93 
    92 void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster)
    94 void CFatFileCB::SetSeekIndexValueL(TUint aRelCluster, TUint aStoredCluster)
    93 //
    95 //
    94 // Sets a value in the seekindex
    96 // Sets a value in the seekindex
    95 //
    97 //
    96 	{
    98 	{
    97 
    99 
   120 //
   122 //
   121 	{
   123 	{
   122 	__PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos);
   124 	__PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos);
   123 	if (aPos==iCurrentPos.iPos)
   125 	if (aPos==iCurrentPos.iPos)
   124 		return;
   126 		return;
   125     __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd));
   127     __ASSERT_DEBUG(aPos <= FCB_FileSize(), Fault(EFatFilePosBeyondEnd));
   126 
   128 
   127 	if (iFileSizeModified && IsSeekBackwards(aPos))
   129 	if (FileSizeModified() && IsSeekBackwards(aPos))
   128 		FlushDataL(); 
   130 		FlushDataL(); 
   129 	
   131 	
   130 	TUint newRelCluster=aPos>>ClusterSizeLog2();
   132 	TUint newRelCluster=aPos>>ClusterSizeLog2();
   131 	if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) )
   133 	if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) )
   132 		newRelCluster--;
   134 		newRelCluster--;
   133 	TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2();
   135 	TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2();
       
   136 	
   134 	if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) )
   137 	if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) )
   135 		oldRelCluster--;	
   138 		oldRelCluster--;	
       
   139 	
   136 	TInt clusterOffset=newRelCluster-oldRelCluster;
   140 	TInt clusterOffset=newRelCluster-oldRelCluster;
   137 	TInt oldCluster=iCurrentPos.iCluster;
   141 	TUint32 oldCluster=iCurrentPos.iCluster;
       
   142 
   138 	iCurrentPos.iPos=aPos;
   143 	iCurrentPos.iPos=aPos;
   139 	if (clusterOffset==0)
   144 	if (clusterOffset==0)
   140 		return;
   145 		return;
   141 	TInt seekOffset=clusterOffset;
   146 	TInt seekOffset=clusterOffset;
   142 	if (iSeekIndex!=NULL)
   147 	if (iSeekIndex!=NULL)
   145 		if (seekOffset==0)
   150 		if (seekOffset==0)
   146 			return;
   151 			return;
   147 		}
   152 		}
   148 	if (clusterOffset==-1 && seekOffset!=1)
   153 	if (clusterOffset==-1 && seekOffset!=1)
   149 		{ // Check previous cluster
   154 		{ // Check previous cluster
   150 		TInt cluster=oldCluster-1;
   155 		TUint32 cluster=oldCluster-1;
   151 		if (FAT().GetNextClusterL(cluster) && cluster==oldCluster)
   156 		if (FAT().GetNextClusterL(cluster) && cluster==oldCluster)
   152 			{
   157 			{
   153             iCurrentPos.iCluster=oldCluster-1;
   158             iCurrentPos.iCluster=oldCluster-1;
   154 			return;
   159 			return;
   155 			}
   160 			}
   156 		}
   161 		}
   157 	if (seekOffset<0)
   162 	if (seekOffset<0)
   158 		{
   163 		{
   159 		seekOffset=newRelCluster;
   164 		seekOffset=newRelCluster;
   160 		iCurrentPos.iCluster=iStartCluster;
   165 		iCurrentPos.iCluster=FCB_StartCluster();
   161 		}
   166 		}
   162 	while (seekOffset--)
   167 	while (seekOffset--)
   163 		{
   168 		{
   164         if (!FAT().GetNextClusterL(iCurrentPos.iCluster))
   169         if (!FAT().GetNextClusterL(iCurrentPos.iCluster))
   165             {
   170             {
   170 		if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster)
   175 		if (iSeekIndex!=NULL && cluster && (cluster>>iSeekIndexSize)<<iSeekIndexSize==cluster)
   171 			SetSeekIndexValueL(cluster,iCurrentPos.iCluster);
   176 			SetSeekIndexValueL(cluster,iCurrentPos.iCluster);
   172 		}
   177 		}
   173 	}
   178 	}
   174 
   179 
   175 void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos)
   180 //-----------------------------------------------------------------------------
   176 //
   181 /** 
   177 // Initialize FileCB from entry data
   182     Initialize FileCB from file's entry data.
   178 //
   183     
   179 	{
   184     @param  aFatDirEntry        this file DOS dir entry.
   180 
   185     @param  aFileDosEntryPos    this file DOS entry dir. iterator in the parent directory.
   181 	__PRINT(_L("CFatFileCB::SetL"));
   186 */
   182 	SetSize(aFatDirEntry.Size()); 
   187 void CFatFileCB::SetupL(const TFatDirEntry& aFatDirEntry, const TEntryPos& aFileDosEntryPos)
       
   188 	{
       
   189 	__PRINT1(_L("CFatFileCB::SetupL[0x%x]"), this);
       
   190 	
       
   191 
       
   192     //-- set up a file control block
   183 	iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry);
   193 	iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry);
   184 	iStartCluster=iCurrentPos.iCluster;
       
   185 	iCurrentPos.iPos=0;
   194 	iCurrentPos.iPos=0;
   186 	iAtt=aFatDirEntry.Attributes();
   195 	
   187 	iModified= aFatDirEntry.Time(FatMount().TimeOffset());
   196     SetAtt(aFatDirEntry.Attributes());
   188 	iShare=aShare;
   197 	SetModified(aFatDirEntry.Time(FatMount().TimeOffset()));
   189 	iFileDirPos=aPos;
   198     
       
   199     FCB_SetStartCluster(iCurrentPos.iCluster);
       
   200     FCB_SetFileSize(aFatDirEntry.Size()); 
       
   201 
       
   202 	iFileDosEntryPos = aFileDosEntryPos;
   190 
   203 
   191     SetMaxSupportedSize(KMaxSupportedFatFileSize);
   204     SetMaxSupportedSize(KMaxSupportedFatFileSize);
   192 	}
   205 
   193 
   206     //-- create seek index
   194 //-----------------------------------------------------------------------------
   207     ASSERT(!iSeekIndex);
   195 // from CFileCB::MExtendedFileInterface
   208     CreateSeekIndex();
       
   209     if(!iSeekIndex)
       
   210         User::Leave(KErrNoMemory);
       
   211 
       
   212     
       
   213     IndicateFileAttModified(EFalse);
       
   214     IndicateFileSizeModified(EFalse);
       
   215     IndicateFileTimeModified(EFalse);
       
   216 	}
       
   217 
       
   218 //-----------------------------------------------------------------------------
       
   219 /**
       
   220     Read data from the file.
       
   221     
       
   222     @param  aFilePos    start read position within a file
       
   223     @param  aLength     how many bytes to read; on return will be how many bytes actually read
       
   224     @param  aDes        local buffer desctriptor
       
   225     @param  aMessage    from file server, used to write data to the buffer in different address space.
       
   226     @param  aDesOffset  offset within data descriptor where the data will be copied
       
   227 
       
   228     @leave on media read error
       
   229 
       
   230 */
   196 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset)
   231 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset)
   197 	{
   232 	{
   198 	__PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength);
   233 	__PRINT3(_L("CFatFileCB::ReadL[0x%x] pos=%LU len=%d"), this, aPos, aLength);
   199 	
   234 	
   200     if((TUint64)aPos > KMaxSupportedFatFileSize-1)
   235     if((TUint64)aPos > KMaxSupportedFatFileSize-1)
   201         User::Leave(KErrNotSupported);  //-- max. position in the file is 0xFFFFFFFE
   236         User::Leave(KErrNotSupported);  //-- max. position in the file is 0xFFFFFFFE
   202 
   237 
   203     FatMount().CheckStateConsistentL();
   238     FatMount().CheckStateConsistentL();
   204     
   239     
   205 	CheckPosL(I64LOW(aPos));
   240 	CheckPosL(I64LOW(aPos));
   206 	
   241 	
   207 	const TUint startPos = iCurrentPos.iPos;
   242 	const TUint startPos = iCurrentPos.iPos;
   208 	const TUint curSize  = (TUint)Size();
   243 	const TUint curSize  = FCB_FileSize();
   209 	const TUint length   = (TUint)aLength;
   244 	const TUint length   = (TUint)aLength;
   210 	
   245 	
   211 	if((startPos + length > curSize) || (startPos > startPos + length) )
   246 	if((startPos + length > curSize) || (startPos > startPos + length) )
   212 		aLength=curSize-startPos;
   247 		aLength=curSize-startPos;
   213 	
   248 	
   220 	{
   255 	{
   221 	ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0);
   256 	ReadL(TInt64(aFilePos),aLength,(TDes8*) aTrg,aMessage, 0);
   222 	}
   257 	}
   223 
   258 
   224 //-----------------------------------------------------------------------------
   259 //-----------------------------------------------------------------------------
   225 // from CFileCB::MExtendedFileInterface
   260 /**
       
   261     Write data to the file.
       
   262     
       
   263     @param  aFilePos    start write position within a file
       
   264     @param  aLength     how many bytes to write; on return contain amount of data actually written
       
   265     @param  aDes        local buffer desctriptor
       
   266     @param  aMessage    from file server, used to write data to the media from different address space.
       
   267     @param  aDesOffset  offset within data descriptor 
       
   268 
       
   269     @leave on media read error
       
   270 
       
   271 */
   226 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset)
   272 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset)
   227 	{
   273 	{
   228 	__PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength);
   274 	__PRINT3(_L("CFatFileCB::WriteL[0x%x] pos=%LU len=%d"), this, aPos, aLength);
       
   275 
   229 	// FAT supports 32 bits only for file size
   276 	// FAT supports 32 bits only for file size
   230    	TUint64 endPos = aPos + aLength;
   277    	TUint64 endPos = aPos + aLength;
   231    	if(endPos > KMaxSupportedFatFileSize)
   278    	if(endPos > KMaxSupportedFatFileSize)
   232    		User::Leave(KErrNotSupported);
   279    		User::Leave(KErrNotSupported);
   233    	
   280    	
   234     FatMount().CheckStateConsistentL();
   281     FatMount().CheckStateConsistentL();
   235     FatMount().CheckWritableL();
   282     FatMount().CheckWritableL();
   236     const TUint pos = I64LOW(aPos);
   283     const TUint pos = I64LOW(aPos);
   237   	CheckPosL(pos);
   284   	CheckPosL(pos);
   238   	
   285   	
   239 	const TUint startCluster = (TUint)iStartCluster;
   286 	const TUint startCluster = FCB_StartCluster();
   240 	const TUint length       = (TUint)aLength;
   287 	const TUint length       = (TUint)aLength;
   241 	
   288 	
   242 	endPos = iCurrentPos.iPos + length; 
   289 	endPos = iCurrentPos.iPos + length; 
   243 	if ((endPos           > (TUint)Size()) ||
   290 	if ((endPos           > FCB_FileSize()) ||
   244 	    (iCurrentPos.iPos > endPos)         ) // Overflow condition 
   291 	    (iCurrentPos.iPos > endPos)         ) // Overflow condition 
   245 		DoSetSizeL(iCurrentPos.iPos+length,EFalse);
   292 		DoSetSizeL(iCurrentPos.iPos+length,EFalse);
   246    	
   293    	
   247 	TUint startPos=iCurrentPos.iPos;
   294 	TUint startPos=iCurrentPos.iPos;
   248 	TInt badcluster=0;
   295 	TUint badcluster=0;
   249 	TInt goodcluster=0;
   296 	TUint goodcluster=0;
   250    	
   297    	
   251 	TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster));
   298 	TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster));
   252    	
   299    	
   253 	if (ret == KErrCorrupt || ret == KErrDied)
   300 	if (ret == KErrCorrupt || ret == KErrDied)
   254 		{
   301 		{
   255         if(startCluster == 0)
   302         if(startCluster == 0)
   256 			{ //Empty File, revert all the clusters allocated.
   303 			{ //Empty File, revert all the clusters allocated.
   257 			TInt cluster = iStartCluster;
   304 			const TUint32 cluster = FCB_StartCluster();
   258 			iStartCluster = 0;
   305 			FCB_SetStartCluster(0);
   259 			SetSize(0);
   306 			FCB_SetFileSize(0);
       
   307 			IndicateFileSizeModified(ETrue);
       
   308             
   260 			FlushAllL();
   309 			FlushAllL();
   261 
   310 
   262 			iCurrentPos.iCluster = 0;
   311 			iCurrentPos.iCluster = 0;
   263 			iCurrentPos.iPos = 0;
   312 			iCurrentPos.iPos = 0;
   264 
   313 
   265 			FAT().FreeClusterListL(cluster);
   314 			FAT().FreeClusterListL(cluster);
   266 			FAT().FlushL();
   315 			FAT().FlushL();
   267 			}
   316 			}
   268 		else
   317 		else
   269 			{ //Calculate the clusters required based on file size, revert extra clusters if allocated.
   318 			{ //Calculate the clusters required based on file size, revert extra clusters if allocated.
   270 			const TUint curSize = (TUint)Size();
   319 			const TUint curSize = FCB_FileSize();
   271 			TUint ClustersNeeded = curSize >> ClusterSizeLog2();
   320 			TUint ClustersNeeded = curSize >> ClusterSizeLog2();
   272 			if(curSize > (ClustersNeeded << ClusterSizeLog2()))
   321 			if(curSize > (ClustersNeeded << ClusterSizeLog2()))
   273 				{
   322 				{
   274 				ClustersNeeded++;
   323 				ClustersNeeded++;
   275 				}
   324 				}
   276 
   325 
   277 			TInt cluster = iStartCluster;
   326 			TUint32 cluster = FCB_StartCluster();
   278 			while(--ClustersNeeded)
   327 			while(--ClustersNeeded)
   279 				{
   328 				{
   280 				FAT().GetNextClusterL(cluster);
   329 				FAT().GetNextClusterL(cluster);
   281 				}
   330 				}
   282                 
   331                 
   294 
   343 
   295 	User::LeaveIfError(ret);
   344 	User::LeaveIfError(ret);
   296 
   345 
   297 	if(badcluster != 0)
   346 	if(badcluster != 0)
   298 		{
   347 		{
   299 		if(iStartCluster == badcluster)
   348 		if(FCB_StartCluster() == badcluster)
   300 			{
   349 			{
   301 			iStartCluster = goodcluster;
   350             FCB_SetStartCluster(goodcluster);
   302 			FlushStartClusterL();
   351 			FlushStartClusterL();
   303 			}
   352 			}
   304 		else
   353 		else
   305 			{
   354 			{
   306 			TInt aCluster = iStartCluster;
   355 			TUint32 aCluster = FCB_StartCluster();
   307 			do
   356 			do
   308 				{
   357 				{
   309                 if((TUint)badcluster == FAT().ReadL(aCluster))
   358                 if((TUint)badcluster == FAT().ReadL(aCluster))
   310 					{
   359 					{
   311 					FAT().WriteL(aCluster, goodcluster);
   360 					FAT().WriteL(aCluster, goodcluster);
   316 			while(FAT().GetNextClusterL(aCluster));
   365 			while(FAT().GetNextClusterL(aCluster));
   317 			}
   366 			}
   318 		}
   367 		}
   319 	aLength=iCurrentPos.iPos-startPos;
   368 	aLength=iCurrentPos.iPos-startPos;
   320 
   369 
   321 	if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size())
   370 	if(FatMount().IsRuggedFSys() && pos+(TUint)aLength > FCB_FileSize())
   322 		{
   371 		{
   323 		WriteFileSizeL(pos+aLength);
   372 		WriteFileSizeL(pos+aLength);
   324 		}
   373 		}
   325 
   374 
   326 	}
   375 	}
   439 		}
   488 		}
   440 	return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1);
   489 	return (count - (KSeekIndexSizeLog2 + ClusterSizeLog2()) + 1);
   441 	}
   490 	}
   442 
   491 
   443 //-----------------------------------------------------------------------------
   492 //-----------------------------------------------------------------------------
   444 
   493 /**
       
   494     Set file size.
       
   495     @param aSize new file size.
       
   496 */
   445 void CFatFileCB::SetSizeL(TInt64 aSize)
   497 void CFatFileCB::SetSizeL(TInt64 aSize)
   446 	{
   498 	{
   447 	__PRINT(_L("CFatFileCB::SetSizeL"));
   499 	__PRINT2(_L("CFatFileCB::SetSizeL[0x%x] sz=%LU"), this, aSize);
   448 	
   500 	
   449 	// FAT supports 32 bits only for file size
   501 	//-- max. file size for FAT is 4GB-1
   450 	if (I64HIGH(aSize))
   502 	if (I64HIGH(aSize))
   451 		User::Leave(KErrNotSupported);
   503 		User::Leave(KErrNotSupported);
   452 
   504 
   453 	if(FatMount().IsRuggedFSys())
   505     DoSetSizeL(I64LOW(aSize), FatMount().IsRuggedFSys());
   454 		DoSetSizeL(I64LOW(aSize),ETrue);
   506 	}
       
   507 
       
   508 
       
   509 void CFatFileCB::SetSizeL(TInt aSize)
       
   510 	{
       
   511 	SetSizeL(TInt64(aSize));
       
   512 	}
       
   513 
       
   514 //-----------------------------------------------------------------------------
       
   515 /**
       
   516     Shrink file to zero size.
       
   517 */
       
   518 void CFatFileCB::DoShrinkFileToZeroSizeL()
       
   519     {
       
   520 	    ASSERT(FCB_FileSize());
       
   521         ASSERT(FileSizeModified());
       
   522         
       
   523             ClearIndex(0); //-- clear seek index array
       
   524 		
       
   525         //-- update file dir. entry
       
   526         const TUint32 cluster = FCB_StartCluster();
       
   527 		FCB_SetStartCluster(0);
       
   528 		FCB_SetFileSize(0);
       
   529 			FlushAllL();
       
   530 		
       
   531         //-- free cluster list. 
       
   532 			CheckPosL(0);
       
   533 			FAT().FreeClusterListL(cluster);
       
   534 			FAT().FlushL();
       
   535 			}
       
   536 
       
   537 //-----------------------------------------------------------------------------
       
   538 /*
       
   539     Shrink file to smaller size, but > 0
       
   540 
       
   541     @param aNewSize new file size
       
   542     @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed 
       
   543 */
       
   544 void CFatFileCB::DoShrinkFileL(TUint32 aNewSize, TBool aForceCachesFlush)
       
   545 		{
       
   546     ASSERT(FileSizeModified());
       
   547     ASSERT(FCB_FileSize() > aNewSize && aNewSize);
       
   548 	
       
   549     if(aForceCachesFlush)		
       
   550         WriteFileSizeL(aNewSize); //-- write file size directly to its dir. entry
       
   551 
       
   552 	CheckPosL(aNewSize);
       
   553 	
       
   554     TUint32 cluster=iCurrentPos.iCluster;
       
   555 		if (FAT().GetNextClusterL(cluster))
       
   556 	    {//-- truncate the cluster chain
       
   557 			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
       
   558 			FAT().FreeClusterListL(cluster);
       
   559 			}
       
   560 		
       
   561     ClearIndex(aNewSize);
       
   562 		FAT().FlushL();
       
   563 		}
       
   564 	
       
   565 //-----------------------------------------------------------------------------
       
   566 /**
       
   567     Expand a file.
       
   568 	
       
   569     @param aNewSize new file size.
       
   570     @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed
       
   571 */
       
   572 void CFatFileCB::DoExpandFileL(TUint32 aNewSize, TBool aForceCachesFlush)
       
   573 		{
       
   574     ASSERT(FCB_FileSize() < aNewSize);
       
   575     ASSERT(FileSizeModified());
       
   576 
       
   577     const TUint32 KClusterSzLog2  = ClusterSizeLog2();
       
   578     const TUint32 newSizeClusters = (TUint32)(((TUint64)aNewSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2);
       
   579 
       
   580 
       
   581 	//-- expanding a file
       
   582 	if (FCB_StartCluster() == 0)
       
   583 		{//-- the initial file size is 0 (no cluster chain)
       
   584          
       
   585         ClearIndex(0); //-- clear seek index array
       
   586         //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
       
   587         const TUint32 tempStartCluster=FAT().AllocateClusterListL(newSizeClusters, FAT().FreeClusterHint()); 
       
   588 		FAT().FlushL();
       
   589 
       
   590 		iCurrentPos.iCluster=tempStartCluster;
       
   591 		FCB_SetStartCluster(tempStartCluster);
       
   592 		FCB_SetFileSize(aNewSize);
       
   593 		FlushAllL();
       
   594 		}
   455 	else
   595 	else
   456 		DoSetSizeL(I64LOW(aSize),EFalse);
   596 		{
   457 	}
   597 		const TUint curSize = FCB_FileSize(); 
   458 
   598 	    const TUint32 oldSizeClusters = ((curSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2);
   459 
   599         ASSERT(newSizeClusters >= oldSizeClusters);
   460 void CFatFileCB::SetSizeL(TInt aSize)
   600 		const TUint newClusters = newSizeClusters-oldSizeClusters;	//-- Number of clusters we need to append to the existing cluster chain
   461 //
   601 		if (newClusters)
   462 // Envelope function around DoSetSizeL to enable aSize to
   602 			{
   463 // be written to disk for rugged fat file system
   603 			TEntryPos currentPos=iCurrentPos;
   464 //
   604 			CheckPosL(FCB_FileSize());
   465 	{
   605 			FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
   466 	SetSizeL(TInt64(aSize));
   606 			iCurrentPos=currentPos;
   467 	}
   607 			}
   468 
   608 	
   469 void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite)
   609 		FAT().FlushL();
   470 //
   610 		
   471 // Extend or truncate the file.
   611         if(aForceCachesFlush)			// write file size if increasing
   472 // Expects the modified attribute and iSize are set afterwards.
   612 			WriteFileSizeL(aNewSize);
   473 // Does not alter iCurrentPos, the current file position.
   613 		}
   474 // Writes size of file to disk if aIsSizeWrite set
   614 
   475 //
   615 	}
   476 	{
   616 
   477 	__PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite);
   617 //-----------------------------------------------------------------------------
       
   618 /**
       
   619     Set file size. This can involve extending/truncating file's cluster chain.
       
   620     @param  aSize               new file size
       
   621     @param  aForceCachesFlush   if ETrue, all changes in metadata will go to the media immediately. 
       
   622                                 it is used in Rugged FAT mode.
       
   623 */
       
   624 void CFatFileCB::DoSetSizeL(TUint aSize, TBool aForceCachesFlush)
       
   625 	{
       
   626 	__PRINT4(_L("CFatFileCB::DoSetSizeL[0x%x] sz:%d, oldSz:%d, flush:%d"), this, aSize, FCB_FileSize(), aForceCachesFlush);
   478 
   627 
   479     FatMount().CheckStateConsistentL();
   628     FatMount().CheckStateConsistentL();
   480     FatMount().CheckWritableL();
   629     FatMount().CheckWritableL();
   481 
   630 
   482 	
   631 	
   483 	// Can not change the file size if it is clamped
   632 	// Can not change the file size if it is clamped
   484 	if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0)
   633 	if(Mount().IsFileClamped(MAKE_TINT64(0,FCB_StartCluster())) > 0)
   485 		User::Leave(KErrInUse);
   634 		User::Leave(KErrInUse);
   486 	
   635 	
   487 	iFileSizeModified=ETrue;
   636 	if(aSize == FCB_FileSize())
       
   637         return;
       
   638 
       
   639     IndicateFileSizeModified(ETrue);
   488 
   640 
   489 	TInt newIndexMult=CalcSeekIndexSize(aSize);
   641 	TInt newIndexMult=CalcSeekIndexSize(aSize);
   490 	if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize)
   642 	if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize)
   491 		ResizeIndex(newIndexMult,aSize);
   643 		ResizeIndex(newIndexMult,aSize);
   492 	if (aSize == 0)
   644 
   493 		{
   645 	//-------------------------------------------
   494 		if (Size() != 0)
   646     //-- shrinking file to 0 size
   495 			{
   647     if(aSize == 0)
   496             ClearIndex(0); //-- clear seek index array
   648         {
   497 			TInt cluster=iStartCluster;
   649         DoShrinkFileToZeroSizeL();
   498 			iStartCluster = 0;
   650         return;
   499 			SetSize(0);
   651         }
   500 			FlushAllL();
   652 
   501 			CheckPosL(0);
   653     //-------------------------------------------
   502 			FAT().FreeClusterListL(cluster);
   654 	//-- shrinking file to non-zero size
   503 			FAT().FlushL();
   655     if (aSize < FCB_FileSize())
   504 			}
   656 		{
   505 		return;
   657         DoShrinkFileL(aSize, aForceCachesFlush);
   506 		}
   658         return;
   507 	if (aSize<(TUint)Size())
   659         }
   508 		{
   660     
   509 		if(aIsSizeWrite)		// write file size if decreasing
   661     //-------------------------------------------
   510 				WriteFileSizeL(aSize);
   662 	//-- expanding a file
   511 		CheckPosL(aSize);
   663     DoExpandFileL(aSize, aForceCachesFlush);
   512 		TInt cluster=iCurrentPos.iCluster;
   664 
   513 		if (FAT().GetNextClusterL(cluster))
   665 	}
   514 			{
   666 
   515 			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
   667 //-----------------------------------------------------------------------------
   516 			FAT().FreeClusterListL(cluster);
   668 /**
   517 			}
   669     Set file entry details, like file attributes and modified time
   518 		ClearIndex(aSize);
   670     This method doesn't write data to the media immediately, instead, all modified data are cached and can be flushed later 
   519 		FAT().FlushL();
   671     in FlushAllL()
   520 		return;
   672 
   521 		}
   673     @param  aTime           file modification time (and last access as well)
   522 	
   674     @param  aSetAttMask     file attributes OR mask
   523 	TUint newSize=aSize>>ClusterSizeLog2();	//	Number of clusters we now need
   675     @param  aClearAttMask   file attributes AND mask
   524 	if (aSize > (newSize<<ClusterSizeLog2()))
   676 
   525 		newSize++;	//	File size is not an exact multiple of cluster size
       
   526 					//	Increment the number of clusters required to accomodate tail
       
   527 	
       
   528 	if (iStartCluster==0)
       
   529 		{
       
   530         //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
       
   531         ClearIndex(0); //-- clear seek index array
       
   532         TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint());
       
   533 		FAT().FlushL();
       
   534 		iCurrentPos.iCluster=tempStartCluster;
       
   535 		iStartCluster=tempStartCluster;
       
   536 		SetSize(aSize);
       
   537 		FlushAllL();
       
   538 		}
       
   539 	else
       
   540 		{
       
   541 		const TUint curSize = (TUint)Size(); 
       
   542 		TUint oldSize=curSize>>ClusterSizeLog2();	//	Number of clusters we had previously
       
   543 		if (curSize>(oldSize<<ClusterSizeLog2()))
       
   544 			oldSize++;
       
   545 	
       
   546 		TInt newClusters=newSize-oldSize;	//	Number of clusters we need to prepare
       
   547 		if (newClusters)
       
   548 			{
       
   549 			TEntryPos currentPos=iCurrentPos;
       
   550 			CheckPosL(Size());
       
   551 			FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
       
   552 			iCurrentPos=currentPos;
       
   553 			}
       
   554 		FAT().FlushL();
       
   555 		if(aIsSizeWrite)			// write file size if increasing
       
   556 			WriteFileSizeL(aSize);
       
   557 		}
       
   558 	}
       
   559 
       
   560 //-----------------------------------------------------------------------------
       
   561 /**
       
   562     Set the entry's attributes and modified time.
       
   563 */
   677 */
   564 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
   678 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
   565 	{
   679 	{
   566 	__PRINT(_L("CFatFileCB::SetEntryL"));
   680 	__PRINT1(_L("CFatFileCB::SetEntryL[0x%x]"), this);
   567     
   681     
   568     FatMount().CheckStateConsistentL();
   682     FatMount().CheckStateConsistentL();
   569     FatMount().CheckWritableL();
   683     FatMount().CheckWritableL();
   570 
   684 
   571 	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
   685     //-- change file attributes
       
   686     const TUint setAttMask = (aSetAttMask & KEntryAttMaskSupported); //-- supported attributes to set
       
   687     TUint newAtt = Att();
       
   688 
   572 	if (setAttMask|aClearAttMask)
   689 	if (setAttMask|aClearAttMask)
   573 		{
   690 		{
   574 		iAtt|=setAttMask;
   691         newAtt |= setAttMask;
   575 		iAtt&=(~aClearAttMask);
   692         newAtt &= ~aClearAttMask;
   576 		}
   693         SetAtt(newAtt);
       
   694         IndicateFileAttModified(ETrue); //-- indicate that file attributes have changed
       
   695 		}
       
   696     
       
   697     //-- set file entry modification time if required
   577 	if (aSetAttMask&KEntryAttModified)
   698 	if (aSetAttMask&KEntryAttModified)
   578 		iModified=aTime;
   699 	{
   579 	iAtt|=KEntryAttModified;
   700         SetModified(aTime);        //-- set file modified time
   580 	}
   701         IndicateFileAttModified(ETrue); //-- indicate that file attributes have changed
   581 
   702         IndicateFileTimeModified(ETrue); //-- this will force writing file mod. time to the media on Flush
   582 /**
   703         }
   583     This is a RuggedFAT - specific method. Writes file size to the corresponding field of this
   704 
   584     file direcrory entry.
   705 	}
   585 */
   706 
   586 void CFatFileCB::WriteFileSizeL(TUint aSize)
       
   587 	{
       
   588 	__PRINT(_L("CFatFileCB::WriteFileSizeL"));
       
   589 	TEntryPos entryPos=iFileDirPos;
       
   590 	entryPos.iPos+=_FOFF(SFatDirEntry,iSize);
       
   591 	TPtrC8 size((TUint8*)&aSize,sizeof(TUint));
       
   592 	
       
   593     //-- use directory cache when dealing with directories
       
   594     FatMount().DirWriteL(entryPos,size);
       
   595 	iFileSizeModified=EFalse;
       
   596     }
       
   597 
   707 
   598 //-----------------------------------------------------------------------------
   708 //-----------------------------------------------------------------------------
   599 /** 
   709 /** 
   600     Flush file size, attributes, time etc. to the media.
   710     The same as FlushAllL(). This method is called from RFile::Flush()
   601     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.
       
   603 */
   711 */
   604 void CFatFileCB::FlushDataL()
   712 void CFatFileCB::FlushDataL()
   605 	{
   713 	{
   606 	__PRINT(_L("CFatFileCB::FlushDataL"));
   714 	__PRINT1(_L("CFatFileCB::FlushDataL[0x%x]"), this);
   607     FlushAllL();
   715     FlushAllL();
   608 	}
   716 	}
   609 
   717 
   610 //-----------------------------------------------------------------------------
   718 //-----------------------------------------------------------------------------
   611 /** 
   719 /** 
   612     Flush the fide directory entry data: files size, attributes, time etc. 
   720     Flush the fide directory entry data: files size, attributes, time etc. 
   613 */
   721 */
   614 void CFatFileCB::FlushAllL()
   722 void CFatFileCB::FlushAllL()
   615 	{
   723 	{
   616 	__PRINT(_L("CFatFileCB::FlushAllL()"));
   724 
       
   725     //-- define this symbol in order to enable legacy behaviour, i.e. compulsory updating file dir. entry on flush.
       
   726     //-- otherwise the FlushAllL() will update the file dir. entry only if it differs from what is on the media, i.e.
       
   727     //-- file size, start cluster, attributes and modification timestamp
       
   728     #define ALWAYS_UPDATE_ENTRY_ON_FLUSH
       
   729 
       
   730 	__PRINT1(_L("CFatFileCB::FlushAllL[0x%x]"), this);
   617 
   731 
   618     if (Mount().IsCurrentMount()==EFalse)
   732     if (Mount().IsCurrentMount()==EFalse)
   619 		User::Leave(KErrDisMounted);
   733 		User::Leave(KErrDisMounted);
   620 
   734 
   621     FatMount().CheckStateConsistentL();
   735     FatMount().CheckStateConsistentL();
   622     FatMount().CheckWritableL();
   736     FatMount().CheckWritableL();
   623 
   737 
       
   738 	if(!FileSizeModified() && !FileAttModified() && !FileTimeModified())
       
   739         return; //-- nothing has changed in the file entry at all
       
   740 
       
   741 
       
   742     //-- read file dir. entry
   624 	TFatDirEntry entry;
   743 	TFatDirEntry entry;
   625 	FatMount().ReadDirEntryL(iFileDirPos,entry);
   744 	FatMount().ReadDirEntryL(iFileDosEntryPos,entry);
   626 	__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   745 	__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   627 	entry.SetAttributes(iAtt&KEntryAttMaskSupported);
   746 
   628 	entry.SetSize(Size());
   747     //-- the problem with KEntryAttModified here is that the file server uses this flag to 
   629 	entry.SetTime(iModified, FatMount().TimeOffset());
   748     //-- deal with dirty file data. This means that this flag can be set even if there were no changes
   630 	entry.SetStartCluster(iStartCluster);
   749     //-- in file time and attributes. Just check if any of the entry field has changed at all
   631 
   750     
   632 	TBool setNotify = FatMount().GetNotifyUser();
   751     TBool bUpdateDirEntry = ETrue;
       
   752     const TTimeIntervalSeconds  timeOffset = FatMount().TimeOffset();
       
   753 
       
   754 #ifndef ALWAYS_UPDATE_ENTRY_ON_FLUSH
       
   755     
       
   756     TBool bTimeModified = FileTimeModified();  //-- check if file modifiication time has been changed explicitly
       
   757     if(bTimeModified)
       
   758         {//-- additional check; for FAT entry modification time has 2 sec. granularity.
       
   759         bTimeModified = !entry.IsTimeTheSame(iModified, timeOffset);
       
   760         }
       
   761 
       
   762     if(!bTimeModified)
       
   763       if(//-- TS is the same as on the media, check other entry fields
       
   764         (entry.Attributes() == (Att() & KEntryAttMaskSupported)) && //-- file attributes have not changed
       
   765         (entry.Size() == FCB_FileSize()) &&                         //-- file size hasn't changed
       
   766         (entry.StartCluster() == FCB_StartCluster())                //-- file start cluster hasn't changed 
       
   767         )               
       
   768         {
       
   769         bUpdateDirEntry = EFalse; //-- no need to update file dir. entry
       
   770         }
       
   771 
       
   772 #endif //#ifndef ALWAYS_UPDATE_ENTRY_TS_ON_FLUSH
       
   773 
       
   774     if(bUpdateDirEntry)
       
   775         {//-- write entry to the media
       
   776 	    __PRINT(_L("  CFatFileCB::FlushAllL #1"));
       
   777         entry.SetAttributes(Att() & KEntryAttMaskSupported);
       
   778 	    entry.SetSize(FCB_FileSize());
       
   779 	    entry.SetTime(iModified, timeOffset);
       
   780 	    
       
   781         entry.SetStartCluster(FCB_StartCluster());
       
   782 
       
   783 	    const TBool setNotify = FatMount().GetNotifyUser();
   633 	if(setNotify)
   784 	if(setNotify)
   634 		{
   785 		{
   635 		FatMount().SetNotifyOff();	// do not launch a notifier
   786 		FatMount().SetNotifyOff();	// do not launch a notifier
   636 		}
   787 		}
   637 
   788 
   638 	TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry));
   789 	    TRAPD(ret, FatMount().WriteDirEntryL(iFileDosEntryPos,entry));
   639 	
   790 	
   640 	if(setNotify)
   791 	if(setNotify)
   641 		{
   792 		{
   642 		FatMount().SetNotifyOn();
   793 		FatMount().SetNotifyOn();
   643 		}
   794 		}
   644 
   795 
   645 	User::LeaveIfError(ret);
   796 	User::LeaveIfError(ret);
   646 	iAtt&=(~KEntryAttModified);
   797 
   647 	iFileSizeModified=EFalse;
   798         IndicateFileSizeModified(EFalse);
       
   799         IndicateFileTimeModified(EFalse);
       
   800 	    }
       
   801 
       
   802 
       
   803         //-- KEntryAttModified must be reset anyway
       
   804         IndicateFileAttModified(EFalse); 
   648 	}
   805 	}
   649 
   806 
   650 //-----------------------------------------------------------------------------
   807 //-----------------------------------------------------------------------------
   651 
   808 
   652 /**
   809 /**
   661     FatMount().CheckWritableL();
   818     FatMount().CheckWritableL();
   662 
   819 
   663     const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name
   820     const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name
   664 
   821 
   665 
   822 
   666 	FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos);
   823 	FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename, iFileDosEntryPos);
   667 	
   824 	
   668     AllocBufferL(iFileName, fileName);
   825     AllocBufferL(iFileName, fileName);
   669 	
   826 	
   670 	if(!FatMount().IsRuggedFSys())
   827 	if(!FatMount().IsRuggedFSys())
   671 		FAT().FlushL();
   828 		FAT().FlushL();
   710 		return r;
   867 		return r;
   711 
   868 
   712 	aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos);
   869 	aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos);
   713 	aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2();
   870 	aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2();
   714 	const TUint myStartPos = iCurrentPos.iPos;
   871 	const TUint myStartPos = iCurrentPos.iPos;
   715 	if ( myStartPos + length > (TUint)Size())
   872 	if ( myStartPos + length > FCB_FileSize())
   716 		return KErrArgument;
   873 		return KErrArgument;
   717 
   874 
   718 	TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo));
   875 	TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo));
   719 	if (r != KErrNone)
   876 	if (r != KErrNone)
   720 		return r;
   877 		return r;
   721 
   878 
   722 	aStartPos = iCurrentPos.iPos;
   879 	aStartPos = iCurrentPos.iPos;
   723 	if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length)))
   880 	if ((I64LOW(aStartPos) == FCB_FileSize()) || ( I64LOW(aStartPos) == (myStartPos + length)))
   724 		return KErrCompletion;
   881 		return KErrCompletion;
   725 	else
   882 	else
   726 		return KErrNone;
   883 		return KErrNone;
   727 	}
   884 	}
   728 
   885 
   754 /**
   911 /**
   755     Overwrites file's start cluster (iStartCluster) in its directory entry.
   912     Overwrites file's start cluster (iStartCluster) in its directory entry.
   756 */
   913 */
   757 void CFatFileCB::FlushStartClusterL()
   914 void CFatFileCB::FlushStartClusterL()
   758 	{
   915 	{
   759 	__PRINT(_L("CFatFileCB::FlushStartClusterL"));
   916 	__PRINT1(_L("CFatFileCB::FlushStartClusterL[0x%x]"), this);
   760 
   917 
   761     CFatMountCB& mount = FatMount();
   918     CFatMountCB& mount = FatMount();
   762     TFatDirEntry dirEntry;
   919     TFatDirEntry dirEntry;
   763     
   920     
   764     mount.ReadDirEntryL(iFileDirPos, dirEntry);      //-- read this file's dir. entry
   921     mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry
   765     dirEntry.SetStartCluster(iStartCluster);         //-- set new start cluster
   922     dirEntry.SetStartCluster(FCB_StartCluster());    //-- set new start cluster
   766     mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back
   923     mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back
   767 	}
   924 	}
   768 
   925 
   769 
   926 
   770 
   927 /**
   771 
   928     This is a RuggedFAT - specific method. Writes file size to the corresponding field of its file directory entry.
   772 
   929 */
       
   930 void CFatFileCB::WriteFileSizeL(TUint aSize)
       
   931 	{
       
   932 	__PRINT2(_L("CFatFileCB::WriteFileSizeL[0x%x], sz:%d"), this, aSize);
       
   933 
       
   934     CFatMountCB& mount = FatMount();
       
   935     TFatDirEntry dirEntry;
       
   936 
       
   937     mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry
       
   938     dirEntry.SetSize(aSize);                         //-- set new size
       
   939     mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back
       
   940 
       
   941     IndicateFileSizeModified(EFalse);
       
   942     }
       
   943 
       
   944 
       
   945 
       
   946 
       
   947 
       
   948 
       
   949