os/kernelhwsrv/kerneltest/f32test/loader/security/exet.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32test\loader\exet.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#define __INCLUDE_DEPENDENCY_GRAPH
sl@0
    19
sl@0
    20
#include <e32svr.h>
sl@0
    21
#include "dllt.h"
sl@0
    22
#include "exetifc.h"
sl@0
    23
#include "dlltree.h"
sl@0
    24
#include <d_ldrtst.h>
sl@0
    25
sl@0
    26
#ifdef __VC32__
sl@0
    27
#pragma warning(disable:4706)
sl@0
    28
#endif
sl@0
    29
sl@0
    30
const TInt KMaxHandlesPerDll=4;
sl@0
    31
const TInt KMaxHandles=KMaxHandlesPerDll*KNumModules;
sl@0
    32
sl@0
    33
extern "C" TInt _E32Startup();
sl@0
    34
sl@0
    35
extern "C" IMPORT_C void RegisterConstructorCall(TInt aDllNum);
sl@0
    36
extern "C" IMPORT_C void RegisterInitCall(TInt aDllNum);
sl@0
    37
extern "C" IMPORT_C void RegisterDestructorCall(TInt aDllNum);
sl@0
    38
sl@0
    39
#define PANIC()		ExeTPanic(__LINE__)
sl@0
    40
#define EXET_ASSERT(c)	((void)((c)||(PANIC(),0)))
sl@0
    41
sl@0
    42
void ExeTPanic(TInt aLine)
sl@0
    43
	{
sl@0
    44
	User::Panic(_L("EXET"),aLine);
sl@0
    45
	}
sl@0
    46
sl@0
    47
/******************************************************************************
sl@0
    48
 * Class Definitions
sl@0
    49
 ******************************************************************************/
sl@0
    50
class CDllInfo;
sl@0
    51
class TDllList : public MDllList
sl@0
    52
	{
sl@0
    53
public:
sl@0
    54
	TDllList();
sl@0
    55
	virtual TBool IsPresent(const SDllInfo& aInfo);
sl@0
    56
	virtual TInt Add(const SDllInfo& aInfo);
sl@0
    57
	virtual void MoveToEnd(TInt aPos);
sl@0
    58
public:
sl@0
    59
	TInt iCount;
sl@0
    60
	SDllInfo iInfo[KNumModules];
sl@0
    61
	};
sl@0
    62
sl@0
    63
class CTestServer : public CServer2
sl@0
    64
	{
sl@0
    65
public:
sl@0
    66
	CTestServer();
sl@0
    67
	virtual ~CTestServer();
sl@0
    68
	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
sl@0
    69
	virtual TInt RunError(TInt aError);
sl@0
    70
public:
sl@0
    71
	CDllInfo* iInfo;
sl@0
    72
	};
sl@0
    73
sl@0
    74
class CTestSession : public CSession2
sl@0
    75
	{
sl@0
    76
public:
sl@0
    77
	virtual ~CTestSession();
sl@0
    78
	virtual void CreateL();
sl@0
    79
	virtual void ServiceL(const RMessage2& aMessage);
sl@0
    80
public:
sl@0
    81
	TInt GetExeDepList(const RMessage2& aMessage);
sl@0
    82
	TInt GetCDList(const RMessage2& aMessage);
sl@0
    83
	TInt LoadDll(const RMessage2& aMessage);
sl@0
    84
	TInt CloseDll(TInt aHandle);
sl@0
    85
	TInt CallBlkI(TInt aHandle, TInt aIn);
sl@0
    86
	TInt CallRBlkI(TInt aHandle, TInt aIn);
sl@0
    87
public:
sl@0
    88
	CDllInfo* iInfo;
sl@0
    89
	};
sl@0
    90
sl@0
    91
class CDllInfo : public CBase
sl@0
    92
	{
sl@0
    93
public:
sl@0
    94
	CDllInfo();
sl@0
    95
	virtual ~CDllInfo();
sl@0
    96
	TInt Create();
sl@0
    97
	TInt StoreHandle(TInt aHandle);
sl@0
    98
	void RemoveHandle(TInt aIndex);
sl@0
    99
	void SetupCDList();
sl@0
   100
public:
sl@0
   101
	void RegisterConstructorCall(TInt aDllNum);
sl@0
   102
	void RegisterInitCall(TInt aDllNum);
sl@0
   103
	void RegisterDestructorCall(TInt aDllNum);
sl@0
   104
public:
sl@0
   105
	TInt iNextGen;
sl@0
   106
	TInt iHandleCount;
sl@0
   107
	TInt iNextHandle;
sl@0
   108
	TInt iHandles[KMaxHandles];
sl@0
   109
	TInt iModuleNum[KMaxHandles];
sl@0
   110
	TDllList iExeDepList;
sl@0
   111
	TDllList iDllConstructList;
sl@0
   112
	};
