Update contrib.
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfat32\sl_bpb32.cpp
15 // Boot sector code, specific for EFat32.fsy
27 //-------------------------------------------------------------------------------------------------------------------
29 TFatBootSector::TFatBootSector()
34 /** initialises the boot sector data */
35 void TFatBootSector::Initialise()
37 Mem::FillZ(this, sizeof(TFatBootSector));
40 //-------------------------------------------------------------------------------------------------------------------
43 @return ETrue if the boot sector contents seems to be valid
45 TBool TFatBootSector::IsValid() const
47 const TFatType fatType = FatType(); //-- it will check SectorsPerCluster etc.
49 if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1)
54 if(VersionNumber()!= 0 || FatSectors()!=0 || FatSectors32()<1 || RootClusterNum()<KFatFirstSearchCluster ||
55 TotalSectors()!=0 || HugeSectors() <5 || RootDirEntries() !=0)
57 goto Invalid; //-- these values are not compliant with FAT specs
62 if(TotalSectors() >0 && HugeSectors() >0 )
63 goto Invalid; //-- values clash
65 const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
66 const TUint32 rootDirStartSec = ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
68 if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5)
69 goto Invalid; //-- these values are not compliant with FAT specs
75 __PRINT(_L("TFatBootSector::IsValid() failed!"));
80 //-------------------------------------------------------------------------------------------------------------------
83 Initialize boot sector object from the given bufer. Does not validate the data.
84 @param aBuf buffer with data.
86 void TFatBootSector::Internalize(const TDesC8& aBuf)
88 ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
94 Mem::Copy(&iJumpInstruction, &aBuf[pos],3); pos+=3; // 0 TUint8 iJumpInstruction[3]
95 Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3 TUint8 iVendorId[KVendorIdSize]
96 Mem::Copy(&iBytesPerSector,&aBuf[pos],2); pos+=2; // 11 TUint16 iBytesPerSector
97 Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1); pos+=1; // 13 TUint8 iSectorsPerCluster
98 Mem::Copy(&iReservedSectors,&aBuf[pos],2); pos+=2; // 14 TUint16 iReservedSectors
99 Mem::Copy(&iNumberOfFats,&aBuf[pos],1); pos+=1; // 16 TUint8 iNumberOfFats
100 Mem::Copy(&iRootDirEntries,&aBuf[pos],2); pos+=2; // 17 TUint16 iRootDirEntries
101 Mem::Copy(&iTotalSectors,&aBuf[pos],2); pos+=2; // 19 TUint16 iTotalSectors
102 Mem::Copy(&iMediaDescriptor,&aBuf[pos],1); pos+=1; // 21 TUint8 iMediaDescriptor
103 Mem::Copy(&iFatSectors,&aBuf[pos],2); pos+=2; // 22 TUint16 iFatSectors
104 Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2); pos+=2; // 24 TUint16 iSectorsPerTrack
105 Mem::Copy(&iNumberOfHeads,&aBuf[pos],2); pos+=2; // 26 TUint16 iNumberOfHeads
106 Mem::Copy(&iHiddenSectors,&aBuf[pos],4); pos+=4; // 28 TUint32 iHiddenSectors
107 Mem::Copy(&iHugeSectors,&aBuf[pos],4); pos+=4; // 32 TUint32 iHugeSectors
109 if(RootDirEntries() == 0) //-- we have FAT32 volume
111 Mem::Copy(&iFatSectors32, &aBuf[pos],4); pos+=4; // 36 TUint32 iFatSectors32
112 Mem::Copy(&iFATFlags, &aBuf[pos],2); pos+=2; // 40 TUint16 iFATFlags
113 Mem::Copy(&iVersionNumber, &aBuf[pos],2); pos+=2; // 42 TUint16 iVersionNumber
114 Mem::Copy(&iRootClusterNum, &aBuf[pos],4); pos+=4; // 44 TUint32 iRootClusterNum
115 Mem::Copy(&iFSInfoSectorNum, &aBuf[pos],2); pos+=2; // 48 TUint16 iFSInfoSectorNum
116 Mem::Copy(&iBkBootRecSector, &aBuf[pos],2); // 50 TUint16 iBkBootRecSector
117 pos+=(2+12); //extra 12 for the reserved bytes
120 Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1); pos+=1;// 36|64 TUint8 iPhysicalDriveNumber
121 Mem::Copy(&iReserved,&aBuf[pos],1); pos+=1;// 37|65 TUint8 iReserved
122 Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature
123 Mem::Copy(&iUniqueID,&aBuf[pos],4); pos+=4;// 39|67 TUint32 iUniqueID
124 Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize); // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize]
125 pos+=KVolumeLabelSize;
127 // 54|82 TUint8 iFileSysType[KFileSysTypeSize]
128 ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
129 Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
132 //-------------------------------------------------------------------------------------------------------------------
135 Externalize boot sector object to the given data buffer.
136 @param aBuf buffer to externalize.
138 void TFatBootSector::Externalize(TDes8& aBuf) const
140 ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
142 if(aBuf.Size() < KSizeOfFatBootSector)
143 aBuf.SetLength(KSizeOfFatBootSector);
147 Mem::Copy(&aBuf[pos],&iJumpInstruction,3); pos+=3;
148 Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8;
149 Mem::Copy(&aBuf[pos],&iBytesPerSector,2); pos+=2;
150 Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1); pos+=1;
151 Mem::Copy(&aBuf[pos],&iReservedSectors,2); pos+=2;
152 Mem::Copy(&aBuf[pos],&iNumberOfFats,1); pos+=1;
153 Mem::Copy(&aBuf[pos],&iRootDirEntries,2); pos+=2;
154 Mem::Copy(&aBuf[pos],&iTotalSectors,2); pos+=2;
155 Mem::Copy(&aBuf[pos],&iMediaDescriptor,1); pos+=1;
156 Mem::Copy(&aBuf[pos],&iFatSectors,2); pos+=2;
157 Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2); pos+=2;
158 Mem::Copy(&aBuf[pos],&iNumberOfHeads,2); pos+=2;
159 Mem::Copy(&aBuf[pos],&iHiddenSectors,4); pos+=4;
160 Mem::Copy(&aBuf[pos],&iHugeSectors,4); pos+=4;
164 Mem::Copy(&aBuf[pos], &iFatSectors32,4); pos+=4;
165 Mem::Copy(&aBuf[pos], &iFATFlags, 2); pos+=2;
166 Mem::Copy(&aBuf[pos], &iVersionNumber, 2); pos+=2;
167 Mem::Copy(&aBuf[pos], &iRootClusterNum, 4); pos+=4;
168 Mem::Copy(&aBuf[pos], &iFSInfoSectorNum, 2);pos+=2;
169 Mem::Copy(&aBuf[pos], &iBkBootRecSector, 2);pos+=2;
171 //extra 12 for the reserved bytes
172 ASSERT(aBuf.Size() >= pos+12);
173 Mem::FillZ(&aBuf[pos],12);
177 Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1); pos+=1;
178 Mem::FillZ(&aBuf[pos],1); pos+=1;
179 Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1;
180 Mem::Copy(&aBuf[pos],&iUniqueID,4); pos+=4;
182 Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize);
183 pos+=KVolumeLabelSize;
185 ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
186 Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
189 //-------------------------------------------------------------------------------------------------------------------
192 /** replaces all non-printable characters in a buffer with spaces */
193 static void FixDes(TDes& aDes)
195 for(TInt i=0; i< aDes.Length(); ++i)
206 Print out the boot sector info.
208 void TFatBootSector::PrintDebugInfo() const
212 __PRINT(_L("======== BootSector info: ======="));
215 buf.Copy(FileSysType()); FixDes(buf);
216 __PRINT1(_L("FAT type:%S"), &buf);
218 buf.Copy(VendorId()); FixDes(buf);
219 __PRINT1(_L("Vendor ID:%S"), &buf);
221 __PRINT1(_L("BytesPerSector:%d"),BytesPerSector());
222 __PRINT1(_L("SectorsPerCluster:%d"),SectorsPerCluster());
223 __PRINT1(_L("ReservedSectors:%d"),ReservedSectors());
224 __PRINT1(_L("NumberOfFats:%d"),NumberOfFats());
225 __PRINT1(_L("RootDirEntries:%d"),RootDirEntries());
226 __PRINT1(_L("Total Sectors:%d"),TotalSectors());
227 __PRINT1(_L("MediaDescriptor:0x%x"),MediaDescriptor());
228 __PRINT1(_L("FatSectors:%d"),FatSectors());
229 __PRINT1(_L("SectorsPerTrack:%d"),SectorsPerTrack());
230 __PRINT1(_L("NumberOfHeads:%d"),NumberOfHeads());
231 __PRINT1(_L("HugeSectors:%d"),HugeSectors());
232 __PRINT1(_L("Fat32 Sectors:%d"),FatSectors32());
233 __PRINT1(_L("Fat32 Flags:%d"),FATFlags());
234 __PRINT1(_L("Fat32 Version Number:%d"),VersionNumber());
235 __PRINT1(_L("Root Cluster Number:%d"),RootClusterNum());
236 __PRINT1(_L("FSInfo Sector Number:%d"),FSInfoSectorNum());
237 __PRINT1(_L("Backup Boot Rec Sector Number:%d"),BkBootRecSector());
238 __PRINT1(_L("PhysicalDriveNumber:%d"),PhysicalDriveNumber());
239 __PRINT1(_L("ExtendedBootSignature:%d"),ExtendedBootSignature());
240 __PRINT1(_L("UniqueID:0x%x"),UniqueID());
242 buf.Copy(VolumeLabel()); FixDes(buf);
243 __PRINT1(_L("VolumeLabel:%S"), &buf);
245 __PRINT(_L("=============================\n"));
249 //-------------------------------------------------------------------------------------------------------------------
252 Determine FAT type according to the information from boot sector, see FAT32 specs.
255 TFatType TFatBootSector::FatType(void) const
258 //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
259 if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 || iBytesPerSector > 4096)
260 return EInvalid; //-- invalid iBytesPerSector value
262 //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
263 if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128)
264 return EInvalid; //-- invalid iSectorsPerCluster value
266 const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
267 const TUint32 fatSz = iFatSectors ? iFatSectors : iFatSectors32;
268 const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors;
269 const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * fatSz) + rootDirSectors);
270 const TUint32 clusterCnt = dataSec / iSectorsPerCluster;
272 //-- magic. see FAT specs for details.
273 if(clusterCnt < 4085)
275 else if(clusterCnt < 65525)
284 /** @return The first Fat sector number */
285 TInt TFatBootSector::FirstFatSector() const
287 __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
288 return ReservedSectors();
292 @return Number of sectors in root directory. 0 for FAT32
294 TUint32 TFatBootSector::RootDirSectors() const
296 __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
297 return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
301 /** @return Start sector number of the root directory */
302 TInt TFatBootSector::RootDirStartSector() const
304 __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
306 const TUint32 firstNonFatSec = ReservedSectors() + TotalFatSectors()*NumberOfFats();
308 if(FatType() == EFat32)
309 {//-- FAT32 root dir is a file, calculate the position by it's 1st cluster number. FAT[0]+FAT[1] are reserved.
310 return (firstNonFatSec + (RootClusterNum()-KFatFirstSearchCluster) * SectorsPerCluster());
313 {//-- FAT12/16 root dir starts just after the FATs
314 return firstNonFatSec;
319 /** @return first data sector number. for FAT32 it includes the root directory */
320 TInt TFatBootSector::FirstDataSector() const
322 return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
325 /** @return FAT-type independent sector count on the volume */
326 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
328 __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
329 return TotalSectors() >0 ? (TUint32)TotalSectors() : (TUint32)HugeSectors();
332 /** @return FAT-type independent number of sectors in one FAT */
333 TUint32 TFatBootSector::TotalFatSectors() const
335 __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
336 return FatSectors() >0 ? (TUint32)FatSectors() : FatSectors32();
342 //-------------------------------------------------------------------------------------------------------------------
344 const TUint32 KLeadSignature = 0x41615252; ///< FSInfo Lead signiture value
345 const TUint32 KStructureSignature = 0x61417272; ///< FSInfo Structure signiture value
346 const TUint32 KTrailingSignature = 0xAA550000; ///< FSInfo Trailing signiture
352 //-------------------------------------------------------------------------------------------------------------------
354 /** Initialise the data */
355 void TFSInfo::Initialise()
357 Mem::FillZ(this, sizeof(TFSInfo));
359 iLeadSig = KLeadSignature;
360 iStructureSig = KStructureSignature;
361 iTrainlingSig = KTrailingSignature;
364 //-------------------------------------------------------------------------------------------------------------------
367 @return ETrue if FSInfo sector contents seems to be valid
369 TBool TFSInfo::IsValid() const
371 return (iLeadSig == KLeadSignature && iStructureSig == KStructureSignature && iTrainlingSig == KTrailingSignature);
374 //-------------------------------------------------------------------------------------------------------------------
377 Initialize FSInfo sector object from the given bufer. Does not validate the data.
378 @param aBuf buffer with data.
380 void TFSInfo::Internalize(const TDesC8& aBuf)
382 ASSERT((TUint32)aBuf.Size() >= KSizeOfFSInfo);
386 Mem::Copy(&iLeadSig, &aBuf[pos],4); pos+=(KFSInfoReserved1Size+4);
387 Mem::Copy(&iStructureSig, &aBuf[pos],4); pos+=4;
388 Mem::Copy(&iFreeCount,&aBuf[pos],4); pos+=4;
389 Mem::Copy(&iNextFree,&aBuf[pos],4); pos+=(4+KFSInfoReserved2Size);
390 Mem::Copy(&iTrainlingSig,&aBuf[pos],4);
393 //-------------------------------------------------------------------------------------------------------------------
396 Externalize FSInfo sector object to the given data buffer.
397 @param aBuf buffer to externalize.
399 void TFSInfo::Externalize(TDes8& aBuf) const
401 ASSERT((TUint32)aBuf.MaxSize() >= KSizeOfFSInfo);
403 aBuf.SetLength(KSizeOfFSInfo);
408 Mem::Copy(&aBuf[pos],&KLeadSignature,4); pos+=4;
409 pos+=KFSInfoReserved1Size;
410 Mem::Copy(&aBuf[pos],&KStructureSignature,4); pos+=4;
411 Mem::Copy(&aBuf[pos],&iFreeCount,4); pos+=4;
412 Mem::Copy(&aBuf[pos],&iNextFree,4); pos+=4;
413 pos+=KFSInfoReserved2Size;
414 Mem::Copy(&aBuf[pos],&KTrailingSignature,4);
417 //-------------------------------------------------------------------------------------------------------------------
420 Print out the FSInfo sector info.
422 void TFSInfo::PrintDebugInfo() const
424 __PRINT(_L("\n==== FSInfoSector : ===="));
425 __PRINT1(_L("FSI_LeadSig: 0x%x"),iLeadSig);
426 __PRINT1(_L("FSI_StrucSig: 0x%x"),iStructureSig);
427 __PRINT1(_L("FSI_FreeCount: 0x%x"),iFreeCount);
428 __PRINT1(_L("FSI_NxtFree: 0x%x"),iNextFree);
429 __PRINT1(_L("FSI_TrailSig: 0x%x"),iTrainlingSig);
430 __PRINT(_L("========================\n"));