userlibandfileserver/fileserver/sfat32/sl_bpb32.cpp
changeset 0 a41df078684a
child 87 2f92ad2dc5db
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 // f32\sfat32\sl_bpb32.cpp
       
    15 // Boot sector code, specific for EFat32.fsy
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22 */
       
    23 
       
    24 #include "sl_std.h"
       
    25 
       
    26 
       
    27 //-------------------------------------------------------------------------------------------------------------------
       
    28 
       
    29 TFatBootSector::TFatBootSector()
       
    30 {
       
    31     Initialise();    
       
    32 }
       
    33 
       
    34 /** initialises the boot sector data */
       
    35 void TFatBootSector::Initialise()
       
    36 {
       
    37     Mem::FillZ(this, sizeof(TFatBootSector));
       
    38 }
       
    39 
       
    40 //-------------------------------------------------------------------------------------------------------------------
       
    41 
       
    42 /**
       
    43     @return ETrue if the boot sector contents seems to be valid
       
    44 */
       
    45 TBool TFatBootSector::IsValid() const
       
    46 {
       
    47     const TFatType fatType = FatType(); //-- it will check SectorsPerCluster etc.
       
    48 
       
    49     if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1)
       
    50         goto Invalid;
       
    51         
       
    52     if(fatType == EFat32)
       
    53     {
       
    54         if(VersionNumber()!= 0 || FatSectors()!=0 || FatSectors32()<1 || RootClusterNum()<KFatFirstSearchCluster ||
       
    55            TotalSectors()!=0 || HugeSectors() <5 || RootDirEntries() !=0)
       
    56         {
       
    57             goto Invalid; //-- these values are not compliant with FAT specs
       
    58         }
       
    59     }
       
    60     else //-- FAT12/16
       
    61     {
       
    62         if(TotalSectors() >0 && HugeSectors() >0 )
       
    63             goto Invalid; //-- values clash
       
    64 
       
    65         const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
       
    66         const TUint32 rootDirStartSec =  ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
       
    67 
       
    68         if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5)
       
    69             goto Invalid; //-- these values are not compliant with FAT specs
       
    70     }
       
    71 
       
    72     return ETrue;
       
    73   
       
    74   Invalid:
       
    75     __PRINT(_L("TFatBootSector::IsValid() failed!"));
       
    76 
       
    77     return EFalse;
       
    78 }
       
    79 
       
    80 //-------------------------------------------------------------------------------------------------------------------
       
    81 
       
    82 /**
       
    83     Initialize boot sector object from the given bufer. Does not validate the data.
       
    84     @param  aBuf buffer with data.
       
    85 */
       
    86 void TFatBootSector::Internalize(const TDesC8& aBuf)
       
    87 {
       
    88     ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
       
    89     
       
    90     Initialise();
       
    91     
       
    92     TInt pos=0;
       
    93 
       
    94     Mem::Copy(&iJumpInstruction, &aBuf[pos],3);     pos+=3; // 0    TUint8 iJumpInstruction[3]
       
    95     Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3    TUint8 iVendorId[KVendorIdSize]
       
    96     Mem::Copy(&iBytesPerSector,&aBuf[pos],2);       pos+=2; // 11   TUint16 iBytesPerSector
       
    97     Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1);    pos+=1; // 13   TUint8 iSectorsPerCluster   
       
    98     Mem::Copy(&iReservedSectors,&aBuf[pos],2);      pos+=2; // 14   TUint16 iReservedSectors
       
    99     Mem::Copy(&iNumberOfFats,&aBuf[pos],1);         pos+=1; // 16   TUint8 iNumberOfFats
       
   100     Mem::Copy(&iRootDirEntries,&aBuf[pos],2);       pos+=2; // 17   TUint16 iRootDirEntries
       
   101     Mem::Copy(&iTotalSectors,&aBuf[pos],2);         pos+=2; // 19   TUint16 iTotalSectors
       
   102     Mem::Copy(&iMediaDescriptor,&aBuf[pos],1);      pos+=1; // 21   TUint8 iMediaDescriptor
       
   103     Mem::Copy(&iFatSectors,&aBuf[pos],2);           pos+=2; // 22   TUint16 iFatSectors
       
   104     Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2);      pos+=2; // 24   TUint16 iSectorsPerTrack
       
   105     Mem::Copy(&iNumberOfHeads,&aBuf[pos],2);        pos+=2; // 26   TUint16 iNumberOfHeads
       
   106     Mem::Copy(&iHiddenSectors,&aBuf[pos],4);        pos+=4; // 28   TUint32 iHiddenSectors
       
   107     Mem::Copy(&iHugeSectors,&aBuf[pos],4);          pos+=4; // 32   TUint32 iHugeSectors
       
   108 
       
   109     if(RootDirEntries() == 0) //-- we have FAT32 volume
       
   110     {
       
   111         Mem::Copy(&iFatSectors32, &aBuf[pos],4);    pos+=4; // 36 TUint32 iFatSectors32     
       
   112         Mem::Copy(&iFATFlags, &aBuf[pos],2);        pos+=2; // 40 TUint16 iFATFlags
       
   113         Mem::Copy(&iVersionNumber, &aBuf[pos],2);   pos+=2; // 42 TUint16 iVersionNumber
       
   114         Mem::Copy(&iRootClusterNum, &aBuf[pos],4);  pos+=4; // 44 TUint32 iRootClusterNum
       
   115         Mem::Copy(&iFSInfoSectorNum, &aBuf[pos],2); pos+=2; // 48 TUint16 iFSInfoSectorNum
       
   116         Mem::Copy(&iBkBootRecSector, &aBuf[pos],2);         // 50 TUint16 iBkBootRecSector
       
   117         pos+=(2+12);    //extra 12 for the reserved bytes   
       
   118     }
       
   119 
       
   120     Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1);  pos+=1;// 36|64 TUint8 iPhysicalDriveNumber
       
   121     Mem::Copy(&iReserved,&aBuf[pos],1);             pos+=1;// 37|65 TUint8 iReserved
       
   122     Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature
       
   123     Mem::Copy(&iUniqueID,&aBuf[pos],4);             pos+=4;// 39|67 TUint32 iUniqueID
       
   124     Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize);  // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize]
       
   125     pos+=KVolumeLabelSize;
       
   126 
       
   127     // 54|82    TUint8 iFileSysType[KFileSysTypeSize]
       
   128     ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
       
   129     Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
       
   130 }
       
   131 
       
   132 //-------------------------------------------------------------------------------------------------------------------
       
   133 
       
   134 /**
       
   135     Externalize boot sector object to the given data buffer.
       
   136     @param  aBuf buffer to externalize.
       
   137 */
       
   138 void TFatBootSector::Externalize(TDes8& aBuf) const
       
   139 {
       
   140     ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
       
   141 
       
   142     if(aBuf.Size() < KSizeOfFatBootSector)
       
   143         aBuf.SetLength(KSizeOfFatBootSector);
       
   144     
       
   145     TInt pos=0;
       
   146 
       
   147     Mem::Copy(&aBuf[pos],&iJumpInstruction,3);      pos+=3;
       
   148     Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8;
       
   149     Mem::Copy(&aBuf[pos],&iBytesPerSector,2);       pos+=2;
       
   150     Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1);    pos+=1;
       
   151     Mem::Copy(&aBuf[pos],&iReservedSectors,2);      pos+=2;
       
   152     Mem::Copy(&aBuf[pos],&iNumberOfFats,1);         pos+=1;
       
   153     Mem::Copy(&aBuf[pos],&iRootDirEntries,2);       pos+=2;
       
   154     Mem::Copy(&aBuf[pos],&iTotalSectors,2);         pos+=2;
       
   155     Mem::Copy(&aBuf[pos],&iMediaDescriptor,1);      pos+=1;
       
   156     Mem::Copy(&aBuf[pos],&iFatSectors,2);           pos+=2;
       
   157     Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2);      pos+=2;
       
   158     Mem::Copy(&aBuf[pos],&iNumberOfHeads,2);        pos+=2;
       
   159     Mem::Copy(&aBuf[pos],&iHiddenSectors,4);        pos+=4;
       
   160     Mem::Copy(&aBuf[pos],&iHugeSectors,4);          pos+=4;
       
   161 
       
   162     if(iFatSectors == 0)    
       
   163         {
       
   164         Mem::Copy(&aBuf[pos], &iFatSectors32,4);    pos+=4;
       
   165         Mem::Copy(&aBuf[pos], &iFATFlags, 2);       pos+=2;
       
   166         Mem::Copy(&aBuf[pos], &iVersionNumber, 2);  pos+=2;
       
   167         Mem::Copy(&aBuf[pos], &iRootClusterNum, 4); pos+=4;
       
   168         Mem::Copy(&aBuf[pos], &iFSInfoSectorNum, 2);pos+=2;
       
   169         Mem::Copy(&aBuf[pos], &iBkBootRecSector, 2);pos+=2;
       
   170 
       
   171         //extra 12 for the reserved bytes   
       
   172         ASSERT(aBuf.Size() >= pos+12);
       
   173         Mem::FillZ(&aBuf[pos],12);
       
   174         pos+=12;
       
   175         }
       
   176 
       
   177     Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1);  pos+=1;
       
   178     Mem::FillZ(&aBuf[pos],1);                       pos+=1;
       
   179     Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1;
       
   180     Mem::Copy(&aBuf[pos],&iUniqueID,4);             pos+=4;
       
   181     
       
   182     Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize); 
       
   183     pos+=KVolumeLabelSize;
       
   184     
       
   185     ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
       
   186     Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
       
   187 }
       
   188 
       
   189 //-------------------------------------------------------------------------------------------------------------------
       
   190 
       
   191 #ifdef _DEBUG
       
   192 /** replaces all non-printable characters in a buffer with spaces */
       
   193 static void FixDes(TDes& aDes)
       
   194 {
       
   195     for(TInt i=0; i< aDes.Length(); ++i)
       
   196     {
       
   197         TChar ch=aDes[i];
       
   198         if(!ch.IsPrint())
       
   199             aDes[i]=' ';    
       
   200     }
       
   201 }
       
   202 #endif
       
   203 
       
   204 
       
   205 /** 
       
   206     Print out the boot sector info.
       
   207 */
       
   208 void TFatBootSector::PrintDebugInfo() const
       
   209 {
       
   210 #ifdef _DEBUG
       
   211     __PRINT(_L("\n"));
       
   212     __PRINT(_L("======== BootSector info: ======="));
       
   213 
       
   214     TBuf<40> buf;
       
   215     buf.Copy(FileSysType()); FixDes(buf);    
       
   216     __PRINT1(_L("FAT type:%S"), &buf);
       
   217 
       
   218     buf.Copy(VendorId()); FixDes(buf);    
       
   219     __PRINT1(_L("Vendor ID:%S"), &buf);
       
   220 
       
   221     __PRINT1(_L("BytesPerSector:%d"),BytesPerSector());
       
   222     __PRINT1(_L("SectorsPerCluster:%d"),SectorsPerCluster());
       
   223     __PRINT1(_L("ReservedSectors:%d"),ReservedSectors());
       
   224     __PRINT1(_L("NumberOfFats:%d"),NumberOfFats());
       
   225     __PRINT1(_L("RootDirEntries:%d"),RootDirEntries());
       
   226     __PRINT1(_L("Total Sectors:%d"),TotalSectors());
       
   227     __PRINT1(_L("MediaDescriptor:0x%x"),MediaDescriptor());
       
   228     __PRINT1(_L("FatSectors:%d"),FatSectors());
       
   229     __PRINT1(_L("SectorsPerTrack:%d"),SectorsPerTrack());
       
   230     __PRINT1(_L("NumberOfHeads:%d"),NumberOfHeads());
       
   231     __PRINT1(_L("HugeSectors:%d"),HugeSectors());
       
   232     __PRINT1(_L("Fat32 Sectors:%d"),FatSectors32());
       
   233     __PRINT1(_L("Fat32 Flags:%d"),FATFlags());
       
   234     __PRINT1(_L("Fat32 Version Number:%d"),VersionNumber());
       
   235     __PRINT1(_L("Root Cluster Number:%d"),RootClusterNum());
       
   236     __PRINT1(_L("FSInfo Sector Number:%d"),FSInfoSectorNum());
       
   237     __PRINT1(_L("Backup Boot Rec Sector Number:%d"),BkBootRecSector());
       
   238     __PRINT1(_L("PhysicalDriveNumber:%d"),PhysicalDriveNumber());
       
   239     __PRINT1(_L("ExtendedBootSignature:%d"),ExtendedBootSignature());
       
   240     __PRINT1(_L("UniqueID:0x%x"),UniqueID());
       
   241     
       
   242     buf.Copy(VolumeLabel()); FixDes(buf);    
       
   243     __PRINT1(_L("VolumeLabel:%S"), &buf);
       
   244 
       
   245     __PRINT(_L("=============================\n"));
       
   246 #endif
       
   247 }
       
   248 
       
   249 //-------------------------------------------------------------------------------------------------------------------
       
   250 
       
   251 /**
       
   252     Determine FAT type according to the information from boot sector, see FAT32 specs.
       
   253     @return  FAT type. 
       
   254 */
       
   255 TFatType TFatBootSector::FatType(void) const
       
   256     {
       
   257 
       
   258     //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
       
   259     if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 ||  iBytesPerSector > 4096)
       
   260         return EInvalid; //-- invalid iBytesPerSector value
       
   261 
       
   262     //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
       
   263     if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128)
       
   264         return EInvalid; //-- invalid iSectorsPerCluster value
       
   265 
       
   266     const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
       
   267     const TUint32 fatSz = iFatSectors ? iFatSectors : iFatSectors32;
       
   268     const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors;
       
   269     const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * fatSz) + rootDirSectors);
       
   270     const TUint32 clusterCnt = dataSec / iSectorsPerCluster;
       
   271 
       
   272     //-- magic. see FAT specs for details.
       
   273     if(clusterCnt < 4085)
       
   274         return EFat12;
       
   275     else if(clusterCnt < 65525)
       
   276         return EFat16;
       
   277     else
       
   278         return EFat32;
       
   279 
       
   280     }
       
   281 
       
   282 
       
   283 
       
   284 /** @return The first Fat sector number */
       
   285 TInt TFatBootSector::FirstFatSector() const
       
   286 {
       
   287     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
       
   288     return ReservedSectors();
       
   289 }
       
   290 
       
   291 /**
       
   292     @return Number of sectors in root directory. 0 for FAT32
       
   293 */
       
   294 TUint32 TFatBootSector::RootDirSectors() const
       
   295 {
       
   296     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
       
   297     return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
       
   298 }
       
   299 
       
   300 
       
   301 /** @return Start sector number of the root directory */
       
   302 TInt TFatBootSector::RootDirStartSector()  const
       
   303 {
       
   304     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
       
   305 
       
   306     const TUint32 firstNonFatSec = ReservedSectors() + TotalFatSectors()*NumberOfFats();
       
   307 
       
   308     if(FatType() == EFat32)
       
   309     {//-- FAT32 root dir is a file, calculate the position by it's 1st cluster number. FAT[0]+FAT[1] are reserved.
       
   310         return (firstNonFatSec + (RootClusterNum()-KFatFirstSearchCluster) * SectorsPerCluster());
       
   311     }
       
   312     else
       
   313     {//-- FAT12/16 root dir starts just after the FATs
       
   314         return firstNonFatSec;
       
   315     }
       
   316 }
       
   317 
       
   318 
       
   319 /** @return first data sector number. for FAT32 it includes the root directory */
       
   320 TInt TFatBootSector::FirstDataSector() const
       
   321 {
       
   322     return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
       
   323 }
       
   324 
       
   325 /** @return FAT-type independent sector count on the volume */
       
   326 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
       
   327 {
       
   328     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
       
   329     return TotalSectors() >0 ? (TUint32)TotalSectors() : (TUint32)HugeSectors();
       
   330 }
       
   331 
       
   332 /** @return FAT-type independent number of sectors in one FAT */
       
   333 TUint32 TFatBootSector::TotalFatSectors() const
       
   334 {
       
   335     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
       
   336     return FatSectors() >0 ? (TUint32)FatSectors() : FatSectors32();
       
   337 }
       
   338 
       
   339 
       
   340 
       
   341 
       
   342 //-------------------------------------------------------------------------------------------------------------------
       
   343 
       
   344 const TUint32   KLeadSignature      = 0x41615252; ///< FSInfo Lead signiture value
       
   345 const TUint32   KStructureSignature = 0x61417272; ///< FSInfo Structure signiture value
       
   346 const TUint32   KTrailingSignature  = 0xAA550000; ///< FSInfo Trailing signiture
       
   347 
       
   348 TFSInfo::TFSInfo()
       
   349 {
       
   350     Initialise();
       
   351 }
       
   352 //-------------------------------------------------------------------------------------------------------------------
       
   353 
       
   354 /** Initialise the data */
       
   355 void TFSInfo::Initialise()  
       
   356 {
       
   357     Mem::FillZ(this, sizeof(TFSInfo));
       
   358 
       
   359     iLeadSig      = KLeadSignature; 
       
   360     iStructureSig = KStructureSignature;
       
   361     iTrainlingSig = KTrailingSignature;
       
   362 }
       
   363 
       
   364 //-------------------------------------------------------------------------------------------------------------------
       
   365 
       
   366 /**
       
   367     @return ETrue if FSInfo sector contents seems to be valid
       
   368 */
       
   369 TBool TFSInfo::IsValid() const
       
   370 {
       
   371     return (iLeadSig == KLeadSignature && iStructureSig == KStructureSignature && iTrainlingSig == KTrailingSignature);
       
   372 }
       
   373 
       
   374 //-------------------------------------------------------------------------------------------------------------------
       
   375 
       
   376 /**
       
   377     Initialize FSInfo sector object from the given bufer. Does not validate the data.
       
   378     @param  aBuf buffer with data.
       
   379 */
       
   380 void TFSInfo::Internalize(const TDesC8& aBuf)
       
   381 {
       
   382     ASSERT((TUint32)aBuf.Size() >= KSizeOfFSInfo);
       
   383 
       
   384     TInt pos=0;
       
   385 
       
   386     Mem::Copy(&iLeadSig, &aBuf[pos],4);      pos+=(KFSInfoReserved1Size+4);
       
   387     Mem::Copy(&iStructureSig, &aBuf[pos],4); pos+=4;
       
   388     Mem::Copy(&iFreeCount,&aBuf[pos],4);     pos+=4;
       
   389     Mem::Copy(&iNextFree,&aBuf[pos],4);      pos+=(4+KFSInfoReserved2Size);
       
   390     Mem::Copy(&iTrainlingSig,&aBuf[pos],4);
       
   391 }
       
   392 
       
   393 //-------------------------------------------------------------------------------------------------------------------
       
   394 
       
   395 /**
       
   396     Externalize FSInfo sector object to the given data buffer.
       
   397     @param  aBuf buffer to externalize.
       
   398 */
       
   399 void TFSInfo::Externalize(TDes8& aBuf) const
       
   400 {
       
   401     ASSERT((TUint32)aBuf.MaxSize() >= KSizeOfFSInfo);
       
   402     
       
   403     aBuf.SetLength(KSizeOfFSInfo);
       
   404     aBuf.FillZ();
       
   405     
       
   406     TInt pos=0;
       
   407 
       
   408     Mem::Copy(&aBuf[pos],&KLeadSignature,4);        pos+=4; 
       
   409                                                     pos+=KFSInfoReserved1Size;
       
   410     Mem::Copy(&aBuf[pos],&KStructureSignature,4);   pos+=4;
       
   411     Mem::Copy(&aBuf[pos],&iFreeCount,4);            pos+=4;
       
   412     Mem::Copy(&aBuf[pos],&iNextFree,4);             pos+=4;
       
   413                                                     pos+=KFSInfoReserved2Size;
       
   414     Mem::Copy(&aBuf[pos],&KTrailingSignature,4);
       
   415 }
       
   416 
       
   417 //-------------------------------------------------------------------------------------------------------------------
       
   418 
       
   419 /** 
       
   420     Print out the FSInfo sector info.
       
   421 */
       
   422 void TFSInfo::PrintDebugInfo() const
       
   423 {
       
   424     __PRINT(_L("\n==== FSInfoSector : ===="));
       
   425     __PRINT1(_L("FSI_LeadSig:   0x%x"),iLeadSig);
       
   426     __PRINT1(_L("FSI_StrucSig:  0x%x"),iStructureSig);
       
   427     __PRINT1(_L("FSI_FreeCount: 0x%x"),iFreeCount);
       
   428     __PRINT1(_L("FSI_NxtFree:   0x%x"),iNextFree);
       
   429     __PRINT1(_L("FSI_TrailSig:  0x%x"),iTrainlingSig);
       
   430     __PRINT(_L("========================\n"));
       
   431 }
       
   432 
       
   433 
       
   434 
       
   435