utilityapps/launcher/engine/src/e32image.cpp
changeset 55 2d9cac8919d3
parent 17 4f2773374eff
equal deleted inserted replaced
53:819e59dfc032 55:2d9cac8919d3
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "e32image.h"
       
    21 #include "e32imageheaders.h"
       
    22 #include "launchertraces.h"
       
    23 
       
    24 
       
    25 const TInt KMaxHeaderSize = sizeof(E32ImageHeaderV) + 65536/8;
       
    26 
       
    27 SCapabilitySet AllCapabilities;
       
    28 SCapabilitySet DisabledCapabilities;
       
    29 
       
    30 // ---------------------------------------------------------------------------
       
    31 
       
    32 E32ImageReader* E32ImageReader::NewLC()
       
    33     {
       
    34     E32ImageReader* self = new(ELeave) E32ImageReader;
       
    35     CleanupStack::PushL(self);
       
    36     self->ConstructL();
       
    37     return self;
       
    38     }
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 
       
    42 E32ImageReader::E32ImageReader()
       
    43     {
       
    44     }
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 
       
    48 void E32ImageReader::ConstructL()
       
    49     {
       
    50     LOGSTRING("Launcher: E32ImageReader::ConstructL");
       
    51 
       
    52     iEnv = CEikonEnv::Static();
       
    53     }
       
    54 
       
    55 // ---------------------------------------------------------------------------
       
    56 
       
    57 CDesCArray* E32ImageReader::ListOfDLLsL(const TDesC& aFullPathToE32Image)
       
    58     {
       
    59     LOGSTRING("Launcher: E32ImageReader::ListOfDLLsL");
       
    60 
       
    61     // open the file for reading
       
    62     User::LeaveIfError( iFile.Open(iEnv->FsSession(), aFullPathToE32Image, EFileRead) );
       
    63     CleanupClosePushL(iFile);
       
    64     
       
    65     // get local copies of capability sets
       
    66     TCapabilitySet caps;
       
    67     caps.SetAllSupported();
       
    68     AllCapabilities=*(SCapabilitySet*)∩︀
       
    69     caps.SetDisabled();
       
    70     DisabledCapabilities=*(SCapabilitySet*)∩︀
       
    71 
       
    72     // read the header of the image
       
    73     User::LeaveIfError( E32ImageHeader::New(iHeader, iFile) );
       
    74 
       
    75     // set stuff
       
    76     iHeapSizeMin = iHeader->iHeapSizeMin;
       
    77     iHeapSizeMax = iHeader->iHeapSizeMax;
       
    78     iStackSize = iHeader->iStackSize;
       
    79     iPriority = iHeader->ProcessPriority();
       
    80     iDepCount = iHeader->iDllRefTableCount;
       
    81     iExportDirCount = iHeader->iExportDirCount;
       
    82     iExportDir = iHeader->iExportDirOffset-iHeader->iCodeOffset;
       
    83     iTextSize = iHeader->iTextSize;
       
    84     iCodeSize = iHeader->iCodeSize;
       
    85     iDataSize = iHeader->iDataSize;
       
    86     iBssSize = iHeader->iBssSize;
       
    87     iTotalDataSize = iDataSize+iBssSize;
       
    88     iFileEntryPoint = iHeader->iEntryPoint;
       
    89     iEntryPtVeneer = 0;
       
    90     iExceptionDescriptor = iHeader->ExceptionDescriptor();
       
    91     if (iHeader->iExportDirOffset)
       
    92         iExportDirLoad=iExportDir;
       
    93     
       
    94     // allocate data for the code area
       
    95     iCodeLoadAddress = (TUint32)User::Alloc(iCodeSize);
       
    96     
       
    97     // load data from the binary
       
    98     User::LeaveIfError( LoadData() );
       
    99 
       
   100     // create an array for the dll names from the import list
       
   101     CDesCArray* dllArray = new(ELeave) CDesCArrayFlat(100);
       
   102     CleanupStack::PushL(dllArray);
       
   103 
       
   104     // get the dll names from the import section
       
   105     E32ImportSection* importSection = (E32ImportSection *)iImportData;
       
   106     E32ImportBlock* block;
       
   107     if(importSection)
       
   108         block = (E32ImportBlock*)(importSection+1);
       
   109     else
       
   110         block = NULL;
       
   111     iNextImportPos = 0;
       
   112 
       
   113     // loop through all import data blocks
       
   114     for (TInt i=0; i<iDepCount; i++)
       
   115         {
       
   116         // get a pointer to the dll name
       
   117         TPtrC8 dllname = (const TText8*)((TUint32)iImportData + block->iOffsetOfDllName);
       
   118         TBuf8<KMaxKernelName> rootname;
       
   119         if (dllname.Length() > KMaxKernelName)
       
   120             User::Leave( KErrNotSupported );
       
   121         
       
   122         // parse the filename
       
   123         TFileNameInfo fni;
       
   124         User::LeaveIfError( fni.Set(dllname, TFileNameInfo::EAllowUid) );
       
   125         fni.GetName(rootname, TFileNameInfo::EIncludeBaseExt);
       
   126 
       
   127         // append the name to the dll name array
       
   128         TFileName dllName16;
       
   129         dllName16.Copy(rootname);
       
   130         dllArray->AppendL(dllName16);
       
   131 
       
   132         // get the next block
       
   133         TUint impfmt = iHeader->ImportFormat();
       
   134         block = (E32ImportBlock*)block->NextBlock(impfmt);
       
   135         }
       
   136 
       
   137     CleanupStack::Pop();  //dllArray
       
   138     CleanupStack::PopAndDestroy(); //iFile
       
   139 
       
   140     // free memory
       
   141     delete iHeader;
       
   142     iHeader = NULL;
       
   143     delete iImportSection;
       
   144     iImportSection = NULL;
       
   145     delete iCodeRelocSection;
       
   146     iCodeRelocSection = NULL;
       
   147     delete iDataRelocSection;
       
   148     iDataRelocSection = NULL;
       
   149     
       
   150     User::Free((TAny*)iCodeLoadAddress);
       
   151     User::Free(iRestOfFileData);
       
   152     User::Free(iCurrentImportList);
       
   153     if (iExportDirLoadAllocated)
       
   154         User::Free((TAny*)iExportDirLoad);
       
   155 
       
   156     return dllArray;
       
   157     }
       
   158 
       
   159 // ---------------------------------------------------------------------------
       
   160 
       
   161 E32ImageReader::~E32ImageReader()
       
   162     {
       
   163     LOGSTRING("Launcher: E32ImageReader::~E32ImageReader");
       
   164     }
       
   165 
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 
       
   169 TInt FileRead(RFile& aFile, TUint8* aDest, TInt aSize)
       
   170     {
       
   171     TPtr8 p(aDest,aSize,aSize);
       
   172     return aFile.Read(p,aSize);
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 
       
   177 TInt E32ImageHeader::New(E32ImageHeader*& aHdr, RFile& aFile)
       
   178     {
       
   179     LOGSTRING("Launcher: E32ImageHeader::New");
       
   180 
       
   181     E32ImageHeader* h = NULL;
       
   182     TInt hdrsz = 0;
       
   183     TInt filesize;
       
   184     TInt r = aFile.Size(filesize);
       
   185     if (r!=KErrNone)
       
   186         return r;
       
   187     E32ImageHeader bh;
       
   188     r = FileRead(aFile, (TUint8*)&bh, sizeof(E32ImageHeader));
       
   189     if (r==KErrNone)
       
   190         {
       
   191         hdrsz = bh.TotalSize();
       
   192         if ( (TUint(hdrsz) > TUint(KMaxHeaderSize)) || (TUint(hdrsz) < TUint(sizeof(bh))) )
       
   193             return KErrCorrupt;
       
   194         }
       
   195     h = (E32ImageHeader*)User::Alloc(hdrsz);
       
   196     if (!h)
       
   197         return KErrNoMemory;
       
   198     wordmove(h, &bh, sizeof(E32ImageHeader));
       
   199     if (hdrsz > (TInt)sizeof(E32ImageHeader))
       
   200         r = FileRead(aFile, (TUint8*)(h + 1), hdrsz - sizeof(E32ImageHeader));
       
   201     if (r==KErrNone)
       
   202         r = h->IntegrityCheck(filesize);
       
   203     if (r==KErrNone)
       
   204         {
       
   205         if (h->HeaderFormat() >= KImageHdrFmt_V)
       
   206             {
       
   207             // Overide capabilities in image
       
   208             for(TInt i=0; i<SCapabilitySet::ENCapW; i++)
       
   209                 {
       
   210                 ((E32ImageHeaderV*)h)->iS.iCaps[i] |= DisabledCapabilities[i];
       
   211                 ((E32ImageHeaderV*)h)->iS.iCaps[i] &= AllCapabilities[i];
       
   212                 }
       
   213             }
       
   214         aHdr = h;
       
   215         }
       
   216     else
       
   217         {
       
   218         delete h;
       
   219         aHdr = NULL;
       
   220         }
       
   221     return r;
       
   222     }
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 
       
   226 TInt E32ImageHeader::IntegrityCheck(TInt aFileSize)
       
   227     {
       
   228     LOGSTRING("Launcher: E32ImageHeader::IntegrityCheck");
       
   229     
       
   230     TInt hdrsz = TotalSize();
       
   231     TUint hdrfmt = HeaderFormat();
       
   232     TUidType uids = *(const TUidType*)&iUid1;
       
   233     E32ImageHeaderV* v = NULL;
       
   234     TCheckedUid chkuid(uids);
       
   235     const TUint32* pChkUid = (const TUint32*)&chkuid;
       
   236 
       
   237     if (pChkUid[3] != iUidChecksum)
       
   238         return KErrCorrupt;    
       
   239 
       
   240     if (hdrfmt == KImageHdrFmt_V)
       
   241         {
       
   242         TUint32 supplied_crc = iHeaderCrc;
       
   243         iHeaderCrc = KImageCrcInitialiser;
       
   244         TUint32 crc = 0;
       
   245         Mem::Crc32(crc, this, hdrsz);
       
   246         iHeaderCrc = supplied_crc;
       
   247         if (crc != supplied_crc)
       
   248             return KErrCorrupt;    
       
   249         v = (E32ImageHeaderV*)this;
       
   250         TUint total_eds = v->iExportDescSize + sizeof(v->iExportDescSize) + sizeof(v->iExportDescType);
       
   251         total_eds = (total_eds + 3) &~ 3;
       
   252         if (total_eds + (TUint)_FOFF(E32ImageHeaderV, iExportDescSize) != (TUint)hdrsz)
       
   253             return KErrCorrupt;
       
   254         if (TUint(v->iExportDescType) > KImageHdr_ExpD_SparseBitmap8)
       
   255             return KErrNotSupported;
       
   256         }
       
   257     else if (hdrfmt >= KImageHdrFmt_V)
       
   258         return KErrNotSupported; 
       
   259 
       
   260     TCpu cpu = CpuIdentifier();
       
   261     TUint abi = ABI();
       
   262     TUint impfmt = ImportFormat();
       
   263     TUint compression = CompressionType();
       
   264 
       
   265     TUint uncompressed_size = compression ? UncompressedFileSize() : (TUint)aFileSize;
       
   266 
       
   267     if (iSignature != 0x434f5045) // 'EPOC'
       
   268         return KErrCorrupt;
       
   269     if (iCodeSize<0)
       
   270         return KErrCorrupt;
       
   271     if (iDataSize<0)
       
   272         return KErrCorrupt;
       
   273     if (iHeapSizeMin<0)
       
   274         return KErrCorrupt;
       
   275     if (iHeapSizeMax<iHeapSizeMin)
       
   276         return KErrCorrupt;
       
   277     if (iStackSize<0)
       
   278         return KErrCorrupt;
       
   279     if (iBssSize<0)
       
   280         return KErrCorrupt;
       
   281     if (iDllRefTableCount<0)
       
   282         return KErrCorrupt;
       
   283     if (iExportDirOffset >= uncompressed_size)
       
   284         return KErrCorrupt;
       
   285     if (TUint(iExportDirCount)>65535)
       
   286         return KErrCorrupt;
       
   287     if (iTextSize<0)
       
   288         return KErrCorrupt;
       
   289     if (iCodeSize<iTextSize)
       
   290         return KErrCorrupt;
       
   291     if (iCodeOffset >= uncompressed_size)
       
   292         return KErrCorrupt;
       
   293     if (iDataOffset >= uncompressed_size)
       
   294         return KErrCorrupt;
       
   295     if (iImportOffset >= uncompressed_size)
       
   296         return KErrCorrupt;
       
   297     if (iCodeRelocOffset >= uncompressed_size)
       
   298         return KErrCorrupt;
       
   299     if (iDataRelocOffset >= uncompressed_size)
       
   300         return KErrCorrupt;
       
   301     if (TUint(iCodeSize+iDataSize) > uncompressed_size)
       
   302         return KErrCorrupt;
       
   303 
       
   304     if (abi>KImageABI_EABI)
       
   305         return KErrNotSupported;
       
   306     if (impfmt>KImageImpFmt_PE2)
       
   307         return KErrNotSupported;
       
   308     if (iUid1 != (TUint32)KExecutableImageUidValue && iUid1 != (TUint32)KDynamicLibraryUidValue)
       
   309         return KErrNotSupported;
       
   310     TUint32 mv = ModuleVersion();
       
   311     if (mv >= 0x80000000u || (mv & 0x0000ffffu) > 0x8000u)
       
   312         return KErrNotSupported;
       
   313 
       
   314     return KErrNone;
       
   315     }
       
   316 // ---------------------------------------------------------------------------
       
   317 
       
   318 TInt E32ImageReader::LoadData()
       
   319     {
       
   320     LOGSTRING("Launcher: E32ImageReader::LoadData");
       
   321 
       
   322     TInt remainder;
       
   323     iFile.Size(remainder);
       
   324     
       
   325     remainder -= iHeader->TotalSize();
       
   326     TUint32 compression = iHeader->CompressionType();
       
   327     if (compression != KMyFormatNotCompressed)
       
   328         {
       
   329         remainder = iHeader->UncompressedFileSize() - iHeader->iCodeOffset;
       
   330         }
       
   331 
       
   332     remainder -= iHeader->iCodeSize;
       
   333     
       
   334     if (remainder > 0)
       
   335         {
       
   336         iRestOfFileData = (TUint8*)User::Alloc(remainder);
       
   337         if (iRestOfFileData)
       
   338             iRestOfFileSize=remainder;
       
   339         else
       
   340             return KErrNoMemory;
       
   341         }
       
   342 
       
   343     iConversionOffset = iHeader->iCodeOffset + iHeader->iCodeSize;
       
   344 
       
   345     TInt r = LoadFile(compression);
       
   346     if (r !=KErrNone)
       
   347         return r;
       
   348 
       
   349 
       
   350     TUint8* source=NULL;
       
   351     if (iHeader->iImportOffset)
       
   352         {
       
   353         TUint bufferOffset=iHeader->iImportOffset-iConversionOffset;
       
   354         
       
   355         if(bufferOffset>iRestOfFileSize || bufferOffset+sizeof(E32ImportSection)>iRestOfFileSize)
       
   356             return KErrCorrupt;
       
   357         
       
   358         source=iRestOfFileData+bufferOffset;
       
   359         
       
   360         iImportSection = new E32ImportSection;
       
   361         
       
   362         if (iImportSection)
       
   363             Mem::Move((TText8*)iImportSection, source, sizeof(E32ImportSection));
       
   364         else
       
   365             return KErrNoMemory;
       
   366         }
       
   367 
       
   368     iCodeDelta = iCodeRunAddress-iHeader->iCodeBase;
       
   369     iDataDelta = iDataRunAddress-iHeader->iDataBase;
       
   370 
       
   371     if (r==KErrNone)
       
   372         r = ReadImportData();
       
   373 
       
   374     return r;
       
   375     }
       
   376 
       
   377 // ---------------------------------------------------------------------------
       
   378 
       
   379 TUint8* E32ImageReader::MemoryMove(TAny* aDestination, const TAny* aSource, TInt aNumberofBytes)
       
   380     {
       
   381     return Mem::Move(aDestination, aSource, aNumberofBytes);
       
   382     }
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 
       
   386 GLDEF_C TInt svRelocateExports(TAny* aPtr)
       
   387     {
       
   388     E32ImageReader* pI=(E32ImageReader*)aPtr;
       
   389     TUint32* destExport=(TUint32*)pI->iExportDirLoad;
       
   390     TInt i=pI->iExportDirCount;
       
   391     TUint32 codeBase=pI->iCodeRunAddress;
       
   392     while (i-->0)
       
   393         *destExport+++=codeBase;
       
   394     return 0;
       
   395     }
       
   396 
       
   397 // ---------------------------------------------------------------------------
       
   398 
       
   399 TInt E32ImageReader::LoadFile(TUint32 aCompression)
       
   400     {
       
   401     LOGSTRING("Launcher: E32ImageReader::LoadFile");
       
   402 
       
   403     TInt r(KErrNone);
       
   404 
       
   405     if (aCompression == KMyFormatNotCompressed)
       
   406         r=LoadFileNoCompress();
       
   407     
       
   408     else if (aCompression == KMyUidCompressionDeflate)
       
   409         {
       
   410         TRAP(r, LoadFileInflateL());
       
   411         }
       
   412     
       
   413     else
       
   414         r = KErrNotSupported;
       
   415     
       
   416     return r;
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 
       
   421 TInt E32ImageReader::LoadFileNoCompress()
       
   422     {
       
   423     LOGSTRING("Launcher: E32ImageReader::LoadFileNoCompress");
       
   424 
       
   425     TInt r(KErrNone);
       
   426 
       
   427     if (iHeader->iCodeSize)
       
   428         {
       
   429         r = Read(iHeader->iCodeOffset, (TText8*)iCodeLoadAddress, iCodeSize);
       
   430         }
       
   431 
       
   432     if (r != KErrNone)
       
   433         {
       
   434         return r;
       
   435         }
       
   436 
       
   437     if (iRestOfFileSize)
       
   438         {
       
   439         r = Read(iConversionOffset, (TText8*)iRestOfFileData, iRestOfFileSize);
       
   440         }
       
   441     
       
   442     return r;
       
   443     }
       
   444 
       
   445 // ---------------------------------------------------------------------------
       
   446 
       
   447 void FileCleanup(TAny* aPtr)
       
   448     {
       
   449     TFileInput* f=(TFileInput*)aPtr;
       
   450     f->Cancel();
       
   451     delete f;
       
   452     }
       
   453 
       
   454 // ---------------------------------------------------------------------------
       
   455 
       
   456 void E32ImageReader::LoadFileInflateL()
       
   457     {
       
   458     LOGSTRING("Launcher: E32ImageReader::LoadFileInflateL");
       
   459 
       
   460     TInt pos = iHeader->TotalSize();
       
   461     User::LeaveIfError(iFile.Seek(ESeekStart,pos));
       
   462 
       
   463     TFileInput* file = new (ELeave) TFileInput(iFile);
       
   464     CleanupStack::PushL(TCleanupItem(&FileCleanup,file));
       
   465     CInflater* inflater = CInflater::NewLC(*file);
       
   466     
       
   467     if (iHeader->iCodeSize)
       
   468         {
       
   469         TInt count = inflater->ReadL((TUint8*)iCodeLoadAddress, iCodeSize, &MemoryMove);
       
   470         
       
   471         if(count!=iCodeSize)
       
   472             User::Leave(KErrCorrupt);
       
   473         }
       
   474 
       
   475     if (iRestOfFileSize)
       
   476         {
       
   477         TUint32 count = inflater->ReadL(iRestOfFileData, iRestOfFileSize, &Mem::Move);
       
   478         
       
   479         if(count!=iRestOfFileSize)
       
   480             User::Leave(KErrCorrupt);
       
   481         }
       
   482     
       
   483     CleanupStack::PopAndDestroy(2,file);
       
   484     }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 
       
   488 TInt E32ImageReader::Read(TText8* aDest, TInt aSize)
       
   489     {
       
   490     TPtr8 p(aDest,aSize,aSize);
       
   491     return iFile.Read(p,aSize);
       
   492     }
       
   493 
       
   494 // ---------------------------------------------------------------------------
       
   495 
       
   496 TInt E32ImageReader::Read(TInt aPos, TText8* aDest, TInt aSize)
       
   497     {
       
   498     TPtr8 p(aDest,aSize,aSize);
       
   499     if (aPos<0)
       
   500         return KErrCorrupt;
       
   501     return iFile.Read(aPos,p,aSize);
       
   502     }
       
   503 
       
   504 // ---------------------------------------------------------------------------
       
   505 
       
   506 TInt E32ImageReader::ReadImportData()
       
   507     {
       
   508     LOGSTRING("Launcher: E32ImageReader::ReadImportData");
       
   509 
       
   510     if (!iHeader->iImportOffset)
       
   511         return KErrNone;
       
   512     
       
   513     TUint32 bufferOffset = iHeader->iImportOffset-iConversionOffset;
       
   514     
       
   515     if(bufferOffset>iRestOfFileSize || bufferOffset+iImportSection->iSize>iRestOfFileSize)
       
   516         return KErrCorrupt;
       
   517     
       
   518     iImportData = (TUint32*)(iRestOfFileData+bufferOffset);
       
   519     
       
   520     E32ImportSection* s = (E32ImportSection*)iImportData;
       
   521     E32ImportBlock* b = (E32ImportBlock*)(s + 1);
       
   522     TUint impfmt = iHeader->ImportFormat();
       
   523     TInt i;
       
   524     TInt n = 0;
       
   525     
       
   526     for (i=0; i<iDepCount; ++i)
       
   527         {
       
   528         if (b->iNumberOfImports > n)
       
   529             n = b->iNumberOfImports;
       
   530         b = (E32ImportBlock*)b->NextBlock(impfmt);
       
   531         }
       
   532     
       
   533     iCurrentImportList = (TUint32*)User::Alloc(n * sizeof(TUint32));
       
   534     
       
   535     if (!iCurrentImportList)
       
   536         return KErrNoMemory;
       
   537     
       
   538     return KErrNone;
       
   539     }
       
   540 
       
   541 // ---------------------------------------------------------------------------
       
   542 
       
   543 inline CInflater::CInflater(TBitInput& aInput)
       
   544     :iBits(&aInput),iEncoding(0),iOut(0)
       
   545     {}
       
   546 
       
   547 // ---------------------------------------------------------------------------
       
   548 
       
   549 void CInflater::ConstructL()
       
   550     {
       
   551     iEncoding=new(ELeave) TEncoding;
       
   552     InitL();
       
   553     iLen=0;
       
   554     iOut=new(ELeave) TUint8[KDeflateMaxDistance];
       
   555     iAvail=iLimit=iOut;
       
   556     }
       
   557 
       
   558 // ---------------------------------------------------------------------------
       
   559 
       
   560 CInflater* CInflater::NewLC(TBitInput& aInput)
       
   561     {
       
   562     CInflater* self=new(ELeave) CInflater(aInput);
       
   563     CleanupStack::PushL(self);
       
   564     self->ConstructL();
       
   565     return self;
       
   566     }
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 
       
   570 CInflater::~CInflater()
       
   571     {
       
   572     delete iEncoding;
       
   573     delete [] iOut;
       
   574     }
       
   575 
       
   576 // ---------------------------------------------------------------------------
       
   577 
       
   578 TInt CInflater::ReadL(TUint8* aBuffer,TInt aLength, TMemoryMoveFunction aMemMovefn)
       
   579     {
       
   580     TInt tfr=0;
       
   581     for (;;)
       
   582         {
       
   583         TInt len=Min(aLength,iLimit-iAvail);
       
   584         if (len && aBuffer)
       
   585             {
       
   586             aMemMovefn(aBuffer,iAvail,len);
       
   587             aBuffer+=len;
       
   588             }
       
   589         aLength-=len;
       
   590         iAvail+=len;
       
   591         tfr+=len;
       
   592         if (aLength==0)
       
   593             return tfr;
       
   594         len=InflateL();
       
   595         if (len==0)
       
   596             return tfr;
       
   597         iAvail=iOut;
       
   598         iLimit=iAvail+len;
       
   599         }
       
   600     }
       
   601 
       
   602 // ---------------------------------------------------------------------------
       
   603 
       
   604 TInt CInflater::SkipL(TInt aLength)
       
   605     {
       
   606     return ReadL(0,aLength,Mem::Move);
       
   607     }
       
   608 
       
   609 // ---------------------------------------------------------------------------
       
   610 
       
   611 void CInflater::InitL()
       
   612     {
       
   613     Huffman::InternalizeL(*iBits,iEncoding->iLitLen,KDeflationCodes);
       
   614 
       
   615     if (!Huffman::IsValid(iEncoding->iLitLen,TEncoding::ELitLens) ||
       
   616         !Huffman::IsValid(iEncoding->iDistance,TEncoding::EDistances))
       
   617         User::Leave(KErrCorrupt);
       
   618 
       
   619     Huffman::Decoding(iEncoding->iLitLen,TEncoding::ELitLens,iEncoding->iLitLen);
       
   620     Huffman::Decoding(iEncoding->iDistance,TEncoding::EDistances,iEncoding->iDistance,KDeflateDistCodeBase);
       
   621     }
       
   622 
       
   623 // ---------------------------------------------------------------------------
       
   624 
       
   625 TInt CInflater::InflateL()
       
   626     {
       
   627     TUint8* out=iOut;
       
   628     TUint8* const end=out+KDeflateMaxDistance;
       
   629     const TUint32* tree=iEncoding->iLitLen;
       
   630     if (iLen<0)    // EOF
       
   631         return 0;
       
   632     if (iLen>0)
       
   633         goto useHistory;
       
   634 
       
   635     while (out<end)
       
   636         {
       
   637         // get a huffman code
       
   638         {
       
   639         TInt val=iBits->HuffmanL(tree)-TEncoding::ELiterals;
       
   640         if (val<0)
       
   641             {
       
   642             *out++=TUint8(val);
       
   643             continue;        
       
   644             }
       
   645         if (val==TEncoding::EEos-TEncoding::ELiterals)
       
   646             {    
       
   647             iLen=-1;
       
   648             break;
       
   649             }
       
   650         
       
   651         TInt code=val&0xff;
       
   652         if (code>=8)
       
   653             {    
       
   654             TInt xtra=(code>>2)-1;
       
   655             code-=xtra<<2;
       
   656             code<<=xtra;
       
   657             code|=iBits->ReadL(xtra);
       
   658             }
       
   659         if (val<KDeflateDistCodeBase-TEncoding::ELiterals)
       
   660             {
       
   661             iLen=code+KDeflateMinLength;
       
   662             tree=iEncoding->iDistance;
       
   663             continue;        
       
   664             }
       
   665         
       
   666         iRptr=out-(code+1);
       
   667         if (iRptr+KDeflateMaxDistance<end)
       
   668             iRptr+=KDeflateMaxDistance;
       
   669         }
       
   670 useHistory:
       
   671         TInt tfr=Min(end-out,iLen);
       
   672         iLen-=tfr;
       
   673         const TUint8* from=iRptr;
       
   674         do
       
   675             {
       
   676             *out++=*from++;
       
   677             if (from==end)
       
   678                 from-=KDeflateMaxDistance;
       
   679             } while (--tfr!=0);
       
   680         iRptr=from;
       
   681         tree=iEncoding->iLitLen;
       
   682         };
       
   683     
       
   684     return out-iOut;
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------------------------
       
   688 
       
   689 TFileInput::TFileInput(RFile& aFile)
       
   690     :iFile(aFile),iReadBuf(iBuf1),iPtr(iBuf1,KBufSize)
       
   691     {
       
   692     aFile.Read(iPtr,iStat);
       
   693     }
       
   694 
       
   695 // ---------------------------------------------------------------------------
       
   696 
       
   697 void TFileInput::Cancel()
       
   698     {
       
   699     if (iReadBuf)
       
   700         User::WaitForRequest(iStat);
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------------------------
       
   704 
       
   705 void TFileInput::UnderflowL()
       
   706     {
       
   707     TUint8* b=iReadBuf;
       
   708     ASSERT(b!=NULL);
       
   709     User::WaitForRequest(iStat);
       
   710     iReadBuf=0;
       
   711     User::LeaveIfError(iStat.Int());
       
   712     if(iPtr.Length()==0)
       
   713         User::Leave(KErrCorrupt);
       
   714     Set(b,iPtr.Length()*8);
       
   715     
       
   716     b = b==iBuf1 ? iBuf2 : iBuf1;
       
   717     iPtr.Set(b,0,KBufSize);
       
   718     iFile.Read(iPtr,iStat);
       
   719     iReadBuf=b;
       
   720     }
       
   721 
       
   722 // ---------------------------------------------------------------------------
       
   723 
       
   724 TFileNameInfo::TFileNameInfo()
       
   725     {
       
   726     memclr(this, sizeof(TFileNameInfo));
       
   727     }
       
   728 
       
   729 // ---------------------------------------------------------------------------
       
   730 
       
   731 TInt TFileNameInfo::Set(const TDesC8& aFileName, TUint aFlags)
       
   732     {
       
   733     iUid = 0;
       
   734     iVersion = 0;
       
   735     iPathPos = 0;
       
   736     iName = aFileName.Ptr();
       
   737     iLen = aFileName.Length();
       
   738     iExtPos = aFileName.LocateReverse('.');
       
   739     if (iExtPos<0)
       
   740         iExtPos = iLen;
       
   741     TInt osq = aFileName.LocateReverse('[');
       
   742     TInt csq = aFileName.LocateReverse(']');
       
   743     if (!(aFlags & EAllowUid) && (osq>=0 || csq>=0))
       
   744         {
       
   745         return KErrBadName;
       
   746         }
       
   747     if (osq>=iExtPos || csq>=iExtPos)
       
   748         {
       
   749         return KErrBadName;
       
   750         }
       
   751     TInt p = iExtPos;
       
   752     if ((aFlags & EAllowUid) && p>=10 && iName[p-1]==']' && iName[p-10]=='[')
       
   753         {
       
   754         TPtrC8 uidstr(iName + p - 9, 8);
       
   755         TLex8 uidlex(uidstr);
       
   756         TUint32 uid = 0;
       
   757         TInt r = uidlex.Val(uid, EHex);
       
   758         if (r==KErrNone && uidlex.Eos())
       
   759             iUid = uid, p -= 10;
       
   760         }
       
   761     iUidPos = p;
       
   762     TInt ob = aFileName.LocateReverse('{');
       
   763     TInt cb = aFileName.LocateReverse('}');
       
   764     if (ob>=iUidPos || cb>=iUidPos)
       
   765         {
       
   766         return KErrBadName;
       
   767         }
       
   768     if (ob>=0 && cb>=0 && p-1==cb)
       
   769         {
       
   770         TPtrC8 p8(iName, p);
       
   771         TInt d = p8.LocateReverse('.');
       
   772         TPtrC8 verstr(iName+ob+1, p-ob-2);
       
   773         TLex8 verlex(verstr);
       
   774         if (ob==p-10 && d<ob)
       
   775             {
       
   776             TUint32 ver = 0;
       
   777             TInt r = verlex.Val(ver, EHex);
       
   778             if (r==KErrNone && verlex.Eos())
       
   779                 iVersion = ver, p = ob;
       
   780             }
       
   781         else if (d>ob && p-1>d && (aFlags & EAllowDecimalVersion))
       
   782             {
       
   783             TUint32 maj = 0;
       
   784             TUint32 min = 0;
       
   785             TInt r = verlex.Val(maj, EDecimal);
       
   786             TUint c = (TUint)verlex.Get();
       
   787             TInt r2 = verlex.Val(min, EDecimal);
       
   788             if (r==KErrNone && c=='.' && r2==KErrNone && verlex.Eos() && maj<32768 && min<32768)
       
   789                 iVersion = (maj << 16) | min, p = ob;
       
   790             }
       
   791         }
       
   792     iVerPos = p;
       
   793     if (iLen>=2 && iName[1]==':')
       
   794         {
       
   795         TUint c = iName[0];
       
   796         if (c!='?' || !(aFlags & EAllowPlaceholder))
       
   797             {
       
   798             c |= 0x20;
       
   799             if (c<'a' || c>'z')
       
   800                 {
       
   801                 return KErrBadName;
       
   802                 }
       
   803             }
       
   804         iPathPos = 2;
       
   805         }
       
   806     TPtrC8 pathp(iName+iPathPos, iVerPos-iPathPos);
       
   807     if (pathp.Locate('[')>=0 || pathp.Locate(']')>=0 || pathp.Locate('{')>=0 || pathp.Locate('}')>=0 || pathp.Locate(':')>=0)
       
   808         {
       
   809         return KErrBadName;
       
   810         }
       
   811     iBasePos = pathp.LocateReverse('\\') + 1 + iPathPos;
       
   812 
       
   813     return KErrNone;
       
   814     }
       
   815 
       
   816 // ---------------------------------------------------------------------------
       
   817 
       
   818 void TFileNameInfo::GetName(TDes8& aName, TUint aFlags) const
       
   819     {
       
   820     if (aFlags & EIncludeDrive)
       
   821         aName.Append(Drive());
       
   822     if (aFlags & EIncludePath)
       
   823         {
       
   824         if (PathLen() && iName[iPathPos]!='\\')
       
   825             aName.Append('\\');
       
   826         aName.Append(Path());
       
   827         }
       
   828     if (aFlags & EIncludeBase)
       
   829         aName.Append(Base());
       
   830     if ((aFlags & EForceVer) || ((aFlags & EIncludeVer) && VerLen()) )
       
   831         {
       
   832         aName.Append('{');
       
   833         aName.AppendNumFixedWidth(iVersion, EHex, 8);
       
   834         aName.Append('}');        
       
   835         }
       
   836     if ((aFlags & EForceUid) || ((aFlags & EIncludeUid) && UidLen()) )
       
   837         {
       
   838         aName.Append('[');
       
   839         aName.AppendNumFixedWidth(iUid, EHex, 8);
       
   840         aName.Append(']');
       
   841         }
       
   842     if (aFlags & EIncludeExt)
       
   843         aName.Append(Ext());
       
   844     }
       
   845 
       
   846 // ---------------------------------------------------------------------------