imgtools/romtools/rofsbuild/r_build.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
child 626 ac03b93ca9c4
equal deleted inserted replaced
588:c7c26511138f 590:360bd6b35136
    24 #include <e32std_private.h>
    24 #include <e32std_private.h>
    25 #include <e32rom.h>
    25 #include <e32rom.h>
    26 #include <u32std.h>
    26 #include <u32std.h>
    27 #include <e32uid.h>
    27 #include <e32uid.h>
    28 #include <f32file.h>
    28 #include <f32file.h>
    29 
    29 #include <malloc.h>
    30 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
    30 #include <map>
    31 	#include <iomanip>
    31 #include <queue> 
    32 	#include <strstream>
    32 #include <iomanip>
    33 #else //!__MSVCDOTNET__
    33 #include <strstream>
    34 	#include <iomanip.h>
    34 #include "utf16string.h"
    35 #endif //__MSVCDOTNET__
       
    36 
       
    37 #ifdef _L
    35 #ifdef _L
    38 #undef _L
    36 #undef _L
       
    37 #endif
       
    38 #ifdef __LINUX__
       
    39 #define _alloca alloca
    39 #endif
    40 #endif
    40 
    41 
    41 #include "h_utl.h"
    42 #include "h_utl.h"
    42 #include "r_obey.h"
    43 #include "r_obey.h"
    43 #include "rofs.h"
    44 #include "rofs.h"
    44 #include "e32image.h"
    45 #include "e32image.h"
    45 #include "patchdataprocessor.h"
    46 #include "patchdataprocessor.h"
    46 
    47 
       
    48 #include <filesystem.hpp>
       
    49 #include <thread/thread.hpp>
       
    50 #include <thread/mutex.hpp>
       
    51 #include <thread/condition_variable.hpp>
       
    52 
       
    53 #include "cache/cacheexception.hpp"
       
    54 #include "cache/cacheentry.hpp"
       
    55 #include "cache/cache.hpp"
       
    56 #include "cache/cachegenerator.hpp"
       
    57 #include "cache/cachevalidator.hpp"
       
    58 #include "cache/cacheablelist.hpp"
       
    59 #include "cache/cachemanager.hpp"
       
    60 
    47 extern TUint checkSum(const void* aPtr);
    61 extern TUint checkSum(const void* aPtr);
    48 
    62 
    49 extern ECompression gCompress;
    63 extern ECompression gCompress;
    50 extern TUint gCompressionMethod;
    64 extern TUint gCompressionMethod;
    51 extern TInt  gCodePagingOverride;
    65 extern TInt  gCodePagingOverride;
    52 extern TInt  gDataPagingOverride;
    66 extern TInt  gDataPagingOverride;
    53 extern TInt  gLogLevel;
    67 extern TInt  gLogLevel;
       
    68 extern bool gCache;
    54 TBool gDriveImage=EFalse;	// for drive image support.
    69 TBool gDriveImage=EFalse;	// for drive image support.
    55 
    70 
    56 
    71 
    57 TInt TRomNode::Count=0;
    72 TInt TRomNode::Count=0;
    58 TRomNode* TRomNode::TheFirstNode = NULL;
    73 TRomNode* TRomNode::TheFirstNode = NULL;
   104 	temp2[i]=0;
   119 	temp2[i]=0;
   105 
   120 
   106 	return stricmp((const char*)&temp1[0], (const char*)&temp2[0]);
   121 	return stricmp((const char*)&temp1[0], (const char*)&temp2[0]);
   107 	}
   122 	}
   108 
   123 
   109 TRomNode::TRomNode(TText* aName, TRomBuilderEntry* aEntry)
   124 TRomNode::TRomNode(const char* aName, TRomBuilderEntry* aEntry)
   110 //
   125 //
   111 // Constructor
   126 // Constructor
   112 //
   127 //
   113 	:
   128 	:
   114 	iNextNode(NULL),
   129 	iNextNode(NULL),
   115 	iParent(NULL), iSibling(0), iChild(0), iNextNodeForSameFile(0), 
   130 	iParent(NULL), iSibling(0), iChild(0), iNextNodeForSameFile(0),
   116 	iTotalDirectoryBlockSize(0),
   131 	iTotalDirectoryBlockSize(0),
   117 	iTotalFileBlockSize(0),
   132 	iTotalFileBlockSize(0),
   118 	iImagePosition(0),
   133 	iImagePosition(0),
   119 	iFileBlockPosition(0),
   134 	iFileBlockPosition(0),
   120 	iAtt(sDefaultInitialAttr),
   135 	iAtt(sDefaultInitialAttr),
   121 	iAttExtra(0xFF),
   136 	iAttExtra(0xFF),
   122 	iHidden(EFalse),
   137 	iHidden(EFalse),
   123 	iEntry(aEntry),
   138 	iEntry(aEntry),
   124 	iFileStartOffset(0), 
   139 	iFileStartOffset(0),
   125 	iSize(0), 
   140 	iSize(0),
   126 	iOverride(0),
   141 	iOverride(0),
   127 	iFileUpdate(EFalse),
   142 	iFileUpdate(EFalse),
   128     iAlias(false)
   143     iAlias(false)
   129 	{
   144 	{
   130 	iName = (TText*)NormaliseFileName((const char*)aName);
   145 	iName = NormaliseFileName(aName);
   131 	iIdentifier=TRomNode::Count++;
   146 	iIdentifier=TRomNode::Count++;
   132 
   147 
   133 	// Add this node to the flat linked list
   148 	// Add this node to the flat linked list
   134 	if( !TheFirstNode )
   149 	if( !TheFirstNode )
   135 		{
   150 		{
   149 		{
   164 		{
   150 		iAtt = (TUint8)KEntryAttDir;
   165 		iAtt = (TUint8)KEntryAttDir;
   151 		}
   166 		}
   152 	}
   167 	}
   153 
   168 
   154 TRomNode::~TRomNode()
   169 TRomNode::~TRomNode() {
   155 	{
       
   156 	if (iEntry && !iAlias)
   170 	if (iEntry && !iAlias)
   157         {
   171 		delete iEntry; 
   158 		delete iEntry;
       
   159         }
       
   160     iEntry = 0;
       
   161 	if(iName)
   172 	if(iName)
   162 		free(iName);
   173 		delete []iName ;
   163     iName = 0;
   174 }
   164 	}
       
   165 
       
   166 TRomNode *TRomNode::FindInDirectory(TText *aName)
       
   167 //
   175 //
   168 // Check if the TRomNode for aName exists in aDir, and if so, return it.
   176 // Check if the TRomNode for aName exists in aDir, and if so, return it.
   169 //
   177 //
   170 	{
   178 TRomNode *TRomNode::FindInDirectory(const char *aName) const{
   171 
       
   172 	TRomNode *entry=iChild; // first subdirectory or file
   179 	TRomNode *entry=iChild; // first subdirectory or file
   173 	while (entry)
   180 	while (entry) {
   174 		{
   181 		if ((stricmp(aName, entry->iName)) == 0)
   175 		if ((stricmp((const char *)aName, (const char *)entry->iName))==0) 
       
   176 			return entry;
   182 			return entry;
   177 		else
   183 		else
   178 			entry=entry->iSibling;
   184 			entry=entry->iSibling;
   179 		}
   185 	}
   180 	return 0;
   186 	return 0;
   181 	}
   187 }
   182 
   188 
   183 
   189 
   184 
   190 
   185 TInt indend = 0;
   191 TInt indend = 0;
   186 
   192 
   189 	while(i > 0)
   195 	while(i > 0)
   190 	   {
   196 	   {
   191 	     cout << "    ";
   197 	     cout << "    ";
   192 	     i--;
   198 	     i--;
   193 	   }
   199 	   }
   194        };  
   200        };
   195 
   201 
   196 // displays the directory structure
   202 // displays the directory structure
   197 void TRomNode::DisplayStructure(ostream* aOut)
   203 void TRomNode::DisplayStructure(ostream* aOut)
   198 	{
   204 	{
   199 	  indendStructure(indend);
   205 	  indendStructure(indend);
   200       *aOut  << iName << "\n";
   206       *aOut  << iName << "\n";
   201 	  if (iChild)
   207 	  if (iChild)
   202 	    {
   208 	    {
   203 	      indend++; 
   209 	      indend++;
   204 	      iChild->DisplayStructure(aOut);
   210 	      iChild->DisplayStructure(aOut);
   205 	      indend--;
   211 	      indend--;
   206 	    }
   212 	    }
   207 	  if (iSibling)
   213 	  if (iSibling)
   208 	    iSibling->DisplayStructure(aOut);
   214 	    iSibling->DisplayStructure(aOut);
   243 		return;
   249 		return;
   244 		}
   250 		}
   245 	Add(aChild);
   251 	Add(aChild);
   246 	}
   252 	}
   247 
   253 
   248 TRomNode* TRomNode::NewSubDir(TText *aName)
   254 TRomNode* TRomNode::NewSubDir(const char *aName) {
   249 	{
   255 	if (iEntry) {
   250 	if (iEntry)
       
   251 		{
       
   252 		Print(EError, "Adding subdirectory to a file!!!\n");
   256 		Print(EError, "Adding subdirectory to a file!!!\n");
   253 		return 0;
   257 		return 0;
   254 		}
   258 	}
   255 
   259 
   256 	TRomNode* node = new TRomNode(aName );
   260 	TRomNode* node = new TRomNode(aName);
   257 	if (node==0)
   261 	if (node==0){
   258 		{
       
   259 		Print(EError, "TRomNode::NewNode: Out of memory\n");
   262 		Print(EError, "TRomNode::NewNode: Out of memory\n");
   260 		return 0;
   263 		return 0;
   261 		}
   264 	}
   262 	node->iParent = this;
   265 	node->iParent = this;
   263 	Add(node);
   266 	Add(node);
   264 	return node;
   267 	return node;
   265 	}
   268 	}
   266 
   269 
   267 void TRomNode::Add(TRomNode* aChild)
   270 void TRomNode::Add(TRomNode* aChild) {
   268 	{
   271 	if (iChild){ // this node is a non-empty directory
   269 	if (iChild) // this node is a non-empty directory
   272 		
   270 		{
       
   271 		TRomNode* dir = iChild; // find where to link in the new node
   273 		TRomNode* dir = iChild; // find where to link in the new node
   272 		while (dir->iSibling)
   274 		while (dir->iSibling)
   273 			dir = dir->iSibling;
   275 			dir = dir->iSibling;
   274 		dir->iSibling = aChild;
   276 		dir->iSibling = aChild;
   275 		}
   277 	}
   276 	else
   278 	else
   277 		iChild = aChild; // else just set it up as the child of the dir
   279 		iChild = aChild; // else just set it up as the child of the dir
   278 	aChild->iSibling = 0;
   280 	aChild->iSibling = 0;
   279 	aChild->iParent = this;
   281 	aChild->iParent = this;
   280 	}
   282 	}
   281 
       
   282 TInt TRomNode::SetAttExtra(TText *anAttWord, TRomBuilderEntry* aFile, enum EKeyword aKeyword)
       
   283 //
   283 //
   284 // Set the file extra attribute byte from the letters passed
   284 // Set the file extra attribute byte from the letters passed
   285 // Note: The iAttExtra bits are inverted. '0' represent enabled
   285 // Note: The iAttExtra bits are inverted. '0' represent enabled
   286 //
   286 //
   287 	{
   287 TInt TRomNode::SetAttExtra(char *anAttWord, TRomBuilderEntry* aFile, enum EKeyword aKeyword){
   288 	iAttExtra=0xFF;
   288 	iAttExtra=0xFF;
   289 	if (anAttWord==0 || anAttWord[0]=='\0')
   289 	if (anAttWord==0 || anAttWord[0]=='\0')
   290 		return Print(EError, "Missing argument for keyword 'exattrib'.\n");
   290 		return Print(EError, "Missing argument for keyword 'exattrib'.\n");
   291 	for (TText *letter=anAttWord;*letter!=0;letter++)
   291 	for (char *letter=anAttWord;*letter!=0;letter++)
   292 		{
   292 		{
   293 		switch (*letter)
   293 		switch (*letter)
   294 			{
   294 			{
   295 		case 'u':
   295 		case 'u':
   296 			iAttExtra |= (KEntryAttUnique >> 23);	// '1' represents disabled in iAttExtra
   296 			iAttExtra |= (KEntryAttUnique >> 23);	// '1' represents disabled in iAttExtra
   316 		}
   316 		}
   317 	return KErrNone;
   317 	return KErrNone;
   318 	}
   318 	}
   319 
   319 
   320 
   320 
   321 TInt TRomNode::SetAtt(TText *anAttWord)
   321 TInt TRomNode::SetAtt(char *anAttWord)
   322 //
   322 //
   323 // Set the file attribute byte from the letters passed
   323 // Set the file attribute byte from the letters passed
   324 //
   324 //
   325 	{
   325 	{
   326 	iAtt=0;
   326 	iAtt=0;
   327 	if (anAttWord==0 || anAttWord[0]=='\0')
   327 	if (anAttWord==0 || anAttWord[0]=='\0')
   328 		return Print(EError, "Missing argument for keyword 'attrib'.\n");
   328 		return Print(EError, "Missing argument for keyword 'attrib'.\n");
   329 	for (TText *letter=anAttWord;*letter!=0;letter++)
   329 	for (char *letter=anAttWord;*letter!=0;letter++)
   330 		{
   330 		{
   331 		switch (*letter)
   331 		switch (*letter)
   332 			{
   332 			{
   333 		case 'R':
   333 		case 'R':
   334 		case 'w':
   334 		case 'w':
   357 		}
   357 		}
   358 	return KErrNone;
   358 	return KErrNone;
   359 	}
   359 	}
   360 
   360 
   361 
   361 
   362 
   362 // Calculates the amount of ROM space required to hold
   363 TInt TRomNode::CalculateEntrySize() const
   363 // this entry. The return is the actual size of the TRofsEntry
   364 	// Calculates the amount of ROM space required to hold
   364 // structure, not rounded up
   365 	// this entry. The return is the actual size of the TRofsEntry
   365 TInt TRomNode::CalculateEntrySize() const {
   366 	// structure, not rounded up
   366 	UTF16String unistr(iName);
   367 	{
   367 	TInt requiredSizeBytes = KRofsEntryHeaderSize +	unistr.bytes();
   368 	TInt requiredSizeBytes = KRofsEntryHeaderSize +	NameLengthUnicode();
       
   369 	return requiredSizeBytes;
   368 	return requiredSizeBytes;
   370 	}
   369 	}
   371 
   370 
   372 TInt TRomNode::CalculateDirectoryEntrySize( TInt& aDirectoryBlockSize,
   371 TInt TRomNode::CalculateDirectoryEntrySize( TInt& aDirectoryBlockSize,
   373 										    TInt& aFileBlockSize )
   372 										    TInt& aFileBlockSize )
   384 
   383 
   385 	TInt offsetBytes=0;
   384 	TInt offsetBytes=0;
   386 	TInt padBytes=0;
   385 	TInt padBytes=0;
   387 	if( 0 == iTotalDirectoryBlockSize )
   386 	if( 0 == iTotalDirectoryBlockSize )
   388 		{
   387 		{
   389 		// need to calculate by walking children	
   388 		// need to calculate by walking children
   390 		if( !iChild )
   389 		if( !iChild )
   391 			{
   390 			{
   392 			return Print(EError, "TRomNode structure corrupt\n");
   391 			return Print(EError, "TRomNode structure corrupt\n");
   393 			}
   392 			}
   394 
   393 
   413 				fileBlockSize += entrySize;
   412 				fileBlockSize += entrySize;
   414 				fileCount++;
   413 				fileCount++;
   415 				}
   414 				}
   416 			node = node->iSibling;
   415 			node = node->iSibling;
   417 			}
   416 			}
   418 		
   417 
   419 		offsetBytes = ((fileCount + dirCount) * 2) + 4; //the +4 are the two offset counts,
   418 		offsetBytes = ((fileCount + dirCount) * 2) + 4; //the +4 are the two offset counts,
   420 		padBytes = offsetBytes % 4;
   419 		padBytes = offsetBytes % 4;
   421 
   420 
   422 		iTotalDirectoryBlockSize = dirBlockSize;
   421 		iTotalDirectoryBlockSize = dirBlockSize;
   423 		iTotalFileBlockSize = fileBlockSize;
   422 		iTotalFileBlockSize = fileBlockSize;
   429 	}
   428 	}
   430 
   429 
   431 /**
   430 /**
   432 Place the files and it's attributes (incase of executables)
   431 Place the files and it's attributes (incase of executables)
   433 Called for both rofs and datadrive creation.
   432 Called for both rofs and datadrive creation.
   434  
   433 
   435 @param aDest   - Destination buffer.
   434 @param aDest   - Destination buffer.
   436 @param aOffset - offset value, used for rofs only.
   435 @param aOffset - offset value, used for rofs only.
   437 @param aMaxSize- Maximum size required for rofs.
   436 @param aMaxSize- Maximum size required for rofs.
   438   
   437 
   439 @return - Returns the number of bytes placed or a -ve error code.
   438 @return - Returns the number of bytes placed or a -ve error code.
   440 */ 
   439 */
   441 TInt TRomNode::PlaceFile( TUint8* &aDest, TUint aOffset, TUint aMaxSize, CBytePair *aBPE )
   440 TInt TRomNode::PlaceFile( TUint8* &aDest, TUint aOffset, TUint aMaxSize, CBytePair *aBPE ){
   442 	//
   441 	//
   443 	// Place the file into the ROM image, making any necessary conversions
   442 	// Place the file into the ROM image, making any necessary conversions
   444 	// along the way.
   443 	// along the way.
   445 	//
   444 	//
   446 	// Returns the number of bytes placed or a -ve error code.
   445 	// Returns the number of bytes placed or a -ve error code.
   447 	{
   446 	
   448 
   447 
   449 	TInt size=0;
   448 	TInt size=0;
   450 	
   449 
   451 	// file hasn't been placed for drive image. 
   450 	// file hasn't been placed for drive image.
   452 	if(gDriveImage)
   451 	if(gDriveImage)
   453 	{
   452 	{
   454 		size = iEntry->PlaceFile(aDest,aMaxSize,aBPE);
   453 		size = iEntry->PlaceFile(aDest,aMaxSize,aBPE);
   455 		iSize = size;
   454 		iSize = size;
   456 	}
   455 	}
   484 		if (hdrfmt != KImageHdrFmt_V)
   483 		if (hdrfmt != KImageHdrFmt_V)
   485 			{
   484 			{
   486 			Print(EError,"%s: Can't load old format binary\n", iEntry->iFileName);
   485 			Print(EError,"%s: Can't load old format binary\n", iEntry->iFileName);
   487 			return KErrNotSupported;
   486 			return KErrNotSupported;
   488 			}
   487 			}
   489 		
   488 
   490 		// First need to check that it's a real image header
   489 		// First need to check that it's a real image header
   491 		if( (TUint)size > sizeof(E32ImageHeader) )
   490 		if( (TUint)size > sizeof(E32ImageHeader) )
   492 			{
   491 			{
   493 			if( ((TInt)hdr->iSignature == 0x434f5045u) && ((TInt)hdr->iUid1 == KExecutableImageUidValue || (TInt)hdr->iUid1 == KDynamicLibraryUidValue) )
   492 			if( ((TInt)hdr->iSignature == 0x434f5045u) && ((TInt)hdr->iUid1 == KExecutableImageUidValue || (TInt)hdr->iUid1 == KDynamicLibraryUidValue) )
   494 				{
   493 				{
   630 			//Offset in 32bit words from start of directory block
   629 			//Offset in 32bit words from start of directory block
   631 			array[index].iOffset = (TUint16) ((((TUint8*) entry) - dirBlockBase) >> 2);
   630 			array[index].iOffset = (TUint16) ((((TUint8*) entry) - dirBlockBase) >> 2);
   632 			array[index].iIsDir = ETrue;
   631 			array[index].iIsDir = ETrue;
   633 			}
   632 			}
   634 		array[index].iEntry = entry;
   633 		array[index].iEntry = entry;
   635 		index++;
   634 		index++;	 
   636 
   635 		entry->iNameOffset = KRofsEntryNameOffset; 
   637 		entry->iNameOffset = KRofsEntryNameOffset;
       
   638 		entry->iAtt = node->iAtt;
   636 		entry->iAtt = node->iAtt;
   639 		entry->iAttExtra = node->iAttExtra;
   637 		entry->iAttExtra = node->iAttExtra;
   640 
   638 
   641 		TInt entryLen = KRofsEntryHeaderSize;
   639 		TInt entryLen = KRofsEntryHeaderSize;
   642 		entryLen += node->NameCpy( (char*)&entry->iName, entry->iNameLength );
   640 		UTF16String unistr(node->iName);
       
   641 		if(!unistr.IsEmpty()){
       
   642 			entry->iNameLength = unistr.length();
       
   643 			memcpy(entry->iName,unistr.c_str(),unistr.bytes());
       
   644 			entryLen += unistr.bytes() ; 
       
   645 		}
   643 		entryLen += (4 - entryLen) & 3;	// round up to nearest word
   646 		entryLen += (4 - entryLen) & 3;	// round up to nearest word
   644 		entry->iStructSize = (TUint16)entryLen;
   647 		entry->iStructSize = (TUint16)entryLen;
   645 
       
   646 
   648 
   647 		if( node->IsFile() )
   649 		if( node->IsFile() )
   648 			{
   650 			{
   649 			// node is a file, entry points to the file
   651 			// node is a file, entry points to the file
   650 			// write an entry out into the file block
   652 			// write an entry out into the file block
   657 		else
   659 		else
   658 			{
   660 			{
   659 			// node is a subdirectory, entry points to directory
   661 			// node is a subdirectory, entry points to directory
   660 			pDirEntry->iFileAddress = node->iImagePosition;
   662 			pDirEntry->iFileAddress = node->iImagePosition;
   661 			node->iAtt |= KEntryAttDir;
   663 			node->iAtt |= KEntryAttDir;
   662 			
   664 
   663 			// the size is just the size of the directory block
   665 			// the size is just the size of the directory block
   664 			pDirEntry->iFileSize = node->iTotalDirectoryBlockSize;
   666 			pDirEntry->iFileSize = node->iTotalDirectoryBlockSize;
   665 			pDirEntry = (TRofsEntry*)( (TUint8*)pDirEntry + entryLen );
   667 			pDirEntry = (TRofsEntry*)( (TUint8*)pDirEntry + entryLen );
   666 			}
   668 			}
   667 
   669 
   738  			aFileCount++;
   740  			aFileCount++;
   739 	current=current->iSibling;
   741 	current=current->iSibling;
   740 		}
   742 		}
   741 	}
   743 	}
   742 
   744 
   743  void TRomNode::Destroy()
       
   744 //
   745 //
   745 // Follow the TRomNode tree, destroying it
   746 // Follow the TRomNode tree, destroying it
   746 //
   747 //
   747 	{
   748 void TRomNode::Destroy() {
   748 
       
   749  	TRomNode *current = this; // root has no siblings
   749  	TRomNode *current = this; // root has no siblings
   750 	while (current)
   750 	while (current)
   751 		{
   751 		{
   752 		if (current->iChild)
   752 		if (current->iChild)
   753 			current->iChild->Destroy();
   753 			current->iChild->Destroy();
   754 		TRomNode* prev=current;
   754 		TRomNode* prev=current;
   755 		current=current->iSibling;
   755 		current=current->iSibling;
   756 		delete prev;
   756 		delete prev;
   757         prev = 0;
   757         prev = 0;
   758 		}
   758 		}
   759  	}
   759  }
   760 
   760 
   761 
   761  
   762 
   762 
   763 
   763  
   764 TInt TRomNode::NameCpy(char* aDest, TUint8& aUnicodeLength )
       
   765 //
       
   766 // Safely copy a file name in the rom entry
       
   767 // Returns the number of bytes used. Write the length in unicode characters
       
   768 // into aUnicodeLength.
       
   769 //
       
   770 	{
       
   771 
       
   772 	if ((aDest==NULL) || (iName==NULL))
       
   773 		return 0;
       
   774 	const unsigned char* pSourceByte = (const unsigned char*)iName;
       
   775 	unsigned char* pTargetByte=(unsigned char*)aDest;
       
   776 	for (;;)
       
   777 		{
       
   778 		const TUint sourceByte=*pSourceByte;
       
   779 		if (sourceByte==0)
       
   780 			{
       
   781 			break;
       
   782 			}
       
   783 		if ((sourceByte&0x80)==0)
       
   784 			{
       
   785 			*pTargetByte=(unsigned char)sourceByte;
       
   786 			++pTargetByte;
       
   787 			*pTargetByte=0;
       
   788 			++pTargetByte;
       
   789 			++pSourceByte;
       
   790 			}
       
   791 		else if ((sourceByte&0xe0)==0xc0)
       
   792 			{
       
   793 			++pSourceByte;
       
   794 			const TUint secondSourceByte=*pSourceByte;
       
   795 			if ((secondSourceByte&0xc0)!=0x80)
       
   796 				{
       
   797 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   798 				exit(671);
       
   799 				}
       
   800 			*pTargetByte=(unsigned char)((secondSourceByte&0x3f)|((sourceByte&0x03)<<6));
       
   801 			++pTargetByte;
       
   802 			*pTargetByte=(unsigned char)((sourceByte>>2)&0x07);
       
   803 			++pTargetByte;
       
   804 			++pSourceByte;
       
   805 			}
       
   806 		else if ((sourceByte&0xf0)==0xe0)
       
   807 			{
       
   808 			++pSourceByte;
       
   809 			const TUint secondSourceByte=*pSourceByte;
       
   810 			if ((secondSourceByte&0xc0)!=0x80)
       
   811 				{
       
   812 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   813 				exit(672);
       
   814 				}
       
   815 			++pSourceByte;
       
   816 			const TUint thirdSourceByte=*pSourceByte;
       
   817 			if ((thirdSourceByte&0xc0)!=0x80)
       
   818 				{
       
   819 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   820 				exit(673);
       
   821 				}
       
   822 			*pTargetByte=(unsigned char)((thirdSourceByte&0x3f)|((secondSourceByte&0x03)<<6));
       
   823 			++pTargetByte;
       
   824 			*pTargetByte=(unsigned char)(((secondSourceByte>>2)&0x0f)|((sourceByte&0x0f)<<4));
       
   825 			++pTargetByte;
       
   826 			++pSourceByte;
       
   827 			}
       
   828 		else
       
   829 			{
       
   830 			Print(EError, "Bad UTF-8 '%s'", iName);
       
   831 			exit(674);
       
   832 			}
       
   833 		}
       
   834 	const TInt numberOfBytesInTarget=(pTargetByte-(unsigned char*)aDest); // this number excludes the trailing null-terminator
       
   835 	if (numberOfBytesInTarget%2!=0)
       
   836 		{
       
   837 		Print(EError, "Internal error");
       
   838 		exit(675);
       
   839 		}
       
   840 	aUnicodeLength = (TUint8)(numberOfBytesInTarget/2); // returns the length of aDest (in UTF-16 characters for Unicode, not bytes)
       
   841 	return numberOfBytesInTarget;
       
   842 	}
       
   843 
       
   844 
       
   845 TInt TRomNode::NameLengthUnicode() const
       
   846 //
       
   847 // Find the unicode lenght of the name
       
   848 //
       
   849 	{
       
   850 
       
   851 	if (iName==NULL)
       
   852 		return 0;
       
   853 
       
   854 	const unsigned char* pSourceByte = (const unsigned char*)iName;
       
   855 	TInt len = 0;
       
   856 	for (;;)
       
   857 		{
       
   858 		const TUint sourceByte=*pSourceByte;
       
   859 		if (sourceByte==0)
       
   860 			{
       
   861 			break;
       
   862 			}
       
   863 		if ((sourceByte&0x80)==0)
       
   864 			{
       
   865 			len += 2;
       
   866 			++pSourceByte;
       
   867 			}
       
   868 		else if ((sourceByte&0xe0)==0xc0)
       
   869 			{
       
   870 			++pSourceByte;
       
   871 			const TUint secondSourceByte=*pSourceByte;
       
   872 			if ((secondSourceByte&0xc0)!=0x80)
       
   873 				{
       
   874 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   875 				exit(671);
       
   876 				}
       
   877 			len += 2;
       
   878 			++pSourceByte;
       
   879 			}
       
   880 		else if ((sourceByte&0xf0)==0xe0)
       
   881 			{
       
   882 			++pSourceByte;
       
   883 			const TUint secondSourceByte=*pSourceByte;
       
   884 			if ((secondSourceByte&0xc0)!=0x80)
       
   885 				{
       
   886 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   887 				exit(672);
       
   888 				}
       
   889 			++pSourceByte;
       
   890 			const TUint thirdSourceByte=*pSourceByte;
       
   891 			if ((thirdSourceByte&0xc0)!=0x80)
       
   892 				{
       
   893 				Print(EError, "Bad UTF-8 '%s'", iName);
       
   894 				exit(673);
       
   895 				}
       
   896 			len += 2;
       
   897 			++pSourceByte;
       
   898 			}
       
   899 		else
       
   900 			{
       
   901 			Print(EError, "Bad UTF-8 '%s'", iName);
       
   902 			exit(674);
       
   903 			}
       
   904 		}
       
   905 	return len;
       
   906 	}
       
   907 
       
   908 
       
   909 void TRomNode::AddNodeForSameFile(TRomNode* aPreviousNode, TRomBuilderEntry* aFile)
   764 void TRomNode::AddNodeForSameFile(TRomNode* aPreviousNode, TRomBuilderEntry* aFile)
   910 	{
   765 	{
   911 	// sanity checking
   766 	// sanity checking
   912 	if (iNextNodeForSameFile != 0 || iEntry != aFile || (aPreviousNode && aPreviousNode->iEntry != iEntry))
   767 	if (iNextNodeForSameFile != 0 || iEntry != aFile || (aPreviousNode && aPreviousNode->iEntry != iEntry))
   913 		{
   768 		{
   924 //**************************************
   779 //**************************************
   925 // TRomBuilderEntry
   780 // TRomBuilderEntry
   926 //**************************************
   781 //**************************************
   927 
   782 
   928 
   783 
   929 
       
   930 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,TText *aName)
       
   931 //
   784 //
   932 // Constructor
   785 // Constructor
   933 //
   786 //
   934 :iFirstDllDataEntry(0),	iName(0),iFileName(0),iNext(0), iNextInArea(0),
   787 TRomBuilderEntry::TRomBuilderEntry(const char *aFileName,const char *aName):
       
   788 iFirstDllDataEntry(0),	iName(0),iFileName(0),iNext(0), iNextInArea(0),
   935 iExecutable(EFalse), iFileOffset(EFalse), iCompressEnabled(0),
   789 iExecutable(EFalse), iFileOffset(EFalse), iCompressEnabled(0),
   936 iHidden(0), iRomNode(0), iRealFileSize(0)		 
   790 iHidden(0), iRomNode(0), iRealFileSize(0)
   937 {
   791 {
   938 	if (aFileName)
   792 	if (aFileName)
   939    		iFileName = NormaliseFileName(aFileName);
   793    		iFileName = NormaliseFileName(aFileName);
   940 	if (aName)
   794 	if (aName)
   941 		iName = (TText*)NormaliseFileName((const char*)aName);
   795 		iName = NormaliseFileName(aName);
   942 	memset(iUids,0 ,sizeof(TCheckedUid));
   796 	memset(iUids,0 ,sizeof(TCheckedUid));
   943 }
   797 }
       
   798 //
       
   799 // Destructor
       
   800 //
       
   801 TRomBuilderEntry::~TRomBuilderEntry() {
       
   802 	if(iFileName) {
       
   803 		delete []iFileName;
       
   804 		iFileName = 0;
       
   805 	}
   944 	
   806 	
   945 TRomBuilderEntry::~TRomBuilderEntry()
   807 	if(iName) {
   946 //
   808 		delete []iName;
   947 // Destructor
   809 		iName = 0 ;
   948 //
   810 	}
   949 	{
   811 }
   950 	if(iFileName)
       
   951 	{
       
   952 	free(iFileName);
       
   953 	}
       
   954 	iFileName = 0;
       
   955 	if(iName)
       
   956 	{
       
   957 	free(iName);
       
   958 	}
       
   959 	}
       
   960 
   812 
   961 void TRomBuilderEntry::SetRomNode(TRomNode* aNode)
   813 void TRomBuilderEntry::SetRomNode(TRomNode* aNode)
   962 	{
   814 	{
   963 	aNode->AddNodeForSameFile(iRomNode, this);
   815 	aNode->AddNodeForSameFile(iRomNode, this);
   964 	iRomNode = aNode;
   816 	iRomNode = aNode;
   965 	}
   817 	}
   966 
   818 
   967 
   819 //
   968 TInt isNumber(TText *aString)
   820 // Place the file in ROFS. Since we don't support compression yet all
   969 	{
   821 // we have to do is read the file into memory
   970 	if (aString==NULL)
   822 // compress it, if it isn't already compressed.
   971 		return 0;
   823 //
   972 	if (strlen((char *)aString)==0)
   824 // Returns the number of bytes used, or -ve error code
   973 		return 0;
   825 TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE ){
   974 	return isdigit(aString[0]);
   826 
   975 	}
   827 
   976 
       
   977 TInt getNumber(TText *aStr)
       
   978 	{
       
   979 	TUint a;
       
   980 	#ifdef __TOOLS2__
       
   981 	istringstream val((char *)aStr);
       
   982 	#else
       
   983 	istrstream val((char *)aStr,strlen((char *)aStr));
       
   984 	#endif
       
   985 
       
   986 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
   987 	val >> setbase(0);
       
   988 #endif //__MSVCDOTNET__
       
   989 
       
   990 	val >> a;
       
   991 	return a;
       
   992 	}
       
   993 
       
   994 
       
   995 TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE )
       
   996 	//
       
   997 	// Place the file in ROM. Since we don't support compression yet all
       
   998 	// we have to do is read the file into memory
       
   999 	// compress it, if it isn't already compressed.
       
  1000 	//
       
  1001 	// Returns the number of bytes used, or -ve error code
       
  1002 	{
       
  1003 	TUint compression = 0;
   828 	TUint compression = 0;
  1004 	TBool executable = iExecutable;
   829 	TBool executable = iExecutable;
  1005 	Print(ELog,"Reading file %s to image\n", iFileName );
   830 	Print(ELog,"Reading file %s to image\n", iFileName );
  1006 	TUint32 size=HFile::GetLength((TText*)iFileName);
   831 	TUint32 size = HFile::GetLength(iFileName);
  1007 	if (size==0)
   832 	if (size==0)
  1008 		Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName);
   833 		Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName);
  1009         if (aDest == NULL) {
   834 	if (aDest == NULL) {
  1010             aMaxSize = size*2;
   835 		aMaxSize = size << 1;
  1011             aMaxSize = (aMaxSize>0) ? aMaxSize : 2;
   836 		aMaxSize = (aMaxSize>0) ? aMaxSize : 2;
  1012             aDest = new TUint8[aMaxSize];
   837 		aDest = new TUint8[aMaxSize];
  1013         }
   838    }
  1014 
   839 
  1015 	if (executable)
   840 	if (executable)
  1016 		{
   841 	{
  1017 		// indicate if the image will overflow without compression
   842 		// indicate if the image will overflow without compression
  1018 	TBool overflow;
   843 		TBool overflow;
  1019 			if(size>aMaxSize)
   844 		if(size>aMaxSize)
  1020 			overflow = ETrue;
   845 			overflow = ETrue;
  1021 		else
   846 		else
  1022 			overflow = EFalse;
   847 			overflow = EFalse;
  1023 
   848 
  1024 		// try to compress this executable
   849 		// try to compress this executable
  1025 		E32ImageFile f(aBPE);
   850 		E32ImageFile f(aBPE);
  1026 		TInt r = f.Open(iFileName);
   851 		TInt r = f.Open(iFileName);
  1027 		// is it really a valid E32ImageFile?
   852 		// is it really a valid E32ImageFile?
  1028 		if (r != KErrNone)
   853 		if (r != KErrNone)
  1029 			{
   854 		{
  1030 			Print(EWarning, "File '%s' is not a valid executable.  Placing file as data.\n", iFileName);
   855 			Print(EWarning, "File '%s' is not a valid executable.  Placing file as data.\n", iFileName);
  1031 			executable = EFalse;
   856 			executable = EFalse;
  1032 			}
   857 		}
  1033 		else
   858 		else
  1034 			{
   859 		{
  1035 
   860 
  1036 			if(iRomNode->iOverride & KOverrideDllData)
   861 			if(iRomNode->iOverride & KOverrideDllData)
  1037 			{
   862 			{
  1038 				DllDataEntry *aDllEntry = iRomNode->iEntry->GetFirstDllDataEntry();
   863 				DllDataEntry *aDllEntry = iRomNode->iEntry->GetFirstDllDataEntry();
  1039 				TLinAddr* aExportTbl;
   864 				TLinAddr* aExportTbl;
  1041 				TUint aDataAddr;
   866 				TUint aDataAddr;
  1042 				char *aCodeSeg, *aDataSeg;
   867 				char *aCodeSeg, *aDataSeg;
  1043 
   868 
  1044 				aExportTbl = (TLinAddr*)((char*)f.iData + f.iOrigHdr->iExportDirOffset);
   869 				aExportTbl = (TLinAddr*)((char*)f.iData + f.iOrigHdr->iExportDirOffset);
  1045 
   870 
  1046 				// const data symbol may belong in the Code section. If the address lies within the Code or data section limits, 
   871 				// const data symbol may belong in the Code section. If the address lies within the Code or data section limits,
  1047 				// get the corresponding location and update it.While considering the Data section limits
   872 				// get the corresponding location and update it.While considering the Data section limits
  1048 				// don't include the Bss section, as it doesn't exist as yet in the image.
   873 				// don't include the Bss section, as it doesn't exist as yet in the image.
  1049 				while( aDllEntry ){
   874 				while( aDllEntry ){
  1050 					if(aDllEntry->iOrdinal != (TUint32)-1){
   875 					if(aDllEntry->iOrdinal != (TUint32)-1){
  1051 						if(aDllEntry->iOrdinal < 1 || aDllEntry->iOrdinal > (TUint)f.iOrigHdr->iExportDirCount){
   876 						if(aDllEntry->iOrdinal < 1 || aDllEntry->iOrdinal > (TUint)f.iOrigHdr->iExportDirCount){
  1052 							Print(EWarning, "Invalid ordinal %d specified for DLL %s\n", aDllEntry->iOrdinal, iRomNode->iName);
   877 							Print(EWarning, "Invalid ordinal %d specified for DLL %s\n", aDllEntry->iOrdinal, iRomNode->iName);
  1053 							aDllEntry = aDllEntry->NextDllDataEntry();
   878 							aDllEntry = aDllEntry->NextDllDataEntry();
  1054 							continue;
   879 							continue;
  1055 						}
   880 						}
  1056 					
   881 
  1057 				//	Get the address of the data field via the export table.
   882 						//	Get the address of the data field via the export table.
  1058 					aDataAddr = (TInt32)(aExportTbl[aDllEntry->iOrdinal - 1] + aDllEntry->iOffset);
   883 						aDataAddr = (TInt32)(aExportTbl[aDllEntry->iOrdinal - 1] + aDllEntry->iOffset);
  1059 					if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){
   884 						if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){
  1060 						aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset);
   885 							aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset);
  1061 						aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase );
   886 							aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase );
  1062 						memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
   887 							memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
  1063 					}
   888 						}
  1064 					else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){
   889 						else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){
  1065 						aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset);
   890 							aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset);
  1066 						aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase );
   891 							aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase );
  1067 						memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
   892 							memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
  1068 					}
   893 						}
  1069 					else
   894 						else
  1070 					{
   895 						{
  1071 						Print(EWarning, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
   896 							Print(EWarning, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
  1072 					}
   897 						}
  1073 					}
   898 					}
  1074 					else if(aDllEntry->iDataAddress != (TLinAddr)-1){
   899 					else if(aDllEntry->iDataAddress != (TLinAddr)-1){
  1075 						aDataAddr = aDllEntry->iDataAddress + aDllEntry->iOffset;
   900 						aDataAddr = aDllEntry->iDataAddress + aDllEntry->iOffset;
  1076 					if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){
   901 						if( aDataAddr >= f.iOrigHdr->iCodeBase && aDataAddr <= (f.iOrigHdr->iCodeBase + f.iOrigHdr->iCodeSize)){
  1077 						aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset);
   902 							aCodeSeg = (char*)(f.iData + f.iOrigHdr->iCodeOffset);
  1078 						aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase );
   903 							aLocation = (void*)(aCodeSeg + aDataAddr - f.iOrigHdr->iCodeBase );
  1079 						memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
   904 							memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
  1080 					}
   905 						}
  1081 					else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){
   906 						else if(aDataAddr >= f.iOrigHdr->iDataBase && aDataAddr <= (f.iOrigHdr->iDataBase + f.iOrigHdr->iDataSize)){
  1082 						aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset);
   907 							aDataSeg = (char*)(f.iData + f.iOrigHdr->iDataOffset);
  1083 						aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase );
   908 							aLocation = (void*)(aDataSeg + aDataAddr - f.iOrigHdr->iDataBase );
  1084 						memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
   909 							memcpy(aLocation, &aDllEntry->iNewValue, aDllEntry->iSize);
  1085 					}
   910 						}
  1086 					else
   911 						else
  1087 					{
   912 						{
  1088 						Print(EWarning, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
   913 							Print(EWarning, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
  1089 					}
   914 						}
  1090 					}
   915 					}
  1091 					aDllEntry = aDllEntry->NextDllDataEntry();
   916 					aDllEntry = aDllEntry->NextDllDataEntry();
  1092 					}
   917 				}
  1093 			}
   918 			}
  1094 
   919 
  1095 			compression = f.iHdr->CompressionType();
   920 			compression = f.iHdr->CompressionType();
  1096 			Print(ELog,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression);
   921 			Print(ELog,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression);
  1097 
   922 
  1110 				oldFileComp = 0;
   935 				oldFileComp = 0;
  1111 			}
   936 			}
  1112 
   937 
  1113 			if( iCompressEnabled != ECompressionUnknown)
   938 			if( iCompressEnabled != ECompressionUnknown)
  1114 			{
   939 			{
  1115 				// The new state would be as stated in obey file, i.e. 
   940 				// The new state would be as stated in obey file, i.e.
  1116 				// filecompress or fileuncompress
   941 				// filecompress or fileuncompress
  1117 				newFileComp = gCompressionMethod;
   942 				newFileComp = gCompressionMethod;
  1118 			}
   943 			}
  1119 			else if (gCompress != ECompressionUnknown)
   944 			else if (gCompress != ECompressionUnknown)
  1120 			{
   945 			{
  1131 			if(!gDriveImage)
   956 			if(!gDriveImage)
  1132 			{
   957 			{
  1133 				// overide paging flags...
   958 				// overide paging flags...
  1134 				E32ImageHeaderV* h=f.iHdr;
   959 				E32ImageHeaderV* h=f.iHdr;
  1135 				if (iRomNode->iOverride & KOverrideCodePaged)
   960 				if (iRomNode->iOverride & KOverrideCodePaged)
  1136 					{
   961 				{
  1137 					h->iFlags &= ~KImageCodeUnpaged;
   962 					h->iFlags &= ~KImageCodeUnpaged;
  1138 					h->iFlags |= KImageCodePaged;
   963 					h->iFlags |= KImageCodePaged;
  1139 					}
   964 				}
  1140 				if (iRomNode->iOverride & KOverrideCodeUnpaged)
   965 				if (iRomNode->iOverride & KOverrideCodeUnpaged)
  1141 					{
   966 				{
  1142 					h->iFlags |= KImageCodeUnpaged;
   967 					h->iFlags |= KImageCodeUnpaged;
  1143 					h->iFlags &= ~KImageCodePaged;
   968 					h->iFlags &= ~KImageCodePaged;
  1144 					}
   969 				}
  1145 				if (iRomNode->iOverride & KOverrideDataPaged)
   970 				if (iRomNode->iOverride & KOverrideDataPaged)
  1146 					{
   971 				{
  1147 					h->iFlags &= ~KImageDataUnpaged;
   972 					h->iFlags &= ~KImageDataUnpaged;
  1148 					h->iFlags |= KImageDataPaged;
   973 					h->iFlags |= KImageDataPaged;
  1149 					}
   974 				}
  1150 				if (iRomNode->iOverride & KOverrideDataUnpaged)
   975 				if (iRomNode->iOverride & KOverrideDataUnpaged)
  1151 					{
   976 				{
  1152 					h->iFlags |= KImageDataUnpaged;
   977 					h->iFlags |= KImageDataUnpaged;
  1153 					h->iFlags &= ~KImageDataPaged;
   978 					h->iFlags &= ~KImageDataPaged;
  1154 					}
   979 				}
  1155 
   980 
  1156 				// apply global paging override...
   981 				// apply global paging override...
  1157 				switch(gCodePagingOverride)
   982 				switch(gCodePagingOverride)
  1158 					{
   983 				{
  1159 				case EKernelConfigPagingPolicyNoPaging:
   984 				case EKernelConfigPagingPolicyNoPaging:
  1160 					h->iFlags |= KImageCodeUnpaged;
   985 					h->iFlags |= KImageCodeUnpaged;
  1161 					h->iFlags &= ~KImageCodePaged;
   986 					h->iFlags &= ~KImageCodePaged;
  1162 					break;
   987 					break;
  1163 				case EKernelConfigPagingPolicyAlwaysPage:
   988 				case EKernelConfigPagingPolicyAlwaysPage:
  1170 					break;
   995 					break;
  1171 				case EKernelConfigPagingPolicyDefaultPaged:
   996 				case EKernelConfigPagingPolicyDefaultPaged:
  1172 					if(!(h->iFlags&(KImageCodeUnpaged|KImageCodePaged)))
   997 					if(!(h->iFlags&(KImageCodeUnpaged|KImageCodePaged)))
  1173 						h->iFlags |= KImageCodePaged;
   998 						h->iFlags |= KImageCodePaged;
  1174 					break;
   999 					break;
  1175 					}
  1000 				}
  1176 				switch(gDataPagingOverride)
  1001 				switch(gDataPagingOverride)
  1177 					{
  1002 				{
  1178 				case EKernelConfigPagingPolicyNoPaging:
  1003 				case EKernelConfigPagingPolicyNoPaging:
  1179 					h->iFlags |= KImageDataUnpaged;
  1004 					h->iFlags |= KImageDataUnpaged;
  1180 					h->iFlags &= ~KImageDataPaged;
  1005 					h->iFlags &= ~KImageDataPaged;
  1181 					break;
  1006 					break;
  1182 				case EKernelConfigPagingPolicyAlwaysPage:
  1007 				case EKernelConfigPagingPolicyAlwaysPage:
  1189 					break;
  1014 					break;
  1190 				case EKernelConfigPagingPolicyDefaultPaged:
  1015 				case EKernelConfigPagingPolicyDefaultPaged:
  1191 					if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged)))
  1016 					if(!(h->iFlags&(KImageDataUnpaged|KImageDataPaged)))
  1192 						h->iFlags |= KImageDataPaged;
  1017 						h->iFlags |= KImageDataPaged;
  1193 					break;
  1018 					break;
  1194 					}
  1019 				}
  1195 				f.UpdateHeaderCrc();
  1020 				f.UpdateHeaderCrc();
  1196 
  1021 
  1197 				// make sure paged code has correct compression type...
  1022 				// make sure paged code has correct compression type...
  1198 				if(h->iFlags&KImageCodePaged)
  1023 				if(h->iFlags&KImageCodePaged)
  1199 					{
  1024 				{
  1200 					if(newFileComp!=0)
  1025 					if(newFileComp!=0)
  1201 						newFileComp = KUidCompressionBytePair;
  1026 						newFileComp = KUidCompressionBytePair;
  1202 					}
  1027 				}
  1203 			}
  1028 			}
  1204 
  1029 
  1205 			if ( oldFileComp != newFileComp )
  1030 			if ( oldFileComp != newFileComp )
  1206 				{
  1031 			{
  1207 				
  1032 
  1208 				if( newFileComp == 0)
  1033 				if( newFileComp == 0)
  1209 					{
  1034 				{
  1210 					Print(ELog,"Decompressing executable '%s'\n", iFileName);
  1035 					Print(ELog,"Decompressing executable '%s'\n", iFileName);
  1211 					f.iHdr->iCompressionType = 0;
  1036 					f.iHdr->iCompressionType = 0;
  1212 					}
  1037 				}
  1213 				else
  1038 				else
  1214 					{
  1039 				{
  1215 					Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp);
  1040 					Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp);
  1216 					f.iHdr->iCompressionType = newFileComp;
  1041 					f.iHdr->iCompressionType = newFileComp;
  1217 					}
  1042 				}
  1218 				f.UpdateHeaderCrc();
  1043 				f.UpdateHeaderCrc();
  1219 				if (overflow)
  1044 				if (overflow)
  1220 					{
  1045 				{
       
  1046 					// need to check if the compressed file will fit in the image
       
  1047 					//TODO the checking will slow down the build process, should do it later along with the writing on aDest.
       
  1048 					TUint32 compressedSize;
  1221 					char * buffer = new char [size];
  1049 					char * buffer = new char [size];
  1222 					// need to check if the compressed file will fit in the image
  1050 #if defined(__LINUX__)
  1223    					#if defined(__LINUX__)
  1051 					ostrstream os((char*)aDest, aMaxSize, (ios_base::openmode)(ios_base::out+ios_base::binary));
  1224  					ostrstream os((char*)aDest, aMaxSize, (ios::openmode)(ios::out+ios::binary));
  1052 #elif defined(__TOOLS2__) && defined (_STLP_THREADS)
  1225 					#elif defined(__TOOLS2__) && defined (_STLP_THREADS)
  1053 					ostrstream os((char*)buffer, size,(ios_base::out+ios_base::binary));
  1226   					ostrstream os((char*)buffer, size,(ios::out+ios::binary));
  1054 #elif defined( __TOOLS2__)
  1227   					#elif defined( __TOOLS2__)
  1055 					ostrstream os((char*)buffer, size,(ios_base::out+ios_base::binary));
  1228    					ostrstream os((char*)buffer, size,(ios::out+ios::binary));
  1056 #else
  1229 					#else
  1057 					ostrstream os( (char*)buffer, size, (ios_base::out+ios_base::binary));
  1230 					ostrstream os( (char*)buffer, size, (ios::out+ios::binary));
  1058 #endif
  1231 					#endif
       
  1232 					os << f;
  1059 					os << f;
  1233 					TUint compressedSize = os.pcount();
  1060 					compressedSize = os.pcount();
       
  1061 					delete[] buffer;
  1234 					if (compressedSize <= aMaxSize)
  1062 					if (compressedSize <= aMaxSize)
  1235 						overflow = EFalse;	
  1063 						overflow = EFalse;
  1236 					delete[] buffer;
  1064 				}
  1237 					}
  1065 			}
  1238 				}
       
  1239 			if (overflow)
  1066 			if (overflow)
  1240 				{
  1067 			{
  1241 				Print(EError, "Can't fit '%s' in image\n", iFileName);
  1068 				Print(EError, "Can't fit '%s' in image\n", iFileName);
  1242 				Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
  1069 				Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
  1243 				exit(667);
  1070 				exit(667);
  1244 				}
  1071 			}
  1245   			#if defined(__TOOLS2__) && defined (_STLP_THREADS)
  1072 
  1246   			ostrstream os((char*)aDest, aMaxSize,(ios::out+ios::binary));
  1073 			//try to use cached version where possible.
  1247   			#elif __TOOLS2__
  1074 			if(gCache && !gDriveImage && !(iRomNode->iAlias) && (iRomNode->iEntry->iExecutable) && !(iRomNode->iOverride & KOverrideDllData))
  1248 			ostrstream os((char*)aDest, aMaxSize, (std::_Ios_Openmode)(ios::out+ios::binary));
  1075 			{
  1249 			#else
  1076 				//retrive cached version.
  1250 			ostrstream os((char*)aDest, aMaxSize, (ios::out+ios::binary));
  1077 				size_t len = strlen(iFileName) + 1;
  1251 			#endif
  1078 				char* temp = (char*)_alloca(len);
       
  1079 				memcpy(temp,iFileName,len);
       
  1080 				CacheEntry* entryref = CacheManager::GetInstance()->GetE32ImageFileRepresentation(temp , compression); 
       
  1081 				if(entryref)
       
  1082 				{
       
  1083 					size = entryref->GetCachedFileBufferLen();
       
  1084 					memcpy(aDest, entryref->GetCachedFileBuffer(), size);
       
  1085 					memcpy(aDest,f.iHdr,sizeof(E32ImageHeaderV));
       
  1086 					compression = atoi(entryref->GetCachedFileCompressionID());
       
  1087 					memcpy(&iUids[0], aDest, sizeof(iUids));
       
  1088 					if (compression)
       
  1089 						Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression);
       
  1090 					else if (iExecutable)
       
  1091 						Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size);
       
  1092 					else
       
  1093 						Print(ELog,"File '%s' size: %08x\n", iFileName, size);
       
  1094 					iRealFileSize = size;	// required later when directory is written
       
  1095 
       
  1096 					return size;
       
  1097 				}
       
  1098 			}
       
  1099 
       
  1100 #if defined(__TOOLS2__) && defined (_STLP_THREADS)
       
  1101 			ostrstream os((char*)aDest, aMaxSize,(ios_base::out+ios_base::binary));
       
  1102 #elif __TOOLS2__
       
  1103 			ostrstream os((char*)aDest, aMaxSize, (_Ios_Openmode)(ios_base::out+ios_base::binary));
       
  1104 #else
       
  1105 			ostrstream os((char*)aDest, aMaxSize, (ios_base::out+ios_base::binary));
       
  1106 #endif
  1252 			os << f;
  1107 			os << f;
  1253 			size = os.pcount();
  1108 			size = os.pcount();
       
  1109 
       
  1110 			//save the decompressed/recompressed executable into the cache if it's enabled.
       
  1111 			if(gCache && !gDriveImage && !(iRomNode->iAlias) && (iRomNode->iEntry->iExecutable) && !(iRomNode->iOverride & KOverrideDllData))
       
  1112 			{
       
  1113 				CacheEntry* newentryref = new (nothrow) CacheEntry();
       
  1114 				if(newentryref)
       
  1115 				{
       
  1116 					boost::filesystem::path originalfilepath(iFileName);
       
  1117 					time_t originalcreationtime = last_write_time(originalfilepath);
       
  1118 					newentryref->SetOriginalFileCreateTime(&originalcreationtime);
       
  1119 					newentryref->SetOriginalFileCompression(f.iHdr->CompressionType());
       
  1120 					size_t len = strlen(iFileName) + 1;					
       
  1121 					char* originalfilename = (char*)_alloca(len);
       
  1122 					memcpy(originalfilename,iFileName,len);
       
  1123 					CacheManager::GetInstance()->NormalizeFilename(originalfilename);
       
  1124 					newentryref->SetOriginalFilename(originalfilename); 
       
  1125 					newentryref->SetCachedFileCompression(compression);
       
  1126 					string cachedfilename(".rofs.");
       
  1127 					cachedfilename += newentryref->GetCachedFileCompressionID();
       
  1128 					cachedfilename += ".";
       
  1129 					cachedfilename += iFileName;
       
  1130 					size_t slashpos;
       
  1131 					while(((slashpos=cachedfilename.find("/"))!=string::npos) || ((slashpos=cachedfilename.find("\\"))!=string::npos))
       
  1132 						cachedfilename.replace(slashpos, 1, 1, '.');
       
  1133 					cachedfilename.insert(0, "/");
       
  1134 					cachedfilename.insert(0, CacheManager::GetInstance()->GetCacheRoot());
       
  1135 					newentryref->SetCachedFilename(cachedfilename.c_str());
       
  1136 					newentryref->SetCachedFileBuffer((char*)aDest, size);
       
  1137 					try
       
  1138 					{
       
  1139 						size_t len = strlen(iFileName) + 1;
       
  1140 						char* temp = (char*)_alloca(len);
       
  1141 						memcpy(temp,iFileName,len);
       
  1142 						CacheManager::GetInstance()->Invalidate(temp, newentryref); 
       
  1143 					}
       
  1144 					catch (CacheException ce)
       
  1145 					{
       
  1146 						Print(EWarning, "Cache brings up an exception (%s) when processes %s\r\n", ce.GetErrorMessage(), iFileName);
       
  1147 					}
       
  1148 				}
       
  1149 			}
       
  1150 
  1254 			compression = f.iHdr->CompressionType();
  1151 			compression = f.iHdr->CompressionType();
  1255 			memcpy(&iUids[0], aDest, sizeof(iUids));
  1152 			memcpy(&iUids[0], aDest, sizeof(iUids));
  1256 			}
  1153 		}
  1257 		}
  1154 	}
  1258 	if (!executable)
  1155 	if (!executable)
  1259 		{
  1156 	{
  1260 		if ( size > aMaxSize )
  1157 		if ( size > aMaxSize )
  1261 			{
  1158 		{
  1262 			Print(EError, "Can't fit '%s' in image\n", iFileName);
  1159 			Print(EError, "Can't fit '%s' in image\n", iFileName);
  1263 			Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
  1160 			Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
  1264 			exit(667);
  1161 			exit(667);
  1265 			}
  1162 		}
  1266 		size = HFile::Read((TText*)iFileName, (TAny *)aDest);
  1163 		size = HFile::Read(iFileName, (TAny *)aDest);
  1267                 TUint32 Uidslen = (size > sizeof(iUids)) ? sizeof(iUids) : size;
  1164 		TUint32 Uidslen = (size > sizeof(iUids)) ? sizeof(iUids) : size;
  1268                 memcpy(&iUids[0], aDest, Uidslen);
  1165 		memcpy(&iUids[0], aDest, Uidslen);
  1269 		}
  1166 	}
  1270 
  1167 
  1271 	if (compression)
  1168 	if (compression)
  1272 		Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression);
  1169 		Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression);
  1273 	else if (iExecutable)
  1170 	else if (iExecutable)
  1274 		Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size);
  1171 		Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size);
  1275 	else
  1172 	else
  1276 		Print(ELog,"File '%s' size: %08x\n", iFileName, size);
  1173 		Print(ELog,"File '%s' size: %08x\n", iFileName, size);
       
  1174 	iCompressEnabled = compression;
  1277 	iRealFileSize = size;	// required later when directory is written
  1175 	iRealFileSize = size;	// required later when directory is written
  1278 	
  1176 
  1279 	return size;
  1177 	return size;
  1280 	}
  1178 }
  1281 
  1179 
  1282 
  1180 
  1283 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable)
  1181 TRomNode* TRomNode::CopyDirectory(TRomNode*& aLastExecutable)
  1284 	{
  1182 	{
  1285 
  1183 
  1321 
  1219 
  1322 
  1220 
  1323 void TRomNode::Alias(TRomNode* aNode)
  1221 void TRomNode::Alias(TRomNode* aNode)
  1324 	{
  1222 	{
  1325 	  // sanity checking
  1223 	  // sanity checking
  1326 	if (aNode->iEntry == 0) 
  1224 	if (aNode->iEntry == 0)
  1327 	{
  1225 	{
  1328 		Print(EError, "Aliasing: TRomNode structure corrupted\n");
  1226 		Print(EError, "Aliasing: TRomNode structure corrupted\n");
  1329 		exit(666);
  1227 		exit(666);
  1330 	}
  1228 	}
  1331 	Clone(aNode);
  1229 	Clone(aNode);
  1336 		}
  1234 		}
  1337     iAlias = true;
  1235     iAlias = true;
  1338 	}
  1236 	}
  1339 
  1237 
  1340 
  1238 
  1341 void TRomNode::Rename(TRomNode *aOldParent, TRomNode* aNewParent, TText* aNewName)
  1239 void TRomNode::Rename(TRomNode *aOldParent, TRomNode* aNewParent, const char* aNewName) {
  1342 	{
       
  1343 	aOldParent->Remove(this);
  1240 	aOldParent->Remove(this);
  1344 	aNewParent->Add(this);
  1241 	aNewParent->Add(this);
  1345 	delete [] iName;
  1242 	delete [] iName;
  1346 	iName = new TText[strlen((const char *)aNewName)+1];
  1243 	size_t len = strlen(aNewName)+1;
  1347 	strcpy ((char *)iName, (const char *)aNewName);
  1244 	iName = new char[len];
  1348 	}
  1245 	memcpy (iName, aNewName,len);
       
  1246 }
  1349 
  1247 
  1350 TInt TRomNode::FullNameLength(TBool aIgnoreHiddenAttrib) const
  1248 TInt TRomNode::FullNameLength(TBool aIgnoreHiddenAttrib) const
  1351 	{
  1249 	{
  1352 	TInt l = 0;
  1250 	TInt l = 0;
  1353 	// aIgnoreHiddenAttrib is used to find the complete file name length as 
  1251 	// aIgnoreHiddenAttrib is used to find the complete file name length as
  1354 	// in ROM of a hidden file.
  1252 	// in ROM of a hidden file.
  1355 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
  1253 	if (iParent && ( !iHidden || aIgnoreHiddenAttrib))
  1356 		l = iParent->FullNameLength() + 1;
  1254 		l = iParent->FullNameLength() + 1;
  1357 	l += strlen((const char*)iName);
  1255 	l += strlen((const char*)iName);
  1358 	return l;
  1256 	return l;
  1389 }
  1287 }
  1390 
  1288 
  1391 // Fuction to set first node in the patchdata linked list
  1289 // Fuction to set first node in the patchdata linked list
  1392 void TRomBuilderEntry::SetFirstDllDataEntry(DllDataEntry *aDllDataEntry)
  1290 void TRomBuilderEntry::SetFirstDllDataEntry(DllDataEntry *aDllDataEntry)
  1393 {
  1291 {
  1394 	iFirstDllDataEntry = aDllDataEntry;	
  1292 	iFirstDllDataEntry = aDllDataEntry;
  1395 }
  1293 }
  1396 void TRomBuilderEntry::DisplaySize(TPrintType aWhere)
  1294 void TRomBuilderEntry::DisplaySize(TPrintType aWhere)
  1397 {
  1295 {
  1398 	TBool aIgnoreHiddenAttrib = ETrue;
  1296 	TBool aIgnoreHiddenAttrib = ETrue;
  1399 	TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);
  1297 	TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);