os/kernelhwsrv/kerneltest/f32test/loader/exet.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
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 <f32file.h>
sl@0
    22
#include "dllt.h"
sl@0
    23
#include "exetifc.h"
sl@0
    24
#include "dlltree.h"
sl@0
    25
#include <d_ldrtst.h>
sl@0
    26
#include "../mmu/d_memorytest.h"
sl@0
    27
sl@0
    28
#ifdef __VC32__
sl@0
    29
#pragma warning(disable:4706)
sl@0
    30
#endif
sl@0
    31
sl@0
    32
const TInt KMaxHandlesPerDll=4;
sl@0
    33
const TInt KMaxHandles=KMaxHandlesPerDll*KNumModules;
sl@0
    34
sl@0
    35
extern "C" TInt _E32Startup();
sl@0
    36
sl@0
    37
extern "C" IMPORT_C void RegisterConstructorCall(TInt aDllNum);
sl@0
    38
extern "C" IMPORT_C void RegisterInitCall(TInt aDllNum);
sl@0
    39
extern "C" IMPORT_C void RegisterDestructorCall(TInt aDllNum);
sl@0
    40
sl@0
    41
#define PANIC()		ExeTPanic(__LINE__)
sl@0
    42
#define EXET_ASSERT(c)	((void)((c)||(PANIC(),0)))
sl@0
    43
sl@0
    44
static TText GetSpecialDrive(TInt aSpecialDriveNum);
sl@0
    45
sl@0
    46
void ExeTPanic(TInt aLine)
sl@0
    47
	{
sl@0
    48
	User::Panic(_L("EXET"),aLine);
sl@0
    49
	}
sl@0
    50
sl@0
    51
/******************************************************************************
sl@0
    52
 * Class Definitions
sl@0
    53
 ******************************************************************************/
sl@0
    54
class CDllInfo;
sl@0
    55
NONSHARABLE_CLASS(TDllList) : public MDllList
sl@0
    56
	{
sl@0
    57
public:
sl@0
    58
	TDllList();
sl@0
    59
	virtual TBool IsPresent(const SDllInfo& aInfo);
sl@0
    60
	virtual TInt Add(const SDllInfo& aInfo);
sl@0
    61
	virtual void MoveToEnd(TInt aPos);
sl@0
    62
public:
sl@0
    63
	TInt iCount;
sl@0
    64
	SDllInfo iInfo[KNumModules];
sl@0
    65
	};
sl@0
    66
sl@0
    67
NONSHARABLE_CLASS(CTestServer) : public CServer2
sl@0
    68
	{
sl@0
    69
public:
sl@0
    70
	CTestServer();
sl@0
    71
	virtual ~CTestServer();
sl@0
    72
	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
sl@0
    73
	virtual TInt RunError(TInt aError);
sl@0
    74
public:
sl@0
    75
	CDllInfo* iInfo;
sl@0
    76
	};
sl@0
    77
sl@0
    78
NONSHARABLE_CLASS(CTestSession) : public CSession2
sl@0
    79
	{
sl@0
    80
public:
sl@0
    81
	virtual ~CTestSession();
sl@0
    82
	virtual void CreateL();
sl@0
    83
	virtual void ServiceL(const RMessage2& aMessage);
sl@0
    84
public:
sl@0
    85
	TInt GetExeDepList(const RMessage2& aMessage);
sl@0
    86
	TInt GetCDList(const RMessage2& aMessage);
sl@0
    87
	TInt LoadDll(const RMessage2& aMessage);
sl@0
    88
	TInt CloseDll(TInt aHandle);
sl@0
    89
	TInt CallBlkI(TInt aHandle, TInt aIn);
sl@0
    90
	TInt CallRBlkI(TInt aHandle, TInt aIn);
sl@0
    91
public:
sl@0
    92
	CDllInfo* iInfo;
sl@0
    93
	RMemoryTestLdd iTestLdd;
sl@0
    94
	};
sl@0
    95
sl@0
    96
