1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfat/sl_bpb.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,314 @@
1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\sfat\sl_bpb.cpp
1.18 +// Boot sector code, specific for EFat.fsy
1.19 +//
1.20 +//
1.21 +
1.22 +
1.23 +/**
1.24 + @file
1.25 + @internalTechnology
1.26 +*/
1.27 +
1.28 +
1.29 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.30 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.31 +//!!
1.32 +//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
1.33 +//!!
1.34 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.35 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.36 +
1.37 +#include "sl_std.h"
1.38 +
1.39 +//-------------------------------------------------------------------------------------------------------------------
1.40 +
1.41 +TFatBootSector::TFatBootSector()
1.42 + {
1.43 + Initialise();
1.44 + }
1.45 +
1.46 +/** initialises the boot sector data */
1.47 +void TFatBootSector::Initialise()
1.48 + {
1.49 + Mem::FillZ(this, sizeof(TFatBootSector));
1.50 + }
1.51 +
1.52 +//-------------------------------------------------------------------------------------------------------------------
1.53 +
1.54 +/**
1.55 + @return ETrue if the boot sector contents seems to be valid
1.56 +*/
1.57 +TBool TFatBootSector::IsValid() const
1.58 + {
1.59 + const TFatType fatType = FatType();
1.60 +
1.61 +
1.62 + const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
1.63 + const TUint32 rootDirStartSec = ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
1.64 +
1.65 + if(fatType == EInvalid || ReservedSectors() < 1 || NumberOfFats() < 1 || FatSectors() < 1 || rootDirStartSec < 3 ||
1.66 + RootDirEntries() < 1 || totSectors < 5)
1.67 + goto Invalid;
1.68 +
1.69 + if(TotalSectors() >0 && HugeSectors() >0 )
1.70 + goto Invalid; //-- values clash
1.71 +
1.72 + return ETrue;
1.73 +
1.74 + Invalid:
1.75 + __PRINT(_L("TFatBootSector::IsValid() failed!"));
1.76 +
1.77 + return EFalse;
1.78 + }
1.79 +
1.80 +//-------------------------------------------------------------------------------------------------------------------
1.81 +
1.82 +/**
1.83 + Initialize boot sector object from the given bufer. Does not validate the data.
1.84 + @param aBuf buffer with data.
1.85 +*/
1.86 +void TFatBootSector::Internalize(const TDesC8& aBuf)
1.87 + {
1.88 + ASSERT(aBuf.Size() >= KSizeOfFatBootSector);
1.89 +
1.90 + Initialise();
1.91 +
1.92 + TInt pos=0;
1.93 +
1.94 + Mem::Copy(&iJumpInstruction, &aBuf[pos],3); pos+=3; // 0 TUint8 iJumpInstruction[3]
1.95 + Mem::Copy(&iVendorId,&aBuf[pos],KVendorIdSize); pos+=KVendorIdSize; // 3 TUint8 iVendorId[KVendorIdSize]
1.96 + Mem::Copy(&iBytesPerSector,&aBuf[pos],2); pos+=2; // 11 TUint16 iBytesPerSector
1.97 + Mem::Copy(&iSectorsPerCluster,&aBuf[pos],1); pos+=1; // 13 TUint8 iSectorsPerCluster
1.98 + Mem::Copy(&iReservedSectors,&aBuf[pos],2); pos+=2; // 14 TUint16 iReservedSectors
1.99 + Mem::Copy(&iNumberOfFats,&aBuf[pos],1); pos+=1; // 16 TUint8 iNumberOfFats
1.100 + Mem::Copy(&iRootDirEntries,&aBuf[pos],2); pos+=2; // 17 TUint16 iRootDirEntries
1.101 + Mem::Copy(&iTotalSectors,&aBuf[pos],2); pos+=2; // 19 TUint16 iTotalSectors
1.102 + Mem::Copy(&iMediaDescriptor,&aBuf[pos],1); pos+=1; // 21 TUint8 iMediaDescriptor
1.103 + Mem::Copy(&iFatSectors,&aBuf[pos],2); pos+=2; // 22 TUint16 iFatSectors
1.104 + Mem::Copy(&iSectorsPerTrack,&aBuf[pos],2); pos+=2; // 24 TUint16 iSectorsPerTrack
1.105 + Mem::Copy(&iNumberOfHeads,&aBuf[pos],2); pos+=2; // 26 TUint16 iNumberOfHeads
1.106 + Mem::Copy(&iHiddenSectors,&aBuf[pos],4); pos+=4; // 28 TUint32 iHiddenSectors
1.107 + Mem::Copy(&iHugeSectors,&aBuf[pos],4); pos+=4; // 32 TUint32 iHugeSectors
1.108 + Mem::Copy(&iPhysicalDriveNumber,&aBuf[pos],1); pos+=1;// 36|64 TUint8 iPhysicalDriveNumber
1.109 + Mem::Copy(&iReserved,&aBuf[pos],1); pos+=1;// 37|65 TUint8 iReserved
1.110 + Mem::Copy(&iExtendedBootSignature,&aBuf[pos],1);pos+=1;// 38|66 TUint8 iExtendedBootSignature
1.111 + Mem::Copy(&iUniqueID,&aBuf[pos],4); pos+=4;// 39|67 TUint32 iUniqueID
1.112 + Mem::Copy(&iVolumeLabel,&aBuf[pos],KVolumeLabelSize); // 43|71 TUint8 iVolumeLabel[KVolumeLabelSize]
1.113 + pos+=KVolumeLabelSize;
1.114 +
1.115 + // 54|82 TUint8 iFileSysType[KFileSysTypeSize]
1.116 + ASSERT(aBuf.Size() >= pos+KFileSysTypeSize);
1.117 + Mem::Copy(&iFileSysType,&aBuf[pos],KFileSysTypeSize);
1.118 + }
1.119 +
1.120 +//-------------------------------------------------------------------------------------------------------------------
1.121 +
1.122 +/**
1.123 + Externalize boot sector object to the given data buffer.
1.124 + @param aBuf buffer to externalize.
1.125 +*/
1.126 +void TFatBootSector::Externalize(TDes8& aBuf) const
1.127 + {
1.128 + ASSERT(aBuf.MaxSize() >= KSizeOfFatBootSector);
1.129 +
1.130 + if(aBuf.Size() < KSizeOfFatBootSector)
1.131 + aBuf.SetLength(KSizeOfFatBootSector);
1.132 +
1.133 + TInt pos=0;
1.134 +
1.135 + Mem::Copy(&aBuf[pos],&iJumpInstruction,3); pos+=3;
1.136 + Mem::Copy(&aBuf[pos],&iVendorId,KVendorIdSize); pos+=8;
1.137 + Mem::Copy(&aBuf[pos],&iBytesPerSector,2); pos+=2;
1.138 + Mem::Copy(&aBuf[pos],&iSectorsPerCluster,1); pos+=1;
1.139 + Mem::Copy(&aBuf[pos],&iReservedSectors,2); pos+=2;
1.140 + Mem::Copy(&aBuf[pos],&iNumberOfFats,1); pos+=1;
1.141 + Mem::Copy(&aBuf[pos],&iRootDirEntries,2); pos+=2;
1.142 + Mem::Copy(&aBuf[pos],&iTotalSectors,2); pos+=2;
1.143 + Mem::Copy(&aBuf[pos],&iMediaDescriptor,1); pos+=1;
1.144 + Mem::Copy(&aBuf[pos],&iFatSectors,2); pos+=2;
1.145 + Mem::Copy(&aBuf[pos],&iSectorsPerTrack,2); pos+=2;
1.146 + Mem::Copy(&aBuf[pos],&iNumberOfHeads,2); pos+=2;
1.147 + Mem::Copy(&aBuf[pos],&iHiddenSectors,4); pos+=4;
1.148 + Mem::Copy(&aBuf[pos],&iHugeSectors,4); pos+=4;
1.149 + Mem::Copy(&aBuf[pos],&iPhysicalDriveNumber,1); pos+=1;
1.150 + Mem::FillZ(&aBuf[pos],1); pos+=1;
1.151 + Mem::Copy(&aBuf[pos],&iExtendedBootSignature,1);pos+=1;
1.152 + Mem::Copy(&aBuf[pos],&iUniqueID,4); pos+=4;
1.153 +
1.154 + Mem::Copy(&aBuf[pos],&iVolumeLabel,KVolumeLabelSize);
1.155 + pos+=KVolumeLabelSize;
1.156 +
1.157 + ASSERT(aBuf.MaxSize() >= pos+KFileSysTypeSize);
1.158 + Mem::Copy(&aBuf[pos],&iFileSysType,KFileSysTypeSize);
1.159 + }
1.160 +
1.161 +//-------------------------------------------------------------------------------------------------------------------
1.162 +
1.163 +#ifdef _DEBUG
1.164 +/** replaces all non-printable characters in a buffer with spaces */
1.165 +static void FixDes(TDes& aDes)
1.166 +{
1.167 + for(TInt i=0; i< aDes.Length(); ++i)
1.168 + {
1.169 + TChar ch=aDes[i];
1.170 + if(!ch.IsPrint())
1.171 + aDes[i]=' ';
1.172 + }
1.173 +}
1.174 +#endif
1.175 +
1.176 +/**
1.177 + Print out the boot sector info.
1.178 +*/
1.179 +void TFatBootSector::PrintDebugInfo() const
1.180 + {
1.181 +#ifdef _DEBUG
1.182 + __PRINT(_L("\n======== BootSector info: =======\n"));
1.183 +
1.184 + TBuf<40> buf;
1.185 + buf.Copy(FileSysType()); FixDes(buf);
1.186 + __PRINT1(_L("FAT type:%S"), &buf);
1.187 +
1.188 + buf.Copy(VendorId()); FixDes(buf);
1.189 + __PRINT1(_L("Vendor ID:%S"), &buf);
1.190 +
1.191 + __PRINT1(_L("BytesPerSector:%d"),BytesPerSector());
1.192 + __PRINT1(_L("SectorsPerCluster:%d"),SectorsPerCluster());
1.193 + __PRINT1(_L("ReservedSectors:%d"),ReservedSectors());
1.194 + __PRINT1(_L("NumberOfFats:%d"),NumberOfFats());
1.195 + __PRINT1(_L("RootDirEntries:%d"),RootDirEntries());
1.196 + __PRINT1(_L("Total Sectors:%d"),TotalSectors());
1.197 + __PRINT1(_L("MediaDescriptor:0x%x"),MediaDescriptor());
1.198 + __PRINT1(_L("FatSectors:%d"),FatSectors());
1.199 + __PRINT1(_L("SectorsPerTrack:%d"),SectorsPerTrack());
1.200 + __PRINT1(_L("NumberOfHeads:%d"),NumberOfHeads());
1.201 + __PRINT1(_L("HugeSectors:%d"),HugeSectors());
1.202 + __PRINT1(_L("Root Cluster Number:%d"),RootClusterNum());
1.203 + __PRINT1(_L("FSInfo Sector Number:%d"),FSInfoSectorNum());
1.204 + __PRINT1(_L("Backup Boot Rec Sector Number:%d"),BkBootRecSector());
1.205 + __PRINT1(_L("PhysicalDriveNumber:%d"),PhysicalDriveNumber());
1.206 + __PRINT1(_L("ExtendedBootSignature:%d"),ExtendedBootSignature());
1.207 + __PRINT1(_L("UniqueID:0x%x"),UniqueID());
1.208 +
1.209 + buf.Copy(VolumeLabel()); FixDes(buf);
1.210 + __PRINT1(_L("VolumeLabel:%S"), &buf);
1.211 +
1.212 + __PRINT(_L("=============================\n"));
1.213 +#endif
1.214 +
1.215 + }
1.216 +
1.217 +//-------------------------------------------------------------------------------------------------------------------
1.218 +
1.219 +/**
1.220 + Determine FAT type according to the information from boot sector, see FAT32 specs.
1.221 + @return FAT type.
1.222 +*/
1.223 +TFatType TFatBootSector::FatType(void) const
1.224 + {
1.225 + //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
1.226 + if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 || iBytesPerSector > 4096)
1.227 + return EInvalid; //-- invalid iBytesPerSector value
1.228 +
1.229 + //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
1.230 + if(!IsPowerOf2(iSectorsPerCluster) || iSectorsPerCluster > 128)
1.231 + return EInvalid; //-- invalid iSectorsPerCluster value
1.232 +
1.233 +
1.234 + const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
1.235 + const TUint32 totSec = iTotalSectors ? iTotalSectors : iHugeSectors;
1.236 + const TUint32 dataSec = totSec - (iReservedSectors + (iNumberOfFats * iFatSectors) + rootDirSectors);
1.237 + const TUint32 clusterCnt = dataSec / iSectorsPerCluster;
1.238 +
1.239 + //-- magic. see FAT specs for details.
1.240 + if(clusterCnt < 4085)
1.241 + return EFat12;
1.242 + else if(clusterCnt < 65525)
1.243 + return EFat16;
1.244 + else
1.245 + return EInvalid; //-- FAT32 is not supported by this fsy
1.246 + }
1.247 +
1.248 +//-------------------------------------------------------------------------------------------------------------------
1.249 +
1.250 +/** @return The first Fat sector number */
1.251 +TInt TFatBootSector::FirstFatSector() const
1.252 + {
1.253 + __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
1.254 + return ReservedSectors();
1.255 + }
1.256 +
1.257 +/**
1.258 + @return Number of sectors in root directory. 0 for FAT32
1.259 +*/
1.260 +TUint32 TFatBootSector::RootDirSectors() const
1.261 + {
1.262 + __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
1.263 + return ( (RootDirEntries()*KSizeOfFatDirEntry + (BytesPerSector()-1)) / BytesPerSector() );
1.264 + }
1.265 +
1.266 +
1.267 +/** @return Start sector number of the root directory */
1.268 +TInt TFatBootSector::RootDirStartSector() const
1.269 + {
1.270 + __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
1.271 +
1.272 + //-- FAT12/16 root dir starts just after the FATs
1.273 + return ReservedSectors() + TotalFatSectors()*NumberOfFats();
1.274 + }
1.275 +
1.276 +
1.277 +/** @return first data sector number. for FAT32 it includes the root directory */
1.278 +TInt TFatBootSector::FirstDataSector() const
1.279 + {
1.280 + return( ReservedSectors() + NumberOfFats()*TotalFatSectors() + RootDirSectors() );
1.281 + }
1.282 +
1.283 +/** @return FAT-type independent sector count on the volume */
1.284 +TUint32 TFatBootSector::VolumeTotalSectorNumber() const
1.285 + {
1.286 + __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
1.287 + return TotalSectors() >0 ? (TUint32)TotalSectors() : (TUint32)HugeSectors();
1.288 + }
1.289 +
1.290 +/** @return FAT-type independent number of sectors in one FAT */
1.291 +TUint32 TFatBootSector::TotalFatSectors() const
1.292 + {
1.293 + __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
1.294 + return (TUint32)FatSectors();
1.295 + }
1.296 +
1.297 +
1.298 +
1.299 +
1.300 +
1.301 +
1.302 +
1.303 +
1.304 +
1.305 +
1.306 +
1.307 +
1.308 +
1.309 +
1.310 +
1.311 +
1.312 +
1.313 +
1.314 +
1.315 +
1.316 +
1.317 +