imgtools/romtools/rofsbuild/rofsbuild.cpp
changeset 0 044383f39525
child 590 360bd6b35136
child 606 30b30f9da0b7
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 /*
       
     2 * Copyright (c) 1996-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 * @internalComponent * @released
       
    16 * Rofsbuild mainfile to generate both rofs and data drive image.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <string.h>
       
    22 #include <stdlib.h>
       
    23 #include <f32file.h>
       
    24 #include "e32image.h"
       
    25 #include "h_utl.h"
       
    26 #include "h_ver.h"
       
    27 #include "r_obey.h"
       
    28 #include "r_driveimage.h"
       
    29 #include "r_driveutl.h"
       
    30 #include "r_coreimage.h"
       
    31 #include "parameterfileprocessor.h"
       
    32 #include "r_smrimage.h"
       
    33 
       
    34 static const TInt RofsbuildMajorVersion=2;
       
    35 static const TInt RofsbuildMinorVersion=6;
       
    36 static const TInt RofsbuildPatchVersion=5;
       
    37 static TBool SizeSummary=EFalse;
       
    38 static TPrintType SizeWhere=EAlways;
       
    39 
       
    40 static TInt gHeaderType=1;			// EPOC header
       
    41 static TInt MAXIMUM_THREADS = 128;
       
    42 static TInt DEFAULT_THREADS = 8;
       
    43 ECompression gCompress=ECompressionUnknown;
       
    44 TUint  gCompressionMethod=0;
       
    45 TBool gFastCompress = EFalse;
       
    46 TInt gThreadNum = 0;
       
    47 TInt gCPUNum = 0;
       
    48 char* g_pCharCPUNum = NULL;
       
    49 TInt gCodePagingOverride = -1;
       
    50 TInt gDataPagingOverride = -1;
       
    51 TInt gLogLevel = 0;	// Information is logged based on logging level.
       
    52 					// The default is 0. So all the existing logs are generated as if gLogLevel = 0.
       
    53 					// If any extra information required, the log level must be appropriately supplied.
       
    54 					// Currrently, file details in ROM (like, file name in ROM & host, file size, whether 
       
    55 					// the file is hidden etc) are logged when gLogLevel >= LOG_LEVEL_FILE_DETAILS.
       
    56 
       
    57 TBool gUseCoreImage=EFalse; // command line option for using core image file
       
    58 char* gImageFilename=NULL;	// instead of obey file
       
    59 TBool gEnableStdPathWarning=EFalse;// for in-correct destination path warning(executables).
       
    60 TBool gLowMem=EFalse;
       
    61 
       
    62 extern TBool gDriveImage;		// to Support data drive image.
       
    63 TText* gDriveFilename=NULL;		// input drive oby filename.
       
    64 
       
    65 string filename;				// to store oby filename passed to Rofsbuild.
       
    66 TBool reallyHelp=EFalse;	
       
    67 
       
    68 TBool gSmrImage = EFalse;
       
    69 TText* gSmrFileName = NULL;
       
    70 
       
    71 void PrintVersion()
       
    72 	{
       
    73 		Print(EAlways,"\nROFSBUILD - Rofs/Datadrive image builder");
       
    74 		Print(EAlways, " V%d.%d.%d\n", RofsbuildMajorVersion, RofsbuildMinorVersion, RofsbuildPatchVersion);
       
    75 		Print(EAlways,Copyright);
       
    76 	}
       
    77 
       
    78 char HelpText[] = 
       
    79 	"Syntax: ROFSBUILD [options] obeyfilename(Rofs)\n"
       
    80 	"Option: -v verbose,  -?,  -s[log|screen|both] size summary\n"
       
    81 	"        -d<bitmask> set trace mask (DEB build only)\n"
       
    82 	"        -compress   compress executable files where possible\n"
       
    83 	"        -fastcompress  compress files with faster bytepair and tradeoff of compress ratio\n"
       
    84 	"        -j<digit> do the main job with <digit> threads\n"
       
    85 	"        -compressionmethod none|inflate|bytepair to set the compression\n"
       
    86 	"              none     uncompress the image.\n"
       
    87 	"              inflate  compress the image.\n"
       
    88 	"              bytepair compress the image.\n"
       
    89 	"        -coreimage <core image file>\n"
       
    90 	"        -datadrive=<drive obyfile1>,<drive obyfile2>,... for driveimage creation\n"
       
    91 	"              user can also input rofs oby file if required to generate both.\n"
       
    92 	"        -smr=<SMR obyfile1>,<SMR obyfile2>,... for SMR partition creation\n"
       
    93 	"        -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.
       
    94 	"        -wstdpath   warn if destination path provided for a file is not the standard path\n"
       
    95 	"        -argfile=<FileName>   specify argument-file name containing list of command-line arguments\n"
       
    96 	"        -lowmem     use memory-mapped file for image build to reduce physical memory consumption\n";
       
    97 
       
    98 char ReallyHelpText[] =
       
    99 	"Log Level:\n"
       
   100 	"        0  produce the default logs\n"
       
   101 	"        1  produce file detail logs in addition to the default logs\n"
       
   102 	"        2  logs e32 header attributes in addition to the level 1 details\n";
       
   103 
       
   104 void processParamfile(string aFileName);
       
   105 
       
   106 /**
       
   107 Process the command line arguments and prints the helpful message if none are supplied.
       
   108 @param argc    - No. of argument.
       
   109 @param *argv[] - Arguments value.
       
   110 */ 
       
   111 void processCommandLine(int argc, char *argv[], TBool paramFileFlag=EFalse)
       
   112 {
       
   113 	// If "-argfile" option is passed to rofsbuild, then process the parameters
       
   114 	// specified in parameter-file first and then the options passed from the 
       
   115 	// command-line.
       
   116 	string ParamFileArg("-ARGFILE=");	
       
   117 	if(paramFileFlag == EFalse)
       
   118 	{	
       
   119 		for (int count=1; count<argc; count++)
       
   120 		{
       
   121 			string paramFile;
       
   122 			strupr(argv[count]);
       
   123 			if(strncmp(argv[count],ParamFileArg.c_str(),ParamFileArg.length())==0)
       
   124 			{
       
   125 				paramFile.assign(&argv[count][ParamFileArg.length()]);									
       
   126 				processParamfile(paramFile);
       
   127 			}
       
   128 		}
       
   129 	}	
       
   130 
       
   131 	int i=1;
       
   132 	while (i<argc)
       
   133 		{
       
   134 		strupr(argv[i]);
       
   135 		if ((argv[i][0] == '-') || (argv[i][0] == '/'))
       
   136 			{ // switch
       
   137 			if (argv[i][1] == 'V')
       
   138 				H.iVerbose = ETrue;
       
   139 			else if(strncmp (argv[i], "-SMR=", 5) == 0)
       
   140 			{
       
   141 				if(argv[i][5])
       
   142 				{
       
   143 					gSmrImage = ETrue;
       
   144 					gSmrFileName = (TText*)strdup(&argv[i][5]);
       
   145 				}
       
   146 				else
       
   147 				{
       
   148 					Print (EError, "SMR obey file is missing\n");
       
   149 				}
       
   150 			}
       
   151 			else if (argv[i][1] == 'S')
       
   152 				{
       
   153 				SizeSummary=ETrue;
       
   154 				if (argv[i][2] == 'L')
       
   155 					SizeWhere=ELog;
       
   156 				if (argv[i][2] == 'S')
       
   157 					SizeWhere=EScreen;
       
   158 				}
       
   159 			else if (strncmp(argv[i],ParamFileArg.c_str(),ParamFileArg.length())==0)
       
   160 				{
       
   161 					if (paramFileFlag)
       
   162 					{
       
   163 						String paramFile;
       
   164 						paramFile.assign(&argv[i][ParamFileArg.length()]);		
       
   165 						processParamfile(paramFile);
       
   166 					}
       
   167 					else
       
   168 					{
       
   169 						i++;
       
   170 						continue;
       
   171 					}
       
   172 				}
       
   173 			else if (strcmp(argv[i], "-COMPRESS")==0)
       
   174 				{
       
   175 				gCompress=ECompressionCompress;
       
   176 				gCompressionMethod = KUidCompressionDeflate;
       
   177 				}
       
   178 			else if (strcmp(argv[i], "-FASTCOMPRESS")==0)
       
   179 				{
       
   180 				gFastCompress=ETrue;
       
   181 				}
       
   182 			else if (strncmp(argv[i], "-J",2)==0)
       
   183 				{
       
   184 					if(argv[i][2])
       
   185 						gThreadNum = atoi(&argv[i][2]);
       
   186 					else
       
   187 						{
       
   188 						printf("WARNING: The option should be like '-j4'.\n");
       
   189 						gThreadNum = 0;
       
   190 						}
       
   191 					if(gThreadNum <= 0 || gThreadNum > MAXIMUM_THREADS)
       
   192 						{
       
   193 						if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS)
       
   194 							{
       
   195 							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);
       
   196 							gThreadNum = gCPUNum;
       
   197 							}
       
   198 						else if(g_pCharCPUNum)
       
   199 							{
       
   200 							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);
       
   201 							gThreadNum = DEFAULT_THREADS;
       
   202 							}
       
   203 						else
       
   204 							{
       
   205 							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);
       
   206 							gThreadNum = DEFAULT_THREADS;
       
   207 							}
       
   208 						}
       
   209 				}
       
   210 			else if (strcmp(argv[i], "-UNCOMPRESS")==0)
       
   211 				{
       
   212 				gCompress=ECompressionUncompress;
       
   213 				}
       
   214 			else if( strcmp(argv[i], "-COMPRESSIONMETHOD") == 0 )
       
   215 				{
       
   216 					// next argument should a be method
       
   217 					if( (i+1) >= argc || argv[i+1][0] == '-') 
       
   218 					{
       
   219 					Print (EError, "Missing compression method! Set it to default (no compression)!");
       
   220 					gCompressionMethod = 0;
       
   221 					}
       
   222 					else 
       
   223 					{
       
   224 					i++;
       
   225 					strupr(argv[i]);
       
   226 					if( strcmp(argv[i], "NONE") == 0)	
       
   227 						{
       
   228 						gCompress=ECompressionUncompress;
       
   229 						gCompressionMethod = 0;	
       
   230 						}
       
   231 					else if( strcmp(argv[i], "INFLATE") == 0)
       
   232 						{
       
   233 						gCompress=ECompressionCompress;
       
   234 						gCompressionMethod = KUidCompressionDeflate;	
       
   235 						}	
       
   236 					else if( strcmp(argv[i], "BYTEPAIR") == 0)
       
   237 						{
       
   238 						gCompress=ECompressionCompress;
       
   239 						gCompressionMethod = KUidCompressionBytePair;	
       
   240 						}
       
   241 					else
       
   242 						{
       
   243 						Print (EError, "Unknown compression method! Set it to default (no compression)!");
       
   244 						gCompress=ECompressionUnknown;
       
   245 						gCompressionMethod = 0;		
       
   246 						}
       
   247 					}
       
   248 					
       
   249 				}
       
   250 			else if (strcmp(argv[i], "-COREIMAGE") ==0)
       
   251 				{
       
   252 					gUseCoreImage = ETrue;
       
   253 
       
   254 					// next argument should be image filename
       
   255 					if ((i+1 >= argc) || argv[i+1][0] == '-')
       
   256 						Print (EError, "Missing image file name");
       
   257 					else
       
   258 					{
       
   259 						i++;
       
   260 						gImageFilename = strdup(argv[i]);
       
   261 					}
       
   262 				}
       
   263 			else if (strncmp(argv[i], "-DATADRIVE=",11) ==0)
       
   264 				{  
       
   265 				   	if(argv[i][11])	
       
   266 						{
       
   267 						gDriveImage = ETrue; 
       
   268 						gDriveFilename = (TText*)strdup(&argv[i][11]);	
       
   269 						}
       
   270 					else
       
   271 						{
       
   272 						Print (EError, "Drive obey file is missing\n"); 
       
   273 						}
       
   274 				}
       
   275 			else if (argv[i][1] == '?')
       
   276 				{
       
   277 				reallyHelp=ETrue;
       
   278 				}
       
   279  			else if (strcmp(argv[i], "-WSTDPATH") ==0)		// Warn if destination path provided for a executables are incorrect as per platsec.		
       
   280  				{
       
   281  				gEnableStdPathWarning=ETrue;						
       
   282  				}
       
   283 			
       
   284 			else if( strcmp(argv[i], "-LOGLEVEL") == 0)
       
   285 				{
       
   286 				// next argument should a be loglevel
       
   287 				if( (i+1) >= argc || argv[i+1][0] == '-')
       
   288 					{
       
   289 					Print (EError, "Missing loglevel!");
       
   290 					gLogLevel = DEFAULT_LOG_LEVEL;
       
   291 					}
       
   292 				else
       
   293 					{
       
   294 					i++;
       
   295 					if (strcmp(argv[i], "2") == 0)
       
   296 						gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
       
   297 					if (strcmp(argv[i], "1") == 0)
       
   298 						gLogLevel = LOG_LEVEL_FILE_DETAILS;
       
   299 					else if (strcmp(argv[i], "0") == 0)
       
   300 						gLogLevel = DEFAULT_LOG_LEVEL;
       
   301 					else
       
   302 						Print(EError, "Only loglevel 0, 1 or 2 is allowed!");
       
   303 					}
       
   304 				}
       
   305 			else if( strcmp(argv[i], "-LOGLEVEL2") == 0)
       
   306 				gLogLevel = (LOG_LEVEL_FILE_DETAILS | LOG_LEVEL_FILE_ATTRIBUTES);
       
   307 			else if( strcmp(argv[i], "-LOGLEVEL1") == 0)
       
   308 				gLogLevel = LOG_LEVEL_FILE_DETAILS;
       
   309 			else if( strcmp(argv[i], "-LOGLEVEL0") == 0)
       
   310 				gLogLevel = DEFAULT_LOG_LEVEL;
       
   311 			else if (strcmp(argv[i], "-LOWMEM") == 0)
       
   312 				gLowMem = ETrue;
       
   313 			else 
       
   314 				cout << "Unrecognised option " << argv[i] << "\n";
       
   315 			}
       
   316 		else // Must be the obey filename
       
   317 			filename=argv[i];
       
   318 		i++;
       
   319 		}
       
   320 	
       
   321 		if (paramFileFlag)
       
   322 		return;
       
   323 
       
   324 		if((gDriveImage == EFalse) && (gSmrImage ==  EFalse) && (filename.empty() || (gUseCoreImage && gImageFilename == NULL)))
       
   325 		{
       
   326 		PrintVersion();
       
   327 		cout << HelpText;
       
   328 		if (reallyHelp)
       
   329 			{
       
   330 			ObeyFileReader::KeywordHelp();
       
   331 			cout << ReallyHelpText;
       
   332 			}
       
   333 		else if (filename.empty())
       
   334 			{
       
   335 			Print(EError, "Obey filename is missing\n");
       
   336 			}
       
   337 		}	
       
   338 	}
       
   339 
       
   340 /**
       
   341 Function to process parameter-file. 
       
   342 
       
   343 @param aFileName parameter-file name.
       
   344 */
       
   345 void processParamfile(string aFileName)
       
   346 {
       
   347 	CParameterFileProcessor parameterFile(aFileName);
       
   348 	
       
   349 	// Invoke fuction "ParameterFileProcessor" to process parameter-file.
       
   350 	if(parameterFile.ParameterFileProcessor())
       
   351 	{
       
   352 		TUint noOfParameters = parameterFile.GetNoOfArguments();
       
   353 		char** parameters = parameterFile.GetParameters();
       
   354 		TBool paramFileFlag=ETrue;
       
   355 
       
   356 		// Invoke function "processCommandLine" to process parameters read from parameter-file.
       
   357 		processCommandLine(noOfParameters,parameters,paramFileFlag);
       
   358 	}	
       
   359 }
       
   360 
       
   361 /**
       
   362 Main logic for data drive image creation. Called many types depending on no. of drive obey files.
       
   363 
       
   364 @param aobeyFileName - Drive obey file.
       
   365 @param alogfile      - log file name required for file system module.
       
   366  
       
   367 @return - returns the status, after processing the drive obey file.
       
   368 */ 
       
   369 TInt ProcessDataDriveMain(TText* aobeyFileName,TText* alogfile)
       
   370 	{
       
   371 
       
   372 	ObeyFileReader *reader=new ObeyFileReader(aobeyFileName);
       
   373 
       
   374 	if(!reader)
       
   375 		return KErrNoMemory;
       
   376 
       
   377 	if(!reader->Open())
       
   378     {
       
   379         if (reader)
       
   380         {
       
   381             delete reader;
       
   382         }
       
   383 		return KErrGeneral;
       
   384     }
       
   385 
       
   386 	TInt retstatus =0;		
       
   387 	CObeyFile* mainObeyFile=new CObeyFile(*reader);   
       
   388 	CDriveImage* userImage = 0; 
       
   389 
       
   390 	if(!mainObeyFile)
       
   391     {
       
   392         if (reader)
       
   393         {
       
   394             delete reader;
       
   395         }
       
   396 		return KErrNoMemory;
       
   397     }
       
   398 
       
   399 	// Process data drive image.
       
   400 	// let's clear the TRomNode::sDefaultInitialAttr first, 'cause data drive is different from rom image
       
   401 	TRomNode::sDefaultInitialAttr = 0; 
       
   402 	retstatus = mainObeyFile->ProcessDataDrive();
       
   403 	if (retstatus == KErrNone)
       
   404 		{
       
   405 		// Build a Data drive image using the description compiled into the CObeyFile object
       
   406 		userImage = new CDriveImage(mainObeyFile);
       
   407 		if(userImage)
       
   408 			{	
       
   409 			// Drive image creation.
       
   410 			retstatus = userImage->CreateImage(alogfile);
       
   411 			if(retstatus == KErrNone)
       
   412 				{
       
   413 				cout << "\nSuccessfully generated the Drive image : " << mainObeyFile->iDriveFileName << "\n";
       
   414 				}
       
   415 			else
       
   416 				{
       
   417 				cout << "\nFailed to generate the Image : " << mainObeyFile->iDriveFileName << "\n";
       
   418 				}
       
   419 
       
   420 			delete userImage;
       
   421 			userImage = 0;
       
   422 			}
       
   423 		else
       
   424 			{
       
   425 			retstatus = KErrNoMemory;
       
   426 			}
       
   427 		}
       
   428 	// restore
       
   429 	TRomNode::sDefaultInitialAttr = (TUint8)KEntryAttReadOnly;
       
   430 	cout << "\n-----------------------------------------------------------\n";
       
   431 	
       
   432 	delete mainObeyFile;
       
   433 	delete reader;
       
   434 	return retstatus;
       
   435 	}
       
   436 
       
   437 TInt ProcessSmrImageMain(TText* aObeyFileName, TText* /* alogfile */)
       
   438 {
       
   439 	ObeyFileReader *reader = new ObeyFileReader(aObeyFileName);
       
   440 	if(!reader)
       
   441 		return KErrNoMemory;
       
   442 	if(!reader->Open())
       
   443     {
       
   444         if (reader)
       
   445         {
       
   446             delete reader;
       
   447         }
       
   448 		return KErrGeneral;
       
   449     }
       
   450 	TInt retstatus = 0;
       
   451 	CObeyFile* mainObeyFile = new CObeyFile(*reader);
       
   452 	CSmrImage* smrImage = 0;
       
   453 	if(!mainObeyFile)
       
   454     {
       
   455         if (reader)
       
   456         {
       
   457             delete reader;
       
   458         }
       
   459 		return KErrNoMemory;
       
   460     }
       
   461 
       
   462 	if(mainObeyFile->Process())
       
   463 	{
       
   464 		smrImage = new CSmrImage(mainObeyFile);
       
   465 		if(smrImage)
       
   466 		{
       
   467 			if((retstatus=smrImage->Initialise()) == KErrNone)
       
   468 			{
       
   469 				retstatus = smrImage->CreateImage();
       
   470 			}
       
   471 			if(retstatus == KErrNone)
       
   472 			{
       
   473 				cout << "\nSuccessfully generated the SMR image : " << smrImage->GetImageName().c_str() << "\n";
       
   474 			}
       
   475 			else
       
   476 			{
       
   477 				cout << "\nFailed to generate the Image : " << smrImage->GetImageName().c_str() << "\n";
       
   478 			}
       
   479 			delete smrImage;
       
   480 		}
       
   481 		else
       
   482 		{
       
   483 			retstatus = KErrNoMemory;
       
   484 		}
       
   485 	}
       
   486 	delete mainObeyFile;
       
   487 	delete reader;
       
   488 	return retstatus;
       
   489 }
       
   490 
       
   491 /**
       
   492 Rofsbuild Main function, which creates both Rofs and Data drive image.
       
   493 
       
   494 @param argc    - No. of argument.
       
   495 @param *argv[] - Arguments value.
       
   496   
       
   497 @return - returns the status to caller.
       
   498 */ 
       
   499 TInt main(int argc, char *argv[])
       
   500 {
       
   501 	TInt r =0;	
       
   502 
       
   503 	g_pCharCPUNum = getenv("NUMBER_OF_PROCESSORS");
       
   504 	if(g_pCharCPUNum != NULL)
       
   505 		gCPUNum = atoi(g_pCharCPUNum);
       
   506 
       
   507  	processCommandLine(argc, argv);
       
   508 
       
   509  	TText *obeyFileName = NULL;	
       
   510  	if(!filename.empty())
       
   511  		obeyFileName=(TText*)filename.c_str();	
       
   512 
       
   513 	if ((obeyFileName==NULL) && (gDriveFilename==NULL) && (gSmrFileName == NULL))                   
       
   514 		return KErrGeneral;
       
   515 	
       
   516 	if(gThreadNum == 0)
       
   517 	{
       
   518 		if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS)
       
   519 		{
       
   520 			printf("The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum);
       
   521 			gThreadNum = gCPUNum;
       
   522 		}
       
   523 		else if(g_pCharCPUNum)
       
   524 		{
       
   525 			printf("WARNING: The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS);
       
   526 			gThreadNum = DEFAULT_THREADS;
       
   527 		}
       
   528 		else
       
   529 		{
       
   530 			printf("WARNING: The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS);
       
   531 			gThreadNum = DEFAULT_THREADS;
       
   532 		}
       
   533 	}
       
   534 
       
   535 	// Process drive obey files.
       
   536 	if(gDriveImage)
       
   537 	{  
       
   538 		TText temp = 0;
       
   539 		TText *driveobeyFileName = gDriveFilename;
       
   540 		
       
   541 		do
       
   542 		{
       
   543 			while(((temp = *gDriveFilename++) != ',') && (temp != 0));
       
   544 			*(--gDriveFilename)++ = 0;
       
   545 			
       
   546 			if(*driveobeyFileName)
       
   547 			{	
       
   548 				TText* logfile = 0;
       
   549 				if(Getlogfile(driveobeyFileName,logfile)== KErrNone)
       
   550 				{
       
   551 					H.SetLogFile(logfile);	
       
   552 					PrintVersion();
       
   553 					GetLocalTime();
       
   554 					r = ProcessDataDriveMain(driveobeyFileName,logfile);   
       
   555 					H.CloseLogFile();
       
   556 					delete[] logfile;
       
   557 					if(r == KErrNoMemory)
       
   558 						return KErrNoMemory;
       
   559 				}
       
   560 				else
       
   561 				{
       
   562 					cout << "Error : Invalid obey file name : " << driveobeyFileName << "\n" ;   
       
   563 				}
       
   564 			}
       
   565 			driveobeyFileName = gDriveFilename;
       
   566 		}
       
   567 		while(temp != 0);   
       
   568 		
       
   569 		gDriveImage=EFalse;
       
   570 	} 
       
   571 	if(gSmrImage)
       
   572 	{
       
   573 		TText temp = 0;
       
   574 		TText *smrImageObeyFileName = gSmrFileName;
       
   575 		do
       
   576 		{
       
   577 			while(((temp = *gSmrFileName++) != ',') && (temp != 0));
       
   578 			*(--gSmrFileName)++ = 0;
       
   579 			if(*smrImageObeyFileName)
       
   580 			{	
       
   581 				TText * logfile = 0;
       
   582 				if(Getlogfile(smrImageObeyFileName,logfile) == KErrNone)
       
   583 				{
       
   584 					H.SetLogFile(logfile);
       
   585 					PrintVersion();
       
   586 					GetLocalTime();
       
   587 					r = ProcessSmrImageMain(smrImageObeyFileName, logfile);
       
   588 					H.CloseLogFile();
       
   589 					delete[] logfile;
       
   590 					if(r == KErrNoMemory)
       
   591 						return KErrNoMemory;
       
   592 				}
       
   593 				else
       
   594 				{
       
   595 					cout << "Error: Invalid obey file name: " << smrImageObeyFileName << "\n";
       
   596 				}
       
   597 			}
       
   598 			smrImageObeyFileName = gSmrFileName;
       
   599 		}
       
   600 		while(temp != 0);
       
   601 		gSmrImage = EFalse;
       
   602 	}
       
   603 	// Process Rofs Obey files.
       
   604 	if(obeyFileName)
       
   605 	{
       
   606 		
       
   607 		H.SetLogFile((unsigned char *)"ROFSBUILD.LOG");	
       
   608 		PrintVersion();
       
   609 		
       
   610 		ObeyFileReader *reader=new ObeyFileReader(obeyFileName);
       
   611 		if (!reader->Open())
       
   612 			return KErrGeneral;
       
   613 		
       
   614 		E32Rofs* RofsImage = 0;		// for image from obey file
       
   615 		CCoreImage *core= 0;		// for image from core image file
       
   616 		MRofsImage* imageInfo=0;
       
   617 		CObeyFile *mainObeyFile=new CObeyFile(*reader);
       
   618 		
       
   619 		// need check if obey file has coreimage keyword
       
   620 		TText *file = mainObeyFile->ProcessCoreImage();
       
   621 		if (file)
       
   622 		{
       
   623 			// hase coreimage keyword but only use if command line option
       
   624 			// for coreimage not already selected
       
   625 			if (!gUseCoreImage)
       
   626 			{
       
   627 				gUseCoreImage = ETrue;
       
   628 				gImageFilename = (char *)file;
       
   629 			}
       
   630 		}
       
   631 		
       
   632 		if (!gUseCoreImage)
       
   633 		{
       
   634 			
       
   635 			r=mainObeyFile->ProcessRofs();
       
   636 			if (r==KErrNone)
       
   637 			{
       
   638 				// Build a ROFS image using the description compiled into the
       
   639 				// CObeyFile object
       
   640 				
       
   641 				RofsImage = new E32Rofs( mainObeyFile );
       
   642 				if( !RofsImage )
       
   643 				{
       
   644 					return KErrNoMemory;
       
   645 				}
       
   646 				
       
   647 				r = RofsImage->Create();
       
   648 				if( KErrNone == r )
       
   649 				{
       
   650 					if(SizeSummary)
       
   651 						RofsImage->DisplaySizes(SizeWhere);
       
   652 					RofsImage->WriteImage( gHeaderType );
       
   653 				}
       
   654 				imageInfo = RofsImage;
       
   655 				mainObeyFile->Release();
       
   656 			}
       
   657 			else if (r!=KErrNotFound)
       
   658 				return r;
       
   659 		}
       
   660 		else
       
   661 		{
       
   662 			
       
   663 			// need to use core image
       
   664 			RCoreImageReader *reader = new RCoreImageReader(gImageFilename);
       
   665 			if (!reader)
       
   666 			{
       
   667 				return KErrNoMemory;
       
   668 			}
       
   669 			core= new CCoreImage(reader);
       
   670 			if (!core)
       
   671 			{
       
   672 				return KErrNoMemory;
       
   673 			}
       
   674 			r = core->ProcessImage();
       
   675 			if (r != KErrNone)
       
   676 				return r;
       
   677 			imageInfo = core;
       
   678 			mainObeyFile->SkipToExtension();
       
   679 			
       
   680 		}
       
   681 		
       
   682 		do 
       
   683 		{
       
   684 			CObeyFile* extensionObeyFile = 0;
       
   685 			E32Rofs* extensionRofs = 0;
       
   686 			
       
   687 			extensionObeyFile = new CObeyFile(*reader);
       
   688 			r = extensionObeyFile->ProcessExtensionRofs(imageInfo);
       
   689 			if (r==KErrEof)
       
   690 			{
       
   691 				if(RofsImage)
       
   692 					delete RofsImage;
       
   693 				if(core)
       
   694 					delete core;
       
   695 				delete extensionObeyFile;
       
   696 				return KErrNone;
       
   697 			}
       
   698 			if (r!=KErrNone)
       
   699 				break;
       
   700 			
       
   701 			extensionRofs = new E32Rofs(extensionObeyFile);
       
   702 			r=extensionRofs->CreateExtension(imageInfo);
       
   703 			if (r!=KErrNone)
       
   704 			{
       
   705 				delete extensionRofs;
       
   706 				delete extensionObeyFile;
       
   707 				break;
       
   708 			}
       
   709 			if(SizeSummary)
       
   710 				RofsImage->DisplaySizes(SizeWhere);
       
   711 			r=extensionRofs->WriteImage(0);		
       
   712 			delete extensionRofs;
       
   713 			delete extensionObeyFile;
       
   714 			extensionRofs = 0;
       
   715 			extensionObeyFile = 0;
       
   716 			
       
   717 		}
       
   718 		while (r==KErrNone);
       
   719 		
       
   720 		if(RofsImage) 
       
   721 			delete RofsImage;									
       
   722 		if(core)
       
   723 			delete core;
       
   724 		delete mainObeyFile;
       
   725 		
       
   726 	}
       
   727 	return r;
       
   728 }//end of main.