sl@0
   113
sl@0
   114
/******************************************************************************
sl@0
   115
 * Static data
sl@0
   116
 ******************************************************************************/
sl@0
   117
#ifdef __MODULE_HAS_DATA
sl@0
   118
class TExeData
sl@0
   119
	{
sl@0
   120
public:
sl@0
   121
	TExeData();
sl@0
   122
public:
sl@0
   123
	TTime iStartTime;
sl@0
   124
	TTime iInitTime;
sl@0
   125
	TInt iTest1;
sl@0
   126
	TFileName iFileName;
sl@0
   127
	};
sl@0
   128
sl@0
   129
TInt Bss[16];
sl@0
   130
TInt ExeNum=EXENUM;
sl@0
   131
TInt Generation=0;
sl@0
   132
TInt InitFlag=0;
sl@0
   133
TFullName StartThread=RThread().FullName();
sl@0
   134
TName StartProcess=RProcess().Name();
sl@0
   135
TExeData TheExeDataObject;
sl@0
   136
sl@0
   137
TExeData::TExeData()
sl@0
   138
	:	iFileName(RProcess().FileName())
sl@0
   139
	{
sl@0
   140
	TInt r;
sl@0
   141
	CHKDEPS(r);		// Check our dependencies are initialised
sl@0
   142
	if (r!=KErrNone)
sl@0
   143
		User::Panic(_L("CHKDEPS"),r);
sl@0
   144
	iStartTime.HomeTime();
sl@0
   145
	iTest1=299792458;
sl@0
   146
	RegisterConstructorCall(EXENUM);
sl@0
   147
	}
sl@0
   148
#endif
sl@0
   149
sl@0
   150
/******************************************************************************
sl@0
   151
 * Class TDllList
sl@0
   152
 ******************************************************************************/
sl@0
   153
TDllList::TDllList()
sl@0
   154
	{
sl@0
   155
	iCount=0;
sl@0
   156
	Mem::Fill(iInfo, KNumModules*sizeof(SDllInfo), 0xff);
sl@0
   157
	}
sl@0
   158
sl@0
   159
TBool TDllList::IsPresent(const SDllInfo& aInfo)
sl@0
   160
	{
sl@0
   161
	TInt i;
sl@0
   162
	for (i=0; i<iCount; ++i)
sl@0
   163
		{
sl@0
   164
		if (iInfo[i].iDllNum==aInfo.iDllNum)
sl@0
   165
			return ETrue;
sl@0
   166
		}
sl@0
   167
	return EFalse;
sl@0
   168
	}
sl@0
   169
sl@0
   170
TInt TDllList::Add(const SDllInfo& aInfo)
sl@0
   171
	{
sl@0
   172
	EXET_ASSERT(iCount<KNumModules);
sl@0
   173
	TInt pos=iCount;
sl@0
   174
	iInfo[iCount++]=aInfo;
sl@0
   175
	return pos;
sl@0
   176
	}
sl@0
   177
sl@0
   178
void TDllList::MoveToEnd(TInt aPos)
sl@0
   179
	{
sl@0
   180
	if (aPos<iCount-1)
sl@0
   181
		{
sl@0
   182
		SDllInfo x(iInfo[aPos]);
sl@0
   183
		Mem::Move(iInfo+aPos, iInfo+aPos+1, (iCount-aPos-1)*sizeof(SDllInfo));
sl@0
   184
		iInfo[iCount-1]=x;
sl@0
   185
		}
sl@0
   186
	}
sl@0
   187
sl@0
   188
/******************************************************************************
sl@0
   189
 * Class CTestSession/CTestServer
sl@0
   190
 ******************************************************************************/
sl@0
   191
void ExceptionHandler(TExcType)
sl@0
   192
	{
sl@0
   193
	User::Leave(KErrGeneral);
sl@0
   194
	}
