--- a/imgtools/romtools/rofsbuild/rofsbuild.cpp Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/romtools/rofsbuild/rofsbuild.cpp Wed Jun 23 16:56:47 2010 +0800
@@ -1,728 +1,677 @@
-/*
-* 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=10;
+static const TInt RofsbuildPatchVersion=4;
+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
+ cout << "Unrecognised option " << argv[i] << "\n";
+#else
+ if(0 == access(argv[i],R_OK)){
+ filename.assign(argv[i]);
+ }
+ else {
+ cout << "Unrecognised option " << argv[i] << "\n";
+ }
+#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))){
+ 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(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) {
+ cout << "\nSuccessfully generated the Drive image : " << mainObeyFile->iDriveFileName << "\n";
+ }
+ else {
+ cout << "\nFailed to generate the Image : " << mainObeyFile->iDriveFileName << "\n";
+ }
+ 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) {
+ 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;
+#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;
+ processCommandLine(argc, argv);
+ //if the user wants to clean up the cache, do it only.
+ if(gCleanCache){
+ try {
+ CacheManager::GetInstance()->CleanCache();
+ printf("Cache has been deleted successfully.\r\n");
+ }
+ catch(CacheException& ce){
+ printf("%s\r\n", ce.GetErrorMessage());
+ return (TInt)1;
+ }
+ return r;
+ }
+ //initialize cache if the user switches on.
+ if(gCache) {
+ try {
+ CacheManager::GetInstance();
+ }
+ catch(CacheException ce){
+ printf("%s\r\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) {
+ printf("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;
+ }
+ }
+ // 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);
+ 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 = 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);
+ 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 = ptr;
+ } while(temp != 0);
+ gSmrImage = EFalse;
+ }
+ // Process Rofs Obey files.
+ if(obeyFileName) {
+ H.SetLogFile("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
+ 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;
+ delete extensionObeyFile;
+ extensionRofs = 0;
+ extensionObeyFile = 0;
+ } while (r == KErrNone);
+ if(RofsImage) {
+ delete RofsImage;
+ }
+ if(core){
+ delete core;
+ }
+ delete mainObeyFile;
+ }
+ return r;
+}//end of main.