/** Read non aligned boot data from media into TFatBootSector structure @param aMediaPos media position the data will be read from @param aBootSector refrence to TFatBootSector populate @return Media read error code */ TInt CFatMountCB::DoReadBootSector(TInt64 aMediaPos, TFatBootSector& aBootSector) const { __PRINT2(_L("#- CFatMountCB::DoReadBootSector() drv:%d, pos:0x%x"),Drive().DriveNumber(), (TUint32)aMediaPos); ASSERT(aMediaPos>=0); TBuf8<KSizeOfFatBootSector> bootSecBuf(KSizeOfFatBootSector); //-- read boot sector from the media TInt r=LocalDrive()->Read(aMediaPos, KSizeOfFatBootSector, bootSecBuf); if (r != KErrNone) { __PRINT2(_L("CFatMountCB::DoReadBootSector() failed! drv:%d, code:%d"),Drive().DriveNumber(),r); //-- fiddling with the error code; taken from MountL() if (r==KErrNotSupported) return KErrNotReady; #if defined(_LOCKABLE_MEDIA) else if(r==KErrLocked) return KErrLocked; #endif else if (r!=KErrNoMemory && r!=KErrNotReady && r!=KErrCorrupt && r!=KErrUnknown) return KErrCorrupt; return r; } ASSERT(r==KErrNone); //-- initialise TFatBootSector object aBootSector.Internalize(bootSecBuf); //-- Validate the partition size, and fix up if the out of bounds TLocalDriveCapsV2Buf localDriveCaps; r = LocalDrive()->Caps(localDriveCaps); if (r != KErrNone) { //-- fiddling with the error code; taken from MountL() if (r!=KErrNoMemory && r!=KErrNotReady && r!=KErrCorrupt && r!=KErrUnknown) return KErrCorrupt; else return r; } if(!(localDriveCaps().iMediaAtt & KMediaAttVariableSize)) {//-- this is not a RAM drive. const TUint32 maxSectors = I64LOW(localDriveCaps().iSize >> KDefSectorSzLog2); if(aBootSector.TotalSectors()) aBootSector.SetTotalSectors(Min(aBootSector.TotalSectors(), maxSectors)); else aBootSector.SetHugeSectors(Min(aBootSector.HugeSectors(), maxSectors)); } return KErrNone; }
/** Create the boot sector on media for the volume. For FAT32 also creates a backup copy of the boot sector. @leave System wide error codes */ void CFatFormatCB::CreateBootSectorL() { __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; bootSector.SetVendorID(KDefaultVendorID); bootSector.SetBytesPerSector(iBytesPerSector); bootSector.SetSectorsPerCluster(iSectorsPerCluster); bootSector.SetReservedSectors(iReservedSectors); bootSector.SetNumberOfFats(iNumberOfFats); iCountOfClusters=iMaxDiskSectors/iSectorsPerCluster; if (!bFat32) { if (iCountOfClusters>(TInt)KMaxTUint16) User::Leave(KErrTooBig); } bootSector.SetReservedByte(0); TTime timeID; timeID.HomeTime(); bootSector.SetUniqueID(I64LOW(timeID.Int64())); // Generate Volume UniqueID from time bootSector.SetVolumeLabel(_L8("")); //-- 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); bootSector.SetHiddenSectors(iHiddenSectors); bootSector.SetSectorsPerTrack(iSectorsPerTrack); bootSector.SetPhysicalDriveNumber(128); bootSector.SetExtendedBootSignature(0x29); if(bFat32) { bootSector.SetFatSectors(0); bootSector.SetFatSectors32(iSectorsPerFat); bootSector.SetRootDirEntries(0); bootSector.SetTotalSectors(0); bootSector.SetHugeSectors(iMaxDiskSectors); bootSector.SetFATFlags(0); bootSector.SetVersionNumber(0x00); bootSector.SetRootClusterNum(iRootClusterNum); bootSector.SetFSInfoSectorNum(KFSInfoSectorNum); bootSector.SetBkBootRecSector(KBkBootSectorNum); } else//fat12 and 16 { bootSector.SetFatSectors32(0); bootSector.SetFatSectors(iSectorsPerFat); bootSector.SetRootDirEntries(iRootDirEntries); if (iMaxDiskSectors<=KMaxTUint16) { bootSector.SetTotalSectors(iMaxDiskSectors); bootSector.SetHugeSectors(0); } else { bootSector.SetTotalSectors(0); bootSector.SetHugeSectors(iMaxDiskSectors); } } //-- write main boot sector to the first sector on media User::LeaveIfError(FatMount().DoWriteBootSector(KBootSectorNum*bootSector.BytesPerSector(), bootSector)); //-- for FAT32 write backup copy of the boot sector if(bFat32) { User::LeaveIfError(FatMount().DoWriteBootSector(KBkBootSectorNum*bootSector.BytesPerSector(), bootSector)); } }