sl@0
   195
sl@0
   196
TUint32 Read(TLinAddr a)
sl@0
   197
	{
sl@0
   198
	return *(volatile TUint32*)a;
sl@0
   199
	}
sl@0
   200
sl@0
   201
TInt CheckReadable(TLinAddr a)
sl@0
   202
	{
sl@0
   203
	User::SetExceptionHandler(ExceptionHandler,KExceptionFault);
sl@0
   204
	TRAPD(r,Read(a));
sl@0
   205
	User::SetExceptionHandler(ExceptionHandler,0);
sl@0
   206
	return r;
sl@0
   207
	}
sl@0
   208
sl@0
   209
CTestSession::~CTestSession()
sl@0
   210
	{
sl@0
   211
	}
sl@0
   212
sl@0
   213
void CTestSession::CreateL()
sl@0
   214
	{
sl@0
   215
//	CSession2::CreateL();
sl@0
   216
	}
sl@0
   217
sl@0
   218
void CTestSession::ServiceL(const RMessage2& aMessage)
sl@0
   219
	{
sl@0
   220
	TInt r=KErrNotSupported;
sl@0
   221
	TInt mid=aMessage.Function();
sl@0
   222
	switch(mid)
sl@0
   223
		{
sl@0
   224
		case RLoaderTest::EMsgGetExeDepList:
sl@0
   225
			r=GetExeDepList(aMessage);
sl@0
   226
			break;
sl@0
   227
		case RLoaderTest::EMsgLoadDll:
sl@0
   228
			r=LoadDll(aMessage);
sl@0
   229
			break;
sl@0
   230
		case RLoaderTest::EMsgCallBlkI:
sl@0
   231
			r=CallBlkI(aMessage.Int0(), aMessage.Int1());
sl@0
   232
			break;
sl@0
   233
		case RLoaderTest::EMsgCallRBlkI:
sl@0
   234
			r=CallRBlkI(aMessage.Int0(), aMessage.Int1());
sl@0
   235
			break;
sl@0
   236
		case RLoaderTest::EMsgCloseDll:
sl@0
   237
			r=CloseDll(aMessage.Int0());
sl@0
   238
			break;
sl@0
   239
		case RLoaderTest::EMsgGetCDList:
sl@0
   240
			r=GetCDList(aMessage);
sl@0
   241
			break;
sl@0
   242
		case RLoaderTest::EMsgCheckReadable:
sl@0
   243
			r=CheckReadable((TLinAddr)aMessage.Int0());
sl@0
   244
			break;
sl@0
   245
		case RLoaderTest::EMsgExit:
sl@0
   246
			r=KErrNone;
sl@0
   247
			CActiveScheduler::Stop();
sl@0
   248
			break;
sl@0
   249
		default:
sl@0
   250
			break;
sl@0
   251
		}
sl@0
   252
	aMessage.Complete(r);
sl@0
   253
	}
sl@0
   254
sl@0
   255
