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.
15 // various FAT test utilities
20 #include "fat_utils.h"
21 using namespace Fat_Test_Utils;
25 //-------------------------------------------------------------------------------------------------------------------
27 //-- define this macro if it is necessarily to exclude all stuff that uses RFs, consoles etc.
28 //-- may be useful if this code is used for file server extensions. mmp file is a good place to define this macro.
29 #ifndef FAT_UTILS_LEAN_AND_MEAN
34 //-------------------------------------------------------------------------------------------------------------------
39 @param aFs reference to the FS session
40 @param aDrive drive number
41 @param aQuickFormat if True, a quick format will be performed. otherwise - full
42 @param apFmtParams pointer to the optional format parameters. if NULL, it means tha no options specified
43 @param aForceErase if True, use media force erase.
45 @return system-wide error codes.
47 TInt Fat_Test_Utils::FormatFatDrive(RFs &aFs, TInt aDrive, TBool aQuickFormat, const TFatFormatParam* apFmtParams/*=NULL*/, TBool aForceErase /*=EFalse*/)
49 TPtrC fmtTypeName = (aQuickFormat ? _L("Quick") : _L("Full"));
50 DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() drv:%d, type:%S\n"),aDrive, &fmtTypeName);
52 ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
61 fmtMode |= EQuickFormat;
64 fmtMode |= EForceErase;
67 drvName.Format(_L("%C:"),'A'+aDrive);
70 {//-- no format parameters specified
71 //DoPrintf(_L("~ Format parameters - not specified\n"));
72 nRes = format.Open(aFs, drvName, fmtMode, fmtCnt);
77 {//-- some extra parameters specified, use special format
78 fmtMode |= ESpecialFormat;
79 TLDFormatInfo formatInfo;
82 buf.Copy(_L("~ Format parameters: "));
84 if(apFmtParams->iFatType)
85 {//-- FAT type is specified
86 buf.AppendFormat(_L("FAT%d"), apFmtParams->iFatType);
87 formatInfo.iFATBits = (TLDFormatInfo::TFATBits)apFmtParams->iFatType;
90 const TUint16 spc = (TUint16)apFmtParams->iSecPerCluster;
92 {//-- sectors per cluster value is specified
93 buf.AppendFormat(_L(", spc:%d"), spc);
94 formatInfo.iSectorsPerCluster = spc;
97 const TUint16 rsvdSec = (TUint16)apFmtParams->iReservedSectors;
99 {//-- reserved sectors numer is specified
100 buf.AppendFormat(_L(", rsvdSec:%d"), rsvdSec);
101 formatInfo.iReservedSectors = rsvdSec;
104 buf.Append(_L("\n"));
107 TSpecialFormatInfoBuf formatInfoBuf(formatInfo);
108 nRes = format.Open(aFs, drvName, fmtMode, fmtCnt, formatInfoBuf);
118 nRes = format.Next(fmtCnt);
122 if(fmtCnt != prevCnt)
129 //-- formatting has finished
136 DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() failed! code:%d\n"), nRes);
141 //-------------------------------------------------------------------------------------------------------------------
144 Read FAT FSInfo sector via RRawDisk interface.
145 @param aFs reference to the FS session
146 @param aDrive drive number
147 @param aMediaPos media position (0 for the main boot sector)
148 @param aFsInfo where to read data
150 @return standard error codes
152 TInt Fat_Test_Utils::ReadFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFSInfo& aFsInfo)
154 DoPrintf(_L("~ Fat_Test_Utils::ReadFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);
156 TInt nRes = KErrNone;
158 TBuf8<KSizeOfFSInfo> fsInfoSecBuf(KSizeOfFSInfo);
159 TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, fsInfoSecBuf.Size(), fsInfoSecBuf));
162 {//-- take FSInfo data from the buffer
163 aFsInfo.Internalize(fsInfoSecBuf);
169 //-------------------------------------------------------------------------------------------------------------------
172 Write FAT FSInfo sector via RRawDisk interface.
173 @param aFs reference to the FS session
174 @param aDrive drive number
175 @param aMediaPos media position (0 for the main boot sector)
176 @param aFsInfo data to write
178 @return standard error codes
180 TInt Fat_Test_Utils::WriteFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFSInfo& aFsInfo)
182 DoPrintf(_L("~ Fat_Test_Utils::WriteFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);
184 TInt nRes = KErrNone;
185 TBuf8<KSizeOfFSInfo> fsInfoSecBuf;
187 //-- put data to the sector buffer
188 aFsInfo.Externalize(fsInfoSecBuf);
190 TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, fsInfoSecBuf))
195 //-------------------------------------------------------------------------------------------------------------------
198 Read FAT boot sector via RRawDisk interface.
199 @param aFs reference to the FS session
200 @param aDrive drive number
201 @param aMediaPos media position (0 for the main boot sector)
202 @param aBootSector where to read data
204 @return standard error codes
206 TInt Fat_Test_Utils::ReadBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFatBootSector& aBootSector)
208 DoPrintf(_L("~ Fat_Test_Utils::ReadBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);
210 TInt nRes = KErrNone;
211 TBuf8<KSizeOfFatBootSector> bootSecBuf(KSizeOfFatBootSector);
213 TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, bootSecBuf.Size(), bootSecBuf));
216 {//-- initialise TFatBootSector object
217 aBootSector.Internalize(bootSecBuf);
223 //-------------------------------------------------------------------------------------------------------------------
226 Write FAT boot sector via RRawDisk interface.
227 @param aFs reference to the FS session
228 @param aDrive drive number
229 @param aMediaPos media position (0 for the main boot sector)
230 @param aBootSector data to write
232 @return standard error codes
234 TInt Fat_Test_Utils::WriteBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFatBootSector& aBootSector)
236 DoPrintf(_L("~ Fat_Test_Utils::WriteBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);
238 TBuf8<KDefaultSectorSize> bootSecBuf(KDefaultSectorSize);
240 //-- externalize boot sector to the data buffer
242 aBootSector.Externalize(bootSecBuf);
244 //-- put a boot sector signature to the last 2 bytes
245 bootSecBuf[KDefaultSectorSize-2] = 0x55;
246 bootSecBuf[KDefaultSectorSize-1] = 0xaa;
248 //-- write boot sector data to the media
250 TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, bootSecBuf));
254 //-------------------------------------------------------------------------------------------------------------------
256 Obtain FAT type for the given drive
258 @return TFatType enum values. if aDrive has not FAT FS, EInvalid value is returned
260 TFatType Fat_Test_Utils::GetFatType(RFs &aFs, TInt aDrive)
262 if(Is_Fat16(aFs, aDrive))
264 else if(Is_Fat32(aFs, aDrive))
266 else if(Is_Fat12(aFs, aDrive))
272 //-------------------------------------------------------------------------------------------------------------------
274 #endif //FAT_UTILS_LEAN_AND_MEAN
279 TFatFormatParam::TFatFormatParam()
283 iReservedSectors = 0;
286 //-------------------------------------------------------------------------------------------------------------------
288 TFatBootSector::TFatBootSector()
293 /** initialises the boot sector data */
294 void TFatBootSector::Initialise()
296 Mem::FillZ(this, sizeof(TFatBootSector));
299 TBool TFatBootSector::operator==(const TFatBootSector& aRhs)
301 ASSERT(&aRhs != this);
303 return ETrue; //-- comparing with itself
305 return (Mem::Compare((TUint8*)this, sizeof(TFatBootSector), (TUint8*)&aRhs, sizeof(TFatBootSector)) == 0);
310 @return ETrue if the boot sector contents seems to be valid
312 TBool TFatBootSector::IsValid() const
314 const TFatType fatType = FatType(); //-- it will check SectorsPerCluster etc.
316 if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1)
319 if(fatType == EFat32)
321 if(VersionNumber()!= 0 || FatSectors()!=0 || FatSectors32()<1 || RootClusterNum()<(TUint32)KFatFirstSearchCluser ||
322 TotalSectors()!=0 || HugeSectors() <5 || RootDirEntries() !=0)
324 goto Invalid; //-- these values are not compliant with FAT specs
329 if(TotalSectors() >0 && HugeSectors() >0 )
330 goto Invalid; //-- values clash
332 const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
333 const TUint32 rootDirStartSec = ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
335 if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5)
336 goto Invalid; //-- these values are not compliant with FAT specs
342 DoPrintf(_L("~ TFatBootSector::IsValid() failed!\n"));
347 //-------------------------------------------------------------------------------------------------------------------
350 Initialize boot sector object from the given bufer. Does not validate the data.
351 @param aBuf buffer with data.
353 void TFatBootSector::Internalize(const TDesC8& aBuf)
355 ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
361 Mem::Copy(&iJumpInstruction, &aBuf[pos],3); pos+=3; // 0 TUint8 iJumpInstruction[3]
362 Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3 TUint8 iVendorId[KVendorIdSize]
363 Mem::Copy(&iBytesPerSector,&aBuf[pos],2); pos+=2; // 11 TUint16 iBytesPerSector
364 Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1); pos+=1; // 13 TUint8 iSectorsPerCluster
365 Mem::Copy(&iReservedSectors,&aBuf[pos],2); pos+=2; // 14 TUint16 iReservedSectors
366 Mem::Copy(&iNumberOfFats,&aBuf[pos],1); pos+=1; // 16 TUint8 iNumberOfFats
367 Mem::Copy(&iRootDirEntries,&aBuf[pos],2); pos+=2; // 17 TUint16 iRootDirEntries
368 Mem::Copy(&iTotalSectors,&aBuf[pos],2); pos+=2; // 19 TUint16 iTotalSectors
369 Mem::Copy(&iMediaDescriptor,&aBuf[pos],1); pos+=1; // 21 TUint8 iMediaDescriptor
370 Mem::Copy(&iFatSectors,&aBuf[pos],2); pos+=2; // 22 TUint16 iFatSectors
371 Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2); pos+=2; // 24 TUint16 iSectorsPerTrack
372 Mem::Copy(&iNumberOfHeads,&aBuf[pos],2); pos+=2; // 26 TUint16 iNumberOfHeads
373 Mem::Copy(&iHiddenSectors,&aBuf[pos],4); pos+=4; // 28 TUint32 iHiddenSectors
374 Mem::Copy(&iHugeSectors,&aBuf[pos],4); pos+=4; // 32 TUint32 iHugeSectors
376 if(RootDirEntries() == 0) //-- we have FAT32 volume
378 Mem::Copy(&iFatSectors32, &aBuf[pos],4); pos+=4; // 36 TUint32 iFatSectors32
379 Mem::Copy(&iFATFlags, &aBuf[pos],2); pos+=2; // 40 TUint16 iFATFlags
380 Mem::Copy(&iVersionNumber, &aBuf[pos],2); pos+=2; // 42 TUint16 iVersionNumber
381 Mem::Copy(&iRootClusterNum, &aBuf[pos],4); pos+=4; // 44 TUint32 iRootClusterNum
382 Mem::Copy(&iFSInfoSectorNum, &aBuf[pos],2); pos+=2; // 48 TUint16 iFSInfoSectorNum
383 Mem::Copy(&iBkBootRecSector, &aBuf[pos],2); // 50 TUint16 iBkBootRecSector
384 pos+=(2+12); //extra 12 for the reserved bytes
387 Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1); pos+=1;// 36|64 TUint8 iPhysicalDriveNumber
388 Mem::Copy(&iReserved,&aBuf[pos],1); pos+=1;// 37|65 TUint8 iReserved
389 Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature
390 Mem::Copy(&iUniqueID,&aBuf[pos],4); pos+=4;// 39|67 TUint32 iUniqueID
391 Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize); // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize]
392 pos+=KVolumeLabelSize;
394 // 54|82 TUint8 iFileSysType[KFileSysTypeSize]
395 ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
396 Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
399 //-------------------------------------------------------------------------------------------------------------------
402 Externalize boot sector object to the given data buffer.
403 @param aBuf buffer to externalize.
405 void TFatBootSector::Externalize(TDes8& aBuf) const
407 ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
409 if(aBuf.Size() < KSizeOfFatBootSector)
410 aBuf.SetLength(KSizeOfFatBootSector);
414 Mem::Copy(&aBuf[pos],&iJumpInstruction,3); pos+=3;
415 Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8;
416 Mem::Copy(&aBuf[pos],&iBytesPerSector,2); pos+=2;
417 Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1); pos+=1;
418 Mem::Copy(&aBuf[pos],&iReservedSectors,2); pos+=2;
419 Mem::Copy(&aBuf[pos],&iNumberOfFats,1); pos+=1;
420 Mem::Copy(&aBuf[pos],&iRootDirEntries,2); pos+=2;
421 Mem::Copy(&aBuf[pos],&iTotalSectors,2); pos+=2;
422 Mem::Copy(&aBuf[pos],&iMediaDescriptor,1); pos+=1;
423 Mem::Copy(&aBuf[pos],&iFatSectors,2); pos+=2;
424 Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2); pos+=2;
425 Mem::Copy(&aBuf[pos],&iNumberOfHeads,2); pos+=2;
426 Mem::Copy(&aBuf[pos],&iHiddenSectors,4); pos+=4;
427 Mem::Copy(&aBuf[pos],&iHugeSectors,4); pos+=4;
431 Mem::Copy(&aBuf[pos], &iFatSectors32,4); pos+=4;
432 Mem::Copy(&aBuf[pos], &iFATFlags, 2); pos+=2;
433 Mem::Copy(&aBuf[pos], &iVersionNumber, 2); pos+=2;
434 Mem::Copy(&aBuf[pos], &iRootClusterNum, 4); pos+=4;
435 Mem::Copy(&aBuf[pos], &iFSInfoSectorNum, 2);pos+=2;
436 Mem::Copy(&aBuf[pos], &iBkBootRecSector, 2);pos+=2;
438 //extra 12 for the reserved bytes
439 ASSERT(aBuf.Size() >= pos+12);
440 Mem::FillZ(&aBuf[pos],12);
444 Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1); pos+=1;
445 Mem::FillZ(&aBuf[pos],1); pos+=1;
446 Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1;
447 Mem::Copy(&aBuf[pos],&iUniqueID,4); pos+=4;
449 Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize);
450 pos+=KVolumeLabelSize;
452 ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
453 Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
456 //-------------------------------------------------------------------------------------------------------------------
458 /** replaces all non-printable characters in a buffer with spaces */
459 static void FixDes(TDes& aDes)
461 for(TInt i=0; i< aDes.Length(); ++i)
470 Print out the boot sector info.
472 void TFatBootSector::PrintDebugInfo() const
476 DoPrintf(_L("======== BootSector info: =======\n"));
478 buf.Copy(FileSysType()); FixDes(buf);
479 DoPrintf(_L("FAT type:%S\n"),&buf);
481 buf.Copy(VendorId()); FixDes(buf);
482 DoPrintf(_L("Vendor ID:%S\n"),&buf);
484 DoPrintf(_L("BytesPerSector: %d\n"),BytesPerSector());
485 DoPrintf(_L("SectorsPerCluster: %d\n"),SectorsPerCluster());
486 DoPrintf(_L("ReservedSectors: %d\n"),ReservedSectors());
487 DoPrintf(_L("NumberOfFats: %d\n"),NumberOfFats());
488 DoPrintf(_L("RootDirEntries: %d\n"),RootDirEntries());
489 DoPrintf(_L("Total Sectors: %d\n"),TotalSectors());
490 DoPrintf(_L("MediaDescriptor: 0x%x\n"),MediaDescriptor());
491 DoPrintf(_L("FatSectors: %d\n"),FatSectors());
492 DoPrintf(_L("SectorsPerTrack: %d\n"),SectorsPerTrack());
493 DoPrintf(_L("NumberOfHeads: %d\n"),NumberOfHeads());
494 DoPrintf(_L("HugeSectors: %d\n"),HugeSectors());
495 DoPrintf(_L("Fat32 Sectors: %d\n"),FatSectors32());
496 DoPrintf(_L("Fat32 Flags: %d\n"),FATFlags());
497 DoPrintf(_L("Fat32 Version Number: %d\n"),VersionNumber());
498 DoPrintf(_L("Root Cluster Number: %d\n"),RootClusterNum());
499 DoPrintf(_L("FSInfo Sector Number: %d\n"),FSInfoSectorNum());
500 DoPrintf(_L("Backup Boot Rec Sector Number: %d\n"),BkBootRecSector());
501 DoPrintf(_L("PhysicalDriveNumber:%d\n"),PhysicalDriveNumber());
502 DoPrintf(_L("ExtendedBootSignature: %d\n"),ExtendedBootSignature());
503 DoPrintf(_L("UniqueID: 0x%x\n"),UniqueID());
505 buf.Copy(VolumeLabel()); FixDes(buf);
506 DoPrintf(_L("VolumeLabel:%S\n"),&buf);
508 DoPrintf(_L("=============================\n"));
511 //-------------------------------------------------------------------------------------------------------------------
515 Determine FAT type according to the information from boot sector, see FAT32 specs.
518 TFatType TFatBootSector::FatType(void) const
521 //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
522 if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 || iBytesPerSector > 4096)
523 return EInvalid; //-- invalid iBytesPerSector value
525 //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
526 if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128)
527 return EInvalid; //-- invalid iSectorsPerCluster value
529 const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
530 const TUint32 fatSz = iFatSectors ? iFatSectors : iFatSectors32;
531 const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors;
532 const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * fatSz) + rootDirSectors);
533 const TUint32 clusterCnt = dataSec / iSectorsPerCluster;
535 //-- magic. see FAT specs for details.
536 if(clusterCnt < 4085)
538 else if(clusterCnt < 65525)
545 //-------------------------------------------------------------------------------------------------------------------
547 /** Returns Sectors in Fat table for 32 bit volume */
548 TUint32 TFatBootSector::FatSectors32() const
549 {return iFatSectors32;}
552 TUint16 TFatBootSector::FATFlags() const
555 /** Version number of the file system */
556 TUint16 TFatBootSector::VersionNumber() const
557 {return iVersionNumber;}
559 /** Cluster number of the root directory */
560 TUint32 TFatBootSector::RootClusterNum() const
561 {return iRootClusterNum;}
563 /** Sector number containing the FSIInfo structure */
564 TUint16 TFatBootSector::FSInfoSectorNum() const
565 {return iFSInfoSectorNum;}
567 /** Backup boot sector */
568 TUint16 TFatBootSector::BkBootRecSector() const
569 {return iBkBootRecSector;}
571 /** Sets the number of sectors in Fat table for 32 bit volume */
572 void TFatBootSector::SetFatSectors32(TUint32 aFatSectors32)
573 {iFatSectors32 = aFatSectors32;}
575 /** Sets the Fat flags */
576 void TFatBootSector::SetFATFlags(TUint16 aFATFlags)
577 {iFATFlags = aFATFlags;}
579 /** Sets the version number of the file system */
580 void TFatBootSector::SetVersionNumber(TUint16 aVersionNumber)
581 {iVersionNumber = aVersionNumber;}
583 /** Sets the cluster number of the root directory */
584 void TFatBootSector::SetRootClusterNum(TUint32 aRootClusterNum)
585 {iRootClusterNum = aRootClusterNum;}
587 /** Set the sector number containing the FSIInfo structure */
588 void TFatBootSector::SetFSInfoSectorNum(TUint16 aFSInfoSectorNum)
589 {iFSInfoSectorNum = aFSInfoSectorNum;}
591 /** Set the backup boot sector */
592 void TFatBootSector::SetBkBootRecSector(TUint16 aBkBootRecSector)
593 {iBkBootRecSector = aBkBootRecSector;}
595 /** Returns the vendor ID of the file system that formatted the volume */
596 const TPtrC8 TFatBootSector::VendorId() const
597 {return TPtrC8(iVendorId,KVendorIdSize);}
599 /** Return the bytes per sector */
600 TUint16 TFatBootSector::BytesPerSector() const
601 {return iBytesPerSector;}
603 /** Returns the sectors per cluster ratio */
604 TInt TFatBootSector::SectorsPerCluster() const
605 {return iSectorsPerCluster;}
607 /** Returns the number of reserved sectors on the volume */
608 TInt TFatBootSector::ReservedSectors() const
609 {return iReservedSectors;}
611 /** Returns the number of Fats on the volume */
612 TInt TFatBootSector::NumberOfFats() const
613 {return iNumberOfFats;}
615 /** Returns the number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32 */
616 TInt TFatBootSector::RootDirEntries() const
617 {return iRootDirEntries;}
619 /** Returns the total sectors on the volume, zero for FAT32 */
620 TInt TFatBootSector::TotalSectors() const
621 {return iTotalSectors;}
623 /** Returns the media descriptor */
624 TUint8 TFatBootSector::MediaDescriptor() const
625 {return iMediaDescriptor;}
627 /** Returns sectors used for the Fat table, zero for FAT32 */
628 TInt TFatBootSector::FatSectors() const
629 {return iFatSectors;}
631 /** Returns sectors per track */
632 TInt TFatBootSector::SectorsPerTrack() const
633 {return iSectorsPerTrack;}
635 /** Returns the number of heads */
636 TInt TFatBootSector::NumberOfHeads() const
637 {return iNumberOfHeads;}
639 /** Returns the number of hidden sectors in the volume */
640 TInt TFatBootSector::HiddenSectors() const
641 {return iHiddenSectors;}
643 /** Returns total sectors in the volume, Used if totalSectors > 65535 */
644 TInt TFatBootSector::HugeSectors() const
645 {return iHugeSectors;}
647 /** Returns the physical drive number, not used in Symbian OS */
648 TInt TFatBootSector::PhysicalDriveNumber() const
649 {return iPhysicalDriveNumber;}
651 /** Returns the extended boot signiture */
652 TInt TFatBootSector::ExtendedBootSignature() const
653 {return iExtendedBootSignature;}
655 /** Returns the unique volume ID */
656 TUint32 TFatBootSector::UniqueID() const
659 /** Returns the volume's label */
660 const TPtrC8 TFatBootSector::VolumeLabel() const
661 {return TPtrC8(iVolumeLabel,KVolumeLabelSize);}
663 /** Returns the file system type */
664 const TPtrC8 TFatBootSector::FileSysType() const
665 {return TPtrC8(iFileSysType,KFileSysTypeSize);}
667 /** Returns the boot sector signiture */
668 TInt TFatBootSector::BootSectorSignature() const
669 {return KBootSectorSignature;}
671 /** Set the jump instruction */
672 void TFatBootSector::SetJumpInstruction()
673 {iJumpInstruction[0]=0xE9;iJumpInstruction[2]=0x90;}
675 /** Set the vendor ID of the file system that formatted the volume */
676 void TFatBootSector::SetVendorID(const TDesC8& aDes)
678 ASSERT(aDes.Length()<=KVendorIdSize);
679 TPtr8 buf(iVendorId,KVendorIdSize);
683 /** Sets the bytes per sector */
684 void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector)
686 ASSERT(!(aBytesPerSector&~KMaxTUint16));
687 iBytesPerSector=(TUint16)aBytesPerSector;
690 /** Set the sectors per cluster ratio */
691 void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster)
693 ASSERT(!(aSectorsPerCluster&~KMaxTUint8));
694 iSectorsPerCluster=(TUint8)aSectorsPerCluster;
698 /** Sets the number of reserved sectors on the volume */
699 void TFatBootSector::SetReservedSectors(TInt aReservedSectors)
701 ASSERT(!(aReservedSectors&~KMaxTUint16));
702 iReservedSectors=(TUint16)aReservedSectors;
705 /** Sets the number of Fats on the volume */
706 void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats)
708 ASSERT(!(aNumberOfFats&~KMaxTUint8));
709 iNumberOfFats=(TUint8)aNumberOfFats;
712 /** Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32 */
713 void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries)
715 ASSERT(!(aRootDirEntries&~KMaxTUint16));
716 iRootDirEntries=(TUint16)aRootDirEntries;
719 /** Total sectors on the volume, zero for FAT32 */
720 void TFatBootSector::SetTotalSectors(TInt aTotalSectors)
722 ASSERT(!(aTotalSectors&~KMaxTUint16));
723 iTotalSectors=(TUint16)aTotalSectors;
726 /** Set the media descriptor */
727 void TFatBootSector::SetMediaDescriptor(TUint8 aMediaDescriptor)
728 {iMediaDescriptor=aMediaDescriptor;}
730 /** Sectors used for the Fat table, zero for FAT32 */
731 void TFatBootSector::SetFatSectors(TInt aFatSectors)
733 ASSERT(!(aFatSectors&~KMaxTUint16));
734 iFatSectors=(TUint16)aFatSectors;
737 /** Set the sectors per track */
738 void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack)
740 ASSERT(!(aSectorsPerTrack&~KMaxTUint16));
741 iSectorsPerTrack=(TUint16)aSectorsPerTrack;
744 /** Set the number of heads */
745 void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads)
747 ASSERT(!(aNumberOfHeads&~KMaxTUint16));
748 iNumberOfHeads=(TUint16)aNumberOfHeads;
751 /** Set the number of hidden sectors in the volume */
752 void TFatBootSector::SetHiddenSectors(TUint32 aHiddenSectors)
754 iHiddenSectors=(TUint32)(aHiddenSectors);
757 /** Set the total sectors in the volume, Used if totalSectors > 65535 */
758 void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors)
759 {iHugeSectors=aHugeSectors;}
762 /** Physical drive number, not used in Symbian OS */
763 void TFatBootSector::SetPhysicalDriveNumber(TInt aPhysicalDriveNumber)
765 ASSERT(!(aPhysicalDriveNumber&~KMaxTUint8));
766 iPhysicalDriveNumber=(TUint8)aPhysicalDriveNumber;
769 /** Set the reserved byte value */
770 void TFatBootSector::SetReservedByte(TUint8 aReservedByte)
771 {iReserved=aReservedByte;}
773 /** Set the extended boot signiture */
774 void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature)
776 ASSERT(!(anExtendedBootSignature&~KMaxTUint8));
777 iExtendedBootSignature=(TUint8)anExtendedBootSignature;
780 /** Set the unique volume ID */
781 void TFatBootSector::SetUniqueID(TUint32 anUniqueID)
782 {iUniqueID=anUniqueID;}
784 /** Set the volume's label */
785 void TFatBootSector::SetVolumeLabel(const TDesC8& aDes)
787 ASSERT(aDes.Length()<=KVolumeLabelSize);
788 TPtr8 buf(iVolumeLabel,KVolumeLabelSize);
792 /** Set the file system type */
793 void TFatBootSector::SetFileSysType(const TDesC8& aDes)
795 ASSERT(aDes.Length()<=8);
796 TPtr8 buf(iFileSysType,8);
801 /** @return The first Fat sector number */
802 TInt TFatBootSector::FirstFatSector() const
804 __ASSERT_ALWAYS(IsValid(), User::Invariant());
805 return ReservedSectors();
809 @return Number of sectors in root directory. 0 for FAT32
811 TUint32 TFatBootSector::RootDirSectors() const
813 __ASSERT_ALWAYS(IsValid(), User::Invariant());
814 return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
818 /** @return Start sector number of the root directory */
819 TInt TFatBootSector::RootDirStartSector() const
821 __ASSERT_ALWAYS(IsValid(), User::Invariant());
823 const TUint32 firstNonFatSec = ReservedSectors() + TotalFatSectors()*NumberOfFats();
825 if(FatType() == EFat32)
826 {//-- FAT32 root dir is a file, calculate the position by it's 1st cluster number. FAT[0]+FAT[1] are reserved.
827 return (firstNonFatSec + (RootClusterNum()-KFatFirstSearchCluser) * SectorsPerCluster());
830 {//-- FAT12/16 root dir starts just after the FATs
831 return firstNonFatSec;
836 /** @return first data sector number. for FAT32 it includes the root directory */
837 TInt TFatBootSector::FirstDataSector() const
839 return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
842 /** @return FAT-type independent sector count on the volume */
843 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
845 __ASSERT_ALWAYS(IsValid(), User::Invariant());
846 return HugeSectors() ? (TUint32)HugeSectors() : (TUint32)TotalSectors();
849 /** @return FAT-type independent number of sectors in one FAT */
850 TUint32 TFatBootSector::TotalFatSectors() const
852 __ASSERT_ALWAYS(IsValid(), User::Invariant());
853 return FatSectors32() ? FatSectors32() : (TUint32)FatSectors();
857 //-------------------------------------------------------------------------------------------------------------------
860 const TUint32 KLeadSignature = 0x41615252; ///< FSInfo Lead signiture value
861 const TUint32 KStructureSignature = 0x61417272; ///< FSInfo Structure signiture value
862 const TUint32 KTrailingSignature = 0xAA550000; ///< FSInfo Trailing signiture
868 //-------------------------------------------------------------------------------------------------------------------
870 /** Initialise the data */
871 void TFSInfo::Initialise()
873 Mem::FillZ(this, sizeof(TFSInfo));
875 iLeadSig = KLeadSignature;
876 iStructureSig = KStructureSignature;
877 iTrainlingSig = KTrailingSignature;
881 TBool TFSInfo::operator==(const TFSInfo& aRhs)
883 ASSERT(&aRhs != this);
885 return ETrue; //-- comparing with itself
887 return (Mem::Compare((TUint8*)this, sizeof(TFSInfo), (TUint8*)&aRhs, sizeof(TFSInfo)) == 0);
890 //-------------------------------------------------------------------------------------------------------------------
893 @return ETrue if FSInfo sector contents seems to be valid
895 TBool TFSInfo::IsValid() const
897 return (iLeadSig == KLeadSignature && iStructureSig == KStructureSignature && iTrainlingSig == KTrailingSignature);
900 //-------------------------------------------------------------------------------------------------------------------
903 Initialize FSInfo sector object from the given bufer. Does not validate the data.
904 @param aBuf buffer with data.
906 void TFSInfo::Internalize(const TDesC8& aBuf)
908 ASSERT((TUint32)aBuf.Size() >= KSizeOfFSInfo);
912 Mem::Copy(&iLeadSig, &aBuf[pos],4); pos+=(KFSInfoReserved1Size+4);
913 Mem::Copy(&iStructureSig, &aBuf[pos],4); pos+=4;
914 Mem::Copy(&iFreeCount,&aBuf[pos],4); pos+=4;
915 Mem::Copy(&iNextFree,&aBuf[pos],4); pos+=(4+KFSInfoReserved2Size);
916 Mem::Copy(&iTrainlingSig,&aBuf[pos],4);
919 //-------------------------------------------------------------------------------------------------------------------
922 Externalize FSInfo sector object to the given data buffer.
923 @param aBuf buffer to externalize.
925 void TFSInfo::Externalize(TDes8& aBuf) const
927 ASSERT((TUint32)aBuf.MaxSize() >= KSizeOfFSInfo);
929 aBuf.SetLength(KSizeOfFSInfo);
934 Mem::Copy(&aBuf[pos],&KLeadSignature,4); pos+=4;
935 pos+=KFSInfoReserved1Size;
936 Mem::Copy(&aBuf[pos],&KStructureSignature,4); pos+=4;
937 Mem::Copy(&aBuf[pos],&iFreeCount,4); pos+=4;
938 Mem::Copy(&aBuf[pos],&iNextFree,4); pos+=4;
939 pos+=KFSInfoReserved2Size;
940 Mem::Copy(&aBuf[pos],&KTrailingSignature,4);
943 //-------------------------------------------------------------------------------------------------------------------
946 Print out the FSInfo sector info.
948 void TFSInfo::PrintDebugInfo() const
950 DoPrintf(_L("==== FSInfoSector : ====\n"));
951 DoPrintf(_L("FSI_LeadSig: 0x%x\n"),iLeadSig);
952 DoPrintf(_L("FSI_StrucSig: 0x%x\n"),iStructureSig);
953 DoPrintf(_L("FSI_FreeCount: 0x%x\n"),iFreeCount);
954 DoPrintf(_L("FSI_NxtFree: 0x%x\n"),iNextFree);
955 DoPrintf(_L("FSI_TrailSig: 0x%x\n"),iTrainlingSig);
956 DoPrintf(_L("========================\n"));
959 TUint32 TFSInfo::FreeClusterCount() const
964 TUint32 TFSInfo::NextFreeCluster() const
970 void TFSInfo::SetFreeClusterCount(TUint32 aFreeCount)
972 iFreeCount = aFreeCount;
975 void TFSInfo::SetNextFreeCluster(TUint32 aNextCluster)
977 iNextFree = aNextCluster;
981 //-------------------------------------------------------------------------------------------------------------------
984 Deciphers the dos time/date entry information and converts to TTime
986 TTime Fat_Test_Utils::DosTimeToTTime(TInt aDosTime,TInt aDosDate)
992 TInt monthMask=0x01E0;
993 TInt yearMask=0xFE00;
995 TInt secs=(aDosTime&secMask)*2;
996 TInt mins=(aDosTime&minMask)>>5;
997 TInt hrs=(aDosTime&hrMask)>>11;
998 TInt days=(aDosDate&dayMask)-1;
999 TMonth months=(TMonth)(((aDosDate&monthMask)>>5)-1);
1000 TInt years=((aDosDate&yearMask)>>9)+1980;
1003 TInt ret=datetime.Set(years,months,days,hrs,mins,secs,0);
1005 return(TTime(datetime));
1010 Converts a TTime to a dos time
1012 TInt Fat_Test_Utils::DosTimeFromTTime(const TTime& aTime)
1014 TDateTime dateTime=aTime.DateTime();
1015 TInt dosSecs=dateTime.Second()/2;
1016 TInt dosMins=dateTime.Minute()<<5;
1017 TInt dosHrs=dateTime.Hour()<<11;
1018 return dosSecs|dosMins|dosHrs;
1022 Converts a TTime to a dos date
1024 TInt Fat_Test_Utils::DosDateFromTTime(const TTime& aTime)
1027 TDateTime dateTime=aTime.DateTime();
1028 TInt dosDays=dateTime.Day()+1;
1029 TInt dosMonths=(dateTime.Month()+1)<<5;
1030 TInt dosYears=(dateTime.Year()-1980)<<9;
1031 return dosDays|dosMonths|dosYears;
1036 Converts xxx.yyy to standard format aaaaaaaayyy
1038 TBuf8<12> Fat_Test_Utils::DosNameToStdFormat(const TDesC8& aDosName)
1040 ASSERT(aDosName.Length()>=0 && aDosName.Length()<=KMaxFatFileName);
1043 Mem::Fill((TUint8*)result.Ptr(),result.MaxSize(),' ');
1044 TInt dotPos=aDosName.Locate('.');
1045 if (dotPos==KErrNotFound)
1048 result.SetLength(11);
1051 result=aDosName.Left(dotPos);
1052 result.SetLength(11);
1053 TPtr8 ext(&result[8],3);
1054 ext=aDosName.Right(aDosName.Length()-dotPos-1);
1059 Converts aaaaaaaayyy to dos name format xxx.yyy
1061 TBuf8<12> Fat_Test_Utils::DosNameFromStdFormat(const TDesC8& aStdFormatName)
1063 ASSERT(aStdFormatName.Length()==11);
1066 TInt nameLen=aStdFormatName.Locate(' ');
1067 if (nameLen>8 || nameLen==KErrNotFound)
1069 result=aStdFormatName.Left(nameLen);
1070 TPtrC8 ext(&aStdFormatName[8],3);
1071 TInt extLen=ext.Locate(' ');
1073 result.Append(TChar('.'));
1074 if (extLen==KErrNotFound)
1076 result.Append(ext.Left(extLen));
1077 if(result.Length() && result[0]==0x05 )
1085 Return the number of VFat entries required to describe a filename of length aNameLength
1087 TInt Fat_Test_Utils::NumberOfVFatEntries(TInt aNameLength)
1089 TInt numberOfEntries=0;
1090 if (aNameLength%KMaxVFatEntryName)
1091 aNameLength++; // Include a zero terminator
1092 // If aNameLength is a exact multiple of KMaxVFatEntryName, don't bother
1093 // with a zero terminator - it just adds an unnecessary directory entry
1095 numberOfEntries=(1+(aNameLength/KMaxVFatEntryName));
1097 if (aNameLength%KMaxVFatEntryName)
1100 return(numberOfEntries);
1104 Calculate a checksum to tie the vFat and dos names together
1106 TUint8 Fat_Test_Utils::CalculateShortNameCheckSum(const TDesC8& aShortName)
1110 for (TInt i=0;i<11;i++)
1111 cksum =(TUint8)((((cksum&1)<<7)|((cksum&0xfe)>>1))+aShortName[i]);
1117 //-------------------------------------------------------------------------------------------------------------------
1120 #define pDir ((SFatDirEntry*)&iData[0])
1121 const TUint8 KEntryErasedMarker=0xE5;
1124 TFatDirEntry::TFatDirEntry()
1129 /** zero-fill the entry contents */
1130 void TFatDirEntry::InitZ()
1132 Mem::FillZ(iData, KSizeOfFatDirEntry);
1137 @return ETrue if the Directory entry contains garbage data
1139 TBool TFatDirEntry::IsGarbage() const
1141 return (iData[0]==0xFF);
1145 Return the Dos name of a directory entry
1146 @return A descriptor containing the Dos name of a directory entry
1148 const TPtrC8 TFatDirEntry::Name() const
1149 {return TPtrC8((TUint8*)&(pDir->iName),KFatDirNameSize);}
1151 /** @return The attributes for the Directory entry */
1152 TInt TFatDirEntry::Attributes() const
1153 {return pDir->iAttributes;}
1155 /** @return Time of file creation */
1156 TTime TFatDirEntry::Time() const
1157 {return DosTimeToTTime(pDir->iTime,pDir->iDate);}
1159 /** @return The Start cluster for the file or directory for this entry */
1160 TInt TFatDirEntry::StartCluster() const
1162 const TUint16 KStClustMaskHi = 0x0FFF;
1163 return ((pDir->iStartClusterHi&KStClustMaskHi)<<16) | pDir->iStartClusterLo;
1166 /** @return The size of file or directory for this entry */
1167 TUint32 TFatDirEntry::Size() const
1168 {return pDir->iSize;}
1170 /** @return True if the entry is erased */
1171 TBool TFatDirEntry::IsErased() const
1172 {return (TBool)(iData[0]==KEntryErasedMarker);}
1174 /** @return True if the entry refers to the current directory */
1175 TBool TFatDirEntry::IsCurrentDirectory() const
1176 {return (TBool)(iData[0]==KDotEntryByte && iData[1]==KBlankSpace);}
1178 /** @return True if the Entry refers to the parent directory */
1179 TBool TFatDirEntry::IsParentDirectory() const
1180 {return (TBool)(iData[0]==KDotEntryByte && iData[1]==KDotEntryByte);}
1182 /** @return True if end of directory */
1183 TBool TFatDirEntry::IsEndOfDirectory() const
1184 {return (TBool)(iData[0]==0x00);}
1187 Set the Dos name of a directory entry
1188 @param aDes A descriptor containg the name
1190 void TFatDirEntry::SetName(const TDesC8& aDes)
1192 ASSERT(aDes.Length()<=KFatDirNameSize);
1193 TPtr8 name(pDir->iName,KFatDirNameSize);
1198 Set the file or directory attributes for this entry
1199 @param anAtts The file or directory attributes
1201 void TFatDirEntry::SetAttributes(TInt anAtts)
1203 ASSERT(!(anAtts&~KMaxTUint8));
1204 pDir->iAttributes=(TUint8)anAtts;
1208 Set the creation time and data of the directory entry
1209 @param aTime Creation time of the file or directory
1211 void TFatDirEntry::SetTime(TTime aTime)
1213 pDir->iTime=(TUint16)DosTimeFromTTime(aTime);
1214 pDir->iDate=(TUint16)DosDateFromTTime(aTime);
1217 void TFatDirEntry::SetCreateTime(TTime aTime)
1219 pDir->iTimeC=(TUint16)DosTimeFromTTime(aTime);
1220 pDir->iDateC=(TUint16)DosDateFromTTime(aTime);
1224 Set the start cluster number of the file or directory refered to by the entry
1225 @param aStartCluster The start cluster number
1227 void TFatDirEntry::SetStartCluster(TInt aStartCluster)
1229 const TUint32 KHalfWordMask = 0x0000FFFF;
1230 pDir->iStartClusterLo=(TUint16)(aStartCluster & KHalfWordMask);
1231 pDir->iStartClusterHi=(TUint16)((aStartCluster>>16) & KHalfWordMask);
1235 Set the size of the file or directory refered to by the entry
1236 @param aFileSize Size of the file
1238 void TFatDirEntry::SetSize(TUint32 aFileSize)
1239 {pDir->iSize=aFileSize;}
1241 /** Set the directory entry as erased */
1242 void TFatDirEntry::SetErased()
1243 {iData[0]=KEntryErasedMarker;}
1245 /** Set the current entry to refer to the current directory */
1246 void TFatDirEntry::SetCurrentDirectory()
1249 Mem::Fill(&iData[1],KFatDirNameSize-1,' ');
1252 /** Set the current entry to refer to the parent directory */
1253 void TFatDirEntry::SetParentDirectory()
1255 iData[0]='.';iData[1]='.';
1256 Mem::Fill(&iData[2],KFatDirNameSize-2,' ');
1259 /** Set the current entry to be the end of directory marker */
1260 void TFatDirEntry::SetEndOfDirectory()
1261 {Mem::FillZ(&iData[0],KFatDirNameSize);}
1263 /** @return True if the entry is the start of a long name set of entries */
1264 TBool TFatDirEntry::IsLongNameStart() const
1265 {return (TBool)((iData[0]&0x40) != 0);}
1267 /** @return True is the Entry is a VFat entry */
1268 TBool TFatDirEntry::IsVFatEntry() const
1269 {return (TBool)(Attributes()==KVFatEntryAttribute && IsEndOfDirectory()==EFalse);}
1271 /** @return The number of following VFat entries */
1272 TInt TFatDirEntry::NumFollowing() const
1273 {return (iData[0]&0x3F);}
1276 TUint8 TFatDirEntry::CheckSum() const
1278 ASSERT(IsVFatEntry());