kerneltest/f32test/fileutils/src/fat_utils.cpp
changeset 0 a41df078684a
child 21 e7d2d738d3c2
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // @file
       
    15 // various FAT test utilities 
       
    16 // 
       
    17 //
       
    18 
       
    19 
       
    20 #include "fat_utils.h"
       
    21 using namespace Fat_Test_Utils;
       
    22 
       
    23 
       
    24 
       
    25 //-------------------------------------------------------------------------------------------------------------------
       
    26 
       
    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
       
    30 
       
    31 #include <e32cons.h>
       
    32 #include <e32math.h>
       
    33 
       
    34 //-------------------------------------------------------------------------------------------------------------------
       
    35 
       
    36 /**
       
    37     Format FAT volume
       
    38     
       
    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.
       
    44 
       
    45     @return system-wide error codes.
       
    46 */
       
    47 TInt Fat_Test_Utils::FormatFatDrive(RFs &aFs, TInt aDrive, TBool aQuickFormat, const TFatFormatParam* apFmtParams/*=NULL*/, TBool aForceErase /*=EFalse*/)
       
    48 {
       
    49     TPtrC fmtTypeName = (aQuickFormat ? _L("Quick") : _L("Full"));
       
    50     DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() drv:%d, type:%S\n"),aDrive, &fmtTypeName);
       
    51    
       
    52     ASSERT(aDrive >= EDriveA && aDrive <= EDriveZ);
       
    53     
       
    54     RFormat format;
       
    55     TUint   fmtMode=0;
       
    56     TInt    fmtCnt=0;
       
    57     TInt    prevCnt;
       
    58     TInt    nRes;
       
    59 
       
    60     if(aQuickFormat) 
       
    61         fmtMode |= EQuickFormat;
       
    62 
       
    63     if(aForceErase)
       
    64         fmtMode |= EForceErase;
       
    65 
       
    66     TBuf<10> drvName;
       
    67     drvName.Format(_L("%C:"),'A'+aDrive);
       
    68 
       
    69     if(!apFmtParams)
       
    70     {//-- no format parameters specified
       
    71         //DoPrintf(_L("~ Format parameters - not specified\n"));
       
    72         nRes = format.Open(aFs, drvName, fmtMode, fmtCnt);
       
    73         if(nRes!=KErrNone)
       
    74             goto Fail;
       
    75     }
       
    76     else
       
    77     {//-- some extra parameters specified, use special format
       
    78         fmtMode |= ESpecialFormat;
       
    79         TLDFormatInfo formatInfo;
       
    80 
       
    81         TBuf<100> buf;
       
    82         buf.Copy(_L("~ Format parameters: "));
       
    83         
       
    84         if(apFmtParams->iFatType)
       
    85         {//-- FAT type is specified
       
    86             buf.AppendFormat(_L("FAT%d"), apFmtParams->iFatType);
       
    87             formatInfo.iFATBits = (TLDFormatInfo::TFATBits)apFmtParams->iFatType;
       
    88         }
       
    89 
       
    90         const TUint16 spc = (TUint16)apFmtParams->iSecPerCluster;
       
    91         if(spc)
       
    92         {//-- sectors per cluster value is specified
       
    93             buf.AppendFormat(_L(", spc:%d"), spc);
       
    94             formatInfo.iSectorsPerCluster = spc;
       
    95         }
       
    96 
       
    97         const TUint16 rsvdSec = (TUint16)apFmtParams->iReservedSectors;
       
    98         if(rsvdSec)
       
    99         {//-- reserved sectors numer is specified
       
   100             buf.AppendFormat(_L(", rsvdSec:%d"), rsvdSec);
       
   101             formatInfo.iReservedSectors = rsvdSec;
       
   102         }
       
   103         
       
   104         buf.Append(_L("\n"));
       
   105         DoPrintf(buf);
       
   106         
       
   107         TSpecialFormatInfoBuf formatInfoBuf(formatInfo);
       
   108         nRes = format.Open(aFs, drvName, fmtMode, fmtCnt, formatInfoBuf);
       
   109         if(nRes!=KErrNone)
       
   110             goto Fail;
       
   111 
       
   112     }
       
   113 
       
   114     //-- do format steps
       
   115     prevCnt=fmtCnt;
       
   116     while(fmtCnt)
       
   117     {
       
   118         nRes = format.Next(fmtCnt);
       
   119         if(nRes!=KErrNone)
       
   120             goto Fail;
       
   121 
       
   122         if(fmtCnt != prevCnt)
       
   123         {
       
   124             DoPrintf(_L("."));
       
   125             prevCnt = fmtCnt;
       
   126         }
       
   127     }
       
   128 
       
   129     //-- formatting has finished
       
   130     DoPrintf(_L("\n"));
       
   131     format.Close();
       
   132     return KErrNone;
       
   133 
       
   134    Fail:
       
   135     format.Close();
       
   136     DoPrintf(_L("~ Fat_Test_Utils::FormatFatDrive() failed! code:%d\n"), nRes);
       
   137 
       
   138     return nRes;
       
   139 }
       
   140 
       
   141 //-------------------------------------------------------------------------------------------------------------------
       
   142 
       
   143 /**
       
   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
       
   149 
       
   150     @return standard error codes
       
   151 */
       
   152 TInt Fat_Test_Utils::ReadFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFSInfo& aFsInfo)
       
   153 {
       
   154     DoPrintf(_L("~ Fat_Test_Utils::ReadFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);   
       
   155 
       
   156     TInt nRes = KErrNone;
       
   157     
       
   158     TBuf8<KSizeOfFSInfo> fsInfoSecBuf(KSizeOfFSInfo);
       
   159     TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, fsInfoSecBuf.Size(), fsInfoSecBuf));
       
   160 
       
   161     if(nRes == KErrNone)
       
   162     {//-- take FSInfo data from the buffer
       
   163         aFsInfo.Internalize(fsInfoSecBuf);
       
   164     }
       
   165 
       
   166     return nRes;
       
   167 }
       
   168 
       
   169 //-------------------------------------------------------------------------------------------------------------------
       
   170 
       
   171 /**
       
   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
       
   177 
       
   178     @return standard error codes
       
   179 */
       
   180 TInt Fat_Test_Utils::WriteFSInfoSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFSInfo& aFsInfo)
       
   181 {
       
   182     DoPrintf(_L("~ Fat_Test_Utils::WriteFSInfoSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);   
       
   183     
       
   184     TInt nRes = KErrNone;
       
   185     TBuf8<KSizeOfFSInfo> fsInfoSecBuf;
       
   186 
       
   187     //-- put data to the sector buffer
       
   188     aFsInfo.Externalize(fsInfoSecBuf);
       
   189   
       
   190     TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, fsInfoSecBuf))
       
   191 
       
   192     return nRes;
       
   193 }
       
   194 
       
   195 //-------------------------------------------------------------------------------------------------------------------
       
   196 
       
   197 /**
       
   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
       
   203 
       
   204     @return standard error codes
       
   205 */
       
   206 TInt  Fat_Test_Utils::ReadBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, TFatBootSector& aBootSector)
       
   207 {
       
   208     DoPrintf(_L("~ Fat_Test_Utils::ReadBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);   
       
   209     
       
   210     TInt nRes = KErrNone;
       
   211     TBuf8<KSizeOfFatBootSector> bootSecBuf(KSizeOfFatBootSector);
       
   212 
       
   213     TRAP(nRes, DoMediaRawReadL(aFs, aDrive, aMediaPos, bootSecBuf.Size(), bootSecBuf));
       
   214 
       
   215     if(nRes==KErrNone)
       
   216     {//-- initialise TFatBootSector object
       
   217         aBootSector.Internalize(bootSecBuf);
       
   218     }
       
   219 
       
   220     return nRes;
       
   221 }
       
   222 
       
   223 //-------------------------------------------------------------------------------------------------------------------
       
   224 
       
   225 /**
       
   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
       
   231 
       
   232     @return standard error codes
       
   233 */
       
   234 TInt  Fat_Test_Utils::WriteBootSector(RFs &aFs, TInt aDrive, TInt64 aMediaPos, const TFatBootSector& aBootSector)
       
   235 {
       
   236     DoPrintf(_L("~ Fat_Test_Utils::WriteBootSector() drv:%d, pos:0x%x\n"),aDrive, (TUint32)aMediaPos);   
       
   237     
       
   238     TBuf8<KDefaultSectorSize> bootSecBuf(KDefaultSectorSize);
       
   239     
       
   240     //-- externalize boot sector to the data buffer
       
   241     bootSecBuf.FillZ();
       
   242     aBootSector.Externalize(bootSecBuf); 
       
   243     
       
   244     //-- put a boot sector signature to the last 2 bytes
       
   245     bootSecBuf[KDefaultSectorSize-2] = 0x55;
       
   246     bootSecBuf[KDefaultSectorSize-1] = 0xaa;
       
   247 
       
   248     //-- write boot sector data to the media
       
   249     TInt nRes=KErrNone;
       
   250     TRAP(nRes, DoMediaRawWriteL(aFs, aDrive, aMediaPos, bootSecBuf));
       
   251     
       
   252     return nRes;
       
   253 }
       
   254 //-------------------------------------------------------------------------------------------------------------------
       
   255 /** 
       
   256     Obtain FAT type for the given drive 
       
   257 
       
   258     @return TFatType enum values. if aDrive has not FAT FS, EInvalid value is returned
       
   259 */
       
   260 TFatType Fat_Test_Utils::GetFatType(RFs &aFs, TInt aDrive)
       
   261 {
       
   262     if(Is_Fat16(aFs, aDrive))
       
   263         return EFat16;
       
   264     else if(Is_Fat32(aFs, aDrive))
       
   265         return EFat32;
       
   266     else if(Is_Fat12(aFs, aDrive))
       
   267         return EFat12;
       
   268 
       
   269     return EInvalid;
       
   270 }
       
   271 
       
   272 //-------------------------------------------------------------------------------------------------------------------
       
   273 
       
   274 #endif //FAT_UTILS_LEAN_AND_MEAN
       
   275 
       
   276 
       
   277 
       
   278 
       
   279 TFatFormatParam::TFatFormatParam()
       
   280 {
       
   281     iFatType = EInvalid;
       
   282     iSecPerCluster = 0;
       
   283     iReservedSectors = 0;
       
   284 }
       
   285         
       
   286 //-------------------------------------------------------------------------------------------------------------------
       
   287 
       
   288 TFatBootSector::TFatBootSector()
       
   289 {
       
   290     Initialise();
       
   291 }
       
   292 
       
   293 /** initialises the boot sector data */
       
   294 void TFatBootSector::Initialise()
       
   295 {
       
   296     Mem::FillZ(this, sizeof(TFatBootSector));
       
   297 }
       
   298 
       
   299 TBool TFatBootSector::operator==(const TFatBootSector& aRhs)
       
   300 {
       
   301     ASSERT(&aRhs != this);
       
   302     if(&aRhs == this)
       
   303         return ETrue; //-- comparing with itself
       
   304 
       
   305     return  (Mem::Compare((TUint8*)this, sizeof(TFatBootSector), (TUint8*)&aRhs, sizeof(TFatBootSector)) == 0);
       
   306 }
       
   307 
       
   308 
       
   309 /**
       
   310     @return ETrue if the boot sector contents seems to be valid
       
   311 */
       
   312 TBool TFatBootSector::IsValid() const
       
   313 {
       
   314     const TFatType fatType = FatType(); //-- it will check SectorsPerCluster etc.
       
   315 
       
   316     if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1)
       
   317         goto Invalid;
       
   318         
       
   319     if(fatType == EFat32)
       
   320     {
       
   321         if(VersionNumber()!= 0 || FatSectors()!=0 || FatSectors32()<1 || RootClusterNum()<(TUint32)KFatFirstSearchCluser ||
       
   322            TotalSectors()!=0 || HugeSectors() <5 || RootDirEntries() !=0)
       
   323         {
       
   324             goto Invalid; //-- these values are not compliant with FAT specs
       
   325         }
       
   326     }
       
   327     else //-- FAT12/16
       
   328     {
       
   329         if(TotalSectors() >0 && HugeSectors() >0 )
       
   330             goto Invalid; //-- values clash
       
   331 
       
   332         const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
       
   333         const TUint32 rootDirStartSec =  ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
       
   334 
       
   335         if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5)
       
   336             goto Invalid; //-- these values are not compliant with FAT specs
       
   337     }
       
   338 
       
   339     return ETrue;
       
   340   
       
   341   Invalid:
       
   342     DoPrintf(_L("~ TFatBootSector::IsValid() failed!\n"));
       
   343 
       
   344     return EFalse;
       
   345 }
       
   346 
       
   347 //-------------------------------------------------------------------------------------------------------------------
       
   348 
       
   349 /**
       
   350     Initialize boot sector object from the given bufer. Does not validate the data.
       
   351     @param  aBuf buffer with data.
       
   352 */
       
   353 void TFatBootSector::Internalize(const TDesC8& aBuf)
       
   354 {
       
   355     ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
       
   356 
       
   357     Initialise();
       
   358 
       
   359     TInt pos=0;
       
   360 
       
   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
       
   375 
       
   376     if(RootDirEntries() == 0) //-- we have FAT32 volume
       
   377     {
       
   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   
       
   385     }
       
   386 
       
   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;
       
   393 
       
   394     // 54|82    TUint8 iFileSysType[KFileSysTypeSize]
       
   395     ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
       
   396     Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
       
   397 }
       
   398 
       
   399 //-------------------------------------------------------------------------------------------------------------------
       
   400 
       
   401 /**
       
   402     Externalize boot sector object to the given data buffer.
       
   403     @param  aBuf buffer to externalize.
       
   404 */
       
   405 void TFatBootSector::Externalize(TDes8& aBuf) const
       
   406 {
       
   407     ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
       
   408 
       
   409     if(aBuf.Size() < KSizeOfFatBootSector)
       
   410         aBuf.SetLength(KSizeOfFatBootSector);
       
   411     
       
   412     TInt pos=0;
       
   413 
       
   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;
       
   428 
       
   429     if(iFatSectors == 0)    
       
   430         {
       
   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;
       
   437 
       
   438         //extra 12 for the reserved bytes   
       
   439         ASSERT(aBuf.Size() >= pos+12);
       
   440         Mem::FillZ(&aBuf[pos],12);
       
   441         pos+=12;
       
   442         }
       
   443 
       
   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;
       
   448     
       
   449     Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize); 
       
   450     pos+=KVolumeLabelSize;
       
   451     
       
   452     ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
       
   453     Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
       
   454 }
       
   455 
       
   456 //-------------------------------------------------------------------------------------------------------------------
       
   457 
       
   458 /** replaces all non-printable characters in a buffer with spaces */
       
   459 static void FixDes(TDes& aDes)
       
   460 {
       
   461     for(TInt i=0; i< aDes.Length(); ++i)
       
   462     {
       
   463         TChar ch=aDes[i];
       
   464         if(!ch.IsPrint())
       
   465             aDes[i]=' ';    
       
   466     }
       
   467 }
       
   468 
       
   469 /** 
       
   470     Print out the boot sector info.
       
   471 */
       
   472 void TFatBootSector::PrintDebugInfo() const
       
   473 {
       
   474     TBuf<40> buf;
       
   475     
       
   476     DoPrintf(_L("======== BootSector info: =======\n"));
       
   477     
       
   478     buf.Copy(FileSysType()); FixDes(buf);    
       
   479     DoPrintf(_L("FAT type:%S\n"),&buf);
       
   480 
       
   481     buf.Copy(VendorId()); FixDes(buf);
       
   482     DoPrintf(_L("Vendor ID:%S\n"),&buf);
       
   483 
       
   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());
       
   504     
       
   505     buf.Copy(VolumeLabel()); FixDes(buf);
       
   506     DoPrintf(_L("VolumeLabel:%S\n"),&buf);
       
   507     
       
   508     DoPrintf(_L("=============================\n"));
       
   509 }
       
   510 
       
   511 //-------------------------------------------------------------------------------------------------------------------
       
   512 
       
   513 
       
   514 /**
       
   515     Determine FAT type according to the information from boot sector, see FAT32 specs.
       
   516     @return  FAT type. 
       
   517 */
       
   518 TFatType TFatBootSector::FatType(void) const
       
   519     {
       
   520 
       
   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
       
   524 
       
   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
       
   528 
       
   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;
       
   534 
       
   535     //-- magic. see FAT specs for details.
       
   536     if(clusterCnt < 4085)
       
   537         return EFat12;
       
   538     else if(clusterCnt < 65525)
       
   539         return EFat16;
       
   540     else
       
   541         return EFat32;
       
   542 
       
   543     }
       
   544 
       
   545 //-------------------------------------------------------------------------------------------------------------------
       
   546 
       
   547 /** Returns Sectors in Fat table for 32 bit volume */
       
   548 TUint32 TFatBootSector::FatSectors32() const	
       
   549 {return iFatSectors32;}
       
   550 
       
   551 /** Fat flags */
       
   552 TUint16 TFatBootSector::FATFlags() const		
       
   553 {return iFATFlags;}
       
   554 
       
   555 /** Version number of the file system */
       
   556 TUint16 TFatBootSector::VersionNumber() const		
       
   557 {return iVersionNumber;}
       
   558 
       
   559 /** Cluster number of the root directory */
       
   560 TUint32 TFatBootSector::RootClusterNum() const	
       
   561 {return iRootClusterNum;}
       
   562 
       
   563 /** Sector number containing the FSIInfo structure */
       
   564 TUint16 TFatBootSector::FSInfoSectorNum() const
       
   565 {return iFSInfoSectorNum;}
       
   566 
       
   567 /** Backup boot sector */
       
   568 TUint16 TFatBootSector::BkBootRecSector() const
       
   569 {return iBkBootRecSector;}
       
   570 
       
   571 /** Sets the number of sectors in Fat table for 32 bit volume */
       
   572 void TFatBootSector::SetFatSectors32(TUint32	aFatSectors32)
       
   573 {iFatSectors32 = aFatSectors32;}
       
   574 
       
   575 /** Sets the Fat flags */
       
   576 void TFatBootSector::SetFATFlags(TUint16 aFATFlags)
       
   577 {iFATFlags = aFATFlags;}
       
   578 
       
   579 /** Sets the version number of the file system */
       
   580 void TFatBootSector::SetVersionNumber(TUint16 aVersionNumber)
       
   581 {iVersionNumber = aVersionNumber;}
       
   582 
       
   583 /** Sets the cluster number of the root directory */
       
   584 void TFatBootSector::SetRootClusterNum(TUint32 aRootClusterNum)	
       
   585 {iRootClusterNum = aRootClusterNum;}
       
   586 
       
   587 /** Set the sector number containing the FSIInfo structure */
       
   588 void TFatBootSector::SetFSInfoSectorNum(TUint16 aFSInfoSectorNum)
       
   589 {iFSInfoSectorNum = aFSInfoSectorNum;}
       
   590 
       
   591 /** Set the backup boot sector */
       
   592 void TFatBootSector::SetBkBootRecSector(TUint16 aBkBootRecSector)
       
   593 {iBkBootRecSector = aBkBootRecSector;}	
       
   594 
       
   595 /** Returns the vendor ID of the file system that formatted the volume */
       
   596 const TPtrC8 TFatBootSector::VendorId() const
       
   597 {return TPtrC8(iVendorId,KVendorIdSize);}
       
   598 
       
   599 /** Return the bytes per sector */
       
   600 TUint16 TFatBootSector::BytesPerSector() const
       
   601 {return iBytesPerSector;}
       
   602 
       
   603 /** Returns the sectors per cluster ratio */
       
   604 TInt TFatBootSector::SectorsPerCluster() const
       
   605 {return iSectorsPerCluster;}
       
   606 
       
   607 /** Returns the number of reserved sectors on the volume */
       
   608 TInt TFatBootSector::ReservedSectors() const
       
   609 {return iReservedSectors;}
       
   610 
       
   611 /** Returns the number of Fats on the volume */
       
   612 TInt TFatBootSector::NumberOfFats() const
       
   613 {return iNumberOfFats;}
       
   614 
       
   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;}
       
   618 
       
   619 /** Returns the total sectors on the volume, zero for FAT32 */
       
   620 TInt TFatBootSector::TotalSectors() const
       
   621 {return iTotalSectors;}
       
   622 
       
   623 /** Returns the media descriptor */
       
   624 TUint8 TFatBootSector::MediaDescriptor() const
       
   625 {return iMediaDescriptor;}
       
   626 
       
   627 /** Returns sectors used for the Fat table, zero for FAT32 */
       
   628 TInt TFatBootSector::FatSectors() const
       
   629 {return iFatSectors;}
       
   630 
       
   631 /** Returns sectors per track */
       
   632 TInt TFatBootSector::SectorsPerTrack() const
       
   633 {return iSectorsPerTrack;}
       
   634 
       
   635 /** Returns the number of heads  */
       
   636 TInt TFatBootSector::NumberOfHeads() const
       
   637 {return iNumberOfHeads;}
       
   638 
       
   639 /** Returns the number of hidden sectors in the volume */
       
   640 TInt TFatBootSector::HiddenSectors() const
       
   641 {return iHiddenSectors;}
       
   642 
       
   643 /** Returns total sectors in the volume, Used if totalSectors > 65535 */
       
   644 TInt TFatBootSector::HugeSectors() const
       
   645 {return iHugeSectors;}
       
   646 
       
   647 /** Returns the physical drive number, not used in Symbian OS */
       
   648 TInt TFatBootSector::PhysicalDriveNumber() const
       
   649 {return iPhysicalDriveNumber;}
       
   650 
       
   651 /** Returns the extended boot signiture */
       
   652 TInt TFatBootSector::ExtendedBootSignature() const
       
   653 {return iExtendedBootSignature;}
       
   654 
       
   655 /** Returns the unique volume ID */
       
   656 TUint32 TFatBootSector::UniqueID() const
       
   657 {return iUniqueID;}
       
   658 
       
   659 /** Returns the volume's label */
       
   660 const TPtrC8 TFatBootSector::VolumeLabel() const
       
   661 {return TPtrC8(iVolumeLabel,KVolumeLabelSize);}
       
   662 
       
   663 /** Returns the file system type */
       
   664 const TPtrC8 TFatBootSector::FileSysType() const
       
   665 {return TPtrC8(iFileSysType,KFileSysTypeSize);}
       
   666 
       
   667 /** Returns the boot sector signiture */
       
   668 TInt TFatBootSector::BootSectorSignature() const
       
   669 {return KBootSectorSignature;}
       
   670 
       
   671 /** Set the jump instruction  */
       
   672 void TFatBootSector::SetJumpInstruction()
       
   673 {iJumpInstruction[0]=0xE9;iJumpInstruction[2]=0x90;}
       
   674 
       
   675 /** Set the vendor ID of the file system that formatted the volume */
       
   676 void TFatBootSector::SetVendorID(const TDesC8& aDes)
       
   677 {
       
   678 	ASSERT(aDes.Length()<=KVendorIdSize);
       
   679 	TPtr8 buf(iVendorId,KVendorIdSize);
       
   680 	buf=aDes;
       
   681 }
       
   682 
       
   683 /** Sets the bytes per sector  */
       
   684 void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector)
       
   685 {
       
   686 	ASSERT(!(aBytesPerSector&~KMaxTUint16));
       
   687 	iBytesPerSector=(TUint16)aBytesPerSector;
       
   688 }
       
   689 
       
   690 /** Set the sectors per cluster ratio */
       
   691 void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster)
       
   692 {
       
   693 	ASSERT(!(aSectorsPerCluster&~KMaxTUint8));
       
   694 	iSectorsPerCluster=(TUint8)aSectorsPerCluster;
       
   695 }
       
   696 
       
   697 
       
   698 /** Sets the number of reserved sectors on the volume */
       
   699 void TFatBootSector::SetReservedSectors(TInt aReservedSectors)
       
   700 {
       
   701 	ASSERT(!(aReservedSectors&~KMaxTUint16));
       
   702 	iReservedSectors=(TUint16)aReservedSectors;
       
   703 }
       
   704 
       
   705 /** Sets the number of Fats on the volume */
       
   706 void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats)
       
   707 {
       
   708 	ASSERT(!(aNumberOfFats&~KMaxTUint8));
       
   709 	iNumberOfFats=(TUint8)aNumberOfFats;
       
   710 }
       
   711 
       
   712 /** Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32 */
       
   713 void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries)
       
   714 {
       
   715 	ASSERT(!(aRootDirEntries&~KMaxTUint16));
       
   716 	iRootDirEntries=(TUint16)aRootDirEntries;
       
   717 }
       
   718 
       
   719 /** Total sectors on the volume, zero for FAT32 */
       
   720 void TFatBootSector::SetTotalSectors(TInt aTotalSectors)
       
   721 {
       
   722 	ASSERT(!(aTotalSectors&~KMaxTUint16));
       
   723 	iTotalSectors=(TUint16)aTotalSectors;
       
   724 }
       
   725 
       
   726 /** Set the media descriptor */
       
   727 void TFatBootSector::SetMediaDescriptor(TUint8 aMediaDescriptor)
       
   728 {iMediaDescriptor=aMediaDescriptor;}
       
   729 
       
   730 /** Sectors used for the Fat table, zero for FAT32 */
       
   731 void TFatBootSector::SetFatSectors(TInt aFatSectors)
       
   732 {
       
   733 	ASSERT(!(aFatSectors&~KMaxTUint16));
       
   734 	iFatSectors=(TUint16)aFatSectors;
       
   735 }
       
   736 
       
   737 /** Set the sectors per track */
       
   738 void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack)
       
   739 {
       
   740 	ASSERT(!(aSectorsPerTrack&~KMaxTUint16));
       
   741 	iSectorsPerTrack=(TUint16)aSectorsPerTrack;
       
   742 }
       
   743 
       
   744 /** Set the number of heads */
       
   745 void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads)
       
   746 {
       
   747 	ASSERT(!(aNumberOfHeads&~KMaxTUint16));
       
   748 	iNumberOfHeads=(TUint16)aNumberOfHeads;
       
   749 }
       
   750 
       
   751 /** Set the number of hidden sectors in the volume */
       
   752 void TFatBootSector::SetHiddenSectors(TUint32 aHiddenSectors)
       
   753 {
       
   754 	iHiddenSectors=(TUint32)(aHiddenSectors);
       
   755 }
       
   756 
       
   757 /** Set the total sectors in the volume, Used if totalSectors > 65535 */
       
   758 void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors)
       
   759 {iHugeSectors=aHugeSectors;}
       
   760 
       
   761 
       
   762 /** Physical drive number, not used in Symbian OS */
       
   763 void TFatBootSector::SetPhysicalDriveNumber(TInt aPhysicalDriveNumber)
       
   764 {
       
   765 	ASSERT(!(aPhysicalDriveNumber&~KMaxTUint8));
       
   766 	iPhysicalDriveNumber=(TUint8)aPhysicalDriveNumber;
       
   767 }
       
   768 
       
   769 /** Set the reserved byte value */
       
   770 void TFatBootSector::SetReservedByte(TUint8 aReservedByte)
       
   771 {iReserved=aReservedByte;}
       
   772 
       
   773 /** Set the extended boot signiture */
       
   774 void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature)
       
   775 {
       
   776 	ASSERT(!(anExtendedBootSignature&~KMaxTUint8));
       
   777 	iExtendedBootSignature=(TUint8)anExtendedBootSignature;
       
   778 }
       
   779 
       
   780 /** Set the unique volume ID */
       
   781 void TFatBootSector::SetUniqueID(TUint32 anUniqueID)
       
   782 {iUniqueID=anUniqueID;}
       
   783 
       
   784 /** Set the volume's label */
       
   785 void TFatBootSector::SetVolumeLabel(const TDesC8& aDes)
       
   786 {
       
   787 	ASSERT(aDes.Length()<=KVolumeLabelSize);
       
   788 	TPtr8 buf(iVolumeLabel,KVolumeLabelSize);
       
   789 	buf=aDes;
       
   790 }
       
   791 
       
   792 /** Set the file system type */
       
   793 void TFatBootSector::SetFileSysType(const TDesC8& aDes)
       
   794 {
       
   795 	ASSERT(aDes.Length()<=8);
       
   796 	TPtr8 buf(iFileSysType,8);
       
   797 	buf=aDes;
       
   798 }
       
   799 
       
   800 
       
   801 /** @return The first Fat sector number */
       
   802 TInt TFatBootSector::FirstFatSector() const
       
   803 {
       
   804     __ASSERT_ALWAYS(IsValid(), User::Invariant());
       
   805     return ReservedSectors();
       
   806 }
       
   807 
       
   808 /**
       
   809     @return Number of sectors in root directory. 0 for FAT32
       
   810 */
       
   811 TUint32 TFatBootSector::RootDirSectors() const
       
   812 {
       
   813     __ASSERT_ALWAYS(IsValid(), User::Invariant());
       
   814     return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
       
   815 }
       
   816 
       
   817 
       
   818 /** @return Start sector number of the root directory */
       
   819 TInt TFatBootSector::RootDirStartSector()  const
       
   820 {
       
   821     __ASSERT_ALWAYS(IsValid(), User::Invariant());
       
   822     
       
   823     const TUint32 firstNonFatSec = ReservedSectors() + TotalFatSectors()*NumberOfFats();
       
   824 
       
   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());
       
   828     }
       
   829     else
       
   830     {//-- FAT12/16 root dir starts just after the FATs
       
   831         return firstNonFatSec;
       
   832     }
       
   833 
       
   834 }
       
   835 
       
   836 /** @return first data sector number. for FAT32 it includes the root directory */
       
   837 TInt TFatBootSector::FirstDataSector() const
       
   838 {
       
   839     return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
       
   840 }
       
   841 
       
   842 /** @return FAT-type independent sector count on the volume */
       
   843 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
       
   844 {
       
   845     __ASSERT_ALWAYS(IsValid(), User::Invariant());
       
   846     return HugeSectors() ? (TUint32)HugeSectors() : (TUint32)TotalSectors();
       
   847 }
       
   848 
       
   849 /** @return FAT-type independent number of sectors in one FAT */
       
   850 TUint32 TFatBootSector::TotalFatSectors() const
       
   851 {
       
   852     __ASSERT_ALWAYS(IsValid(), User::Invariant());
       
   853     return FatSectors32() ? FatSectors32() : (TUint32)FatSectors();
       
   854 }
       
   855 
       
   856 
       
   857 //-------------------------------------------------------------------------------------------------------------------
       
   858 
       
   859 
       
   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
       
   863 
       
   864 TFSInfo::TFSInfo()
       
   865 {
       
   866     Initialise();
       
   867 }
       
   868 //-------------------------------------------------------------------------------------------------------------------
       
   869 
       
   870 /** Initialise the data */
       
   871 void TFSInfo::Initialise()  
       
   872 {
       
   873     Mem::FillZ(this, sizeof(TFSInfo));
       
   874 
       
   875     iLeadSig      = KLeadSignature; 
       
   876     iStructureSig = KStructureSignature;
       
   877     iTrainlingSig = KTrailingSignature;
       
   878 }
       
   879 
       
   880 
       
   881 TBool TFSInfo::operator==(const TFSInfo& aRhs)
       
   882 {
       
   883     ASSERT(&aRhs != this);
       
   884     if(&aRhs == this)
       
   885         return ETrue; //-- comparing with itself
       
   886 
       
   887     return  (Mem::Compare((TUint8*)this, sizeof(TFSInfo), (TUint8*)&aRhs, sizeof(TFSInfo)) == 0);
       
   888 }
       
   889 
       
   890 //-------------------------------------------------------------------------------------------------------------------
       
   891 
       
   892 /**
       
   893     @return ETrue if FSInfo sector contents seems to be valid
       
   894 */
       
   895 TBool TFSInfo::IsValid() const
       
   896 {
       
   897     return (iLeadSig == KLeadSignature && iStructureSig == KStructureSignature && iTrainlingSig == KTrailingSignature);
       
   898 }
       
   899 
       
   900 //-------------------------------------------------------------------------------------------------------------------
       
   901 
       
   902 /**
       
   903     Initialize FSInfo sector object from the given bufer. Does not validate the data.
       
   904     @param  aBuf buffer with data.
       
   905 */
       
   906 void TFSInfo::Internalize(const TDesC8& aBuf)
       
   907 {
       
   908     ASSERT((TUint32)aBuf.Size() >= KSizeOfFSInfo);
       
   909 
       
   910     TInt pos=0;
       
   911 
       
   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);
       
   917 }
       
   918 
       
   919 //-------------------------------------------------------------------------------------------------------------------
       
   920 
       
   921 /**
       
   922     Externalize FSInfo sector object to the given data buffer.
       
   923     @param  aBuf buffer to externalize.
       
   924 */
       
   925 void TFSInfo::Externalize(TDes8& aBuf) const
       
   926 {
       
   927     ASSERT((TUint32)aBuf.MaxSize() >= KSizeOfFSInfo);
       
   928     
       
   929     aBuf.SetLength(KSizeOfFSInfo);
       
   930     aBuf.FillZ();
       
   931     
       
   932     TInt pos=0;
       
   933 
       
   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);
       
   941 }
       
   942 
       
   943 //-------------------------------------------------------------------------------------------------------------------
       
   944 
       
   945 /** 
       
   946     Print out the FSInfo sector info.
       
   947 */
       
   948 void TFSInfo::PrintDebugInfo() const
       
   949 {
       
   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"));
       
   957 }
       
   958 
       
   959 TUint32 TFSInfo::FreeClusterCount() const 
       
   960 {
       
   961     return iFreeCount;
       
   962 }
       
   963 
       
   964 TUint32 TFSInfo::NextFreeCluster() const
       
   965 {
       
   966     return iNextFree;
       
   967 }
       
   968 
       
   969 
       
   970 void TFSInfo::SetFreeClusterCount(TUint32 aFreeCount)
       
   971 {
       
   972     iFreeCount = aFreeCount;
       
   973 }
       
   974 
       
   975 void TFSInfo::SetNextFreeCluster(TUint32 aNextCluster)
       
   976 {
       
   977     iNextFree = aNextCluster;
       
   978 }
       
   979 
       
   980 
       
   981 //-------------------------------------------------------------------------------------------------------------------
       
   982 
       
   983 /**
       
   984     Deciphers the dos time/date entry information and converts to TTime
       
   985 */
       
   986 TTime Fat_Test_Utils::DosTimeToTTime(TInt aDosTime,TInt aDosDate)
       
   987 	{
       
   988 	TInt secMask=0x1F;
       
   989 	TInt minMask=0x07E0;
       
   990 	TInt hrMask=0xF800;
       
   991 	TInt dayMask=0x1F;
       
   992 	TInt monthMask=0x01E0;
       
   993 	TInt yearMask=0xFE00;
       
   994 
       
   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;
       
  1001 	
       
  1002 	TDateTime datetime;
       
  1003 	TInt ret=datetime.Set(years,months,days,hrs,mins,secs,0);
       
  1004 	if (ret==KErrNone)
       
  1005 		return(TTime(datetime));
       
  1006 	return(TTime(0));
       
  1007 	}
       
  1008 
       
  1009 /**
       
  1010 Converts a TTime to a dos time
       
  1011 */
       
  1012 TInt Fat_Test_Utils::DosTimeFromTTime(const TTime& aTime)
       
  1013 	{
       
  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;
       
  1019 	}
       
  1020 
       
  1021 /**
       
  1022 Converts a TTime to a dos date
       
  1023 */
       
  1024 TInt Fat_Test_Utils::DosDateFromTTime(const TTime& aTime)
       
  1025 	{
       
  1026 
       
  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;
       
  1032 	}
       
  1033 
       
  1034 
       
  1035 /**
       
  1036 Converts xxx.yyy to standard format aaaaaaaayyy
       
  1037 */
       
  1038 TBuf8<12> Fat_Test_Utils::DosNameToStdFormat(const TDesC8& aDosName)
       
  1039 	{
       
  1040     ASSERT(aDosName.Length()>=0 && aDosName.Length()<=KMaxFatFileName);
       
  1041 
       
  1042 	TBuf8<12> result;
       
  1043 	Mem::Fill((TUint8*)result.Ptr(),result.MaxSize(),' ');
       
  1044 	TInt dotPos=aDosName.Locate('.');
       
  1045 	if (dotPos==KErrNotFound)
       
  1046 		{
       
  1047 		result=aDosName;
       
  1048 		result.SetLength(11);
       
  1049 		return result;
       
  1050 		}
       
  1051 	result=aDosName.Left(dotPos);
       
  1052 	result.SetLength(11);
       
  1053 	TPtr8 ext(&result[8],3);
       
  1054 	ext=aDosName.Right(aDosName.Length()-dotPos-1);
       
  1055 	return result;
       
  1056 	}
       
  1057 
       
  1058 /**
       
  1059 Converts aaaaaaaayyy to dos name format xxx.yyy
       
  1060 */
       
  1061 TBuf8<12> Fat_Test_Utils::DosNameFromStdFormat(const TDesC8& aStdFormatName)
       
  1062 	{
       
  1063     ASSERT(aStdFormatName.Length()==11);
       
  1064 
       
  1065 	TBuf8<12> result;
       
  1066 	TInt nameLen=aStdFormatName.Locate(' ');
       
  1067 	if (nameLen>8 || nameLen==KErrNotFound)
       
  1068 		nameLen=8;
       
  1069 	result=aStdFormatName.Left(nameLen);
       
  1070 	TPtrC8 ext(&aStdFormatName[8],3);
       
  1071 	TInt extLen=ext.Locate(' ');
       
  1072 	if (extLen)
       
  1073 		result.Append(TChar('.'));
       
  1074 	if (extLen==KErrNotFound)
       
  1075 		extLen=3;
       
  1076 	result.Append(ext.Left(extLen));
       
  1077     if(result.Length() && result[0]==0x05 )
       
  1078 	    {
       
  1079 	    result[0]=0xE5;
       
  1080 	    }
       
  1081 	return result;
       
  1082 	}
       
  1083 
       
  1084 /**
       
  1085 Return the number of VFat entries required to describe a filename of length aNameLength
       
  1086 */
       
  1087 TInt Fat_Test_Utils::NumberOfVFatEntries(TInt aNameLength)
       
  1088 	{
       
  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		
       
  1094 	
       
  1095 	numberOfEntries=(1+(aNameLength/KMaxVFatEntryName));	
       
  1096 	
       
  1097 	if (aNameLength%KMaxVFatEntryName)
       
  1098 		numberOfEntries++;
       
  1099 	
       
  1100 	return(numberOfEntries);
       
  1101 	}
       
  1102 
       
  1103 /**
       
  1104 Calculate a checksum to tie the vFat and dos names together
       
  1105 */
       
  1106 TUint8 Fat_Test_Utils::CalculateShortNameCheckSum(const TDesC8& aShortName)
       
  1107 	{
       
  1108 
       
  1109 	TUint8 cksum=0;
       
  1110 	for (TInt i=0;i<11;i++)
       
  1111 		cksum =(TUint8)((((cksum&1)<<7)|((cksum&0xfe)>>1))+aShortName[i]);
       
  1112 
       
  1113 	return(cksum);
       
  1114 	}
       
  1115 
       
  1116 
       
  1117 //-------------------------------------------------------------------------------------------------------------------
       
  1118 
       
  1119 
       
  1120 #define pDir ((SFatDirEntry*)&iData[0])
       
  1121 const TUint8 KEntryErasedMarker=0xE5;
       
  1122 
       
  1123 
       
  1124 TFatDirEntry::TFatDirEntry() 
       
  1125     {
       
  1126     InitZ();
       
  1127     }       
       
  1128 
       
  1129 /** zero-fill the entry contents  */
       
  1130 void TFatDirEntry::InitZ() 
       
  1131     {
       
  1132     Mem::FillZ(iData, KSizeOfFatDirEntry);
       
  1133     }
       
  1134 
       
  1135 
       
  1136 /**
       
  1137 @return  ETrue if the Directory entry contains garbage data
       
  1138 */
       
  1139 TBool TFatDirEntry::IsGarbage() const
       
  1140     {
       
  1141     return (iData[0]==0xFF);
       
  1142     }
       
  1143 
       
  1144 /**
       
  1145 Return the Dos name of a directory entry
       
  1146 @return A descriptor containing the Dos name of a directory entry
       
  1147 */
       
  1148 const TPtrC8 TFatDirEntry::Name() const
       
  1149 	{return TPtrC8((TUint8*)&(pDir->iName),KFatDirNameSize);}
       
  1150 
       
  1151 /** @return The attributes for the Directory entry */
       
  1152 TInt TFatDirEntry::Attributes() const
       
  1153 	{return pDir->iAttributes;}
       
  1154 
       
  1155 /** @return Time of file creation */
       
  1156 TTime TFatDirEntry::Time() const
       
  1157 	{return DosTimeToTTime(pDir->iTime,pDir->iDate);}
       
  1158 
       
  1159 /** @return The Start cluster for the file or directory for this entry  */
       
  1160 TInt TFatDirEntry::StartCluster() const		
       
  1161 	{
       
  1162     const TUint16 KStClustMaskHi = 0x0FFF;	
       
  1163     return ((pDir->iStartClusterHi&KStClustMaskHi)<<16) | pDir->iStartClusterLo;
       
  1164     }
       
  1165 
       
  1166 /** @return The size of file or directory for this entry  */
       
  1167 TUint32 TFatDirEntry::Size() const
       
  1168 	{return pDir->iSize;}
       
  1169 
       
  1170 /** @return True if the entry is erased */
       
  1171 TBool TFatDirEntry::IsErased() const
       
  1172 	{return (TBool)(iData[0]==KEntryErasedMarker);}
       
  1173 
       
  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);}
       
  1177 
       
  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);}
       
  1181 
       
  1182 /** @return True if end of directory */
       
  1183 TBool TFatDirEntry::IsEndOfDirectory() const
       
  1184 	{return (TBool)(iData[0]==0x00);}
       
  1185 
       
  1186 /** 
       
  1187 Set the Dos name of a directory entry 
       
  1188 @param aDes A descriptor containg the name
       
  1189 */
       
  1190 void TFatDirEntry::SetName(const TDesC8& aDes)
       
  1191 	{
       
  1192     ASSERT(aDes.Length()<=KFatDirNameSize);
       
  1193 	TPtr8 name(pDir->iName,KFatDirNameSize);
       
  1194 	name=aDes;
       
  1195 	}
       
  1196 
       
  1197 /** 
       
  1198 Set the file or directory attributes for this entry 
       
  1199 @param anAtts The file or directory attributes
       
  1200 */
       
  1201 void TFatDirEntry::SetAttributes(TInt anAtts)
       
  1202 	{
       
  1203 	ASSERT(!(anAtts&~KMaxTUint8));
       
  1204 	pDir->iAttributes=(TUint8)anAtts;
       
  1205 	}
       
  1206 
       
  1207 /**
       
  1208 Set the creation time and data of the directory entry
       
  1209 @param aTime Creation time of the file or directory
       
  1210 */
       
  1211 void TFatDirEntry::SetTime(TTime aTime)
       
  1212 	{
       
  1213 	pDir->iTime=(TUint16)DosTimeFromTTime(aTime);
       
  1214 	pDir->iDate=(TUint16)DosDateFromTTime(aTime);
       
  1215 	}
       
  1216 
       
  1217 void TFatDirEntry::SetCreateTime(TTime aTime)
       
  1218 	{
       
  1219 	pDir->iTimeC=(TUint16)DosTimeFromTTime(aTime);
       
  1220 	pDir->iDateC=(TUint16)DosDateFromTTime(aTime);
       
  1221 	}
       
  1222 
       
  1223 /**
       
  1224 Set the start cluster number of the file or directory refered to by the entry
       
  1225 @param aStartCluster The start cluster number
       
  1226 */
       
  1227 void TFatDirEntry::SetStartCluster(TInt aStartCluster)
       
  1228 	{
       
  1229 	const TUint32 KHalfWordMask	= 0x0000FFFF;
       
  1230     pDir->iStartClusterLo=(TUint16)(aStartCluster & KHalfWordMask);
       
  1231 	pDir->iStartClusterHi=(TUint16)((aStartCluster>>16) & KHalfWordMask);
       
  1232 	}
       
  1233 
       
  1234 /**
       
  1235 Set the size of the file or directory refered to by the entry
       
  1236 @param aFileSize Size of the file
       
  1237 */
       
  1238 void TFatDirEntry::SetSize(TUint32 aFileSize)
       
  1239 	{pDir->iSize=aFileSize;}
       
  1240 
       
  1241 /** Set the directory entry as erased */
       
  1242 void TFatDirEntry::SetErased()
       
  1243 	{iData[0]=KEntryErasedMarker;}
       
  1244 
       
  1245 /**  Set the current entry to refer to the current directory */
       
  1246 void TFatDirEntry::SetCurrentDirectory()
       
  1247 	{
       
  1248 	iData[0]='.';
       
  1249 	Mem::Fill(&iData[1],KFatDirNameSize-1,' ');
       
  1250 	}
       
  1251 
       
  1252 /** Set the current entry to refer to the parent directory */
       
  1253 void TFatDirEntry::SetParentDirectory()
       
  1254 	{
       
  1255 	iData[0]='.';iData[1]='.';
       
  1256 	Mem::Fill(&iData[2],KFatDirNameSize-2,' ');
       
  1257 	}
       
  1258 
       
  1259 /** Set the current entry to be the end of directory marker */
       
  1260 void TFatDirEntry::SetEndOfDirectory()
       
  1261 	{Mem::FillZ(&iData[0],KFatDirNameSize);}
       
  1262 
       
  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);}
       
  1266 
       
  1267 /** @return True is the Entry is a VFat entry  */
       
  1268 TBool TFatDirEntry::IsVFatEntry() const
       
  1269 	{return (TBool)(Attributes()==KVFatEntryAttribute && IsEndOfDirectory()==EFalse);}
       
  1270 
       
  1271 /** @return The number of following VFat entries */
       
  1272 TInt TFatDirEntry::NumFollowing() const
       
  1273 	{return (iData[0]&0x3F);}
       
  1274 
       
  1275 
       
  1276 TUint8 TFatDirEntry::CheckSum() const
       
  1277     {
       
  1278         ASSERT(IsVFatEntry());
       
  1279         return iData[13];
       
  1280     }
       
  1281 
       
  1282 
       
  1283 
       
  1284 
       
  1285 
       
  1286 
       
  1287 
       
  1288 
       
  1289 
       
  1290 
       
  1291 
       
  1292 
       
  1293 
       
  1294 
       
  1295 
       
  1296 
       
  1297 
       
  1298 
       
  1299 
       
  1300 
       
  1301