kerneltest/e32test/secure/t_sobject.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/secure/t_sobject.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1470 @@
+// Copyright (c) 2002-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\secure\t_sobject.cpp
+// Overview:
+// Test the security aspects of the TFind??? (TFindChunk etc.) classes.
+// API Information:
+// TFind??? (TFindChunk, TFindThread etc.)
+// Details:
+// - Test TFindPhysicalDevices and attempt to open the found device. 
+// Verify results are as expected.
+// - Test TFindLogicalDevices and attempt to open the found device. 
+// Duplicate the object in another thread. Verify results are as expected.
+// - Test TFindLibrary and attempt to open the found device. Verify results 
+// are as expected.
+// - Test TFindServer and attempt to open the found server. Test duplication 
+// of a named or unnamed server. Verify results are as expected.
+// - Test TFindProcess and attempt to open the found process. Test duplication 
+// of the object. Attempt to open the process by name and by id. Verify 
+// results are as expected.
+// - Test TFindThread and attempt to open the found thread. Test duplication 
+// of the object. Attempt to open the thread in various ways. Verify 
+// results are as expected.
+// - Test TFindChunk and attempt to open the found object. Test duplication 
+// of the object. Attempt to open the object in various ways. Verify 
+// results are as expected.
+// - Test TFindSemaphore and attempt to open the found object. Attempt to 
+// open the object in various ways. Test duplication of the object. Verify 
+// results are as expected.
+// - Test TFindMutex and attempt to open the found object. Attempt to 
+// open the object in various ways. Test duplication of the object. Verify 
+// results are as expected.
+// - Create some RMsgQueue objects. Attempt to open the objects in various ways. 
+// Test duplication of the objects. Verify results are as expected.
+// - Create some RCondVar objects. Attempt to open the objects in various ways. 
+// Test duplication of the objects. Verify results are as expected.
+// - Test passing a handle via IPC: test sending LogicalChannel, Chunk, 
+// Semaphore, Mutex, MsgQueue, CondVar and Session handles. Verify results
+// are as expected.
+// Platforms/Drives/Compatibility:
+// All.
+// Assumptions/Requirement/Pre-requisites:
+// Failures and causes:
+// Base Port information:
+// 
+//
+
+#include <e32test.h>
+#include <e32msgqueue.h>
+#include <f32file.h>
+#include "d_sldd.h"
+
+LOCAL_D RTest test(_L("T_SOBJECT"));
+
+TInt PlatSecProcessIsolationError = 1;
+TInt PlatSecFindError = 1;
+
+_LIT(KTestMutexName,"T_SOBJECT-test-mutex");
+_LIT(KTestSemaphoreName,"T_SOBJECT-test-semaphore");
+_LIT(KTestChunkName,"T_SOBJECT-test-chunk");
+_LIT(KTestMsgQueueName,"T_SOBJECT-test-msgqueue");
+_LIT(KTestCondVarName,"T_SOBJECT-test-condvar");
+
+TFullName Name;
+TFullName Name2;
+
+void SetName(RHandleBase a)
+	{
+	Name = a.FullName();
+	}
+
+TBool CheckName(RHandleBase a)
+	{
+	Name2 = a.FullName();
+	return Name==Name2;
+	}
+
+class RTestHandle : public RHandleBase
+	{
+public:
+	inline TInt Open(const TFindHandleBase& aHandle,TOwnerType aType=EOwnerThread)
+		{ return RHandleBase::Open(aHandle,aType); }
+	};
+
+
+
+enum TTestProcessFunctions
+	{
+	ETestProcessServer,
+	ETestProcessDuplicate,
+	ETestProcessOpenThreadById,
+	};
+
+#include "testprocess.h"
+
+
+TThreadId MainThreadId;
+
+TInt TestThreadDuplicate(TAny* aArg)
+	{
+	RHandleBase handle;
+	handle.SetHandle((TInt)aArg);
+	RThread thread;
+	TInt r = thread.Open(MainThreadId);
+	if(r!=KErrNone)
+		r = 999;
+	else
+		r = handle.Duplicate(thread);
+	thread.Close();
+	return r;
+	}
+
+TInt DuplicateInOtherThread(RHandleBase aHandle)
+	{
+	RThread thread;
+	TRequestStatus logonStatus;
+	thread.Create(_L(""),TestThreadDuplicate,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,(TAny*)aHandle.Handle());
+	MainThreadId = RThread().Id();
+	thread.Logon(logonStatus);
+	thread.Resume();
+	User::WaitForRequest(logonStatus);
+	test(thread.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(thread);
+	return logonStatus.Int();
+	}
+
+TInt DuplicateInOtherProcess(RHandleBase aHandle)
+	{
+	RTestProcess process;
+	TRequestStatus logonStatus;
+	process.Create(ETestProcessDuplicate,RThread().Id(),aHandle.Handle());
+	process.Logon(logonStatus);
+	process.Resume();
+	User::WaitForRequest(logonStatus);
+	test(process.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(process);
+	return logonStatus.Int();
+	}
+
+TInt OpenThreadByIdInOtherProcess(TThreadId aId)
+	{
+	RTestProcess process;
+	TRequestStatus logonStatus;
+	process.Create(ETestProcessOpenThreadById,aId);
+	process.Logon(logonStatus);
+	process.Resume();
+	User::WaitForRequest(logonStatus);
+	test(process.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(process);
+	return logonStatus.Int();
+	}
+
+
+
+//
+// RTestSession
+//
+
+enum TServerName
+	{
+	EMainServer,EGlobalSharableServer,EAnonymousServer,ENumServerTypes
+	};
+
+_LIT(KServerName,"T_SOBJECT-MainServer");
+_LIT(KServerName2,"T_SOBJECT-GlobalSharableServer");
+
+inline const TDesC& ServerName(TServerName aName)
+	{
+	switch(aName)
+		{
+	case EMainServer:
+		return KServerName;
+	case EGlobalSharableServer:
+		return KServerName2;
+	default:
+		return KNullDesC;
+		}
+	}
+
+class RTestSession : public RSessionBase
+	{
+public:
+	inline TInt Connect(TServerName aName=EMainServer)
+		{
+		TInt r=CreateSession(ServerName(aName),TVersion());
+		if(r) return r;
+		return ShareAuto();
+		}
+	inline TInt ConnectProtected(TServerName aName=EMainServer)
+		{
+		TInt r=CreateSession(ServerName(aName),TVersion());
+		if(r) return r;
+		return ShareProtected();
+		}
+	inline TInt Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType=EOwnerProcess)
+		{ return RSessionBase::Open(aMessage,aParam,aType); }
+	inline TInt Open(RMessagePtr2 aMessage,TInt aParam,const TSecurityPolicy& aServerPolicy,TOwnerType aType=EOwnerProcess)
+		{ return RSessionBase::Open(aMessage,aParam,aServerPolicy,aType); }
+	inline TInt Send(TInt aFunction)
+		{ return RSessionBase::SendReceive(aFunction); }
+	inline TInt Send(TInt aFunction,const TIpcArgs& aArgs)
+		{ return RSessionBase::SendReceive(aFunction,aArgs); }
+	inline void Send(TInt aFunction,TRequestStatus& aStatus)
+		{ RSessionBase::SendReceive(aFunction,aStatus); }
+	inline void Send(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus)
+		{ RSessionBase::SendReceive(aFunction,aArgs,aStatus); }
+	};
+
+
+
+//
+// CTestSession
+//
+
+class CTestSession : public CSession2
+	{
+public:
+	enum {EShutdown,EPing,ETestMutex,ETestSemaphore,ETestMsgQueue,ETestCondVar,ETestChunk,ETestChunkAdjust,ETestLdd,
+		ETestSession,ETestSession2,ETestSession3,ETestServerDuplicateInThread,ETestServerDuplicateInProcess};
+public:
+	CTestSession();
+	virtual void ServiceL(const RMessage2& aMessage);
+public:
+	};
+
+CTestSession::CTestSession()
+	: CSession2()
+	{
+	}
+
+const TInt KTestDataMaxLength8 = 20;
+const TInt KTestDataMaxLength16 = 40;
+_LIT8(KTestData8,"12345678");
+_LIT16(KTestData16,"1234567890123456");
+_LIT(KTestPanicCategory,"TEST PANIC");
+
+void CTestSession::ServiceL(const RMessage2& aMessage)
+	{
+	RMessagePtr2 m(aMessage);
+	TFullName name;
+	TInt r = KErrGeneral;
+
+	switch (aMessage.Function())
+		{
+		case CTestSession::EShutdown:
+			CActiveScheduler::Stop();
+			break;
+
+		case CTestSession::EPing:
+			r=aMessage.Int0();
+			break;
+
+		case CTestSession::ETestMutex:
+			{
+			RMutex object;
+
+			r = object.Open(m,0,EOwnerThread);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+
+			r = object.Open(m,1,EOwnerProcess);
+			if(r!=KErrNone)
+				break;
+			name = object.FullName();
+			object.Close();
+			if(name!=KTestMutexName)
+				goto fail;
+
+			r = object.Open(m,2,EOwnerThread);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+			break;
+
+		case CTestSession::ETestSemaphore:
+			{
+			RSemaphore object;
+
+			r = object.Open(m,0,EOwnerThread);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+
+			r = object.Open(m,1,EOwnerProcess);
+			if(r!=KErrNone)
+				break;
+			name = object.FullName();
+			object.Close();
+			if(name!=KTestSemaphoreName)
+				goto fail;
+
+			r = object.Open(m,2,EOwnerThread);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+			break;
+
+		case CTestSession::ETestMsgQueue:
+			{
+			RMsgQueue<TInt> object;
+
+			r = object.Open(m,0,EOwnerThread);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+
+			r = object.Open(m,1,EOwnerProcess);
+			if(r!=KErrNone)
+				break;
+			name = object.FullName();
+			object.Close();
+			if(name!=KTestMsgQueueName)
+				goto fail;
+
+			r = object.Open(m,2,EOwnerThread);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+			break;
+
+		case CTestSession::ETestCondVar:
+			{
+			RCondVar object;
+
+			r = object.Open(m,0,EOwnerThread);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+
+			r = object.Open(m,1,EOwnerProcess);
+			if(r!=KErrNone)
+				break;
+			name = object.FullName();
+			object.Close();
+			if(name!=KTestCondVarName)
+				goto fail;
+
+			r = object.Open(m,2,EOwnerThread);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+			break;
+
+		case CTestSession::ETestChunk:
+			{
+			RChunk object;
+
+			r = object.Open(m,0,EOwnerThread);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+
+			r = object.Open(m,1,EOwnerProcess);
+			if(r!=KErrNone)
+				break;
+			name = object.FullName();
+			object.Close();
+			if(name!=KTestChunkName)
+				goto fail;
+
+			r = object.Open(m,2,EOwnerThread);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+			break;
+
+		case CTestSession::ETestChunkAdjust:
+			{
+			RChunk object;
+			r = object.Open(m,0,EOwnerThread);
+			if(r==KErrNone)
+				r = object.Adjust(0x1000);
+			object.Close();
+			}
+			break;
+
+		case CTestSession::ETestLdd:
+			{
+			RLddTest object;
+			r = object.Open(m,0);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+			r = object.Open(m,1);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+			r = object.Test1();
+			if(r!=aMessage.Int2())
+				goto fail;
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+
+		case CTestSession::ETestSession:
+			{
+			RTestSession object;
+			r = object.Open(m,0);
+			if(r!=KErrBadHandle || object.Handle())
+				goto fail;
+			r = object.Open(m,1,TSecurityPolicy(ECapabilityTCB));
+			if(r!=KErrPermissionDenied || object.Handle())
+				goto fail;
+			r = object.Open(m,1);
+			if(r!=KErrNone)
+				break;
+			SetName(object);
+			m.Read(3,Name2);
+			if(Name!=Name2)
+				goto fail;
+
+			RFs fs;
+			r = fs.Open(m,2,TSecurityPolicy(ECapabilityTCB));
+			if(r!=KErrNone)
+				goto fail;
+			fs.Close();
+
+			r=object.Send(CTestSession::EPing,TIpcArgs(234));
+			if(r!=234)
+				goto fail;
+
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+
+		case CTestSession::ETestSession2:
+			{
+			RTestSession object;
+			object.Connect(EGlobalSharableServer);
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+
+		case CTestSession::ETestSession3:
+			{
+			RFs object;
+			object.Connect();
+			object.ShareProtected();
+			m.Complete(object);
+			object.Close();
+			return;
+			}
+
+		case CTestSession::ETestServerDuplicateInThread:
+			r = DuplicateInOtherThread(Server()->Server());
+			break;
+
+		case CTestSession::ETestServerDuplicateInProcess:
+			r = DuplicateInOtherProcess(Server()->Server());
+			break;
+
+		default:
+			m.Complete(KErrNotSupported);
+			break;
+		}
+	m.Complete(r);
+	return;
+fail:
+	m.Complete(KErrGeneral);
+	return;
+	}
+
+RTestSession Session;
+
+
+
+//
+// CTestServer
+//
+
+class CTestServer : public CServer2
+	{
+public:
+	CTestServer(TInt aPriority,TInt aType=ESharableSessions);
+	virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
+	};
+
+CTestServer::CTestServer(TInt aPriority,TInt aType)
+	: CServer2(aPriority,(TServerType)aType)
+	{
+	}
+
+CSession2* CTestServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const
+	{
+	return new (ELeave) CTestSession();
+	}
+
+
+
+//
+// CTestActiveScheduler
+//
+
+class CTestActiveScheduler : public CActiveScheduler
+	{
+public:
+	virtual void Error(TInt anError) const;
+	};
+
+void CTestActiveScheduler::Error(TInt anError) const
+	{
+	User::Panic(_L("TestServer Error"),anError);
+	}
+
+
+
+//
+// Server thread
+//
+
+const TInt KServerRendezvous = KRequestPending+1;
+
+RServer2 Servers[ENumServerTypes];
+
+void DoStartServer(TServerName aName)
+	{
+	CTestActiveScheduler* activeScheduler = new (ELeave) CTestActiveScheduler;
+	CActiveScheduler::Install(activeScheduler);
+	CleanupStack::PushL(activeScheduler);
+
+	TInt type = 1; // ESharableSessions
+	if(aName==EGlobalSharableServer)
+		type = 2; // EGlobalSharableSessions;
+	CTestServer* server = new (ELeave) CTestServer(0,type);
+	CleanupStack::PushL(server);
+
+	User::LeaveIfError(server->Start(ServerName(aName)));
+
+	Servers[aName] = server->Server();
+	RProcess::Rendezvous(KServerRendezvous);
+	RThread::Rendezvous(KServerRendezvous);
+
+	CActiveScheduler::Start();
+
+	Servers[aName].SetHandle(0);
+	CleanupStack::PopAndDestroy(2);
+	}
+
+TInt StartServer(TServerName aName)
+	{
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();
+	if(!cleanupStack)
+		return KErrNoMemory;
+	TRAPD(leaveError,DoStartServer(aName))
+	delete cleanupStack;
+	return leaveError;
+	}
+
+TInt DoThreadStartServer(TAny* aArg)
+	{
+	return StartServer((TServerName)(TInt)aArg);
+	}
+
+TRequestStatus ThrdSvrStat;
+
+TInt StartServerInThread(TServerName aName)
+	{
+	RThread thread;
+	TRequestStatus rendezvousStatus;
+	thread.Create(_L(""),DoThreadStartServer,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,(TAny*)aName);
+	thread.NotifyDestruction(ThrdSvrStat);
+	thread.Rendezvous(rendezvousStatus);
+	thread.Resume();
+	User::WaitForRequest(rendezvousStatus);
+	thread.Close();
+	if(rendezvousStatus.Int()!=KServerRendezvous)
+		return KErrGeneral;
+	return KErrNone;
+	}
+
+
+
+void TestPhysicalDevices()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Test find named object"));
+	TFindPhysicalDevice find(_L("*"));
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Try open found object"));
+	RTestHandle testObject;
+	test((r=testObject.Open(find))==PlatSecProcessIsolationError);
+	testObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestLogicalDevices()
+	{
+	TFullName name;
+	TInt r;
+	RDevice device;
+
+	test.Start(_L("Test find named object"));
+	TFindLogicalDevice find(_L("*"));
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=device.Open(find))==KErrNone);
+
+	test.Next(_L("Test duplicate object in other thread"));
+	test((r=DuplicateInOtherThread(device))==KErrNone);
+
+	test.Next(_L("Test duplicate object in other process"));
+	test((r=DuplicateInOtherProcess(device))==KErrNone);
+
+	device.Close();
+
+	test.Next(_L("Test open device by name"));
+	test((r=device.Open(name))==KErrNone);
+	device.Close();
+
+	test.End();
+	}
+
+
+
+void TestLibraries()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Test find named object"));
+	TFindLibrary find(_L("*"));
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Try open found object"));
+	RTestHandle testObject;
+	test((r=testObject.Open(find))==PlatSecProcessIsolationError);
+	testObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestServers()
+	{
+	TFullName name;
+	TInt r;
+	RServer2 localObject(Servers[EAnonymousServer]);
+
+	test.Start(_L("Test find named object"));
+	TFindServer find(ServerName(EMainServer));
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Try open found object"));
+	RTestHandle testObject;
+	test((r=testObject.Open(find))==KErrPermissionDenied);
+
+	test.Next(_L("Test duplicate named server in other thread"));
+	test((r=Session.Send(CTestSession::ETestServerDuplicateInThread))==KErrNone);
+
+	test.Next(_L("Try duplicate named server in other process"));
+	test((r=Session.Send(CTestSession::ETestServerDuplicateInProcess))==KErrPermissionDenied);
+
+	test.Next(_L("Test duplicate unnamed server in other thread"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Try duplicate unnamed server in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==KErrPermissionDenied);
+
+	test.End();
+	}
+
+
+
+void TestProcesses()
+	{
+	TFullName name;
+	TInt r;
+	RProcess process;
+
+	test.Start(_L("Test find named object"));
+	TFindProcess find(_L("EKern*"));
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=process.Open(find))==KErrNone);
+
+	test.Next(_L("Test duplicate object in other thread"));
+	test((r=DuplicateInOtherThread(process))==KErrNone);
+
+	test.Next(_L("Test duplicate object in other process"));
+	test((r=DuplicateInOtherProcess(process))==KErrNone);
+
+	process.Close();
+
+	test.Next(_L("Test open process by name"));
+	test((r=process.Open(name))==KErrNone);
+	TProcessId id=process.Id();
+	process.Close();
+
+	test.Next(_L("Test open process by id"));
+	test((r=process.Open(id))==KErrNone);
+	test(name==process.FullName());
+	process.Close();
+
+	test.End();
+	}
+
+
+
+void TestThreads()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Creating threads"));
+	RThread globalObject;
+	RThread localObject;
+	RThread testObject;
+	test((r=globalObject.Create(_L("T_SOBJECT-test-global-thread"),TestThreadDuplicate,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL))==KErrNone);
+	test((r=localObject.Create(_L(""),TestThreadDuplicate,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL))==KErrNone);
+
+	test.Next(_L("Test find named thread"));
+	TFindThread find(globalObject.FullName());
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=testObject.Open(find))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't find unnamed thread"));
+	TName objectName(localObject.FullName());
+	find.Find(objectName);
+	test((r=find.Next(name))==PlatSecFindError);
+
+	test.Next(_L("Test open named thread by name"));
+	test((r=testObject.Open(globalObject.FullName()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open unnamed thread by name"));
+	test((r=testObject.Open(localObject.FullName()))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Check can't open with no name"));
+	test((r=testObject.Open(KNullDesC))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open named thread by id (in same process)"));
+	test((r=testObject.Open(globalObject.Id()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Test open named thread by id (in other process)"));
+	test((r=OpenThreadByIdInOtherProcess(globalObject.Id()))==KErrNone);
+
+	test.Next(_L("Test open unnamed thread by id (in same process)"));
+	test((r=testObject.Open(localObject.Id()))==KErrNone);
+
+	test.Next(_L("Check can't open unnamed thread by id (in other process)"));
+	test((r=OpenThreadByIdInOtherProcess(localObject.Id()))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate named thread in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate unnamed thread in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate named thread in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate unnamed thread in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Closing threads"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestChunks()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Creating chunks"));
+	RChunk globalObject;
+	RChunk localObject;
+	RChunk testObject;
+	test((r=globalObject.CreateGlobal(_L("T_SOBJECT-test-global-chunk"),4096,1024*1024))==KErrNone);
+	test((r=localObject.CreateLocal(4096,1024*1024))==KErrNone);
+
+	test.Next(_L("Test find global object"));
+	TFindChunk find(globalObject.FullName());
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=testObject.Open(find))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't find local object"));
+	TName objectName(localObject.FullName());
+	find.Find(objectName);
+	test((r=find.Next(name))==PlatSecFindError);
+
+	test.Next(_L("Test open with null name"));
+	test((r=testObject.OpenGlobal(KNullDesC,ETrue))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open global object by name"));
+	test((r=testObject.OpenGlobal(globalObject.FullName(),ETrue))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open local object by name"));
+	test((r=testObject.OpenGlobal(localObject.FullName(),ETrue))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Test duplicate global object in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate local object in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate global object in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate local object in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Test Chunk protection"));
+	{
+	RChunk protectedChunk;
+	test((r=protectedChunk.CreateGlobal(KNullDesC,0x1000,0x100000,EOwnerProcess))==KErrNone);
+	test((r=Session.Send(CTestSession::ETestChunkAdjust,TIpcArgs(protectedChunk)))==KErrNone);
+	protectedChunk.SetRestrictions(RChunk::EPreventAdjust);
+	test((r=Session.Send(CTestSession::ETestChunkAdjust,TIpcArgs(protectedChunk)))==KErrAccessDenied);
+	protectedChunk.Close();
+	}
+
+	test.Next(_L("Closing chunks"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestSemaphores()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Creating semaphores"));
+	RSemaphore globalObject;
+	RSemaphore localObject;
+	RSemaphore testObject;
+	test((r=globalObject.CreateGlobal(_L("T_SOBJECT-test-global-semaphore"),1))==KErrNone);
+	test((r=localObject.CreateLocal(1))==KErrNone);
+
+	test.Next(_L("Test find global object"));
+	TFindSemaphore find(globalObject.FullName());
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=testObject.Open(find))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't find local object"));
+	TName objectName(localObject.FullName());
+	find.Find(objectName);
+	test((r=find.Next(name))==PlatSecFindError);
+
+	test.Next(_L("Test open with null name"));
+	test((r=testObject.OpenGlobal(KNullDesC))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open global object by name"));
+	test((r=testObject.OpenGlobal(globalObject.FullName()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open local object by name"));
+	test((r=testObject.OpenGlobal(localObject.FullName()))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Test duplicate global object in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate local object in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate global object in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate local object in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Closing Semaphores"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestMutexes()
+	{
+	TFullName name;
+	TInt r;
+
+	test.Start(_L("Creating mutexes"));
+	RMutex globalObject;
+	RMutex localObject;
+	RMutex testObject;
+	test((r=globalObject.CreateGlobal(_L("T_SOBJECT-test-global-mutex")))==KErrNone);
+	test((r=localObject.CreateLocal())==KErrNone);
+
+	test.Next(_L("Test find global object"));
+	TFindMutex find(globalObject.FullName());
+	test((r=find.Next(name))==KErrNone);
+
+	test.Next(_L("Test open found object"));
+	test((r=testObject.Open(find))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't find local object"));
+	TName objectName(localObject.FullName());
+	find.Find(objectName);
+	test((r=find.Next(name))==PlatSecFindError);
+
+	test.Next(_L("Test open with null name"));
+	test((r=testObject.OpenGlobal(KNullDesC))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open global object by name"));
+	test((r=testObject.OpenGlobal(globalObject.FullName()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open local object by name"));
+	test((r=testObject.OpenGlobal(localObject.FullName()))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Test duplicate global object in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate local object in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate global object in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate local object in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Closing mutexes"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestMessageQueues()
+	{
+	TInt r;
+
+	test.Start(_L("Creating message queues"));
+	RMsgQueue<TInt> globalObject;
+	RMsgQueue<TInt> localObject;
+	RMsgQueue<TInt> testObject;
+	test((r=globalObject.CreateGlobal(_L("T_SOBJECT-test-global-msgqueue"),1))==KErrNone);
+	test((r=localObject.CreateLocal(1))==KErrNone);
+
+	test.Next(_L("Test open with null name"));
+	test((r=testObject.OpenGlobal(KNullDesC))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open global object by name"));
+	test((r=testObject.OpenGlobal(globalObject.FullName()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open local object by name"));
+	test((r=testObject.OpenGlobal(localObject.FullName()))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Test duplicate global object in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate local object in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate global object in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate local object in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Closing message queues"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestConditionVariables()
+	{
+	TInt r;
+
+	test.Start(_L("Creating condition variables"));
+	RCondVar globalObject;
+	RCondVar localObject;
+	RCondVar testObject;
+	test((r=globalObject.CreateGlobal(_L("T_SOBJECT-test-global-condvar")))==KErrNone);
+	test((r=localObject.CreateLocal())==KErrNone);
+
+	test.Next(_L("Test open with null name"));
+	test((r=testObject.OpenGlobal(KNullDesC))==KErrNotFound);
+	testObject.Close();
+
+	test.Next(_L("Test open global object by name"));
+	test((r=testObject.OpenGlobal(globalObject.FullName()))==KErrNone);
+	testObject.Close();
+
+	test.Next(_L("Check can't open local object by name"));
+	test((r=testObject.OpenGlobal(localObject.FullName()))==PlatSecFindError);
+	testObject.Close();
+
+	test.Next(_L("Test duplicate global object in other process"));
+	test((r=DuplicateInOtherProcess(globalObject))==KErrNone);
+
+	test.Next(_L("Check can't duplicate local object in other process"));
+	test((r=DuplicateInOtherProcess(localObject))==PlatSecProcessIsolationError);
+
+	test.Next(_L("Test duplicate global object in other thread"));
+	test((r=DuplicateInOtherThread(globalObject))==KErrNone);
+
+	test.Next(_L("Test duplicate local object in other thead"));
+	test((r=DuplicateInOtherThread(localObject))==KErrNone);
+
+	test.Next(_L("Closing message queues"));
+	globalObject.Close();
+	localObject.Close();
+
+	test.End();
+	}
+
+
+
+void TestIPCHandles()
+	{
+	RTestProcess server;
+	TRequestStatus rendezvous;
+	TInt r;
+
+	test.Next(_L("Test sending LogicalChannel handles"));
+	{
+	RLddTest localLdd;
+	RLddTest protectedLdd;
+	RLddTest returnLdd;
+	r=User::LoadLogicalDevice(_L("D_SLDD.LDD"));
+	test(r==KErrNone || r==KErrAlreadyExists);
+	r=localLdd.OpenLocal();
+	test(r==KErrNone);
+	r=protectedLdd.OpenProtected();
+	test(r==KErrNone);
+	TInt lddValue=protectedLdd.Test1();
+	test(lddValue==RLddTest::ETest1Value);
+	SetName(protectedLdd);
+	r = Session.Send(CTestSession::ETestLdd,TIpcArgs(localLdd,protectedLdd,lddValue,&Name));
+	r = returnLdd.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnLdd));
+	protectedLdd.Close();
+	returnLdd.Close();
+	localLdd.Close();
+	}
+
+	test.Next(_L("Test sending Chunk handles"));
+	{
+	RChunk localChunk;
+	RChunk globalChunk;
+	RChunk protectedChunk;
+	RChunk returnChunk;
+	test((r=localChunk.CreateLocal(0x1000,0x100000,EOwnerThread))==KErrNone);
+	test((r=globalChunk.CreateGlobal(KTestChunkName,0x1000,0x100000,EOwnerProcess))==KErrNone);
+	test((r=protectedChunk.CreateGlobal(KNullDesC,0x1000,0x100000,EOwnerProcess))==KErrNone);
+	SetName(protectedChunk);
+	r = Session.Send(CTestSession::ETestChunk,TIpcArgs(localChunk,globalChunk,protectedChunk,&Name));
+	r = returnChunk.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnChunk));
+	returnChunk.Close();
+	protectedChunk.Close();
+	globalChunk.Close();
+	localChunk.Close();
+	}
+
+	test.Next(_L("Test sending Semaphore handles"));
+	{
+	RSemaphore localSemaphore;
+	RSemaphore globalSemaphore;
+	RSemaphore protectedSemaphore;
+	RSemaphore returnSemaphore;
+	test((r=localSemaphore.CreateLocal(1,EOwnerThread))==KErrNone);
+	test((r=globalSemaphore.CreateGlobal(KTestSemaphoreName,1,EOwnerProcess))==KErrNone);
+	test((r=protectedSemaphore.CreateGlobal(KNullDesC,1,EOwnerProcess))==KErrNone);
+	SetName(protectedSemaphore);
+	r = Session.Send(CTestSession::ETestSemaphore,TIpcArgs(localSemaphore,globalSemaphore,protectedSemaphore,&Name));
+	r = returnSemaphore.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnSemaphore));
+	returnSemaphore.Close();
+	protectedSemaphore.Close();
+	globalSemaphore.Close();
+	localSemaphore.Close();
+	}
+
+	test.Next(_L("Test sending Mutex handles"));
+	{
+	RMutex localMutex;
+	RMutex globalMutex;
+	RMutex protectedMutex;
+	RMutex returnMutex;
+	test((r=localMutex.CreateLocal(EOwnerThread))==KErrNone);
+	test((r=globalMutex.CreateGlobal(KTestMutexName,EOwnerProcess))==KErrNone);
+	test((r=protectedMutex.CreateGlobal(KNullDesC,EOwnerProcess))==KErrNone);
+	SetName(protectedMutex);
+	r = Session.Send(CTestSession::ETestMutex,TIpcArgs(localMutex,globalMutex,protectedMutex,&Name));
+	r = returnMutex.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnMutex));
+	returnMutex.Close();
+	protectedMutex.Close();
+	globalMutex.Close();
+	localMutex.Close();
+	}
+
+	test.Next(_L("Test sending MsgQueue handles"));
+	{
+	RMsgQueue<TInt> localMsgQueue;
+	RMsgQueue<TInt> globalMsgQueue;
+	RMsgQueue<TInt> protectedMsgQueue;
+	RMsgQueue<TInt> returnMsgQueue;
+	test((r=localMsgQueue.CreateLocal(1,EOwnerThread))==KErrNone);
+	test((r=globalMsgQueue.CreateGlobal(KTestMsgQueueName,1,EOwnerProcess))==KErrNone);
+	test((r=protectedMsgQueue.CreateGlobal(KNullDesC,1,EOwnerProcess))==KErrNone);
+	SetName(protectedMsgQueue);
+	r = Session.Send(CTestSession::ETestMsgQueue,TIpcArgs(localMsgQueue,globalMsgQueue,protectedMsgQueue,&Name));
+	r = returnMsgQueue.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnMsgQueue));
+	returnMsgQueue.Close();
+	protectedMsgQueue.Close();
+	globalMsgQueue.Close();
+	localMsgQueue.Close();
+	}
+
+	test.Next(_L("Test sending CondVar handles"));
+	{
+	RCondVar localCondVar;
+	RCondVar globalCondVar;
+	RCondVar protectedCondVar;
+	RCondVar returnCondVar;
+	test((r=localCondVar.CreateLocal(EOwnerThread))==KErrNone);
+	test((r=globalCondVar.CreateGlobal(KTestCondVarName,EOwnerProcess))==KErrNone);
+	test((r=protectedCondVar.CreateGlobal(KNullDesC,EOwnerProcess))==KErrNone);
+	SetName(protectedCondVar);
+	r = Session.Send(CTestSession::ETestCondVar,TIpcArgs(localCondVar,globalCondVar,protectedCondVar,&Name));
+	r = returnCondVar.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnCondVar));
+	returnCondVar.Close();
+	protectedCondVar.Close();
+	globalCondVar.Close();
+	localCondVar.Close();
+	}
+
+	test.Start(_L("Starting test server 2"));
+	server.Create(ETestProcessServer,EGlobalSharableServer);
+	server.Rendezvous(rendezvous);
+	server.Resume();
+	User::WaitForRequest(rendezvous);
+	test(rendezvous==KServerRendezvous);
+	server.Close();
+
+	test.Next(_L("Test sending Session handles"));
+	{
+	RTestSession localSession;
+	RTestSession protectedSession;
+	RTestSession returnSession;
+	RFs fsSession;
+	test((r=localSession.Connect(EGlobalSharableServer))==KErrNone);
+	test((r=localSession.Send(CTestSession::EPing,TIpcArgs(123)))==123);
+	test((r=protectedSession.ConnectProtected(EGlobalSharableServer))==KErrNone);
+	test((r=protectedSession.Send(CTestSession::EPing,TIpcArgs(123)))==123);
+	test((r=fsSession.Connect())==KErrNone);
+	test((r=fsSession.ShareProtected())==KErrNone);
+	SetName(protectedSession);
+	r = Session.Send(CTestSession::ETestSession,TIpcArgs(localSession,protectedSession,fsSession,&Name));
+	r = returnSession.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test(CheckName(returnSession));
+	returnSession.Close();
+	protectedSession.Close();
+	localSession.Close();
+	fsSession.Close();
+	}
+
+	test.Next(_L("Test receiving Session handles"));
+	{
+	RTestSession returnSession;
+	r = Session.Send(CTestSession::ETestSession2);
+	r = returnSession.SetReturnedHandle(r);
+	test(r==KErrNone);
+	test((r=Session.Send(CTestSession::EPing,TIpcArgs(123)))==123);  // So we know server has closed returnedSession
+	test((r=returnSession.Send(CTestSession::EPing,TIpcArgs(123)))==123);
+	returnSession.Close();
+	RFs returnFsSession;
+	r = Session.Send(CTestSession::ETestSession3);
+	r = returnSession.SetReturnedHandle(r,TSecurityPolicy(TSecureId(0x100039e3))); // f32 sid
+	test(r==KErrNone);
+	returnFsSession.Close();
+	}
+
+	test.Next(_L("Try global sharing of Sessions without server support"));
+	{
+	RTestSession protectedSession;
+	test((r=protectedSession.ConnectProtected(EMainServer))==KErrPermissionDenied);
+	}
+
+	test.Next(_L("Stopping test server 2"));
+	{
+	RTestSession session;
+	test((r=session.Connect(EGlobalSharableServer))==KErrNone);
+	session.Send(CTestSession::EShutdown);
+	session.Close();
+	}
+
+	test.End();
+	}
+
+// Test uniqness of object names is enforced by DObjectCon when creating objects
+void TestObjectNames()
+	{
+	_LIT(KNameFormat, "TestObject-%d");
+	const TInt KObjectCount = 10;
+	RMutex objects[KObjectCount];
+
+	test.Start(_L("Test uniqueness of object names"));
+	
+	// Test creating named and unnamed objects is ok
+	TInt i;
+	for (i = 0 ; i < KObjectCount ; ++i)
+		{
+		if (i % 2)
+			test(objects[i].CreateLocal() == KErrNone);
+		else
+			{
+			TBuf<16> name;
+			name.AppendFormat(KNameFormat, i);
+			test(objects[i].CreateGlobal(name) == KErrNone);
+			}
+		}
+
+	// Test we cannot create objects with duplicate names
+	for (i = 0 ; i < KObjectCount ; i+=2)
+		{
+		TBuf<16> name;
+		name.AppendFormat(KNameFormat, i);
+		test(objects[i].CreateGlobal(name) == KErrAlreadyExists);
+		}	
+	
+	// Close all objects
+	for (i = 0 ; i < KObjectCount ; ++i)
+		{
+		objects[i].Close();
+		}
+
+	test.End();
+	}
+
+
+TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
+	{
+	TInt r;
+
+	switch(aTestNum)
+		{
+
+	case ETestProcessServer:
+		return StartServer((TServerName)aArg1);
+
+	case ETestProcessDuplicate:
+		{
+		RHandleBase handle;
+		handle.SetHandle(aArg2);
+		RThread thread;
+		r = thread.Open(TThreadId(aArg1));
+		if(r!=KErrNone)
+			r = 999;
+		else
+			r = handle.Duplicate(thread);
+		thread.Close();
+		}
+		return r;
+
+	case ETestProcessOpenThreadById:
+		{
+		RThread thread;
+		r = thread.Open(TThreadId(aArg1));
+		if(r==KErrNone)
+			thread.Close();
+		}
+		return r;
+
+
+	default:
+		User::Panic(_L("T_SOBJECT"),1);
+		}
+
+	return KErrNone;
+	}
+
+
+GLDEF_C TInt E32Main()
+    {
+	PlatSecProcessIsolationError = PlatSec::ConfigSetting(PlatSec::EPlatSecProcessIsolation)&&PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)
+		? KErrPermissionDenied : KErrNone;
+	PlatSecFindError = PlatSec::ConfigSetting(PlatSec::EPlatSecProcessIsolation)
+		? KErrNotFound : KErrNone;
+
+	TBuf16<512> cmd;
+	User::CommandLine(cmd);
+	if(cmd.Length() && TChar(cmd[0]).IsDigit())
+		{
+		TInt function = -1;
+		TInt arg1 = -1;
+		TInt arg2 = -1;
+		TLex lex(cmd);
+		lex.Val(function);
+		lex.SkipSpace();
+		lex.Val(arg1);
+		lex.SkipSpace();
+		lex.Val(arg2);
+		return DoTestProcess(function,arg1,arg2);
+		}
+
+
+	test.Title();
+	TInt r;
+	
+	test.Start(_L("Starting test servers"));
+	RTestProcess server;
+	TRequestStatus rendezvous;
+	TRequestStatus svrstat;
+	server.Create(ETestProcessServer,EMainServer);
+	server.NotifyDestruction(svrstat);
+	server.Rendezvous(rendezvous);
+	server.Resume();
+	User::WaitForRequest(rendezvous);
+	test(rendezvous==KServerRendezvous);
+	server.Close();
+	test((r=StartServerInThread(EAnonymousServer))==KErrNone);
+
+	test.Next(_L("Openning server session"));
+	test((r=Session.Connect())==KErrNone);
+
+	test.Next(_L("Test Find and Open PhysicalDevices"));
+	TestPhysicalDevices();
+
+	test.Next(_L("Test Find and Open LogicalDevices"));
+	TestLogicalDevices();
+
+	test.Next(_L("Test Find and Open Libraries"));
+	TestLibraries();
+
+	test.Next(_L("Test Find and Open Servers"));
+	TestServers();
+
+	test.Next(_L("Test Find and Open Processes"));
+	TestProcesses();
+
+	test.Next(_L("Test Find and Open Threads"));
+	TestThreads();
+
+	test.Next(_L("Test Find and Open Chunks"));
+	TestChunks();
+
+	test.Next(_L("Test Find and Open Semaphores"));
+	TestSemaphores();
+
+	test.Next(_L("Test Find and Open Mutexes"));
+	TestMutexes();
+
+	test.Next(_L("Test Message Queues"));
+	TestMessageQueues();
+
+	test.Next(_L("Test Condition Variables"));
+	TestConditionVariables();
+
+	test.Next(_L("Test passing handle via IPC"));
+	TestIPCHandles();
+
+	test.Next(_L("Test object names"));
+	TestObjectNames();
+
+	test.Next(_L("Stopping test server"));
+	Session.Send(CTestSession::EShutdown);
+	Session.Close();
+	User::WaitForRequest(svrstat);
+	test(svrstat == KErrNone);
+
+	test.End();
+
+	return(0);
+    }
+