imgtools/imglib/filesystem/source/fat16filesystem.cpp
changeset 0 044383f39525
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * CFat16FileSystem is the concrete class which is responsible for 
       
    16 * creating a FAT16 image. This class constitutes the method to 
       
    17 * create boot sector, FAT Table and data region of a FAT16 Image
       
    18 * @internalComponent
       
    19 * @released
       
    20 *
       
    21 */
       
    22 
       
    23 #include"fat16filesystem.h"
       
    24 
       
    25 
       
    26 /**
       
    27 Initializes the boot sector of a FAT 16 volume
       
    28 
       
    29 @internalComponent
       
    30 @released
       
    31 
       
    32 @param aPartitionSize partition size in bytes
       
    33 @param aConfigurableFatAttributes ConfigurableFatAttributes
       
    34 */
       
    35 void CFat16FileSystem::CreateBootSector(Long64 aPartitionSize,ConfigurableFatAttributes* aConfigurableFatAttributes)
       
    36 {
       
    37  	iFAT16BootSector.SetOEMName();
       
    38 	unsigned char* OEMName = iFAT16BootSector.OEMName();
       
    39 	iFAT16BootSector.SetJumpInstruction();
       
    40 	unsigned char* JmpBoot = iFAT16BootSector.JumpInstruction();
       
    41 	iFAT16BootSector.SetBytesPerSector(aConfigurableFatAttributes->iDriveSectorSize);
       
    42 	unsigned short BytesPerSector = (unsigned short)iFAT16BootSector.BytesPerSector();
       
    43 	iFAT16BootSector.ComputeSectorsPerCluster(aPartitionSize);
       
    44 	unsigned char SectorsPerCluster = iFAT16BootSector.SectorsPerCluster();
       
    45 	iFAT16BootSector.SetReservedSectors();
       
    46 	unsigned short ReservedSectors = iFAT16BootSector.ReservedSectors();
       
    47 	iFAT16BootSector.SetNumberOfFats(aConfigurableFatAttributes->iDriveNoOfFATs);
       
    48 	unsigned char NumFats = iFAT16BootSector.NumberOfFats();
       
    49 	iFAT16BootSector.SetRootDirEntries();
       
    50 	unsigned short RootDirEntries = iFAT16BootSector.RootDirEntries();
       
    51 	iFAT16BootSector.ComputeTotalSectors(aPartitionSize);
       
    52 	unsigned short LowSectors = iFAT16BootSector.LowSectorsCount();
       
    53 	iFAT16BootSector.SetMedia();
       
    54 	unsigned char Media = iFAT16BootSector.Media();
       
    55 	iFAT16BootSector.ComputeFatSectors(aPartitionSize);
       
    56 	unsigned short FatSectors = iFAT16BootSector.FatSectors();
       
    57 	iFAT16BootSector.SetSectorsPerTrack();
       
    58 	unsigned short SectorPerTrack = iFAT16BootSector.SectorsPerTrack();
       
    59 	iFAT16BootSector.SetNumberOfHeads();
       
    60 	unsigned short NumberOfHeads = iFAT16BootSector.NumberOfHeads();
       
    61 	iFAT16BootSector.SetHiddenSectors();
       
    62 	unsigned int HiddenSectors = iFAT16BootSector.HiddenSectors();
       
    63 	unsigned int HighSectorsCount = iFAT16BootSector.HighSectorsCount();
       
    64 	iFAT16BootSector.SetBootSectorDriveNumber();
       
    65 	unsigned char BootSectorDriveNumber = iFAT16BootSector.BootSectorDriveNumber();
       
    66 	iFAT16BootSector.SetReservedByte();
       
    67 	unsigned char ReservedByte = iFAT16BootSector.ReservedByte();
       
    68 	iFAT16BootSector.SetBootSignature();
       
    69 	unsigned char BootSignature = iFAT16BootSector.BootSignature();
       
    70 	iFAT16BootSector.SetVolumeId();
       
    71 	unsigned int VolumeId = iFAT16BootSector.VolumeId();
       
    72 	iFAT16BootSector.SetVolumeLab(aConfigurableFatAttributes->iDriveVolumeLabel);
       
    73 	unsigned char* VolumeLab = iFAT16BootSector.VolumeLab();
       
    74 	iFAT16BootSector.SetFileSysType();
       
    75 	unsigned char* FileSysType = iFAT16BootSector.FileSysType();
       
    76 	//copying of boot sector values in to the array
       
    77 	iData = new unsigned char[BytesPerSector];
       
    78 	unsigned int pos = 0;
       
    79 	memcpy(&iData[pos],JmpBoot,3);
       
    80 	pos += 3;
       
    81 	memcpy(&iData[pos],OEMName,8);
       
    82 	pos += 8;
       
    83 	memcpy(&iData[pos],&BytesPerSector,2);
       
    84 	pos += 2;
       
    85 	memcpy(&iData[pos],&SectorsPerCluster,1);
       
    86 	pos += 1;
       
    87 	memcpy(&iData[pos],&ReservedSectors,2);
       
    88 	pos += 2;
       
    89 	memcpy(&iData[pos],&NumFats,1);
       
    90 	pos += 1;
       
    91 	memcpy(&iData[pos],&RootDirEntries,2);
       
    92 	pos += 2;
       
    93 	memcpy(&iData[pos],&LowSectors,2);
       
    94 	pos += 2;
       
    95 	memcpy(&iData[pos],&Media,1);
       
    96 	pos += 1;
       
    97 	memcpy(&iData[pos],&FatSectors,2);
       
    98 	pos += 2;
       
    99 	memcpy(&iData[pos],&SectorPerTrack,2);
       
   100 	pos += 2;
       
   101 	memcpy(&iData[pos],&NumberOfHeads,2);
       
   102 	pos += 2;
       
   103 	memcpy(&iData[pos],&HiddenSectors,4);
       
   104 	pos += 4;
       
   105 	memcpy(&iData[pos],&HighSectorsCount,4);
       
   106 	pos += 4;
       
   107 	memcpy(&iData[pos],&BootSectorDriveNumber,1);		
       
   108 	pos += 1;
       
   109 	memcpy(&iData[pos],&ReservedByte,1);
       
   110 	pos += 1;
       
   111 	memcpy(&iData[pos],&BootSignature,1);
       
   112 	pos += 1;
       
   113 	memcpy(&iData[pos],&VolumeId,4);
       
   114 	pos += 4;
       
   115 	memcpy(&iData[pos],VolumeLab,11);
       
   116 	pos += 11;
       
   117 	memcpy(&iData[pos],FileSysType,8);
       
   118 	pos += 8;
       
   119 	while(pos < BytesPerSector)
       
   120 	{
       
   121 		iData[pos] = 0;
       
   122 		pos++;
       
   123 	}
       
   124 	// Set sector [510] as 0xAA and [511] as 0x55 to mark the end of boot sector
       
   125 	iData[KSizeOfFatBootSector-2] = 0x55;
       
   126 	iData[KSizeOfFatBootSector-1] = 0xAA;
       
   127 	// It is perfectly ok for the last two bytes of the boot sector to also 
       
   128 	// have the signature 0xAA55.
       
   129 	iData[BytesPerSector-2] = 0x55;
       
   130 	iData[BytesPerSector-1] = 0xAA;
       
   131 
       
   132 
       
   133 	ComputeClusterSizeInBytes();
       
   134 	ComputeRootDirSectors();
       
   135 	ComputeBytesPerSector();
       
   136 	MessageHandler::ReportMessage (INFORMATION,BOOTSECTORCREATEMSG, "FAT16");
       
   137 }
       
   138 
       
   139 /**
       
   140 Writes the boot sector of a FAT 16 volume
       
   141 @param aOutPutStream handle to file stream	
       
   142 
       
   143 @internalComponent
       
   144 @released
       
   145 */
       
   146 void CFat16FileSystem::WriteBootSector(ofstream& aOutPutStream)
       
   147 {
       
   148 	MessageHandler::ReportMessage (INFORMATION,BOOTSECTORWRITEMSG,"FAT16");
       
   149 	aOutPutStream.write(reinterpret_cast<char*>(&iData[0]),iFAT16BootSector.BytesPerSector());
       
   150 	aOutPutStream.flush();
       
   151 }
       
   152 /**
       
   153 Creates the FAT Table
       
   154 
       
   155 @internalComponent
       
   156 @released
       
   157 
       
   158 @param ofstream
       
   159 */
       
   160 void CFat16FileSystem::CreateFatTable(ofstream& aOutPutStream)
       
   161 {
       
   162 	int FATSizeInBytes = (iFAT16BootSector.FatSectors()) * (iFAT16BootSector.BytesPerSector());
       
   163 	// Each FAT16 entries occupies 2 bytes, hence divided by 2
       
   164 	unsigned int totalFatEntries = FATSizeInBytes / 2;
       
   165 	unsigned short *FatTable = new unsigned short[totalFatEntries];
       
   166 	unsigned short int clusterCounter = 1;
       
   167 	int previousCluster;
       
   168 	FatTable[0] = KFat16FirstEntry;
       
   169 	/**Say cluster 5 starts at 5 and occupies clusters 7 and 9. The FAT table should have the 
       
   170 	value 7 at	cluster location 5, the value 9 at cluster 7 and 'eof' value at cluster 9.
       
   171 	Below algorithm serves this algorithm
       
   172 	*/
       
   173 	Iterator itr = iClustersPerEntry->begin();
       
   174 	while(itr != iClustersPerEntry->end())
       
   175 	{
       
   176 		previousCluster = itr->second;
       
   177 		if(iClustersPerEntry->count(itr->first) > 1)
       
   178 		{
       
   179 			for(unsigned int i = 1; i < iClustersPerEntry->count(itr->first); i++)
       
   180 			{
       
   181 				FatTable[previousCluster] = (unsigned short)(++itr)->second;
       
   182 				previousCluster = itr->second;
       
   183 				++clusterCounter;
       
   184 			}
       
   185 		}
       
   186 		FatTable[previousCluster] = EOF16;
       
   187 		itr++;
       
   188 		++clusterCounter;
       
   189 	}
       
   190 	// Each FAT16 entries occupies 2 bytes, hence multiply by 2
       
   191 	std::string aFatString(reinterpret_cast<char*>(FatTable),clusterCounter*2);
       
   192 	delete[] FatTable;
       
   193 	if(clusterCounter < totalFatEntries)
       
   194 	{
       
   195 		// Each FAT16 entries occupies 2 bytes, hence multiply by 2
       
   196 		aFatString.append((totalFatEntries - clusterCounter)*2, 0);
       
   197 	}
       
   198 	MessageHandler::ReportMessage (INFORMATION,FATTABLEWRITEMSG,
       
   199 								   "FAT16");
       
   200 	
       
   201 	// Write FAT table multiple times depending upon the No of FATS set.
       
   202 	unsigned int noOfFats = iFAT16BootSector.NumberOfFats();
       
   203 	for(unsigned int i=0; i<noOfFats; i++)
       
   204 	{
       
   205 		aOutPutStream.write(aFatString.c_str(),aFatString.length());
       
   206 	}
       
   207 	
       
   208 	aFatString.erase();
       
   209 	aOutPutStream.flush();
       
   210 }
       
   211 
       
   212 /**
       
   213 set the cluster size in bytes,iClusterSize
       
   214 
       
   215 @internalComponent
       
   216 @released
       
   217 */
       
   218 void CFat16FileSystem::ComputeClusterSizeInBytes()
       
   219 {
       
   220 	iClusterSize = (iFAT16BootSector.SectorsPerCluster()) * (iFAT16BootSector.BytesPerSector());
       
   221 }
       
   222 
       
   223 /**
       
   224 set the count of sectors occupied by the root directory,iRootDirSectors.
       
   225 
       
   226 @internalComponent
       
   227 @released
       
   228 */
       
   229 void CFat16FileSystem::ComputeRootDirSectors()
       
   230 {
       
   231 	iRootDirSectors = (iFAT16BootSector.RootDirEntries() * (KDefaultRootDirEntrySize) + 
       
   232 					  (iFAT16BootSector.BytesPerSector() - 1)) / iFAT16BootSector.BytesPerSector();
       
   233 }	
       
   234 
       
   235 /**
       
   236 Initialize the Bytes per Sector variable value.
       
   237 
       
   238 @internalComponent
       
   239 @released
       
   240 */
       
   241 void CFat16FileSystem::ComputeBytesPerSector()
       
   242 {
       
   243 	iBytesPerSector = iFAT16BootSector.BytesPerSector();
       
   244 }
       
   245 
       
   246 
       
   247 /**
       
   248 Compute the total number of clusters in Data segment of the FAT volume
       
   249 
       
   250 @internalComponent
       
   251 @released
       
   252 */
       
   253 void CFat16FileSystem::ComputeTotalClusters(Long64 aPartitionSize)
       
   254 {
       
   255 	unsigned long int iTotalDataSectors = iFAT16BootSector.TotalSectors(aPartitionSize) - 
       
   256 										  ((iFAT16BootSector.NumberOfFats() * iFAT16BootSector.FatSectors()) + 
       
   257 										  iRootDirSectors + iFAT16BootSector.ReservedSectors());
       
   258 	iTotalClusters = iTotalDataSectors / iFAT16BootSector.SectorsPerCluster();
       
   259 	if(iTotalClusters < KMinimumFat16Clusters)
       
   260 	{
       
   261 		throw ErrorHandler(BOOTSECTORERROR,"Low Partition Size",__FILE__,__LINE__);
       
   262 	}
       
   263 	if(iTotalClusters > KMaximumFat16Clusters)
       
   264 	{
       
   265 		throw ErrorHandler(BOOTSECTORERROR,"High Partition Size",__FILE__,__LINE__);
       
   266 	}
       
   267 	
       
   268 }
       
   269 
       
   270 /**
       
   271 This methods encapsulates the function call to write a complete FAT16 Image
       
   272 
       
   273 @internalComponent
       
   274 @released
       
   275 
       
   276 @param aPartitionSize partition size in bytes
       
   277 @param aNodeList Directory structure 
       
   278 @param aOutPutStream output stream for writing file image
       
   279 @param aImageFileName image file name 
       
   280 @param aLogFileName log file name 
       
   281 @param aConfigurableFatAttributes ConfigurableFatAttributes
       
   282 */
       
   283 
       
   284 void CFat16FileSystem::Execute(Long64 aPartitionSize,EntryList aNodeList,ofstream& aOutPutStream,
       
   285 							   ConfigurableFatAttributes* aConfigurableFatAttributes)
       
   286 {
       
   287 	CDirRegion* dirRegionPtr = NULL;
       
   288 	try
       
   289 	{
       
   290 		CreateBootSector(aPartitionSize,aConfigurableFatAttributes);
       
   291 		ComputeTotalClusters(aPartitionSize);
       
   292 		WriteBootSector(aOutPutStream);
       
   293 		dirRegionPtr = new CDirRegion(aNodeList,this);
       
   294 		dirRegionPtr->Execute();
       
   295 		iClustersPerEntry = dirRegionPtr->GetClustersPerEntryMap();
       
   296 		CreateFatTable(aOutPutStream);
       
   297 		dirRegionPtr ->WriteClustersIntoFile(aOutPutStream);
       
   298 		delete dirRegionPtr ;
       
   299 	}
       
   300 	catch(ErrorHandler &aError)
       
   301 	{
       
   302 		delete dirRegionPtr;
       
   303 		//Re throw the same error message
       
   304 		throw ErrorHandler(aError.iMessageIndex,(char*)aError.iSubMessage.c_str(),(char*)aError.iFileName.c_str(),aError.iLineNumber);
       
   305 	}
       
   306 	/**
       
   307 	Irrespective of successful or unsuccessful data drive image generation ROFSBUILD
       
   308 	may try to generate images for successive ".oby" file input.
       
   309 	During this course unhandled exceptions may cause leaving some memory on heap 
       
   310 	unused. so the unhandled exceptions handling is used to free the memory allocated 
       
   311 	on heap. 
       
   312 	*/
       
   313 	catch(...)
       
   314 	{
       
   315 		delete dirRegionPtr;
       
   316 		throw ErrorHandler(UNKNOWNERROR, __FILE__, __LINE__);
       
   317 	}
       
   318 }