--- a/imgtools/romtools/rombuild/r_coreimagereader.cpp Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/romtools/rombuild/r_coreimagereader.cpp Wed Jun 23 16:56:47 2010 +0800
@@ -1,615 +1,606 @@
-/*
-* Copyright (c) 2008-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:
-*
-*/
-
-
-#include <e32def.h>
-#include <e32def_private.h>
-#include <e32rom.h>
-
-#include "h_utl.h"
-#include "r_rom.h"
-
-#include "memmap.h"
-
-#include "r_coreimage.h"
-#include "r_global.h"
-
-
-#define ROM_PTR(base_ptr) ((TInt8*)iRomHdr + (base_ptr - iRomHdr->iRomBase))
-
-void InflateUnCompress(unsigned char* source, int sourcesize, unsigned char* dest, int destsize);
-
-const TUint KEntryAttDir=0x0010;
-const TUint KEntryAttXIP=0x0080;
-const TUint KEntryAttHidden=0x0002;
-
-// CoreRomImageReader
-//
-CoreRomImageReader::CoreRomImageReader(String aFileName, TBool aUseMemMap) : iImgFileName(aFileName),
-iData(0), iLoaderHdr(0), iRomHdr(0), iRootDirList(0), iRootDirectory(0), iUseMemMap(aUseMemMap), iImageMap(0)
-{
-}
-
-CoreRomImageReader::~CoreRomImageReader()
-{
- if(iData)
- {
- if(iUseMemMap)
- {
- iImageMap->CloseMemoryMap(ETrue);
- delete iImageMap;
- }
- else
- delete iData;
- }
-
- if(iRootDirectory)
- {
- DeleteAll(iRootDirectory);
- }
-}
-
-TBool CoreRomImageReader::IsCoreROM()
-{
- if(iData)
- {
- if(iData[0] == 'E' && iData[1] == 'P' && iData[2] == 'O' && iData[3] == 'C' &&
- iData[8] == 'R' && iData[9] == 'O' && iData[10] == 'M')
- {
- return ETrue;
- }
- }
-
- return EFalse;
-}
-
-TUint CoreRomImageReader::GetHdrSize()
-{
- return (sizeof(TRomLoaderHeader) + sizeof(TRomHeader));
-}
-
-TBool CoreRomImageReader::AllocateImageMap(Memmap*& aImageMap, TUint8*& aData, TUint aLen)
-{
- aImageMap = new Memmap(EFalse);
-
- if(aImageMap == NULL)
- {
- return EFalse;
- }
- else
- {
- aImageMap->SetMaxMapSize(aLen);
- if(aImageMap->CreateMemoryMap() == EFalse)
- {
- aImageMap->CloseMemoryMap(ETrue);
- delete aImageMap;
- aImageMap = NULL;
- return EFalse;
- }
- else
- {
- aData = (TUint8*)aImageMap->GetMemoryMapPointer();
- }
- }
-
- return ETrue;
-}
-
-TBool CoreRomImageReader::OpenImage()
-{
- TUint aLen = 0;
-
- Ifstream aIf(iImgFileName.data(), std::ios::binary | std::ios::in);
- if( !aIf.is_open() )
- {
- Print(EError, "Cannot open file %s", (char*)iImgFileName.data());
- return EFalse;
- }
-
- aIf.seekg(0, std::ios::end);
- aLen = aIf.tellg();
-
- if(iUseMemMap)
- {
- if(!AllocateImageMap(iImageMap, iData, aLen))
- {
- aLen = 0;
- Print(EError, "Failed to create image map object");
- return EFalse;
- }
- }
- else
- {
- iData = new unsigned char[aLen];
- if(iData == NULL)
- {
- aLen = 0;
- Print(EError, "Out of memory.\n");
- return EFalse;
- }
- memset(iData, 0, aLen);
- }
- aIf.seekg(0, std::ios::beg);
- aIf.read((char*)iData, aLen);
-
- if(!IsCoreROM() || !StoreImageHeader())
- {
- Print(EError, "Invalid Core ROM image %s", (char*)iImgFileName.data());
- aIf.close();
- return EFalse;
- }
-
- aIf.close();
-
- return ETrue;
-}
-
-TBool CoreRomImageReader::StoreImageHeader()
-{
- iLoaderHdr = (TRomLoaderHeader*)iData;
- iRomHdr = (TRomHeader*)(iData + sizeof(TRomLoaderHeader));
-
- if(!iLoaderHdr || !iRomHdr)
- return EFalse;
-
- return ETrue;
-}
-
-TInt CoreRomImageReader::CreateRootDirectory()
-{
- iRootDirectory = new TRomNode((TText*)"", (TRomBuilderEntry*)0);
- if (iRootDirectory == 0 )
- return KErrNoMemory;
- return KErrNone;
-}
-
-TBool CoreRomImageReader::ProcessImage()
-{
- Memmap *aImageMap = 0;
-
- if(iRomHdr->iCompressionType == KUidCompressionDeflate)
- {
- TUint aDataStart = GetHdrSize();
- TUint8* aData = 0;
- if(iUseMemMap)
- {
- if(!AllocateImageMap(aImageMap, aData, (iRomHdr->iUncompressedSize + aDataStart)))
- {
- Print(EError, "Failed to create image map object");
- return EFalse;
- }
- }
- else
- {
- aData = new unsigned char[iRomHdr->iUncompressedSize + aDataStart];
- }
-
- InflateUnCompress((unsigned char*)(iData + aDataStart), iRomHdr->iCompressedSize, (unsigned char*)(aData + aDataStart), iRomHdr->iUncompressedSize);
- memcpy(aData, iData, aDataStart);
-
- if(iUseMemMap)
- {
- iImageMap->CloseMemoryMap(ETrue);
- delete iImageMap;
- iImageMap = aImageMap;
- }
- else
- {
- delete [] iData;
- }
-
- iData = aData;
-
- //update the header fields...
- if(!StoreImageHeader())
- {
- return EFalse;
- }
- }
- else if (iRomHdr && iRomHdr->iRomPageIndex) // paged ROM
- {
- const TInt KPageSize = 0x1000;
- TUint8* aData = 0;
-
- TRomHeader *pRomHdr = iRomHdr;
-
- TUint headerSize = GetHdrSize();
-
- TInt numPages = (pRomHdr->iPageableRomStart + pRomHdr->iPageableRomSize+KPageSize-1)/KPageSize;
- if(iUseMemMap)
- {
- if(!AllocateImageMap(aImageMap, aData, (pRomHdr->iUncompressedSize + headerSize)))
- {
- Print(EError, "Failed to create image map object");
- return EFalse;
- }
- }
- else
- {
- aData = new TUint8[pRomHdr->iUncompressedSize + headerSize];
- }
- TUint8* dest = (aData + sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart);
- SRomPageInfo* pi = (SRomPageInfo*)((TUint8*)pRomHdr + pRomHdr->iRomPageIndex);
-
- CBytePair bpe(gFastCompress);
- for(TInt i=0; i<numPages; i++,pi++)
- {
- if (pi->iPagingAttributes != SRomPageInfo::EPageable) // skip uncompressed part at the beginning of ROM image
- continue;
-
- switch(pi->iCompressionType)
- {
- case SRomPageInfo::ENoCompression:
- {
- memcpy(dest, (TUint8*)pRomHdr + pi->iDataStart, pi->iDataSize);
- dest += pi->iDataSize;
- }
- break;
-
- case SRomPageInfo::EBytePair:
- {
- TUint8* srcNext=0;
- TInt unpacked = bpe.Decompress((unsigned char*)dest, KPageSize, (TUint8*)pRomHdr + pi->iDataStart, pi->iDataSize, srcNext);
- if (unpacked < 0)
- {
- if(iUseMemMap)
- {
- aImageMap->CloseMemoryMap(ETrue);
- delete aImageMap;
- }
- else
- {
- delete [] aData;
- }
- Print(EError, "Corrupted BytePair compressed ROM image %s", (char*)iImgFileName.data());
- return EFalse;
- }
-
- dest += unpacked;
- }
- break;
-
- default:
- {
- if(iUseMemMap)
- {
- aImageMap->CloseMemoryMap(ETrue);
- delete aImageMap;
- }
- else
- {
- delete [] aData;
- }
- Print(EError, "Undefined compression type in %s", (char*)iImgFileName.data());
- return EFalse;
- }
- }
- }
-
- memcpy(aData, iData, sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart);
- if(iUseMemMap)
- {
- iImageMap->CloseMemoryMap(ETrue);
- delete iImageMap;
- iImageMap = aImageMap;
- }
- else
- {
- delete [] iData;
- }
-
- iData = aData;
-
- //update the header fields...
- if(!StoreImageHeader())
- {
- return EFalse;
- }
- }
-
- if(CreateRootDirectory() != KErrNone)
- {
- return EFalse;
- }
-
- if(GetDirectoryStructures() != KErrNone)
- {
- return EFalse;
- }
-
- return ETrue;
-}
-
-TInt CoreRomImageReader::GetDirectoryStructures()
-{
- int aDirs = 0;
- TRomDir *aRomDir = 0;
-
- iRootDirList = (TRomRootDirectoryList*)ROM_PTR(iRomHdr->iRomRootDirectoryList);
-
- while( aDirs < iRootDirList->iNumRootDirs )
- {
- aRomDir = (TRomDir*)ROM_PTR(iRootDirList->iRootDir[aDirs].iAddressLin);
-
- if(BuildDir(aRomDir, iRootDirectory) != KErrNone)
- {
- return KErrNoMemory;
- }
- aDirs++;
- }
-
- return KErrNone;
-}
-
-
-TInt OffsetCompare(const void *a, const void *b)
-{
- return ( *(TInt16*)a - *(TInt16*)b );
-}
-
-TInt CoreRomImageReader::BuildDir(TRomDir* aDir, TRomNode* aPaFSEntry)
-{
- TInt16 *aFileCnt = 0;
- TInt16 *aBase, aCount;
- TInt16 *aSubDirCnt = 0;
-
- //Sub directories in this directories
- aSubDirCnt = (TInt16*)((char*)aDir + aDir->iSize + sizeof(aDir->iSize));
-
- //Files within this directory
- aFileCnt = aSubDirCnt+1;
-
- aCount = (*aFileCnt + *aSubDirCnt);
-
- aBase = aFileCnt+1;
-
- qsort((void*)aBase, aCount, sizeof(TInt16), &OffsetCompare);
-
- return BuildDir(aBase, aCount, aDir, aPaFSEntry);
-}
-
-TInt CoreRomImageReader::BuildDir(TInt16 *aOffsetTbl, TInt16 aOffsetTblCount,
- TRomDir *aPaRomDir, TRomNode* aPaFSEntry)
-{
- TRomNode *aNewFSEntry;
- TRomDir *aNewDir;
- TRomEntry *aRomEntry;
- TUint32 aOffsetFromBase;
-
- String aName;
- char *aPtr;
-
- while( aOffsetTblCount )
- {
- aOffsetFromBase = *aOffsetTbl;
-
- aOffsetFromBase <<= 2;
-
- aRomEntry = (TRomEntry*)((char*)aPaRomDir + sizeof(int) + aOffsetFromBase);
-
- aPtr = (char*)aRomEntry->iName;
- Name(aName, aPtr, aRomEntry->iNameLength);
-
- if( aRomEntry->iAtt & KEntryAttDir )
- {
- // add directory
- aNewFSEntry = aPaFSEntry->NewSubDir((unsigned char*)aName.data());
- if(aRomEntry->iAtt & KEntryAttHidden)
- aNewFSEntry->iHidden = ETrue;
- else
- aNewFSEntry->iHidden = EFalse;
-
- aNewDir = (TRomDir*)ROM_PTR(aRomEntry->iAddressLin);
- if(BuildDir(aNewDir, aNewFSEntry) != KErrNone)
- {
- return KErrNoMemory;
- }
- }
- else
- {
- // add file
- if(AddFile(aPaFSEntry, (char*)aName.data(), aRomEntry) != KErrNone)
- {
- return KErrNoMemory;
- }
- }
-
- aOffsetTblCount--;
- aOffsetTbl++;
- }
-
- return KErrNone;
-}
-
-TInt CoreRomImageReader::AddFile(TRomNode *aPa, char *entryName, TRomEntry* aRomEntry)
-{
- TRomImageHeader* aImgHdr = 0;
- TRomBuilderEntry* aFile = 0;
- TRomNode* aNewFSEntry = 0;
- static TRomNode* aLastExecutable = GetRootDirectory();
- TUint8 aUid1[4];
-
- aImgHdr = (TRomImageHeader*)ROM_PTR(aRomEntry->iAddressLin);
-
- aFile = new TRomBuilderEntry(0, (TUint8*)entryName);
-
- if(!aFile)
- {
- return KErrNoMemory;
- }
-
- aFile->iBareName = strdup((char*)aFile->iName);
- aFile->iUid1 = aImgHdr->iUid1;
- aFile->iUid2 = aImgHdr->iUid2;
- aFile->iUid3 = aImgHdr->iUid3;
- aFile->iRomImageFlags = aImgHdr->iFlags;
- aFile->iHardwareVariant = aImgHdr->iHardwareVariant;
-
- memcpy(aUid1, &(aImgHdr->iUid1), 4);
-
- aFile->iResource = !IsExecutable(aUid1);
-
- aNewFSEntry = new TRomNode((TUint8*)entryName, aFile);
- if(!aNewFSEntry)
- {
- return KErrNoMemory;
- }
-
- if(aRomEntry->iAtt & KEntryAttHidden)
- aNewFSEntry->iHidden = ETrue;
- else
- aNewFSEntry->iHidden = EFalse;
-
- // RomEntry Update
- aNewFSEntry->iRomFile->SetRomEntry(aRomEntry);
- aNewFSEntry->iRomFile->iFinal = ETrue;
-
- // E32 Image Pointer Update
- aNewFSEntry->iRomFile->iAddresses.iImageAddr = aRomEntry->iAddressLin;
- aNewFSEntry->iRomFile->iAddresses.iRunAddr = aRomEntry->iAddressLin;
- aNewFSEntry->iRomFile->iAddresses.iSize = aRomEntry->iSize;
- aNewFSEntry->iRomFile->iAddresses.iImagePtr = 0;
- aNewFSEntry->iRomFile->iExportDir.iImagePtr = 0;
-
- if(!aFile->iResource && !aFile->HCRDataFile())
- {
- // Hardware Variant Update
- aNewFSEntry->iRomFile->iHwvd = aImgHdr->iHardwareVariant;
- // Security Info Update
- aNewFSEntry->iRomFile->iRbEntry->iS = aImgHdr->iS;
-
- // Export Table Update
- aNewFSEntry->iRomFile->iExportDir.iSize = aImgHdr->iExportDirCount*4;
- aNewFSEntry->iRomFile->iExportDir.iImageAddr = aImgHdr->iExportDir;
- aNewFSEntry->iRomFile->iExportDir.iRunAddr = aImgHdr->iExportDir;
-
- if(aImgHdr->iExportDirCount)
- {
- aNewFSEntry->iRomFile->iExportDir.iImagePtr = new char[aNewFSEntry->iRomFile->iExportDir.iSize];
- memcpy(aNewFSEntry->iRomFile->iExportDir.iImagePtr,
- (TInt8*)ROM_PTR(aImgHdr->iExportDir),
- aNewFSEntry->iRomFile->iExportDir.iSize);
- }
-
- // E32 Image pointer Update
- aNewFSEntry->iRomFile->iAddresses.iImagePtr = new char[sizeof(TRomImageHeader)];
- memcpy(aNewFSEntry->iRomFile->iAddresses.iImagePtr, aImgHdr, sizeof(TRomImageHeader));
- }
- else
- {
- aNewFSEntry->iRomFile->iHwvd = KVariantIndependent;
- }
-
- aPa->AddFile(aNewFSEntry);
-
- if(aRomEntry->iAtt & KEntryAttXIP)
- {
- TRomNode::AddExecutableFile(aLastExecutable, aNewFSEntry);
- }
-
- return KErrNone;
-}
-
-void CoreRomImageReader::Name(String& aName, char * aUnicodeName, int aLen)
-{
- int aPos = 0;
- int uncodeLen = aLen << 1;
- aName=("");
- while( aPos < uncodeLen)
- {
- if( aUnicodeName[aPos] )
- aName += aUnicodeName[aPos];
- aPos++;
- }
-}
-
-TBool CoreRomImageReader::IsExecutable(TUint8* Uids1)
-{
- //In the little-endian world
- if( Uids1[3] == 0x10 &&
- Uids1[2] == 0x0 &&
- Uids1[1] == 0x0 )
- {
- if(Uids1[0] == 0x79 || Uids1[0] == 0x7a)
- return ETrue;
- }
- return EFalse;
-}
-
-void CoreRomImageReader::DeleteAll(TRomNode *node)
-{
- if(!node)
- return;
-
- if(node->iChild)
- {
- DeleteAll(node->iChild);
- }
-
- if(node->iSibling)
- {
- DeleteAll(node->iSibling);
- }
-
- if(node->iRomFile)
- {
- if(!node->iRomFile->iDir)
- {
- if(node->iRomFile->iExportDir.iImagePtr)
- {
- delete[] (char*)node->iRomFile->iExportDir.iImagePtr;
- node->iRomFile->iExportDir.iImagePtr = 0;
- }
- if(node->iRomFile->iAddresses.iImagePtr)
- {
- delete[] (char*)node->iRomFile->iAddresses.iImagePtr;
- node->iRomFile->iAddresses.iImagePtr = 0;
- }
-
- if(node->iRomFile->iRbEntry)
- {
- delete node->iRomFile->iRbEntry;
- node->iRomFile->iRbEntry = 0;
- }
- }
- delete node->iRomFile;
- node->iRomFile = 0;
- }
- delete node;
- node = 0;
-}
-
-
-void CoreRomImageReader::Display(TRomNode *node, TInt pad)
-{
- if(!node)
- return;
-
- Print(ELog, "\n%*s%s", pad, " ", node->iBareName);
-
- if(node->iChild)
- {
- pad += 2;
- Display(node->iChild, pad);
- pad -= 2;
- }
-
- if(node->iSibling)
- {
- Display(node->iSibling, pad);
- }
-}
+/*
+* Copyright (c) 2008-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:
+*
+*/
+
+
+#include <e32def.h>
+#include <e32def_private.h>
+#include <e32rom.h>
+
+#include "h_utl.h"
+#include "r_rom.h"
+
+#include "memmap.h"
+
+#include "r_coreimage.h"
+#include "r_global.h"
+#include "utf16string.h"
+
+
+#define ROM_PTR(base_ptr) ((TInt8*)iRomHdr + (base_ptr - iRomHdr->iRomBase))
+
+void InflateUnCompress(unsigned char* source, int sourcesize, unsigned char* dest, int destsize);
+
+const TUint KEntryAttDir=0x0010;
+const TUint KEntryAttXIP=0x0080;
+const TUint KEntryAttHidden=0x0002;
+
+// CoreRomImageReader
+//
+CoreRomImageReader::CoreRomImageReader(const char* aFileName, TBool aUseMemMap) : iImgFileName(aFileName),
+iData(0), iLoaderHdr(0), iRomHdr(0), iRootDirList(0), iRootDirectory(0), iUseMemMap(aUseMemMap), iImageMap(0)
+{
+}
+
+CoreRomImageReader::~CoreRomImageReader()
+{
+ if(iData)
+ {
+ if(iUseMemMap)
+ {
+ iImageMap->CloseMemoryMap(ETrue);
+ delete iImageMap;
+ }
+ else
+ delete iData;
+ }
+
+ if(iRootDirectory)
+ {
+ DeleteAll(iRootDirectory);
+ }
+}
+
+TBool CoreRomImageReader::IsCoreROM()
+{
+ if(iData)
+ {
+ if(iData[0] == 'E' && iData[1] == 'P' && iData[2] == 'O' && iData[3] == 'C' &&
+ iData[8] == 'R' && iData[9] == 'O' && iData[10] == 'M')
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+}
+
+TUint CoreRomImageReader::GetHdrSize()
+{
+ return (sizeof(TRomLoaderHeader) + sizeof(TRomHeader));
+}
+
+TBool CoreRomImageReader::AllocateImageMap(Memmap*& aImageMap, TUint8*& aData, TUint aLen)
+{
+ aImageMap = new Memmap(EFalse);
+
+ if(aImageMap == NULL)
+ {
+ return EFalse;
+ }
+ else
+ {
+ aImageMap->SetMaxMapSize(aLen);
+ if(aImageMap->CreateMemoryMap() == EFalse)
+ {
+ aImageMap->CloseMemoryMap(ETrue);
+ delete aImageMap;
+ aImageMap = NULL;
+ return EFalse;
+ }
+ else
+ {
+ aData = (TUint8*)aImageMap->GetMemoryMapPointer();
+ }
+ }
+
+ return ETrue;
+}
+
+TBool CoreRomImageReader::OpenImage()
+{
+ TUint aLen = 0;
+
+ ifstream aIf(iImgFileName.c_str(), ios_base::binary | ios_base::in);
+ if( !aIf.is_open() )
+ {
+ Print(EError, "Cannot open file %s", iImgFileName.c_str());
+ return EFalse;
+ }
+
+ aIf.seekg(0, ios_base::end);
+ aLen = aIf.tellg();
+
+ if(iUseMemMap)
+ {
+ if(!AllocateImageMap(iImageMap, iData, aLen))
+ {
+ aLen = 0;
+ Print(EError, "Failed to create image map object");
+ return EFalse;
+ }
+ }
+ else
+ {
+ iData = new unsigned char[aLen];
+ if(iData == NULL)
+ {
+ aLen = 0;
+ Print(EError, "Out of memory.\n");
+ return EFalse;
+ }
+ memset(iData, 0, aLen);
+ }
+ aIf.seekg(0, ios_base::beg);
+ aIf.read((char*)iData, aLen);
+
+ if(!IsCoreROM() || !StoreImageHeader())
+ {
+ Print(EError, "Invalid Core ROM image %s", iImgFileName.c_str());
+ aIf.close();
+ return EFalse;
+ }
+
+ aIf.close();
+
+ return ETrue;
+}
+
+TBool CoreRomImageReader::StoreImageHeader()
+{
+ iLoaderHdr = (TRomLoaderHeader*)iData;
+ iRomHdr = (TRomHeader*)(iData + sizeof(TRomLoaderHeader));
+
+ if(!iLoaderHdr || !iRomHdr)
+ return EFalse;
+
+ return ETrue;
+}
+
+TInt CoreRomImageReader::CreateRootDirectory()
+{
+ iRootDirectory = new TRomNode("", (TRomBuilderEntry*)0);
+ if (iRootDirectory == 0 )
+ return KErrNoMemory;
+ return KErrNone;
+}
+
+TBool CoreRomImageReader::ProcessImage()
+{
+ Memmap *aImageMap = 0;
+
+ if(iRomHdr->iCompressionType == KUidCompressionDeflate)
+ {
+ TUint aDataStart = GetHdrSize();
+ TUint8* aData = 0;
+ if(iUseMemMap)
+ {
+ if(!AllocateImageMap(aImageMap, aData, (iRomHdr->iUncompressedSize + aDataStart)))
+ {
+ Print(EError, "Failed to create image map object");
+ return EFalse;
+ }
+ }
+ else
+ {
+ aData = new unsigned char[iRomHdr->iUncompressedSize + aDataStart];
+ }
+
+ InflateUnCompress((unsigned char*)(iData + aDataStart), iRomHdr->iCompressedSize, (unsigned char*)(aData + aDataStart), iRomHdr->iUncompressedSize);
+ memcpy(aData, iData, aDataStart);
+
+ if(iUseMemMap)
+ {
+ iImageMap->CloseMemoryMap(ETrue);
+ delete iImageMap;
+ iImageMap = aImageMap;
+ }
+ else
+ {
+ delete [] iData;
+ }
+
+ iData = aData;
+
+ //update the header fields...
+ if(!StoreImageHeader())
+ {
+ return EFalse;
+ }
+ }
+ else if (iRomHdr && iRomHdr->iRomPageIndex) // paged ROM
+ {
+ const TInt KPageSize = 0x1000;
+ TUint8* aData = 0;
+
+ TRomHeader *pRomHdr = iRomHdr;
+
+ TUint headerSize = GetHdrSize();
+
+ TInt numPages = (pRomHdr->iPageableRomStart + pRomHdr->iPageableRomSize+KPageSize-1)/KPageSize;
+ if(iUseMemMap)
+ {
+ if(!AllocateImageMap(aImageMap, aData, (pRomHdr->iUncompressedSize + headerSize)))
+ {
+ Print(EError, "Failed to create image map object");
+ return EFalse;
+ }
+ }
+ else
+ {
+ aData = new TUint8[pRomHdr->iUncompressedSize + headerSize];
+ }
+ TUint8* dest = (aData + sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart);
+ SRomPageInfo* pi = (SRomPageInfo*)((TUint8*)pRomHdr + pRomHdr->iRomPageIndex);
+
+ CBytePair bpe;
+ for(TInt i=0; i<numPages; i++,pi++)
+ {
+ if (pi->iPagingAttributes != SRomPageInfo::EPageable) // skip uncompressed part at the beginning of ROM image
+ continue;
+
+ switch(pi->iCompressionType)
+ {
+ case SRomPageInfo::ENoCompression:
+ {
+ memcpy(dest, (TUint8*)pRomHdr + pi->iDataStart, pi->iDataSize);
+ dest += pi->iDataSize;
+ }
+ break;
+
+ case SRomPageInfo::EBytePair:
+ {
+ TUint8* srcNext=0;
+ TInt unpacked = bpe.Decompress((unsigned char*)dest, KPageSize, (TUint8*)pRomHdr + pi->iDataStart, pi->iDataSize, srcNext);
+ if (unpacked < 0)
+ {
+ if(iUseMemMap)
+ {
+ aImageMap->CloseMemoryMap(ETrue);
+ delete aImageMap;
+ }
+ else
+ {
+ delete [] aData;
+ }
+ Print(EError, "Corrupted BytePair compressed ROM image %s", iImgFileName.c_str());
+ return EFalse;
+ }
+
+ dest += unpacked;
+ }
+ break;
+
+ default:
+ {
+ if(iUseMemMap)
+ {
+ aImageMap->CloseMemoryMap(ETrue);
+ delete aImageMap;
+ }
+ else
+ {
+ delete [] aData;
+ }
+ Print(EError, "Undefined compression type in %s", iImgFileName.c_str());
+ return EFalse;
+ }
+ }
+ }
+
+ memcpy(aData, iData, sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart);
+ if(iUseMemMap)
+ {
+ iImageMap->CloseMemoryMap(ETrue);
+ delete iImageMap;
+ iImageMap = aImageMap;
+ }
+ else
+ {
+ delete [] iData;
+ }
+
+ iData = aData;
+
+ //update the header fields...
+ if(!StoreImageHeader())
+ {
+ return EFalse;
+ }
+ }
+
+ if(CreateRootDirectory() != KErrNone)
+ {
+ return EFalse;
+ }
+
+ if(GetDirectoryStructures() != KErrNone)
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+}
+
+TInt CoreRomImageReader::GetDirectoryStructures()
+{
+ int aDirs = 0;
+ TRomDir *aRomDir = 0;
+
+ iRootDirList = (TRomRootDirectoryList*)ROM_PTR(iRomHdr->iRomRootDirectoryList);
+
+ while( aDirs < iRootDirList->iNumRootDirs )
+ {
+ aRomDir = (TRomDir*)ROM_PTR(iRootDirList->iRootDir[aDirs].iAddressLin);
+
+ if(BuildDir(aRomDir, iRootDirectory) != KErrNone)
+ {
+ return KErrNoMemory;
+ }
+ aDirs++;
+ }
+
+ return KErrNone;
+}
+
+
+TInt OffsetCompare(const void *a, const void *b)
+{
+ return ( *(TInt16*)a - *(TInt16*)b );
+}
+
+TInt CoreRomImageReader::BuildDir(TRomDir* aDir, TRomNode* aPaFSEntry)
+{
+ TInt16 *aFileCnt = 0;
+ TInt16 *aBase, aCount;
+ TInt16 *aSubDirCnt = 0;
+
+ //Sub directories in this directories
+ aSubDirCnt = (TInt16*)((char*)aDir + aDir->iSize + sizeof(aDir->iSize));
+
+ //Files within this directory
+ aFileCnt = aSubDirCnt+1;
+
+ aCount = (*aFileCnt + *aSubDirCnt);
+
+ aBase = aFileCnt+1;
+
+ qsort((void*)aBase, aCount, sizeof(TInt16), &OffsetCompare);
+
+ return BuildDir(aBase, aCount, aDir, aPaFSEntry);
+}
+
+TInt CoreRomImageReader::BuildDir(TInt16 *aOffsetTbl, TInt16 aOffsetTblCount,
+ TRomDir *aPaRomDir, TRomNode* aPaFSEntry)
+{
+ TRomNode *aNewFSEntry;
+ TRomDir *aNewDir;
+ TRomEntry *aRomEntry;
+ TUint32 aOffsetFromBase;
+
+ string aName;
+ //char *aPtr;
+
+ while( aOffsetTblCount )
+ {
+ aOffsetFromBase = *aOffsetTbl;
+
+ aOffsetFromBase <<= 2;
+
+ aRomEntry = (TRomEntry*)((char*)aPaRomDir + sizeof(int) + aOffsetFromBase);
+ UTF16String unistr(reinterpret_cast<const TUint16*>(aRomEntry->iName),aRomEntry->iNameLength);
+ if(!unistr.ToUTF8(aName))
+ aName.assign(reinterpret_cast<const char*>(aRomEntry->iName),aRomEntry->iNameLength);
+
+ if( aRomEntry->iAtt & KEntryAttDir )
+ {
+ // add directory
+ aNewFSEntry = aPaFSEntry->NewSubDir(aName.c_str());
+ if(aRomEntry->iAtt & KEntryAttHidden)
+ aNewFSEntry->iHidden = ETrue;
+ else
+ aNewFSEntry->iHidden = EFalse;
+
+ aNewDir = (TRomDir*)ROM_PTR(aRomEntry->iAddressLin);
+ if(BuildDir(aNewDir, aNewFSEntry) != KErrNone)
+ {
+ return KErrNoMemory;
+ }
+ }
+ else
+ {
+ // add file
+ if(AddFile(aPaFSEntry, aName.c_str(), aRomEntry) != KErrNone)
+ {
+ return KErrNoMemory;
+ }
+ }
+
+ aOffsetTblCount--;
+ aOffsetTbl++;
+ }
+
+ return KErrNone;
+}
+
+TInt CoreRomImageReader::AddFile(TRomNode *aPa, const char* entryName, TRomEntry* aRomEntry)
+{
+ TRomImageHeader* aImgHdr = 0;
+ TRomBuilderEntry* aFile = 0;
+ TRomNode* aNewFSEntry = 0;
+ static TRomNode* aLastExecutable = GetRootDirectory();
+ TUint8 aUid1[4];
+
+ aImgHdr = (TRomImageHeader*)ROM_PTR(aRomEntry->iAddressLin);
+
+ aFile = new TRomBuilderEntry(0, entryName);
+
+ if(!aFile)
+ {
+ return KErrNoMemory;
+ }
+ size_t len = strlen(aFile->iName) + 1;
+ aFile->iBareName = new char[len];
+ memcpy(aFile->iBareName,aFile->iName,len);
+ aFile->iUid1 = aImgHdr->iUid1;
+ aFile->iUid2 = aImgHdr->iUid2;
+ aFile->iUid3 = aImgHdr->iUid3;
+ aFile->iRomImageFlags = aImgHdr->iFlags;
+ aFile->iHardwareVariant = aImgHdr->iHardwareVariant;
+
+ memcpy(aUid1, &(aImgHdr->iUid1), 4);
+
+ aFile->iResource = !IsExecutable(aUid1);
+
+ aNewFSEntry = new TRomNode(entryName, aFile);
+ if(!aNewFSEntry)
+ {
+ return KErrNoMemory;
+ }
+
+ if(aRomEntry->iAtt & KEntryAttHidden)
+ aNewFSEntry->iHidden = ETrue;
+ else
+ aNewFSEntry->iHidden = EFalse;
+
+ // RomEntry Update
+ aNewFSEntry->iRomFile->SetRomEntry(aRomEntry);
+ aNewFSEntry->iRomFile->iFinal = ETrue;
+
+ // E32 Image Pointer Update
+ aNewFSEntry->iRomFile->iAddresses.iImageAddr = aRomEntry->iAddressLin;
+ aNewFSEntry->iRomFile->iAddresses.iRunAddr = aRomEntry->iAddressLin;
+ aNewFSEntry->iRomFile->iAddresses.iSize = aRomEntry->iSize;
+ aNewFSEntry->iRomFile->iAddresses.iImagePtr = 0;
+ aNewFSEntry->iRomFile->iExportDir.iImagePtr = 0;
+
+ if(!aFile->iResource && !aFile->HCRDataFile())
+ {
+ // Hardware Variant Update
+ aNewFSEntry->iRomFile->iHwvd = aImgHdr->iHardwareVariant;
+ // Security Info Update
+ aNewFSEntry->iRomFile->iRbEntry->iS = aImgHdr->iS;
+
+ // Export Table Update
+ aNewFSEntry->iRomFile->iExportDir.iSize = aImgHdr->iExportDirCount*4;
+ aNewFSEntry->iRomFile->iExportDir.iImageAddr = aImgHdr->iExportDir;
+ aNewFSEntry->iRomFile->iExportDir.iRunAddr = aImgHdr->iExportDir;
+
+ if(aImgHdr->iExportDirCount)
+ {
+ aNewFSEntry->iRomFile->iExportDir.iImagePtr = new char[aNewFSEntry->iRomFile->iExportDir.iSize];
+ memcpy(aNewFSEntry->iRomFile->iExportDir.iImagePtr,
+ (TInt8*)ROM_PTR(aImgHdr->iExportDir),
+ aNewFSEntry->iRomFile->iExportDir.iSize);
+ }
+
+ // E32 Image pointer Update
+ aNewFSEntry->iRomFile->iAddresses.iImagePtr = new char[sizeof(TRomImageHeader)];
+ memcpy(aNewFSEntry->iRomFile->iAddresses.iImagePtr, aImgHdr, sizeof(TRomImageHeader));
+ }
+ else
+ {
+ aNewFSEntry->iRomFile->iHwvd = KVariantIndependent;
+ }
+
+ aPa->AddFile(aNewFSEntry);
+
+ if(aRomEntry->iAtt & KEntryAttXIP)
+ {
+ TRomNode::AddExecutableFile(aLastExecutable, aNewFSEntry);
+ }
+
+ return KErrNone;
+}
+
+
+
+TBool CoreRomImageReader::IsExecutable(TUint8* Uids1)
+{
+ //In the little-endian world
+ if( Uids1[3] == 0x10 &&
+ Uids1[2] == 0x0 &&
+ Uids1[1] == 0x0 )
+ {
+ if(Uids1[0] == 0x79 || Uids1[0] == 0x7a)
+ return ETrue;
+ }
+ return EFalse;
+}
+
+void CoreRomImageReader::DeleteAll(TRomNode *node)
+{
+ if(!node)
+ return;
+
+ if(node->iChild)
+ {
+ DeleteAll(node->iChild);
+ }
+
+ if(node->iSibling)
+ {
+ DeleteAll(node->iSibling);
+ }
+
+ if(node->iRomFile)
+ {
+ if(!node->iRomFile->iDir)
+ {
+ if(node->iRomFile->iExportDir.iImagePtr)
+ {
+ delete[] (char*)node->iRomFile->iExportDir.iImagePtr;
+ node->iRomFile->iExportDir.iImagePtr = 0;
+ }
+ if(node->iRomFile->iAddresses.iImagePtr)
+ {
+ delete[] (char*)node->iRomFile->iAddresses.iImagePtr;
+ node->iRomFile->iAddresses.iImagePtr = 0;
+ }
+
+ if(node->iRomFile->iRbEntry)
+ {
+ delete node->iRomFile->iRbEntry;
+ node->iRomFile->iRbEntry = 0;
+ }
+ }
+ delete node->iRomFile;
+ node->iRomFile = 0;
+ }
+ delete node;
+ node = 0;
+}
+
+
+void CoreRomImageReader::Display(TRomNode *node, TInt pad)
+{
+ if(!node)
+ return;
+
+ Print(ELog, "\n%*s%s", pad, " ", node->iBareName);
+
+ if(node->iChild)
+ {
+ pad += 2;
+ Display(node->iChild, pad);
+ pad -= 2;
+ }
+
+ if(node->iSibling)
+ {
+ Display(node->iSibling, pad);
+ }
+}