diff -r 000000000000 -r a41df078684a kerneltest/e32test/dll/t_xxver2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dll/t_xxver2.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,775 @@ +// Copyright (c) 2003-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: +// e32test\dll\t_xxver2.cpp +// Overview: +// Test matching algorithm for DLL versions. Test aspects of DLL and EXE files. +// API Information: +// RLibrary +// Details: +// - This test makes use of 4 versions of a single DLL, and 15 EXEs which link +// against it. The EXEs all have different reqirements on which DLL versions +// are acceptable +// - Test that the correct version of linked libraries are used (Run for each +// EXE and for the 16 combinations in which the 4 versions of the DLL can be +// available. The test is performed with each EXE run in sequence, and again +// with all of them run at the same time) +// - Test that the correct version of dynamically loaded libraries are used and +// the libary exports are as expected. (Run for each DLL version and for the +// 16 combinations of DLL availability) +// - Test that RLibrary::GetInfo and RLibrary::GetInfoFromHeader return the +// expected data for all DLLs and EXEs +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include +#include +#include +#include +#include + +RTest test(_L("T_XXVER2")); +RFs gFs; +CFileMan* gFileMan; +RLdrTest LdrTest; + +TBuf<8> SourcePath = _S16("Z:\\img\\"); + + +TFileName KDestPath() + { + _LIT(KDestPath, "C:\\system\\bin\\ver"); + _LIT(KDestPathSysBin, "C:\\sys\\bin\\ver"); + if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + return KDestPathSysBin(); + else + return KDestPath(); + } + +_LIT(KDllName0, "t_ver2{00010000}.dll"); +_LIT(KDllName1, "t_ver2{00010001}.dll"); +_LIT(KDllName2, "t_ver2{00020000}.dll"); +_LIT(KDllName3, "t_ver2.dll"); + +const TDesC* const DllArray[] = + { + &KDllName0(), + &KDllName1(), + &KDllName2(), + &KDllName3() + }; + +const TInt KNumDlls = sizeof(DllArray)/sizeof(const TDesC* const); + +const TInt DllVersion[KNumDlls] = + { + 0x00010000, + 0x00010001, + 0x00020000, + 0x00030000 + }; + +const TInt KNumTestVersions = 7; +const TInt TestDllVersion[KNumTestVersions] = + { + 0x00000000, + 0x00010000, + 0x00010001, + 0x00010002, + 0x00020000, + 0x00030000, + 0x00040000 + }; + +_LIT(KExeName0, "t_xver2a.exe"); // request 1.0 work with any +_LIT(KExeName1, "t_xver2b.exe"); // request 1.0 work with 2.0 but not 3.0 +_LIT(KExeName2, "t_xver2c.exe"); // request 1.0 don't work with 2.0 +_LIT(KExeName3, "t_xver2d.exe"); // request 1.1 work with 1.0 but not 2.0 +_LIT(KExeName4, "t_xver2e.exe"); // request 1.1 work with any +_LIT(KExeName5, "t_xver2f.exe"); // request 1.1 work with 2.0, 3.0 but not with 1.0 +_LIT(KExeName6, "t_xver2g.exe"); // request 1.1 don't work with 2.0, 3.0 or 1.0 +_LIT(KExeName7, "t_xver2h.exe"); // request 1.1 work with 1.0 and 2.0 but not 3.0 +_LIT(KExeName8, "t_xver2i.exe"); // request 1.1 work with 2.0 but not 3.0 or 1.0 +_LIT(KExeName9, "t_xver2j.exe"); // request 2.0 only use 1.0 exports +_LIT(KExeName10, "t_xver2k.exe"); // request 2.0 only use 1.0, 1.1 exports +_LIT(KExeName11, "t_xver2l.exe"); // request 2.0 use 2.0 exports work on 3.0 +_LIT(KExeName12, "t_xver2m.exe"); // request 2.0 use 2.0 exports, don't work on 3.0 +_LIT(KExeName13, "t_xver2n.exe"); // request 3.0 use 1.0 exports only +_LIT(KExeName14, "t_xver2o.exe"); // request 3.0 use all + +const TDesC* const ExeArray[] = + { + &KExeName0(), + &KExeName1(), + &KExeName2(), + &KExeName3(), + &KExeName4(), + &KExeName5(), + &KExeName6(), + &KExeName7(), + &KExeName8(), + &KExeName9(), + &KExeName10(), + &KExeName11(), + &KExeName12(), + &KExeName13(), + &KExeName14() + }; + +const TInt KNumExes = sizeof(ExeArray)/sizeof(const TDesC* const); + +const TInt ResultArray[KNumExes<iTotal; + TInt nh = e->iHoles; + TInt ord; + for (ord=1; ord<=n+1; ++ord) + { + TLibraryFunction f = aLib.Lookup(ord); + test.Printf(_L("Ord %3d->%08x\n"), ord, f); + if (ord>n) + { + test(!f); + continue; + } + TInt i; + for (i=0; iiHole[i]!=ord; ++i) {} + if (i%d\n"), &fn, r); + test(r==KErrNone || r==KErrAlreadyExists); + TFileName fn2 = fn; + fn2.Append(_L("*.*")); + TTime now; + now.HomeTime(); + r = gFileMan->Attribs(fn2, 0, KEntryAttReadOnly|KEntryAttHidden|KEntryAttSystem|KEntryAttArchive, now); + test.Printf(_L("Attribs %S->%d\n"), &fn2, r); + r = gFileMan->Delete(fn2); + test.Printf(_L("Delete %S->%d\n"), &fn2, r); + TInt n = 0; + for (; aMask; aMask>>=1, ++n) + { + if (!(aMask & 1)) + continue; + fn2 = fn; + fn2.Append(*DllArray[n]); + TFileName src = SourcePath; + src.Append(*DllArray[n]); + r = gFileMan->Copy(src, fn2); + test.Printf(_L("%S->%S (%d)\n"), &src, &fn2, r); + test(r == KErrNone); + } + for (n=0; nCopy(src, fn2); + test.Printf(_L("%S->%S (%d)\n"), &src, &fn2, r); + test(r == KErrNone); + } + } + +void RunExe(TUint aMask, TInt aExeNum) + { + test.Printf(_L("RunExe mask %d exenum %d\n"), aMask, aExeNum); + RProcess p; + TRequestStatus s; + TFileName fn = KDestPath(); + fn.AppendNumFixedWidth(aMask, EDecimal, 2); + fn.Append('\\'); + fn.Append(*ExeArray[aExeNum]); + TInt r = p.Create(fn, KNullDesC); + test.Printf(_L("Create %S->%d\n"), &fn, r); + TInt rix = aExeNum + KNumExes*TInt(aMask); + TInt expected = ResultArray[rix]; + test.Printf(_L("RunExe expected %d\n"), expected); + if (expected<0) + { + test(r<0); + return; + } + p.Logon(s); + p.Resume(); + User::WaitForRequest(s); + if (p.ExitType()!=EExitKill) + { + TInt et = p.ExitType(); + TInt er = p.ExitReason(); + const TDesC& ec = p.ExitCategory(); + test.Printf(_L("Exit %d,%d,%S\n"), et, er, &ec); + test(0); + } + CLOSE_AND_WAIT(p); + test.Printf(_L("Return code %08x\n"), s.Int()); + test(s.Int() == DllVersion[expected]); + } + +void RunExes(TUint aMask) + { + test.Printf(_L("RunExes mask %d\n"), aMask); + RProcess p[KNumExes]; + TRequestStatus s[KNumExes]; + TInt xn; + for (xn=0; xn%d\n"), &fn, r); + TInt rix = xn + KNumExes*TInt(aMask); + TInt expected = ResultArray[rix]; + test.Printf(_L("RunExe expected %d\n"), expected); + if (expected<0) + { + test(r<0); + continue; + } + p[xn].Logon(s[xn]); + } + for (xn=0; xn infoBuf(info); + TInt r; + if(formHeader) + { + TUint8* buf; + + RFs fs; + test(fs.Connect()==KErrNone); + RFile file; + test((r=file.Open(fs,fn,0))==KErrNone); + TInt size; + test((r=file.Size(size))==KErrNone); + if(size>RLibrary::KRequiredImageHeaderSize) + size=RLibrary::KRequiredImageHeaderSize; + buf=new TUint8[size]; + test(buf!=0); + TPtr8 header(buf,size); + test((r=file.Read(header))==KErrNone); + file.Close(); + fs.Close(); + + r = RLibrary::GetInfoFromHeader(header, infoBuf); + test.Printf(_L("GetInfoFromHeader returns %d\n"), r); + + delete buf; + } + else + { + r = RLibrary::GetInfo(fn, infoBuf); + test.Printf(_L("GetInfo returns %d\n"), r); + } + + test(r==KErrNone); + const TUint32* uid = (const TUint32*)&info.iUids; + test.Printf(_L("VER %08x\n"), info.iModuleVersion); + test.Printf(_L("UID1 %08x\n"), uid[0]); + test.Printf(_L("UID2 %08x\n"), uid[1]); + test.Printf(_L("UID3 %08x\n"), uid[2]); + test.Printf(_L("SID %08x\n"), (TUint32)info.iSecurityInfo.iSecureId); + test.Printf(_L("VID %08x\n"), (TUint32)info.iSecurityInfo.iVendorId); + test.Printf(_L("CAP0 %08x\n"), ((SSecurityInfo&)info.iSecurityInfo).iCaps[0]); + test.Printf(_L("CAP1 %08x\n"), ((SSecurityInfo&)info.iSecurityInfo).iCaps[1]); + TUint32 v = (TUint32)DllVersion[aN]; + test(info.iModuleVersion == v); + test(uid[0] == (TUint32)KDynamicLibraryUidValue); + test(uid[2] == (TUint32)0x40abcdef); + TUint32 xsid = ((v>>16)<<4)|(v&0x0f)|0x89abcd00u; + test(info.iSecurityInfo.iSecureId == xsid); + TUint32 xvid = 0x01234500+(xsid&0xff); + test(info.iSecurityInfo.iVendorId == xvid); + test(((SSecurityInfo&)info.iSecurityInfo).iCaps[0]==0x0002aaab); + test(((SSecurityInfo&)info.iSecurityInfo).iCaps[1]==0); + if(formHeader) +#if defined(__ARMCC__) + test(info.iHardwareFloatingPoint == EFpTypeVFPv2); +#else + test(info.iHardwareFloatingPoint == EFpTypeNone); +#endif + + if(formHeader) + break; + formHeader = ETrue; + } + } + +void TestExeInfo(TInt aN) + { + TFileName fn; + if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + fn = _S16("C:\\sys\\bin\\ver15\\"); + else + fn = _S16("C:\\system\\bin\\ver15\\"); + fn += *ExeArray[aN]; + test.Printf(_L("Getting info for %S\n"), &fn); + TBool formHeader=EFalse; + for(;;) + { + RLibrary::TInfoV2 info; + TPckg infoBuf(info); + TInt r; + if(formHeader) + { + TUint8* buf; + + RFs fs; + test(fs.Connect()==KErrNone); + RFile file; + test((r=file.Open(fs,fn,0))==KErrNone); + TInt size; + test((r=file.Size(size))==KErrNone); + if(size>RLibrary::KRequiredImageHeaderSize) + size=RLibrary::KRequiredImageHeaderSize; + buf=new TUint8[size]; + test(buf!=0); + TPtr8 header(buf,size); + test((r=file.Read(header))==KErrNone); + file.Close(); + fs.Close(); + + r = RLibrary::GetInfoFromHeader(header, infoBuf); + test.Printf(_L("GetInfoFromHeader returns %d\n"), r); + + delete buf; + } + else + { + r = RLibrary::GetInfo(fn, infoBuf); + test.Printf(_L("GetInfo returns %d\n"), r); + } + + test(r==KErrNone); + const TUint32* uid = (const TUint32*)&info.iUids; + test.Printf(_L("VER %08x\n"), info.iModuleVersion); + test.Printf(_L("UID1 %08x\n"), uid[0]); + test.Printf(_L("UID2 %08x\n"), uid[1]); + test.Printf(_L("UID3 %08x\n"), uid[2]); + test.Printf(_L("SID %08x\n"), (TUint32)info.iSecurityInfo.iSecureId); + test.Printf(_L("VID %08x\n"), (TUint32)info.iSecurityInfo.iVendorId); + test.Printf(_L("CAP0 %08x\n"), ((SSecurityInfo&)info.iSecurityInfo).iCaps[0]); + test.Printf(_L("CAP1 %08x\n"), ((SSecurityInfo&)info.iSecurityInfo).iCaps[1]); + #if defined(__EABI__) && !defined(__X86__) + test(info.iModuleVersion == 0x000a0000); + #else + test(info.iModuleVersion == 0x00010000); + #endif + test(uid[0] == (TUint32)KExecutableImageUidValue); + TUint32 xuid3 = 0x40abcd61u + aN; + test(uid[2] == xuid3); + test(info.iSecurityInfo.iSecureId == xuid3); + TUint32 xvid = 0x01234500+(xuid3&0xff); + test(info.iSecurityInfo.iVendorId == xvid); + test(((SSecurityInfo&)info.iSecurityInfo).iCaps[0]==0x0002aaab); + test(((SSecurityInfo&)info.iSecurityInfo).iCaps[1]==0); + if(formHeader) + test(info.iHardwareFloatingPoint == EFpTypeNone); + + if(formHeader) + break; + formHeader = ETrue; + } + } + +void TestCompression(void) + { + + // Check target directory + TFileName fn; + if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + fn = _S16("c:\\sys\\bin\\"); + else + fn = _S16("c:\\system\\bin\\"); + + TInt r = gFs.MkDirAll(fn); + test.Printf(_L("MkDir %S->%d\n"), &fn, r); + test(r==KErrNone || r==KErrAlreadyExists); + + // Make copy from t_xxver2.exe to t_xxvercomp.exe + fn.Append(_L("t_xxvercomp.exe")); + + TFileName fn2 = fn; + TTime now; + now.HomeTime(); + r = gFileMan->Attribs(fn2, 0, KEntryAttReadOnly|KEntryAttHidden|KEntryAttSystem|KEntryAttArchive, now); + test.Printf(_L("Attribs %S->%d\n"), &fn2, r); + r = gFileMan->Delete(fn2); + test.Printf(_L("Delete %S->%d\n"), &fn2, r); + + fn2 = fn; + TFileName src = SourcePath; + src.Append(*ExeArray[0]); + r = gFileMan->Copy(src, fn2); + test.Printf(_L("%S->%S (%d)\n"), &src, &fn2, r); + test(r == KErrNone); + + + // Check RLibrary::GetInfoFromHeader on a correct executable + test.Printf(_L("fn:%S\n"), &fn); + + RLibrary::TInfoV2 info; + TPckg infoBuf(info); + + TUint8* buf; + + RFs fs; + test(fs.Connect()==KErrNone); + RFile file; + r=file.Open(fs,fn,0); + test.Printf(_L("file.Open returns %d\n"), r); + test(r==KErrNone); + TInt size; + test((r=file.Size(size))==KErrNone); + if(size>RLibrary::KRequiredImageHeaderSize) + size=RLibrary::KRequiredImageHeaderSize; + buf=new TUint8[size]; + test(buf!=0); + TPtr8 header(buf,size); + test((r=file.Read(header))==KErrNone); + file.Close(); + + + r = RLibrary::GetInfoFromHeader(header, infoBuf); + test.Printf(_L("GetInfoFromHeader returns %d\n"), r); + test(r==KErrNone); + + + test.Printf(_L("Write invalid compression info into the header.\n")); + E32ImageHeader* e32Header = (E32ImageHeader*) buf; + + e32Header->iCompressionType = 0x00000001; + test((r=file.Open(fs,fn,EFileWrite))==KErrNone); + r=file.Write(header); + test.Printf(_L("file.Write returns %d\n"), r); + test(r==KErrNone); + file.Close(); + + // Check RLibrary::GetInfoFromHeader on a wrong compression method. + + r = RLibrary::GetInfoFromHeader(header, infoBuf); + test.Printf(_L("GetInfoFromHeader returns %d\n"), r); + test(r==KErrCorrupt); + + + fs.Close(); + delete buf; + + + + } // End of TestCompression() + +TInt E32Main() + { + test.Title(); + + // Turn off evil lazy dll unloading + RLoader l; + test(l.Connect()==KErrNone); + test(l.CancelLazyDllUnload()==KErrNone); + l.Close(); + + TBuf<256> cmdline; + User::CommandLine(cmdline); + TLex lex(cmdline); + TInt options[8]; + TInt i; + memclr(options, sizeof(options)); + for (i=0; i<8; ++i) + { + lex.SkipSpace(); + if (lex.Eos()) + break; + lex.Val(options[i]); + } + TUint tm = 0xffffffffu; + if (options[0]) + tm = (TUint)options[0]; + + test.Start(_L("Create cleanup stack")); + CTrapCleanup* ct = CTrapCleanup::New(); + test(ct!=0); + test.Next(_L("Connect to file server")); + TInt r = gFs.Connect(); + test(r==KErrNone); + test.Next(_L("Create CFileMan")); + TRAP(r, gFileMan=CFileMan::NewL(gFs)); + test(r==KErrNone); + test.Next(_L("Connect to test driver")); + r = User::LoadLogicalDevice(_L("d_ldrtst")); + test(r==KErrNone || r==KErrAlreadyExists); + r = LdrTest.Open(); + test(r==KErrNone); + TFileName fn(RProcess().FileName()); + test.Printf(_L("Process file name = %S\n"), &fn); + SourcePath[0] = fn[0]; // use same drive as this EXE + + TUint mask; + TUint nmasks = 1u << KNumDlls; + for (mask=0; mask