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: // @file sl@0: // various FAT test utilities sl@0: // sl@0: // sl@0: sl@0: sl@0: #include "fat_utils.h" sl@0: using namespace Fat_Test_Utils; sl@0: sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: //-- define this macro if it is necessarily to exclude all stuff that uses RFs, consoles etc. sl@0: //-- may be useful if this code is used for file server extensions. mmp file is a good place to define this macro. sl@0: #ifndef FAT_UTILS_LEAN_AND_MEAN sl@0: sl@0: #include sl@0: #include sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Format FAT volume sl@0: sl@0: @param aFs reference to the FS session sl@0: @param aDrive drive number sl@0: @param aQuickFormat if True, a quick format will be performed. otherwise - full sl@0: @param apFmtParams pointer to the optional format parameters. if NULL, it means tha no options specified sl@0: @param aForceErase if True, use media force erase. sl@0: sl@0: @return system-wide error codes. sl@0: */ sl@0: TInt Fat_Test_Utils::FormatFatDrive(RFs &aFs, TInt aDrive, TBool aQuickFormat, const TFatFormatParam* apFmtParams/*=NULL*/, TBool aForceErase /*=EFalse*/) sl@0: { sl@0: TPtrC fmtTypeName = (aQuickFormat ? _L("Quick") : _L("Full")); sl@0: DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() drv:%d, type:%S\n"),aDrive, &fmtTypeName); sl@0: sl@0: ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ); sl@0: sl@0: RFormat format; sl@0: TUint fmtMode=0; sl@0: TInt fmtCnt=0; sl@0: TInt prevCnt; sl@0: TInt nRes; sl@0: sl@0: if(aQuickFormat) sl@0: fmtMode |= EQuickFormat; sl@0: sl@0: if(aForceErase) sl@0: fmtMode |= EForceErase; sl@0: sl@0: TBuf<10> drvName; sl@0: drvName.Format(_L("%C:"),'A'+aDrive); sl@0: sl@0: if(!apFmtParams) sl@0: {//-- no format parameters specified sl@0: //DoPrintf(_L("~ Format parameters - not specified\n")); sl@0: nRes = format.Open(aFs, drvName, fmtMode, fmtCnt); sl@0: if(nRes!=KErrNone) sl@0: goto Fail; sl@0: } sl@0: else sl@0: {//-- some extra parameters specified, use special format sl@0: fmtMode |= ESpecialFormat; sl@0: TLDFormatInfo formatInfo; sl@0: sl@0: TBuf<100> buf; sl@0: buf.Copy(_L("~ Format parameters: ")); sl@0: sl@0: if(apFmtParams->iFatType) sl@0: {//-- FAT type is specified sl@0: buf.AppendFormat(_L("FAT%d"), apFmtParams->iFatType); sl@0: formatInfo.iFATBits = (TLDFormatInfo::TFATBits)apFmtParams->iFatType; sl@0: } sl@0: sl@0: const TUint16 spc = (TUint16)apFmtParams->iSecPerCluster; sl@0: if(spc) sl@0: {//-- sectors per cluster value is specified sl@0: buf.AppendFormat(_L(", spc:%d"), spc); sl@0: formatInfo.iSectorsPerCluster = spc; sl@0: } sl@0: sl@0: const TUint16 rsvdSec = (TUint16)apFmtParams->iReservedSectors; sl@0: if(rsvdSec) sl@0: {//-- reserved sectors numer is specified sl@0: buf.AppendFormat(_L(", rsvdSec:%d"), rsvdSec); sl@0: formatInfo.iReservedSectors = rsvdSec; sl@0: } sl@0: sl@0: buf.Append(_L("\n")); sl@0: DoPrintf(buf); sl@0: sl@0: TSpecialFormatInfoBuf formatInfoBuf(formatInfo); sl@0: nRes = format.Open(aFs, drvName, fmtMode, fmtCnt, formatInfoBuf); sl@0: if(nRes!=KErrNone) sl@0: goto Fail; sl@0: sl@0: } sl@0: sl@0: //-- do format steps sl@0: prevCnt=fmtCnt; sl@0: while(fmtCnt) sl@0: { sl@0: nRes = format.Next(fmtCnt); sl@0: if(nRes!=KErrNone) sl@0: goto Fail; sl@0: sl@0: if(fmtCnt != prevCnt) sl@0: { sl@0: DoPrintf(_L(".")); sl@0: prevCnt = fmtCnt; sl@0: } sl@0: } sl@0: sl@0: //-- formatting has finished sl@0: DoPrintf(_L("\n")); sl@0: format.Close(); sl@0: return KErrNone; sl@0: sl@0: Fail: sl@0: format.Close(); sl@0: DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() failed! code:%d\n"), nRes); sl@0: sl@0: return nRes; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Read FAT FSInfo sector via RRawDisk interface. sl@0: @param aFs reference to the FS session sl@0: @param aDrive drive number sl@0: @param aMediaPos media position (0 for the main boot sector) sl@0: @param aFsInfo where to read data sl@0: sl@0: @return standard error codes sl@0: */ sl@0: TInt Fat_Test_Utils::ReadFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFSInfo& aFsInfo) sl@0: { sl@0: DoPrintf(_L("~ Fat_Test_Utils::ReadFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos); sl@0: sl@0: TInt nRes = KErrNone; sl@0: sl@0: TBuf8 fsInfoSecBuf(KSizeOfFSInfo); sl@0: TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, fsInfoSecBuf.Size(), fsInfoSecBuf)); sl@0: sl@0: if(nRes == KErrNone) sl@0: {//-- take FSInfo data from the buffer sl@0: aFsInfo.Internalize(fsInfoSecBuf); sl@0: } sl@0: sl@0: return nRes; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Write FAT FSInfo sector via RRawDisk interface. sl@0: @param aFs reference to the FS session sl@0: @param aDrive drive number sl@0: @param aMediaPos media position (0 for the main boot sector) sl@0: @param aFsInfo data to write sl@0: sl@0: @return standard error codes sl@0: */ sl@0: TInt Fat_Test_Utils::WriteFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFSInfo& aFsInfo) sl@0: { sl@0: DoPrintf(_L("~ Fat_Test_Utils::WriteFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos); sl@0: sl@0: TInt nRes = KErrNone; sl@0: TBuf8 fsInfoSecBuf; sl@0: sl@0: //-- put data to the sector buffer sl@0: aFsInfo.Externalize(fsInfoSecBuf); sl@0: sl@0: TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, fsInfoSecBuf)) sl@0: sl@0: return nRes; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Read FAT boot sector via RRawDisk interface. sl@0: @param aFs reference to the FS session sl@0: @param aDrive drive number sl@0: @param aMediaPos media position (0 for the main boot sector) sl@0: @param aBootSector where to read data sl@0: sl@0: @return standard error codes sl@0: */ sl@0: TInt Fat_Test_Utils::ReadBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFatBootSector& aBootSector) sl@0: { sl@0: DoPrintf(_L("~ Fat_Test_Utils::ReadBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos); sl@0: sl@0: TInt nRes = KErrNone; sl@0: TBuf8 bootSecBuf(KSizeOfFatBootSector); sl@0: sl@0: TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, bootSecBuf.Size(), bootSecBuf)); sl@0: sl@0: if(nRes==KErrNone) sl@0: {//-- initialise TFatBootSector object sl@0: aBootSector.Internalize(bootSecBuf); sl@0: } sl@0: sl@0: return nRes; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Write FAT boot sector via RRawDisk interface. sl@0: @param aFs reference to the FS session sl@0: @param aDrive drive number sl@0: @param aMediaPos media position (0 for the main boot sector) sl@0: @param aBootSector data to write sl@0: sl@0: @return standard error codes sl@0: */ sl@0: TInt Fat_Test_Utils::WriteBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFatBootSector& aBootSector) sl@0: { sl@0: DoPrintf(_L("~ Fat_Test_Utils::WriteBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos); sl@0: sl@0: TBuf8 bootSecBuf(KDefaultSectorSize); sl@0: sl@0: //-- externalize boot sector to the data buffer sl@0: bootSecBuf.FillZ(); sl@0: aBootSector.Externalize(bootSecBuf); sl@0: sl@0: //-- put a boot sector signature to the last 2 bytes sl@0: bootSecBuf[KDefaultSectorSize-2] = 0x55; sl@0: bootSecBuf[KDefaultSectorSize-1] = 0xaa; sl@0: sl@0: //-- write boot sector data to the media sl@0: TInt nRes=KErrNone; sl@0: TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, bootSecBuf)); sl@0: sl@0: return nRes; sl@0: } sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: /** sl@0: Obtain FAT type for the given drive sl@0: sl@0: @return TFatType enum values. if aDrive has not FAT FS, EInvalid value is returned sl@0: */ sl@0: TFatType Fat_Test_Utils::GetFatType(RFs &aFs, TInt aDrive) sl@0: { sl@0: if(Is_Fat16(aFs, aDrive)) sl@0: return EFat16; sl@0: else if(Is_Fat32(aFs, aDrive)) sl@0: return EFat32; sl@0: else if(Is_Fat12(aFs, aDrive)) sl@0: return EFat12; sl@0: sl@0: return EInvalid; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: #endif //FAT_UTILS_LEAN_AND_MEAN sl@0: sl@0: sl@0: sl@0: sl@0: TFatFormatParam::TFatFormatParam() sl@0: { sl@0: iFatType = EInvalid; sl@0: iSecPerCluster = 0; sl@0: iReservedSectors = 0; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: TFatBootSector::TFatBootSector() sl@0: { sl@0: Initialise(); sl@0: } sl@0: sl@0: /** initialises the boot sector data */ sl@0: void TFatBootSector::Initialise() sl@0: { sl@0: Mem::FillZ(this, sizeof(TFatBootSector)); sl@0: } sl@0: sl@0: TBool TFatBootSector::operator==(const TFatBootSector& aRhs) sl@0: { sl@0: ASSERT(&aRhs != this); sl@0: if(&aRhs == this) sl@0: return ETrue; //-- comparing with itself sl@0: sl@0: return (Mem::Compare((TUint8*)this, sizeof(TFatBootSector), (TUint8*)&aRhs, sizeof(TFatBootSector)) == 0); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @return ETrue if the boot sector contents seems to be valid sl@0: */ sl@0: TBool TFatBootSector::IsValid() const sl@0: { sl@0: const TFatType fatType = FatType(); //-- it will check SectorsPerCluster etc. sl@0: sl@0: if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1) sl@0: goto Invalid; sl@0: sl@0: if(fatType == EFat32) sl@0: { sl@0: if(VersionNumber()!= 0 || FatSectors()!=0 || FatSectors32()<1 || RootClusterNum()<(TUint32)KFatFirstSearchCluser || sl@0: TotalSectors()!=0 || HugeSectors() <5 || RootDirEntries() !=0) sl@0: { sl@0: goto Invalid; //-- these values are not compliant with FAT specs sl@0: } sl@0: } sl@0: else //-- FAT12/16 sl@0: { sl@0: if(TotalSectors() >0 && HugeSectors() >0 ) sl@0: goto Invalid; //-- values clash sl@0: sl@0: const TUint32 totSectors = Max(TotalSectors(), HugeSectors()); sl@0: const TUint32 rootDirStartSec = ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector sl@0: sl@0: if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5) sl@0: goto Invalid; //-- these values are not compliant with FAT specs sl@0: } sl@0: sl@0: return ETrue; sl@0: sl@0: Invalid: sl@0: DoPrintf(_L("~ TFatBootSector::IsValid() failed!\n")); sl@0: sl@0: return EFalse; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Initialize boot sector object from the given bufer. Does not validate the data. sl@0: @param aBuf buffer with data. sl@0: */ sl@0: void TFatBootSector::Internalize(const TDesC8& aBuf) sl@0: { sl@0: ASSERT(aBuf.Size() >= KSizeOfFatBootSector); sl@0: sl@0: Initialise(); sl@0: sl@0: TInt pos=0; sl@0: sl@0: Mem::Copy(&iJumpInstruction, &aBuf[pos],3); pos+=3; // 0 TUint8 iJumpInstruction[3] sl@0: Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3 TUint8 iVendorId[KVendorIdSize] sl@0: Mem::Copy(&iBytesPerSector,&aBuf[pos],2); pos+=2; // 11 TUint16 iBytesPerSector sl@0: Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1); pos+=1; // 13 TUint8 iSectorsPerCluster sl@0: Mem::Copy(&iReservedSectors,&aBuf[pos],2); pos+=2; // 14 TUint16 iReservedSectors sl@0: Mem::Copy(&iNumberOfFats,&aBuf[pos],1); pos+=1; // 16 TUint8 iNumberOfFats sl@0: Mem::Copy(&iRootDirEntries,&aBuf[pos],2); pos+=2; // 17 TUint16 iRootDirEntries sl@0: Mem::Copy(&iTotalSectors,&aBuf[pos],2); pos+=2; // 19 TUint16 iTotalSectors sl@0: Mem::Copy(&iMediaDescriptor,&aBuf[pos],1); pos+=1; // 21 TUint8 iMediaDescriptor sl@0: Mem::Copy(&iFatSectors,&aBuf[pos],2); pos+=2; // 22 TUint16 iFatSectors sl@0: Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2); pos+=2; // 24 TUint16 iSectorsPerTrack sl@0: Mem::Copy(&iNumberOfHeads,&aBuf[pos],2); pos+=2; // 26 TUint16 iNumberOfHeads sl@0: Mem::Copy(&iHiddenSectors,&aBuf[pos],4); pos+=4; // 28 TUint32 iHiddenSectors sl@0: Mem::Copy(&iHugeSectors,&aBuf[pos],4); pos+=4; // 32 TUint32 iHugeSectors sl@0: sl@0: if(RootDirEntries() == 0) //-- we have FAT32 volume sl@0: { sl@0: Mem::Copy(&iFatSectors32, &aBuf[pos],4); pos+=4; // 36 TUint32 iFatSectors32 sl@0: Mem::Copy(&iFATFlags, &aBuf[pos],2); pos+=2; // 40 TUint16 iFATFlags sl@0: Mem::Copy(&iVersionNumber, &aBuf[pos],2); pos+=2; // 42 TUint16 iVersionNumber sl@0: Mem::Copy(&iRootClusterNum, &aBuf[pos],4); pos+=4; // 44 TUint32 iRootClusterNum sl@0: Mem::Copy(&iFSInfoSectorNum, &aBuf[pos],2); pos+=2; // 48 TUint16 iFSInfoSectorNum sl@0: Mem::Copy(&iBkBootRecSector, &aBuf[pos],2); // 50 TUint16 iBkBootRecSector sl@0: pos+=(2+12); //extra 12 for the reserved bytes sl@0: } sl@0: sl@0: Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1); pos+=1;// 36|64 TUint8 iPhysicalDriveNumber sl@0: Mem::Copy(&iReserved,&aBuf[pos],1); pos+=1;// 37|65 TUint8 iReserved sl@0: Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature sl@0: Mem::Copy(&iUniqueID,&aBuf[pos],4); pos+=4;// 39|67 TUint32 iUniqueID sl@0: Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize); // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize] sl@0: pos+=KVolumeLabelSize; sl@0: sl@0: // 54|82 TUint8 iFileSysType[KFileSysTypeSize] sl@0: ASSERT(aBuf.Size() >= pos+KFileSysTypeSize); sl@0: Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Externalize boot sector object to the given data buffer. sl@0: @param aBuf buffer to externalize. sl@0: */ sl@0: void TFatBootSector::Externalize(TDes8& aBuf) const sl@0: { sl@0: ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector); sl@0: sl@0: if(aBuf.Size() < KSizeOfFatBootSector) sl@0: aBuf.SetLength(KSizeOfFatBootSector); sl@0: sl@0: TInt pos=0; sl@0: sl@0: Mem::Copy(&aBuf[pos],&iJumpInstruction,3); pos+=3; sl@0: Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8; sl@0: Mem::Copy(&aBuf[pos],&iBytesPerSector,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1); pos+=1; sl@0: Mem::Copy(&aBuf[pos],&iReservedSectors,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iNumberOfFats,1); pos+=1; sl@0: Mem::Copy(&aBuf[pos],&iRootDirEntries,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iTotalSectors,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iMediaDescriptor,1); pos+=1; sl@0: Mem::Copy(&aBuf[pos],&iFatSectors,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iNumberOfHeads,2); pos+=2; sl@0: Mem::Copy(&aBuf[pos],&iHiddenSectors,4); pos+=4; sl@0: Mem::Copy(&aBuf[pos],&iHugeSectors,4); pos+=4; sl@0: sl@0: if(iFatSectors == 0) sl@0: { sl@0: Mem::Copy(&aBuf[pos], &iFatSectors32,4); pos+=4; sl@0: Mem::Copy(&aBuf[pos], &iFATFlags, 2); pos+=2; sl@0: Mem::Copy(&aBuf[pos], &iVersionNumber, 2); pos+=2; sl@0: Mem::Copy(&aBuf[pos], &iRootClusterNum, 4); pos+=4; sl@0: Mem::Copy(&aBuf[pos], &iFSInfoSectorNum, 2);pos+=2; sl@0: Mem::Copy(&aBuf[pos], &iBkBootRecSector, 2);pos+=2; sl@0: sl@0: //extra 12 for the reserved bytes sl@0: ASSERT(aBuf.Size() >= pos+12); sl@0: Mem::FillZ(&aBuf[pos],12); sl@0: pos+=12; sl@0: } sl@0: sl@0: Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1); pos+=1; sl@0: Mem::FillZ(&aBuf[pos],1); pos+=1; sl@0: Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1; sl@0: Mem::Copy(&aBuf[pos],&iUniqueID,4); pos+=4; sl@0: sl@0: Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize); sl@0: pos+=KVolumeLabelSize; sl@0: sl@0: ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize); sl@0: Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** replaces all non-printable characters in a buffer with spaces */ sl@0: static void FixDes(TDes& aDes) sl@0: { sl@0: for(TInt i=0; i< aDes.Length(); ++i) sl@0: { sl@0: TChar ch=aDes[i]; sl@0: if(!ch.IsPrint()) sl@0: aDes[i]=' '; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Print out the boot sector info. sl@0: */ sl@0: void TFatBootSector::PrintDebugInfo() const sl@0: { sl@0: TBuf<40> buf; sl@0: sl@0: DoPrintf(_L("======== BootSector info: =======\n")); sl@0: sl@0: buf.Copy(FileSysType()); FixDes(buf); sl@0: DoPrintf(_L("FAT type:%S\n"),&buf); sl@0: sl@0: buf.Copy(VendorId()); FixDes(buf); sl@0: DoPrintf(_L("Vendor ID:%S\n"),&buf); sl@0: sl@0: DoPrintf(_L("BytesPerSector: %d\n"),BytesPerSector()); sl@0: DoPrintf(_L("SectorsPerCluster: %d\n"),SectorsPerCluster()); sl@0: DoPrintf(_L("ReservedSectors: %d\n"),ReservedSectors()); sl@0: DoPrintf(_L("NumberOfFats: %d\n"),NumberOfFats()); sl@0: DoPrintf(_L("RootDirEntries: %d\n"),RootDirEntries()); sl@0: DoPrintf(_L("Total Sectors: %d\n"),TotalSectors()); sl@0: DoPrintf(_L("MediaDescriptor: 0x%x\n"),MediaDescriptor()); sl@0: DoPrintf(_L("FatSectors: %d\n"),FatSectors()); sl@0: DoPrintf(_L("SectorsPerTrack: %d\n"),SectorsPerTrack()); sl@0: DoPrintf(_L("NumberOfHeads: %d\n"),NumberOfHeads()); sl@0: DoPrintf(_L("HugeSectors: %d\n"),HugeSectors()); sl@0: DoPrintf(_L("Fat32 Sectors: %d\n"),FatSectors32()); sl@0: DoPrintf(_L("Fat32 Flags: %d\n"),FATFlags()); sl@0: DoPrintf(_L("Fat32 Version Number: %d\n"),VersionNumber()); sl@0: DoPrintf(_L("Root Cluster Number: %d\n"),RootClusterNum()); sl@0: DoPrintf(_L("FSInfo Sector Number: %d\n"),FSInfoSectorNum()); sl@0: DoPrintf(_L("Backup Boot Rec Sector Number: %d\n"),BkBootRecSector()); sl@0: DoPrintf(_L("PhysicalDriveNumber:%d\n"),PhysicalDriveNumber()); sl@0: DoPrintf(_L("ExtendedBootSignature: %d\n"),ExtendedBootSignature()); sl@0: DoPrintf(_L("UniqueID: 0x%x\n"),UniqueID()); sl@0: sl@0: buf.Copy(VolumeLabel()); FixDes(buf); sl@0: DoPrintf(_L("VolumeLabel:%S\n"),&buf); sl@0: sl@0: DoPrintf(_L("=============================\n")); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: sl@0: /** sl@0: Determine FAT type according to the information from boot sector, see FAT32 specs. sl@0: @return FAT type. sl@0: */ sl@0: TFatType TFatBootSector::FatType(void) const sl@0: { sl@0: sl@0: //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096 sl@0: if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 || iBytesPerSector > 4096) sl@0: return EInvalid; //-- invalid iBytesPerSector value sl@0: sl@0: //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128 sl@0: if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128) sl@0: return EInvalid; //-- invalid iSectorsPerCluster value sl@0: sl@0: const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector; sl@0: const TUint32 fatSz = iFatSectors ? iFatSectors : iFatSectors32; sl@0: const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors; sl@0: const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * fatSz) + rootDirSectors); sl@0: const TUint32 clusterCnt = dataSec / iSectorsPerCluster; sl@0: sl@0: //-- magic. see FAT specs for details. sl@0: if(clusterCnt < 4085) sl@0: return EFat12; sl@0: else if(clusterCnt < 65525) sl@0: return EFat16; sl@0: else sl@0: return EFat32; sl@0: sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** Returns Sectors in Fat table for 32 bit volume */ sl@0: TUint32 TFatBootSector::FatSectors32() const sl@0: {return iFatSectors32;} sl@0: sl@0: /** Fat flags */ sl@0: TUint16 TFatBootSector::FATFlags() const sl@0: {return iFATFlags;} sl@0: sl@0: /** Version number of the file system */ sl@0: TUint16 TFatBootSector::VersionNumber() const sl@0: {return iVersionNumber;} sl@0: sl@0: /** Cluster number of the root directory */ sl@0: TUint32 TFatBootSector::RootClusterNum() const sl@0: {return iRootClusterNum;} sl@0: sl@0: /** Sector number containing the FSIInfo structure */ sl@0: TUint16 TFatBootSector::FSInfoSectorNum() const sl@0: {return iFSInfoSectorNum;} sl@0: sl@0: /** Backup boot sector */ sl@0: TUint16 TFatBootSector::BkBootRecSector() const sl@0: {return iBkBootRecSector;} sl@0: sl@0: /** Sets the number of sectors in Fat table for 32 bit volume */ sl@0: void TFatBootSector::SetFatSectors32(TUint32 aFatSectors32) sl@0: {iFatSectors32 = aFatSectors32;} sl@0: sl@0: /** Sets the Fat flags */ sl@0: void TFatBootSector::SetFATFlags(TUint16 aFATFlags) sl@0: {iFATFlags = aFATFlags;} sl@0: sl@0: /** Sets the version number of the file system */ sl@0: void TFatBootSector::SetVersionNumber(TUint16 aVersionNumber) sl@0: {iVersionNumber = aVersionNumber;} sl@0: sl@0: /** Sets the cluster number of the root directory */ sl@0: void TFatBootSector::SetRootClusterNum(TUint32 aRootClusterNum) sl@0: {iRootClusterNum = aRootClusterNum;} sl@0: sl@0: /** Set the sector number containing the FSIInfo structure */ sl@0: void TFatBootSector::SetFSInfoSectorNum(TUint16 aFSInfoSectorNum) sl@0: {iFSInfoSectorNum = aFSInfoSectorNum;} sl@0: sl@0: /** Set the backup boot sector */ sl@0: void TFatBootSector::SetBkBootRecSector(TUint16 aBkBootRecSector) sl@0: {iBkBootRecSector = aBkBootRecSector;} sl@0: sl@0: /** Returns the vendor ID of the file system that formatted the volume */ sl@0: const TPtrC8 TFatBootSector::VendorId() const sl@0: {return TPtrC8(iVendorId,KVendorIdSize);} sl@0: sl@0: /** Return the bytes per sector */ sl@0: TUint16 TFatBootSector::BytesPerSector() const sl@0: {return iBytesPerSector;} sl@0: sl@0: /** Returns the sectors per cluster ratio */ sl@0: TInt TFatBootSector::SectorsPerCluster() const sl@0: {return iSectorsPerCluster;} sl@0: sl@0: /** Returns the number of reserved sectors on the volume */ sl@0: TInt TFatBootSector::ReservedSectors() const sl@0: {return iReservedSectors;} sl@0: sl@0: /** Returns the number of Fats on the volume */ sl@0: TInt TFatBootSector::NumberOfFats() const sl@0: {return iNumberOfFats;} sl@0: sl@0: /** Returns the number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32 */ sl@0: TInt TFatBootSector::RootDirEntries() const sl@0: {return iRootDirEntries;} sl@0: sl@0: /** Returns the total sectors on the volume, zero for FAT32 */ sl@0: TInt TFatBootSector::TotalSectors() const sl@0: {return iTotalSectors;} sl@0: sl@0: /** Returns the media descriptor */ sl@0: TUint8 TFatBootSector::MediaDescriptor() const sl@0: {return iMediaDescriptor;} sl@0: sl@0: /** Returns sectors used for the Fat table, zero for FAT32 */ sl@0: TInt TFatBootSector::FatSectors() const sl@0: {return iFatSectors;} sl@0: sl@0: /** Returns sectors per track */ sl@0: TInt TFatBootSector::SectorsPerTrack() const sl@0: {return iSectorsPerTrack;} sl@0: sl@0: /** Returns the number of heads */ sl@0: TInt TFatBootSector::NumberOfHeads() const sl@0: {return iNumberOfHeads;} sl@0: sl@0: /** Returns the number of hidden sectors in the volume */ sl@0: TInt TFatBootSector::HiddenSectors() const sl@0: {return iHiddenSectors;} sl@0: sl@0: /** Returns total sectors in the volume, Used if totalSectors > 65535 */ sl@0: TInt TFatBootSector::HugeSectors() const sl@0: {return iHugeSectors;} sl@0: sl@0: /** Returns the physical drive number, not used in Symbian OS */ sl@0: TInt TFatBootSector::PhysicalDriveNumber() const sl@0: {return iPhysicalDriveNumber;} sl@0: sl@0: /** Returns the extended boot signiture */ sl@0: TInt TFatBootSector::ExtendedBootSignature() const sl@0: {return iExtendedBootSignature;} sl@0: sl@0: /** Returns the unique volume ID */ sl@0: TUint32 TFatBootSector::UniqueID() const sl@0: {return iUniqueID;} sl@0: sl@0: /** Returns the volume's label */ sl@0: const TPtrC8 TFatBootSector::VolumeLabel() const sl@0: {return TPtrC8(iVolumeLabel,KVolumeLabelSize);} sl@0: sl@0: /** Returns the file system type */ sl@0: const TPtrC8 TFatBootSector::FileSysType() const sl@0: {return TPtrC8(iFileSysType,KFileSysTypeSize);} sl@0: sl@0: /** Returns the boot sector signiture */ sl@0: TInt TFatBootSector::BootSectorSignature() const sl@0: {return KBootSectorSignature;} sl@0: sl@0: /** Set the jump instruction */ sl@0: void TFatBootSector::SetJumpInstruction() sl@0: {iJumpInstruction[0]=0xE9;iJumpInstruction[2]=0x90;} sl@0: sl@0: /** Set the vendor ID of the file system that formatted the volume */ sl@0: void TFatBootSector::SetVendorID(const TDesC8& aDes) sl@0: { sl@0: ASSERT(aDes.Length()<=KVendorIdSize); sl@0: TPtr8 buf(iVendorId,KVendorIdSize); sl@0: buf=aDes; sl@0: } sl@0: sl@0: /** Sets the bytes per sector */ sl@0: void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector) sl@0: { sl@0: ASSERT(!(aBytesPerSector&~KMaxTUint16)); sl@0: iBytesPerSector=(TUint16)aBytesPerSector; sl@0: } sl@0: sl@0: /** Set the sectors per cluster ratio */ sl@0: void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster) sl@0: { sl@0: ASSERT(!(aSectorsPerCluster&~KMaxTUint8)); sl@0: iSectorsPerCluster=(TUint8)aSectorsPerCluster; sl@0: } sl@0: sl@0: sl@0: /** Sets the number of reserved sectors on the volume */ sl@0: void TFatBootSector::SetReservedSectors(TInt aReservedSectors) sl@0: { sl@0: ASSERT(!(aReservedSectors&~KMaxTUint16)); sl@0: iReservedSectors=(TUint16)aReservedSectors; sl@0: } sl@0: sl@0: /** Sets the number of Fats on the volume */ sl@0: void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats) sl@0: { sl@0: ASSERT(!(aNumberOfFats&~KMaxTUint8)); sl@0: iNumberOfFats=(TUint8)aNumberOfFats; sl@0: } sl@0: sl@0: /** Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32 */ sl@0: void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries) sl@0: { sl@0: ASSERT(!(aRootDirEntries&~KMaxTUint16)); sl@0: iRootDirEntries=(TUint16)aRootDirEntries; sl@0: } sl@0: sl@0: /** Total sectors on the volume, zero for FAT32 */ sl@0: void TFatBootSector::SetTotalSectors(TInt aTotalSectors) sl@0: { sl@0: ASSERT(!(aTotalSectors&~KMaxTUint16)); sl@0: iTotalSectors=(TUint16)aTotalSectors; sl@0: } sl@0: sl@0: /** Set the media descriptor */ sl@0: void TFatBootSector::SetMediaDescriptor(TUint8 aMediaDescriptor) sl@0: {iMediaDescriptor=aMediaDescriptor;} sl@0: sl@0: /** Sectors used for the Fat table, zero for FAT32 */ sl@0: void TFatBootSector::SetFatSectors(TInt aFatSectors) sl@0: { sl@0: ASSERT(!(aFatSectors&~KMaxTUint16)); sl@0: iFatSectors=(TUint16)aFatSectors; sl@0: } sl@0: sl@0: /** Set the sectors per track */ sl@0: void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack) sl@0: { sl@0: ASSERT(!(aSectorsPerTrack&~KMaxTUint16)); sl@0: iSectorsPerTrack=(TUint16)aSectorsPerTrack; sl@0: } sl@0: sl@0: /** Set the number of heads */ sl@0: void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads) sl@0: { sl@0: ASSERT(!(aNumberOfHeads&~KMaxTUint16)); sl@0: iNumberOfHeads=(TUint16)aNumberOfHeads; sl@0: } sl@0: sl@0: /** Set the number of hidden sectors in the volume */ sl@0: void TFatBootSector::SetHiddenSectors(TUint32 aHiddenSectors) sl@0: { sl@0: iHiddenSectors=(TUint32)(aHiddenSectors); sl@0: } sl@0: sl@0: /** Set the total sectors in the volume, Used if totalSectors > 65535 */ sl@0: void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors) sl@0: {iHugeSectors=aHugeSectors;} sl@0: sl@0: sl@0: /** Physical drive number, not used in Symbian OS */ sl@0: void TFatBootSector::SetPhysicalDriveNumber(TInt aPhysicalDriveNumber) sl@0: { sl@0: ASSERT(!(aPhysicalDriveNumber&~KMaxTUint8)); sl@0: iPhysicalDriveNumber=(TUint8)aPhysicalDriveNumber; sl@0: } sl@0: sl@0: /** Set the reserved byte value */ sl@0: void TFatBootSector::SetReservedByte(TUint8 aReservedByte) sl@0: {iReserved=aReservedByte;} sl@0: sl@0: /** Set the extended boot signiture */ sl@0: void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature) sl@0: { sl@0: ASSERT(!(anExtendedBootSignature&~KMaxTUint8)); sl@0: iExtendedBootSignature=(TUint8)anExtendedBootSignature; sl@0: } sl@0: sl@0: /** Set the unique volume ID */ sl@0: void TFatBootSector::SetUniqueID(TUint32 anUniqueID) sl@0: {iUniqueID=anUniqueID;} sl@0: sl@0: /** Set the volume's label */ sl@0: void TFatBootSector::SetVolumeLabel(const TDesC8& aDes) sl@0: { sl@0: ASSERT(aDes.Length()<=KVolumeLabelSize); sl@0: TPtr8 buf(iVolumeLabel,KVolumeLabelSize); sl@0: buf=aDes; sl@0: } sl@0: sl@0: /** Set the file system type */ sl@0: void TFatBootSector::SetFileSysType(const TDesC8& aDes) sl@0: { sl@0: ASSERT(aDes.Length()<=8); sl@0: TPtr8 buf(iFileSysType,8); sl@0: buf=aDes; sl@0: } sl@0: sl@0: sl@0: /** @return The first Fat sector number */ sl@0: TInt TFatBootSector::FirstFatSector() const sl@0: { sl@0: __ASSERT_ALWAYS(IsValid(), User::Invariant()); sl@0: return ReservedSectors(); sl@0: } sl@0: sl@0: /** sl@0: @return Number of sectors in root directory. 0 for FAT32 sl@0: */ sl@0: TUint32 TFatBootSector::RootDirSectors() const sl@0: { sl@0: __ASSERT_ALWAYS(IsValid(), User::Invariant()); sl@0: return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() ); sl@0: } sl@0: sl@0: sl@0: /** @return Start sector number of the root directory */ sl@0: TInt TFatBootSector::RootDirStartSector() const sl@0: { sl@0: __ASSERT_ALWAYS(IsValid(), User::Invariant()); sl@0: sl@0: const TUint32 firstNonFatSec = ReservedSectors() + TotalFatSectors()*NumberOfFats(); sl@0: sl@0: if(FatType() == EFat32) sl@0: {//-- FAT32 root dir is a file, calculate the position by it's 1st cluster number. FAT[0]+FAT[1] are reserved. sl@0: return (firstNonFatSec + (RootClusterNum()-KFatFirstSearchCluser) * SectorsPerCluster()); sl@0: } sl@0: else sl@0: {//-- FAT12/16 root dir starts just after the FATs sl@0: return firstNonFatSec; sl@0: } sl@0: sl@0: } sl@0: sl@0: /** @return first data sector number. for FAT32 it includes the root directory */ sl@0: TInt TFatBootSector::FirstDataSector() const sl@0: { sl@0: return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() ); sl@0: } sl@0: sl@0: /** @return FAT-type independent sector count on the volume */ sl@0: TUint32 TFatBootSector::VolumeTotalSectorNumber() const sl@0: { sl@0: __ASSERT_ALWAYS(IsValid(), User::Invariant()); sl@0: return HugeSectors() ? (TUint32)HugeSectors() : (TUint32)TotalSectors(); sl@0: } sl@0: sl@0: /** @return FAT-type independent number of sectors in one FAT */ sl@0: TUint32 TFatBootSector::TotalFatSectors() const sl@0: { sl@0: __ASSERT_ALWAYS(IsValid(), User::Invariant()); sl@0: return FatSectors32() ? FatSectors32() : (TUint32)FatSectors(); sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: sl@0: const TUint32 KLeadSignature = 0x41615252; ///< FSInfo Lead signiture value sl@0: const TUint32 KStructureSignature = 0x61417272; ///< FSInfo Structure signiture value sl@0: const TUint32 KTrailingSignature = 0xAA550000; ///< FSInfo Trailing signiture sl@0: sl@0: TFSInfo::TFSInfo() sl@0: { sl@0: Initialise(); sl@0: } sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** Initialise the data */ sl@0: void TFSInfo::Initialise() sl@0: { sl@0: Mem::FillZ(this, sizeof(TFSInfo)); sl@0: sl@0: iLeadSig = KLeadSignature; sl@0: iStructureSig = KStructureSignature; sl@0: iTrainlingSig = KTrailingSignature; sl@0: } sl@0: sl@0: sl@0: TBool TFSInfo::operator==(const TFSInfo& aRhs) sl@0: { sl@0: ASSERT(&aRhs != this); sl@0: if(&aRhs == this) sl@0: return ETrue; //-- comparing with itself sl@0: sl@0: return (Mem::Compare((TUint8*)this, sizeof(TFSInfo), (TUint8*)&aRhs, sizeof(TFSInfo)) == 0); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: @return ETrue if FSInfo sector contents seems to be valid sl@0: */ sl@0: TBool TFSInfo::IsValid() const sl@0: { sl@0: return (iLeadSig == KLeadSignature && iStructureSig == KStructureSignature && iTrainlingSig == KTrailingSignature); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Initialize FSInfo sector object from the given bufer. Does not validate the data. sl@0: @param aBuf buffer with data. sl@0: */ sl@0: void TFSInfo::Internalize(const TDesC8& aBuf) sl@0: { sl@0: ASSERT((TUint32)aBuf.Size() >= KSizeOfFSInfo); sl@0: sl@0: TInt pos=0; sl@0: sl@0: Mem::Copy(&iLeadSig, &aBuf[pos],4); pos+=(KFSInfoReserved1Size+4); sl@0: Mem::Copy(&iStructureSig, &aBuf[pos],4); pos+=4; sl@0: Mem::Copy(&iFreeCount,&aBuf[pos],4); pos+=4; sl@0: Mem::Copy(&iNextFree,&aBuf[pos],4); pos+=(4+KFSInfoReserved2Size); sl@0: Mem::Copy(&iTrainlingSig,&aBuf[pos],4); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Externalize FSInfo sector object to the given data buffer. sl@0: @param aBuf buffer to externalize. sl@0: */ sl@0: void TFSInfo::Externalize(TDes8& aBuf) const sl@0: { sl@0: ASSERT((TUint32)aBuf.MaxSize() >= KSizeOfFSInfo); sl@0: sl@0: aBuf.SetLength(KSizeOfFSInfo); sl@0: aBuf.FillZ(); sl@0: sl@0: TInt pos=0; sl@0: sl@0: Mem::Copy(&aBuf[pos],&KLeadSignature,4); pos+=4; sl@0: pos+=KFSInfoReserved1Size; sl@0: Mem::Copy(&aBuf[pos],&KStructureSignature,4); pos+=4; sl@0: Mem::Copy(&aBuf[pos],&iFreeCount,4); pos+=4; sl@0: Mem::Copy(&aBuf[pos],&iNextFree,4); pos+=4; sl@0: pos+=KFSInfoReserved2Size; sl@0: Mem::Copy(&aBuf[pos],&KTrailingSignature,4); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Print out the FSInfo sector info. sl@0: */ sl@0: void TFSInfo::PrintDebugInfo() const sl@0: { sl@0: DoPrintf(_L("==== FSInfoSector : ====\n")); sl@0: DoPrintf(_L("FSI_LeadSig: 0x%x\n"),iLeadSig); sl@0: DoPrintf(_L("FSI_StrucSig: 0x%x\n"),iStructureSig); sl@0: DoPrintf(_L("FSI_FreeCount: 0x%x\n"),iFreeCount); sl@0: DoPrintf(_L("FSI_NxtFree: 0x%x\n"),iNextFree); sl@0: DoPrintf(_L("FSI_TrailSig: 0x%x\n"),iTrainlingSig); sl@0: DoPrintf(_L("========================\n")); sl@0: } sl@0: sl@0: TUint32 TFSInfo::FreeClusterCount() const sl@0: { sl@0: return iFreeCount; sl@0: } sl@0: sl@0: TUint32 TFSInfo::NextFreeCluster() const sl@0: { sl@0: return iNextFree; sl@0: } sl@0: sl@0: sl@0: void TFSInfo::SetFreeClusterCount(TUint32 aFreeCount) sl@0: { sl@0: iFreeCount = aFreeCount; sl@0: } sl@0: sl@0: void TFSInfo::SetNextFreeCluster(TUint32 aNextCluster) sl@0: { sl@0: iNextFree = aNextCluster; sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Deciphers the dos time/date entry information and converts to TTime sl@0: */ sl@0: TTime Fat_Test_Utils::DosTimeToTTime(TInt aDosTime,TInt aDosDate) sl@0: { sl@0: TInt secMask=0x1F; sl@0: TInt minMask=0x07E0; sl@0: TInt hrMask=0xF800; sl@0: TInt dayMask=0x1F; sl@0: TInt monthMask=0x01E0; sl@0: TInt yearMask=0xFE00; sl@0: sl@0: TInt secs=(aDosTime&secMask)*2; sl@0: TInt mins=(aDosTime&minMask)>>5; sl@0: TInt hrs=(aDosTime&hrMask)>>11; sl@0: TInt days=(aDosDate&dayMask)-1; sl@0: TMonth months=(TMonth)(((aDosDate&monthMask)>>5)-1); sl@0: TInt years=((aDosDate&yearMask)>>9)+1980; sl@0: sl@0: TDateTime datetime; sl@0: TInt ret=datetime.Set(years,months,days,hrs,mins,secs,0); sl@0: if (ret==KErrNone) sl@0: return(TTime(datetime)); sl@0: return(TTime(0)); sl@0: } sl@0: sl@0: /** sl@0: Converts a TTime to a dos time sl@0: */ sl@0: TInt Fat_Test_Utils::DosTimeFromTTime(const TTime& aTime) sl@0: { sl@0: TDateTime dateTime=aTime.DateTime(); sl@0: TInt dosSecs=dateTime.Second()/2; sl@0: TInt dosMins=dateTime.Minute()<<5; sl@0: TInt dosHrs=dateTime.Hour()<<11; sl@0: return dosSecs|dosMins|dosHrs; sl@0: } sl@0: sl@0: /** sl@0: Converts a TTime to a dos date sl@0: */ sl@0: TInt Fat_Test_Utils::DosDateFromTTime(const TTime& aTime) sl@0: { sl@0: sl@0: TDateTime dateTime=aTime.DateTime(); sl@0: TInt dosDays=dateTime.Day()+1; sl@0: TInt dosMonths=(dateTime.Month()+1)<<5; sl@0: TInt dosYears=(dateTime.Year()-1980)<<9; sl@0: return dosDays|dosMonths|dosYears; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Converts xxx.yyy to standard format aaaaaaaayyy sl@0: */ sl@0: TBuf8<12> Fat_Test_Utils::DosNameToStdFormat(const TDesC8& aDosName) sl@0: { sl@0: ASSERT(aDosName.Length()>=0 && aDosName.Length()<=KMaxFatFileName); sl@0: sl@0: TBuf8<12> result; sl@0: Mem::Fill((TUint8*)result.Ptr(),result.MaxSize(),' '); sl@0: TInt dotPos=aDosName.Locate('.'); sl@0: if (dotPos==KErrNotFound) sl@0: { sl@0: result=aDosName; sl@0: result.SetLength(11); sl@0: return result; sl@0: } sl@0: result=aDosName.Left(dotPos); sl@0: result.SetLength(11); sl@0: TPtr8 ext(&result[8],3); sl@0: ext=aDosName.Right(aDosName.Length()-dotPos-1); sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: Converts aaaaaaaayyy to dos name format xxx.yyy sl@0: */ sl@0: TBuf8<12> Fat_Test_Utils::DosNameFromStdFormat(const TDesC8& aStdFormatName) sl@0: { sl@0: ASSERT(aStdFormatName.Length()==11); sl@0: sl@0: TBuf8<12> result; sl@0: TInt nameLen=aStdFormatName.Locate(' '); sl@0: if (nameLen>8 || nameLen==KErrNotFound) sl@0: nameLen=8; sl@0: result=aStdFormatName.Left(nameLen); sl@0: TPtrC8 ext(&aStdFormatName[8],3); sl@0: TInt extLen=ext.Locate(' '); sl@0: if (extLen) sl@0: result.Append(TChar('.')); sl@0: if (extLen==KErrNotFound) sl@0: extLen=3; sl@0: result.Append(ext.Left(extLen)); sl@0: if(result.Length() && result[0]==0x05 ) sl@0: { sl@0: result[0]=0xE5; sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: /** sl@0: Return the number of VFat entries required to describe a filename of length aNameLength sl@0: */ sl@0: TInt Fat_Test_Utils::NumberOfVFatEntries(TInt aNameLength) sl@0: { sl@0: TInt numberOfEntries=0; sl@0: if (aNameLength%KMaxVFatEntryName) sl@0: aNameLength++; // Include a zero terminator sl@0: // If aNameLength is a exact multiple of KMaxVFatEntryName, don't bother sl@0: // with a zero terminator - it just adds an unnecessary directory entry sl@0: sl@0: numberOfEntries=(1+(aNameLength/KMaxVFatEntryName)); sl@0: sl@0: if (aNameLength%KMaxVFatEntryName) sl@0: numberOfEntries++; sl@0: sl@0: return(numberOfEntries); sl@0: } sl@0: sl@0: /** sl@0: Calculate a checksum to tie the vFat and dos names together sl@0: */ sl@0: TUint8 Fat_Test_Utils::CalculateShortNameCheckSum(const TDesC8& aShortName) sl@0: { sl@0: sl@0: TUint8 cksum=0; sl@0: for (TInt i=0;i<11;i++) sl@0: cksum =(TUint8)((((cksum&1)<<7)|((cksum&0xfe)>>1))+aShortName[i]); sl@0: sl@0: return(cksum); sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: sl@0: #define pDir ((SFatDirEntry*)&iData[0]) sl@0: const TUint8 KEntryErasedMarker=0xE5; sl@0: sl@0: sl@0: TFatDirEntry::TFatDirEntry() sl@0: { sl@0: InitZ(); sl@0: } sl@0: sl@0: /** zero-fill the entry contents */ sl@0: void TFatDirEntry::InitZ() sl@0: { sl@0: Mem::FillZ(iData, KSizeOfFatDirEntry); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @return ETrue if the Directory entry contains garbage data sl@0: */ sl@0: TBool TFatDirEntry::IsGarbage() const sl@0: { sl@0: return (iData[0]==0xFF); sl@0: } sl@0: sl@0: /** sl@0: Return the Dos name of a directory entry sl@0: @return A descriptor containing the Dos name of a directory entry sl@0: */ sl@0: const TPtrC8 TFatDirEntry::Name() const sl@0: {return TPtrC8((TUint8*)&(pDir->iName),KFatDirNameSize);} sl@0: sl@0: /** @return The attributes for the Directory entry */ sl@0: TInt TFatDirEntry::Attributes() const sl@0: {return pDir->iAttributes;} sl@0: sl@0: /** @return Time of file creation */ sl@0: TTime TFatDirEntry::Time() const sl@0: {return DosTimeToTTime(pDir->iTime,pDir->iDate);} sl@0: sl@0: /** @return The Start cluster for the file or directory for this entry */ sl@0: TInt TFatDirEntry::StartCluster() const sl@0: { sl@0: const TUint16 KStClustMaskHi = 0x0FFF; sl@0: return ((pDir->iStartClusterHi&KStClustMaskHi)<<16) | pDir->iStartClusterLo; sl@0: } sl@0: sl@0: /** @return The size of file or directory for this entry */ sl@0: TUint32 TFatDirEntry::Size() const sl@0: {return pDir->iSize;} sl@0: sl@0: /** @return True if the entry is erased */ sl@0: TBool TFatDirEntry::IsErased() const sl@0: {return (TBool)(iData[0]==KEntryErasedMarker);} sl@0: sl@0: /** @return True if the entry refers to the current directory */ sl@0: TBool TFatDirEntry::IsCurrentDirectory() const sl@0: {return (TBool)(iData[0]==KDotEntryByte && iData[1]==KBlankSpace);} sl@0: sl@0: /** @return True if the Entry refers to the parent directory */ sl@0: TBool TFatDirEntry::IsParentDirectory() const sl@0: {return (TBool)(iData[0]==KDotEntryByte && iData[1]==KDotEntryByte);} sl@0: sl@0: /** @return True if end of directory */ sl@0: TBool TFatDirEntry::IsEndOfDirectory() const sl@0: {return (TBool)(iData[0]==0x00);} sl@0: sl@0: /** sl@0: Set the Dos name of a directory entry sl@0: @param aDes A descriptor containg the name sl@0: */ sl@0: void TFatDirEntry::SetName(const TDesC8& aDes) sl@0: { sl@0: ASSERT(aDes.Length()<=KFatDirNameSize); sl@0: TPtr8 name(pDir->iName,KFatDirNameSize); sl@0: name=aDes; sl@0: } sl@0: sl@0: /** sl@0: Set the file or directory attributes for this entry sl@0: @param anAtts The file or directory attributes sl@0: */ sl@0: void TFatDirEntry::SetAttributes(TInt anAtts) sl@0: { sl@0: ASSERT(!(anAtts&~KMaxTUint8)); sl@0: pDir->iAttributes=(TUint8)anAtts; sl@0: } sl@0: sl@0: /** sl@0: Set the creation time and data of the directory entry sl@0: @param aTime Creation time of the file or directory sl@0: */ sl@0: void TFatDirEntry::SetTime(TTime aTime) sl@0: { sl@0: pDir->iTime=(TUint16)DosTimeFromTTime(aTime); sl@0: pDir->iDate=(TUint16)DosDateFromTTime(aTime); sl@0: } sl@0: sl@0: void TFatDirEntry::SetCreateTime(TTime aTime) sl@0: { sl@0: pDir->iTimeC=(TUint16)DosTimeFromTTime(aTime); sl@0: pDir->iDateC=(TUint16)DosDateFromTTime(aTime); sl@0: } sl@0: sl@0: /** sl@0: Set the start cluster number of the file or directory refered to by the entry sl@0: @param aStartCluster The start cluster number sl@0: */ sl@0: void TFatDirEntry::SetStartCluster(TInt aStartCluster) sl@0: { sl@0: const TUint32 KHalfWordMask = 0x0000FFFF; sl@0: pDir->iStartClusterLo=(TUint16)(aStartCluster & KHalfWordMask); sl@0: pDir->iStartClusterHi=(TUint16)((aStartCluster>>16) & KHalfWordMask); sl@0: } sl@0: sl@0: /** sl@0: Set the size of the file or directory refered to by the entry sl@0: @param aFileSize Size of the file sl@0: */ sl@0: void TFatDirEntry::SetSize(TUint32 aFileSize) sl@0: {pDir->iSize=aFileSize;} sl@0: sl@0: /** Set the directory entry as erased */ sl@0: void TFatDirEntry::SetErased() sl@0: {iData[0]=KEntryErasedMarker;} sl@0: sl@0: /** Set the current entry to refer to the current directory */ sl@0: void TFatDirEntry::SetCurrentDirectory() sl@0: { sl@0: iData[0]='.'; sl@0: Mem::Fill(&iData[1],KFatDirNameSize-1,' '); sl@0: } sl@0: sl@0: /** Set the current entry to refer to the parent directory */ sl@0: void TFatDirEntry::SetParentDirectory() sl@0: { sl@0: iData[0]='.';iData[1]='.'; sl@0: Mem::Fill(&iData[2],KFatDirNameSize-2,' '); sl@0: } sl@0: sl@0: /** Set the current entry to be the end of directory marker */ sl@0: void TFatDirEntry::SetEndOfDirectory() sl@0: {Mem::FillZ(&iData[0],KFatDirNameSize);} sl@0: sl@0: /** @return True if the entry is the start of a long name set of entries */ sl@0: TBool TFatDirEntry::IsLongNameStart() const sl@0: {return (TBool)((iData[0]&0x40) != 0);} sl@0: sl@0: /** @return True is the Entry is a VFat entry */ sl@0: TBool TFatDirEntry::IsVFatEntry() const sl@0: {return (TBool)(Attributes()==KVFatEntryAttribute && IsEndOfDirectory()==EFalse);} sl@0: sl@0: /** @return The number of following VFat entries */ sl@0: TInt TFatDirEntry::NumFollowing() const sl@0: {return (iData[0]&0x3F);} sl@0: sl@0: sl@0: TUint8 TFatDirEntry::CheckSum() const sl@0: { sl@0: ASSERT(IsVFatEntry()); sl@0: return iData[13]; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: