userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp
branchRCL_3
changeset 87 2f92ad2dc5db
parent 80 597aaf25e343
equal deleted inserted replaced
81:e7d2d738d3c2 87:2f92ad2dc5db
    37 /**
    37 /**
    38 Calculate the FAT size in sectors for a Fat32 volume
    38 Calculate the FAT size in sectors for a Fat32 volume
    39 
    39 
    40 @return The number of sectors
    40 @return The number of sectors
    41 */
    41 */
    42 TUint32 CFatFormatCB::MaxFat32Sectors() const
    42 TUint CFatFormatCB::MaxFat32Sectors() const
    43 	{
    43 	{
    44 	TUint32 calc1 = iMaxDiskSectors - iReservedSectors;
    44 	TUint32 calc1 = iMaxDiskSectors - iReservedSectors;
    45 	TUint32 calc2 = (256 * iSectorsPerCluster) + iNumberOfFats;
    45 	TUint32 calc2 = (256 * iSectorsPerCluster) + iNumberOfFats;
    46 	calc2 = calc2 >> 1;
    46 	calc2 = calc2 >> 1;
    47 	return (calc1 + (calc2 - 1))/calc2;
    47 	return ((calc1 + (calc2 - 1))/calc2);
    48 	}
    48 	}
    49 
    49 
    50 
    50 
    51 const TUint KDefFatResvdSec = 1;    ///< default number of FAT12/16 reserved sectors
    51 const TUint KDefFatResvdSec = 1;    ///< default number of FAT12/16 reserved sectors
    52 const TUint KDefFat32ResvdSec = 32; ///< default number of FAT32 reserved sectors
    52 const TUint KDefFat32ResvdSec = 32; ///< default number of FAT32 reserved sectors
    74 Setting set to adhere to Rules of Count of clusters for FAT type
    74 Setting set to adhere to Rules of Count of clusters for FAT type
    75 
    75 
    76 @param  aDiskSizeInSectors Size of volume in sectors
    76 @param  aDiskSizeInSectors Size of volume in sectors
    77 @return system-wide error code
    77 @return system-wide error code
    78 */
    78 */
    79 TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
    79 TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TUint aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
    80 	{
    80 	{
    81 	__PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskNormal() sectors:%d"), aDiskSizeInSectors);
    81 	__PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskNormal() sectors:%d"), aDiskSizeInSectors);
    82     
    82     
    83     if( Drive().IsRemovable() )
    83     if( Drive().IsRemovable() )
    84 		iNumberOfFats = KNumberOfFatsExternal;
    84 		iNumberOfFats = KNumberOfFatsExternal;
   115 		iSectorsPerFat=MaxFat12Sectors();
   115 		iSectorsPerFat=MaxFat12Sectors();
   116 		}
   116 		}
   117 	else if(aDiskSizeInSectors<1048576) // >= 16Mb - FAT16   < (1048576) 512MB
   117 	else if(aDiskSizeInSectors<1048576) // >= 16Mb - FAT16   < (1048576) 512MB
   118 		{
   118 		{
   119 		iFileSystemName=KFileSystemName16;
   119 		iFileSystemName=KFileSystemName16;
   120 		TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
   120 		TUint minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
   121 		iRootDirEntries=512;
   121 		iRootDirEntries=512;
   122 		iSectorsPerCluster=1;
   122 		iSectorsPerCluster=1;
       
   123 		
   123 		while (minSectorsPerCluster>iSectorsPerCluster)
   124 		while (minSectorsPerCluster>iSectorsPerCluster)
   124 			iSectorsPerCluster<<=1;
   125 			iSectorsPerCluster<<=1;
       
   126 
   125 		iSectorsPerFat=MaxFat16Sectors();
   127 		iSectorsPerFat=MaxFat16Sectors();
   126 		}
   128 		}
   127 	else	//use FAT32
   129 	else	//use FAT32
   128 		{
   130 		{
   129 		iFileSystemName=KFileSystemName32;
   131 		iFileSystemName=KFileSystemName32;
   193 	{
   195 	{
   194 	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   196 	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   195     return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors;
   197     return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors;
   196 	}
   198 	}
   197 
   199 
   198 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster)
   200 void CFatFormatCB::AdjustClusterSize(TUint aRecommendedSectorsPerCluster)
   199 	{
   201 	{
   200     const TInt KMaxSecPerCluster = 64;	// 32K
   202     const TUint KMaxSecPerCluster = 64;	// 32K
       
   203 
   201 	while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
   204 	while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
   202 		iSectorsPerCluster<<= 1;
   205 		iSectorsPerCluster<<= 1;
       
   206 
   203 	}
   207 	}
   204 
   208 
   205 // AdjustFirstDataSectorAlignment()
   209 // AdjustFirstDataSectorAlignment()
   206 // Attempts to align the first data sector on an erase block boundary by modifying the
   210 // Attempts to align the first data sector on an erase block boundary by modifying the
   207 // number of reserved sectors.
   211 // number of reserved sectors.
   208 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors)
   212 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TUint aEraseBlockSizeInSectors)
   209 	{
   213 	{
   210 	const TBool bFat16 = Is16BitFat();
   214 	const TBool bFat16 = Is16BitFat();
   211     const TBool bFat32 = Is32BitFat();
   215     const TBool bFat32 = Is32BitFat();
   212 
   216 
   213 	// Save these 2 values in the event of a convergence failure; this should 
   217 	// Save these 2 values in the event of a convergence failure; this should 
   214 	// hopefully never happen, but we will cater for this in release mode to be safe,
   218 	// hopefully never happen, but we will cater for this in release mode to be safe,
   215 	TInt reservedSectorsSaved = iReservedSectors;
   219 	TUint reservedSectorsSaved = iReservedSectors;
   216 	TInt sectorsPerFatSaved = iSectorsPerFat;
   220 	TUint sectorsPerFatSaved = iSectorsPerFat;
   217 
   221 
   218 	TInt reservedSectorsOld = 0;
   222 	TUint reservedSectorsOld = 0;
   219 
   223 
   220 	// zero for FAT32
   224 	// zero for FAT32
   221 	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   225 	TUint rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   222 	TInt fatSectors = 0;
   226 	TUint fatSectors = 0;
   223 
   227 
   224 	TInt KMaxIterations = 10;
   228 	TUint KMaxIterations = 10;
   225 	TInt n;
   229 	TUint n;
   226 	for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++)
   230 	for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++)
   227 		{
   231 		{
   228 		reservedSectorsOld = iReservedSectors;
   232 		reservedSectorsOld = iReservedSectors;
   229 
   233 
   230 		iSectorsPerFat = bFat32 ? MaxFat32Sectors() : bFat16 ? MaxFat16Sectors() : MaxFat12Sectors();
   234 		iSectorsPerFat = bFat32 ? MaxFat32Sectors() : bFat16 ? MaxFat16Sectors() : MaxFat12Sectors();
   235 		TInt  nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors;
   239 		TInt  nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors;
   236 
   240 
   237 		iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors;
   241 		iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors;
   238 		}
   242 		}
   239 	
   243 	
   240 	ASSERT(iReservedSectors >= (TInt) (bFat32 ? KDefFat32ResvdSec : KDefFatResvdSec));
   244 	ASSERT(iReservedSectors >= (bFat32 ? KDefFat32ResvdSec : KDefFatResvdSec));
   241 
   245 
   242 	if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0)
   246 	if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0)
   243 		{
   247 		{
   244 		return KErrNone;
   248 		return KErrNone;
   245 		}
   249 		}
   312 		{
   316 		{
   313 		bootSector.SetFatSectors32(0);
   317 		bootSector.SetFatSectors32(0);
   314 		bootSector.SetFatSectors(iSectorsPerFat);
   318 		bootSector.SetFatSectors(iSectorsPerFat);
   315 		bootSector.SetRootDirEntries(iRootDirEntries);
   319 		bootSector.SetRootDirEntries(iRootDirEntries);
   316 
   320 
   317 		if (iMaxDiskSectors<=(TInt)KMaxTUint16)
   321 		if (iMaxDiskSectors<=KMaxTUint16)
   318 			{
   322 			{
   319 			bootSector.SetTotalSectors(iMaxDiskSectors);
   323 			bootSector.SetTotalSectors(iMaxDiskSectors);
   320 			bootSector.SetHugeSectors(0);
   324 			bootSector.SetHugeSectors(0);
   321 			}
   325 			}
   322 		else
   326 		else
   566     Initialize the user specific format parameters for fixed sized disk.
   570     Initialize the user specific format parameters for fixed sized disk.
   567     
   571     
   568     @param  aDiskSizeInSectors disk size in sectors
   572     @param  aDiskSizeInSectors disk size in sectors
   569     @return system-wide error code
   573     @return system-wide error code
   570 */
   574 */
   571 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors)
   575 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TUint aDiskSizeInSectors)
   572 	{
   576 	{
   573     __PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() sectors:%d"), aDiskSizeInSectors);
   577     __PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() sectors:%d"), aDiskSizeInSectors);
   574     Dump_TLDFormatInfo(iSpecialInfo());
   578     Dump_TLDFormatInfo(iSpecialInfo());
   575 
   579 
   576     //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32
   580     //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32
   589         iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16)
   593         iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16)
   590     else
   594     else
   591         iReservedSectors = iSpecialInfo().iReservedSectors;
   595         iReservedSectors = iSpecialInfo().iReservedSectors;
   592 
   596 
   593 
   597 
   594     const TInt KMaxSecPerCluster    = 64; 
   598     const TUint KMaxSecPerCluster    = 64; 
   595 	const TInt KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
   599 	const TUint KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
   596 
   600 
   597     iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster;
   601     iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster;
   598     if(iSectorsPerCluster <= 0)
   602     if(iSectorsPerCluster <= 0)
   599         {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster
   603         {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster
   600         iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later
   604         iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later
   611         iSectorsPerCluster = 1;
   615         iSectorsPerCluster = 1;
   612 		iRootDirEntries = 128;
   616 		iRootDirEntries = 128;
   613         }
   617         }
   614 	else if (aDiskSizeInSectors < 8192) // < 4MB
   618 	else if (aDiskSizeInSectors < 8192) // < 4MB
   615         {
   619         {
   616         iSectorsPerCluster = Min(iSectorsPerCluster, 2);
   620         iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)2);
   617 		iRootDirEntries = 256;
   621 		iRootDirEntries = 256;
   618         }
   622         }
   619 	else if (aDiskSizeInSectors < 32768) // < 16MB
   623 	else if (aDiskSizeInSectors < 32768) // < 16MB
   620         {
   624         {
   621         iSectorsPerCluster = Min(iSectorsPerCluster, 4);
   625         iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)4);
   622 		iRootDirEntries = 512;
   626 		iRootDirEntries = 512;
   623         }
   627         }
   624 	else if (aDiskSizeInSectors < 1048576) // < 512MB
   628 	else if (aDiskSizeInSectors < 1048576) // < 512MB
   625         {
   629         {
   626         iSectorsPerCluster = Min(iSectorsPerCluster, 8);
   630         iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)8);
   627 		iRootDirEntries = 512;
   631 		iRootDirEntries = 512;
   628         }
   632         }
   629     else // FAT32
   633     else // FAT32
   630 		{
   634 		{
   631         iRootDirEntries = 512;
   635         iRootDirEntries = 512;
   632         iSectorsPerCluster = Min(iSectorsPerCluster, KMaxSecPerCluster);
   636         iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)KMaxSecPerCluster);
   633         }
   637         }
   634 
   638 
   635 
   639 
   636     //-----------------------------------------
   640     //-----------------------------------------
   637 
   641 
   817     TInt sizeofFatAndRootDir;
   821     TInt sizeofFatAndRootDir;
   818     if (iFileSystemName != KFileSystemName32)
   822     if (iFileSystemName != KFileSystemName32)
   819 		sizeofFatAndRootDir = iSectorsPerFat*iNumberOfFats + ((iRootDirEntries*KSizeOfFatDirEntry+(1<<iSectorSizeLog2)-1)>>iSectorSizeLog2);
   823 		sizeofFatAndRootDir = iSectorsPerFat*iNumberOfFats + ((iRootDirEntries*KSizeOfFatDirEntry+(1<<iSectorSizeLog2)-1)>>iSectorSizeLog2);
   820     else
   824     else
   821         sizeofFatAndRootDir = (iRootClusterNum-2) * iSectorsPerCluster;
   825         sizeofFatAndRootDir = (iRootClusterNum-2) * iSectorsPerCluster;
   822     TInt firstFreeSector = iReservedSectors + sizeofFatAndRootDir;
   826 
       
   827     TUint firstFreeSector = iReservedSectors + sizeofFatAndRootDir;
   823 
   828 
   824     // Check in rare case that corrupt in critical area
   829     // Check in rare case that corrupt in critical area
   825     // which includes bootsector, FAT table, (and root dir if not FAT32)
   830     // which includes bootsector, FAT table, (and root dir if not FAT32)
   826     TInt i, r;
   831     TInt i, r;
   827     for (i=0; i<iBadSectors.Count(); ++i)
   832     for (i=0; i<iBadSectors.Count(); ++i)
   828         {
   833         {
   829         TInt badSector = iBadSectors[i];
   834         const TUint badSector = iBadSectors[i];
   830         // Check in rare case that corrupt in critical area
   835         // Check in rare case that corrupt in critical area
   831         // which includes bootsector, FAT table, (and root dir if not FAT32)
   836         // which includes bootsector, FAT table, (and root dir if not FAT32)
   832         if (firstFreeSector > badSector)
   837         if (firstFreeSector > badSector)
   833             {
   838             {
   834             if (badSector == 0) // Boot sector corrupt
   839             if (badSector == 0) // Boot sector corrupt