NONSHARABLE_CLASS(CDllInfo) : public CBase
sl@0
    97
	{
sl@0
    98
public:
sl@0
    99
	CDllInfo();
sl@0
   100
	virtual ~CDllInfo();
sl@0
   101
	TInt Create();
sl@0
   102
	TInt StoreHandle(TInt aHandle);
sl@0
   103
	void RemoveHandle(TInt aIndex);
sl@0
   104
	void SetupCDList();
sl@0
   105
public:
sl@0
   106
	void RegisterConstructorCall(TInt aDllNum);
sl@0
   107
	void RegisterInitCall(TInt aDllNum);
sl@0
   108
	void RegisterDestructorCall(TInt aDllNum);
sl@0
   109
public:
sl@0
   110
	TInt iNextGen;
sl@0
   111
	TInt iHandleCount;
sl@0
   112
	TInt iNextHandle;
sl@0
   113
	TInt iHandles[KMaxHandles];
sl@0
   114
	TInt iModuleNum[KMaxHandles];
sl@0
   115
	TDllList iExeDepList;
sl@0
   116
	TDllList iDllConstructList;
sl@0
   117
	};
sl@0
   118
sl@0
   119
/******************************************************************************
sl@0
   120
 * Static data
sl@0
   121
 ******************************************************************************/
sl@0
   122
#ifdef __MODULE_HAS_DATA
sl@0
   123
class TExeData
sl@0
   124
	{
sl@0
   125
public:
sl@0
   126
	TExeData();
sl@0
   127
public:
sl@0
   128
	TTime iStartTime;
sl@0
   129
	TTime iInitTime;
sl@0
   130
	TInt iTest1;
sl@0
   131
	TFileName iFileName;
sl@0
   132
	};
sl@0
   133
sl@0
   134
TInt Bss[16];
sl@0
   135
TInt ExeNum=EXENUM;
sl@0
   136
TInt Generation=0;
sl@0
   137
TInt InitFlag=0;
sl@0
   138
TFullName StartThread=RThread().FullName();
sl@0
   139
TName StartProcess=RProcess().Name();
sl@0
   140
TExeData TheExeDataObject;
sl@0
   141
sl@0
   142
TExeData::TExeData()
sl@0
   143
	:	iFileName(RProcess().FileName())
sl@0
   144
	{
sl@0
   145
	TInt r;
sl@0
   146
	CHKDEPS(r);		// Check our dependencies are initialised
sl@0
   147
	if (r!=KErrNone)
sl@0
   148
		User::Panic(_L("CHKDEPS"),r);
sl@0
   149
	iStartTime.HomeTime();
sl@0
   150
	iTest1=299792458;
sl@0
   151
	RegisterConstructorCall(EXENUM);
sl@0
   152
	}
sl@0
   153
#endif
sl@0
   154
sl@0
   155
/******************************************************************************
sl@0
   156
 * Class TDllList
sl@0
   157
 ******************************************************************************/
sl@0
   158
TDllList::TDllList()
sl@0
   159
	{
sl@0
   160
	iCount=0;
sl@0
   161
	Mem::Fill(iInfo, KNumModules*sizeof(SDllInfo), 0xff);
sl@0
   162
	}
sl@0
   163
sl@0
   164
TBool TDllList::IsPresent(const SDllInfo& aInfo)
sl@0
   165
	{
sl@0
   166
	TInt i;
sl@0
   167
	for (i=0; i<iCount; ++i)
sl@0
   168
		{
sl@0
   169
		if (iInfo[i].iDllNum==aInfo.iDllNum)
sl@0
   170
			return ETrue;
sl@0
   171
		}
sl@0
   172
	return EFalse;
sl@0
   173
	}
sl@0
   174
sl@0
   175
TInt TDllList::Add(const SDllInfo& aInfo)
sl@0
   176
	{
sl@0
   177
	EXET_ASSERT(iCount<KNumModules);
sl@0
   178
	TInt pos=iCount;
sl@0
   179
	iInfo[iCount++]=aInfo;
sl@0
   180
	return pos;
sl@0
   181
	}
sl@0
   182
sl@0
   183
void TDllList::MoveToEnd(TInt aPos)
sl@0
   184
	{
sl@0
   185
	if (aPos<iCount-1)
sl@0
   186
		{
sl@0
   187
		SDllInfo x(iInfo[aPos]);
sl@0
   188
		Mem::Move(iInfo+aPos, iInfo+aPos+1, (iCount-aPos-1)*sizeof(SDllInfo));
sl@0
   189
		iInfo[iCount-1]=x;
sl@0
   190
		}
sl@0
   191
	}
