sl@0: // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32\sfat\sl_fat16.cpp sl@0: // sl@0: // sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!! sl@0: //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it sl@0: //!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: sl@0: sl@0: #include "sl_std.h" sl@0: #include "sl_cache.h" sl@0: sl@0: const TUint KDefFatResvdSec = 1; ///< default number of FAT12/16 reserved sectors sl@0: sl@0: /** sl@0: Initialize the format parameters for a normal fixed sized disk sl@0: Setting set to adhere to Rules of Count of clusters for FAT type sl@0: sl@0: @param aDiskSizeInSectors Size of volume in sectors sl@0: @return system-wide error code sl@0: */ sl@0: TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps) sl@0: { sl@0: if( Drive().IsRemovable() ) sl@0: iNumberOfFats = KNumberOfFatsExternal; sl@0: else sl@0: iNumberOfFats = KNumberOfFatsInternal; sl@0: sl@0: iReservedSectors=KDefFatResvdSec; sl@0: if (aDiskSizeInSectors<4084*1) // < 2MB sl@0: { sl@0: iRootDirEntries=128; sl@0: iSectorsPerCluster=1; sl@0: iFileSystemName=KFileSystemName12; sl@0: iSectorsPerFat=MaxFat12Sectors(); sl@0: } sl@0: else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors) sl@0: { sl@0: iRootDirEntries=256; sl@0: iSectorsPerCluster=2; sl@0: iFileSystemName=KFileSystemName12; sl@0: iSectorsPerFat=MaxFat12Sectors(); sl@0: } sl@0: else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors) sl@0: { sl@0: iRootDirEntries=512; sl@0: iSectorsPerCluster=4; sl@0: iFileSystemName=KFileSystemName12; sl@0: iSectorsPerFat=MaxFat12Sectors(); sl@0: } sl@0: else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors) sl@0: { sl@0: iRootDirEntries=512; sl@0: iSectorsPerCluster=8; sl@0: iFileSystemName=KFileSystemName12; sl@0: iSectorsPerFat=MaxFat12Sectors(); sl@0: } sl@0: else // >= 16Mb - FAT16 sl@0: { sl@0: iFileSystemName=KFileSystemName16; sl@0: TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; sl@0: iRootDirEntries=512; sl@0: iSectorsPerCluster=1; sl@0: while (minSectorsPerCluster>iSectorsPerCluster) sl@0: iSectorsPerCluster<<=1; sl@0: iSectorsPerFat=MaxFat16Sectors(); sl@0: } sl@0: sl@0: // Ensure cluster size is a multiple of the block size sl@0: TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; sl@0: __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); sl@0: ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); sl@0: if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) sl@0: { sl@0: __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); sl@0: AdjustClusterSize(blockSizeInSectors); sl@0: __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); sl@0: } sl@0: sl@0: // Align first data sector on an erase block boundary if sl@0: // (1) the iEraseBlockSize is specified sl@0: // (2) the start of the partition is already aligned to an erase block boundary, sl@0: // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize sl@0: __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); sl@0: TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; sl@0: __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); sl@0: ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); sl@0: ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); sl@0: if ((eraseblockSizeInSectors != 0) && sl@0: (iHiddenSectors % eraseblockSizeInSectors == 0) && sl@0: (IsPowerOf2(eraseblockSizeInSectors)) && sl@0: (eraseblockSizeInSectors >= blockSizeInSectors)) sl@0: { sl@0: TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); sl@0: ASSERT(r == KErrNone); sl@0: (void) r; sl@0: } sl@0: __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); sl@0: __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CFatFormatCB::FirstDataSector() const sl@0: { sl@0: TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; sl@0: return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors; sl@0: } sl@0: sl@0: void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster) sl@0: { sl@0: const TInt KMaxSecPerCluster = 64; // 32K sl@0: while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2)) sl@0: iSectorsPerCluster<<= 1; sl@0: } sl@0: sl@0: // AdjustFirstDataSectorAlignment() sl@0: // Attempts to align the first data sector on an erase block boundary by modifying the sl@0: // number of reserved sectors. sl@0: TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors) sl@0: { sl@0: const TBool bFat16 = Is16BitFat(); sl@0: sl@0: // Save these 2 values in the event of a convergence failure; this should sl@0: // hopefully never happen, but we will cater for this in release mode to be safe, sl@0: TInt reservedSectorsSaved = iReservedSectors; sl@0: TInt sectorsPerFatSaved = iSectorsPerFat; sl@0: sl@0: TInt reservedSectorsOld = 0; sl@0: sl@0: // zero for FAT32 sl@0: TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; sl@0: TInt fatSectors = 0; sl@0: sl@0: TInt KMaxIterations = 10; sl@0: TInt n; sl@0: for (n=0; n= (TInt) KDefFatResvdSec); sl@0: sl@0: if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: else sl@0: { sl@0: iReservedSectors = reservedSectorsSaved; sl@0: iSectorsPerFat = sectorsPerFatSaved; sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Initialize the user specific format parameters for fixed sized disk. sl@0: sl@0: @param aDiskSizeInSectors disk size in sectors sl@0: @return system-wide error code sl@0: */ sl@0: TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors) sl@0: { sl@0: //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32 sl@0: sl@0: if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable) sl@0: iNumberOfFats = 1; sl@0: else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables) sl@0: iNumberOfFats = 2; sl@0: else if(Drive().IsRemovable()) sl@0: iNumberOfFats = KNumberOfFatsExternal; sl@0: else sl@0: iNumberOfFats = KNumberOfFatsInternal; sl@0: sl@0: sl@0: if(iSpecialInfo().iReservedSectors == 0) sl@0: iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16) sl@0: else sl@0: iReservedSectors = iSpecialInfo().iReservedSectors; sl@0: sl@0: sl@0: const TInt KMaxSecPerCluster = 64; sl@0: const TInt KDefaultSecPerCluster= 8; //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified sl@0: sl@0: iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster; sl@0: if(iSectorsPerCluster <= 0) sl@0: {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster sl@0: iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later sl@0: } sl@0: else sl@0: { sl@0: iSectorsPerCluster = Min(1<= 64Mb sl@0: iRootDirEntries = 512; sl@0: sl@0: //----------------------------------------- sl@0: sl@0: TLDFormatInfo::TFATBits fatBits = iSpecialInfo().iFATBits; sl@0: if (fatBits == TLDFormatInfo::EFBDontCare) sl@0: { sl@0: const TFatType fatType = SuggestFatType(); sl@0: switch(fatType) sl@0: { sl@0: case EFat12: sl@0: fatBits = TLDFormatInfo::EFB12; sl@0: break; sl@0: case EFat16: sl@0: fatBits = TLDFormatInfo::EFB16; sl@0: break; sl@0: case EFat32: sl@0: fatBits = TLDFormatInfo::EFB32; sl@0: break; sl@0: case EInvalid: sl@0: ASSERT(0); sl@0: } sl@0: } sl@0: sl@0: TFatType reqFatType(EInvalid); //-- requested FAT type sl@0: sl@0: switch (fatBits) sl@0: { sl@0: case TLDFormatInfo::EFB12: sl@0: iFileSystemName=KFileSystemName12; sl@0: iSectorsPerFat=MaxFat12Sectors(); sl@0: reqFatType = EFat12; sl@0: break; sl@0: sl@0: case TLDFormatInfo::EFB16: sl@0: iFileSystemName=KFileSystemName16; sl@0: iSectorsPerFat=MaxFat16Sectors(); sl@0: reqFatType = EFat16; sl@0: break; sl@0: sl@0: case TLDFormatInfo::EFB32: sl@0: __PRINT(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() FAT32 Not supported!")); sl@0: return KErrNotSupported; sl@0: sl@0: default: sl@0: __PRINT(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() Incorrect FAT type specifier!")); sl@0: return KErrArgument; sl@0: }; sl@0: sl@0: //-- check if we can format the volume with requested FAT type sl@0: const TFatType fatType = SuggestFatType(); sl@0: if(fatType != reqFatType) sl@0: {//-- volume metrics don't correspond to the requested FAT type sl@0: __PRINT(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() FAT type mismatch!")); sl@0: return KErrArgument; sl@0: } sl@0: sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Initialize the format parameters for a custom fixed sized disk sl@0: sl@0: @param aFormatInfo The custom format parameters sl@0: @return system-wide error code sl@0: */ sl@0: TInt CFatFormatCB::InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo) sl@0: { sl@0: if(aFormatInfo.iFlags & TLDFormatInfo::EOneFatTable) sl@0: iNumberOfFats = 1; sl@0: else if(aFormatInfo.iFlags & TLDFormatInfo::ETwoFatTables) sl@0: iNumberOfFats = 2; sl@0: else if(Drive().IsRemovable()) sl@0: iNumberOfFats = KNumberOfFatsExternal; sl@0: else sl@0: iNumberOfFats = KNumberOfFatsInternal; sl@0: sl@0: iRootDirEntries=512; sl@0: sl@0: iSectorsPerCluster = aFormatInfo.iSectorsPerCluster; sl@0: iSectorsPerTrack = aFormatInfo.iSectorsPerTrack; sl@0: iNumberOfHeads = aFormatInfo.iNumberOfSides; sl@0: iReservedSectors = aFormatInfo.iReservedSectors ? aFormatInfo.iReservedSectors : KDefFatResvdSec; sl@0: sl@0: switch (aFormatInfo.iFATBits) sl@0: { sl@0: case TLDFormatInfo::EFB12: sl@0: iFileSystemName = KFileSystemName12; sl@0: iSectorsPerFat = MaxFat12Sectors(); sl@0: break; sl@0: sl@0: case TLDFormatInfo::EFB16: sl@0: iFileSystemName = KFileSystemName16; sl@0: iSectorsPerFat = MaxFat16Sectors(); sl@0: break; sl@0: sl@0: default: sl@0: { sl@0: TInt64 clusters64 = (aFormatInfo.iCapacity / KDefaultSectorSize) / iSectorsPerCluster; sl@0: TInt clusters = I64LOW(clusters64); sl@0: if (clusters < 4085) sl@0: { sl@0: iFileSystemName = KFileSystemName12; sl@0: iSectorsPerFat = MaxFat12Sectors(); sl@0: } sl@0: else sl@0: { sl@0: iFileSystemName = KFileSystemName16; sl@0: iSectorsPerFat = MaxFat16Sectors(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CFatFormatCB::RecordOldInfoL() sl@0: { sl@0: __PRINT(_L("CFatFormatCB::RecordOldInfoL")); sl@0: // Check if mount or disk is corrupt sl@0: // This should be stored in member variable because FatMount is remounted sl@0: // every time RFormat::Next() gets called thus FatMount().Initialised() sl@0: // will be inconsistent with previous state. sl@0: TLocalDriveCapsV3Buf caps; sl@0: User::LeaveIfError(LocalDrive()->Caps(caps)); sl@0: iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse; sl@0: iDiskCorrupt = !FatMount().ConsistentState(); sl@0: iBadClusters.Reset(); sl@0: iBadSectors.Reset(); sl@0: if (!iVariableSize && !iDiskCorrupt && (iMode & EQuickFormat)) sl@0: { sl@0: iOldFirstFreeSector = FatMount().iFirstFreeByte >> FatMount().SectorSizeLog2(); sl@0: iOldSectorsPerCluster = FatMount().SectorsPerCluster(); sl@0: sl@0: FatMount().FAT().InvalidateCacheL(); //-- invalidate whole FAT cache sl@0: sl@0: const TInt maxClusterNum = FatMount().iUsableClusters + KFatFirstSearchCluster; sl@0: sl@0: // Collect bad cluster information from current FAT table sl@0: const TUint32 mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit; sl@0: for (TInt i=KFatFirstSearchCluster; i(TInt)KMaxTUint16) sl@0: User::Leave(KErrTooBig); sl@0: bootSector.SetFatSectors(iSectorsPerFat); sl@0: bootSector.SetReservedByte(0); sl@0: TTime timeID; sl@0: timeID.HomeTime(); // System time in future? sl@0: bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate UniqueID from time sl@0: bootSector.SetVolumeLabel(_L8("")); sl@0: bootSector.SetFileSysType(iFileSystemName); sl@0: // Floppy specific info: sl@0: bootSector.SetJumpInstruction(); sl@0: bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor); sl@0: bootSector.SetNumberOfHeads(iNumberOfHeads); sl@0: bootSector.SetHiddenSectors(iHiddenSectors); sl@0: bootSector.SetSectorsPerTrack(iSectorsPerTrack); sl@0: bootSector.SetPhysicalDriveNumber(128); sl@0: bootSector.SetExtendedBootSignature(0x29); sl@0: sl@0: sl@0: User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector)); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Format a disk section, called iteratively to erase whole of media, on last iteration sl@0: creates an empty volume. If called with quick formatonly erases the Fat leaving the sl@0: rest of the volume intact. sl@0: sl@0: @leave System wide error code sl@0: */ sl@0: void CFatFormatCB::DoFormatStepL() sl@0: { sl@0: if (iFormatInfo.iFormatIsCurrent==EFalse) sl@0: { sl@0: if (iMode & EForceErase) sl@0: { sl@0: TInt r = FatMount().ErasePassword(); sl@0: User::LeaveIfError(r); sl@0: // CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(), sl@0: // so need to stop a remount from occurring in next call to : sl@0: // TFsFormatNext::DoRequestL((), TDrive::CheckMount(). sl@0: FatMount().Drive().SetChanged(EFalse); sl@0: } sl@0: sl@0: RecordOldInfoL(); sl@0: InitializeFormatDataL(); sl@0: FatMount().DoDismount(); sl@0: if (iVariableSize) sl@0: FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize)); sl@0: } sl@0: // sl@0: // Blank disk if not EQuickFormat sl@0: // sl@0: if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep) sl@0: { sl@0: if (iFormatInfo.iFormatIsCurrent == EFalse) sl@0: {//-- firstly invalidate sectors 0-6 inclusive sl@0: DoZeroFillMediaL(0, 7*iBytesPerSector); sl@0: } sl@0: sl@0: TInt ret=FatMount().LocalDrive()->Format(iFormatInfo); sl@0: if (ret!=KErrNone && ret!=KErrEof) // Handle format error sl@0: ret = HandleCorrupt(ret); sl@0: if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format() sl@0: User::Leave(ret); sl@0: if (ret==KErrNone) sl@0: { sl@0: iCurrentStep=100-(100*iFormatInfo.i512ByteSectorsFormatted)/iMaxDiskSectors; sl@0: if (iCurrentStep<=0) sl@0: iCurrentStep=1; sl@0: return; sl@0: } sl@0: } sl@0: sl@0: // ReMount since MBR may have been rewritten and partition may have moved / changed size sl@0: TInt ret = LocalDrive()->ForceRemount(0); sl@0: if (ret != KErrNone && ret != KErrNotSupported) sl@0: User::Leave(ret); sl@0: sl@0: // MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written sl@0: InitializeFormatDataL(); sl@0: sl@0: // Translate bad sector number to cluster number which contains that sector sl@0: // This only happens in full format, in quick format they are already cluster numbers sl@0: if (!iVariableSize && !(iMode & EQuickFormat)) sl@0: User::LeaveIfError(BadSectorToCluster()); sl@0: sl@0: // sl@0: // Do the rest of the disk in one lump sl@0: // sl@0: iCurrentStep=0; sl@0: sl@0: sl@0: //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs sl@0: const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position sl@0: sl@0: if (iVariableSize) sl@0: FatMount().EnlargeL(posFatEnd); sl@0: sl@0: DoZeroFillMediaL(0, posFatEnd); sl@0: sl@0: //-- Zero fill root directory sl@0: const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); sl@0: const TInt rootDirSize = iRootDirEntries * KSizeOfFatDirEntry; //-- size in bytes sl@0: sl@0: const TUint32 posRootDirStart = rootDirSector * iBytesPerSector; sl@0: const TUint32 posRootDirEnd = posRootDirStart + rootDirSize; sl@0: sl@0: const TInt numOfRootSectors=(rootDirSize%iBytesPerSector) ? (rootDirSize/iBytesPerSector+1) : (rootDirSize/iBytesPerSector); sl@0: if (iVariableSize) sl@0: FatMount().EnlargeL(iBytesPerSector*numOfRootSectors); sl@0: sl@0: DoZeroFillMediaL(posRootDirStart, posRootDirEnd); sl@0: sl@0: // Enlarge ram drive to take into account rounding of sl@0: // data start to cluster boundary sl@0: if(iVariableSize && iSectorsPerCluster!=1) sl@0: { sl@0: const TInt firstFreeSector=rootDirSector+numOfRootSectors; sl@0: const TInt firstFreeCluster=firstFreeSector%iSectorsPerCluster ? firstFreeSector/iSectorsPerCluster+1 : firstFreeSector/iSectorsPerCluster; sl@0: const TInt alignedSector=firstFreeCluster*iSectorsPerCluster; sl@0: if(alignedSector!=firstFreeSector) sl@0: FatMount().EnlargeL((alignedSector-firstFreeSector)*iBytesPerSector); sl@0: } sl@0: sl@0: //-- FAT[0] must contain media descriptor in the low byte, FAT[1] for fat16/32 may contain some flags sl@0: TBuf8<4> startFat(4); sl@0: startFat.Fill(0xFF); sl@0: sl@0: if(iVariableSize||Is16BitFat()) //-- FAT16 or RAM drive which is always FAT16 sl@0: { sl@0: startFat.SetLength(4); sl@0: } sl@0: else //-- FAT12 sl@0: { sl@0: startFat.SetLength(3); sl@0: } sl@0: sl@0: startFat[0]=KBootSectorMediaDescriptor; sl@0: sl@0: //-- write FAT[0] and FAT[1] entries to all copies of FAT sl@0: for(TInt i=0;iWrite(iBytesPerSector*(iReservedSectors+(iSectorsPerFat*i)),startFat)); sl@0: } sl@0: sl@0: //-- create boot sectors sl@0: CreateBootSectorL(); sl@0: sl@0: //-- here we have bad clusters numbers saved by the quick format sl@0: //-- Interpret old bad cluster number to new cluster number and mark new bad clusters sl@0: if (!iVariableSize && iBadClusters.Count()>0) sl@0: { sl@0: //-- Here we need fully mounted volume, so mount it normally. sl@0: FatMount().MountL(EFalse); sl@0: sl@0: iBadClusters.Sort(); sl@0: TranslateL(); sl@0: TInt mark = FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit; sl@0: TInt i; sl@0: sl@0: for (i=0; i>iSectorSizeLog2); sl@0: TInt firstFreeSector = iReservedSectors + sizeofFatAndRootDir; sl@0: sl@0: TInt i, r; sl@0: for (i=0; i