userlibandfileserver/fileserver/sfat/sl_fat16.cpp
changeset 15 4122176ea935
parent 0 a41df078684a
child 80 597aaf25e343
equal deleted inserted replaced
0:a41df078684a 15:4122176ea935
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 // f32\sfat\sl_fat16.cpp
    14 // f32\sfat\sl_fat16.cpp
    15 // 
    15 // 
    16 //
    16 //
       
    17 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    18 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    19 //!!
       
    20 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
       
    21 //!!
       
    22 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    23 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    17 
    24 
    18 
    25 
    19 #include "sl_std.h"
    26 #include "sl_std.h"
    20 #include "sl_cache.h"
    27 #include "sl_cache.h"
    21 
    28 
    27 
    34 
    28 @param  aDiskSizeInSectors Size of volume in sectors
    35 @param  aDiskSizeInSectors Size of volume in sectors
    29 @return system-wide error code
    36 @return system-wide error code
    30 */
    37 */
    31 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
    38 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
    32 	{
    39     {
    33 	if( Drive().IsRemovable() )
    40     if( Drive().IsRemovable() )
    34 		iNumberOfFats = KNumberOfFatsExternal;
    41         iNumberOfFats = KNumberOfFatsExternal;
    35 	else
    42     else
    36 		iNumberOfFats = KNumberOfFatsInternal;
    43         iNumberOfFats = KNumberOfFatsInternal;
    37 	
    44     
    38 	iReservedSectors=KDefFatResvdSec;		
    45     iReservedSectors=KDefFatResvdSec;       
    39 	if (aDiskSizeInSectors<4084*1) // < 2MB
    46     if (aDiskSizeInSectors<4084*1) // < 2MB
    40 		{
    47         {
    41 		iRootDirEntries=128;
    48         iRootDirEntries=128;
    42 		iSectorsPerCluster=1;
    49         iSectorsPerCluster=1;
    43 		iFileSystemName=KFileSystemName12;
    50         iFileSystemName=KFileSystemName12;
    44 		iSectorsPerFat=MaxFat12Sectors();
    51         iSectorsPerFat=MaxFat12Sectors();
    45    		}
    52         }
    46 	else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors)
    53     else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors)
    47 		{
    54         {
    48 		iRootDirEntries=256; 
    55         iRootDirEntries=256; 
    49 		iSectorsPerCluster=2;
    56         iSectorsPerCluster=2;
    50 		iFileSystemName=KFileSystemName12;
    57         iFileSystemName=KFileSystemName12;
    51 		iSectorsPerFat=MaxFat12Sectors();
    58         iSectorsPerFat=MaxFat12Sectors();
    52 		}
    59         }
    53 	else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors)
    60     else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors)
    54 		{
    61         {
    55 		iRootDirEntries=512;
    62         iRootDirEntries=512;
    56 		iSectorsPerCluster=4;
    63         iSectorsPerCluster=4;
    57 		iFileSystemName=KFileSystemName12;
    64         iFileSystemName=KFileSystemName12;
    58 		iSectorsPerFat=MaxFat12Sectors();
    65         iSectorsPerFat=MaxFat12Sectors();
    59 		}
    66         }
    60 	else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors)
    67     else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors)
    61 		{
    68         {
    62 		iRootDirEntries=512;
    69         iRootDirEntries=512;
    63 		iSectorsPerCluster=8;
    70         iSectorsPerCluster=8;
    64 		iFileSystemName=KFileSystemName12;
    71         iFileSystemName=KFileSystemName12;
    65 		iSectorsPerFat=MaxFat12Sectors();
    72         iSectorsPerFat=MaxFat12Sectors();
    66 		}
    73         }
    67 	else	// >= 16Mb - FAT16
    74     else    // >= 16Mb - FAT16
    68 		{
    75         {
    69 		iFileSystemName=KFileSystemName16;
    76         iFileSystemName=KFileSystemName16;
    70 		TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
    77         TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
    71 		iRootDirEntries=512;
    78         iRootDirEntries=512;
    72 		iSectorsPerCluster=1;
    79         iSectorsPerCluster=1;
    73 		while (minSectorsPerCluster>iSectorsPerCluster)
    80         while (minSectorsPerCluster>iSectorsPerCluster)
    74 			iSectorsPerCluster<<=1;
    81             iSectorsPerCluster<<=1;
    75 		iSectorsPerFat=MaxFat16Sectors();
    82         iSectorsPerFat=MaxFat16Sectors();
    76 		}
    83         }
    77 	
    84     
    78 	// Ensure cluster size is a multiple of the block size
    85     // Ensure cluster size is a multiple of the block size
    79 	TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2;
    86     TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2;
    80 	__PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors);
    87     __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors);
    81 	ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors));
    88     ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors));
    82 	if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors))
    89     if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors))
    83 		{
    90         {
    84 		__PRINT1(_L("iSectorsPerCluster	(old): %d"),iSectorsPerCluster);
    91         __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster);
    85 		AdjustClusterSize(blockSizeInSectors);
    92         AdjustClusterSize(blockSizeInSectors);
    86 		__PRINT1(_L("iSectorsPerCluster	(new): %d"),iSectorsPerCluster);
    93         __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster);
    87 		}
    94         }
    88 	
    95     
    89 	// Align first data sector on an erase block boundary if
    96     // Align first data sector on an erase block boundary if
    90 	// (1) the iEraseBlockSize is specified
    97     // (1) the iEraseBlockSize is specified
    91 	// (2) the start of the partition is already aligned to an erase block boundary, 
    98     // (2) the start of the partition is already aligned to an erase block boundary, 
    92 	//     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
    99     //     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
    93 	__PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
   100     __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
    94 	TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
   101     TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
    95 	__PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
   102     __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
    96 	ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));	
   103     ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));    
    97 	ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
   104     ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
    98 	if ((eraseblockSizeInSectors != 0) &&
   105     if ((eraseblockSizeInSectors != 0) &&
    99 		(iHiddenSectors % eraseblockSizeInSectors == 0) &&	
   106         (iHiddenSectors % eraseblockSizeInSectors == 0) &&  
   100 		(IsPowerOf2(eraseblockSizeInSectors)) &&
   107         (IsPowerOf2(eraseblockSizeInSectors)) &&
   101 		(eraseblockSizeInSectors >= blockSizeInSectors))
   108         (eraseblockSizeInSectors >= blockSizeInSectors))
   102 		{
   109         {
   103 		TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
   110         TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
   104 		ASSERT(r == KErrNone);
   111         ASSERT(r == KErrNone);
   105 		(void) r;
   112         (void) r;
   106 		}
   113         }
   107 	__PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
   114     __PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
   108 	__PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
   115     __PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
   109 
   116 
   110     return KErrNone;
   117     return KErrNone;
   111 	}
   118     }
   112 
   119 
   113 TInt CFatFormatCB::FirstDataSector() const
   120 TInt CFatFormatCB::FirstDataSector() const
   114 	{
   121     {
   115 	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   122     TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   116     return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors;
   123     return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors;
   117 	}
   124     }
   118 
   125 
   119 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster)
   126 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster)
   120 	{
   127     {
   121     const TInt KMaxSecPerCluster = 64;	// 32K
   128     const TInt KMaxSecPerCluster = 64;  // 32K
   122 	while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
   129     while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
   123 		iSectorsPerCluster<<= 1;
   130         iSectorsPerCluster<<= 1;
   124 	}
   131     }
   125 
   132 
   126 // AdjustFirstDataSectorAlignment()
   133 // AdjustFirstDataSectorAlignment()
   127 // Attempts to align the first data sector on an erase block boundary by modifying the
   134 // Attempts to align the first data sector on an erase block boundary by modifying the
   128 // number of reserved sectors.
   135 // number of reserved sectors.
   129 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors)
   136 TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors)
   130 	{
   137     {
   131 	const TBool bFat16 = Is16BitFat();
   138     const TBool bFat16 = Is16BitFat();
   132 
   139 
   133 	// Save these 2 values in the event of a convergence failure; this should 
   140     // Save these 2 values in the event of a convergence failure; this should 
   134 	// hopefully never happen, but we will cater for this in release mode to be safe,
   141     // hopefully never happen, but we will cater for this in release mode to be safe,
   135 	TInt reservedSectorsSaved = iReservedSectors;
   142     TInt reservedSectorsSaved = iReservedSectors;
   136 	TInt sectorsPerFatSaved = iSectorsPerFat;
   143     TInt sectorsPerFatSaved = iSectorsPerFat;
   137 
   144 
   138 	TInt reservedSectorsOld = 0;
   145     TInt reservedSectorsOld = 0;
   139 
   146 
   140 	// zero for FAT32
   147     // zero for FAT32
   141 	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   148     TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   142 	TInt fatSectors = 0;
   149     TInt fatSectors = 0;
   143 
   150 
   144 	TInt KMaxIterations = 10;
   151     TInt KMaxIterations = 10;
   145 	TInt n;
   152     TInt n;
   146 	for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++)
   153     for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++)
   147 		{
   154         {
   148 		reservedSectorsOld = iReservedSectors;
   155         reservedSectorsOld = iReservedSectors;
   149 
   156 
   150 		iSectorsPerFat = bFat16 ? MaxFat16Sectors() : MaxFat12Sectors();
   157         iSectorsPerFat = bFat16 ? MaxFat16Sectors() : MaxFat12Sectors();
   151 
   158 
   152 		fatSectors = iSectorsPerFat * iNumberOfFats;
   159         fatSectors = iSectorsPerFat * iNumberOfFats;
   153 
   160 
   154 		// calculate number of blocks
   161         // calculate number of blocks
   155 		TInt nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors;
   162         TInt nBlocks = (iReservedSectors + fatSectors + rootDirSectors + aEraseBlockSizeInSectors-1) / aEraseBlockSizeInSectors;
   156 
   163 
   157 		iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors;
   164         iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors;
   158 		}
   165         }
   159 	
   166     
   160 	ASSERT(iReservedSectors >= (TInt) KDefFatResvdSec);
   167     ASSERT(iReservedSectors >= (TInt) KDefFatResvdSec);
   161 
   168 
   162 	if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0)
   169     if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0)
   163 		{
   170         {
   164 		return KErrNone;
   171         return KErrNone;
   165 		}
   172         }
   166 	else
   173     else
   167 		{
   174         {
   168 		iReservedSectors = reservedSectorsSaved;
   175         iReservedSectors = reservedSectorsSaved;
   169 		iSectorsPerFat = sectorsPerFatSaved;
   176         iSectorsPerFat = sectorsPerFatSaved;
   170 		return KErrGeneral;
   177         return KErrGeneral;
   171 		}
   178         }
   172 	}
   179     }
   173 
   180 
   174 /**
   181 /**
   175     Initialize the user specific format parameters for fixed sized disk.
   182     Initialize the user specific format parameters for fixed sized disk.
   176     
   183     
   177     @param  aDiskSizeInSectors disk size in sectors
   184     @param  aDiskSizeInSectors disk size in sectors
   178     @return system-wide error code
   185     @return system-wide error code
   179 */
   186 */
   180 TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors)
   187 TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors)
   181 	{
   188     {
   182     //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32
   189     //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32
   183 
   190 
   184     if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable)
   191     if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable)
   185 		iNumberOfFats = 1;
   192         iNumberOfFats = 1;
   186     else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables)
   193     else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables)
   187 		iNumberOfFats = 2;
   194         iNumberOfFats = 2;
   188     else if(Drive().IsRemovable())
   195     else if(Drive().IsRemovable())
   189 		iNumberOfFats = KNumberOfFatsExternal;
   196         iNumberOfFats = KNumberOfFatsExternal;
   190 	else 
   197     else 
   191 		iNumberOfFats = KNumberOfFatsInternal;
   198         iNumberOfFats = KNumberOfFatsInternal;
   192 
   199 
   193 
   200 
   194     if(iSpecialInfo().iReservedSectors == 0)
   201     if(iSpecialInfo().iReservedSectors == 0)
   195         iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16)
   202         iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16)
   196     else
   203     else
   197         iReservedSectors = iSpecialInfo().iReservedSectors;
   204         iReservedSectors = iSpecialInfo().iReservedSectors;
   198 
   205 
   199 
   206 
   200     const TInt KMaxSecPerCluster = 64; 
   207     const TInt KMaxSecPerCluster = 64; 
   201 	const TInt KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
   208     const TInt KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
   202 	
   209     
   203     iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster;
   210     iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster;
   204     if(iSectorsPerCluster <= 0)
   211     if(iSectorsPerCluster <= 0)
   205         {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster
   212         {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster
   206         iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later
   213         iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later
   207         }
   214         }
   208     else
   215     else
   209         {
   216         {
   210         iSectorsPerCluster = Min(1<<Log2(iSectorsPerCluster), KMaxSecPerCluster);
   217         iSectorsPerCluster = Min(1<<Log2(iSectorsPerCluster), KMaxSecPerCluster);
   211 	    }
   218         }
   212 
   219 
   213     //-----------------------------------------
   220     //-----------------------------------------
   214 
   221 
   215 	if (aDiskSizeInSectors < 4096) // < 2MB
   222     if (aDiskSizeInSectors < 4096) // < 2MB
   216         {
   223         {
   217         iSectorsPerCluster = 1;
   224         iSectorsPerCluster = 1;
   218 		iRootDirEntries = 128;
   225         iRootDirEntries = 128;
   219         }
   226         }
   220 	else if (aDiskSizeInSectors < 8192) // < 4MB
   227     else if (aDiskSizeInSectors < 8192) // < 4MB
   221         {
   228         {
   222         iSectorsPerCluster = Min(iSectorsPerCluster, 2);
   229         iSectorsPerCluster = Min(iSectorsPerCluster, 2);
   223 		iRootDirEntries = 256;
   230         iRootDirEntries = 256;
   224         }
   231         }
   225 	else if (aDiskSizeInSectors < 32768) // < 16MB
   232     else if (aDiskSizeInSectors < 32768) // < 16MB
   226         {
   233         {
   227         iSectorsPerCluster = Min(iSectorsPerCluster, 4);
   234         iSectorsPerCluster = Min(iSectorsPerCluster, 4);
   228 		iRootDirEntries = 512;
   235         iRootDirEntries = 512;
   229         }
   236         }
   230 	else if (aDiskSizeInSectors < 131072) // < 64MB
   237     else if (aDiskSizeInSectors < 131072) // < 64MB
   231         {
   238         {
   232         iSectorsPerCluster = Min(iSectorsPerCluster, 8);
   239         iSectorsPerCluster = Min(iSectorsPerCluster, 8);
   233 		iRootDirEntries = 512;
   240         iRootDirEntries = 512;
   234         }
   241         }
   235 	else	// >= 64Mb
   242     else    // >= 64Mb
   236 		iRootDirEntries = 512;
   243         iRootDirEntries = 512;
   237 
   244 
   238     //-----------------------------------------
   245     //-----------------------------------------
   239 
   246 
   240 	TLDFormatInfo::TFATBits fatBits = iSpecialInfo().iFATBits;
   247     TLDFormatInfo::TFATBits fatBits = iSpecialInfo().iFATBits;
   241 	if (fatBits == TLDFormatInfo::EFBDontCare)
   248     if (fatBits == TLDFormatInfo::EFBDontCare)
   242 		{
   249         {
   243         const TFatType fatType = SuggestFatType();
   250         const TFatType fatType = SuggestFatType();
   244 		switch(fatType)
   251         switch(fatType)
   245 			{
   252             {
   246 			case EFat12:
   253             case EFat12:
   247 				fatBits = TLDFormatInfo::EFB12;
   254                 fatBits = TLDFormatInfo::EFB12;
   248 				break;
   255                 break;
   249 			case EFat16:
   256             case EFat16:
   250 				fatBits = TLDFormatInfo::EFB16;
   257                 fatBits = TLDFormatInfo::EFB16;
   251 				break;
   258                 break;
   252 			case EFat32:
   259             case EFat32:
   253 				fatBits = TLDFormatInfo::EFB32;
   260                 fatBits = TLDFormatInfo::EFB32;
   254 				break;
   261                 break;
   255 			case EInvalid:
   262             case EInvalid:
   256 				ASSERT(0);
   263                 ASSERT(0);
   257 			}
   264             }
   258 		}
   265         }
   259 
   266 
   260     TFatType reqFatType(EInvalid); //-- requested FAT type
   267     TFatType reqFatType(EInvalid); //-- requested FAT type
   261 
   268 
   262     switch (fatBits)
   269     switch (fatBits)
   263         {
   270         {
   267         reqFatType = EFat12;
   274         reqFatType = EFat12;
   268         break;
   275         break;
   269 
   276 
   270         case TLDFormatInfo::EFB16:
   277         case TLDFormatInfo::EFB16:
   271         iFileSystemName=KFileSystemName16;
   278         iFileSystemName=KFileSystemName16;
   272 		iSectorsPerFat=MaxFat16Sectors();
   279         iSectorsPerFat=MaxFat16Sectors();
   273         reqFatType = EFat16;
   280         reqFatType = EFat16;
   274         break;
   281         break;
   275         
   282         
   276         case TLDFormatInfo::EFB32:
   283         case TLDFormatInfo::EFB32:
   277         __PRINT(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() FAT32 Not supported!"));
   284         __PRINT(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() FAT32 Not supported!"));
   290             return KErrArgument;
   297             return KErrArgument;
   291         }
   298         }
   292 
   299 
   293 
   300 
   294     return KErrNone;
   301     return KErrNone;
   295 	}
   302     }
   296 
   303 
   297 /**
   304 /**
   298     Initialize the format parameters for a custom fixed sized disk
   305     Initialize the format parameters for a custom fixed sized disk
   299 
   306 
   300     @param  aFormatInfo The custom format parameters
   307     @param  aFormatInfo The custom format parameters
   301     @return system-wide error code
   308     @return system-wide error code
   302 */
   309 */
   303 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo)
   310 TInt CFatFormatCB::InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo)
   304 	{
   311     {
   305 	if(aFormatInfo.iFlags & TLDFormatInfo::EOneFatTable)
   312     if(aFormatInfo.iFlags & TLDFormatInfo::EOneFatTable)
   306 		iNumberOfFats = 1;
   313         iNumberOfFats = 1;
   307     else if(aFormatInfo.iFlags & TLDFormatInfo::ETwoFatTables)
   314     else if(aFormatInfo.iFlags & TLDFormatInfo::ETwoFatTables)
   308 		iNumberOfFats = 2;
   315         iNumberOfFats = 2;
   309     else if(Drive().IsRemovable())
   316     else if(Drive().IsRemovable())
   310 		iNumberOfFats = KNumberOfFatsExternal;
   317         iNumberOfFats = KNumberOfFatsExternal;
   311 	else
   318     else
   312 		iNumberOfFats = KNumberOfFatsInternal;	
   319         iNumberOfFats = KNumberOfFatsInternal;  
   313 
   320 
   314 	iRootDirEntries=512;
   321     iRootDirEntries=512;
   315 
   322 
   316 	iSectorsPerCluster = aFormatInfo.iSectorsPerCluster;
   323     iSectorsPerCluster = aFormatInfo.iSectorsPerCluster;
   317 	iSectorsPerTrack   = aFormatInfo.iSectorsPerTrack;
   324     iSectorsPerTrack   = aFormatInfo.iSectorsPerTrack;
   318 	iNumberOfHeads     = aFormatInfo.iNumberOfSides;
   325     iNumberOfHeads     = aFormatInfo.iNumberOfSides;
   319 	iReservedSectors   = aFormatInfo.iReservedSectors ? aFormatInfo.iReservedSectors : KDefFatResvdSec;
   326     iReservedSectors   = aFormatInfo.iReservedSectors ? aFormatInfo.iReservedSectors : KDefFatResvdSec;
   320 	
   327     
   321     switch (aFormatInfo.iFATBits)
   328     switch (aFormatInfo.iFATBits)
   322 		{
   329         {
   323 		case TLDFormatInfo::EFB12:
   330         case TLDFormatInfo::EFB12:
   324 			iFileSystemName = KFileSystemName12;
   331             iFileSystemName = KFileSystemName12;
   325 			iSectorsPerFat  = MaxFat12Sectors();
   332             iSectorsPerFat  = MaxFat12Sectors();
   326 			break;
       
   327 
       
   328 		case TLDFormatInfo::EFB16:
       
   329 			iFileSystemName = KFileSystemName16;
       
   330 			iSectorsPerFat  = MaxFat16Sectors();
       
   331             break;
   333             break;
   332 
   334 
   333 		default:
   335         case TLDFormatInfo::EFB16:
   334 			{
   336             iFileSystemName = KFileSystemName16;
   335 			TInt64 clusters64 = (aFormatInfo.iCapacity / KDefaultSectorSize) / iSectorsPerCluster;
   337             iSectorsPerFat  = MaxFat16Sectors();
   336 			TInt clusters = I64LOW(clusters64);
   338             break;
   337 			if (clusters < 4085)
   339 
   338 				{
   340         default:
   339 				iFileSystemName = KFileSystemName12;
   341             {
   340 				iSectorsPerFat  = MaxFat12Sectors();
   342             TInt64 clusters64 = (aFormatInfo.iCapacity / KDefaultSectorSize) / iSectorsPerCluster;
   341 				}
   343             TInt clusters = I64LOW(clusters64);
   342 			else
   344             if (clusters < 4085)
   343 				{
   345                 {
   344 				iFileSystemName = KFileSystemName16;
   346                 iFileSystemName = KFileSystemName12;
   345 				iSectorsPerFat  = MaxFat16Sectors();
   347                 iSectorsPerFat  = MaxFat12Sectors();
   346                 }
   348                 }
   347 			}
   349             else
   348 		}
   350                 {
       
   351                 iFileSystemName = KFileSystemName16;
       
   352                 iSectorsPerFat  = MaxFat16Sectors();
       
   353                 }
       
   354             }
       
   355         }
   349 
   356 
   350     return KErrNone;
   357     return KErrNone;
   351 	}
   358     }
   352 
   359 
   353 void CFatFormatCB::RecordOldInfoL()
   360 void CFatFormatCB::RecordOldInfoL()
   354     {
   361     {
   355 	__PRINT(_L("CFatFormatCB::RecordOldInfoL"));
   362     __PRINT(_L("CFatFormatCB::RecordOldInfoL"));
   356     // Check if mount or disk is corrupt
   363     // Check if mount or disk is corrupt
   357     // This should be stored in member variable because FatMount is remounted
   364     // This should be stored in member variable because FatMount is remounted
   358     //  every time RFormat::Next() gets called thus FatMount().Initialised()
   365     //  every time RFormat::Next() gets called thus FatMount().Initialised()
   359     //  will be inconsistent with previous state.
   366     //  will be inconsistent with previous state.
   360 	TLocalDriveCapsV3Buf caps;
   367     TLocalDriveCapsV3Buf caps;
   361 	User::LeaveIfError(LocalDrive()->Caps(caps));
   368     User::LeaveIfError(LocalDrive()->Caps(caps));
   362 	iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse;
   369     iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse;
   363     iDiskCorrupt = !FatMount().ConsistentState();
   370     iDiskCorrupt = !FatMount().ConsistentState();
   364     iBadClusters.Reset();
   371     iBadClusters.Reset();
   365     iBadSectors.Reset();
   372     iBadSectors.Reset();
   366     if (!iVariableSize && !iDiskCorrupt && (iMode & EQuickFormat))
   373     if (!iVariableSize && !iDiskCorrupt && (iMode & EQuickFormat))
   367         {
   374         {
   368         iOldFirstFreeSector = FatMount().iFirstFreeByte >> FatMount().SectorSizeLog2();
   375         iOldFirstFreeSector = FatMount().iFirstFreeByte >> FatMount().SectorSizeLog2();
   369         iOldSectorsPerCluster = FatMount().SectorsPerCluster();
   376         iOldSectorsPerCluster = FatMount().SectorsPerCluster();
   370         
   377         
   371         FatMount().FAT().InvalidateCacheL(); //-- invalidate whole FAT cache
   378         FatMount().FAT().InvalidateCacheL(); //-- invalidate whole FAT cache
   372 
   379 
   373     	const TInt maxClusterNum = FatMount().iUsableClusters + KFatFirstSearchCluster;
   380         const TInt maxClusterNum = FatMount().iUsableClusters + KFatFirstSearchCluster;
   374 
   381 
   375         // Collect bad cluster information from current FAT table
   382         // Collect bad cluster information from current FAT table
   376         const TUint32 mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit;
   383         const TUint32 mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit;
   377         for (TInt i=KFatFirstSearchCluster; i<maxClusterNum; i++)
   384         for (TInt i=KFatFirstSearchCluster; i<maxClusterNum; i++)
   378             if (FatMount().FAT().ReadL(i) == mark)
   385             if (FatMount().FAT().ReadL(i) == mark)
   384 Create the boot sector on media for the volume. 
   391 Create the boot sector on media for the volume. 
   385 
   392 
   386 @leave System wide error codes
   393 @leave System wide error codes
   387 */
   394 */
   388 void CFatFormatCB::CreateBootSectorL()
   395 void CFatFormatCB::CreateBootSectorL()
   389 	{
   396     {
   390 	__PRINT1(_L("CFatFormatCB::CreateBootSector() drive:%d"),DriveNumber());
   397     __PRINT1(_L("CFatFormatCB::CreateBootSector() drive:%d"),DriveNumber());
   391 
   398 
   392 	TFatBootSector bootSector;
   399     TFatBootSector bootSector;
   393 
   400 
   394 	bootSector.SetVendorID(KDefaultVendorID);
   401     bootSector.SetVendorID(KDefaultVendorID);
   395 	bootSector.SetBytesPerSector(iBytesPerSector);
   402     bootSector.SetBytesPerSector(iBytesPerSector);
   396 	bootSector.SetSectorsPerCluster(iSectorsPerCluster);
   403     bootSector.SetSectorsPerCluster(iSectorsPerCluster);
   397 	bootSector.SetReservedSectors(iReservedSectors);
   404     bootSector.SetReservedSectors(iReservedSectors);
   398 	bootSector.SetNumberOfFats(iNumberOfFats);
   405     bootSector.SetNumberOfFats(iNumberOfFats);
   399 	bootSector.SetRootDirEntries(iRootDirEntries);
   406     bootSector.SetRootDirEntries(iRootDirEntries);
   400 	if (iMaxDiskSectors<(TInt)KMaxTUint16)
   407     if (iMaxDiskSectors<(TInt)KMaxTUint16)
   401 		bootSector.SetTotalSectors(iMaxDiskSectors);
   408         bootSector.SetTotalSectors(iMaxDiskSectors);
   402 	else
   409     else
   403 		{
   410         {
   404 		bootSector.SetTotalSectors(0);
   411         bootSector.SetTotalSectors(0);
   405 		bootSector.SetHugeSectors(iMaxDiskSectors);
   412         bootSector.SetHugeSectors(iMaxDiskSectors);
   406 		}
   413         }
   407 	TInt numberOfClusters=iMaxDiskSectors/iSectorsPerCluster;
   414     TInt numberOfClusters=iMaxDiskSectors/iSectorsPerCluster;
   408 	if (numberOfClusters>(TInt)KMaxTUint16)
   415     if (numberOfClusters>(TInt)KMaxTUint16)
   409 		User::Leave(KErrTooBig);
   416         User::Leave(KErrTooBig);
   410 	bootSector.SetFatSectors(iSectorsPerFat);
   417     bootSector.SetFatSectors(iSectorsPerFat);
   411 	bootSector.SetReservedByte(0);
   418     bootSector.SetReservedByte(0);
   412 	TTime timeID;
   419     TTime timeID;
   413 	timeID.HomeTime();						//	System time in future?
   420     timeID.HomeTime();                      //  System time in future?
   414 	bootSector.SetUniqueID(I64LOW(timeID.Int64()));	//	Generate UniqueID from time
   421     bootSector.SetUniqueID(I64LOW(timeID.Int64())); //  Generate UniqueID from time
   415 	bootSector.SetVolumeLabel(_L8(""));
   422     bootSector.SetVolumeLabel(_L8(""));
   416 	bootSector.SetFileSysType(iFileSystemName);
   423     bootSector.SetFileSysType(iFileSystemName);
   417 // Floppy specific info:
   424 // Floppy specific info:
   418 	bootSector.SetJumpInstruction();
   425     bootSector.SetJumpInstruction();
   419 	bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor);
   426     bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor);
   420 	bootSector.SetNumberOfHeads(iNumberOfHeads);
   427     bootSector.SetNumberOfHeads(iNumberOfHeads);
   421 	bootSector.SetHiddenSectors(iHiddenSectors);
   428     bootSector.SetHiddenSectors(iHiddenSectors);
   422 	bootSector.SetSectorsPerTrack(iSectorsPerTrack);
   429     bootSector.SetSectorsPerTrack(iSectorsPerTrack);
   423 	bootSector.SetPhysicalDriveNumber(128);
   430     bootSector.SetPhysicalDriveNumber(128);
   424 	bootSector.SetExtendedBootSignature(0x29);
   431     bootSector.SetExtendedBootSignature(0x29);
   425 
   432 
   426 	
   433     
   427     User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector));
   434     User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector));
   428 	}
   435     }
   429 
   436 
   430 //-------------------------------------------------------------------------------------------------------------------
   437 //-------------------------------------------------------------------------------------------------------------------
   431 
   438 
   432 /**
   439 /**
   433 Format a disk section, called iteratively to erase whole of media, on last iteration
   440 Format a disk section, called iteratively to erase whole of media, on last iteration
   435 rest of the volume intact.
   442 rest of the volume intact.
   436 
   443 
   437 @leave System wide error code
   444 @leave System wide error code
   438 */
   445 */
   439 void CFatFormatCB::DoFormatStepL()
   446 void CFatFormatCB::DoFormatStepL()
   440 	{
   447     {
   441 	if (iFormatInfo.iFormatIsCurrent==EFalse)
   448     if (iFormatInfo.iFormatIsCurrent==EFalse)
   442 		{
   449         {
   443 		if (iMode & EForceErase)
   450         if (iMode & EForceErase)
   444 			{
   451             {
   445 			TInt r = FatMount().ErasePassword();
   452             TInt r = FatMount().ErasePassword();
   446 			User::LeaveIfError(r);
   453             User::LeaveIfError(r);
   447 			// CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(), 
   454             // CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(), 
   448 			// so need to stop a remount from occurring in next call to :
   455             // so need to stop a remount from occurring in next call to :
   449 			// TFsFormatNext::DoRequestL((), TDrive::CheckMount().
   456             // TFsFormatNext::DoRequestL((), TDrive::CheckMount().
   450 			FatMount().Drive().SetChanged(EFalse);
   457             FatMount().Drive().SetChanged(EFalse);
   451 			}
   458             }
   452 
   459 
   453         RecordOldInfoL();
   460         RecordOldInfoL();
   454         InitializeFormatDataL();
   461         InitializeFormatDataL();
   455 		FatMount().DoDismount();
   462         FatMount().DoDismount();
   456 		if (iVariableSize)
   463         if (iVariableSize)
   457 			FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize));
   464             FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize));
   458 		}
   465         }
   459     //
   466     //
   460     // Blank disk if not EQuickFormat
   467     // Blank disk if not EQuickFormat
   461     //
   468     //
   462 	if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep)
   469     if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep)
   463 		{
   470         {
   464 		if (iFormatInfo.iFormatIsCurrent == EFalse)
   471         if (iFormatInfo.iFormatIsCurrent == EFalse)
   465 			{//-- firstly invalidate sectors 0-6 inclusive
   472             {//-- firstly invalidate sectors 0-6 inclusive
   466 	        DoZeroFillMediaL(0, 7*iBytesPerSector);
   473             DoZeroFillMediaL(0, 7*iBytesPerSector);
   467 			}
   474             }
   468 
   475 
   469 		TInt ret=FatMount().LocalDrive()->Format(iFormatInfo);
   476         TInt ret=FatMount().LocalDrive()->Format(iFormatInfo);
   470 		if (ret!=KErrNone && ret!=KErrEof) // Handle format error
   477         if (ret!=KErrNone && ret!=KErrEof) // Handle format error
   471 		    ret = HandleCorrupt(ret);
   478             ret = HandleCorrupt(ret);
   472         if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format()
   479         if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format()
   473 		    User::Leave(ret);
   480             User::Leave(ret);
   474 		if (ret==KErrNone)
   481         if (ret==KErrNone)
   475 			{
   482             {
   476 			iCurrentStep=100-(100*iFormatInfo.i512ByteSectorsFormatted)/iMaxDiskSectors;
   483             iCurrentStep=100-(100*iFormatInfo.i512ByteSectorsFormatted)/iMaxDiskSectors;
   477 			if (iCurrentStep<=0)
   484             if (iCurrentStep<=0)
   478 				iCurrentStep=1;
   485                 iCurrentStep=1;
   479 			return;
   486             return;
   480 			}
   487             }
   481 		}
   488         }
   482 
   489 
   483 	// ReMount since MBR may have been rewritten and partition may have moved / changed size
   490     // ReMount since MBR may have been rewritten and partition may have moved / changed size
   484 	TInt ret = LocalDrive()->ForceRemount(0);
   491     TInt ret = LocalDrive()->ForceRemount(0);
   485 	if (ret != KErrNone && ret != KErrNotSupported)
   492     if (ret != KErrNone && ret != KErrNotSupported)
   486 		User::Leave(ret);
   493         User::Leave(ret);
   487 
   494 
   488 	// MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written
   495     // MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written
   489 	InitializeFormatDataL(); 
   496     InitializeFormatDataL(); 
   490 
   497 
   491     // Translate bad sector number to cluster number which contains that sector
   498     // Translate bad sector number to cluster number which contains that sector
   492     // This only happens in full format, in quick format they are already cluster numbers
   499     // This only happens in full format, in quick format they are already cluster numbers
   493     if (!iVariableSize && !(iMode & EQuickFormat))
   500     if (!iVariableSize && !(iMode & EQuickFormat))
   494         User::LeaveIfError(BadSectorToCluster());
   501         User::LeaveIfError(BadSectorToCluster());
   495 
   502 
   496     //
   503     //
   497     // Do the rest of the disk in one lump
   504     // Do the rest of the disk in one lump
   498     //
   505     //
   499 	iCurrentStep=0;
   506     iCurrentStep=0;
   500 	
   507     
   501 
   508 
   502     //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs
   509     //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs
   503     const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position
   510     const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position
   504 	
   511     
   505     if (iVariableSize)
   512     if (iVariableSize)
   506 		FatMount().EnlargeL(posFatEnd); 
   513         FatMount().EnlargeL(posFatEnd); 
   507 
   514 
   508     DoZeroFillMediaL(0, posFatEnd);
   515     DoZeroFillMediaL(0, posFatEnd);
   509 
   516 
   510     //-- Zero fill root directory
   517     //-- Zero fill root directory
   511     const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); 
   518     const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); 
   513             
   520             
   514     const TUint32 posRootDirStart = rootDirSector * iBytesPerSector;
   521     const TUint32 posRootDirStart = rootDirSector * iBytesPerSector;
   515     const TUint32 posRootDirEnd   = posRootDirStart + rootDirSize;
   522     const TUint32 posRootDirEnd   = posRootDirStart + rootDirSize;
   516 
   523 
   517     const TInt numOfRootSectors=(rootDirSize%iBytesPerSector) ? (rootDirSize/iBytesPerSector+1) : (rootDirSize/iBytesPerSector);
   524     const TInt numOfRootSectors=(rootDirSize%iBytesPerSector) ? (rootDirSize/iBytesPerSector+1) : (rootDirSize/iBytesPerSector);
   518 	if (iVariableSize)
   525     if (iVariableSize)
   519 	    FatMount().EnlargeL(iBytesPerSector*numOfRootSectors);
   526         FatMount().EnlargeL(iBytesPerSector*numOfRootSectors);
   520 
   527 
   521     DoZeroFillMediaL(posRootDirStart, posRootDirEnd);
   528     DoZeroFillMediaL(posRootDirStart, posRootDirEnd);
   522 
   529 
   523 	// Enlarge ram drive to take into account rounding of
   530     // Enlarge ram drive to take into account rounding of
   524 	// data start to cluster boundary
   531     // data start to cluster boundary
   525 	if(iVariableSize && iSectorsPerCluster!=1)
   532     if(iVariableSize && iSectorsPerCluster!=1)
   526 		{
   533         {
   527 		const TInt firstFreeSector=rootDirSector+numOfRootSectors;
   534         const TInt firstFreeSector=rootDirSector+numOfRootSectors;
   528 		const TInt firstFreeCluster=firstFreeSector%iSectorsPerCluster ? firstFreeSector/iSectorsPerCluster+1 : firstFreeSector/iSectorsPerCluster;
   535         const TInt firstFreeCluster=firstFreeSector%iSectorsPerCluster ? firstFreeSector/iSectorsPerCluster+1 : firstFreeSector/iSectorsPerCluster;
   529 		const TInt alignedSector=firstFreeCluster*iSectorsPerCluster;
   536         const TInt alignedSector=firstFreeCluster*iSectorsPerCluster;
   530 		if(alignedSector!=firstFreeSector)
   537         if(alignedSector!=firstFreeSector)
   531 			FatMount().EnlargeL((alignedSector-firstFreeSector)*iBytesPerSector);
   538             FatMount().EnlargeL((alignedSector-firstFreeSector)*iBytesPerSector);
   532 		}
   539         }
   533 
   540 
   534     //-- FAT[0] must contain media descriptor in the low byte, FAT[1] for fat16/32 may contain some flags
   541     //-- FAT[0] must contain media descriptor in the low byte, FAT[1] for fat16/32 may contain some flags
   535 	TBuf8<4> startFat(4);
   542     TBuf8<4> startFat(4);
   536     startFat.Fill(0xFF);
   543     startFat.Fill(0xFF);
   537     
   544     
   538     if(iVariableSize||Is16BitFat()) //-- FAT16 or RAM drive which is always FAT16
   545     if(iVariableSize||Is16BitFat()) //-- FAT16 or RAM drive which is always FAT16
   539         {
   546         {
   540         startFat.SetLength(4);
   547         startFat.SetLength(4);
   545         }
   552         }
   546      
   553      
   547     startFat[0]=KBootSectorMediaDescriptor; 
   554     startFat[0]=KBootSectorMediaDescriptor; 
   548 
   555 
   549     //-- write FAT[0] and FAT[1] entries to all copies of FAT
   556     //-- write FAT[0] and FAT[1] entries to all copies of FAT
   550 	for(TInt i=0;i<iNumberOfFats;i++)
   557     for(TInt i=0;i<iNumberOfFats;i++)
   551 		{
   558         {
   552 		User::LeaveIfError(LocalDrive()->Write(iBytesPerSector*(iReservedSectors+(iSectorsPerFat*i)),startFat));
   559         User::LeaveIfError(LocalDrive()->Write(iBytesPerSector*(iReservedSectors+(iSectorsPerFat*i)),startFat));
   553 		}
   560         }
   554 
   561 
   555     //-- create boot sectors
   562     //-- create boot sectors
   556 	CreateBootSectorL();
   563     CreateBootSectorL();
   557 
   564 
   558     //-- here we have bad clusters numbers saved by the quick format
   565     //-- here we have bad clusters numbers saved by the quick format
   559     //-- Interpret old bad cluster number to new cluster number and mark new bad clusters
   566     //-- Interpret old bad cluster number to new cluster number and mark new bad clusters
   560     if (!iVariableSize && iBadClusters.Count()>0)
   567     if (!iVariableSize && iBadClusters.Count()>0)
   561         {
   568         {
   562         //-- Here we need fully mounted volume, so mount it normally.
   569         //-- Here we need fully mounted volume, so mount it normally.
   563 	    FatMount().MountL(EFalse);
   570         FatMount().MountL(EFalse);
   564 
   571 
   565         iBadClusters.Sort();
   572         iBadClusters.Sort();
   566         TranslateL();
   573         TranslateL();
   567         TInt mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit;
   574         TInt mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit;
   568         TInt i;
   575         TInt i;
   570         for (i=0; i<iBadClusters.Count(); ++i)
   577         for (i=0; i<iBadClusters.Count(); ++i)
   571             FatMount().FAT().WriteL(iBadClusters[i], mark);
   578             FatMount().FAT().WriteL(iBadClusters[i], mark);
   572         
   579         
   573         FatMount().FAT().FlushL();
   580         FatMount().FAT().FlushL();
   574 #if defined(_DEBUG)
   581 #if defined(_DEBUG)
   575 	TInt r=FatMount().CheckDisk();
   582     TInt r=FatMount().CheckDisk();
   576 	__PRINT1(_L("CFatFormatCB::DoFormatStepL() CheckDisk res: %d"),r);
   583     __PRINT1(_L("CFatFormatCB::DoFormatStepL() CheckDisk res: %d"),r);
   577 #endif
   584 #endif
   578         }
   585         }
   579         else
   586         else
   580         {
   587         {
   581         //-- We do not need to perform full mount in this case, the TDrive object will be marked as changed in ~CFormatCB and the
   588         //-- We do not need to perform full mount in this case, the TDrive object will be marked as changed in ~CFormatCB and the
   582         //-- mount will be closed. Therefore on the first access to it it will be mounted normally.
   589         //-- mount will be closed. Therefore on the first access to it it will be mounted normally.
   583         FatMount().MountL(ETrue); //-- force mount
   590         FatMount().MountL(ETrue); //-- force mount
   584         }
   591         }
   585 
   592 
   586     __PRINT1(_L("CFatFormatCB::DoFormatStepL() Format complete drv:%d"), DriveNumber());
   593     __PRINT1(_L("CFatFormatCB::DoFormatStepL() Format complete drv:%d"), DriveNumber());
   587 	}
   594     }
   588 
   595 
   589 TInt CFatFormatCB::BadSectorToCluster()
   596 TInt CFatFormatCB::BadSectorToCluster()
   590     {
   597     {
   591     const TInt sizeofFatAndRootDir = iSectorsPerFat*iNumberOfFats + ((iRootDirEntries*KSizeOfFatDirEntry+(1<<iSectorSizeLog2)-1)>>iSectorSizeLog2);
   598     const TInt sizeofFatAndRootDir = iSectorsPerFat*iNumberOfFats + ((iRootDirEntries*KSizeOfFatDirEntry+(1<<iSectorSizeLog2)-1)>>iSectorSizeLog2);
   592     TInt firstFreeSector = iReservedSectors + sizeofFatAndRootDir;
   599     TInt firstFreeSector = iReservedSectors + sizeofFatAndRootDir;