diff -r 000000000000 -r a41df078684a kerneltest/f32test/manager/t_romg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/manager/t_romg.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,577 @@ +// Copyright (c) 1995-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: +// f32test\manager\t_romg.cpp +// +// + +#include +#include +#include +#include "..\server\t_server.h" + +const TInt KBufSize=0x10000; +const TInt KFillerSize=0x100; +const TInt KRomFileHeaderSize=0x100; +const TInt KRomFileHeaderNameSize=0x10; + +class TRomFileHeaderBase + { +public: + TText8 iName[KRomFileHeaderNameSize]; + TText8 iVersionStr[4]; + TText8 iBuildNumStr[4]; + TInt iRomSize; + TInt iHeaderSize; + }; + +class TRomFileHeader : public TRomFileHeaderBase + { +public: + TUint8 iFiller[KRomFileHeaderSize-sizeof(TRomFileHeaderBase)]; + }; + +class CMemDir; +class CMemEntry : public CBase + { +public: + static CMemEntry* New(const TEntry& anEntry); + ~CMemEntry(); + TInt EntrySize(); + void Write(); + void WriteFile(); + inline TBool IsDir() {return(iEntry.iAtt&KEntryAttDir);} + inline CMemDir& Dir() {return(*iDir);} + inline void SetDir(CMemDir& aDir) {iDir=(&aDir);} + inline TInt Size() {return(iSize);} + inline TLinAddr Base() {return(iBase);} + inline void SetBase(); + inline const TDesC& Name() {return(*iName);} + inline static TInt LinkOffset() {return(_FOFF(CMemEntry,iLink));} +protected: + CMemEntry(const TEntry& anEntry); +private: + TLinAddr iBase; + TInt iSize; + TRomEntry iEntry; + HBufC* iName; + CMemDir* iDir; + TDblQueLink iLink; + }; + +class CMemDir : public CBase + { +public: + static CMemDir* NewL(); + ~CMemDir(); + void LoadDirL(const TDesC& aPath); + void SetBaseDirs(); + void SetBaseFiles(); + void WriteDirs(); + void WriteFiles(); + void Write(); + TFileName Name(const TDesC& aName); + inline TLinAddr Base() {return(iBase);} +protected: + CMemDir(); +private: + TInt iSize; + TInt iCount; + TLinAddr iBase; + HBufC* iPath; + TDblQue iEntryQ; + }; + +class RFileX : public RFile + { +public: + RFileX() : RFile() {} + TInt Write(const TDesC8& aDes); + TInt Write(const TDesC8& aDes,TInt aLength); + }; + +GLDEF_D RTest test(_L("T_ROMG")); +LOCAL_D RFileX TheFile; +LOCAL_D TRomHeader TheRomHeader; +LOCAL_D TLinAddr TheCurrentBase; +LOCAL_D CMemDir* TheRootDir; +LOCAL_D TInt TheLevel; +LOCAL_D TBuf8 TheBuf; +LOCAL_D TBuf8 TheFiller; +#if defined(_UNICODE) +LOCAL_D const TPtrC TheFileName=_L("ROMFILEU.BIN"); +#else +LOCAL_D const TPtrC TheFileName=_L("ROMFILE.BIN"); +#endif + +TInt RFileX::Write(const TDesC8& aDes) +// +// Write and update the file pos +// + { + + TheCurrentBase+=aDes.Size(); + return(RFile::Write(aDes)); + } + +TInt RFileX::Write(const TDesC8& aDes,TInt aLength) +// +// Write and update the file pos +// + { + + TheCurrentBase+=aLength; + return(RFile::Write(aDes,aLength)); + } + +CMemEntry* CMemEntry::New(const TEntry& anEntry) +// +// Create a new entry. +// + { + + CMemEntry* pE=new(ELeave) CMemEntry(anEntry); + pE->iName=anEntry.iName.Alloc(); + test(pE->iName!=NULL); + return(pE); + } + +#pragma warning( disable : 4705 ) // statement has no effect +CMemEntry::CMemEntry(const TEntry& anEntry) +// +// Constructor. +// + { + + iEntry.iAtt=(TUint8)(anEntry.iAtt|KEntryAttReadOnly); // All rom files are read only + iEntry.iSize=anEntry.iSize; + iEntry.iNameLength=(TUint8)anEntry.iName.Size(); + iSize=Align4(anEntry.iSize); + __DECLARE_NAME(_S("CMemEntry")); + } +#pragma warning( default : 4705 ) + +CMemEntry::~CMemEntry() +// +// Destruct. +// + { + + if (iLink.iNext!=NULL) + iLink.Deque(); + delete iName; + if (IsDir()) + delete iDir; + } + +void CMemEntry::SetBase() +// +// Set the entries base address. +// + { + + iBase=TheCurrentBase; + iEntry.iAddressLin=TheCurrentBase; + } + +TInt CMemEntry::EntrySize() +// +// Calculate the entries size. +// + { + + return(Align4(KRomEntrySize+iEntry.iNameLength)); + } + +void CMemEntry::Write() +// +// Write the current entry. +// + { + + test(TheFile.Write(TPtrC8((TUint8*)&iEntry,KRomEntrySize))==KErrNone); + test(TheFile.Write(TPtrC8((TUint8*)iName->Ptr(),iName->Size()))==KErrNone); + TInt rem=EntrySize()-iName->Size()-KRomEntrySize; + if (rem) + test(TheFile.Write(TheFiller,rem)==KErrNone); + } + +void CMemEntry::WriteFile() +// +// Write the current entries file. +// + { + + test(iBase==TheCurrentBase); + TAutoClose f; + TFileName n=Dir().Name(*iName); + test(f.iObj.Open(TheFs,n,EFileStream|EFileRead)==KErrNone); + TInt size=0; + do + { + test(f.iObj.Read(TheBuf)==KErrNone); + test(TheFile.Write(TheBuf)==KErrNone); + size+=TheBuf.Length(); + } while (TheBuf.Length()==TheBuf.MaxLength()); + test(iEntry.iSize==size); + TInt rem=iSize-size; + if (rem) + test(TheFile.Write(TheFiller,rem)==KErrNone); + } + +CMemDir* CMemDir::NewL() +// +// Create a new directory. +// + { + + return(new(ELeave) CMemDir); + } + +CMemDir::CMemDir() +// +// Constructor. +// + : iEntryQ(CMemEntry::LinkOffset()) + { + + __DECLARE_NAME(_S("CMemDir")); + } + +CMemDir::~CMemDir() +// +// Destruct. +// + { + + while (!iEntryQ.IsEmpty()) + { + CMemEntry* pE=iEntryQ.First(); + delete pE; + } + delete iPath; + } + +void CMemDir::SetBaseDirs() +// +// Set the base address of the directory and any sub-directories. +// + { + + iBase=TheCurrentBase; + iSize=sizeof(TInt); + TDblQueIter q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + { + iCount++; + iSize+=pE->EntrySize(); + } + TheCurrentBase+=iSize; + q.SetToFirst(); + while ((pE=q++)!=NULL) + { + if (pE->IsDir()) + { + pE->SetBase(); + pE->Dir().SetBaseDirs(); + } + } + } + +void CMemDir::SetBaseFiles() +// +// Set the base address of each file. +// + { + + TDblQueIter q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + { + if (!pE->IsDir()) + { + pE->SetBase(); + TheCurrentBase+=pE->Size(); + } + } + q.SetToFirst(); + while ((pE=q++)!=NULL) + { + if (pE->IsDir()) + pE->Dir().SetBaseFiles(); + } + } + +void CMemDir::WriteDirs() +// +// Write the directory and any sub-directories. +// + { + + TheLevel++; + TFileName name=Name(_L("")); + test.Printf(_L("%*p%S\n"),TheLevel<<1,&name); + Write(); + TDblQueIter q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + { + if (pE->IsDir()) + pE->Dir().WriteDirs(); + } + TheLevel--; + } + +void CMemDir::WriteFiles() +// +// Set the base address of each file. +// + { + + TheLevel++; + TFileName name=Name(_L("")); + test.Printf(_L("%*p%S\n"),TheLevel<<1,&name); + TDblQueIter q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + { + if (!pE->IsDir()) + { + test.Printf(_L("%*p%S\n"),(TheLevel<<1)+2,&pE->Name()), + pE->WriteFile(); + } + } + q.SetToFirst(); + while ((pE=q++)!=NULL) + { + if (pE->IsDir()) + pE->Dir().WriteFiles(); + } + TheLevel--; + } + +void CMemDir::Write() +// +// Write the current directory. +// + { + + test(iBase==TheCurrentBase); + TInt size=iSize-sizeof(TInt); + test(TheFile.Write(TPtrC8((TUint8*)&size,sizeof(TInt)))==KErrNone); + TDblQueIter q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + pE->Write(); + TInt sz=(TheCurrentBase-iBase); + test(sz==iSize); + } + +TFileName CMemDir::Name(const TDesC& aName) +// +// Make a full path name from aName. +// + { + + TFileName n(*iPath); + n+=_L("\\"); + n+=aName; + return(n); + } + +void CMemDir::LoadDirL(const TDesC& aPath) +// +// Load a directory. +// + { + + TheLevel++; + iPath=aPath.AllocL(); + TFileName name=Name(_L("*.*")); + test.Printf(_L("%*p%S\n"),TheLevel<<1,&name); + CDir* pD; + test(TheFs.GetDir(Name(_L("*.*")),KEntryAttMatchMask,EDirsFirst|ESortByName,pD)==KErrNone); + TInt count=pD->Count(); + TInt i=0; + while (i q(iEntryQ); + CMemEntry* pE; + while ((pE=q++)!=NULL) + { + if (pE->IsDir()) + { + CMemDir* pM=CMemDir::NewL(); + pE->SetDir(*pM); + pM->LoadDirL(Name(pE->Name())); + } + else + pE->SetDir(*this); + } + TheLevel--; + } + +LOCAL_C void buildRomImageL() +// +// Build the ROM image. +// + { + + test.Start(_L("Parse command line")); + HBufC* buf=HBufC::New(RProcess().CommandLineLength()); + test(buf!=NULL); + TPtr cmd = buf->Des(); + RProcess().CommandLine(cmd); + TLex lex(*buf); + TFileName n=lex.NextToken(); + if (n.Length()==0) + n=_L("\\F32"); + test(n.Length()!=0); + if (n.Right(1)==_L("\\")) + n.SetLength(n.Length()-1); +// + test.Next(_L("Create root mem dir")); + TRAPD(r,TheRootDir=CMemDir::NewL()); + test(r==KErrNone); +// + test.Next(_L("Load directory structure")); + TheLevel=(-1); + TRAP(r,TheRootDir->LoadDirL(n)); + test(r==KErrNone); + test(TheLevel==(-1)); +// + delete buf; + test.End(); + } + +LOCAL_C void baseRomImage() +// +// Set base addresses for the ROM image. +// + { + + test.Start(_L("Setting up the header")); + Mem::FillZ(&TheRomHeader,sizeof(TRomHeader)); + test.Printf(_L("1")); + TheRomHeader.iVersion=TVersion(1,0,1); + test.Printf(_L("2")); + TTime t; + t.HomeTime(); + test.Printf(_L("3")); + TheRomHeader.iTime=t.Int64(); + test.Printf(_L("4")); + TheRomHeader.iRomBase=UserSvr::RomHeaderAddress(); + test.Printf(_L("5")); + TheRomHeader.iRomRootDirectoryList=TheCurrentBase=UserSvr::RomHeaderAddress()+sizeof(TRomHeader); + test.Printf(_L("6")); +// + test.Next(_L("Set dirs base")); + TheRootDir->SetBaseDirs(); +// + test.Next(_L("Set files base")); + TheRootDir->SetBaseFiles(); + TheRomHeader.iRomSize=TheCurrentBase-UserSvr::RomHeaderAddress(); +// + test.End(); + } + +LOCAL_C void writeRomImage() +// +// Write the ROM image. +// + { + + test.Start(_L("Write rom file header")); +// + TPckgBuf fileHeadB; + fileHeadB.FillZ(fileHeadB.MaxLength()); + TRomFileHeader& fileHead=fileHeadB(); + Mem::Copy(&fileHead.iName[0],"EPOC468 ROM ",KRomFileHeaderNameSize); + Mem::Copy(&fileHead.iVersionStr[0],"0.01",4); + Mem::Copy(&fileHead.iBuildNumStr[0]," 1",4); + fileHead.iRomSize=TheRomHeader.iRomSize; + fileHead.iHeaderSize=KRomFileHeaderSize; + test(TheFile.Write(fileHeadB)==KErrNone); +// + test.Next(_L("Write rom header")); + TheFiller.FillZ(TheFiller.MaxLength()); + TPckgC head(TheRomHeader); + test(TheFile.Write(head)==KErrNone); + TheCurrentBase=UserSvr::RomHeaderAddress()+sizeof(TheRomHeader); +// + test.Next(_L("Write directories")); + TheLevel=(-1); + TheRootDir->WriteDirs(); + test(TheLevel==(-1)); +// + test.Next(_L("Write files")); + TheLevel=(-1); + TheRootDir->WriteFiles(); + test(TheLevel==(-1)); +// + test.End(); + } + +GLDEF_C void CallTestsL(void) +// +// Test the file server. +// + { + test.Title(); + +#if defined(__WINS__) + test.Printf(_L("Running on WINS. Skipping ROM test")); + return; +#endif +// + test.Start(_L("Testing rom")); + + TInt r=TheFs.Delete(TheFileName); + if (r==KErrAccessDenied) + { + test.Printf(_L("Error: Cannot access %S"),&TheFileName); + test.End(); + return; + } + test(r==KErrNone || r==KErrNotFound); +// + test.Next(_L("Generating ROM image")); + TRAP(r,buildRomImageL()); + test(r==KErrNone); +// + test.Next(_L("Basing the rom image")); + baseRomImage(); +// + TBuf<0x80> b=_L("Writing ROM file "); + b+=TheFileName; + test.Next(b); + r=TheFile.Replace(TheFs,TheFileName,EFileStream|EFileWrite); + test(r==KErrNone); + writeRomImage(); + TheFile.Close(); + delete TheRootDir; + + test.End(); + return; + } +