sl@0
   192
sl@0
   193
/******************************************************************************
sl@0
   194
 * Class CTestSession/CTestServer
sl@0
   195
 ******************************************************************************/
sl@0
   196
sl@0
   197
CTestSession::~CTestSession()
sl@0
   198
	{
sl@0
   199
	}
sl@0
   200
sl@0
   201
void CTestSession::CreateL()
sl@0
   202
	{
sl@0
   203
	User::LeaveIfError(iTestLdd.Open());
sl@0
   204
	}
sl@0
   205
sl@0
   206
void CTestSession::ServiceL(const RMessage2& aMessage)
sl@0
   207
	{
sl@0
   208
	TInt r=KErrNotSupported;
sl@0
   209
	TInt mid=aMessage.Function();
sl@0
   210
	switch(mid)
sl@0
   211
		{
sl@0
   212
		case RLoaderTest::EMsgGetExeDepList:
sl@0
   213
			r=GetExeDepList(aMessage);
sl@0
   214
			break;
sl@0
   215
		case RLoaderTest::EMsgLoadDll:
sl@0
   216
			r=LoadDll(aMessage);
sl@0
   217
			break;
sl@0
   218
		case RLoaderTest::EMsgCallBlkI:
sl@0
   219
			r=CallBlkI(aMessage.Int0(), aMessage.Int1());
sl@0
   220
			break;
sl@0
   221
		case RLoaderTest::EMsgCallRBlkI:
sl@0
   222
			r=CallRBlkI(aMessage.Int0(), aMessage.Int1());
sl@0
   223
			break;
sl@0
   224
		case RLoaderTest::EMsgCloseDll:
sl@0
   225
			r=CloseDll(aMessage.Int0());
sl@0
   226
			break;
sl@0
   227
		case RLoaderTest::EMsgGetCDList:
sl@0
   228
			r=GetCDList(aMessage);
sl@0
   229
			break;
sl@0
   230
		case RLoaderTest::EMsgCheckReadable:
sl@0
   231
			{
sl@0
   232
			TUint32 value;
sl@0
   233
			r = iTestLdd.ReadMemory((TAny*)aMessage.Int0(),value);
sl@0
   234
			if(r)
sl@0
   235
				r = KErrGeneral;
sl@0
   236
			}
sl@0
   237
			break;
sl@0
   238
		case RLoaderTest::EMsgExit:
sl@0
   239
			r=KErrNone;
sl@0
   240
			CActiveScheduler::Stop();
sl@0
   241
			break;
sl@0
   242
		default:
sl@0
   243
			break;
sl@0
   244
		}
sl@0
   245
	aMessage.Complete(r);
sl@0
   246
	}
sl@0
   247
sl@0
   248
