os/kernelhwsrv/userlibandfileserver/fileserver/sfat/sl_bpb.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32\sfat\sl_bpb.cpp
    15 // Boot sector code, specific for EFat.fsy
    16 // 
    17 //
    18 
    19 
    20 /**
    21  @file
    22  @internalTechnology
    23 */
    24 
    25 
    26 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    27 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    28 //!!
    29 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
    30 //!!
    31 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    32 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    33 
    34 #include "sl_std.h"
    35 
    36 //-------------------------------------------------------------------------------------------------------------------
    37 
    38 TFatBootSector::TFatBootSector()
    39     {
    40     Initialise();    
    41     }
    42 
    43 /** initialises the boot sector data */
    44 void TFatBootSector::Initialise()
    45     {
    46     Mem::FillZ(this, sizeof(TFatBootSector));
    47     }
    48 
    49 //-------------------------------------------------------------------------------------------------------------------
    50 
    51 /**
    52     @return ETrue if the boot sector contents seems to be valid
    53 */
    54 TBool TFatBootSector::IsValid() const
    55     {
    56     const TFatType fatType = FatType();
    57    
    58     
    59     const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
    60     const TUint32 rootDirStartSec =  ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
    61 
    62     if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1 || FatSectors() < 1 || rootDirStartSec < 3 ||
    63        RootDirEntries() < 1 || totSectors < 5)
    64         goto Invalid;
    65 
    66     if(TotalSectors() >0 && HugeSectors() >0 )
    67         goto Invalid; //-- values clash
    68 
    69     return ETrue;
    70   
    71     Invalid:
    72         __PRINT(_L("TFatBootSector::IsValid() failed!"));
    73 
    74     return EFalse;
    75     }
    76 
    77 //-------------------------------------------------------------------------------------------------------------------
    78 
    79 /**
    80     Initialize boot sector object from the given bufer. Does not validate the data.
    81     @param  aBuf buffer with data.
    82 */
    83 void TFatBootSector::Internalize(const TDesC8& aBuf)
    84     {
    85     ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
    86 
    87     Initialise();
    88     
    89     TInt pos=0;
    90 
    91     Mem::Copy(&iJumpInstruction, &aBuf[pos],3);     pos+=3; // 0    TUint8 iJumpInstruction[3]
    92     Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3    TUint8 iVendorId[KVendorIdSize]
    93     Mem::Copy(&iBytesPerSector,&aBuf[pos],2);       pos+=2; // 11   TUint16 iBytesPerSector
    94     Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1);    pos+=1; // 13   TUint8 iSectorsPerCluster   
    95     Mem::Copy(&iReservedSectors,&aBuf[pos],2);      pos+=2; // 14   TUint16 iReservedSectors
    96     Mem::Copy(&iNumberOfFats,&aBuf[pos],1);         pos+=1; // 16   TUint8 iNumberOfFats
    97     Mem::Copy(&iRootDirEntries,&aBuf[pos],2);       pos+=2; // 17   TUint16 iRootDirEntries
    98     Mem::Copy(&iTotalSectors,&aBuf[pos],2);         pos+=2; // 19   TUint16 iTotalSectors
    99     Mem::Copy(&iMediaDescriptor,&aBuf[pos],1);      pos+=1; // 21   TUint8 iMediaDescriptor
   100     Mem::Copy(&iFatSectors,&aBuf[pos],2);           pos+=2; // 22   TUint16 iFatSectors
   101     Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2);      pos+=2; // 24   TUint16 iSectorsPerTrack
   102     Mem::Copy(&iNumberOfHeads,&aBuf[pos],2);        pos+=2; // 26   TUint16 iNumberOfHeads
   103     Mem::Copy(&iHiddenSectors,&aBuf[pos],4);        pos+=4; // 28   TUint32 iHiddenSectors
   104     Mem::Copy(&iHugeSectors,&aBuf[pos],4);          pos+=4; // 32   TUint32 iHugeSectors
   105     Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1);  pos+=1;// 36|64 TUint8 iPhysicalDriveNumber
   106     Mem::Copy(&iReserved,&aBuf[pos],1);             pos+=1;// 37|65 TUint8 iReserved
   107     Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature
   108     Mem::Copy(&iUniqueID,&aBuf[pos],4);             pos+=4;// 39|67 TUint32 iUniqueID
   109     Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize);  // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize]
   110     pos+=KVolumeLabelSize;
   111 
   112     // 54|82    TUint8 iFileSysType[KFileSysTypeSize]
   113     ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
   114     Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
   115     }
   116 
   117 //-------------------------------------------------------------------------------------------------------------------
   118 
   119 /**
   120     Externalize boot sector object to the given data buffer.
   121     @param  aBuf buffer to externalize.
   122 */
   123 void TFatBootSector::Externalize(TDes8& aBuf) const
   124     {
   125     ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
   126 
   127     if(aBuf.Size() < KSizeOfFatBootSector)
   128         aBuf.SetLength(KSizeOfFatBootSector);
   129 
   130     TInt pos=0;
   131 
   132     Mem::Copy(&aBuf[pos],&iJumpInstruction,3);      pos+=3;
   133     Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8;
   134     Mem::Copy(&aBuf[pos],&iBytesPerSector,2);       pos+=2;
   135     Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1);    pos+=1;
   136     Mem::Copy(&aBuf[pos],&iReservedSectors,2);      pos+=2;
   137     Mem::Copy(&aBuf[pos],&iNumberOfFats,1);         pos+=1;
   138     Mem::Copy(&aBuf[pos],&iRootDirEntries,2);       pos+=2;
   139     Mem::Copy(&aBuf[pos],&iTotalSectors,2);         pos+=2;
   140     Mem::Copy(&aBuf[pos],&iMediaDescriptor,1);      pos+=1;
   141     Mem::Copy(&aBuf[pos],&iFatSectors,2);           pos+=2;
   142     Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2);      pos+=2;
   143     Mem::Copy(&aBuf[pos],&iNumberOfHeads,2);        pos+=2;
   144     Mem::Copy(&aBuf[pos],&iHiddenSectors,4);        pos+=4;
   145     Mem::Copy(&aBuf[pos],&iHugeSectors,4);          pos+=4;
   146     Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1);  pos+=1;
   147     Mem::FillZ(&aBuf[pos],1);                       pos+=1;
   148     Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1;
   149     Mem::Copy(&aBuf[pos],&iUniqueID,4);             pos+=4;
   150     
   151     Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize); 
   152     pos+=KVolumeLabelSize;
   153     
   154     ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
   155     Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
   156     }
   157 
   158 //-------------------------------------------------------------------------------------------------------------------
   159 
   160 #ifdef _DEBUG
   161 /** replaces all non-printable characters in a buffer with spaces */
   162 static void FixDes(TDes& aDes)
   163 {
   164     for(TInt i=0; i< aDes.Length(); ++i)
   165     {
   166         TChar ch=aDes[i];
   167         if(!ch.IsPrint())
   168             aDes[i]=' ';    
   169     }
   170 }
   171 #endif
   172 
   173 /** 
   174     Print out the boot sector info.
   175 */
   176 void TFatBootSector::PrintDebugInfo() const
   177     {
   178 #ifdef _DEBUG
   179     __PRINT(_L("\n======== BootSector info: =======\n"));
   180     
   181     TBuf<40> buf;
   182     buf.Copy(FileSysType()); FixDes(buf);    
   183     __PRINT1(_L("FAT type:%S"), &buf);
   184 
   185     buf.Copy(VendorId()); FixDes(buf);    
   186     __PRINT1(_L("Vendor ID:%S"), &buf);
   187 
   188     __PRINT1(_L("BytesPerSector:%d"),BytesPerSector());
   189     __PRINT1(_L("SectorsPerCluster:%d"),SectorsPerCluster());
   190     __PRINT1(_L("ReservedSectors:%d"),ReservedSectors());
   191     __PRINT1(_L("NumberOfFats:%d"),NumberOfFats());
   192     __PRINT1(_L("RootDirEntries:%d"),RootDirEntries());
   193     __PRINT1(_L("Total Sectors:%d"),TotalSectors());
   194     __PRINT1(_L("MediaDescriptor:0x%x"),MediaDescriptor());
   195     __PRINT1(_L("FatSectors:%d"),FatSectors());
   196     __PRINT1(_L("SectorsPerTrack:%d"),SectorsPerTrack());
   197     __PRINT1(_L("NumberOfHeads:%d"),NumberOfHeads());
   198     __PRINT1(_L("HugeSectors:%d"),HugeSectors());
   199     __PRINT1(_L("Root Cluster Number:%d"),RootClusterNum());
   200     __PRINT1(_L("FSInfo Sector Number:%d"),FSInfoSectorNum());
   201     __PRINT1(_L("Backup Boot Rec Sector Number:%d"),BkBootRecSector());
   202     __PRINT1(_L("PhysicalDriveNumber:%d"),PhysicalDriveNumber());
   203     __PRINT1(_L("ExtendedBootSignature:%d"),ExtendedBootSignature());
   204     __PRINT1(_L("UniqueID:0x%x"),UniqueID());
   205     
   206     buf.Copy(VolumeLabel()); FixDes(buf);    
   207     __PRINT1(_L("VolumeLabel:%S"), &buf);
   208     
   209     __PRINT(_L("=============================\n"));
   210 #endif
   211 
   212     }
   213 
   214 //-------------------------------------------------------------------------------------------------------------------
   215 
   216 /**
   217     Determine FAT type according to the information from boot sector, see FAT32 specs.
   218     @return  FAT type. 
   219 */
   220 TFatType TFatBootSector::FatType(void) const
   221     {
   222     //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
   223     if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 ||  iBytesPerSector > 4096)
   224         return EInvalid; //-- invalid iBytesPerSector value
   225 
   226     //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
   227     if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128)
   228         return EInvalid; //-- invalid iSectorsPerCluster value
   229 
   230 
   231     const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
   232     const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors;
   233     const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * iFatSectors) + rootDirSectors);
   234     const TUint32 clusterCnt = dataSec / iSectorsPerCluster;
   235 
   236     //-- magic. see FAT specs for details.
   237     if(clusterCnt < 4085)
   238         return EFat12;
   239     else if(clusterCnt < 65525)
   240         return EFat16;
   241     else
   242         return EInvalid; //-- FAT32 is not supported by this fsy
   243     }
   244 
   245 //-------------------------------------------------------------------------------------------------------------------
   246 
   247 /** @return The first Fat sector number */
   248 TInt TFatBootSector::FirstFatSector() const
   249     {
   250     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
   251     return ReservedSectors();
   252     }
   253 
   254 /**
   255     @return Number of sectors in root directory. 0 for FAT32
   256 */
   257 TUint32 TFatBootSector::RootDirSectors() const
   258     {
   259     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
   260     return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
   261     }
   262 
   263 
   264 /** @return Start sector number of the root directory */
   265 TInt TFatBootSector::RootDirStartSector()  const
   266     {
   267     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
   268 
   269     //-- FAT12/16 root dir starts just after the FATs
   270     return ReservedSectors() + TotalFatSectors()*NumberOfFats();
   271     }
   272 
   273 
   274 /** @return first data sector number. for FAT32 it includes the root directory */
   275 TInt TFatBootSector::FirstDataSector() const
   276     {
   277     return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
   278     }
   279 
   280 /** @return FAT-type independent sector count on the volume */
   281 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
   282     {
   283     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
   284     return TotalSectors() >0 ? (TUint32)TotalSectors() : (TUint32)HugeSectors();
   285     }
   286 
   287 /** @return FAT-type independent number of sectors in one FAT */
   288 TUint32 TFatBootSector::TotalFatSectors() const
   289     {
   290     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
   291     return (TUint32)FatSectors();
   292     }
   293 
   294 
   295 
   296 
   297 
   298 
   299 
   300 
   301 
   302 
   303 
   304 
   305 
   306 
   307 
   308 
   309 
   310 
   311 
   312 
   313 
   314