diff -r b3cee849fa46 -r fad26422216a launcher/engine/src/e32image.cpp --- a/launcher/engine/src/e32image.cpp Tue Aug 31 15:15:20 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,846 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "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 "e32image.h" -#include "e32imageheaders.h" -#include "launchertraces.h" - - -const TInt KMaxHeaderSize = sizeof(E32ImageHeaderV) + 65536/8; - -SCapabilitySet AllCapabilities; -SCapabilitySet DisabledCapabilities; - -// --------------------------------------------------------------------------- - -E32ImageReader* E32ImageReader::NewLC() - { - E32ImageReader* self = new(ELeave) E32ImageReader; - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } - -// --------------------------------------------------------------------------- - -E32ImageReader::E32ImageReader() - { - } - -// --------------------------------------------------------------------------- - -void E32ImageReader::ConstructL() - { - LOGSTRING("Launcher: E32ImageReader::ConstructL"); - - iEnv = CEikonEnv::Static(); - } - -// --------------------------------------------------------------------------- - -CDesCArray* E32ImageReader::ListOfDLLsL(const TDesC& aFullPathToE32Image) - { - LOGSTRING("Launcher: E32ImageReader::ListOfDLLsL"); - - // open the file for reading - User::LeaveIfError( iFile.Open(iEnv->FsSession(), aFullPathToE32Image, EFileRead) ); - CleanupClosePushL(iFile); - - // get local copies of capability sets - TCapabilitySet caps; - caps.SetAllSupported(); - AllCapabilities=*(SCapabilitySet*)∩︀ - caps.SetDisabled(); - DisabledCapabilities=*(SCapabilitySet*)∩︀ - - // read the header of the image - User::LeaveIfError( E32ImageHeader::New(iHeader, iFile) ); - - // set stuff - iHeapSizeMin = iHeader->iHeapSizeMin; - iHeapSizeMax = iHeader->iHeapSizeMax; - iStackSize = iHeader->iStackSize; - iPriority = iHeader->ProcessPriority(); - iDepCount = iHeader->iDllRefTableCount; - iExportDirCount = iHeader->iExportDirCount; - iExportDir = iHeader->iExportDirOffset-iHeader->iCodeOffset; - iTextSize = iHeader->iTextSize; - iCodeSize = iHeader->iCodeSize; - iDataSize = iHeader->iDataSize; - iBssSize = iHeader->iBssSize; - iTotalDataSize = iDataSize+iBssSize; - iFileEntryPoint = iHeader->iEntryPoint; - iEntryPtVeneer = 0; - iExceptionDescriptor = iHeader->ExceptionDescriptor(); - if (iHeader->iExportDirOffset) - iExportDirLoad=iExportDir; - - // allocate data for the code area - iCodeLoadAddress = (TUint32)User::Alloc(iCodeSize); - - // load data from the binary - User::LeaveIfError( LoadData() ); - - // create an array for the dll names from the import list - CDesCArray* dllArray = new(ELeave) CDesCArrayFlat(100); - CleanupStack::PushL(dllArray); - - // get the dll names from the import section - E32ImportSection* importSection = (E32ImportSection *)iImportData; - E32ImportBlock* block; - if(importSection) - block = (E32ImportBlock*)(importSection+1); - else - block = NULL; - iNextImportPos = 0; - - // loop through all import data blocks - for (TInt i=0; iiOffsetOfDllName); - TBuf8 rootname; - if (dllname.Length() > KMaxKernelName) - User::Leave( KErrNotSupported ); - - // parse the filename - TFileNameInfo fni; - User::LeaveIfError( fni.Set(dllname, TFileNameInfo::EAllowUid) ); - fni.GetName(rootname, TFileNameInfo::EIncludeBaseExt); - - // append the name to the dll name array - TFileName dllName16; - dllName16.Copy(rootname); - dllArray->AppendL(dllName16); - - // get the next block - TUint impfmt = iHeader->ImportFormat(); - block = (E32ImportBlock*)block->NextBlock(impfmt); - } - - CleanupStack::Pop(); //dllArray - CleanupStack::PopAndDestroy(); //iFile - - // free memory - delete iHeader; - iHeader = NULL; - delete iImportSection; - iImportSection = NULL; - delete iCodeRelocSection; - iCodeRelocSection = NULL; - delete iDataRelocSection; - iDataRelocSection = NULL; - - User::Free((TAny*)iCodeLoadAddress); - User::Free(iRestOfFileData); - User::Free(iCurrentImportList); - if (iExportDirLoadAllocated) - User::Free((TAny*)iExportDirLoad); - - return dllArray; - } - -// --------------------------------------------------------------------------- - -E32ImageReader::~E32ImageReader() - { - LOGSTRING("Launcher: E32ImageReader::~E32ImageReader"); - } - - -// --------------------------------------------------------------------------- - -TInt FileRead(RFile& aFile, TUint8* aDest, TInt aSize) - { - TPtr8 p(aDest,aSize,aSize); - return aFile.Read(p,aSize); - } - -// --------------------------------------------------------------------------- - -TInt E32ImageHeader::New(E32ImageHeader*& aHdr, RFile& aFile) - { - LOGSTRING("Launcher: E32ImageHeader::New"); - - E32ImageHeader* h = NULL; - TInt hdrsz = 0; - TInt filesize; - TInt r = aFile.Size(filesize); - if (r!=KErrNone) - return r; - E32ImageHeader bh; - r = FileRead(aFile, (TUint8*)&bh, sizeof(E32ImageHeader)); - if (r==KErrNone) - { - hdrsz = bh.TotalSize(); - if ( (TUint(hdrsz) > TUint(KMaxHeaderSize)) || (TUint(hdrsz) < TUint(sizeof(bh))) ) - return KErrCorrupt; - } - h = (E32ImageHeader*)User::Alloc(hdrsz); - if (!h) - return KErrNoMemory; - wordmove(h, &bh, sizeof(E32ImageHeader)); - if (hdrsz > (TInt)sizeof(E32ImageHeader)) - r = FileRead(aFile, (TUint8*)(h + 1), hdrsz - sizeof(E32ImageHeader)); - if (r==KErrNone) - r = h->IntegrityCheck(filesize); - if (r==KErrNone) - { - if (h->HeaderFormat() >= KImageHdrFmt_V) - { - // Overide capabilities in image - for(TInt i=0; iiS.iCaps[i] |= DisabledCapabilities[i]; - ((E32ImageHeaderV*)h)->iS.iCaps[i] &= AllCapabilities[i]; - } - } - aHdr = h; - } - else - { - delete h; - aHdr = NULL; - } - return r; - } - -// --------------------------------------------------------------------------- - -TInt E32ImageHeader::IntegrityCheck(TInt aFileSize) - { - LOGSTRING("Launcher: E32ImageHeader::IntegrityCheck"); - - TInt hdrsz = TotalSize(); - TUint hdrfmt = HeaderFormat(); - TUidType uids = *(const TUidType*)&iUid1; - E32ImageHeaderV* v = NULL; - TCheckedUid chkuid(uids); - const TUint32* pChkUid = (const TUint32*)&chkuid; - - if (pChkUid[3] != iUidChecksum) - return KErrCorrupt; - - if (hdrfmt == KImageHdrFmt_V) - { - TUint32 supplied_crc = iHeaderCrc; - iHeaderCrc = KImageCrcInitialiser; - TUint32 crc = 0; - Mem::Crc32(crc, this, hdrsz); - iHeaderCrc = supplied_crc; - if (crc != supplied_crc) - return KErrCorrupt; - v = (E32ImageHeaderV*)this; - TUint total_eds = v->iExportDescSize + sizeof(v->iExportDescSize) + sizeof(v->iExportDescType); - total_eds = (total_eds + 3) &~ 3; - if (total_eds + (TUint)_FOFF(E32ImageHeaderV, iExportDescSize) != (TUint)hdrsz) - return KErrCorrupt; - if (TUint(v->iExportDescType) > KImageHdr_ExpD_SparseBitmap8) - return KErrNotSupported; - } - else if (hdrfmt >= KImageHdrFmt_V) - return KErrNotSupported; - - TCpu cpu = CpuIdentifier(); - TUint abi = ABI(); - TUint impfmt = ImportFormat(); - TUint compression = CompressionType(); - - TUint uncompressed_size = compression ? UncompressedFileSize() : (TUint)aFileSize; - - if (iSignature != 0x434f5045) // 'EPOC' - return KErrCorrupt; - if (iCodeSize<0) - return KErrCorrupt; - if (iDataSize<0) - return KErrCorrupt; - if (iHeapSizeMin<0) - return KErrCorrupt; - if (iHeapSizeMax= uncompressed_size) - return KErrCorrupt; - if (TUint(iExportDirCount)>65535) - return KErrCorrupt; - if (iTextSize<0) - return KErrCorrupt; - if (iCodeSize= uncompressed_size) - return KErrCorrupt; - if (iDataOffset >= uncompressed_size) - return KErrCorrupt; - if (iImportOffset >= uncompressed_size) - return KErrCorrupt; - if (iCodeRelocOffset >= uncompressed_size) - return KErrCorrupt; - if (iDataRelocOffset >= uncompressed_size) - return KErrCorrupt; - if (TUint(iCodeSize+iDataSize) > uncompressed_size) - return KErrCorrupt; - - if (abi>KImageABI_EABI) - return KErrNotSupported; - if (impfmt>KImageImpFmt_PE2) - return KErrNotSupported; - if (iUid1 != (TUint32)KExecutableImageUidValue && iUid1 != (TUint32)KDynamicLibraryUidValue) - return KErrNotSupported; - TUint32 mv = ModuleVersion(); - if (mv >= 0x80000000u || (mv & 0x0000ffffu) > 0x8000u) - return KErrNotSupported; - - return KErrNone; - } -// --------------------------------------------------------------------------- - -TInt E32ImageReader::LoadData() - { - LOGSTRING("Launcher: E32ImageReader::LoadData"); - - TInt remainder; - iFile.Size(remainder); - - remainder -= iHeader->TotalSize(); - TUint32 compression = iHeader->CompressionType(); - if (compression != KMyFormatNotCompressed) - { - remainder = iHeader->UncompressedFileSize() - iHeader->iCodeOffset; - } - - remainder -= iHeader->iCodeSize; - - if (remainder > 0) - { - iRestOfFileData = (TUint8*)User::Alloc(remainder); - if (iRestOfFileData) - iRestOfFileSize=remainder; - else - return KErrNoMemory; - } - - iConversionOffset = iHeader->iCodeOffset + iHeader->iCodeSize; - - TInt r = LoadFile(compression); - if (r !=KErrNone) - return r; - - - TUint8* source=NULL; - if (iHeader->iImportOffset) - { - TUint bufferOffset=iHeader->iImportOffset-iConversionOffset; - - if(bufferOffset>iRestOfFileSize || bufferOffset+sizeof(E32ImportSection)>iRestOfFileSize) - return KErrCorrupt; - - source=iRestOfFileData+bufferOffset; - - iImportSection = new E32ImportSection; - - if (iImportSection) - Mem::Move((TText8*)iImportSection, source, sizeof(E32ImportSection)); - else - return KErrNoMemory; - } - - iCodeDelta = iCodeRunAddress-iHeader->iCodeBase; - iDataDelta = iDataRunAddress-iHeader->iDataBase; - - if (r==KErrNone) - r = ReadImportData(); - - return r; - } - -// --------------------------------------------------------------------------- - -TUint8* E32ImageReader::MemoryMove(TAny* aDestination, const TAny* aSource, TInt aNumberofBytes) - { - return Mem::Move(aDestination, aSource, aNumberofBytes); - } - -// --------------------------------------------------------------------------- - -GLDEF_C TInt svRelocateExports(TAny* aPtr) - { - E32ImageReader* pI=(E32ImageReader*)aPtr; - TUint32* destExport=(TUint32*)pI->iExportDirLoad; - TInt i=pI->iExportDirCount; - TUint32 codeBase=pI->iCodeRunAddress; - while (i-->0) - *destExport+++=codeBase; - return 0; - } - -// --------------------------------------------------------------------------- - -TInt E32ImageReader::LoadFile(TUint32 aCompression) - { - LOGSTRING("Launcher: E32ImageReader::LoadFile"); - - TInt r(KErrNone); - - if (aCompression == KMyFormatNotCompressed) - r=LoadFileNoCompress(); - - else if (aCompression == KMyUidCompressionDeflate) - { - TRAP(r, LoadFileInflateL()); - } - - else - r = KErrNotSupported; - - return r; - } - -// --------------------------------------------------------------------------- - -TInt E32ImageReader::LoadFileNoCompress() - { - LOGSTRING("Launcher: E32ImageReader::LoadFileNoCompress"); - - TInt r(KErrNone); - - if (iHeader->iCodeSize) - { - r = Read(iHeader->iCodeOffset, (TText8*)iCodeLoadAddress, iCodeSize); - } - - if (r != KErrNone) - { - return r; - } - - if (iRestOfFileSize) - { - r = Read(iConversionOffset, (TText8*)iRestOfFileData, iRestOfFileSize); - } - - return r; - } - -// --------------------------------------------------------------------------- - -void FileCleanup(TAny* aPtr) - { - TFileInput* f=(TFileInput*)aPtr; - f->Cancel(); - delete f; - } - -// --------------------------------------------------------------------------- - -void E32ImageReader::LoadFileInflateL() - { - LOGSTRING("Launcher: E32ImageReader::LoadFileInflateL"); - - TInt pos = iHeader->TotalSize(); - User::LeaveIfError(iFile.Seek(ESeekStart,pos)); - - TFileInput* file = new (ELeave) TFileInput(iFile); - CleanupStack::PushL(TCleanupItem(&FileCleanup,file)); - CInflater* inflater = CInflater::NewLC(*file); - - if (iHeader->iCodeSize) - { - TInt count = inflater->ReadL((TUint8*)iCodeLoadAddress, iCodeSize, &MemoryMove); - - if(count!=iCodeSize) - User::Leave(KErrCorrupt); - } - - if (iRestOfFileSize) - { - TUint32 count = inflater->ReadL(iRestOfFileData, iRestOfFileSize, &Mem::Move); - - if(count!=iRestOfFileSize) - User::Leave(KErrCorrupt); - } - - CleanupStack::PopAndDestroy(2,file); - } - -// --------------------------------------------------------------------------- - -TInt E32ImageReader::Read(TText8* aDest, TInt aSize) - { - TPtr8 p(aDest,aSize,aSize); - return iFile.Read(p,aSize); - } - -// --------------------------------------------------------------------------- - -TInt E32ImageReader::Read(TInt aPos, TText8* aDest, TInt aSize) - { - TPtr8 p(aDest,aSize,aSize); - if (aPos<0) - return KErrCorrupt; - return iFile.Read(aPos,p,aSize); - } - -// --------------------------------------------------------------------------- - -TInt E32ImageReader::ReadImportData() - { - LOGSTRING("Launcher: E32ImageReader::ReadImportData"); - - if (!iHeader->iImportOffset) - return KErrNone; - - TUint32 bufferOffset = iHeader->iImportOffset-iConversionOffset; - - if(bufferOffset>iRestOfFileSize || bufferOffset+iImportSection->iSize>iRestOfFileSize) - return KErrCorrupt; - - iImportData = (TUint32*)(iRestOfFileData+bufferOffset); - - E32ImportSection* s = (E32ImportSection*)iImportData; - E32ImportBlock* b = (E32ImportBlock*)(s + 1); - TUint impfmt = iHeader->ImportFormat(); - TInt i; - TInt n = 0; - - for (i=0; iiNumberOfImports > n) - n = b->iNumberOfImports; - b = (E32ImportBlock*)b->NextBlock(impfmt); - } - - iCurrentImportList = (TUint32*)User::Alloc(n * sizeof(TUint32)); - - if (!iCurrentImportList) - return KErrNoMemory; - - return KErrNone; - } - -// --------------------------------------------------------------------------- - -inline CInflater::CInflater(TBitInput& aInput) - :iBits(&aInput),iEncoding(0),iOut(0) - {} - -// --------------------------------------------------------------------------- - -void CInflater::ConstructL() - { - iEncoding=new(ELeave) TEncoding; - InitL(); - iLen=0; - iOut=new(ELeave) TUint8[KDeflateMaxDistance]; - iAvail=iLimit=iOut; - } - -// --------------------------------------------------------------------------- - -CInflater* CInflater::NewLC(TBitInput& aInput) - { - CInflater* self=new(ELeave) CInflater(aInput); - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } - -// --------------------------------------------------------------------------- - -CInflater::~CInflater() - { - delete iEncoding; - delete [] iOut; - } - -// --------------------------------------------------------------------------- - -TInt CInflater::ReadL(TUint8* aBuffer,TInt aLength, TMemoryMoveFunction aMemMovefn) - { - TInt tfr=0; - for (;;) - { - TInt len=Min(aLength,iLimit-iAvail); - if (len && aBuffer) - { - aMemMovefn(aBuffer,iAvail,len); - aBuffer+=len; - } - aLength-=len; - iAvail+=len; - tfr+=len; - if (aLength==0) - return tfr; - len=InflateL(); - if (len==0) - return tfr; - iAvail=iOut; - iLimit=iAvail+len; - } - } - -// --------------------------------------------------------------------------- - -TInt CInflater::SkipL(TInt aLength) - { - return ReadL(0,aLength,Mem::Move); - } - -// --------------------------------------------------------------------------- - -void CInflater::InitL() - { - Huffman::InternalizeL(*iBits,iEncoding->iLitLen,KDeflationCodes); - - if (!Huffman::IsValid(iEncoding->iLitLen,TEncoding::ELitLens) || - !Huffman::IsValid(iEncoding->iDistance,TEncoding::EDistances)) - User::Leave(KErrCorrupt); - - Huffman::Decoding(iEncoding->iLitLen,TEncoding::ELitLens,iEncoding->iLitLen); - Huffman::Decoding(iEncoding->iDistance,TEncoding::EDistances,iEncoding->iDistance,KDeflateDistCodeBase); - } - -// --------------------------------------------------------------------------- - -TInt CInflater::InflateL() - { - TUint8* out=iOut; - TUint8* const end=out+KDeflateMaxDistance; - const TUint32* tree=iEncoding->iLitLen; - if (iLen<0) // EOF - return 0; - if (iLen>0) - goto useHistory; - - while (outHuffmanL(tree)-TEncoding::ELiterals; - if (val<0) - { - *out++=TUint8(val); - continue; - } - if (val==TEncoding::EEos-TEncoding::ELiterals) - { - iLen=-1; - break; - } - - TInt code=val&0xff; - if (code>=8) - { - TInt xtra=(code>>2)-1; - code-=xtra<<2; - code<<=xtra; - code|=iBits->ReadL(xtra); - } - if (valiDistance; - continue; - } - - iRptr=out-(code+1); - if (iRptr+KDeflateMaxDistanceiLitLen; - }; - - return out-iOut; - } - -// --------------------------------------------------------------------------- - -TFileInput::TFileInput(RFile& aFile) - :iFile(aFile),iReadBuf(iBuf1),iPtr(iBuf1,KBufSize) - { - aFile.Read(iPtr,iStat); - } - -// --------------------------------------------------------------------------- - -void TFileInput::Cancel() - { - if (iReadBuf) - User::WaitForRequest(iStat); - } - -// --------------------------------------------------------------------------- - -void TFileInput::UnderflowL() - { - TUint8* b=iReadBuf; - ASSERT(b!=NULL); - User::WaitForRequest(iStat); - iReadBuf=0; - User::LeaveIfError(iStat.Int()); - if(iPtr.Length()==0) - User::Leave(KErrCorrupt); - Set(b,iPtr.Length()*8); - - b = b==iBuf1 ? iBuf2 : iBuf1; - iPtr.Set(b,0,KBufSize); - iFile.Read(iPtr,iStat); - iReadBuf=b; - } - -// --------------------------------------------------------------------------- - -TFileNameInfo::TFileNameInfo() - { - memclr(this, sizeof(TFileNameInfo)); - } - -// --------------------------------------------------------------------------- - -TInt TFileNameInfo::Set(const TDesC8& aFileName, TUint aFlags) - { - iUid = 0; - iVersion = 0; - iPathPos = 0; - iName = aFileName.Ptr(); - iLen = aFileName.Length(); - iExtPos = aFileName.LocateReverse('.'); - if (iExtPos<0) - iExtPos = iLen; - TInt osq = aFileName.LocateReverse('['); - TInt csq = aFileName.LocateReverse(']'); - if (!(aFlags & EAllowUid) && (osq>=0 || csq>=0)) - { - return KErrBadName; - } - if (osq>=iExtPos || csq>=iExtPos) - { - return KErrBadName; - } - TInt p = iExtPos; - if ((aFlags & EAllowUid) && p>=10 && iName[p-1]==']' && iName[p-10]=='[') - { - TPtrC8 uidstr(iName + p - 9, 8); - TLex8 uidlex(uidstr); - TUint32 uid = 0; - TInt r = uidlex.Val(uid, EHex); - if (r==KErrNone && uidlex.Eos()) - iUid = uid, p -= 10; - } - iUidPos = p; - TInt ob = aFileName.LocateReverse('{'); - TInt cb = aFileName.LocateReverse('}'); - if (ob>=iUidPos || cb>=iUidPos) - { - return KErrBadName; - } - if (ob>=0 && cb>=0 && p-1==cb) - { - TPtrC8 p8(iName, p); - TInt d = p8.LocateReverse('.'); - TPtrC8 verstr(iName+ob+1, p-ob-2); - TLex8 verlex(verstr); - if (ob==p-10 && dob && p-1>d && (aFlags & EAllowDecimalVersion)) - { - TUint32 maj = 0; - TUint32 min = 0; - TInt r = verlex.Val(maj, EDecimal); - TUint c = (TUint)verlex.Get(); - TInt r2 = verlex.Val(min, EDecimal); - if (r==KErrNone && c=='.' && r2==KErrNone && verlex.Eos() && maj<32768 && min<32768) - iVersion = (maj << 16) | min, p = ob; - } - } - iVerPos = p; - if (iLen>=2 && iName[1]==':') - { - TUint c = iName[0]; - if (c!='?' || !(aFlags & EAllowPlaceholder)) - { - c |= 0x20; - if (c<'a' || c>'z') - { - return KErrBadName; - } - } - iPathPos = 2; - } - TPtrC8 pathp(iName+iPathPos, iVerPos-iPathPos); - if (pathp.Locate('[')>=0 || pathp.Locate(']')>=0 || pathp.Locate('{')>=0 || pathp.Locate('}')>=0 || pathp.Locate(':')>=0) - { - return KErrBadName; - } - iBasePos = pathp.LocateReverse('\\') + 1 + iPathPos; - - return KErrNone; - } - -// --------------------------------------------------------------------------- - -void TFileNameInfo::GetName(TDes8& aName, TUint aFlags) const - { - if (aFlags & EIncludeDrive) - aName.Append(Drive()); - if (aFlags & EIncludePath) - { - if (PathLen() && iName[iPathPos]!='\\') - aName.Append('\\'); - aName.Append(Path()); - } - if (aFlags & EIncludeBase) - aName.Append(Base()); - if ((aFlags & EForceVer) || ((aFlags & EIncludeVer) && VerLen()) ) - { - aName.Append('{'); - aName.AppendNumFixedWidth(iVersion, EHex, 8); - aName.Append('}'); - } - if ((aFlags & EForceUid) || ((aFlags & EIncludeUid) && UidLen()) ) - { - aName.Append('['); - aName.AppendNumFixedWidth(iUid, EHex, 8); - aName.Append(']'); - } - if (aFlags & EIncludeExt) - aName.Append(Ext()); - } - -// ---------------------------------------------------------------------------