kernel/eka/kernel/sexec.cpp
changeset 0 a41df078684a
child 4 56f325a607ea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/sexec.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,2768 @@
+// Copyright (c) 1994-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:
+// e32\kernel\sexec.cpp
+// 
+//
+
+#include <kernel/kern_priv.h>
+#include <e32uid.h>
+#include <e32ver.h>
+//#include <unicode.h>
+#include "execs.h"
+
+TInt ExecHandler::ObjectNext(TObjectType aType, TBuf8<KMaxFullName>& aName, TFindHandle& aFindHandle)
+//
+// Do the next find.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ObjectNext type %d",aType));
+	if (aType<0 || aType>=ENumObjectTypes)
+		K::PanicKernExec(EBadObjectType);
+	DObjectCon* pC=K::Containers[aType];
+	TFullName fn;
+	TFullName match;
+	TFindHandle h;
+	Kern::KUDesGet(match,aName);
+	kumemget32(&h,&aFindHandle,sizeof(h));
+	__KTRACE_OPT(KEXEC,Kern::Printf("ObjN: %lS %08x", &match, h.Handle()));
+	NKern::ThreadEnterCS();
+	TInt r=pC->FindByFullName(h, match, fn);
+	NKern::ThreadLeaveCS();
+	Kern::KUDesPut(aName,fn);
+	kumemput32(&aFindHandle,&h,sizeof(h));
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ObjectNext ret %d",r));
+	return r;
+	}
+
+TUint8 *ExecHandler::ChunkBase(DChunk* aChunk)
+//
+// Return the address of the base of the Chunk.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkBase"));
+	return (TUint8*)aChunk->Base(&Kern::CurrentProcess());
+	}
+
+TInt ExecHandler::ChunkSize(DChunk* aChunk)
+//
+// Return the current size of the Chunk.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkSize"));
+	return aChunk->Size();
+	}
+
+TInt ExecHandler::ChunkMaxSize(DChunk* aChunk)
+//
+// Return the maximum size of the Chunk.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkMaxSize")); 	
+	return aChunk->MaxSize();
+	}
+
+TInt ExecHandler::ChunkBottom(DChunk* aChunk)
+//
+// Return the position of the bottom of the chunk
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkBottom"));
+	return aChunk->Bottom();
+	}
+
+TInt ExecHandler::ChunkTop(DChunk* aChunk)
+//
+// Return the position of the top of the chunk
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkTop"));
+	return aChunk->Top();
+	}
+
+void ExecHandler::MutexWait(DMutex* aMutex)
+//
+// Wait for the mutex.
+//
+	{
+
+//	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexWait"));
+	aMutex->Wait();
+	}
+
+void ExecHandler::MutexSignal(DMutex* aMutex)
+//
+// Signal the mutex.
+//
+	{
+
+//	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexSignal"));
+	if (TheCurrentThread==aMutex->iCleanup.iThread)
+		{
+		aMutex->Signal();
+		return;
+		}
+	K::PanicCurrentThread(EAccessDenied);
+	}
+
+/**
+Test if mutex is held by the current thread.
+@return True if the current thread has waited on the mutex, false otherwise.
+*/
+TBool ExecHandler::MutexIsHeld(DMutex* aMutex)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexIsHeld"));
+	return TheCurrentThread==aMutex->iCleanup.iThread;
+	}
+
+void ExecHandler::ProcessType(DProcess* aProcess, TUidType& aUids)
+//
+// Get process' UIDs.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessType"));
+	TUidType uids(aProcess->iUids);
+	NKern::UnlockSystem();
+	kumemput32(&aUids,&uids,sizeof(TUidType));
+	}
+
+TInt ExecHandler::ProcessId(DProcess* aProcess)
+//
+// Get process ID.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessId")); 	
+	return (TInt)aProcess->iId;
+	}
+
+void ExecHandler::ProcessSecurityInfo(DProcess* aProcess,SSecurityInfo& aInfo)
+//
+// Get process security info.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSecurityInfo"));
+	SSecurityInfo info(aProcess->iS);
+	NKern::UnlockSystem();
+	kumemput32(&aInfo,&info,sizeof(info));
+	}
+
+void ExecHandler::ThreadSecurityInfo(DThread* aThread,SSecurityInfo& aInfo)
+//
+// Get threads security info.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSecurityInfo"));
+	SSecurityInfo info(aThread->iOwningProcess->iS);
+	NKern::UnlockSystem();
+	kumemput32(&aInfo,&info,sizeof(info));
+	}
+
+void ExecHandler::MessageSecurityInfo(DThread* aClient,SSecurityInfo& aInfo)
+//
+// Get clients security info.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MessageSecurityInfo"));
+	SSecurityInfo info(aClient->iOwningProcess->iS);
+	NKern::UnlockSystem();
+	kumemput32(&aInfo,&info,sizeof(info));
+	}
+
+TInt ExecHandler::SessionSecurityInfo(TInt aSession,SSecurityInfo& aInfo)
+//
+// Get session security info.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SessionSecurityInfo"));
+	TInt r = KErrBadHandle;
+	SSecurityInfo info;
+	NKern::LockSystem();
+	DSession* s = (DSession*)TheCurrentThread->ObjectFromHandle(aSession,ESession);
+	if (s)
+		{
+		if (s->iServer && s->iServer->iOwningThread)
+			{
+			// session is connected, and server is alive
+			info = s->iServer->iOwningThread->iOwningProcess->iS;
+			r = KErrNone;
+			}
+		else
+			{
+			r = KErrServerTerminated;
+			}
+		}
+	NKern::UnlockSystem();
+	if (r==KErrNone)
+		kumemput32(&aInfo,&info,sizeof(info));
+	return r;
+	}
+
+void ExecHandler::CreatorSecurityInfo(SSecurityInfo& aInfo)
+//
+// Get creator's security info.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::CreatorSecurityInfo"));
+	kumemput32(&aInfo,&TheCurrentThread->iOwningProcess->iCreatorInfo,sizeof(aInfo));
+	}
+
+void ExecHandler::DisabledCapabilities(SCapabilitySet& aCaps)
+//
+// Get the set of capabilities which are not to be checked (implemented by effectively
+// setting them for all executables).
+//
+	{
+	__KTRACE_OPT(KEXEC, Kern::Printf("Exec::DisabledCapabilities"));
+#ifdef __PLATSEC_UNLOCKED__
+	kumemput32(&aCaps, &TheSuperPage().iDisabledCapabilities, sizeof(aCaps));
+#else
+	kumemset(&aCaps, 0, sizeof(aCaps));
+#endif	// __PLATSEC_UNLOCKED__
+	}
+
+void ExecHandler::ProcessResume(DProcess* aProcess)
+//
+// Resume the first thread in the process.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessResume"));
+	if (aProcess->iCreatorId!=TheCurrentThread->iOwningProcess->iId) // Not creator...
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::Resume"));
+	aProcess->Resume();
+	}
+
+void ExecHandler::ProcessFileName(DProcess* aProcess, TDes8& aName)
+//
+// Return the process file name.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessFileName"));
+	TFileName fn;
+	DCodeSeg* pS=aProcess->iCodeSeg;
+	if (pS)
+		pS->AppendFullFileName(fn);
+	NKern::UnlockSystem();
+	if (pS)
+		P::NormalizeExecutableFileName(fn);
+	Kern::KUDesPut(aName, fn);
+	}
+
+TInt ExecHandler::ProcessCommandLineLength(DProcess* aProcess)
+//
+// Return the process command line length.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessCommandLineLength"));
+
+	if (aProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::CommandLineLength"));
+	const TDesC* pC=aProcess->iCommandLine;
+#ifdef _UNICODE
+	return pC?(pC->Length()>>1):0;
+#else
+	return pC?(pC->Length()):0;
+#endif
+	}
+
+void ExecHandler::ProcessCommandLine(DProcess* aProcess, TDes8& aCommandLine)
+//
+// Return the process command line.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessCommandLine"));
+	if (aProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::CommandLine"));
+	aProcess->CheckedOpen();
+	DThread& t=*TheCurrentThread;
+	t.iTempObj=aProcess;
+	NKern::UnlockSystem();
+	const TDesC* pC=aProcess->iCommandLine;
+	if (!pC)
+		pC=&KNullDesC;
+	Kern::KUDesPut(aCommandLine,*pC);
+	NKern::ThreadEnterCS();
+	t.iTempObj=NULL;
+	aProcess->Close(NULL);
+	NKern::ThreadLeaveCS();
+	}
+
+TExitType ExecHandler::ProcessExitType(DProcess* aProcess)
+//
+// Return the exit type.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitType")); 	
+	return (TExitType)aProcess->iExitType;
+	}
+
+TInt ExecHandler::ProcessExitReason(DProcess* aProcess)
+//
+// Return the exit reason.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitReason"));
+	return aProcess->iExitReason;
+	}
+
+void ExecHandler::ProcessExitCategory(DProcess* aProcess, TDes8& aName)
+//
+// Return the category of the exit type.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitCategory"));
+	TBufC<KMaxExitCategoryName> exitCat(aProcess->iExitCategory);
+	NKern::UnlockSystem();
+	Kern::KUDesPut(aName,exitCat);
+	}
+
+LOCAL_D const TProcessPriority procPriorityConvertTable[8]=
+	{
+	EPriorityLow,			EPriorityBackground,	EPriorityForeground,	EPriorityHigh,
+	EPriorityWindowServer,	EPriorityFileServer,	EPrioritySupervisor,	EPriorityRealTimeServer
+	};
+
+LOCAL_D const TThreadPriority thrdPriorityConvertTable[8]=
+	{
+	EPriorityMuchLess,	EPriorityMuchLess,	EPriorityLess,		EPriorityNormal,
+	EPriorityMore,		EPriorityMuchMore,	EPriorityRealTime,	EPriorityRealTime
+	};
+
+LOCAL_C TThreadPriority ConvertThreadPriority(TInt p)
+	{
+	switch(p)
+		{
+		case EThrdPriorityAbsoluteVeryLow:
+			return EPriorityAbsoluteVeryLow;
+		case EThrdPriorityAbsoluteLowNormal:
+			return EPriorityAbsoluteLowNormal;
+		case EThrdPriorityAbsoluteLow:
+			return EPriorityAbsoluteLow;
+		case EThrdPriorityAbsoluteBackgroundNormal:
+			return EPriorityAbsoluteBackgroundNormal;
+		case EThrdPriorityAbsoluteBackground:
+			return EPriorityAbsoluteBackground;
+		case EThrdPriorityAbsoluteForegroundNormal:
+			return EPriorityAbsoluteForegroundNormal;
+		case EThrdPriorityAbsoluteForeground:
+			return EPriorityAbsoluteForeground;
+		case EThrdPriorityAbsoluteHighNormal:
+			return EPriorityAbsoluteHighNormal;
+		case EThrdPriorityAbsoluteHigh:
+			return EPriorityAbsoluteHigh;
+		case EThrdPriorityAbsoluteRealTime1:
+			return EPriorityAbsoluteRealTime1;
+		case EThrdPriorityAbsoluteRealTime2:
+			return EPriorityAbsoluteRealTime2;
+		case EThrdPriorityAbsoluteRealTime3:
+			return EPriorityAbsoluteRealTime3;
+		case EThrdPriorityAbsoluteRealTime4:
+			return EPriorityAbsoluteRealTime4;
+		case EThrdPriorityAbsoluteRealTime5:
+			return EPriorityAbsoluteRealTime5;
+		case EThrdPriorityAbsoluteRealTime6:
+			return EPriorityAbsoluteRealTime6;
+		case EThrdPriorityAbsoluteRealTime7:
+			return EPriorityAbsoluteRealTime7;
+		case EThrdPriorityAbsoluteRealTime8:
+			return EPriorityAbsoluteRealTime8;
+		default:
+			if (p>=-8 && p<0)
+				return thrdPriorityConvertTable[p+8];
+		}
+	return EPriorityNormal;
+	}
+
+LOCAL_C TBool ProcessPriorityValid(TProcessPriority p)
+	{
+	switch(p)
+		{
+		case EPriorityLow:
+		case EPriorityBackground:
+		case EPriorityForeground:
+		case EPriorityHigh:
+			return ETrue;
+		default:
+			return EFalse;
+		}
+	}
+
+TProcessPriority ExecHandler::ProcessPriority(DProcess* aProcess)
+//
+// Get the process base priority.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessPriority"));
+	return procPriorityConvertTable[aProcess->iPriority];
+	}
+
+TInt ExecHandler::ProcessSetPriority(DProcess* aProcess, TProcessPriority aPriority)
+//
+// Set the process base priority.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSetPriority"));
+	aProcess->CheckedOpen();
+	DThread& t=*TheCurrentThread;
+	t.iTempObj=aProcess;
+	NKern::UnlockSystem();
+	if (!ProcessPriorityValid(aPriority))
+		K::PanicKernExec(EBadPriority);
+
+	TBool allowed=ETrue;
+	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
+	if (aProcess->iSecurityZone!=currentProcess->iSecurityZone)  // Not self...
+		if (aProcess->iCreatorId!=currentProcess->iId)  // Not creator
+			{
+			TInt processPriority=aProcess->iPriority;
+			if (!(aProcess->iFlags&KProcessFlagPriorityControl)  // No remote control...
+ 				|| (processPriority!=EProcPriorityBackground && processPriority!=EProcPriorityForeground && processPriority!=EProcPriorityHigh)
+				|| (aPriority!=EPriorityBackground && aPriority!=EPriorityForeground && aPriority!=EPriorityHigh) )  // Or not foreground/background/high
+					allowed=!(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation);
+			}
+
+	NKern::ThreadEnterCS();
+	t.iTempObj=NULL;
+	if(allowed)
+		aProcess->SetPriority(aPriority);
+	aProcess->Close(NULL);
+	NKern::ThreadLeaveCS();
+	if (allowed)
+		{
+		return KErrNone;
+		}
+	else
+		{
+		return KErrPermissionDenied;
+		}
+
+	}
+
+
+
+const TUint32 KDefinedProcessFlags=
+	KProcessFlagSystemCritical|
+	KProcessFlagSystemPermanent|
+	KProcessFlagJustInTime|
+	KProcessFlagPriorityControl|
+	KThreadFlagProcessCritical;
+
+const TUint32 KRestrictedProcessFlags =
+		~(KProcessFlagJustInTime|KProcessFlagPriorityControl|KThreadFlagProcessCritical); // All but these are restricted
+
+const TUint32 KSelfOnlyProcessFlags =
+		~0u; // (KProcessFlagJustInTime|KProcessFlagPriorityControl); // Only self can change these
+
+const TUint32 KDefinedThreadFlags=
+	KThreadFlagProcessCritical|
+	KThreadFlagProcessPermanent|
+	KThreadFlagSystemCritical|
+	KThreadFlagSystemPermanent|
+	KThreadFlagLastChance|
+	KThreadFlagRealtime|
+	KThreadFlagRealtimeTest;
+
+const TUint32 KRestrictedThreadFlags =
+		~(KThreadFlagProcessCritical|KThreadFlagProcessPermanent|KThreadFlagLastChance|
+			KThreadFlagRealtime|KThreadFlagRealtimeTest); // All but these are restricted
+
+const TUint32 KSelfOnlyThreadFlags =
+		~0u; // (KThreadFlagProcessCritical|KThreadFlagProcessPermanent|KThreadFlagLastChance); // Only owning process can change these
+
+
+TUint ExecHandler::ProcessFlags(DProcess* aProcess)
+//
+// Get the process flags
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessFlags"));
+	return aProcess->iFlags;
+	}
+
+TUint ExecHandler::ThreadProcessFlags(DThread* aThread)
+//
+// Get the process flags
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcessFlags"));
+	return aThread->iOwningProcess->iFlags;
+	}
+
+void ExecHandler::ProcessSetFlags(DProcess* aProcess, TUint aClearMask, TUint aSetMask)
+//
+// Set the process flags
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSetFlags"));
+
+	TUint flags = aProcess->iFlags;
+	TUint modified = ((flags&~aClearMask)|aSetMask);
+	modified = (modified^flags)&KDefinedProcessFlags;
+
+	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
+
+	if (modified&KSelfOnlyProcessFlags)
+		if(aProcess->iSecurityZone!=currentProcess->iSecurityZone)
+			if(aProcess->iCreatorId!=currentProcess->iId)
+				K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to modify the attributes of another Process. Possibly RProcess::SetSystem."));
+
+	if (modified&KRestrictedProcessFlags)
+		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetProcessCritical (or RProcess::SetSystem)")))
+			K::LockedPlatformSecurityPanic();
+
+	aProcess->iFlags=flags^modified;
+
+	// if flags altered before resume, original thread inherits system critical and
+	// process critical from process.
+	if (!(aProcess->iAttributes & DProcess::EResumed))
+		{
+		TUint32& tf = aProcess->FirstThread()->iFlags;
+		tf = (tf &~ (KThreadFlagSystemCritical|KThreadFlagProcessCritical)) |
+			(aProcess->iFlags & (KThreadFlagSystemCritical|KThreadFlagProcessCritical));
+		}
+	}
+
+TInt ExecHandler::SemaphoreWait(DSemaphore* aSemaphore, TInt aTimeout)
+//
+// Wait for a signal.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreWait"));
+	if (aTimeout)
+		{
+		if (aTimeout<0)
+			{
+			NKern::UnlockSystem();
+			return KErrArgument;
+			}
+
+		// Convert microseconds to NTimer ticks, rounding up
+		TInt ntp = NKern::TickPeriod();
+		aTimeout += ntp-1;
+		aTimeout /= ntp;
+		}
+	return aSemaphore->Wait(aTimeout);
+	}
+
+void ExecHandler::SemaphoreSignal1(DSemaphore* aSemaphore)
+//
+// Signal the semaphore once.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreSignal1"));
+	aSemaphore->Signal();
+	}
+
+void ExecHandler::SemaphoreSignalN(DSemaphore* aSem, TInt aCount)
+//
+// Signal the semaphore aCount times.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreSignalN"));
+	aSem->CheckedOpen();
+	NKern::ThreadEnterCS();
+	aSem->SignalN(aCount);
+	NKern::UnlockSystem();
+	aSem->Close(NULL);
+	NKern::ThreadLeaveCS();
+	}
+
+TInt ExecHandler::ThreadId(DThread* aThread)
+//
+// Get thread ID.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadId"));
+	return (TInt)aThread->iId;
+	}
+	
+LOCAL_C TBool IsThreadPriorityAbsoluteRealTime(TThreadPriority p)
+//
+// Returns true if priority is an absolute "real time" thread priority.
+//
+	{
+	switch(p)
+		{
+		case EPriorityAbsoluteRealTime1:
+		case EPriorityAbsoluteRealTime2:
+		case EPriorityAbsoluteRealTime3:
+		case EPriorityAbsoluteRealTime4:
+		case EPriorityAbsoluteRealTime5:
+		case EPriorityAbsoluteRealTime6:
+		case EPriorityAbsoluteRealTime7:
+		case EPriorityAbsoluteRealTime8:
+			return ETrue;
+		default:
+			return EFalse;
+		}
+	}
+
+void ExecHandler::ThreadResume(DThread* aThread)
+//
+// Resume a thread.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadResume"));
+	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Use of RThread::Resume on a thread in another process"));
+	aThread->Resume();
+	}
+
+TThreadPriority ExecHandler::ThreadPriority(DThread* aThread)
+//
+// Get the threads priority.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadPriority"));
+	return ConvertThreadPriority(aThread->iThreadPriority);
+	}
+
+void ExecHandler::ThreadSetPriority(DThread* aThread,TThreadPriority aPriority)
+//
+// Set the threads priority.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSetPriority"));
+	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Use of RThread::SetPriority on a thread in a different process"));
+	if(IsThreadPriorityAbsoluteRealTime(aPriority) && 
+	   !(TheCurrentThread->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::SetPriority"))))
+		K::LockedPlatformSecurityPanic();
+	else
+		aThread->SetPriority(aPriority);
+	}
+
+TProcessPriority ExecHandler::ThreadProcessPriority(DThread* aThread)
+//
+// Get the owning process's priority.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcessPriority"));
+	return procPriorityConvertTable[aThread->iOwningProcess->iPriority];
+	}
+
+void ExecHandler::ThreadSetProcessPriority(DThread* aThread, TProcessPriority aPriority)
+//
+// Set the owning process's priority.
+//
+	{
+	ExecHandler::ProcessSetPriority(aThread->iOwningProcess,aPriority);
+	}
+
+TUint ExecHandler::ThreadFlags(DThread* aThread)
+//
+// Get the threads flag state.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadFlags"));
+	return(aThread->iFlags);
+	}
+
+void ExecHandler::ThreadSetFlags(DThread* aThread,TUint aClearMask,TUint aSetMask)
+//
+// Set the thread flags
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSetFlags"));
+	TUint flags = aThread->iFlags;
+	TUint modified = ((flags&~aClearMask)|aSetMask);
+	modified = (modified^flags)&KDefinedThreadFlags;
+
+	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
+
+	if (modified&KSelfOnlyThreadFlags)
+		if(aThread->iOwningProcess->iSecurityZone!=currentProcess->iSecurityZone)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to modify attributes of a thread in another process. Possibly RThread::SetSystem"));
+
+	if (modified&KRestrictedThreadFlags)
+		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetCritical (or RThread::SetSystem)")))
+			K::LockedPlatformSecurityPanic();
+
+	aThread->iFlags=flags^modified;
+	}
+
+TExitType ExecHandler::ThreadExitType(DThread* aThread)
+//
+// Return the exit type.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitType"));
+	return (TExitType)aThread->iExitType;
+	}
+
+TInt ExecHandler::ThreadExitReason(DThread* aThread)
+//
+// Return the exit reason.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitReason"));
+	return aThread->iExitReason;
+	}
+
+void ExecHandler::ThreadExitCategory(DThread* aThread, TDes8& aName)
+//
+// Return the category of the exit type.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitCategory"));
+	TBufC<KMaxExitCategoryName> exitCat(aThread->iExitCategory);
+	NKern::UnlockSystem();
+	Kern::KUDesPut(aName,exitCat);
+	}
+
+void ExecHandler::ThreadRequestSignal(DThread* aThread)
+//
+// Signal a request completion.
+// Enter with system locked, return with system unlocked.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRequestSignal"));
+	if(aThread->iOwningProcess!=TheCurrentThread->iOwningProcess)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to use RThread::RequestComplete on a thread in another process"));
+	NKern::ThreadRequestSignal(&aThread->iNThread, SYSTEM_LOCK);
+	}
+
+TInt ExecHandler::FindHandleOpen(TOwnerType aType, const TFindHandle& aFindHandle)
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::FindHandleOpen"));
+	TFindHandle fh;
+	kumemget32(&fh,&aFindHandle,sizeof(fh));
+	NKern::ThreadEnterCS();
+	TInt h;
+	TInt r=TheCurrentThread->OpenFindHandle(aType,fh,h);
+	if(r==KErrNone)
+		r = h;
+	NKern::ThreadLeaveCS();
+	if (r==KErrBadHandle)
+		K::PanicKernExec(EBadHandle);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::FindHandleOpen returns %d",r));
+	return r;
+	}
+
+TInt ExecHandler::HandleClose(TInt aHandle)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleClose %08x",aHandle));
+	NKern::ThreadEnterCS();
+	TInt r=K::HandleClose(aHandle);
+	NKern::ThreadLeaveCS();
+	if (r==KErrBadHandle)
+		K::PanicKernExec(EBadHandle);
+	else if (r==DObject::EObjectUnmapped)
+		TheCurrentThread->iOwningProcess->WaitDllLock();
+	return r;
+	}
+
+TInt ExecHandler::LastThreadHandle()
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LastThreadHandle"));
+	DThread& t=*TheCurrentThread;
+	NKern::ThreadEnterCS();
+	RObjectIx::Wait();
+	TInt r=t.iHandles.LastHandle();
+	RObjectIx::Signal();
+	NKern::ThreadLeaveCS();
+	if (r)
+		r|=KHandleFlagLocal;
+	return r;
+	}
+
+TInt ExecHandler::ChunkCreate(TOwnerType aType, const TDesC8* aName, TChunkCreate& anInfo)
+	{
+	TKName n;
+	if (aName)
+		Kern::KUDesGet(n,*aName);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkCreate %lS",&n));
+	TChunkCreate uinfo;
+	SChunkCreateInfo info;
+	kumemget32(&uinfo,&anInfo,sizeof(uinfo));
+	info.iGlobal=uinfo.iAtt & TChunkCreate::EGlobal;
+	info.iAtt = uinfo.iAtt&TChunkCreate::EChunkCreateAttMask;
+	info.iForceFixed=uinfo.iForceFixed;
+	info.iOperations=SChunkCreateInfo::EAdjust;	// adjust but don't add to process
+	info.iRunAddress=0;
+	info.iType=(uinfo.iAtt & TChunkCreate::ECode) ? EUserSelfModCode : EUserData;
+	info.iMaxSize=uinfo.iMaxSize;
+	info.iInitialBottom=uinfo.iInitialBottom;
+	info.iInitialTop=uinfo.iInitialTop;
+	info.iPreallocated=0;
+	info.iClearByte = uinfo.iClearByte;
+	DThread* pT=TheCurrentThread;
+	DProcess* pP=pT->iOwningProcess;
+	if (aName)
+		info.iName.Set(n);
+	else
+		info.iName.Set(NULL,0);
+	if (!info.iGlobal)
+		info.iOwner=(aType==EOwnerThread)?(DObject*)pT:(DObject*)pP;
+	else
+		info.iOwner=NULL;
+	NKern::ThreadEnterCS();
+	DChunk* pC=NULL;
+	TLinAddr addr;
+	TInt r=pP->NewChunk(pC,info,addr);
+	if (r==KErrNone)
+		r=K::MakeHandle(aType,pC);	// this will add the chunk to the process
+	if (r<KErrNone && pC)
+		pC->Close(NULL);				// can't have been added so NULL
+	NKern::ThreadLeaveCS();
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ChunkCreate returns %d",r));
+	return r;
+	}
+
+TInt ExecHandler::ChunkSetRestrictions(DChunk* aChunk, TUint aRestrictions)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkSetRestrictions %O flags=%x",aChunk,aRestrictions));
+	if(aChunk->iControllingOwner!=TheCurrentThread->iOwningProcess->iId)
+		return KErrAccessDenied;
+	aChunk->iRestrictions = aRestrictions;
+	return KErrNone;
+	}
+
+TInt ExecHandler::ChunkAdjust(DChunk* aChunk, TInt aType, TInt a1, TInt a2)
+	{
+	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ChunkAdjust %O type %d a1=%x a2=%x",aChunk,aType,a1,a2));
+	aChunk->CheckedOpen();
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	TInt r=KErrNone;
+	TInt s=aChunk->CheckAccess();
+	if (s!=KErrNone)
+		goto done;
+	if((aChunk->iRestrictions&EChunkPreventAdjust) && (aChunk->iControllingOwner!=TheCurrentThread->iOwningProcess->iId))
+		{
+		r=KErrAccessDenied;
+		goto done;
+		}
+	switch (aType)
+		{
+		case EChunkAdjust:
+			r=aChunk->Adjust(a1);
+			break;
+		case EChunkAdjustDoubleEnded:
+			r=aChunk->AdjustDoubleEnded(a1,a2);
+			break;
+		case EChunkCommit:
+			r=aChunk->Commit(a1,a2);
+			break;
+		case EChunkDecommit:
+			r=aChunk->Decommit(a1,a2);
+			break;
+		case EChunkAllocate:
+			r=aChunk->Allocate(a1);
+			break;
+		case EChunkLock:
+			if(&Kern::CurrentProcess()!=aChunk->iOwningProcess)
+				r = KErrAccessDenied;	
+			else
+				r=aChunk->Lock(a1,a2);
+			break;
+		case EChunkUnlock:
+			if(&Kern::CurrentProcess()!=aChunk->iOwningProcess)
+				r = KErrAccessDenied;	
+			else
+				r=aChunk->Unlock(a1,a2);
+			break;
+		default:
+			r=KErrArgument;
+			break;
+		}
+done:
+	aChunk->Close(NULL);		// NULL because we didn't up the process access count
+	NKern::ThreadLeaveCS();
+	if (s!=KErrNone)
+		K::PanicKernExec(EAccessDenied);
+	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ChunkAdjust returns %d",r));
+	return r;
+	}
+
+
+/**
+@return ETrue if the chunk is data paged, EFalse otherwise.
+*/
+TBool ExecHandler::ChunkIsPaged(DChunk* aChunk)
+	{
+	return (aChunk->iAttributes & DChunk::EDataPaged) != 0;
+	}
+
+
+/**
+@return ETrue if the process is data paged, EFalse otherwise.
+*/
+TBool ExecHandler::ProcessDefaultDataPaged(DProcess* aProcess)
+	{
+	return (aProcess->iAttributes & DProcess::EDataPaged) != 0;
+	}
+
+
+
+TInt ExecHandler::OpenObject(TObjectType aObjType, const TDesC8& aName, TOwnerType aType)
+	{
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::OpenObject %lS",&aName));
+	TFullName n;
+	Kern::KUDesGet(n,aName);
+	if (Kern::ValidateFullName(n)!=KErrNone)
+		K::PanicKernExec(EBadName);
+	if ((TUint)aObjType>=(TUint)ENumObjectTypes)
+		K::PanicKernExec(EBadObjectType);
+	TInt h=0;
+	DObject* pO=NULL;
+	NKern::ThreadEnterCS();
+	TInt r=TheCurrentThread->OpenObject(aType,n,h,pO,aObjType);
+	NKern::ThreadLeaveCS();
+	if(r==KErrNone)
+		r = h;
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::OpenObject returns %d",r));
+	return r;
+	}
+
+
+TInt ExecHandler::HandleDuplicate(TInt aThreadHandle, TOwnerType aType, TInt& aHandle)
+	{
+	TInt h;
+	kumemget32(&h, &aHandle, sizeof(h));
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate %08x", h));
+	DThread* pC=TheCurrentThread;
+	NKern::LockSystem();
+	DThread* pT=(DThread*)K::ThreadEnterCS(aThreadHandle,EThread);
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate source thread %O",pT));
+	TInt r=KErrBadHandle;
+	NKern::LockSystem();
+	DObject* pO=pT->ObjectFromHandle(h);
+	h = 0;	// now holds value to be returned
+	if (pO)
+		r=pO->Open();
+	NKern::UnlockSystem();
+	if (r==KErrNone)
+		{
+		if (pO->Protection()!=DObject::EGlobal
+			&& pT->iOwningProcess->iSecurityZone!=pC->iOwningProcess->iSecurityZone)
+			{
+#ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
+			r = PlatSec::ProcessIsolationFail(__PLATSEC_DIAGNOSTIC_STRING("Checked by RHandleBase::Duplicate"));
+#else //__REMOVE_PLATSEC_DIAGNOSTICS__
+			r = PlatSec::EmitDiagnostic();
+#endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
+			}
+		if (r==KErrNone)
+			r = pC->MakeHandle(aType, pO, h);	// this will add to process if necessary
+		if (r<KErrNone)
+			pO->Close(NULL);	// can't have been added to process so NULL
+		}
+	pT->Close(NULL);
+	TInt s = KErrNone;
+	XTRAP(s, XT_DEFAULT, kumemput32(&aHandle, &h, sizeof(h)));
+	if (s!=KErrNone && r==KErrNone)
+		pC->HandleClose(h);
+	NKern::ThreadLeaveCS();
+	if (r == KErrBadHandle)
+		K::PanicKernExec(EBadHandle);
+	if (s != KErrNone)
+		K::PanicKernExec(ECausedException);
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate returns %d",r));
+	return r;
+	}
+
+TInt ExecHandler::MutexCreate(const TDesC8* aName, TOwnerType aType)
+	{
+	TKName n;
+	DObject* pO=NULL;
+	const TDesC* pN=NULL;
+	if (aName)
+		{
+		Kern::KUDesGet(n,*aName);
+		pN=&n;
+		}
+	else if (aType==EOwnerThread)
+		pO=TheCurrentThread;
+	else
+		pO=TheCurrentThread->iOwningProcess;
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::MutexCreate %lS",aName));
+	NKern::ThreadEnterCS();
+	DMutex* pM;
+	TInt r=K::MutexCreate(pM, *pN, pO, ETrue, KMutexOrdUser);
+	if (r==KErrNone)
+		{
+		if(aName)
+			pM->SetProtection(n.Length()? DObject::EGlobal : DObject::EProtected);
+		r=K::MakeHandle(aType,pM);
+		if (r<KErrNone)
+			pM->Close(NULL);
+		}
+	NKern::ThreadLeaveCS();
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::MutexCreate returns %d",r));
+	return r;
+	}
+
+TInt ExecHandler::SemaphoreCreate(const TDesC8* aName, TInt aCount, TOwnerType aType)
+	{
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::SemaphoreCreate %lS",aName));
+	TKName n;
+	DObject* pO=NULL;
+	const TDesC* pN=NULL;
+	if (aName)
+		{
+		Kern::KUDesGet(n,*aName);
+		pN=&n;
+		}
+	else if (aType==EOwnerThread)
+		pO=TheCurrentThread;
+	else
+		pO=TheCurrentThread->iOwningProcess;
+	NKern::ThreadEnterCS();
+	TInt r=KErrNoMemory;
+	DSemaphore* pS=new DSemaphore;
+	if (pS)
+		r=pS->Create(pO,pN,aCount);
+	if (r==KErrNone)
+		{
+		if(aName)
+			pS->SetProtection(n.Length()? DObject::EGlobal : DObject::EProtected);
+		r=K::MakeHandle(aType,pS);
+		}
+	if (r<KErrNone && pS)
+		pS->Close(NULL);
+	NKern::ThreadLeaveCS();
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::SemaphoreCreate returns %d",r));
+	return r;
+	}
+
+LOCAL_C TInt OpenById(TUint anId, TOwnerType aType, TBool aProcess)
+	{
+	NKern::ThreadEnterCS();
+	TInt type=aProcess?EProcess:EThread;
+	DObjectCon* pC=K::Containers[type];
+	pC->Wait();
+	DObject* pO=aProcess?(DObject*)Kern::ProcessFromId(anId):(DObject*)Kern::ThreadFromId(anId);
+	TInt r=KErrNotFound;
+	if (pO && (r=pO->Open())==KErrNone)
+		{
+		pC->Signal();	// must release this before opening handle
+		DProcess* pP;
+		if(aProcess)
+			pP=(DProcess*)pO;
+		else
+			pP=((DThread*)pO)->iOwningProcess;
+
+		if( pO->Protection()!=DObject::EGlobal
+			&& pP->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+			{
+#ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
+			r = PlatSec::ProcessIsolationFail(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Open(TThreadId)"));
+#else //__REMOVE_PLATSEC_DIAGNOSTICS__
+			r = PlatSec::EmitDiagnostic();
+#endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
+			}
+		if (r==KErrNone)
+			r=K::MakeHandle(aType,pO);
+		if (r<KErrNone)
+			pO->Close(NULL);
+		}
+	else
+		pC->Signal();
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+TInt ExecHandler::ThreadOpenById(TUint anId, TOwnerType aType)
+	{
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ThreadOpenById %d",anId));
+	TInt r=OpenById(anId,aType,EFalse);
+	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ThreadOpenById returns %d",r));
+	return r;
+	}
+
+TInt ExecHandler::ProcessOpenById(TUint anId, TOwnerType aType)
+	{
+	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ProcessOpenById %d",anId));
+	TInt r=OpenById(anId,aType,ETrue);
+	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ProcessOpenById returns %d",r));
+	return r;
+	}
+
+// Enter with system locked, return with system unlocked
+void ExecHandler::ThreadLogon(DThread* aThread, TRequestStatus* aStatus, TBool aRendezvous)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadLogon"));
+	aThread->CheckedOpen();
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	TInt r=aThread->Logon(aStatus,aRendezvous);
+	if (r!=KErrNone)
+		{
+		if (r==KErrDied)
+			r=aThread->iExitReason;
+		Kern::RequestComplete(aStatus,r);
+		}
+	aThread->Close(NULL);
+	NKern::ThreadLeaveCS();
+	}
+
+// Enter with system locked, return with system unlocked
+TInt ExecHandler::ThreadLogonCancel(DThread* aThread, TRequestStatus* aStatus, TBool aRendezvous)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadLogonCancel"));
+	aThread->CheckedOpen();
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	DThread& t = *TheCurrentThread;
+	TUint32 type = TLogon::ETargetThread;
+	if (aRendezvous)
+		type |= TLogon::ERendezvous;
+	TInt r = TLogon::Cancel(t.iOwnedLogons, aThread, aStatus, type);
+	aThread->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+// Enter with system locked, return with system unlocked
+void ExecHandler::ProcessLogon(DProcess* aProcess, TRequestStatus* aStatus, TBool aRendezvous)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessLogon"));
+	aProcess->CheckedOpen();
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	TInt r=aProcess->Logon(aStatus,aRendezvous);
+	if (r!=KErrNone)
+		{
+		if (r==KErrDied)
+			r=aProcess->iExitReason;
+		Kern::RequestComplete(aStatus,r);
+		}
+	aProcess->Close(NULL);
+	NKern::ThreadLeaveCS();
+	}
+
+// Enter with system locked, return with system unlocked
+TInt ExecHandler::ProcessLogonCancel(DProcess* aProcess, TRequestStatus* aStatus, TBool aRendezvous)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessLogonCancel"));
+	aProcess->CheckedOpen();
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	DThread& t = *TheCurrentThread;
+	TUint32 type = TLogon::ETargetProcess;
+	if (aRendezvous)
+		type |= TLogon::ERendezvous;
+	TInt r = TLogon::Cancel(t.iOwnedLogons, aProcess, aStatus, type);
+	aProcess->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+TAny* ExecHandler::DllTls(TInt aHandle, TInt aDllUid)
+	{
+	// no protection needed since only this thread can access the TLS array
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllTls"));
+#ifndef __EPOC32__
+	extern TInt LookupDllUid(TInt);
+
+	if (aDllUid == KDllUid_Special)
+		aDllUid = LookupDllUid(aHandle);
+#endif
+	return TheCurrentThread->Tls(aHandle,aDllUid);
+	}
+
+TInt ExecHandler::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllSetTls %08x->%08x", aHandle, aPtr));
+#ifndef __EPOC32__
+	extern TInt LookupDllUid(TInt);
+
+	if (aDllUid == KDllUid_Special)
+		aDllUid = LookupDllUid(aHandle);
+#endif
+	NKern::ThreadEnterCS();
+	TInt r=TheCurrentThread->SetTls(aHandle,aDllUid,aPtr);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+void ExecHandler::DllFreeTls(TInt aHandle)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllFreeTls"));
+	NKern::ThreadEnterCS();
+	TheCurrentThread->FreeTls(aHandle);
+	NKern::ThreadLeaveCS();
+	}
+
+TInt ExecHandler::ThreadRename(TInt aHandle, const TDesC8& aName)
+	{
+	TKName n;
+	Kern::KUDesGet(n,aName);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRename %lS",&n));
+	NKern::LockSystem();
+	DThread* pT=(DThread*)K::ThreadEnterCS(aHandle,EThread);
+	if (pT!=TheCurrentThread &&
+		pT->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		{
+		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
+			{
+			pT->Close(NULL);
+			K::ThreadLeaveCS();
+			}
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Rename"));
+		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
+			Kern::Fault("ThreadRename",0);
+		}
+	TInt r=pT->Rename(n);
+	pT->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+TInt ExecHandler::ProcessRename(TInt aHandle, const TDesC8& aName)
+	{
+	TKName n;
+	Kern::KUDesGet(n,aName);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessRename %lS",&n));
+	NKern::LockSystem();
+	DProcess* pP=(DProcess*)K::ThreadEnterCS(aHandle,EProcess);
+	if (pP->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		{
+		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
+			{
+			pP->Close(NULL);
+			K::ThreadLeaveCS();
+			}
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::Rename"));
+		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
+			Kern::Fault("ProcessRename",0);
+		}
+	TInt r=pP->Rename(n);
+	pP->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+TInt ExecHandler::ThreadProcess(DThread* aThread)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcess"));
+	DProcess* pP=aThread->iOwningProcess;
+	pP->Open();	// can't get an error here
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	TInt r=K::MakeHandle(EOwnerThread,pP);
+	if (r<KErrNone)
+		pP->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+RAllocator* ExecHandler::ThreadGetHeap(DThread* aThread)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadGetHeap %O",aThread));
+	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
+		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Heap"));
+	return aThread->iAllocator;
+	}
+
+void ExecHandler::HandleName(TInt aHandle, TDes8& aName)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleName"));
+	DObject* pO=NULL;
+	TInt r=K::OpenObjectFromHandle(aHandle,pO);
+	if (r!=KErrNone)
+		K::PanicKernExec(EBadHandle);
+	TKName n;
+	pO->Name(n);
+	pO->Close(NULL);
+	NKern::ThreadLeaveCS();
+	Kern::KUDesPut(aName,n);
+	}
+
+void ExecHandler::HandleFullName(TInt aHandle, TDes8& aFullName)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleFullName"));
+	DObject* pO=NULL;
+	TInt r=K::OpenObjectFromHandle(aHandle,pO);
+	if (r!=KErrNone)
+		K::PanicKernExec(EBadHandle);
+	TFullName n;
+	pO->FullName(n);
+	pO->Close(NULL);
+	NKern::ThreadLeaveCS();
+	Kern::KUDesPut(aFullName,n);
+	}
+
+void ExecHandler::HandleCount(DThread* aThread, TInt& aProcessHandleCount, TInt& aThreadHandleCount)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleCount"));
+	TInt tCount=aThread->iHandles.ActiveCount();
+	TInt pCount=aThread->iOwningProcess->iHandles.ActiveCount();
+	NKern::UnlockSystem();
+	kumemput32(&aProcessHandleCount,&pCount,sizeof(pCount));
+	kumemput32(&aThreadHandleCount,&tCount,sizeof(tCount));
+	}
+
+TInt ExecHandler::GetBTraceId(DObject* aObj)
+//
+// Get the BTraceID of any given RHandleBase-derived object. In practice
+// this ID is simply a pointer to the associated DObject.
+//
+	{
+	return (TInt)aObj;
+	}
+
+void ExecHandler::HandleInfo(TInt aHandle, THandleInfo* anInfo)
+//
+// Find out how many threads and processes have an open handle on the object given by 
+// a handle, and whether it's open in this process and thread.
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleInfo"));
+	THandleInfo hinfo;
+	memclr(&hinfo, sizeof(hinfo));
+	DObject* pO=NULL;
+	TInt r=K::OpenObjectFromHandle(aHandle,pO);
+	if (r==KErrNone)
+		{
+		RObjectIx::Wait();
+		DProcess* pCurrentProcess=TheCurrentThread->iOwningProcess;
+		hinfo.iNumOpenInThread=TheCurrentThread->iHandles.Count(pO);
+		hinfo.iNumOpenInProcess=pCurrentProcess->iHandles.Count(pO);
+
+		DObjectCon& threads=*K::Containers[EThread];
+		threads.Wait();
+		TInt c=threads.Count();
+		TInt i=0;
+		for (;i<c;i++)
+			{
+			DThread *pT=(DThread *)threads[i];
+			TInt r=pT->iHandles.At(pO);
+			if (r!=KErrNotFound)
+				{
+				++hinfo.iNumThreads;
+				if (pT->iOwningProcess==pCurrentProcess)
+					++hinfo.iNumOpenInProcess;
+				}
+			}
+		threads.Signal();
+		DObjectCon& processes=*K::Containers[EProcess];
+		processes.Wait();
+		c=processes.Count();
+		for (i=0;i<c;i++)
+			{
+			DProcess *pP=(DProcess *)processes[i];
+			TInt r=pP->iHandles.At(pO);
+			if (r!=KErrNotFound)
+				++hinfo.iNumProcesses;
+			}
+		processes.Signal();
+		RObjectIx::Signal();
+		pO->Close(NULL);
+		NKern::ThreadLeaveCS();
+		}
+	kumemput32(anInfo,&hinfo,sizeof(hinfo));
+	}
+
+TUint ExecHandler::HandleAttributes(TInt /*aHandle*/)
+	{
+	// NOT YET IMPLEMENTED
+	return 0x0f;
+	}
+
+TLibraryFunction ExecHandler::LibraryLookup(TInt aLibraryHandle, TInt aOrdinal)
+	{
+	TLibraryFunction f = NULL;
+	NKern::LockSystem();
+
+XTRAP_PAGING_RETRY(
+	DLibrary* library = (DLibrary*)K::ObjectFromHandle(aLibraryHandle,ELibrary);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryLookup %O %d",library,aOrdinal));
+	DCodeSeg* pS = library->iCodeSeg;
+	if(pS)
+		f = pS->Lookup(aOrdinal);
+)
+	NKern::UnlockSystem();
+	return f;
+	}
+
+/**
+Retrieves pointer to the named symbol export data, if present.
+	
+@param aProcessHandle Handle to the process whose code seg to search
+@return	Pointer to named symbol export data if its present, NULL otherwise
+@internalComponent
+*/
+TAny* ExecHandler::ProcessExeExportData(void)
+	{
+	DProcess* pP = &Kern::CurrentProcess();
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExeExportData %O",pP));
+	DCodeSeg* pS = pP->CodeSeg();	// can't be null if process is running
+	
+	// Lookup() returns NULL if this is not a stdexe/stddll
+	return (TAny*)pS->Lookup(0);
+	}
+
+void ExecHandler::LibraryType(DLibrary* aLibrary, TUidType& aUids)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryType"));
+	TUidType uids;
+	memclr(&uids, sizeof(uids));
+	DCodeSeg* pS=aLibrary->iCodeSeg;
+	if (pS)
+		uids=pS->iUids;
+	__KTRACE_OPT(KEXEC,Kern::Printf("UIDS: %08x,%08x,%08x",uids.iUid[0],uids.iUid[1],uids.iUid[2]));
+	NKern::UnlockSystem();
+	kumemput32(&aUids,&uids,sizeof(TUidType));
+	}
+
+void ExecHandler::LibraryFileName(DLibrary* aLibrary, TDes8& aFileName)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryFileName"));
+	TFileName fn;
+	DCodeSeg* pS=aLibrary->iCodeSeg;
+	if (pS)
+		pS->AppendFullFileName(fn);
+	NKern::UnlockSystem();
+	P::NormalizeExecutableFileName(fn);
+	Kern::KUDesPut(aFileName, fn);
+	}
+
+TInt ExecHandler::HalFunction(TInt aGroup, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	TInt aDeviceNumber = TUint(aGroup)>>16;
+	aGroup=aGroup&0xffff;
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HalFunction(%d,%d,%08x,%08x,%d)",aGroup,aFunction,a1,a2,aDeviceNumber));
+	TInt r=KErrNotSupported;
+	if(TUint(aDeviceNumber)>=TUint(KMaxHalEntries))
+		return r;
+	if (aGroup>=0 && aGroup<KMaxHalGroups)
+		{
+		SHalEntry2* pE=&K::HalEntryArray[aGroup];
+		SHalEntry* pBase=(SHalEntry*)pE;
+		THalFunc f=NULL;
+		TAny* p=NULL;
+		if(aDeviceNumber>0)
+			{
+			if(!pE->iExtendedEntries)
+				return r;
+			pBase=pE->iExtendedEntries + (aDeviceNumber-1);
+			}
+		NKern::LockSystem();
+		f=pBase->iFunction;
+		p=pBase->iPtr;
+		NKern::UnlockSystem();
+		if (f)
+			r=(*f)(p,aFunction,a1,a2);
+		}
+	return r;
+	}
+
+TUint32 ExecHandler::DebugMask()
+	{
+	return TheSuperPage().iDebugMask[0];
+	}
+
+TUint32 ExecHandler::DebugMaskIndex(TUint aIndex)
+ 	{
+	if (aIndex >= (TUint)KNumTraceMaskWords) 
+		return 0;	
+	else
+		return TheSuperPage().iDebugMask[aIndex];
+	}
+
+void ExecHandler::SetDebugMask(TUint32 aVal)
+	{
+	TheSuperPage().iDebugMask[0]=(TInt)aVal;
+	}
+
+void ExecHandler::SetDebugMaskIndex(TUint32 aVal, TUint aIndex)
+	{
+	if (aIndex >= (TUint)KNumTraceMaskWords) return;
+	
+	// check that we have permission to set KALLTHREADSSYSTEM bit
+	if (aIndex == DEBUGMASKWORD2 && (aVal & (1 << (KALLTHREADSSYSTEM%32))))
+		{
+		DProcess* currentProcess=TheCurrentThread->iOwningProcess;
+		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetDebugMask(TUint32, TUint)")))
+			K::UnlockedPlatformSecurityPanic();
+		}
+
+	TheSuperPage().iDebugMask[aIndex]=(TInt)aVal;
+	}
+
+RAllocator* ExecHandler::HeapSwitch(RAllocator* aA)
+	{
+	DThread* pT = TheCurrentThread;
+	RAllocator* pA = pT->iAllocator;
+	pT->iAllocator = aA;
+	if (!pT->iCreatedAllocator)
+		pT->iCreatedAllocator = aA;
+	return pA;
+	}
+
+void ExecHandler::KernelHeapDebug(TInt aFunction, TInt a1, TAny* a2)
+	{
+	(void)aFunction;
+	(void)a1;
+	(void)a2;
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::KernelHeapDebug %d,%08x,%08x",aFunction,a1,a2));
+#ifdef _DEBUG
+	TInt panic=KMinTInt;
+	switch (aFunction)
+		{
+		case EDbgMarkStart:
+			NKern::ThreadEnterCS();
+			K::Allocator->__DbgMarkStart();
+			NKern::ThreadLeaveCS();
+			break;
+
+		case EDbgMarkCheck:
+			{
+			TBuf8<KMaxFileName> name;
+			TKernelHeapMarkCheckInfo info;
+			kumemget32(&info,a2,sizeof(info));
+			Kern::KUDesGet(name,*info.iFileName);
+			NKern::ThreadEnterCS();
+			TInt r = K::Allocator->__DbgMarkCheck(info.iCountAll, a1, name, info.iLineNum);
+			if (r!=KErrNone)
+				panic=EFailedKernelHeapCheck;
+			NKern::ThreadLeaveCS();
+			break;
+			}
+
+		case EDbgMarkEnd:
+			{
+			NKern::ThreadEnterCS();
+			TInt r = K::Allocator->__DbgMarkEnd(a1);
+			if (r!=KErrNone)
+				panic=EFailedKernelHeapCheck;
+			NKern::ThreadLeaveCS();
+			break;
+			}
+
+		case EDbgSetAllocFail:
+			NKern::ThreadEnterCS();
+			K::Allocator->__DbgSetAllocFail((RAllocator::TAllocFail)a1,(TInt)a2);
+			NKern::ThreadLeaveCS();
+			break;
+
+		case EDbgSetBurstAllocFail:
+			{
+			SRAllocatorBurstFail burstFail;
+			kumemget32(&burstFail, a2, sizeof(SRAllocatorBurstFail));
+			NKern::ThreadEnterCS();
+			K::Allocator->__DbgSetBurstAllocFail((RAllocator::TAllocFail)a1, burstFail.iRate, burstFail.iBurst);
+			NKern::ThreadLeaveCS();
+			break;
+			}
+
+		case EDbgCheckFailure:
+			{
+			NKern::ThreadEnterCS();
+			TUint failures = K::Allocator->__DbgCheckFailure();
+			NKern::ThreadLeaveCS();
+			kumemput32(a2, (TAny*)&failures, sizeof(TUint));
+			break;
+			}
+
+		default:
+			panic=EBadKernelHeapDebugFunction;
+			break;
+		}
+	if (panic>KMinTInt)
+		K::PanicKernExec(panic);
+#endif
+	}
+
+TExceptionHandler ExecHandler::ExceptionHandler(DThread* aThread)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ExceptionHandler"));
+	if(aThread!=TheCurrentThread)
+		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::ExceptionHandler"));
+	return aThread->iExceptionHandler;
+	}
+
+TInt ExecHandler::SetExceptionHandler(DThread* aThread, TExceptionHandler aHandler, TUint32 aMask)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetExceptionHandler"));
+	if(aThread!=TheCurrentThread)
+		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::SetExceptionHandler"));
+	aThread->iExceptionHandler=aHandler;
+	aThread->iExceptionMask=aMask;
+	return KErrNone;
+	}
+
+void ExecHandler::ModifyExceptionMask(DThread* aThread, TUint32 aClearMask, TUint32 aSetMask)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ModifyExceptionMask"));
+	if(aThread!=TheCurrentThread)
+		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::ModifyExceptionMask"));
+	TUint& m=aThread->iExceptionMask;
+	m=(m&~aClearMask)|aSetMask;
+	}
+
+TInt ExecHandler::RaiseException(DThread* aThread, TExcType aType)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RaiseException %d on %O",aType,aThread));
+	if(aThread!=TheCurrentThread)
+		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::RaiseException"));
+	return aThread->RaiseException(aType);
+	}
+
+TBool ExecHandler::IsExceptionHandled(DThread* aThread,TExcType aType, TBool aSwExcInProgress)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::IsExceptionHandled %d %d",aType,aSwExcInProgress));
+	if(aThread!=TheCurrentThread)
+		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
+			)
+			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::IsExceptionHandled"));
+	TBool isHandled=aThread->IsExceptionHandled(aType);
+	NKern::UnlockSystem();
+	if (aSwExcInProgress)
+		DKernelEventHandler::Dispatch(EEventSwExc, (TAny*)aType, NULL);
+	return isHandled;
+	}
+
+void ExecHandler::ThreadContext(DThread* aThread, TDes8& aDes)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadContext %O",aThread));
+	TBuf8<KMaxThreadContext> c;
+	aThread->Context(c);
+	NKern::UnlockSystem();
+	Kern::InfoCopy(aDes,c);
+	}
+
+TInt ExecHandler::ThreadStackInfo(DThread* aThread, TThreadStackInfo& aInfo)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadStackInfo %O",aThread));
+	TThreadStackInfo info;
+	memclr(&info, sizeof(info));
+	TInt r=KErrGeneral;
+	if(aThread->iUserStackRunAddress)
+		{
+		info.iBase = aThread->iUserStackRunAddress+aThread->iUserStackSize;
+		info.iLimit = aThread->iUserStackRunAddress;
+		info.iExpandLimit = aThread->iUserStackRunAddress;
+		r = KErrNone;
+		}
+	NKern::UnlockSystem();
+	kumemput32(&aInfo,&info,sizeof(info));
+	return r;
+	}
+
+TInt ExecHandler::ProcessGetMemoryInfo(TInt aProcessHandle, TModuleMemoryInfo& aInfo)
+	{
+	TModuleMemoryInfo info;
+	memclr(&info, sizeof(info));
+	TInt r = KErrGeneral;
+	NKern::LockSystem();
+
+XTRAP_PAGING_RETRY(
+	DProcess* process = (DProcess*)K::ObjectFromHandle(aProcessHandle,EProcess);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessGetMemoryInfo %O",process));
+	DCodeSeg* seg=process->iCodeSeg;
+	if(seg)
+		r = seg->GetMemoryInfo(info,TheCurrentThread->iOwningProcess);
+)
+	NKern::UnlockSystem();
+	kumemput32(&aInfo, &info, sizeof(info));
+	return r;
+	}
+
+TInt ExecHandler::LibraryGetMemoryInfo(TInt aLibraryHandle, TModuleMemoryInfo& aInfo)
+	{
+	TModuleMemoryInfo info;
+	memclr(&info, sizeof(info));
+	TInt r = KErrGeneral;
+	NKern::LockSystem();
+
+XTRAP_PAGING_RETRY(
+	DLibrary* library = (DLibrary*)K::ObjectFromHandle(aLibraryHandle,ELibrary);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryGetMemoryInfo %O",library));
+	DCodeSeg* seg=library->iCodeSeg;
+	if(seg)
+		r = seg->GetMemoryInfo(info,TheCurrentThread->iOwningProcess);
+)
+	NKern::UnlockSystem();
+	kumemput32(&aInfo, &info, sizeof(info));
+	return r;
+	}
+
+void AccessMachineConfig()
+	{
+	NKern::ThreadEnterCS();
+	Kern::MutexWait(*K::MachineConfigMutex);
+	}
+
+void EndAccessMachineConfig()
+	{
+	Kern::MutexSignal(*K::MachineConfigMutex);
+	NKern::ThreadLeaveCS();
+	}
+
+TInt ExecHandler::MachineConfiguration(TDes8& aConfig, TInt& aSize)
+//
+// Get the machine configuration
+// Enter and leave with system unlocked
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MachineConfiguration"));
+	if(!Kern::CurrentThreadHasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::MachineConfiguration")))
+		K::UnlockedPlatformSecurityPanic();
+    const TPtrC8 platConfig(A::MachineConfiguration());
+    TInt platSize=platConfig.Length();
+	TInt usize=sizeof(TUid)+sizeof(TVersion)+sizeof(platSize)+platSize;
+
+	TInt ulen, umax;
+	Kern::KUDesInfo(aConfig,ulen,umax);
+	TInt r = KErrArgument;
+	if(umax<usize)
+		goto done; // user buffer not big enough
+
+	// create tempory  buffer for config data
+	{
+	DThread& t=*TheCurrentThread;
+	NKern::ThreadEnterCS();
+	TUint8* buf=(TUint8*)Kern::Alloc(usize);
+	t.iTempAlloc=buf;			// if we are killed, buf will be deleted
+	NKern::ThreadLeaveCS();
+	r = KErrNoMemory;
+	if (!buf)
+		goto done; // no memory
+
+	// get config data
+	{
+	TUint8* p=buf;
+	*((TUid*&)p)++ = KMachineConfigurationUid;
+	*((TVersion*&)p)++ = TVersion(KMachineConfigurationMajorVersionNumber,KMachineConfigurationMinorVersionNumber,KMachineConfigurationBuildVersionNumber);
+	*((TInt*&)p)++ = platSize;
+	AccessMachineConfig();
+	NKern::LockSystem();
+	memcpy(p,platConfig.Ptr(),platSize);
+	NKern::UnlockSystem();
+	EndAccessMachineConfig();
+
+	Kern::KUDesPut(aConfig,TPtrC8(buf,usize));
+
+	NKern::ThreadEnterCS();
+	t.iTempAlloc=NULL;
+	delete buf;
+	NKern::ThreadLeaveCS();
+
+	r = KErrNone;
+	}
+	}
+done:
+	kumemput32(&aSize,&usize,sizeof(usize));
+	return r;
+	}
+
+TInt ExecHandler::SetMachineConfiguration(const TDesC8& aConfig)
+//
+// Set the machine configuration
+// Enter and leave with system unlocked
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetMachineConfiguration"));
+	if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetMachineConfiguration")))
+		K::UnlockedPlatformSecurityPanic();
+	TInt len;
+	TInt maxLen;
+	const TUint8* pC=Kern::KUDesInfo(aConfig,len,maxLen);
+	TInt r=KErrNoMemory;
+	TUint8* pB=NULL;
+    TPckgBuf<TUid> uid;
+    TPckgBuf<TVersion> version;
+    TPckgBuf<TInt> platSizeBuf;
+	TInt platSize;
+	TInt i=0;
+	TPtrC8 platConfig;
+	DThread& t=*TheCurrentThread;
+
+	// first allocate a kernel-side buffer big enough to hold the new configuration
+	NKern::ThreadEnterCS();
+	pB=(TUint8*)Kern::Alloc(len);
+	if (!pB)
+		goto endSetMachineConfig2;
+	t.iTempAlloc=pB;			// if we are killed, pB will be deleted
+	NKern::ThreadLeaveCS();
+
+	// copy the configuration
+	kumemget(pB,pC,len);
+	r=KErrArgument;
+	if (len<(TInt)(sizeof(TUid)+sizeof(TVersion)+sizeof(TInt)))
+		goto endSetMachineConfig;
+
+	// extract and check the UID
+	uid.Copy(pB+i,(TInt)sizeof(TUid));
+    if (uid().iUid!=KMachineConfigurationUidValue)
+		goto endSetMachineConfig;
+	i+=(TInt)sizeof(TUid);
+
+	// extract and check the version
+	version.Copy(pB+i,(TInt)sizeof(TVersion));
+	r=KErrNotSupported;
+    if(!Kern::QueryVersionSupported(TVersion(KMachineConfigurationMajorVersionNumber,KMachineConfigurationMinorVersionNumber,KMachineConfigurationBuildVersionNumber),version()))
+		goto endSetMachineConfig;
+	i+=(TInt)sizeof(TVersion);
+
+	// extract and check the super page size
+	platSizeBuf.Copy(pB+i,(TInt)sizeof(TInt));
+	i+=(TInt)sizeof(TInt);
+	platSize=platSizeBuf();
+	r=KErrArgument;
+    if (platSize>(len-i))
+		goto endSetMachineConfig;
+
+	platConfig.Set(pB+i,platSize);
+
+	// restore the super page config
+	AccessMachineConfig();
+	K::SetMachineConfiguration(platConfig);
+	r=KErrNone;
+	EndAccessMachineConfig();
+
+endSetMachineConfig:
+	NKern::ThreadEnterCS();
+	t.iTempAlloc=NULL;
+	delete pB;
+endSetMachineConfig2:
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+TInt ExecHandler::ThreadCreate(const TDesC8& aName, TOwnerType aType, SThreadCreateInfo& aInfo)
+	{
+	TKName n;
+	Kern::KUDesGet(n,aName);
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadCreate %lS",&n));
+	TUint32 infoBuf[KMaxThreadCreateInfo/sizeof(TUint32)];
+	SThreadCreateInfo& info = *(SThreadCreateInfo*)infoBuf;
+	kumemget32(&info, &aInfo, sizeof(SThreadCreateInfo));
+	TInt r = ( (info.iTotalSize < (TInt)sizeof(SThreadCreateInfo)) || (info.iTotalSize > KMaxThreadCreateInfo) || (info.iTotalSize & 7) )
+		? KErrArgument : KErrNone;
+	if (info.iUserStackSize < KMaxThreadCreateInfo*2)
+		r=KErrArgument;
+	if (r==KErrNone)
+		{
+		if (info.iTotalSize > (TInt)sizeof(SThreadCreateInfo))
+			kumemget32( (&info)+1, (&aInfo)+1, info.iTotalSize-(TInt)sizeof(SThreadCreateInfo) );
+		info.iType=EThreadUser;
+		info.iSupervisorStackSize=0;	// zero means use default value
+		info.iSupervisorStack=NULL;
+		info.iInitialThreadPriority=EThrdPriorityNormal;
+		info.iName.Set(n);
+		NKern::ThreadEnterCS();
+		DThread* pT=NULL;
+		TInt h;
+		r=TheCurrentThread->iOwningProcess->NewThread(pT, info, &h, aType);
+		if(r==KErrNone)
+			r = h;
+		NKern::ThreadLeaveCS();
+		}
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadCreate returns %d",r));
+	return r;
+	}
+
+/********************************************
+ * Kernel-side executive calls
+ ********************************************/
+
+TInt K::MutexCreate(DMutex*& aMutex, const TDesC& aName, DObject* anOwner, TBool aVisible, TUint aOrder)
+	{
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("K::MutexCreate %lS owner %O visible=%d order=%02x",&aName,anOwner,aVisible,aOrder));
+	DMutex* pM=new DMutex;
+	TInt r=KErrNoMemory;
+	if (pM)
+		{
+		r=pM->Create(anOwner, &aName, aVisible, aOrder);
+		if (r==KErrNone)
+			aMutex=pM;
+		else
+			pM->Close(NULL);
+		}
+	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("K::MutexCreate returns %d %08x",r,pM));
+	return r;
+	}
+
+/**	Creates a new thread.
+
+	It receives a parameter of type SThreadCreateInfo. The members of this structure have the following meaning for this function:
+
+	iHandle	[out]	Heap allocated DThread pointer to the new created thread.
+					This member is valid only if the return code is KErrNone.
+					Do not assume it's NULL if the operation failed.
+	iType	[in]	Specifies if the thread will run in User mode or in Kernel mode.
+					It can be one of:
+						EThreadInitial - this is the initial thread
+						EThreadSupervisor - this runs in supervisor mode
+						EThreadMinimalSupervisor - this runs in supervisor mode and has no handles array
+						EThreadUser - this runs in User Mode
+						EThreadAPInitial - this is the initial thread on a non-boot processor (SMP only)
+	iFunction [in]	This is the function that will be run in the new thread.
+	iPtr	[in]	Extra custom parameters passed to iFunction when it starts running.
+	iSupervisorStack	Ignored.
+	iSupervisorStackSize [in]	If the thread is a Kernel thread, this parameter will specify the desired supervisor stack size.
+								If the size is 0, the size will be specified by K::SupervisorThreadStackSize, which is 4K.
+								The size will be rounded up to Page or Block size.
+	iUserStack			Ignored.
+	iUserStackSize [in]	If the thread is a User Mode thread, this parameter will specify the desired user stack size.
+						The size will be rounded up to Page or Block size.
+						It will fail with KErrTooBig if the size is greater than PP::MaxUserThreadStack which is usually set to 0x14000 (80K).
+	iInitialThreadPriority [in] Initial priority for this thread. Must be in [0,63] interval.
+	iName	[in]	Name of the thread. In case you do not specify a name for this thread, it will be created EProtected
+					and any attempts to open it will fail with KErrPermissionDenied. Otherwise, the object will be EGlobal.
+	iTotalSize [in]	Total size in bytes of the SThreadCreateInfo, including the extras. Fails with KErrArgument if it's less than sizeof(SThreadCreateInfo) or greater than KMaxThreadCreateInfo.
+
+	It can fail with KErrArgument if aInfo.iTotalSize is not set correctly or aInfo.iPriority is not in [0,63] interval
+	In x86 port it can fail with KErrArgument if anInfo.iStackBase is NULL or anInfo.iStackSize is less than 0x100
+	It can fail with KErrTooBig if aInfo.iUserStackSize is bigger than maximum user stack size
+	It can fail in Emulator with a Win32 error code returned by GetLastError if the Win32 thread or the scheduler Win32 event cannot be created
+	It can fail with KErrDied if the thread dies during the creation process
+	It can fail with KErrNoMemory in OOM scenarios.
+	It can fail with KErrGeneral indicating a general malfunction or data corruption.
+	
+	If it succeeds it will return the heap allocated DThread pointer to the new created thread in iHandle member of aInfo
+	  
+	@param aInfo Information passed by the caller to specify how to create the thread.
+	
+	@pre Calling thread must be in a critical section.
+	@pre Call in a thread context.
+	@pre Kernel must be unlocked.
+	@pre interrupts enabled
+	@pre No fast mutex can be held
+	
+	@post Calling thread is in a critical section.
+*/
+EXPORT_C TInt Kern::ThreadCreate(SThreadCreateInfo& aInfo)
+	{
+	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Kern::ThreadCreate");		
+	__KTRACE_OPT(KEXEC,Kern::Printf("Kern::ThreadCreate %lS",&aInfo.iName));
+	aInfo.iHandle=NULL;
+	DThread* pT=NULL;
+	TBool svc = aInfo.iType!=EThreadUser;
+	DProcess* pP = svc ? K::TheKernelProcess : TheCurrentThread->iOwningProcess;
+	aInfo.iSupervisorStack = NULL;
+	aInfo.iUserStack = NULL;
+	TInt r = pP->NewThread(pT, aInfo, NULL, EOwnerProcess);
+	if (r==KErrNone)
+		aInfo.iHandle = pT;
+	__KTRACE_OPT(KEXEC,Kern::Printf("Kern::ThreadCreate returns %d",r));
+	return r;
+	}
+
+#ifdef _UNICODE
+void ccopy (TUint16* aDest, const TAny* aSrc)
+{
+	TUint16* pSrc = (TUint16*)aSrc;
+	if(aSrc) {
+		TUint16* p = aDest + 1;
+		for (;*pSrc;)
+			*p++ = *pSrc++;
+		*aDest = (TUint16)(p-aDest-1);
+	}
+	else
+		*aDest = 0;	
+}
+#else
+void ccopy (TUint8* aDest, const TAny* aSrc)
+{
+	TUint8* pSrc = (TUint8*)aSrc;
+	if(aSrc) {
+		TUint8* p = aDest + 1;
+		for (;*pSrc;)
+			*p++ = *pSrc++;
+		*aDest = (TUint8)(p-aDest-1);
+	}
+	else
+		*aDest = 0;	
+}
+#endif
+
+TInt ExecHandler::GetModuleNameFromAddress(TAny* aPtr, TDes8& aModuleName)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::GetModuleNameFromAddress 0x%X", aPtr));
+	TFileName fn;
+	Kern::AccessCode();
+	DCodeSeg* pSeg = Kern::CodeSegFromAddress( (TLinAddr)aPtr, TheCurrentThread->iOwningProcess );
+	if (pSeg)
+		pSeg->AppendFullFileName(fn);
+	Kern::EndAccessCode();
+	if (!pSeg)
+		{
+ 		return KErrNotFound;
+		}
+	Kern::KUDesPut(aModuleName, fn);
+	return KErrNone;
+	}
+
+TInt ExecHandler::LocaleExports(TAny* aHandle, TLibraryFunction* aExportList)
+//
+// Change Locale setups
+//
+// NOTES
+//
+// 1. A mutex is NOT used to protect this, so if it is called by more than one thread
+//    simultaneousely, the locale info may be garbled.
+// 2. Locale libraries are never closed once they have been used. This prevents them from
+//    being unloaded whilst other threads are referencing the data contained in them.
+// 3. This function doesn't duplicate the EKA1 behaviour of saving the default data for
+//    restoring later.
+//
+// The current use case for this function is that it is called once by WSERV after boot,
+// so the above points should never be a problem. ( A generic 'change locale' will cause
+// all sorts of problems throught the OS, so current practice won't change before a
+// comprehensive rearchitecture occurs anyway.)
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LocaleExports"));
+
+	DCodeSeg& cs=*DCodeSeg::VerifyCallerAndHandle(aHandle);
+
+  	if(cs.iUids.iUid[1].iUid !=	KLocaleDllUid.iUid)
+  		return KErrNotSupported;
+
+	// Increment the code segment's access count
+	// This will increment every time the same locale is reloaded, but
+	// this doesn't matter since we don't unload locale DLLs.
+	NKern::ThreadEnterCS();
+	DCodeSeg::Wait();
+	cs.CheckedOpen();
+	DCodeSeg::Signal();
+	NKern::ThreadLeaveCS();
+	
+	TLibraryFunction data[KNumLocaleExports];
+	TInt n;
+	for(n=0; n<KNumLocaleExports; n++)
+		data[n] = (TLibraryFunction)cs.Lookup(n);
+  
+	kumemput32(aExportList, &data[0], KNumLocaleExports * sizeof(TLibraryFunction));
+
+	return KErrNone;
+	}
+
+TInt ExecHandler::ResetMachine(TMachineStartupType /*aType*/)
+	{
+	// Don't implement without considering Platform Security!
+	return KErrNotSupported;
+	}
+
+TInt ExecHandler::ExecuteInSupervisorMode(TSupervisorFunction aFunction, TAny* aParameter)
+//
+// Execute a function in supervisor mode. Only available to F32 - panic anyone else
+//
+	{
+#ifndef __MEMMODEL_FLEXIBLE__
+	if (TheCurrentThread->iOwningProcess == K::TheFileServerProcess)
+		{
+		UNLOCK_USER_MEMORY();
+		TInt r = A::CallSupervisorFunction(aFunction,aParameter);
+		LOCK_USER_MEMORY();
+		return r;
+		}
+#endif
+	K::PanicKernExec(EAccessDenied);
+	return 0;
+	}
+
+_LIT(KDriveZed, "Z:");
+void ExecHandler::DllFileName(TInt aHandle, TDes8& aFileName)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllFileName %08x",aHandle));
+	TFileName n;
+	Kern::AccessCode();
+	DCodeSeg* pS=DCodeSeg::CodeSegFromEntryPoint(aHandle);
+	if (pS)
+		pS->AppendFullFileName(n);
+	else
+		n=KDriveZed;
+	Kern::EndAccessCode();
+	if (pS)
+		P::NormalizeExecutableFileName(n);
+	Kern::KUDesPut(aFileName,n);
+	}
+
+#ifdef MONITOR_THREAD_CPU_TIME
+TInt ExecHandler::ThreadGetCpuTime(DThread* aThread, Int64& aTime)
+	{
+#ifndef __SMP__
+	TInt64 time = (1000000 * aThread->iNThread.iTotalCpuTime) / NKern::FastCounterFrequency();
+	NKern::UnlockSystem();
+	kumemput32(&aTime, &time, sizeof(TInt64));
+#else
+	TUint64 t = NKern::ThreadCpuTime(&aThread->iNThread);
+	NKern::UnlockSystem();
+	TUint32 f = NKern::CpuTimeMeasFreq();
+	TUint64 t2 = t>>32;
+	t = ((t<<32)>>32)*1000000;
+	t2 *= 1000000;
+	t2 += (t>>32);
+	t &= TUint64(KMaxTUint32);
+	TUint64 q2 = t2/f;
+	t2 -= q2*f;
+	t += (t2<<32);
+	TUint64 q = t/f;
+	q += (q2<<32);
+	kumemput32(&aTime, &q, sizeof(TInt64));
+#endif
+	return KErrNone;
+	}
+#else		
+TInt ExecHandler::ThreadGetCpuTime(DThread* /*aThread*/, Int64& /*aTime*/)
+	{
+	NKern::UnlockSystem();
+	return KErrNotSupported;
+	}
+#endif
+
+TInt ExecHandler::SetMemoryThresholds(TInt aLowThreshold, TInt aGoodThreshold)
+	{
+	if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by UserSvr::SetMemoryThresholds")))
+		K::LockedPlatformSecurityPanic();
+	if (aLowThreshold<0 || aGoodThreshold<aLowThreshold)
+		return KErrArgument;
+	K::MemoryLowThreshold=aLowThreshold;
+	K::MemoryGoodThreshold=aGoodThreshold;
+	return KErrNone;
+	}
+
+void ExecHandler::FsRegisterThread()
+//
+// Register the file server thread
+//
+	{
+
+	__KTRACE_OPT(KBOOT,Kern::Printf("File server thread registered"));
+	DThread* pT = TheCurrentThread;
+	DProcess* pP = pT->iOwningProcess;
+	pP->iFlags |= (KThreadFlagProcessCritical | KProcessFlagSystemPermanent);
+	pT->iFlags |= KThreadFlagSystemPermanent;
+	if (K::TheFileServerProcess && K::TheFileServerProcess!=pP)
+		K::PanicCurrentThread(EAccessDenied);
+	K::TheFileServerProcess=pP;
+	K::ThreadEnterCS();
+	pP->SetPriority(EPriorityFileServer);
+	M::FsRegisterThread();
+	K::ThreadLeaveCS();
+	}
+
+
+void ExecHandler::RegisterTrustedChunk(DChunk* aChunk)
+//
+// Register file server's chunk intended for DMA transfer
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RegisterTrustedChunk %x",aChunk));
+
+	DProcess* pP=TheCurrentThread->iOwningProcess;
+	if (K::TheFileServerProcess && K::TheFileServerProcess!=pP)
+		{
+		K::PanicCurrentThread(EAccessDenied);
+		}
+	aChunk->iAttributes |= DChunk::ETrustedChunk;
+	}
+	
+void ExecHandler::WsRegisterThread()
+//
+// Register the window server thread
+//
+	{
+
+	__KTRACE_OPT(KBOOT,Kern::Printf("Window server thread registered"));
+	DProcess* pP=TheCurrentThread->iOwningProcess;
+	if (K::TheWindowServerProcess && K::TheWindowServerProcess!=pP)
+		K::PanicCurrentThread(EAccessDenied);
+	K::TheWindowServerProcess=pP;
+	K::ThreadEnterCS();
+	pP->SetPriority(EPriorityWindowServer);
+	K::ThreadLeaveCS();
+	}
+
+void ExecHandler::RequestSignal(TInt aCount)
+//
+// Signal the request semaphore.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RequestSignal %d",aCount));
+	NKern::ThreadRequestSignal(NULL,aCount);
+	}
+
+TInt ExecHandler::ThreadRequestCount(DThread* aThread)
+//
+// Get the request semaphores count.
+//
+	{
+
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRequestCount"));
+	return aThread->iNThread.iRequestSemaphore.iCount;
+	}
+
+void CompleteUserAfter(TAny* aPtr)
+	{
+	DThread* pT=DThread::FromTimer(aPtr);
+	if (pT->iTimer.iState==TTimer::EWaiting)
+		{
+		Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
+		pT->iTimer.iState=TTimer::EIdle;
+		}
+	}
+
+void CompleteUserAt(TAny* aPtr)
+	{
+	DThread* pT=DThread::FromTimer(aPtr);
+	if (pT->iTimer.iState==TTimer::EWaiting)
+		{
+		Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
+		pT->iTimer.iState=TTimer::EIdle;
+		}
+	}
+
+void CompleteUserAfterHighRes(TAny* aPtr)
+	{
+	DThread* pT=DThread::FromTimer(aPtr);
+	NKern::LockSystem();
+	pT->iTimer.iState=TTimer::EIdle;
+	Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
+	NKern::UnlockSystem();
+	}
+
+void ExecHandler::After(TInt anInterval, TRequestStatus& aStatus)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::After %d",anInterval));
+	TInt iv=anInterval;
+	if (iv<=0)
+		{
+		// just rotate the ready queue for this thread
+		NKern::RotateReadyList(-1);
+		TRequestStatus* s=&aStatus;
+		Kern::RequestComplete(s,KErrNone);
+		return;
+		}
+	NKern::ThreadEnterCS();
+	TInt r=TheCurrentThread->iTimer.After(iv,CompleteUserAfter,aStatus);
+	NKern::ThreadLeaveCS();
+	if (r==KErrInUse)
+		K::PanicKernExec(ETimerAlreadyPending);
+	else if (r!=KErrNone)
+		{
+		TRequestStatus* s=&aStatus;
+		Kern::RequestComplete(s,r);
+		}
+	}
+
+void ExecHandler::AfterHighRes(TInt anInterval, TRequestStatus& aStatus)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::AfterHighRes %d",anInterval));
+	TInt r=TheCurrentThread->iTimer.AfterHighRes(anInterval,CompleteUserAfterHighRes,aStatus);
+	if (r==KErrInUse)
+		K::PanicCurrentThread(ETimerAlreadyPending);
+	}
+
+void ExecHandler::At(const TTimeK& aTime, TRequestStatus& aStatus)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::At"));
+	TTimeK time;
+	kumemget32(&time,&aTime,sizeof(time));
+	NKern::ThreadEnterCS();
+	TInt r=TheCurrentThread->iTimer.At(time,CompleteUserAt,aStatus);
+	NKern::ThreadLeaveCS();
+	if (r==KErrInUse)
+		K::PanicKernExec(ETimerAlreadyPending);
+	else if (r!=KErrNone)
+		{
+		TRequestStatus* s=&aStatus;
+		Kern::RequestComplete(s,r);
+		}
+	}
+
+#ifndef __FASTEXEC_MACHINE_CODED__
+RAllocator* ExecHandler::Heap()
+	{
+	return TheCurrentThread->iAllocator;
+	}
+
+extern void InvalidFastExec();
+
+TTrapHandler* ExecHandler::PushTrapFrame(TTrap* aFrame)
+//
+// Push a new trap frame.
+//
+	{
+#ifdef __LEAVE_EQUALS_THROW__
+#ifdef __WINS__
+	// On WINS overload this function to remember when a TWin32SEHTrap is installed
+	// over another one
+	DThread& t=*TheCurrentThread;
+	t.iFrame=aFrame;
+	return 0;
+#else
+	InvalidFastExec();
+	return (TTrapHandler*)aFrame; // Prevents compiler warnings
+#endif
+#else
+	DThread& t=*TheCurrentThread;
+	aFrame->iHandler=t.iTrapHandler;
+	aFrame->iNext=t.iFrame;
+	t.iFrame=aFrame;
+	return t.iTrapHandler;
+#endif
+	}
+
+TTrap* ExecHandler::PopTrapFrame()
+//
+// Pop the current frame.
+//
+	{
+#ifdef __LEAVE_EQUALS_THROW__
+#ifdef __WINS__
+	// On WINS overload this function to recall when a TWin32SEHTrap is installed
+	// over another one
+	DThread& t=*TheCurrentThread;
+	return t.iFrame;
+#else
+	InvalidFastExec();
+	return 0;
+#endif
+#else
+	DThread& t=*TheCurrentThread;
+	TTrap* pF=t.iFrame;
+	if (pF)
+		t.iFrame=pF->iNext;
+	return pF;
+#endif
+	}
+
+CActiveScheduler* ExecHandler::ActiveScheduler()
+//
+// Return the address of the current active scheduler
+//
+	{
+	DThread& t=*TheCurrentThread;
+	return t.iScheduler;
+	}
+
+void ExecHandler::SetActiveScheduler(CActiveScheduler* aScheduler)
+//
+// Set the address of the current active scheduler
+//
+	{
+	DThread& t=*TheCurrentThread;
+	t.iScheduler=aScheduler;
+	}
+
+TTrapHandler* ExecHandler::TrapHandler()
+//
+// Return the current trap handler.
+//
+	{
+	DThread& t=*TheCurrentThread;
+	return t.iTrapHandler;
+	}
+
+TTrapHandler* ExecHandler::SetTrapHandler(TTrapHandler* aHandler)
+//
+// Set the current trap handler.
+//
+	{
+	DThread& t=*TheCurrentThread;
+	TTrapHandler* pH=t.iTrapHandler;
+	t.iTrapHandler=aHandler;
+	return pH;
+	}
+
+void ExecHandler::SetReentryPoint(TLinAddr a)
+	{
+	DThread& t = *TheCurrentThread;
+	t.iOwningProcess->iReentryPoint = a;
+	}
+#endif
+
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+void K::DoProcessIsolationFailure(const char* aContextText)
+	{
+	// enter with system locked
+	if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation)
+		{
+		if(PlatSec::ProcessIsolationFail(aContextText)==KErrNone)
+			return;
+		LockedPlatformSecurityPanic();
+		}
+	}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+void K::DoProcessIsolationFailure()
+	{
+	// enter with system locked
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	DoProcessIsolationFailure(NULL);
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	if (TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation)
+		{
+		if (PlatSec::EmitDiagnostic() == KErrNone)
+			return;
+		LockedPlatformSecurityPanic();
+		}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	}
+
+
+void K::UnlockedPlatformSecurityPanic()
+	{
+	// enter with system unlocked
+	NKern::LockSystem();
+	K::LockedPlatformSecurityPanic();
+	}
+
+void K::LockedPlatformSecurityPanic()
+	{
+	// enter with system locked
+	K::PanicCurrentThread(EPlatformSecurityTrap);
+	}
+
+void ExecHandler::ThreadRendezvous(TInt aReason)
+	{
+	NKern::ThreadEnterCS();
+	TheCurrentThread->Rendezvous(aReason);
+	NKern::ThreadLeaveCS();
+	}
+
+void ExecHandler::ProcessRendezvous(TInt aReason)
+	{
+	NKern::ThreadEnterCS();
+	TheCurrentThread->iOwningProcess->Rendezvous(aReason);
+	NKern::ThreadLeaveCS();
+	}
+
+void ExecHandler::DebugPrint(TAny* aDes, TInt aMode)
+	{
+	TInt l, m;
+	const TText* p = Kern::KUDesInfo(*(const TDesC*)aDes, l, m);
+
+#ifdef __DEBUGGER_SUPPORT__
+	TUint r = DKernelEventHandler::Dispatch(EEventUserTrace, (TAny*)p, (TAny*)l);
+	if (r & DKernelEventHandler::ETraceHandled)
+		l = 0;
+#endif
+
+	TBuf8<256> buffer;
+	l = Min(l,256);
+	buffer.SetLength(l);
+	kumemget((TUint8*)buffer.Ptr(), p, l); //Copy user-side data into kernel memory
+	K::TextTrace(buffer,EUserTrace,!aMode);
+	}
+
+
+TInt ExecHandler::ProcessSetHandleParameter(DProcess* aProcess, TInt aSlot, TInt aHandle)
+	{
+	if (aProcess->iCreatorId != TheCurrentThread->iOwningProcess->iId) //check called by creator
+		K::LockedPlatformSecurityPanic();
+
+	if ((aSlot < 0) || (aSlot >= KArgIndex))
+		K::PanicCurrentThread(EParameterSlotRange);
+
+	if (aProcess->iEnvironmentData[aSlot] != 0)
+		K::PanicCurrentThread(EParameterSlotInUse);
+
+	DObject* pObject = K::ObjectFromHandle(aHandle);
+
+	if (pObject->Protection() == DObject::ELocal) 
+		K::LockedPlatformSecurityPanic();
+	pObject->CheckedOpen();
+
+	aProcess->iEnvironmentData[aSlot] = (TInt)pObject | EHandle;
+	return KErrNone;
+	}
+
+//no locks held on entry
+TInt ExecHandler::ProcessSetDataParameter(TInt aProcess, TInt aSlot, const TUint8* aData, TInt aLen)
+	{
+
+	if ((aSlot < 0) || (aSlot >= KArgIndex))
+		K::PanicKernExec(EParameterSlotRange);
+
+	if (aLen < 0)
+		K::PanicKernExec(EParameterSlotDataLength);
+
+	NKern::ThreadEnterCS();
+	HBuf8* pBuf = NULL;
+	if (aLen)
+		pBuf = HBuf8::New(aLen);
+
+	DThread* currentThread = TheCurrentThread;
+	currentThread->iTempAlloc = pBuf;
+	NKern::ThreadLeaveCS();				
+
+	if (aLen)
+		{
+		if (!pBuf)
+			return KErrNoMemory;
+		kumemget((void*)pBuf->Ptr(), aData, aLen);
+		pBuf->SetLength(aLen);
+		}
+
+
+	NKern::LockSystem();
+	DProcess* pProc = (DProcess*)K::ObjectFromHandle(aProcess, EProcess); 
+
+	if (pProc->iCreatorId != currentThread->iOwningProcess->iId) //check called by creator
+		K::LockedPlatformSecurityPanic();
+
+	if (pProc->iEnvironmentData[aSlot] != 0)
+		K::PanicCurrentThread(EParameterSlotInUse);
+
+	pProc->iEnvironmentData[aSlot] = (TInt)pBuf | EBinaryData;
+	currentThread->iTempAlloc = NULL;
+	NKern::UnlockSystem();
+
+	return KErrNone;
+	}
+
+
+
+//need to have sys locked on way in
+TInt ExecHandler::ProcessGetHandleParameter(TInt aSlot, TObjectType aObjectType, TOwnerType aOwnerType)
+	{
+
+	DThread * currentThread = TheCurrentThread;
+	DProcess * currentProcess = currentThread->iOwningProcess;
+
+	if ((aSlot < 0) || (aSlot >= KArgIndex))
+		K::PanicCurrentThread(EParameterSlotRange);
+
+	TInt data = currentProcess->iEnvironmentData[aSlot];
+
+	if (!data)
+		return KErrNotFound;
+
+	TProcessParameterType type = (TProcessParameterType)(data&3);
+
+	if (type != EHandle)
+		return KErrArgument;
+
+	DObject* pObject = (DObject*)(data&~3);
+
+	if ((TInt)aObjectType+1 != pObject->UniqueID())	//check it's the correct type
+		return KErrArgument;
+
+	// zero parameter to prevent race conditions while retrieving the object
+	currentProcess->iEnvironmentData[aSlot]=0;
+	
+	NKern::ThreadEnterCS();
+	NKern::UnlockSystem();
+	TInt handle = 0;
+
+	TInt ret = currentThread->MakeHandle(aOwnerType, pObject, handle);
+
+	NKern::LockSystem();
+	NKern::ThreadLeaveCS();
+
+	if (ret != KErrNone)
+		{
+		// restore parameter data as 'nothing happened'
+		currentProcess->iEnvironmentData[aSlot]=data;
+		return ret;
+		}
+	return handle;
+	}
+
+
+//enter with the system lock held, auto release on exit
+TInt ExecHandler::ProcessGetDataParameter(TInt aSlot,  TUint8* aData, TInt aLen)
+	{
+
+	DThread * currentThread = TheCurrentThread;
+	DProcess * currentProcess = currentThread->iOwningProcess;
+
+	if ((aSlot < 0) || (aSlot >= KArgIndex))
+		K::PanicCurrentThread(EParameterSlotRange);
+
+	TInt data = currentProcess->iEnvironmentData[aSlot];
+	if (!data)
+		return KErrNotFound;
+
+	TProcessParameterType type = (TProcessParameterType)(data&3);
+	if (type != EBinaryData)
+		return KErrArgument;
+
+	HBuf8* p = (HBuf8*)(data&~3);
+	if (!p)	//we've passed zero length binary data so nothing to copy
+		return 0;
+
+	if (aLen < p->Length())
+		return KErrArgument;
+
+	currentThread->iTempAlloc = p;
+	currentProcess->iEnvironmentData[aSlot] = 0;
+	NKern::UnlockSystem();
+
+	TInt len = p->Length();
+	kumemput((void*)aData, (void*)p->Ptr(), len);
+
+	NKern::ThreadEnterCS();
+	currentThread->iTempAlloc = NULL;
+	delete p;
+	NKern::ThreadLeaveCS();
+
+	NKern::LockSystem();
+	return len;
+	}
+
+TInt ExecHandler::ProcessDataParameterLength(TInt aSlot)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessDesParameterLength"));
+
+	DProcess * currentProcess = TheCurrentThread->iOwningProcess;
+
+	if ((aSlot < 0) || (aSlot >= KArgIndex))
+		K::PanicCurrentThread(EParameterSlotRange);
+
+	TInt data = currentProcess->iEnvironmentData[aSlot];
+
+	if (!data)
+		return KErrNotFound;
+
+	TProcessParameterType type = (TProcessParameterType)(data&3);
+
+	if (type != EBinaryData)
+		return KErrArgument;
+
+	const HBuf8* p = (const HBuf8*)(data&~3);
+
+	return p ? p->Length() : 0;
+	}
+
+
+
+void ExecHandler::NotifyChanges(TUint aChanges)
+//
+// Check that the caller has permission to notify the requested changes,
+// and pass it on to Kern::NotifyChanges if it's ok
+//
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::NotifyChanges"));
+	
+	if (aChanges & ~EChangesLocale)
+		K::UnlockedPlatformSecurityPanic();
+	
+	NKern::ThreadEnterCS();
+	Kern::NotifyChanges(aChanges);
+	NKern::ThreadLeaveCS();
+	}
+
+
+
+static TInt GlobalUserData[EMaxGlobalUserData] = {0};
+
+TInt ExecHandler::GetGlobalUserData(TInt aIndex)
+	{
+	if(TUint(aIndex)<TUint(EMaxGlobalUserData))
+		return GlobalUserData[aIndex];
+	return 0;
+	}
+
+TInt ExecHandler::SetGlobalUserData(TInt aIndex,TInt aValue)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetGlobalUserData %d 0x%8x",aIndex,aValue));
+	if(TUint(aIndex)<TUint(EMaxGlobalUserData))
+		{
+		if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by SetGlobalUserData")))
+			return KErrPermissionDenied;
+		else
+			{
+			GlobalUserData[aIndex] = aValue;
+			return KErrNone;
+			}
+		}
+	return KErrArgument;
+	}
+
+TBool ExecHandler::UserThreadExiting(TInt aReason)
+	{
+	// Mark this thread as exiting and check whether there are any other threads in the process that
+	// are not already exiting
+	
+	DThread* thread = TheCurrentThread;
+	DProcess* process = thread->iOwningProcess;
+	
+	NKern::ThreadEnterCS();
+
+	// If the thread is process permanent then all other threads in the process will be killed -
+	// make sure this happens now, so that this thread has a chance to run global object destructors.
+	if (thread->iFlags & KThreadFlagProcessPermanent)
+		{
+		__NK_ASSERT_ALWAYS(process->WaitProcessLock() == KErrNone);
+		NKern::LockSystem();
+		process->KillAllThreads(EExitKill, aReason, KNullDesC);
+		NKern::UnlockSystem();
+		process->SignalProcessLock();
+		}
+
+	TBool lastThread = EFalse;
+	__NK_ASSERT_DEBUG(thread->iUserThreadState >= DThread::EUserThreadRunning);
+	if (thread->iUserThreadState == DThread::EUserThreadRunning)
+		{
+		thread->iUserThreadState = DThread::EUserThreadExiting;
+		lastThread = (__e32_atomic_tas_ord32(&process->iUserThreadsRunning, 1, -1, 0) == 1);
+		}
+	
+	NKern::ThreadLeaveCS();
+	
+	return lastThread;
+	}
+
+
+#include <kernel/cache.h>
+
+void ExecHandler::IMBRange(TAny* aStart, TUint aSize)
+	{
+	UNLOCK_USER_MEMORY();
+	Cache::IMB_Range((TLinAddr)aStart,aSize);
+	LOCK_USER_MEMORY();
+	}