TInt CTestSession::GetExeDepList(const RMessage2& aMsg)
sl@0
   249
	{
sl@0
   250
	TPtrC8 dep_list_ptr((const TUint8*)&iInfo->iExeDepList.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   251
	aMsg.WriteL(0, dep_list_ptr, 0);
sl@0
   252
	return KErrNone;
sl@0
   253
	}
sl@0
   254
sl@0
   255
TInt CTestSession::GetCDList(const RMessage2& aMsg)
sl@0
   256
	{
sl@0
   257
	TPtrC8 list_ptr((const TUint8*)&iInfo->iDllConstructList.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   258
	aMsg.WriteL(0, list_ptr, 0);
sl@0
   259
	return KErrNone;
sl@0
   260
	}
sl@0
   261
sl@0
   262
static void GetDllFileName(const TDesC& aListName, TDes& aTargetName)
sl@0
   263
/**
sl@0
   264
	Helper function for CTestSession::LoadDll transforms the supplied
sl@0
   265
	filename to an absolutely qualified name if it has been copied to a drive.
sl@0
   266
sl@0
   267
	@param	aListName		The DLL name.  This will not have a path if it should
sl@0
   268
							be loaded from the Z drive.  Otherwise it will be fully
sl@0
   269
							qualified but with a digit for the drive letter.
sl@0
   270
	@param	aTargetName		Descriptor to populate with target filename.  If the
sl@0
   271
							DLL should be loaded from Z this is the same as aListName.
sl@0
   272
							Otherwise, it is the same as aListName but with the correct
sl@0
   273
							drive letter.
sl@0
   274
 */
sl@0
   275
	{
sl@0
   276
	aTargetName.Copy(aListName);
sl@0
   277
	if (aListName[1] != ':')
sl@0
   278
		return;
sl@0
   279
sl@0
   280
	TText& targetDrive = aTargetName[0];
sl@0
   281
	targetDrive = GetSpecialDrive(targetDrive - '0');
sl@0
   282
	}
sl@0
   283
sl@0
   284
sl@0
   285
TInt CTestSession::LoadDll(const RMessage2& aMsg)
sl@0
   286
	{
sl@0
   287
	TInt module=aMsg.Int0();
sl@0
   288
	TDllList dll_list;
sl@0
   289
	TPtrC8 dll_list_ptr((const TUint8*)dll_list.iInfo, KNumModules*sizeof(SDllInfo));
sl@0
   290
	TPtrC dllname0=MODULE_FILENAME(module);
sl@0
   291
	TFileName dllname;
sl@0
   292
	GetDllFileName(dllname0, dllname);
sl@0
   293
	iInfo->SetupCDList();
sl@0
   294
	RLibrary l;
sl@0
   295
	TInt r=l.Load(dllname, TUidType());
sl@0
   296
	if (r>0)
sl@0
   297
		{
sl@0
   298
		RDebug::Printf("RLibrary::Load returned 0x%x !",r);
sl@0
   299
		return -999; // return unexpected error type so test fails.
sl@0
   300
		}
sl@0
   301
	if (r!=KErrNone)
sl@0
   302
		return r;
sl@0
   303
	TInitFunction f=(TInitFunction)l.Lookup(INIT_ORDINAL);
sl@0
   304
	EXET_ASSERT(f);
sl@0
   305
	r=(*f)(dll_list);
sl@0
   306
	if (r!=KErrNone)
sl@0
   307
		return r;
sl@0
   308
	TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
sl@0
   309
	EXET_ASSERT(bf);
sl@0
   310
	TInt result=(*bf)(531441);
sl@0
   311
	EXET_ASSERT(result==BlkIValue(module, 531441));
sl@0
   312
	TInt h=iInfo->StoreHandle(l.Handle());
sl@0
   313
	EXET_ASSERT(h>=0);
sl@0
   314
	iInfo->iModuleNum[h]=module;
sl@0
   315
	aMsg.WriteL(1, dll_list_ptr, 0);
sl@0
   316
	return h;
sl@0
   317
	}
sl@0
   318
sl@0
   319
TInt CTestSession::CallBlkI(TInt aHandle, TInt aIn)
sl@0
   320
	{
sl@0
   321
	TInt h=iInfo->iHandles[aHandle];
sl@0
   322
	EXET_ASSERT(h!=0);
sl@0
   323
	RLibrary l;
sl@0
   324
	l.SetHandle(h);
sl@0
   325
	TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
sl@0
   326
	EXET_ASSERT(bf);
sl@0
   327
	return (*bf)(aIn);
sl@0
   328
	}
sl@0
   329
sl@0
   330
TInt CTestSession::CallRBlkI(TInt aHandle, TInt aIn)
sl@0
   331
	{
sl@0
   332
	TInt h=iInfo->iHandles[aHandle];
sl@0
   333
	EXET_ASSERT(h!=0);
sl@0
   334
	RLibrary l;
sl@0
   335
	l.SetHandle(h);
sl@0
   336
	TRBlkIFunction rbf=(TRBlkIFunction)l.Lookup(REC_BLOCK_INC_ORDINAL);
sl@0
   337
	EXET_ASSERT(rbf);
sl@0
   338
	++iInfo->iNextGen;
sl@0
   339
	return (*rbf)(aIn,iInfo->iNextGen);
sl@0
   340
	}
sl@0
   341
sl@0
   342
TInt CTestSession::CloseDll(TInt aHandle)
sl@0
   343
	{
sl@0
   344
	TInt h=iInfo->iHandles[aHandle];
sl@0
   345
	TInt m=iInfo->iModuleNum[aHandle];
sl@0
   346
	EXET_ASSERT(h!=0);
sl@0
   347
	EXET_ASSERT(m>=0);
sl@0
   348
	iInfo->iHandles[aHandle]=0;
sl@0
   349
	iInfo->iModuleNum[aHandle]=-1;
sl@0
   350
	iInfo->SetupCDList();
sl@0
   351
	RLibrary l;
sl@0
   352
	l.SetHandle(h);
sl@0
   353
	l.Close();
sl@0
   354
	return KErrNone;
sl@0
   355
	}
sl@0
   356
sl@0
   357
CTestServer::CTestServer()
sl@0
   358
	: CServer2(0,ESharableSessions)
sl@0
   359
	{
sl@0
   360
	}
sl@0
   361
sl@0
   362
CTestServer::~CTestServer()
sl@0
   363
	{
sl@0
   364
	}
sl@0
   365
sl@0
   366
CSession2* CTestServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
sl@0
   367
	{
sl@0
   368
	(void)aVersion;
sl@0
   369
	CTestSession* s = new (ELeave) CTestSession;
sl@0
   370
	s->iInfo=iInfo;
sl@0
   371
	return s;
sl@0
   372
	}
sl@0
   373
sl@0
   374
_LIT(KExetErr,"EXETERR");
sl@0
   375
TInt CTestServer::RunError(TInt aError)
sl@0
   376
	{
sl@0
   377
	User::Panic(KExetErr,aError);
sl@0
   378
	return 0;
sl@0
   379
	}
sl@0
   380
sl@0
   381
/******************************************************************************
sl@0
   382
 * Class CDllInfo
sl@0
   383
 ******************************************************************************/
sl@0
   384
TInt ChkC()
sl@0
   385
	{
sl@0
   386
#ifdef __MODULE_HAS_DATA
sl@0
   387
	TInt init_mark=~((EXENUM+DLLNUMOFFSET)*(EXENUM+DLLNUMOFFSET));
sl@0
   388
	if (InitFlag==init_mark)
sl@0
   389
		return KErrNone;
sl@0
   390
	if (InitFlag!=0)
sl@0
   391
		return 0x494e4946;
sl@0
   392
	TInt i;
sl@0
   393
	TInt x=0;
sl@0
   394
	for (i=0; i<16; ++i) x|=Bss[i];
sl@0
   395
	if (x)
sl@0
   396
		return 0x425353;
sl@0
   397
	if (ExeNum!=EXENUM)
sl@0
   398
		return 0x44415441;
sl@0
   399
	if (Generation!=0)
sl@0
   400
		return 0x47454e;
sl@0
   401
	if (StartProcess!=RProcess().Name())
sl@0
   402
		return 0x535450;
sl@0
   403
	if (TheExeDataObject.iTest1!=299792458)
sl@0
   404
		return 0x54455354;
sl@0
   405
	if (TheExeDataObject.iFileName != RProcess().FileName())
sl@0
   406
		return 0x464e414d;
sl@0
   407
	InitFlag=init_mark;
sl@0
   408
	RDebug::Print(_L("ChkC %S OK"),&TheExeDataObject.iFileName);
sl@0
   409
#endif
sl@0
   410
	return KErrNone;
sl@0
   411
	}
sl@0
   412
sl@0
   413
TInt Init(MDllList& aList)
sl@0
   414
	{
sl@0
   415
	TInt r=KErrNone;
sl@0
   416
	SDllInfo info;
sl@0
   417
	info.iDllNum=DLLNUM;
sl@0
   418
	info.iEntryPointAddress=((TInt)&_E32Startup);
sl@0
   419
	RLdrTest ldd;
sl@0
   420
	ldd.Open();
sl@0
   421
	info.iModuleHandle=ldd.ModuleHandleFromAddr((TInt)&_E32Startup);
sl@0
   422
	ldd.Close();
sl@0
   423
	if (!aList.IsPresent(info))
sl@0
   424
		{
sl@0
   425
		TInt pos=aList.Add(info);
sl@0
   426
		INITDEPS(r,aList);		// Call Init on our dependencies
sl@0
   427
		aList.MoveToEnd(pos);
sl@0
   428
#ifdef __MODULE_HAS_DATA
sl@0
   429
		if (r==KErrNone)
sl@0
   430
			r=ChkC();		// Check initial values for .data/.bss and check constructors have been called
sl@0
   431
#endif
sl@0
   432
		RegisterInitCall(DLLNUM);
sl@0
   433
		}
sl@0
   434
	return r;
sl@0
   435
	}
sl@0
   436
sl@0
   437
CDllInfo::CDllInfo()
sl@0
   438
	{
sl@0
   439
	Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff);
sl@0
   440
	}
sl@0
   441
sl@0
   442
CDllInfo::~CDllInfo()
sl@0
   443
	{
sl@0
   444
	}
sl@0
   445
sl@0
   446
TInt CDllInfo::Create()
sl@0
   447
	{
sl@0
   448
	TInt r;
sl@0
   449
	r=UserSvr::DllSetTls(0, this);
sl@0
   450
	if (r==KErrNone)
sl@0
   451
		r=UserSvr::DllSetTls(TLS_INDEX, NULL);
sl@0
   452
	if (r==KErrNone)
sl@0
   453
		{
sl@0
   454
		r=Init(iExeDepList);
sl@0
   455
		}
sl@0
   456
	return r;
sl@0
   457
	}
sl@0
   458
sl@0
   459
void CDllInfo::RegisterConstructorCall(TInt aDllNum)
sl@0
   460
	{
sl@0
   461
	(void)aDllNum;
sl@0
   462
	}
sl@0
   463
sl@0
   464
void CDllInfo::RegisterInitCall(TInt aDllNum)
sl@0
   465
	{
sl@0
   466
	(void)aDllNum;
sl@0
   467
	}
sl@0
   468
sl@0
   469
void CDllInfo::RegisterDestructorCall(TInt aDllNum)
sl@0
   470
	{
sl@0
   471
	(void)aDllNum;
sl@0
   472
	}
sl@0
   473
sl@0
   474
TInt CDllInfo::StoreHandle(TInt aHandle)
sl@0
   475
	{
sl@0
   476
	if (iHandleCount==KMaxHandles)
sl@0
   477
		return KErrOverflow;
sl@0
   478
	TInt i=iNextHandle;
sl@0
   479
	for (; i<KMaxHandles && iHandles[i]!=0; ++i) {}
sl@0
   480
	if (i==KMaxHandles)
sl@0
   481
		{
sl@0
   482
		for (i=0; i<iNextHandle && iHandles[i]!=0; ++i) {}
sl@0
   483
		EXET_ASSERT(i!=iNextHandle);
sl@0
   484
		}
sl@0
   485
	iNextHandle=i;
sl@0
   486
	iHandles[i]=aHandle;
sl@0
   487
	++iHandleCount;
sl@0
   488
	return i;
sl@0
   489
	}
sl@0
   490
sl@0
   491
void CDllInfo::RemoveHandle(TInt aIndex)
sl@0
   492
	{
sl@0
   493
	iHandles[aIndex]=0;
sl@0
   494
	--iHandleCount;
sl@0
   495
	}
sl@0
   496
sl@0
   497
void CDllInfo::SetupCDList()
sl@0
   498
	{
sl@0
   499
	new (&iDllConstructList) TDllList;
sl@0
   500
	EXET_ASSERT(UserSvr::DllSetTls(TLS_INDEX, &iDllConstructList)==KErrNone);
sl@0
   501
	}
sl@0
   502
sl@0
   503
/******************************************************************************
sl@0
   504
 * Exports
sl@0
   505
 ******************************************************************************/
sl@0
   506
extern "C" __MODULE_EXPORT void RegisterConstructorCall(TInt aDllNum)
sl@0
   507
	{
sl@0
   508
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   509
	if (p)
sl@0
   510
		p->RegisterConstructorCall(aDllNum);
sl@0
   511
	}
sl@0
   512
sl@0
   513
extern "C" __MODULE_EXPORT void RegisterInitCall(TInt aDllNum)
sl@0
   514
	{
sl@0
   515
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   516
	if (p)
sl@0
   517
		p->RegisterInitCall(aDllNum);
sl@0
   518
	}
sl@0
   519
sl@0
   520
extern "C" __MODULE_EXPORT void RegisterDestructorCall(TInt aDllNum)
sl@0
   521
	{
sl@0
   522
	CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
sl@0
   523
	if (p)
sl@0
   524
		p->RegisterDestructorCall(aDllNum);
sl@0
   525
	}
sl@0
   526
sl@0
   527
static TText GetSpecialDrive(TInt aSpecialDriveNum)
sl@0
   528
/**
sl@0
   529
	Work out which physical drive corresponds to the supplied
sl@0
   530
	logical drive.
sl@0
   531
	
sl@0
   532
	@param	aSpecialDriveNum	Number which identifies which drive to find.
sl@0
   533
							Zero means internal drive.
sl@0
   534
	@return					Drive letter.
sl@0
   535
 */
sl@0
   536
	{
sl@0
   537
	RFs fs;
sl@0
   538
	TInt r = fs.Connect();
sl@0
   539
	EXET_ASSERT(r == KErrNone);
sl@0
   540
sl@0
   541
	// cannot load binaries from emulated removable drives
sl@0
   542
#ifdef __WINS__
sl@0
   543
	if (aSpecialDriveNum == 1)
sl@0
   544
		return 'c';
sl@0
   545
#endif
sl@0
   546
sl@0
   547
	TInt dr = 0;
sl@0
   548
	for (TInt d = 0; d <= (TInt)sizeof(SpecialDriveList); ++d)
sl@0
   549
		{
sl@0
   550
		dr = SpecialDriveList[d];
sl@0
   551
		TDriveInfo di;
sl@0
   552
		r = fs.Drive(di, dr);
sl@0
   553
		EXET_ASSERT(r == KErrNone);
sl@0
   554
		if (di.iType == EMediaNotPresent)
sl@0
   555
			continue;
sl@0
   556
		
sl@0
   557
		// drive 0 == internal
sl@0
   558
		if (aSpecialDriveNum == 0 && (di.iDriveAtt & KDriveAttInternal) != 0)
sl@0
   559
			break;
sl@0
   560
		// drive 1 == removable
sl@0
   561
		if (aSpecialDriveNum == 1 && (di.iDriveAtt & KDriveAttRemovable) != 0)
sl@0
   562
			break;
sl@0
   563
		}	
sl@0
   564
sl@0
   565
	TChar ch0;
sl@0
   566
	r = RFs::DriveToChar(dr, ch0);
sl@0
   567
	EXET_ASSERT(r == KErrNone);
sl@0
   568
	fs.Close();
sl@0
   569
	return static_cast<TText>(TUint(ch0));
sl@0
   570
	}
sl@0
   571
sl@0
   572
GLDEF_C TInt E32Main()
sl@0
   573
	{
sl@0
   574
	CTrapCleanup* cleanup=CTrapCleanup::New();
sl@0
   575
	EXET_ASSERT(cleanup);
sl@0
   576
	CActiveScheduler* sched=new CActiveScheduler;
sl@0
   577
	EXET_ASSERT(sched);
sl@0
   578
	CActiveScheduler::Install(sched);
sl@0
   579
	CTestServer* svr=new CTestServer;
sl@0
   580
	EXET_ASSERT(svr);
sl@0
   581
	TBuf<16> suffix;
sl@0
   582
	User::CommandLine(suffix);
sl@0
   583
	TName svr_name=KServerName();
sl@0
   584
	if (suffix.Length())
sl@0
   585
		{
sl@0
   586
		svr_name.Append('.');
sl@0
   587
		svr_name+=suffix;
sl@0
   588
		}
sl@0
   589
	EXET_ASSERT(svr->Start(svr_name)==KErrNone);
sl@0
   590
	CDllInfo* dllinfo=new CDllInfo;
sl@0
   591
	EXET_ASSERT(dllinfo);
sl@0
   592
	EXET_ASSERT(dllinfo->Create()==KErrNone);
sl@0
   593
	svr->iInfo=dllinfo;
sl@0
   594
sl@0
   595
	CActiveScheduler::Start();
sl@0
   596
sl@0
   597
	UserSvr::DllFreeTls(0);
sl@0
   598
	UserSvr::DllFreeTls(TLS_INDEX);
sl@0
   599
	delete dllinfo;
sl@0
   600
	delete svr;
sl@0
   601
	delete sched;
sl@0
   602
	delete cleanup;
sl@0
   603
sl@0
   604
	return 0;
sl@0
   605
	}