TInt CTestSession::GetExeDepList(const RMessage2& aMsg)
sl@0
   256
	{
sl@0
   257
	TPtrC8 dep_list_ptr((const TUint8*)&iInfo->iExeDepList.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   258
	aMsg.WriteL(0, dep_list_ptr, 0);
sl@0
   259
	return KErrNone;
sl@0
   260
	}
sl@0
   261
sl@0
   262
TInt CTestSession::GetCDList(const RMessage2& aMsg)
sl@0
   263
	{
sl@0
   264
	TPtrC8 list_ptr((const TUint8*)&iInfo->iDllConstructList.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   265
	aMsg.WriteL(0, list_ptr, 0);
sl@0
   266
	return KErrNone;
sl@0
   267
	}
sl@0
   268
sl@0
   269
TInt CTestSession::LoadDll(const RMessage2& aMsg)
sl@0
   270
	{
sl@0
   271
	TInt module=aMsg.Int0();
sl@0
   272
	TDllList dll_list;
sl@0
   273
	TPtrC8 dll_list_ptr((const TUint8*)dll_list.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   274
	TPtrC dllname=MODULE_FILENAME(module);
sl@0
   275
	iInfo->SetupCDList();
sl@0
   276
	RLibrary l;
sl@0
   277
	TInt r=l.Load(dllname, TUidType());
sl@0
   278
	if (r!=KErrNone)
sl@0
   279
		return r;
sl@0
   280
	TInitFunction f=(TInitFunction)l.Lookup(INIT_ORDINAL);
sl@0
   281
	EXET_ASSERT(f);
sl@0
   282
	r=(*f)(dll_list);
sl@0
   283
	if (r!=KErrNone)
sl@0
   284
		return r;
sl@0
   285
	TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
sl@0
   286
	EXET_ASSERT(bf);
sl@0
   287
	TInt result=(*bf)(531441);
sl@0
   288
	EXET_ASSERT(result==BlkIValue(module, 531441));
sl@0
   289
	TInt h=iInfo->StoreHandle(l.Handle());
sl@0
   290
	EXET_ASSERT(h>=0);
sl@0
   291
	iInfo->iModuleNum[h]=module;
sl@0
   292
	aMsg.WriteL(1, dll_list_ptr, 0);
sl@0
   293
	return h;
sl@0
   294
	}
sl@0
   295
sl@0
   296
TInt CTestSession::CallBlkI(TInt aHandle, TInt aIn)
sl@0
   297
	{
sl@0
   298
	TInt h=iInfo->iHandles[aHandle];
sl@0
   299
	EXET_ASSERT(h!=0);
sl@0
   300
	RLibrary l;
sl@0
   301
	l.SetHandle(h);
sl@0
   302
	TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
sl@0
   303
	EXET_ASSERT(bf);
sl@0
   304
	return (*bf)(aIn);
sl@0
   305
	}
sl@0
   306
sl@0
   307
TInt CTestSession::CallRBlkI(TInt aHandle, TInt aIn)
sl@0
   308
	{
sl@0
   309
	TInt h=iInfo->iHandles[aHandle];
sl@0
   310
	EXET_ASSERT(h!=0);
sl@0
   311
	RLibrary l;
sl@0
   312
	l.SetHandle(h);
sl@0
   313
	TRBlkIFunction rbf=(TRBlkIFunction)l.Lookup(REC_BLOCK_INC_ORDINAL);
sl@0
   314
	EXET_ASSERT(rbf);
sl@0
   315
	++iInfo->iNextGen;
sl@0
   316
	return (*rbf)(aIn,iInfo->iNextGen);
sl@0
   317
	}
sl@0
   318
sl@0
   319
TInt CTestSession::CloseDll(TInt aHandle)
sl@0
   320
	{
sl@0
   321
	TInt h=iInfo->iHandles[aHandle];
sl@0
   322
	TInt m=iInfo->iModuleNum[aHandle];
sl@0
   323
	EXET_ASSERT(h!=0);
sl@0
   324
	EXET_ASSERT(m>=0);
sl@0
   325
	iInfo->iHandles[aHandle]=0;
sl@0
   326
	iInfo->iModuleNum[aHandle]=-1;
sl@0
   327
	iInfo->SetupCDList();
sl@0
   328
	RLibrary l;
sl@0
   329
	l.SetHandle(h);
sl@0
   330
	l.Close();
sl@0
   331
	return KErrNone;
sl@0
   332
	}
sl@0
   333
sl@0
   334
CTestServer::CTestServer()
sl@0
   335
	: CServer2(0,ESharableSessions)
sl@0
   336
	{
sl@0
   337
	}
sl@0
   338
sl@0
   339
CTestServer::~CTestServer()
sl@0
   340
	{
sl@0
   341
	}
sl@0
   342
sl@0
   343
CSession2* CTestServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
sl@0
   344
	{
sl@0
   345
	(void)aVersion;
sl@0
   346
	CTestSession* s = new (ELeave) CTestSession;
sl@0
   347
	s->iInfo=iInfo;
sl@0
   348
	return s;
sl@0
   349
	}
sl@0
   350
sl@0
   351
_LIT(KExetErr,"EXETERR");
sl@0
   352
TInt CTestServer::RunError(TInt aError)
sl@0
   353
	{
sl@0
   354
	User::Panic(KExetErr,aError);
sl@0
   355
	return 0;
sl@0
   356
	}
sl@0
   357
sl@0
   358
/******************************************************************************
sl@0
   359
 * Class CDllInfo
sl@0
   360
 ******************************************************************************/
sl@0
   361
TInt ChkC()
sl@0
   362
	{
sl@0
   363
#ifdef __MODULE_HAS_DATA
sl@0
   364
	TInt init_mark=~((EXENUM+DLLNUMOFFSET)*(EXENUM+DLLNUMOFFSET));
sl@0
   365
	if (InitFlag==init_mark)
sl@0
   366
		return KErrNone;
sl@0
   367
	if (InitFlag!=0)
sl@0
   368
		return 0x494e4946;
sl@0
   369
	TInt i;
sl@0
   370
	TInt x=0;
sl@0
   371
	for (i=0; i<16; ++i) x|=Bss[i];
sl@0
   372
	if (x)
sl@0
   373
		return 0x425353;
sl@0
   374
	if (ExeNum!=EXENUM)
sl@0
   375
		return 0x44415441;
sl@0
   376
	if (Generation!=0)
sl@0
   377
		return 0x47454e;
sl@0
   378
	if (StartProcess!=RProcess().Name())
sl@0
   379
		return 0x535450;
sl@0
   380
	if (TheExeDataObject.iTest1!=299792458)
sl@0
   381
		return 0x54455354;
sl@0
   382
	if (TheExeDataObject.iFileName != RProcess().FileName())
sl@0
   383
		return 0x464e414d;
sl@0
   384
	InitFlag=init_mark;
sl@0
   385
	RDebug::Print(_L("ChkC %S OK"),&TheExeDataObject.iFileName);
sl@0
   386
#endif
sl@0
   387
	return KErrNone;
sl@0
   388
	}
sl@0
   389
sl@0
   390
TInt Init(MDllList& aList)
sl@0
   391
	{
sl@0
   392
	TInt r=KErrNone;
sl@0
   393
	SDllInfo info;
sl@0
   394
	info.iDllNum=DLLNUM;
sl@0
   395
	info.iEntryPointAddress=((TInt)&_E32Startup);
sl@0
   396
	RLdrTest ldd;
sl@0
   397
	ldd.Open();
sl@0
   398
	info.iModuleHandle=ldd.ModuleHandleFromAddr((TInt)&_E32Startup);
sl@0
   399
	ldd.Close();
sl@0
   400
	if (!aList.IsPresent(info))
sl@0
   401
		{
sl@0
   402
		TInt pos=aList.Add(info);
sl@0
   403
		INITDEPS(r,aList);		// Call Init on our dependencies
sl@0
   404
		aList.MoveToEnd(pos);
sl@0
   405
#ifdef __MODULE_HAS_DATA
sl@0
   406
		if (r==KErrNone)
sl@0
   407
			r=ChkC();		// Check initial values for .data/.bss and check constructors have been called
sl@0
   408
#endif
sl@0
   409
		RegisterInitCall(DLLNUM);
sl@0
   410
		}
sl@0
   411
	return r;
sl@0
   412
	}
sl@0
   413
sl@0
   414
CDllInfo::CDllInfo()
sl@0
   415
	{
sl@0
   416
	Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff);
sl@0
   417
	}
sl@0
   418
sl@0
   419
CDllInfo::~CDllInfo()
sl@0
   420
	{
sl@0
   421
	}
sl@0
   422
sl@0
   423
TInt CDllInfo::Create()
sl@0
   424
	{
sl@0
   425
	TInt r;
sl@0
   426
	r=UserSvr::DllSetTls(0, this);
sl@0
   427
	if (r==KErrNone)
sl@0
   428
		r=UserSvr::DllSetTls(TLS_INDEX, NULL);
sl@0
   429
	if (r==KErrNone)
sl@0
   430
		{
sl@0
   431
		r=Init(iExeDepList);
sl@0
   432
		}
sl@0
   433
	return r;
sl@0
   434
	}
sl@0
   435
sl@0
   436
void CDllInfo::RegisterConstructorCall(TInt aDllNum)
sl@0
   437
	{
sl@0
   438
	(void)aDllNum;
sl@0
   439
	}
sl@0
   440
sl@0
   441
void CDllInfo::RegisterInitCall(TInt aDllNum)
sl@0
   442
	{
sl@0
   443
	(void)aDllNum;
sl@0
   444
	}
sl@0
   445
sl@0
   446
void CDllInfo::RegisterDestructorCall(TInt aDllNum)
sl@0
   447
	{
sl@0
   448
	(void)aDllNum;
sl@0
   449
	}
sl@0
   450
sl@0
   451
TInt CDllInfo::StoreHandle(TInt aHandle)
sl@0
   452
	{
sl@0
   453
	if (iHandleCount==KMaxHandles)
sl@0
   454
		return KErrOverflow;
sl@0
   455
	TInt i=iNextHandle;
sl@0
   456
	for (; i<KMaxHandles && iHandles[i]!=0; ++i) {}
sl@0
   457
	if (i==KMaxHandles)
sl@0
   458
		{
sl@0
   459
		for (i=0; i<iNextHandle && iHandles[i]!=0; ++i) {}
sl@0
   460
		EXET_ASSERT(i!=iNextHandle);
sl@0
   461
		}
sl@0
   462
	iNextHandle=i;
sl@0
   463
	iHandles[i]=aHandle;
sl@0
   464
	++iHandleCount;
sl@0
   465
	return i;
sl@0
   466
	}
sl@0
   467
sl@0
   468
void CDllInfo::RemoveHandle(TInt aIndex)
sl@0
   469
	{
sl@0
   470
	iHandles[aIndex]=0;
sl@0
   471
	--iHandleCount;
sl@0
   472
	}
sl@0
   473
sl@0
   474
void CDllInfo::SetupCDList()
sl@0
   475
	{
sl@0
   476
	new (&iDllConstructList) TDllList;
sl@0
   477
	EXET_ASSERT(UserSvr::DllSetTls(TLS_INDEX, &iDllConstructList)==KErrNone);
sl@0
   478
	}
sl@0
   479
sl@0
   480
/******************************************************************************
sl@0
   481
 * Exports
sl@0
   482
 ******************************************************************************/
sl@0
   483
extern "C" __MODULE_EXPORT void RegisterConstructorCall(TInt aDllNum)
sl@0
   484
	{
sl@0
   485
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   486
	if (p)
sl@0
   487
		p->RegisterConstructorCall(aDllNum);
sl@0
   488
	}
sl@0
   489
sl@0
   490
extern "C" __MODULE_EXPORT void RegisterInitCall(TInt aDllNum)
sl@0
   491
	{
sl@0
   492
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   493
	if (p)
sl@0
   494
		p->RegisterInitCall(aDllNum);
sl@0
   495
	}
sl@0
   496
sl@0
   497
extern "C" __MODULE_EXPORT void RegisterDestructorCall(TInt aDllNum)
sl@0
   498
	{
sl@0
   499
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   500
	if (p)
sl@0
   501
		p->RegisterDestructorCall(aDllNum);
sl@0
   502
	}
sl@0
   503
sl@0
   504
GLDEF_C TInt E32Main()
sl@0
   505
	{
sl@0
   506
	CTrapCleanup* cleanup=CTrapCleanup::New();
sl@0
   507
	EXET_ASSERT(cleanup);
sl@0
   508
	CActiveScheduler* sched=new CActiveScheduler;
sl@0
   509
	EXET_ASSERT(sched);
sl@0
   510
	CActiveScheduler::Install(sched);
sl@0
   511
	CTestServer* svr=new CTestServer;
sl@0
   512
	EXET_ASSERT(svr);
sl@0
   513
	TBuf<16> suffix;
sl@0
   514
	User::CommandLine(suffix);
sl@0
   515
	TName svr_name=KServerName();
sl@0
   516
	if (suffix.Length())
sl@0
   517
		{
sl@0
   518
		svr_name.Append('.');
sl@0
   519
		svr_name+=suffix;
sl@0
   520
		}
sl@0
   521
	EXET_ASSERT(svr->Start(svr_name)==KErrNone);
sl@0
   522
	CDllInfo* dllinfo=new CDllInfo;
sl@0
   523
	EXET_ASSERT(dllinfo);
sl@0
   524
	EXET_ASSERT(dllinfo->Create()==KErrNone);
sl@0
   525
	svr->iInfo=dllinfo;
sl@0
   526
sl@0
   527
	CActiveScheduler::Start();
sl@0
   528
sl@0
   529
	UserSvr::DllFreeTls(0);
sl@0
   530
	UserSvr::DllFreeTls(TLS_INDEX);
sl@0
   531
	delete dllinfo;
sl@0
   532
	delete svr;
sl@0
   533
	delete sched;
sl@0
   534
	delete cleanup;
sl@0
   535
sl@0
   536
	return 0;
sl@0
   537
	}