imgtools/romtools/rofsbuild/rofsbuild.cpp
changeset 606 30b30f9da0b7
parent 0 044383f39525
child 607 378360dbbdba
--- a/imgtools/romtools/rofsbuild/rofsbuild.cpp	Fri Jun 25 20:58:33 2010 +0800
+++ b/imgtools/romtools/rofsbuild/rofsbuild.cpp	Tue Jun 29 14:52:54 2010 +0800
@@ -1,728 +1,672 @@
-/*
-* Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: 
-* @internalComponent * @released
-* Rofsbuild mainfile to generate both rofs and data drive image.
-*
-*/
-
-
-#include <string.h>
-#include <stdlib.h>
-#include <f32file.h>
-#include "e32image.h"
-#include "h_utl.h"
-#include "h_ver.h"
-#include "r_obey.h"
-#include "r_driveimage.h"
-#include "r_driveutl.h"
-#include "r_coreimage.h"
-#include "parameterfileprocessor.h"
-#include "r_smrimage.h"
-
-static const TInt RofsbuildMajorVersion=2;
-static const TInt RofsbuildMinorVersion=6;
-static const TInt RofsbuildPatchVersion=5;
-static TBool SizeSummary=EFalse;
-static TPrintType SizeWhere=EAlways;
-
-static TInt gHeaderType=1;			// EPOC header
-static TInt MAXIMUM_THREADS = 128;
-static TInt DEFAULT_THREADS = 8;
-ECompression gCompress=ECompressionUnknown;
-TUint  gCompressionMethod=0;
-TBool gFastCompress = EFalse;
-TInt gThreadNum = 0;
-TInt gCPUNum = 0;
-char* g_pCharCPUNum = NULL;
-TInt gCodePagingOverride = -1;
-TInt gDataPagingOverride = -1;
-TInt gLogLevel = 0;	// Information is logged based on logging level.
-					// The default is 0. So all the existing logs are generated as if gLogLevel = 0.
-					// If any extra information required, the log level must be appropriately supplied.
-					// Currrently, file details in ROM (like, file name in ROM & host, file size, whether 
-					// the file is hidden etc) are logged when gLogLevel >= LOG_LEVEL_FILE_DETAILS.
-
-TBool gUseCoreImage=EFalse; // command line option for using core image file
-char* gImageFilename=NULL;	// instead of obey file
-TBool gEnableStdPathWarning=EFalse;// for in-correct destination path warning(executables).
-TBool gLowMem=EFalse;
-
-extern TBool gDriveImage;		// to Support data drive image.
-TText* gDriveFilename=NULL;		// input drive oby filename.
-
-string filename;				// to store oby filename passed to Rofsbuild.
-TBool reallyHelp=EFalse;	
-
-TBool gSmrImage = EFalse;
-TText* gSmrFileName = NULL;
-
-void PrintVersion()
-	{
-		Print(EAlways,"\nROFSBUILD - Rofs/Datadrive image builder");
-		Print(EAlways, " V%d.%d.%d\n", RofsbuildMajorVersion, RofsbuildMinorVersion, RofsbuildPatchVersion);
-		Print(EAlways,Copyright);
-	}
-
-char HelpText[] = 
-	"Syntax: ROFSBUILD [options] obeyfilename(Rofs)\n"
-	"Option: -v verbose,  -?,  -s[log|screen|both] size summary\n"
-	"        -d<bitmask> set trace mask (DEB build only)\n"
-	"        -compress   compress executable files where possible\n"
-	"        -fastcompress  compress files with faster bytepair and tradeoff of compress ratio\n"
-	"        -j<digit> do the main job with <digit> threads\n"
-	"        -compressionmethod none|inflate|bytepair to set the compression\n"
-	"              none     uncompress the image.\n"
-	"              inflate  compress the image.\n"
-	"              bytepair compress the image.\n"
-	"        -coreimage <core image file>\n"
-	"        -datadrive=<drive obyfile1>,<drive obyfile2>,... for driveimage creation\n"
-	"              user can also input rofs oby file if required to generate both.\n"
-	"        -smr=<SMR obyfile1>,<SMR obyfile2>,... for SMR partition creation\n"
-	"        -loglevel<level>  level of information to log (valid levels are 0,1,2).\n"//Tools like Visual ROM builder need the host/ROM filenames, size & if the file is hidden.
-	"        -wstdpath   warn if destination path provided for a file is not the standard path\n"
-	"        -argfile=<FileName>   specify argument-file name containing list of command-line arguments\n"
-	"        -lowmem     use memory-mapped file for image build to reduce physical memory consumption\n";
-
-char ReallyHelpText[] =
-	"Log Level:\n"
-	"        0  produce the default logs\n"
-	"        1  produce file detail logs in addition to the default logs\n"
-	"        2  logs e32 header attributes in addition to the level 1 details\n";
-
-void processParamfile(string aFileName);
-
-/**
-Process the command line arguments and prints the helpful message if none are supplied.
-@param argc    - No. of argument.
-@param *argv[] - Arguments value.
-*/ 
-void processCommandLine(int argc, char *argv[], TBool paramFileFlag=EFalse)
-{
-	// If "-argfile" option is passed to rofsbuild, then process the parameters
-	// specified in parameter-file first and then the options passed from the 
-	// command-line.
-	string ParamFileArg("-ARGFILE=");	
-	if(paramFileFlag == EFalse)
-	{	
-		for (int count=1; count<argc; count++)
-		{
-			string paramFile;
-			strupr(argv[count]);
-			if(strncmp(argv[count],ParamFileArg.c_str(),ParamFileArg.length())==0)
-			{
-				paramFile.assign(&argv[count][ParamFileArg.length()]);									
-				processParamfile(paramFile);
-			}
-		}
-	}	
-
-	int i=1;
-	while (i<argc)
-		{
-		strupr(argv[i]);
-		if ((argv[i][0] == '-') || (argv[i][0] == '/'))
-			{ // switch
-			if (argv[i][1] == 'V')
-				H.iVerbose = ETrue;
-			else if(strncmp (argv[i], "-SMR=", 5) == 0)
-			{
-				if(argv[i][5])
-				{
-					gSmrImage = ETrue;
-					gSmrFileName = (TText*)strdup(&argv[i][5]);
-				}
-				else
-				{
-					Print (EError, "SMR obey file is missing\n");
-				}
-			}
-			else if (argv[i][1] == 'S')
-				{
-				SizeSummary=ETrue;
-				if (argv[i][2] == 'L')
-					SizeWhere=ELog;
-				if (argv[i][2] == 'S')
-					SizeWhere=EScreen;
-				}
-			else if (strncmp(argv[i],ParamFileArg.c_str(),ParamFileArg.length())==0)
-				{
-					if (paramFileFlag)
-					{
-						String paramFile;
-						paramFile.assign(&argv[i][ParamFileArg.length()]);		
-						processParamfile(paramFile);
-					}
-					else
-					{
-						i++;
-						continue;
-					}
-				}
-			else if (strcmp(argv[i], "-COMPRESS")==0)
-				{
-				gCompress=ECompressionCompress;
-				gCompressionMethod = KUidCompressionDeflate;
-				}
-			else if (strcmp(argv[i], "-FASTCOMPRESS")==0)
-				{
-				gFastCompress=ETrue;
-				}
-			else if (strncmp(argv[i], "-J",2)==0)
-				{
-					if(argv[i][2])
-						gThreadNum = atoi(&argv[i][2]);
-					else
-						{
-						printf("WARNING: The option should be like '-j4'.\n");
-						gThreadNum = 0;
-						}
-					if(gThreadNum <= 0 || gThreadNum > MAXIMUM_THREADS)
-						{
-						if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS)
-							{
-							printf("WARNING: The number of concurrent jobs set by -j should be between 1 and 128. And the number of processors %d will be used as the number of concurrent jobs.\n", gCPUNum);
-							gThreadNum = gCPUNum;
-							}
-						else if(g_pCharCPUNum)
-							{
-							printf("WARNING: The number of concurrent jobs set by -j should be between 1 and 128. And the NUMBER_OF_PROCESSORS is invalid, so the default value %d will be used.\n", DEFAULT_THREADS);
-							gThreadNum = DEFAULT_THREADS;
-							}
-						else
-							{
-							printf("WARNING: The number of concurrent jobs set by -j should be between 1 and 128. And the NUMBER_OF_PROCESSORS is not available, so the default value %d will be used.\n", DEFAULT_THREADS);
-							gThreadNum = DEFAULT_THREADS;
-							}
-						}
-				}
-			else if (strcmp(argv[i], "-UNCOMPRESS")==0)
-				{
-				gCompress=ECompressionUncompress;
-				}
-			else if( strcmp(argv[i], "-COMPRESSIONMETHOD") == 0 )
-				{
-					// next argument should a be method
-					if( (i+1) >= argc || argv[i+1][0] == '-') 
-					{
-					Print (EError, "Missing compression method! Set it to default (no compression)!");
-					gCompressionMethod = 0;
-					}
-					else 
-					{
-					i++;
-					strupr(argv[i]);
-					if( strcmp(argv[i], "NONE") == 0)	
-						{
-						gCompress=ECompressionUncompress;
-						gCompressionMethod = 0;	
-						}
-					else if( strcmp(argv[i], "INFLATE") == 0)
-						{
-						gCompress=ECompressionCompress;
-						gCompressionMethod = KUidCompressionDeflate;	
-						}	
-					else if( strcmp(argv[i], "BYTEPAIR") == 0)
-						{
-						gCompress=ECompressionCompress;
-						gCompressionMethod = KUidCompressionBytePair;	
-						}
-					else
-						{
-						Print (EError, "Unknown compression method! Set it to default (no compression)!");
-						gCompress=ECompressionUnknown;
-						gCompressionMethod = 0;		
-						}
-					}
-					
-				}
-			else if (strcmp(argv[i], "-COREIMAGE") ==0)
-				{
-					gUseCoreImage = ETrue;
-
-					// next argument should be image filename
-					if ((i+1 >= argc) || argv[i+1][0] == '-')
-						Print (EError, "Missing image file name");
-					else
-					{
-						i++;
-						gImageFilename = strdup(argv[i]);
-					}
-				}
-			else if (strncmp(argv[i], "-DATADRIVE=",11) ==0)
-				{  
-				   	if(argv[i][11])	
-						{
-						gDriveImage = ETrue; 
-						gDriveFilename = (TText*)strdup(&argv[i][11]);	
-						}
-					else
-						{
-						Print (EError, "Drive obey file is missing\n"); 
-						}
-				}
-			else if (argv[i][1] == '?')
-				{
-				reallyHelp=ETrue;
-				}
- 			else if (strcmp(argv[i], "-WSTDPATH") ==0)		// Warn if destination path provided for a executables are incorrect as per platsec.		
- 				{
- 				gEnableStdPathWarning=ETrue;						
- 				}
-			
-			else if( strcmp(argv[i], "-LOGLEVEL") == 0)
-				{
-				// next argument should a be loglevel
-				if( (i+1) >= argc || argv[i+1][0] == '-')
-					{
-					Print (EError, "Missing loglevel!");
-					gLogLevel = DEFAULT_LOG_LEVEL;
-					}
-				else
-					{
-					i++;
-					if (strcmp(argv[i], "2") == 0)
-						gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
-					if (strcmp(argv[i], "1") == 0)
-						gLogLevel = LOG_LEVEL_FILE_DETAILS;
-					else if (strcmp(argv[i], "0") == 0)
-						gLogLevel = DEFAULT_LOG_LEVEL;
-					else
-						Print(EError, "Only loglevel 0, 1 or 2 is allowed!");
-					}
-				}
-			else if( strcmp(argv[i], "-LOGLEVEL2") == 0)
-				gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
-			else if( strcmp(argv[i], "-LOGLEVEL1") == 0)
-				gLogLevel = LOG_LEVEL_FILE_DETAILS;
-			else if( strcmp(argv[i], "-LOGLEVEL0") == 0)
-				gLogLevel = DEFAULT_LOG_LEVEL;
-			else if (strcmp(argv[i], "-LOWMEM") == 0)
-				gLowMem = ETrue;
-			else 
-				cout << "Unrecognised option " << argv[i] << "\n";
-			}
-		else // Must be the obey filename
-			filename=argv[i];
-		i++;
-		}
-	
-		if (paramFileFlag)
-		return;
-
-		if((gDriveImage == EFalse) && (gSmrImage ==  EFalse) && (filename.empty() || (gUseCoreImage && gImageFilename == NULL)))
-		{
-		PrintVersion();
-		cout << HelpText;
-		if (reallyHelp)
-			{
-			ObeyFileReader::KeywordHelp();
-			cout << ReallyHelpText;
-			}
-		else if (filename.empty())
-			{
-			Print(EError, "Obey filename is missing\n");
-			}
-		}	
-	}
-
-/**
-Function to process parameter-file. 
-
-@param aFileName parameter-file name.
-*/
-void processParamfile(string aFileName)
-{
-	CParameterFileProcessor parameterFile(aFileName);
-	
-	// Invoke fuction "ParameterFileProcessor" to process parameter-file.
-	if(parameterFile.ParameterFileProcessor())
-	{
-		TUint noOfParameters = parameterFile.GetNoOfArguments();
-		char** parameters = parameterFile.GetParameters();
-		TBool paramFileFlag=ETrue;
-
-		// Invoke function "processCommandLine" to process parameters read from parameter-file.
-		processCommandLine(noOfParameters,parameters,paramFileFlag);
-	}	
-}
-
-/**
-Main logic for data drive image creation. Called many types depending on no. of drive obey files.
-
-@param aobeyFileName - Drive obey file.
-@param alogfile      - log file name required for file system module.
- 
-@return - returns the status, after processing the drive obey file.
-*/ 
-TInt ProcessDataDriveMain(TText* aobeyFileName,TText* alogfile)
-	{
-
-	ObeyFileReader *reader=new ObeyFileReader(aobeyFileName);
-
-	if(!reader)
-		return KErrNoMemory;
-
-	if(!reader->Open())
-    {
-        if (reader)
-        {
-            delete reader;
-        }
-		return KErrGeneral;
-    }
-
-	TInt retstatus =0;		
-	CObeyFile* mainObeyFile=new CObeyFile(*reader);   
-	CDriveImage* userImage = 0; 
-
-	if(!mainObeyFile)
-    {
-        if (reader)
-        {
-            delete reader;
-        }
-		return KErrNoMemory;
-    }
-
-	// Process data drive image.
-	// let's clear the TRomNode::sDefaultInitialAttr first, 'cause data drive is different from rom image
-	TRomNode::sDefaultInitialAttr = 0; 
-	retstatus = mainObeyFile->ProcessDataDrive();
-	if (retstatus == KErrNone)
-		{
-		// Build a Data drive image using the description compiled into the CObeyFile object
-		userImage = new CDriveImage(mainObeyFile);
-		if(userImage)
-			{	
-			// Drive image creation.
-			retstatus = userImage->CreateImage(alogfile);
-			if(retstatus == KErrNone)
-				{
-				cout << "\nSuccessfully generated the Drive image : " << mainObeyFile->iDriveFileName << "\n";
-				}
-			else
-				{
-				cout << "\nFailed to generate the Image : " << mainObeyFile->iDriveFileName << "\n";
-				}
-
-			delete userImage;
-			userImage = 0;
-			}
-		else
-			{
-			retstatus = KErrNoMemory;
-			}
-		}
-	// restore
-	TRomNode::sDefaultInitialAttr = (TUint8)KEntryAttReadOnly;
-	cout << "\n-----------------------------------------------------------\n";
-	
-	delete mainObeyFile;
-	delete reader;
-	return retstatus;
-	}
-
-TInt ProcessSmrImageMain(TText* aObeyFileName, TText* /* alogfile */)
-{
-	ObeyFileReader *reader = new ObeyFileReader(aObeyFileName);
-	if(!reader)
-		return KErrNoMemory;
-	if(!reader->Open())
-    {
-        if (reader)
-        {
-            delete reader;
-        }
-		return KErrGeneral;
-    }
-	TInt retstatus = 0;
-	CObeyFile* mainObeyFile = new CObeyFile(*reader);
-	CSmrImage* smrImage = 0;
-	if(!mainObeyFile)
-    {
-        if (reader)
-        {
-            delete reader;
-        }
-		return KErrNoMemory;
-    }
-
-	if(mainObeyFile->Process())
-	{
-		smrImage = new CSmrImage(mainObeyFile);
-		if(smrImage)
-		{
-			if((retstatus=smrImage->Initialise()) == KErrNone)
-			{
-				retstatus = smrImage->CreateImage();
-			}
-			if(retstatus == KErrNone)
-			{
-				cout << "\nSuccessfully generated the SMR image : " << smrImage->GetImageName().c_str() << "\n";
-			}
-			else
-			{
-				cout << "\nFailed to generate the Image : " << smrImage->GetImageName().c_str() << "\n";
-			}
-			delete smrImage;
-		}
-		else
-		{
-			retstatus = KErrNoMemory;
-		}
-	}
-	delete mainObeyFile;
-	delete reader;
-	return retstatus;
-}
-
-/**
-Rofsbuild Main function, which creates both Rofs and Data drive image.
-
-@param argc    - No. of argument.
-@param *argv[] - Arguments value.
-  
-@return - returns the status to caller.
-*/ 
-TInt main(int argc, char *argv[])
-{
-	TInt r =0;	
-
-	g_pCharCPUNum = getenv("NUMBER_OF_PROCESSORS");
-	if(g_pCharCPUNum != NULL)
-		gCPUNum = atoi(g_pCharCPUNum);
-
- 	processCommandLine(argc, argv);
-
- 	TText *obeyFileName = NULL;	
- 	if(!filename.empty())
- 		obeyFileName=(TText*)filename.c_str();	
-
-	if ((obeyFileName==NULL) && (gDriveFilename==NULL) && (gSmrFileName == NULL))                   
-		return KErrGeneral;
-	
-	if(gThreadNum == 0)
-	{
-		if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS)
-		{
-			printf("The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum);
-			gThreadNum = gCPUNum;
-		}
-		else if(g_pCharCPUNum)
-		{
-			printf("WARNING: The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS);
-			gThreadNum = DEFAULT_THREADS;
-		}
-		else
-		{
-			printf("WARNING: The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS);
-			gThreadNum = DEFAULT_THREADS;
-		}
-	}
-
-	// Process drive obey files.
-	if(gDriveImage)
-	{  
-		TText temp = 0;
-		TText *driveobeyFileName = gDriveFilename;
-		
-		do
-		{
-			while(((temp = *gDriveFilename++) != ',') && (temp != 0));
-			*(--gDriveFilename)++ = 0;
-			
-			if(*driveobeyFileName)
-			{	
-				TText* logfile = 0;
-				if(Getlogfile(driveobeyFileName,logfile)== KErrNone)
-				{
-					H.SetLogFile(logfile);	
-					PrintVersion();
-					GetLocalTime();
-					r = ProcessDataDriveMain(driveobeyFileName,logfile);   
-					H.CloseLogFile();
-					delete[] logfile;
-					if(r == KErrNoMemory)
-						return KErrNoMemory;
-				}
-				else
-				{
-					cout << "Error : Invalid obey file name : " << driveobeyFileName << "\n" ;   
-				}
-			}
-			driveobeyFileName = gDriveFilename;
-		}
-		while(temp != 0);   
-		
-		gDriveImage=EFalse;
-	} 
-	if(gSmrImage)
-	{
-		TText temp = 0;
-		TText *smrImageObeyFileName = gSmrFileName;
-		do
-		{
-			while(((temp = *gSmrFileName++) != ',') && (temp != 0));
-			*(--gSmrFileName)++ = 0;
-			if(*smrImageObeyFileName)
-			{	
-				TText * logfile = 0;
-				if(Getlogfile(smrImageObeyFileName,logfile) == KErrNone)
-				{
-					H.SetLogFile(logfile);
-					PrintVersion();
-					GetLocalTime();
-					r = ProcessSmrImageMain(smrImageObeyFileName, logfile);
-					H.CloseLogFile();
-					delete[] logfile;
-					if(r == KErrNoMemory)
-						return KErrNoMemory;
-				}
-				else
-				{
-					cout << "Error: Invalid obey file name: " << smrImageObeyFileName << "\n";
-				}
-			}
-			smrImageObeyFileName = gSmrFileName;
-		}
-		while(temp != 0);
-		gSmrImage = EFalse;
-	}
-	// Process Rofs Obey files.
-	if(obeyFileName)
-	{
-		
-		H.SetLogFile((unsigned char *)"ROFSBUILD.LOG");	
-		PrintVersion();
-		
-		ObeyFileReader *reader=new ObeyFileReader(obeyFileName);
-		if (!reader->Open())
-			return KErrGeneral;
-		
-		E32Rofs* RofsImage = 0;		// for image from obey file
-		CCoreImage *core= 0;		// for image from core image file
-		MRofsImage* imageInfo=0;
-		CObeyFile *mainObeyFile=new CObeyFile(*reader);
-		
-		// need check if obey file has coreimage keyword
-		TText *file = mainObeyFile->ProcessCoreImage();
-		if (file)
-		{
-			// hase coreimage keyword but only use if command line option
-			// for coreimage not already selected
-			if (!gUseCoreImage)
-			{
-				gUseCoreImage = ETrue;
-				gImageFilename = (char *)file;
-			}
-		}
-		
-		if (!gUseCoreImage)
-		{
-			
-			r=mainObeyFile->ProcessRofs();
-			if (r==KErrNone)
-			{
-				// Build a ROFS image using the description compiled into the
-				// CObeyFile object
-				
-				RofsImage = new E32Rofs( mainObeyFile );
-				if( !RofsImage )
-				{
-					return KErrNoMemory;
-				}
-				
-				r = RofsImage->Create();
-				if( KErrNone == r )
-				{
-					if(SizeSummary)
-						RofsImage->DisplaySizes(SizeWhere);
-					RofsImage->WriteImage( gHeaderType );
-				}
-				imageInfo = RofsImage;
-				mainObeyFile->Release();
-			}
-			else if (r!=KErrNotFound)
-				return r;
-		}
-		else
-		{
-			
-			// need to use core image
-			RCoreImageReader *reader = new RCoreImageReader(gImageFilename);
-			if (!reader)
-			{
-				return KErrNoMemory;
-			}
-			core= new CCoreImage(reader);
-			if (!core)
-			{
-				return KErrNoMemory;
-			}
-			r = core->ProcessImage();
-			if (r != KErrNone)
-				return r;
-			imageInfo = core;
-			mainObeyFile->SkipToExtension();
-			
-		}
-		
-		do 
-		{
-			CObeyFile* extensionObeyFile = 0;
-			E32Rofs* extensionRofs = 0;
-			
-			extensionObeyFile = new CObeyFile(*reader);
-			r = extensionObeyFile->ProcessExtensionRofs(imageInfo);
-			if (r==KErrEof)
-			{
-				if(RofsImage)
-					delete RofsImage;
-				if(core)
-					delete core;
-				delete extensionObeyFile;
-				return KErrNone;
-			}
-			if (r!=KErrNone)
-				break;
-			
-			extensionRofs = new E32Rofs(extensionObeyFile);
-			r=extensionRofs->CreateExtension(imageInfo);
-			if (r!=KErrNone)
-			{
-				delete extensionRofs;
-				delete extensionObeyFile;
-				break;
-			}
-			if(SizeSummary)
-				RofsImage->DisplaySizes(SizeWhere);
-			r=extensionRofs->WriteImage(0);		
-			delete extensionRofs;
-			delete extensionObeyFile;
-			extensionRofs = 0;
-			extensionObeyFile = 0;
-			
-		}
-		while (r==KErrNone);
-		
-		if(RofsImage) 
-			delete RofsImage;									
-		if(core)
-			delete core;
-		delete mainObeyFile;
-		
-	}
-	return r;
-}//end of main.
+/*
+* Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+#include <string.h>
+#include <stdlib.h>
+#include <f32file.h>
+#include "e32image.h"
+#include "h_utl.h"
+#include "h_ver.h"
+#include "r_obey.h"
+#include "r_driveimage.h"
+#include "r_driveutl.h"
+#include "r_coreimage.h"
+#include "parameterfileprocessor.h"
+#include "r_smrimage.h"
+//cache headers
+#include "cache/cacheexception.hpp"
+#include "cache/cacheentry.hpp"
+#include "cache/cache.hpp"
+#include "cache/cachegenerator.hpp"
+#include "cache/cachevalidator.hpp"
+#include "cache/cacheablelist.hpp"
+#include "cache/cachemanager.hpp"
+#include <malloc.h>
+ 
+#ifndef WIN32
+#include <unistd.h>
+#include <strings.h>
+#include <fstream>
+#define strnicmp strncasecmp
+#define stricmp strcasecmp
+#define _alloca alloca
+#endif
+
+static const TInt RofsbuildMajorVersion=2;
+static const TInt RofsbuildMinorVersion=12;
+static const TInt RofsbuildPatchVersion=0;
+static TBool SizeSummary=EFalse;
+static TPrintType SizeWhere=EAlways;
+
+static TInt gHeaderType=1;			// EPOC header
+static TInt MAXIMUM_THREADS = 128;
+static TInt DEFAULT_THREADS = 8;
+ECompression gCompress=ECompressionUnknown;
+TUint  gCompressionMethod=0;
+TInt gThreadNum = 0;
+TInt gCPUNum = 0;
+TBool gGenSymbols = EFalse;
+TInt gCodePagingOverride = -1;
+TInt gDataPagingOverride = -1;
+TInt gLogLevel = 0;	// Information is logged based on logging level.
+// The default is 0. So all the existing logs are generated as if gLogLevel = 0.
+// If any extra information required, the log level must be appropriately supplied.
+// Currrently, file details in ROM (like, file name in ROM & host, file size, whether
+// the file is hidden etc) are logged when gLogLevel >= LOG_LEVEL_FILE_DETAILS.
+
+TBool gUseCoreImage = EFalse; // command line option for using core image file
+string gImageFilename = "";	// instead of obey file
+TBool gEnableStdPathWarning = EFalse;// for in-correct destination path warning(executables).
+TBool gLowMem = EFalse;
+extern TBool gDriveImage;		// to Support data drive image.
+string gDriveFilename = "";		// input drive oby filename.
+string filename;				// to store oby filename passed to Rofsbuild.
+TBool reallyHelp = EFalse;	
+TBool gSmrImage = EFalse;
+string gSmrFileName = "";
+
+//Cache global variables
+bool gCache = false;
+bool gCleanCache = false;
+bool gNoCache = false;
+TBool gKeepGoing = EFalse;
+void PrintVersion() {
+	Print(EAlways,"\nROFSBUILD - Rofs/Datadrive image builder");
+	Print(EAlways, " V%d.%d.%d\n", RofsbuildMajorVersion, RofsbuildMinorVersion, RofsbuildPatchVersion);
+	Print(EAlways,Copyright);
+}
+
+char HelpText[] = 
+	"Syntax: ROFSBUILD [options] obeyfilename(Rofs)\n"
+	"Option: -v verbose,  -?,  -s[log|screen|both] size summary\n"
+	"        -d<bitmask> set trace mask (DEB build only)\n"
+	"        -compress   compress executable files where possible\n"
+	"        -j<digit> do the main job with <digit> threads\n"
+	"        -symbols generate symbol file\n"
+	"        -compressionmethod none|inflate|bytepair to set the compression\n"
+	"              none     uncompress the image.\n"
+	"              inflate  compress the image.\n"
+	"              bytepair compress the image.\n"
+	"        -coreimage <core image file>\n"
+	"        -cache allow the ROFSBUILD to reuse/generate cached executable files\n"
+	"        -nocache force the ROFSBUILD not to reuse/generate cached executable files\n"
+	"        -cleancache permanently remove all cached executable files\n"
+	"        -datadrive=<drive obyfile1>,<drive obyfile2>,... for driveimage creation\n"
+	"              user can also input rofs oby file if required to generate both.\n"
+	"        -smr=<SMR obyfile1>,<SMR obyfile2>,... for SMR partition creation\n"
+	"        -loglevel<level>  level of information to log (valid levels are 0,1,2).\n"//Tools like Visual ROM builder need the host/ROM filenames, size & if the file is hidden.
+	"        -wstdpath   warn if destination path provided for a file is not the standard path\n"
+	"        -argfile=<FileName>   specify argument-file name containing list of command-line arguments\n"
+"        -lowmem     use memory-mapped file for image build to reduce physical memory consumption\n"
+"        -k     to enable keepgoing when duplicate files exist in oby\n";
+
+char ReallyHelpText[] =
+"Log Level:\n"
+"        0  produce the default logs\n"
+"        1  produce file detail logs in addition to the default logs\n"
+"        2  logs e32 header attributes in addition to the level 1 details\n";
+void processParamfile(const string& aFileName);
+/**
+Process the command line arguments and prints the helpful message if none are supplied.
+@param argc    - No. of argument.
+@param *argv[] - Arguments value.
+*/ 
+void processCommandLine(int argc, char *argv[], TBool paramFileFlag = EFalse) {
+	// If "-argfile" option is passed to rofsbuild, then process the parameters
+	// specified in parameter-file first and then the options passed from the command-line.
+	
+	string ParamFileArg("-ARGFILE=");	
+	if(paramFileFlag == EFalse) {
+		for (int count = 1; count<argc; count++) {
+			string paramFile;
+			//strupr(argv[count]);
+			if(strnicmp(argv[count],ParamFileArg.c_str(),ParamFileArg.length()) == 0) {
+				paramFile.assign(&argv[count][ParamFileArg.length()]);									
+				processParamfile(paramFile);
+			}
+		}
+	}	
+
+	int i = 1;
+	while (i<argc) {		 
+#ifdef __LINUX__	
+		if (argv[i][0] == '-') 
+#else
+		if ((argv[i][0] == '-') || (argv[i][0] == '/'))
+#endif
+		{ 
+			// switch
+			if ((argv[i][1] & 0x20) == 'v')
+				H.iVerbose = ETrue;
+			else if(strnicmp (argv[i], "-SMR=", 5) == 0) {
+				if(argv[i][5]) {
+					gSmrImage = ETrue;
+					gSmrFileName.assign(&argv[i][5]);
+				}
+				else {
+					Print (EError, "SMR obey file is missing\n");
+				}
+			} else if (stricmp(argv[i], "-K") == 0) {
+				gKeepGoing = ETrue;
+			}else if (stricmp(argv[i], "-SYMBOLS") == 0) {
+				gGenSymbols = ETrue;
+			}
+			else if (((argv[i][1] | 0x20) == 's') &&  
+				(((argv[i][2]| 0x20) == 'l')||((argv[i][2] | 0x20) == 's'))) {
+					SizeSummary = ETrue;
+					if ((argv[i][2]| 0x20) == 'l')
+						SizeWhere = ELog;
+					else
+						SizeWhere = EScreen;
+			}
+			else if (strnicmp(argv[i],ParamFileArg.c_str(),ParamFileArg.length()) == 0) {
+				if (paramFileFlag){
+					string paramFile;
+					paramFile.assign(&argv[i][ParamFileArg.length()]);		
+					processParamfile(paramFile);
+				}
+				else {
+					i++;
+					continue;
+				}
+			}
+			else if (stricmp(argv[i], "-COMPRESS") == 0) {
+				gCompress = ECompressionCompress;
+				gCompressionMethod = KUidCompressionDeflate;
+			}
+			else if(stricmp(argv[i], "-CACHE") == 0) {
+				gCache = true;
+				if(gCleanCache || gNoCache) {
+					printf("Cache command line options are mutually exclusive, only one option can be used at a time\n");
+					exit(1);
+				}
+			}
+			else if(stricmp(argv[i], "-NOCACHE") == 0) {
+				gNoCache = true;
+				if(gCleanCache || gCache) {
+					printf("Cache command line options are mutually exclusive, only one option can be used at a time\n");
+					exit(1);
+				}
+			}
+			else if(stricmp(argv[i], "-CLEANCACHE") == 0) {
+				gCleanCache = true;
+				if(gCache || gNoCache)
+				{
+					printf("Cache command line options are mutually exclusive, only one option can be used at a time\n");
+					exit(1);
+				}
+			}
+			else if (strnicmp(argv[i], "-J",2) == 0) {
+				if(argv[i][2])
+					gThreadNum = atoi(&argv[i][2]);
+				else {
+					printf("WARNING: The option should be like '-j4'.\n");
+					gThreadNum = 0;
+				}
+				if(gThreadNum <= 0 || gThreadNum > MAXIMUM_THREADS) {
+					printf("WARNING: The number of concurrent jobs set by -j should be between 1 and 128. ");
+					if(gCPUNum > 0) {
+						printf("WARNING: The number of processors %d is used as the number of concurrent jobs.\n", gCPUNum);
+						gThreadNum = gCPUNum;
+					}
+					else {
+						printf("WARNING: Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS);
+						gThreadNum = DEFAULT_THREADS;
+					}
+				}
+			}
+			else if (stricmp(argv[i], "-UNCOMPRESS") == 0) {
+				gCompress = ECompressionUncompress;
+			}
+			else if( stricmp(argv[i], "-COMPRESSIONMETHOD") == 0 ) {
+				// next argument should a be method
+				if( (i+1) >= argc || argv[i+1][0] == '-') {
+					Print (EError, "Missing compression method! Set it to default (no compression)!");
+					gCompressionMethod = 0;
+				}
+				else {
+					i++;					
+					if( stricmp(argv[i], "NONE") == 0) {
+						gCompress = ECompressionUncompress;
+						gCompressionMethod = 0;	
+					}
+					else if( stricmp(argv[i], "INFLATE") == 0) {
+						gCompress = ECompressionCompress;
+						gCompressionMethod = KUidCompressionDeflate;	
+					}	
+					else if( stricmp(argv[i], "BYTEPAIR") == 0) {
+						gCompress = ECompressionCompress;
+						gCompressionMethod = KUidCompressionBytePair;	
+					}
+					else {
+						Print (EError, "Unknown compression method! Set it to default (no compression)!");
+						gCompress = ECompressionUnknown;
+						gCompressionMethod = 0;		
+					}
+				}
+
+			}
+			else if (stricmp(argv[i], "-COREIMAGE") == 0) {
+				
+				gUseCoreImage = ETrue;
+				// next argument should be image filename
+				if ((i+1 >= argc) || argv[i+1][0] == '-')
+					Print (EError, "Missing image file name");
+				else {
+					i++;
+					gImageFilename.assign(argv[i]);
+				}
+			}
+			else if (strnicmp(argv[i], "-DATADRIVE=",11) == 0){  
+				if(argv[i][11])	{
+					gDriveImage = ETrue; 
+					gDriveFilename.assign(&argv[i][11]);	
+				}
+				else {
+					Print (EError, "Drive obey file is missing\n"); 
+				}
+			}
+			else if (argv[i][1] == '?') {
+				reallyHelp = ETrue;
+			}
+			else if (stricmp(argv[i], "-WSTDPATH") == 0)	{	// Warn if destination path provided for a executables are incorrect as per platsec.		
+				gEnableStdPathWarning = ETrue;						
+			}
+			else if( stricmp(argv[i], "-LOGLEVEL") == 0) {
+				// next argument should a be loglevel
+				if( (i+1) >= argc || argv[i+1][0] == '-') {
+					Print (EError, "Missing loglevel!");
+					gLogLevel = DEFAULT_LOG_LEVEL;
+				}
+				else {
+					i++;
+					if (strcmp(argv[i], "2") == 0)
+						gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
+					if (strcmp(argv[i], "1") == 0)
+						gLogLevel = LOG_LEVEL_FILE_DETAILS;
+					else if (strcmp(argv[i], "0") == 0)
+						gLogLevel = DEFAULT_LOG_LEVEL;
+					else
+						Print(EError, "Only loglevel 0, 1 or 2 is allowed!");
+				}
+			}
+			else if( stricmp(argv[i], "-LOGLEVEL2") == 0)
+				gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
+			else if( stricmp(argv[i], "-LOGLEVEL1") == 0)
+				gLogLevel = LOG_LEVEL_FILE_DETAILS;
+			else if( stricmp(argv[i], "-LOGLEVEL0") == 0)
+				gLogLevel = DEFAULT_LOG_LEVEL;
+			else if (stricmp(argv[i], "-LOWMEM") == 0)
+				gLowMem = ETrue;
+			else {
+#ifdef WIN32
+				Print (EWarning, "Unrecognised option %s\n",argv[i]);
+#else
+				if(0 == access(argv[i],R_OK)){
+					filename.assign(argv[i]);
+				}
+				else {
+					Print (EWarning, "Unrecognised option %s\n",argv[i]);
+				}
+#endif				
+
+			}
+		}
+		else // Must be the obey filename
+			filename.assign(argv[i]);
+		i++;
+	}
+
+	if (paramFileFlag)
+		return;
+
+	if((gDriveImage == EFalse) && (gSmrImage ==  EFalse) && 
+		(filename.empty() || (gUseCoreImage && gImageFilename.length() == 0))){
+			Print (EAlways, HelpText);
+			if (reallyHelp) {
+				ObeyFileReader::KeywordHelp();
+				Print (EAlways, ReallyHelpText);
+			}
+			else if (filename.empty()){
+				Print(EAlways, "Obey filename is missing\n");
+			}
+	}	
+}
+
+/**
+Function to process parameter-file.
+@param aFileName parameter-file name.
+*/
+void processParamfile(const string& aFileName) {
+
+	CParameterFileProcessor parameterFile(aFileName);
+	// Invoke fuction "ParameterFileProcessor" to process parameter-file.
+	if(parameterFile.ParameterFileProcessor()) {
+		TUint noOfParameters = parameterFile.GetNoOfArguments();
+		char** parameters = parameterFile.GetParameters();
+		TBool paramFileFlag = ETrue;
+
+		// Invoke function "processCommandLine" to process parameters read from parameter-file.
+		processCommandLine(noOfParameters,parameters,paramFileFlag);
+	}	
+}
+
+/**
+Main logic for data drive image creation. Called many types depending on no. of drive obey files.
+
+@param aobeyFileName - Drive obey file.
+@param alogfile      - log file name required for file system module.
+
+@return - returns the status, after processing the drive obey file.
+*/ 
+TInt ProcessDataDriveMain(char* aobeyFileName,char* alogfile) {
+
+	ObeyFileReader *reader = new ObeyFileReader(aobeyFileName);
+
+	if(!reader)
+		return KErrNoMemory;
+
+	if(!reader->Open())
+		return KErrGeneral; 
+		
+	CObeyFile* mainObeyFile = new CObeyFile(*reader);    
+	
+	if(!mainObeyFile)
+		return KErrNoMemory;
+
+	// Process data drive image.
+	// let's clear the TRomNode::sDefaultInitialAttr first, 'cause data drive is different from rom image
+	TRomNode::sDefaultInitialAttr = 0; 
+	TInt retstatus = mainObeyFile->ProcessDataDrive();
+	if (retstatus == KErrNone) {
+		// Build a Data drive image using the description compiled into the CObeyFile object
+		CDriveImage* userImage = new CDriveImage(mainObeyFile);
+		if(userImage) {	
+			// Drive image creation.
+			retstatus = userImage->CreateImage(alogfile);
+			if(retstatus == KErrNone) {
+				Print (EAlways, "\nSuccessfully generated the Drive image : %s \n",mainObeyFile->iDriveFileName);
+			}
+			else {
+				Print (EError, "Failed to generate the Image : %s\n",mainObeyFile->iDriveFileName);
+			}
+			delete userImage; 
+		}
+		else {
+			retstatus = KErrNoMemory;
+		}
+	}
+	// restore
+	TRomNode::sDefaultInitialAttr = (TUint8)KEntryAttReadOnly;
+	cout << "\n-----------------------------------------------------------\n";
+
+	delete mainObeyFile;
+	delete reader;
+	return retstatus;
+}
+
+TInt ProcessSmrImageMain(char* aObeyFileName, char* /* alogfile */) {
+	ObeyFileReader *reader = new ObeyFileReader(aObeyFileName);
+	if(!reader)
+		return KErrNoMemory;
+	if(!reader->Open())
+		return KErrGeneral;
+	TInt retstatus = 0;
+	CObeyFile* mainObeyFile = new CObeyFile(*reader);
+	CSmrImage* smrImage = 0;
+	if(!mainObeyFile)
+		return KErrNoMemory;
+	if(mainObeyFile->Process()) {
+		smrImage = new CSmrImage(mainObeyFile);
+		if(smrImage) {
+			if((retstatus = smrImage->Initialise()) == KErrNone) {
+				retstatus = smrImage->CreateImage();
+			}
+			if(retstatus == KErrNone) {
+				Print (EAlways,  "\nSuccessfully generated the SMR image : %s\n" ,smrImage->GetImageName().c_str());
+			}
+			else {
+				Print (EError, "\nFailed to generate the Image : %s\n" ,smrImage->GetImageName().c_str());
+			}
+			delete smrImage;
+		}
+		else {
+			retstatus = KErrNoMemory;
+		}
+	}
+	delete mainObeyFile;
+	delete reader;
+	return retstatus;
+}
+
+/**
+Rofsbuild Main function, which creates both Rofs and Data drive image.
+
+@param argc    - No. of argument.
+@param *argv[] - Arguments value.
+
+@return - returns the status to caller.
+*/ 
+TInt main(int argc, char *argv[]){
+	TInt r =0;
+#ifdef __LINUX__
+	gCPUNum = sysconf(_SC_NPROCESSORS_CONF);
+#else	
+	char* pCPUNum = getenv ("NUMBER_OF_PROCESSORS");
+	if (pCPUNum != NULL)
+		gCPUNum = atoi(pCPUNum);
+#endif		
+	if(gCPUNum > MAXIMUM_THREADS)
+		gCPUNum = MAXIMUM_THREADS;
+	PrintVersion();
+	processCommandLine(argc, argv);
+	//if the user wants to clean up the cache, do it only.
+	if(gCleanCache){
+		try {
+			CacheManager::GetInstance()->CleanCache();
+			Print (EAlways, "Cache has been deleted successfully.\n");
+		}
+		catch(CacheException& ce){
+			Print (EError, "%s\n", ce.GetErrorMessage());
+			return (TInt)1;
+		}
+		return r;
+	}
+	//initialize cache if the user switches on.
+	if(gCache) {
+		try {
+			CacheManager::GetInstance();
+		}
+		catch(CacheException ce){
+			Print (EError, "%s\n", ce.GetErrorMessage());
+			return (TInt)1;
+		}
+	}
+	const char *obeyFileName = 0;	
+	if(!filename.empty())
+		obeyFileName = filename.c_str(); 
+	if ((!obeyFileName) && (!gDriveFilename.empty()) && (!gSmrFileName.empty())){
+		return KErrGeneral;
+	}
+	if(gThreadNum == 0) {
+		if(gCPUNum > 0) {
+			Print (EWarning, "The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum);
+			gThreadNum = gCPUNum;
+		}
+		else {
+			Print (EWarning, "Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS);
+			gThreadNum = DEFAULT_THREADS;
+		}
+	}
+	// Process drive obey files.
+	if(gDriveImage) {  
+		char temp = 0;
+		char *driveobeyFileName = (char*)_alloca(gDriveFilename.length() + 1);
+		memcpy(driveobeyFileName,gDriveFilename.c_str(),gDriveFilename.length() + 1);
+		char* ptr = driveobeyFileName;
+		do {
+			while(((temp = *ptr++) != ',') && (temp != 0));
+			*(--ptr)++ = 0; 
+
+			if(*driveobeyFileName) {
+				char* logfile = 0;
+				if(Getlogfile(driveobeyFileName,logfile) == KErrNone) {
+					H.SetLogFile(logfile);
+					GetLocalTime();
+					r = ProcessDataDriveMain(driveobeyFileName,logfile);   
+					H.CloseLogFile();
+					delete[] logfile;
+					if(r == KErrNoMemory)
+						return KErrNoMemory;
+				}
+				else {
+					Print(EError,"Invalid obey file name : %s\n", driveobeyFileName);   
+				}
+			}
+			driveobeyFileName = ptr;
+		} while(temp != 0); 
+		gDriveImage = EFalse;
+	} 
+	if(gSmrImage){
+		char temp = 0;
+		char *smrImageObeyFileName = (char*)_alloca(gSmrFileName.length() + 1);
+		memcpy(smrImageObeyFileName,gSmrFileName.c_str(),gSmrFileName.length() + 1);
+		char* ptr = smrImageObeyFileName;
+		do {
+			while(((temp = *ptr++) != ',') && (temp != 0));
+			*(--ptr)++ = 0;
+
+			if(*smrImageObeyFileName){	
+				char * logfile = 0;
+				if(Getlogfile(smrImageObeyFileName,logfile) == KErrNone){
+					H.SetLogFile(logfile);
+					GetLocalTime();
+					r = ProcessSmrImageMain(smrImageObeyFileName, logfile);
+					H.CloseLogFile();
+					delete[] logfile;
+					if(r == KErrNoMemory)
+						return KErrNoMemory;
+				}
+				else {
+					Print(EError,"Invalid obey file name: %s", smrImageObeyFileName);
+				}
+			}
+			smrImageObeyFileName = ptr;
+		} while(temp != 0);
+		gSmrImage = EFalse;
+	}
+	// Process Rofs Obey files.
+	if(obeyFileName) {
+		H.SetLogFile("ROFSBUILD.LOG");		
+		ObeyFileReader *reader = new ObeyFileReader(obeyFileName); 
+		if (!reader->Open())
+			return KErrGeneral;
+
+		E32Rofs* RofsImage = 0;		// for image from obey file
+		CCoreImage *core = 0;		// for image from core image file
+		MRofsImage* imageInfo = 0;
+		CObeyFile *mainObeyFile = new CObeyFile(*reader);
+		// need check if obey file has coreimage keyword
+		char *file = mainObeyFile->ProcessCoreImage();
+		if (file) {
+			// hase coreimage keyword but only use if command line option
+			// for coreimage not already selected
+			if (!gUseCoreImage){
+				gUseCoreImage = ETrue;
+				gImageFilename = file;
+			}
+			delete []file ;
+		}
+		if (!gUseCoreImage) {
+			r = mainObeyFile->ProcessRofs();
+			if (r == KErrNone) {
+				// Build a ROFS image using the description compiled into the CObeyFile object
+				RofsImage = new E32Rofs( mainObeyFile );
+				if( !RofsImage ) {
+					if(gCache || gCleanCache)
+						delete CacheManager::GetInstance();
+					return KErrNoMemory;
+				}
+				r = RofsImage->Create();
+
+				if( KErrNone == r )	{
+					RofsImage->WriteImage( gHeaderType );
+				}
+				imageInfo = RofsImage;
+				mainObeyFile->Release();
+				if(gCache || gCleanCache)
+					delete CacheManager::GetInstance();
+			}
+			else if (r != KErrNotFound){
+				return r;
+			}
+		}
+		else {
+			// need to use core image
+			RCoreImageReader *reader = new RCoreImageReader(gImageFilename.c_str());
+			if (!reader) {
+				return KErrNoMemory;
+			}
+			core = new CCoreImage(reader);
+			if (!core) {
+				return KErrNoMemory;
+			}
+			r = core->ProcessImage();
+			if (r != KErrNone) {
+				return r;
+			}
+			imageInfo = core;
+			mainObeyFile->SkipToExtension();
+		}
+
+		do {
+			CObeyFile* extensionObeyFile = new CObeyFile(*reader);
+			r = extensionObeyFile->ProcessExtensionRofs(imageInfo);
+			if (r == KErrEof){
+				if(RofsImage){
+					delete RofsImage;
+				}
+				if(core){
+					delete core;
+				}
+				delete extensionObeyFile;
+				return KErrNone;
+			}
+			if (r != KErrNone){
+				break;
+			}
+			E32Rofs* extensionRofs = new E32Rofs(extensionObeyFile);
+			r = extensionRofs->CreateExtension(imageInfo);
+			if (r!= KErrNone){
+				delete extensionRofs;
+				delete extensionObeyFile;
+				break;
+			}
+			r = extensionRofs->WriteImage(0);	
+
+			delete extensionRofs;
+			extensionRofs = 0;
+		} while (r == KErrNone);
+		if(RofsImage) {
+			delete RofsImage;									
+		}
+		if(core){
+			delete core;
+		}
+		delete mainObeyFile;
+	}
+	return r;
+}//end of main.