diff -r d45b74d3fb20 -r ea2cef07f9fe userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp Tue Aug 31 11:40:45 2010 +0100 +++ b/userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp Tue Sep 14 15:52:42 2010 +0100 @@ -18,22 +18,7 @@ #include "sl_std.h" #include "sl_cache.h" -/** -@return ETrue if it is Fat32 -*/ -TBool CFatFormatCB::Is32BitFat() const - { - return(iFileSystemName==KFileSystemName32); - } - -/** -@return ETrue if it is Fat16 -*/ -TBool CFatFormatCB::Is16BitFat() const - { - return(iFileSystemName==KFileSystemName16); - } - +//------------------------------------------------------------------------------------------------------------------- /** Calculate the FAT size in sectors for a Fat32 volume @@ -69,128 +54,6 @@ //------------------------------------------------------------------------------------------------------------------- -/** -Initialize the format parameters for a normal fixed sized disk -Setting set to adhere to Rules of Count of clusters for FAT type - -@param aDiskSizeInSectors Size of volume in sectors -@return system-wide error code -*/ -TInt CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TUint aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps) - { - __PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskNormal() sectors:%d"), aDiskSizeInSectors); - - if( Drive().IsRemovable() ) - iNumberOfFats = KNumberOfFatsExternal; - else - iNumberOfFats = KNumberOfFatsInternal; - - iReservedSectors=KDefFatResvdSec; - if (aDiskSizeInSectors <=4084*1) // 2MB - { - iRootDirEntries=128; - iSectorsPerCluster=1; - iFileSystemName=KFileSystemName12; - iSectorsPerFat=MaxFat12Sectors(); - } - else if (aDiskSizeInSectors<4084*2) // < 4MB (8168 sectors) - { - iRootDirEntries=256; - iSectorsPerCluster=2; - iFileSystemName=KFileSystemName12; - iSectorsPerFat=MaxFat12Sectors(); - } - else if (aDiskSizeInSectors<4084*4) // < 8MB (16336 sectors) - { - iRootDirEntries=512; - iSectorsPerCluster=4; - iFileSystemName=KFileSystemName12; - iSectorsPerFat=MaxFat12Sectors(); - } - else if (aDiskSizeInSectors<4084*8) // < 16MB (32672 sectors) - { - iRootDirEntries=512; - iSectorsPerCluster=8; - iFileSystemName=KFileSystemName12; - iSectorsPerFat=MaxFat12Sectors(); - } - else if(aDiskSizeInSectors<1048576) // >= 16Mb - FAT16 < (1048576) 512MB - { - iFileSystemName=KFileSystemName16; - TUint minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; - iRootDirEntries=512; - iSectorsPerCluster=1; - - while (minSectorsPerCluster>iSectorsPerCluster) - iSectorsPerCluster<<=1; - - iSectorsPerFat=MaxFat16Sectors(); - } - else //use FAT32 - { - iFileSystemName=KFileSystemName32; - iRootDirEntries=0; //this is always the case for fat32 - if(aDiskSizeInSectors < 16777216) //8GB in 512byte sectors - iSectorsPerCluster=8; - else if(aDiskSizeInSectors < 33554432) //16GB in 512byte sectors - iSectorsPerCluster=16; - else if(aDiskSizeInSectors < 67108864) //32GB in 512byte sectors - iSectorsPerCluster=32; - else - iSectorsPerCluster=64; //Anything >= 32GB uses a 32K cluster size - iReservedSectors=KDefFat32ResvdSec; - iRootClusterNum=2; //As recomended in the document - iSectorsPerFat=MaxFat32Sectors(); - - } - - const TFatType fatType = SuggestFatType(); - - // Ensure cluster size is a multiple of the block size - TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; - __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); - ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); - if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) - { - __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); - AdjustClusterSize(blockSizeInSectors); - __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); - } - - - for (; iSectorsPerCluster>1; iSectorsPerCluster>>= 1) - { - // Align first data sector on an erase block boundary if - // (1) the iEraseBlockSize is specified - // (2) the start of the partition is already aligned to an erase block boundary, - // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize - __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); - TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; - __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); - ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); - ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); - if ((eraseblockSizeInSectors != 0) && - (iHiddenSectors % eraseblockSizeInSectors == 0) && - (IsPowerOf2(eraseblockSizeInSectors)) && - (eraseblockSizeInSectors >= blockSizeInSectors)) - { - TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); - ASSERT(r == KErrNone); - (void) r; - } - __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); - __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); - - // If we've shrunk the number of clusters by so much that it's now invalid for this FAT type - // then we need to decrease the cluster size and try again, otherwise we're finshed. - if (SuggestFatType() == fatType) - break; - } - __PRINT1(_L("iSectorsPerCluster (final): %d"),iSectorsPerCluster); - - return KErrNone; - } - TInt CFatFormatCB::FirstDataSector() const { TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; @@ -267,7 +130,11 @@ { __PRINT1(_L("CFatFormatCB::CreateBootSector() drive:%d"),DriveNumber()); - + _LIT8(KName_Fat12,"FAT12 "); ///< Name in BPB given to a Fat12 volume + _LIT8(KName_Fat16,"FAT16 "); ///< Name in BPB given to a Fat16 volume + _LIT8(KName_Fat32,"FAT32 "); ///< Name in BPB given to a Fat32 volume + _LIT8(KDefaultVendorID, "EPOC"); ///< Vendor Name for BPB for any volume formated using a Symbian OS device + const TBool bFat32 = Is32BitFat(); TFatBootSector bootSector; @@ -286,11 +153,32 @@ bootSector.SetReservedByte(0); TTime timeID; - timeID.HomeTime(); // System time in future? - bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate UniqueID from time + timeID.HomeTime(); + bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate Volume UniqueID from time bootSector.SetVolumeLabel(_L8("")); - bootSector.SetFileSysType(iFileSystemName); -// Floppy specific info: + + //-- set a text string in BPB that corresponds to the FS type + switch(FatType()) + { + case EFat12: + bootSector.SetFileSysType(KName_Fat12); + break; + + case EFat16: + bootSector.SetFileSysType(KName_Fat16); + break; + + case EFat32: + bootSector.SetFileSysType(KName_Fat32); + break; + + default: + ASSERT(0); + User::Leave(KErrArgument); + }; + + + bootSector.SetJumpInstruction(); bootSector.SetMediaDescriptor(KBootSectorMediaDescriptor); bootSector.SetNumberOfHeads(iNumberOfHeads); @@ -566,221 +454,6 @@ //------------------------------------------------------------------------------------------------------------------- -/** - Initialize the user specific format parameters for fixed sized disk. - - @param aDiskSizeInSectors disk size in sectors - @return system-wide error code -*/ -TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TUint aDiskSizeInSectors) - { - __PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() sectors:%d"), aDiskSizeInSectors); - Dump_TLDFormatInfo(iSpecialInfo()); - - //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32 - - if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable) - iNumberOfFats = 1; - else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables) - iNumberOfFats = 2; - else if(Drive().IsRemovable()) - iNumberOfFats = KNumberOfFatsExternal; - else - iNumberOfFats = KNumberOfFatsInternal; - - - if(iSpecialInfo().iReservedSectors == 0) - iReservedSectors = KDefFatResvdSec; //-- user hasn't specified reserved sectors count, use default (FAT12/16) - else - iReservedSectors = iSpecialInfo().iReservedSectors; - - - const TUint KMaxSecPerCluster = 64; - const TUint KDefaultSecPerCluster= 8; //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified - - iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster; - if(iSectorsPerCluster <= 0) - {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster - iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later - } - else - { - iSectorsPerCluster = Min(1<>iSectorSizeLog2); else sizeofFatAndRootDir = (iRootClusterNum-2) * iSectorsPerCluster; @@ -838,8 +512,10 @@ { if (badSector == 0) // Boot sector corrupt return KErrCorrupt; - if (iFileSystemName==KFileSystemName32 && badSector==1) // FSInfo corrupt + + if (Is32BitFat() && badSector==1) // FSInfo corrupt return KErrCorrupt; + if (badSector < iReservedSectors) // Harmless in reserved area continue; // Extend reserved area to cover bad sector @@ -854,7 +530,8 @@ { if ((r=iBadClusters.Append(cluster)) != KErrNone) return r; - if (iFileSystemName==KFileSystemName32 && iRootClusterNum==cluster) + + if (Is32BitFat() && iRootClusterNum==cluster) iRootClusterNum++; } } @@ -909,5 +586,400 @@ } +//------------------------------------------------------------------------------------------------------------------- + +/** + Initialize the user-specific format parameters + Tries to figure out number of FATs, SPC, etc. values passed from the user side. + This method is called if the user has specified some formatting parameters, like SPC +*/ +TInt CFatFormatCB::ProcessVolParam_User(const TLocalDriveCapsV6& /*aCaps*/) +{ + __PRINT1(_L("CFatFormatCB::ProcessVolParam_User() sectors:%d"), iMaxDiskSectors); + Dump_TLDFormatInfo(iSpecialInfo()); + + //-- KErrArgument will be returned if iSpecialInfo().iFATBits isn't one of EFB32, EFB16, EFB32 + + if(iSpecialInfo().iFlags & TLDFormatInfo::EOneFatTable) + iNumberOfFats = 1; + else if(iSpecialInfo().iFlags & TLDFormatInfo::ETwoFatTables) + iNumberOfFats = 2; + else if(Drive().IsRemovable()) + iNumberOfFats = KNumberOfFatsExternal; + else + iNumberOfFats = KNumberOfFatsInternal; + + + if(iSpecialInfo().iReservedSectors) + iReservedSectors = iSpecialInfo().iReservedSectors; + else + iReservedSectors = KDefFatResvdSec; //-- the user hasn't specified reserved sectors count, use default (FAT12/16) + + //----------------------------------------- + + + const TUint KMaxSecPerCluster = 64; + const TUint KDefaultSecPerCluster= 8; //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified + + iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster; + if(iSectorsPerCluster <= 0) + {//-- default value, user hasn't specified TLDFormatInfo::iSectorsPerCluster + iSectorsPerCluster = KDefaultSecPerCluster; //-- will be adjusted later + } + else + { + iSectorsPerCluster = Min(1<= 16Mb - FAT16 < (1048576) 512MB + { + SetFatType(EFat16); + TUint minSectorsPerCluster=(iMaxDiskSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; + iRootDirEntries=512; + iSectorsPerCluster=1; + + while (minSectorsPerCluster>iSectorsPerCluster) + iSectorsPerCluster<<=1; + + iSectorsPerFat=MaxFat16Sectors(); + } + else //use FAT32 + { + SetFatType(EFat32); + iRootDirEntries=0; //this is always the case for fat32 + + if(iMaxDiskSectors < 16777216) //8GB in 512byte sectors + iSectorsPerCluster=8; + else if(iMaxDiskSectors < 33554432) //16GB in 512byte sectors + iSectorsPerCluster=16; + else if(iMaxDiskSectors < 67108864) //32GB in 512byte sectors + iSectorsPerCluster=32; + else + iSectorsPerCluster=64; //Anything >= 32GB uses a 32K cluster size + + iReservedSectors=KDefFat32ResvdSec; + iRootClusterNum=2; //As recomended in the document + iSectorsPerFat=MaxFat32Sectors(); + + } + + const TFatType fatType = SuggestFatType(); + + // Ensure cluster size is a multiple of the block size + TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2; + __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors); + ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors)); + if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors)) + { + __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster); + AdjustClusterSize(blockSizeInSectors); + __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster); + } + + + for (; iSectorsPerCluster>1; iSectorsPerCluster>>= 1) + { + // Align first data sector on an erase block boundary if + // (1) the iEraseBlockSize is specified + // (2) the start of the partition is already aligned to an erase block boundary, + // i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize + __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors); + TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2; + __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors); + ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors)); + ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors); + if ((eraseblockSizeInSectors != 0) && + (iHiddenSectors % eraseblockSizeInSectors == 0) && + (IsPowerOf2(eraseblockSizeInSectors)) && + (eraseblockSizeInSectors >= blockSizeInSectors)) + { + TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors); + ASSERT(r == KErrNone); + (void) r; + } + __PRINT1(_L("iReservedSectors: %d"),iReservedSectors); + __PRINT1(_L("FirstDataSector: %d"), FirstDataSector()); + + // If we've shrunk the number of clusters by so much that it's now invalid for this FAT type + // then we need to decrease the cluster size and try again, otherwise we're finshed. + if (SuggestFatType() == fatType) + break; + } + __PRINT1(_L("iSectorsPerCluster (final): %d"),iSectorsPerCluster); + + return KErrNone; +} + +//------------------------------------------------------------------------------------------------------------------- +/** + Initialize the format parameters for a variable sized disk (RAM drive) + + @param aDiskSizeInSectors volume size in sectors + @return standard error code +*/ +TInt CFatFormatCB::ProcessVolParam_RamDisk() + { + __PRINT1(_L("CFatFormatCB::ProcessVolParam_RamDisk() sectors:%d"), iMaxDiskSectors); + + iNumberOfFats = 2; // 1 FAT 1 Indirection table (FIT) + iReservedSectors= 1; + iRootDirEntries = 2*(4*KDefaultSectorSize)/sizeof(SFatDirEntry); + TUint minSectorsPerCluster=(iMaxDiskSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries; + iSectorsPerCluster=1; + + while(minSectorsPerCluster > iSectorsPerCluster) + iSectorsPerCluster<<=1; + + + iSectorsPerFat=MaxFat16Sectors(); + __PRINT1(_L("iSectorsPerCluster = %d"),iSectorsPerCluster); + __PRINT1(_L("iSectorsPerFat = %d"),iSectorsPerFat); + + SetFatType(EFat16); + + return KErrNone; + } + + + + + + + + + + + + + + + + + + + + + + + +