kerneltest/e32test/secure/t_sobject.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 137 8aab599e3476
parent 0 a41df078684a
child 109 b3a1d9898418
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// 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);
    }