kernel/eka/kernel/sexec.cpp
changeset 0 a41df078684a
child 4 56f325a607ea
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\kernel\sexec.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <kernel/kern_priv.h>
       
    19 #include <e32uid.h>
       
    20 #include <e32ver.h>
       
    21 //#include <unicode.h>
       
    22 #include "execs.h"
       
    23 
       
    24 TInt ExecHandler::ObjectNext(TObjectType aType, TBuf8<KMaxFullName>& aName, TFindHandle& aFindHandle)
       
    25 //
       
    26 // Do the next find.
       
    27 //
       
    28 	{
       
    29 
       
    30 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ObjectNext type %d",aType));
       
    31 	if (aType<0 || aType>=ENumObjectTypes)
       
    32 		K::PanicKernExec(EBadObjectType);
       
    33 	DObjectCon* pC=K::Containers[aType];
       
    34 	TFullName fn;
       
    35 	TFullName match;
       
    36 	TFindHandle h;
       
    37 	Kern::KUDesGet(match,aName);
       
    38 	kumemget32(&h,&aFindHandle,sizeof(h));
       
    39 	__KTRACE_OPT(KEXEC,Kern::Printf("ObjN: %lS %08x", &match, h.Handle()));
       
    40 	NKern::ThreadEnterCS();
       
    41 	TInt r=pC->FindByFullName(h, match, fn);
       
    42 	NKern::ThreadLeaveCS();
       
    43 	Kern::KUDesPut(aName,fn);
       
    44 	kumemput32(&aFindHandle,&h,sizeof(h));
       
    45 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ObjectNext ret %d",r));
       
    46 	return r;
       
    47 	}
       
    48 
       
    49 TUint8 *ExecHandler::ChunkBase(DChunk* aChunk)
       
    50 //
       
    51 // Return the address of the base of the Chunk.
       
    52 //
       
    53 	{
       
    54 
       
    55 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkBase"));
       
    56 	return (TUint8*)aChunk->Base(&Kern::CurrentProcess());
       
    57 	}
       
    58 
       
    59 TInt ExecHandler::ChunkSize(DChunk* aChunk)
       
    60 //
       
    61 // Return the current size of the Chunk.
       
    62 //
       
    63 	{
       
    64 
       
    65 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkSize"));
       
    66 	return aChunk->Size();
       
    67 	}
       
    68 
       
    69 TInt ExecHandler::ChunkMaxSize(DChunk* aChunk)
       
    70 //
       
    71 // Return the maximum size of the Chunk.
       
    72 //
       
    73 	{
       
    74 
       
    75 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkMaxSize")); 	
       
    76 	return aChunk->MaxSize();
       
    77 	}
       
    78 
       
    79 TInt ExecHandler::ChunkBottom(DChunk* aChunk)
       
    80 //
       
    81 // Return the position of the bottom of the chunk
       
    82 //
       
    83 	{
       
    84 
       
    85 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkBottom"));
       
    86 	return aChunk->Bottom();
       
    87 	}
       
    88 
       
    89 TInt ExecHandler::ChunkTop(DChunk* aChunk)
       
    90 //
       
    91 // Return the position of the top of the chunk
       
    92 //
       
    93 	{
       
    94 
       
    95 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkTop"));
       
    96 	return aChunk->Top();
       
    97 	}
       
    98 
       
    99 void ExecHandler::MutexWait(DMutex* aMutex)
       
   100 //
       
   101 // Wait for the mutex.
       
   102 //
       
   103 	{
       
   104 
       
   105 //	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexWait"));
       
   106 	aMutex->Wait();
       
   107 	}
       
   108 
       
   109 void ExecHandler::MutexSignal(DMutex* aMutex)
       
   110 //
       
   111 // Signal the mutex.
       
   112 //
       
   113 	{
       
   114 
       
   115 //	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexSignal"));
       
   116 	if (TheCurrentThread==aMutex->iCleanup.iThread)
       
   117 		{
       
   118 		aMutex->Signal();
       
   119 		return;
       
   120 		}
       
   121 	K::PanicCurrentThread(EAccessDenied);
       
   122 	}
       
   123 
       
   124 /**
       
   125 Test if mutex is held by the current thread.
       
   126 @return True if the current thread has waited on the mutex, false otherwise.
       
   127 */
       
   128 TBool ExecHandler::MutexIsHeld(DMutex* aMutex)
       
   129 	{
       
   130 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MutexIsHeld"));
       
   131 	return TheCurrentThread==aMutex->iCleanup.iThread;
       
   132 	}
       
   133 
       
   134 void ExecHandler::ProcessType(DProcess* aProcess, TUidType& aUids)
       
   135 //
       
   136 // Get process' UIDs.
       
   137 //
       
   138 	{
       
   139 
       
   140 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessType"));
       
   141 	TUidType uids(aProcess->iUids);
       
   142 	NKern::UnlockSystem();
       
   143 	kumemput32(&aUids,&uids,sizeof(TUidType));
       
   144 	}
       
   145 
       
   146 TInt ExecHandler::ProcessId(DProcess* aProcess)
       
   147 //
       
   148 // Get process ID.
       
   149 //
       
   150 	{
       
   151 
       
   152 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessId")); 	
       
   153 	return (TInt)aProcess->iId;
       
   154 	}
       
   155 
       
   156 void ExecHandler::ProcessSecurityInfo(DProcess* aProcess,SSecurityInfo& aInfo)
       
   157 //
       
   158 // Get process security info.
       
   159 //
       
   160 	{
       
   161 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSecurityInfo"));
       
   162 	SSecurityInfo info(aProcess->iS);
       
   163 	NKern::UnlockSystem();
       
   164 	kumemput32(&aInfo,&info,sizeof(info));
       
   165 	}
       
   166 
       
   167 void ExecHandler::ThreadSecurityInfo(DThread* aThread,SSecurityInfo& aInfo)
       
   168 //
       
   169 // Get threads security info.
       
   170 //
       
   171 	{
       
   172 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSecurityInfo"));
       
   173 	SSecurityInfo info(aThread->iOwningProcess->iS);
       
   174 	NKern::UnlockSystem();
       
   175 	kumemput32(&aInfo,&info,sizeof(info));
       
   176 	}
       
   177 
       
   178 void ExecHandler::MessageSecurityInfo(DThread* aClient,SSecurityInfo& aInfo)
       
   179 //
       
   180 // Get clients security info.
       
   181 //
       
   182 	{
       
   183 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MessageSecurityInfo"));
       
   184 	SSecurityInfo info(aClient->iOwningProcess->iS);
       
   185 	NKern::UnlockSystem();
       
   186 	kumemput32(&aInfo,&info,sizeof(info));
       
   187 	}
       
   188 
       
   189 TInt ExecHandler::SessionSecurityInfo(TInt aSession,SSecurityInfo& aInfo)
       
   190 //
       
   191 // Get session security info.
       
   192 //
       
   193 	{
       
   194 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SessionSecurityInfo"));
       
   195 	TInt r = KErrBadHandle;
       
   196 	SSecurityInfo info;
       
   197 	NKern::LockSystem();
       
   198 	DSession* s = (DSession*)TheCurrentThread->ObjectFromHandle(aSession,ESession);
       
   199 	if (s)
       
   200 		{
       
   201 		if (s->iServer && s->iServer->iOwningThread)
       
   202 			{
       
   203 			// session is connected, and server is alive
       
   204 			info = s->iServer->iOwningThread->iOwningProcess->iS;
       
   205 			r = KErrNone;
       
   206 			}
       
   207 		else
       
   208 			{
       
   209 			r = KErrServerTerminated;
       
   210 			}
       
   211 		}
       
   212 	NKern::UnlockSystem();
       
   213 	if (r==KErrNone)
       
   214 		kumemput32(&aInfo,&info,sizeof(info));
       
   215 	return r;
       
   216 	}
       
   217 
       
   218 void ExecHandler::CreatorSecurityInfo(SSecurityInfo& aInfo)
       
   219 //
       
   220 // Get creator's security info.
       
   221 //
       
   222 	{
       
   223 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::CreatorSecurityInfo"));
       
   224 	kumemput32(&aInfo,&TheCurrentThread->iOwningProcess->iCreatorInfo,sizeof(aInfo));
       
   225 	}
       
   226 
       
   227 void ExecHandler::DisabledCapabilities(SCapabilitySet& aCaps)
       
   228 //
       
   229 // Get the set of capabilities which are not to be checked (implemented by effectively
       
   230 // setting them for all executables).
       
   231 //
       
   232 	{
       
   233 	__KTRACE_OPT(KEXEC, Kern::Printf("Exec::DisabledCapabilities"));
       
   234 #ifdef __PLATSEC_UNLOCKED__
       
   235 	kumemput32(&aCaps, &TheSuperPage().iDisabledCapabilities, sizeof(aCaps));
       
   236 #else
       
   237 	kumemset(&aCaps, 0, sizeof(aCaps));
       
   238 #endif	// __PLATSEC_UNLOCKED__
       
   239 	}
       
   240 
       
   241 void ExecHandler::ProcessResume(DProcess* aProcess)
       
   242 //
       
   243 // Resume the first thread in the process.
       
   244 //
       
   245 	{
       
   246 
       
   247 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessResume"));
       
   248 	if (aProcess->iCreatorId!=TheCurrentThread->iOwningProcess->iId) // Not creator...
       
   249 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::Resume"));
       
   250 	aProcess->Resume();
       
   251 	}
       
   252 
       
   253 void ExecHandler::ProcessFileName(DProcess* aProcess, TDes8& aName)
       
   254 //
       
   255 // Return the process file name.
       
   256 //
       
   257 	{
       
   258 
       
   259 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessFileName"));
       
   260 	TFileName fn;
       
   261 	DCodeSeg* pS=aProcess->iCodeSeg;
       
   262 	if (pS)
       
   263 		pS->AppendFullFileName(fn);
       
   264 	NKern::UnlockSystem();
       
   265 	if (pS)
       
   266 		P::NormalizeExecutableFileName(fn);
       
   267 	Kern::KUDesPut(aName, fn);
       
   268 	}
       
   269 
       
   270 TInt ExecHandler::ProcessCommandLineLength(DProcess* aProcess)
       
   271 //
       
   272 // Return the process command line length.
       
   273 //
       
   274 	{
       
   275 
       
   276 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessCommandLineLength"));
       
   277 
       
   278 	if (aProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
   279 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::CommandLineLength"));
       
   280 	const TDesC* pC=aProcess->iCommandLine;
       
   281 #ifdef _UNICODE
       
   282 	return pC?(pC->Length()>>1):0;
       
   283 #else
       
   284 	return pC?(pC->Length()):0;
       
   285 #endif
       
   286 	}
       
   287 
       
   288 void ExecHandler::ProcessCommandLine(DProcess* aProcess, TDes8& aCommandLine)
       
   289 //
       
   290 // Return the process command line.
       
   291 //
       
   292 	{
       
   293 
       
   294 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessCommandLine"));
       
   295 	if (aProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
   296 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::CommandLine"));
       
   297 	aProcess->CheckedOpen();
       
   298 	DThread& t=*TheCurrentThread;
       
   299 	t.iTempObj=aProcess;
       
   300 	NKern::UnlockSystem();
       
   301 	const TDesC* pC=aProcess->iCommandLine;
       
   302 	if (!pC)
       
   303 		pC=&KNullDesC;
       
   304 	Kern::KUDesPut(aCommandLine,*pC);
       
   305 	NKern::ThreadEnterCS();
       
   306 	t.iTempObj=NULL;
       
   307 	aProcess->Close(NULL);
       
   308 	NKern::ThreadLeaveCS();
       
   309 	}
       
   310 
       
   311 TExitType ExecHandler::ProcessExitType(DProcess* aProcess)
       
   312 //
       
   313 // Return the exit type.
       
   314 //
       
   315 	{
       
   316 
       
   317 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitType")); 	
       
   318 	return (TExitType)aProcess->iExitType;
       
   319 	}
       
   320 
       
   321 TInt ExecHandler::ProcessExitReason(DProcess* aProcess)
       
   322 //
       
   323 // Return the exit reason.
       
   324 //
       
   325 	{
       
   326 
       
   327 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitReason"));
       
   328 	return aProcess->iExitReason;
       
   329 	}
       
   330 
       
   331 void ExecHandler::ProcessExitCategory(DProcess* aProcess, TDes8& aName)
       
   332 //
       
   333 // Return the category of the exit type.
       
   334 //
       
   335 	{
       
   336 
       
   337 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExitCategory"));
       
   338 	TBufC<KMaxExitCategoryName> exitCat(aProcess->iExitCategory);
       
   339 	NKern::UnlockSystem();
       
   340 	Kern::KUDesPut(aName,exitCat);
       
   341 	}
       
   342 
       
   343 LOCAL_D const TProcessPriority procPriorityConvertTable[8]=
       
   344 	{
       
   345 	EPriorityLow,			EPriorityBackground,	EPriorityForeground,	EPriorityHigh,
       
   346 	EPriorityWindowServer,	EPriorityFileServer,	EPrioritySupervisor,	EPriorityRealTimeServer
       
   347 	};
       
   348 
       
   349 LOCAL_D const TThreadPriority thrdPriorityConvertTable[8]=
       
   350 	{
       
   351 	EPriorityMuchLess,	EPriorityMuchLess,	EPriorityLess,		EPriorityNormal,
       
   352 	EPriorityMore,		EPriorityMuchMore,	EPriorityRealTime,	EPriorityRealTime
       
   353 	};
       
   354 
       
   355 LOCAL_C TThreadPriority ConvertThreadPriority(TInt p)
       
   356 	{
       
   357 	switch(p)
       
   358 		{
       
   359 		case EThrdPriorityAbsoluteVeryLow:
       
   360 			return EPriorityAbsoluteVeryLow;
       
   361 		case EThrdPriorityAbsoluteLowNormal:
       
   362 			return EPriorityAbsoluteLowNormal;
       
   363 		case EThrdPriorityAbsoluteLow:
       
   364 			return EPriorityAbsoluteLow;
       
   365 		case EThrdPriorityAbsoluteBackgroundNormal:
       
   366 			return EPriorityAbsoluteBackgroundNormal;
       
   367 		case EThrdPriorityAbsoluteBackground:
       
   368 			return EPriorityAbsoluteBackground;
       
   369 		case EThrdPriorityAbsoluteForegroundNormal:
       
   370 			return EPriorityAbsoluteForegroundNormal;
       
   371 		case EThrdPriorityAbsoluteForeground:
       
   372 			return EPriorityAbsoluteForeground;
       
   373 		case EThrdPriorityAbsoluteHighNormal:
       
   374 			return EPriorityAbsoluteHighNormal;
       
   375 		case EThrdPriorityAbsoluteHigh:
       
   376 			return EPriorityAbsoluteHigh;
       
   377 		case EThrdPriorityAbsoluteRealTime1:
       
   378 			return EPriorityAbsoluteRealTime1;
       
   379 		case EThrdPriorityAbsoluteRealTime2:
       
   380 			return EPriorityAbsoluteRealTime2;
       
   381 		case EThrdPriorityAbsoluteRealTime3:
       
   382 			return EPriorityAbsoluteRealTime3;
       
   383 		case EThrdPriorityAbsoluteRealTime4:
       
   384 			return EPriorityAbsoluteRealTime4;
       
   385 		case EThrdPriorityAbsoluteRealTime5:
       
   386 			return EPriorityAbsoluteRealTime5;
       
   387 		case EThrdPriorityAbsoluteRealTime6:
       
   388 			return EPriorityAbsoluteRealTime6;
       
   389 		case EThrdPriorityAbsoluteRealTime7:
       
   390 			return EPriorityAbsoluteRealTime7;
       
   391 		case EThrdPriorityAbsoluteRealTime8:
       
   392 			return EPriorityAbsoluteRealTime8;
       
   393 		default:
       
   394 			if (p>=-8 && p<0)
       
   395 				return thrdPriorityConvertTable[p+8];
       
   396 		}
       
   397 	return EPriorityNormal;
       
   398 	}
       
   399 
       
   400 LOCAL_C TBool ProcessPriorityValid(TProcessPriority p)
       
   401 	{
       
   402 	switch(p)
       
   403 		{
       
   404 		case EPriorityLow:
       
   405 		case EPriorityBackground:
       
   406 		case EPriorityForeground:
       
   407 		case EPriorityHigh:
       
   408 			return ETrue;
       
   409 		default:
       
   410 			return EFalse;
       
   411 		}
       
   412 	}
       
   413 
       
   414 TProcessPriority ExecHandler::ProcessPriority(DProcess* aProcess)
       
   415 //
       
   416 // Get the process base priority.
       
   417 //
       
   418 	{
       
   419 
       
   420 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessPriority"));
       
   421 	return procPriorityConvertTable[aProcess->iPriority];
       
   422 	}
       
   423 
       
   424 TInt ExecHandler::ProcessSetPriority(DProcess* aProcess, TProcessPriority aPriority)
       
   425 //
       
   426 // Set the process base priority.
       
   427 //
       
   428 	{
       
   429 
       
   430 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSetPriority"));
       
   431 	aProcess->CheckedOpen();
       
   432 	DThread& t=*TheCurrentThread;
       
   433 	t.iTempObj=aProcess;
       
   434 	NKern::UnlockSystem();
       
   435 	if (!ProcessPriorityValid(aPriority))
       
   436 		K::PanicKernExec(EBadPriority);
       
   437 
       
   438 	TBool allowed=ETrue;
       
   439 	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
       
   440 	if (aProcess->iSecurityZone!=currentProcess->iSecurityZone)  // Not self...
       
   441 		if (aProcess->iCreatorId!=currentProcess->iId)  // Not creator
       
   442 			{
       
   443 			TInt processPriority=aProcess->iPriority;
       
   444 			if (!(aProcess->iFlags&KProcessFlagPriorityControl)  // No remote control...
       
   445  				|| (processPriority!=EProcPriorityBackground && processPriority!=EProcPriorityForeground && processPriority!=EProcPriorityHigh)
       
   446 				|| (aPriority!=EPriorityBackground && aPriority!=EPriorityForeground && aPriority!=EPriorityHigh) )  // Or not foreground/background/high
       
   447 					allowed=!(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation);
       
   448 			}
       
   449 
       
   450 	NKern::ThreadEnterCS();
       
   451 	t.iTempObj=NULL;
       
   452 	if(allowed)
       
   453 		aProcess->SetPriority(aPriority);
       
   454 	aProcess->Close(NULL);
       
   455 	NKern::ThreadLeaveCS();
       
   456 	if (allowed)
       
   457 		{
       
   458 		return KErrNone;
       
   459 		}
       
   460 	else
       
   461 		{
       
   462 		return KErrPermissionDenied;
       
   463 		}
       
   464 
       
   465 	}
       
   466 
       
   467 
       
   468 
       
   469 const TUint32 KDefinedProcessFlags=
       
   470 	KProcessFlagSystemCritical|
       
   471 	KProcessFlagSystemPermanent|
       
   472 	KProcessFlagJustInTime|
       
   473 	KProcessFlagPriorityControl|
       
   474 	KThreadFlagProcessCritical;
       
   475 
       
   476 const TUint32 KRestrictedProcessFlags =
       
   477 		~(KProcessFlagJustInTime|KProcessFlagPriorityControl|KThreadFlagProcessCritical); // All but these are restricted
       
   478 
       
   479 const TUint32 KSelfOnlyProcessFlags =
       
   480 		~0u; // (KProcessFlagJustInTime|KProcessFlagPriorityControl); // Only self can change these
       
   481 
       
   482 const TUint32 KDefinedThreadFlags=
       
   483 	KThreadFlagProcessCritical|
       
   484 	KThreadFlagProcessPermanent|
       
   485 	KThreadFlagSystemCritical|
       
   486 	KThreadFlagSystemPermanent|
       
   487 	KThreadFlagLastChance|
       
   488 	KThreadFlagRealtime|
       
   489 	KThreadFlagRealtimeTest;
       
   490 
       
   491 const TUint32 KRestrictedThreadFlags =
       
   492 		~(KThreadFlagProcessCritical|KThreadFlagProcessPermanent|KThreadFlagLastChance|
       
   493 			KThreadFlagRealtime|KThreadFlagRealtimeTest); // All but these are restricted
       
   494 
       
   495 const TUint32 KSelfOnlyThreadFlags =
       
   496 		~0u; // (KThreadFlagProcessCritical|KThreadFlagProcessPermanent|KThreadFlagLastChance); // Only owning process can change these
       
   497 
       
   498 
       
   499 TUint ExecHandler::ProcessFlags(DProcess* aProcess)
       
   500 //
       
   501 // Get the process flags
       
   502 //
       
   503 	{
       
   504 
       
   505 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessFlags"));
       
   506 	return aProcess->iFlags;
       
   507 	}
       
   508 
       
   509 TUint ExecHandler::ThreadProcessFlags(DThread* aThread)
       
   510 //
       
   511 // Get the process flags
       
   512 //
       
   513 	{
       
   514 
       
   515 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcessFlags"));
       
   516 	return aThread->iOwningProcess->iFlags;
       
   517 	}
       
   518 
       
   519 void ExecHandler::ProcessSetFlags(DProcess* aProcess, TUint aClearMask, TUint aSetMask)
       
   520 //
       
   521 // Set the process flags
       
   522 //
       
   523 	{
       
   524 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessSetFlags"));
       
   525 
       
   526 	TUint flags = aProcess->iFlags;
       
   527 	TUint modified = ((flags&~aClearMask)|aSetMask);
       
   528 	modified = (modified^flags)&KDefinedProcessFlags;
       
   529 
       
   530 	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
       
   531 
       
   532 	if (modified&KSelfOnlyProcessFlags)
       
   533 		if(aProcess->iSecurityZone!=currentProcess->iSecurityZone)
       
   534 			if(aProcess->iCreatorId!=currentProcess->iId)
       
   535 				K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to modify the attributes of another Process. Possibly RProcess::SetSystem."));
       
   536 
       
   537 	if (modified&KRestrictedProcessFlags)
       
   538 		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetProcessCritical (or RProcess::SetSystem)")))
       
   539 			K::LockedPlatformSecurityPanic();
       
   540 
       
   541 	aProcess->iFlags=flags^modified;
       
   542 
       
   543 	// if flags altered before resume, original thread inherits system critical and
       
   544 	// process critical from process.
       
   545 	if (!(aProcess->iAttributes & DProcess::EResumed))
       
   546 		{
       
   547 		TUint32& tf = aProcess->FirstThread()->iFlags;
       
   548 		tf = (tf &~ (KThreadFlagSystemCritical|KThreadFlagProcessCritical)) |
       
   549 			(aProcess->iFlags & (KThreadFlagSystemCritical|KThreadFlagProcessCritical));
       
   550 		}
       
   551 	}
       
   552 
       
   553 TInt ExecHandler::SemaphoreWait(DSemaphore* aSemaphore, TInt aTimeout)
       
   554 //
       
   555 // Wait for a signal.
       
   556 //
       
   557 	{
       
   558 
       
   559 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreWait"));
       
   560 	if (aTimeout)
       
   561 		{
       
   562 		if (aTimeout<0)
       
   563 			{
       
   564 			NKern::UnlockSystem();
       
   565 			return KErrArgument;
       
   566 			}
       
   567 
       
   568 		// Convert microseconds to NTimer ticks, rounding up
       
   569 		TInt ntp = NKern::TickPeriod();
       
   570 		aTimeout += ntp-1;
       
   571 		aTimeout /= ntp;
       
   572 		}
       
   573 	return aSemaphore->Wait(aTimeout);
       
   574 	}
       
   575 
       
   576 void ExecHandler::SemaphoreSignal1(DSemaphore* aSemaphore)
       
   577 //
       
   578 // Signal the semaphore once.
       
   579 //
       
   580 	{
       
   581 
       
   582 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreSignal1"));
       
   583 	aSemaphore->Signal();
       
   584 	}
       
   585 
       
   586 void ExecHandler::SemaphoreSignalN(DSemaphore* aSem, TInt aCount)
       
   587 //
       
   588 // Signal the semaphore aCount times.
       
   589 //
       
   590 	{
       
   591 
       
   592 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SemaphoreSignalN"));
       
   593 	aSem->CheckedOpen();
       
   594 	NKern::ThreadEnterCS();
       
   595 	aSem->SignalN(aCount);
       
   596 	NKern::UnlockSystem();
       
   597 	aSem->Close(NULL);
       
   598 	NKern::ThreadLeaveCS();
       
   599 	}
       
   600 
       
   601 TInt ExecHandler::ThreadId(DThread* aThread)
       
   602 //
       
   603 // Get thread ID.
       
   604 //
       
   605 	{
       
   606 
       
   607 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadId"));
       
   608 	return (TInt)aThread->iId;
       
   609 	}
       
   610 	
       
   611 LOCAL_C TBool IsThreadPriorityAbsoluteRealTime(TThreadPriority p)
       
   612 //
       
   613 // Returns true if priority is an absolute "real time" thread priority.
       
   614 //
       
   615 	{
       
   616 	switch(p)
       
   617 		{
       
   618 		case EPriorityAbsoluteRealTime1:
       
   619 		case EPriorityAbsoluteRealTime2:
       
   620 		case EPriorityAbsoluteRealTime3:
       
   621 		case EPriorityAbsoluteRealTime4:
       
   622 		case EPriorityAbsoluteRealTime5:
       
   623 		case EPriorityAbsoluteRealTime6:
       
   624 		case EPriorityAbsoluteRealTime7:
       
   625 		case EPriorityAbsoluteRealTime8:
       
   626 			return ETrue;
       
   627 		default:
       
   628 			return EFalse;
       
   629 		}
       
   630 	}
       
   631 
       
   632 void ExecHandler::ThreadResume(DThread* aThread)
       
   633 //
       
   634 // Resume a thread.
       
   635 //
       
   636 	{
       
   637 
       
   638 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadResume"));
       
   639 	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
   640 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Use of RThread::Resume on a thread in another process"));
       
   641 	aThread->Resume();
       
   642 	}
       
   643 
       
   644 TThreadPriority ExecHandler::ThreadPriority(DThread* aThread)
       
   645 //
       
   646 // Get the threads priority.
       
   647 //
       
   648 	{
       
   649 
       
   650 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadPriority"));
       
   651 	return ConvertThreadPriority(aThread->iThreadPriority);
       
   652 	}
       
   653 
       
   654 void ExecHandler::ThreadSetPriority(DThread* aThread,TThreadPriority aPriority)
       
   655 //
       
   656 // Set the threads priority.
       
   657 //
       
   658 	{
       
   659 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSetPriority"));
       
   660 	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
   661 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Use of RThread::SetPriority on a thread in a different process"));
       
   662 	if(IsThreadPriorityAbsoluteRealTime(aPriority) && 
       
   663 	   !(TheCurrentThread->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::SetPriority"))))
       
   664 		K::LockedPlatformSecurityPanic();
       
   665 	else
       
   666 		aThread->SetPriority(aPriority);
       
   667 	}
       
   668 
       
   669 TProcessPriority ExecHandler::ThreadProcessPriority(DThread* aThread)
       
   670 //
       
   671 // Get the owning process's priority.
       
   672 //
       
   673 	{
       
   674 
       
   675 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcessPriority"));
       
   676 	return procPriorityConvertTable[aThread->iOwningProcess->iPriority];
       
   677 	}
       
   678 
       
   679 void ExecHandler::ThreadSetProcessPriority(DThread* aThread, TProcessPriority aPriority)
       
   680 //
       
   681 // Set the owning process's priority.
       
   682 //
       
   683 	{
       
   684 	ExecHandler::ProcessSetPriority(aThread->iOwningProcess,aPriority);
       
   685 	}
       
   686 
       
   687 TUint ExecHandler::ThreadFlags(DThread* aThread)
       
   688 //
       
   689 // Get the threads flag state.
       
   690 //
       
   691 	{
       
   692 
       
   693 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadFlags"));
       
   694 	return(aThread->iFlags);
       
   695 	}
       
   696 
       
   697 void ExecHandler::ThreadSetFlags(DThread* aThread,TUint aClearMask,TUint aSetMask)
       
   698 //
       
   699 // Set the thread flags
       
   700 //
       
   701 	{
       
   702 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadSetFlags"));
       
   703 	TUint flags = aThread->iFlags;
       
   704 	TUint modified = ((flags&~aClearMask)|aSetMask);
       
   705 	modified = (modified^flags)&KDefinedThreadFlags;
       
   706 
       
   707 	DProcess* currentProcess=TheCurrentThread->iOwningProcess;
       
   708 
       
   709 	if (modified&KSelfOnlyThreadFlags)
       
   710 		if(aThread->iOwningProcess->iSecurityZone!=currentProcess->iSecurityZone)
       
   711 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to modify attributes of a thread in another process. Possibly RThread::SetSystem"));
       
   712 
       
   713 	if (modified&KRestrictedThreadFlags)
       
   714 		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetCritical (or RThread::SetSystem)")))
       
   715 			K::LockedPlatformSecurityPanic();
       
   716 
       
   717 	aThread->iFlags=flags^modified;
       
   718 	}
       
   719 
       
   720 TExitType ExecHandler::ThreadExitType(DThread* aThread)
       
   721 //
       
   722 // Return the exit type.
       
   723 //
       
   724 	{
       
   725 
       
   726 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitType"));
       
   727 	return (TExitType)aThread->iExitType;
       
   728 	}
       
   729 
       
   730 TInt ExecHandler::ThreadExitReason(DThread* aThread)
       
   731 //
       
   732 // Return the exit reason.
       
   733 //
       
   734 	{
       
   735 
       
   736 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitReason"));
       
   737 	return aThread->iExitReason;
       
   738 	}
       
   739 
       
   740 void ExecHandler::ThreadExitCategory(DThread* aThread, TDes8& aName)
       
   741 //
       
   742 // Return the category of the exit type.
       
   743 //
       
   744 	{
       
   745 
       
   746 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadExitCategory"));
       
   747 	TBufC<KMaxExitCategoryName> exitCat(aThread->iExitCategory);
       
   748 	NKern::UnlockSystem();
       
   749 	Kern::KUDesPut(aName,exitCat);
       
   750 	}
       
   751 
       
   752 void ExecHandler::ThreadRequestSignal(DThread* aThread)
       
   753 //
       
   754 // Signal a request completion.
       
   755 // Enter with system locked, return with system unlocked.
       
   756 //
       
   757 	{
       
   758 
       
   759 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRequestSignal"));
       
   760 	if(aThread->iOwningProcess!=TheCurrentThread->iOwningProcess)
       
   761 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Attempt to use RThread::RequestComplete on a thread in another process"));
       
   762 	NKern::ThreadRequestSignal(&aThread->iNThread, SYSTEM_LOCK);
       
   763 	}
       
   764 
       
   765 TInt ExecHandler::FindHandleOpen(TOwnerType aType, const TFindHandle& aFindHandle)
       
   766 	{
       
   767 
       
   768 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::FindHandleOpen"));
       
   769 	TFindHandle fh;
       
   770 	kumemget32(&fh,&aFindHandle,sizeof(fh));
       
   771 	NKern::ThreadEnterCS();
       
   772 	TInt h;
       
   773 	TInt r=TheCurrentThread->OpenFindHandle(aType,fh,h);
       
   774 	if(r==KErrNone)
       
   775 		r = h;
       
   776 	NKern::ThreadLeaveCS();
       
   777 	if (r==KErrBadHandle)
       
   778 		K::PanicKernExec(EBadHandle);
       
   779 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::FindHandleOpen returns %d",r));
       
   780 	return r;
       
   781 	}
       
   782 
       
   783 TInt ExecHandler::HandleClose(TInt aHandle)
       
   784 	{
       
   785 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleClose %08x",aHandle));
       
   786 	NKern::ThreadEnterCS();
       
   787 	TInt r=K::HandleClose(aHandle);
       
   788 	NKern::ThreadLeaveCS();
       
   789 	if (r==KErrBadHandle)
       
   790 		K::PanicKernExec(EBadHandle);
       
   791 	else if (r==DObject::EObjectUnmapped)
       
   792 		TheCurrentThread->iOwningProcess->WaitDllLock();
       
   793 	return r;
       
   794 	}
       
   795 
       
   796 TInt ExecHandler::LastThreadHandle()
       
   797 	{
       
   798 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LastThreadHandle"));
       
   799 	DThread& t=*TheCurrentThread;
       
   800 	NKern::ThreadEnterCS();
       
   801 	RObjectIx::Wait();
       
   802 	TInt r=t.iHandles.LastHandle();
       
   803 	RObjectIx::Signal();
       
   804 	NKern::ThreadLeaveCS();
       
   805 	if (r)
       
   806 		r|=KHandleFlagLocal;
       
   807 	return r;
       
   808 	}
       
   809 
       
   810 TInt ExecHandler::ChunkCreate(TOwnerType aType, const TDesC8* aName, TChunkCreate& anInfo)
       
   811 	{
       
   812 	TKName n;
       
   813 	if (aName)
       
   814 		Kern::KUDesGet(n,*aName);
       
   815 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkCreate %lS",&n));
       
   816 	TChunkCreate uinfo;
       
   817 	SChunkCreateInfo info;
       
   818 	kumemget32(&uinfo,&anInfo,sizeof(uinfo));
       
   819 	info.iGlobal=uinfo.iAtt & TChunkCreate::EGlobal;
       
   820 	info.iAtt = uinfo.iAtt&TChunkCreate::EChunkCreateAttMask;
       
   821 	info.iForceFixed=uinfo.iForceFixed;
       
   822 	info.iOperations=SChunkCreateInfo::EAdjust;	// adjust but don't add to process
       
   823 	info.iRunAddress=0;
       
   824 	info.iType=(uinfo.iAtt & TChunkCreate::ECode) ? EUserSelfModCode : EUserData;
       
   825 	info.iMaxSize=uinfo.iMaxSize;
       
   826 	info.iInitialBottom=uinfo.iInitialBottom;
       
   827 	info.iInitialTop=uinfo.iInitialTop;
       
   828 	info.iPreallocated=0;
       
   829 	info.iClearByte = uinfo.iClearByte;
       
   830 	DThread* pT=TheCurrentThread;
       
   831 	DProcess* pP=pT->iOwningProcess;
       
   832 	if (aName)
       
   833 		info.iName.Set(n);
       
   834 	else
       
   835 		info.iName.Set(NULL,0);
       
   836 	if (!info.iGlobal)
       
   837 		info.iOwner=(aType==EOwnerThread)?(DObject*)pT:(DObject*)pP;
       
   838 	else
       
   839 		info.iOwner=NULL;
       
   840 	NKern::ThreadEnterCS();
       
   841 	DChunk* pC=NULL;
       
   842 	TLinAddr addr;
       
   843 	TInt r=pP->NewChunk(pC,info,addr);
       
   844 	if (r==KErrNone)
       
   845 		r=K::MakeHandle(aType,pC);	// this will add the chunk to the process
       
   846 	if (r<KErrNone && pC)
       
   847 		pC->Close(NULL);				// can't have been added so NULL
       
   848 	NKern::ThreadLeaveCS();
       
   849 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ChunkCreate returns %d",r));
       
   850 	return r;
       
   851 	}
       
   852 
       
   853 TInt ExecHandler::ChunkSetRestrictions(DChunk* aChunk, TUint aRestrictions)
       
   854 	{
       
   855 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ChunkSetRestrictions %O flags=%x",aChunk,aRestrictions));
       
   856 	if(aChunk->iControllingOwner!=TheCurrentThread->iOwningProcess->iId)
       
   857 		return KErrAccessDenied;
       
   858 	aChunk->iRestrictions = aRestrictions;
       
   859 	return KErrNone;
       
   860 	}
       
   861 
       
   862 TInt ExecHandler::ChunkAdjust(DChunk* aChunk, TInt aType, TInt a1, TInt a2)
       
   863 	{
       
   864 	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ChunkAdjust %O type %d a1=%x a2=%x",aChunk,aType,a1,a2));
       
   865 	aChunk->CheckedOpen();
       
   866 	NKern::ThreadEnterCS();
       
   867 	NKern::UnlockSystem();
       
   868 	TInt r=KErrNone;
       
   869 	TInt s=aChunk->CheckAccess();
       
   870 	if (s!=KErrNone)
       
   871 		goto done;
       
   872 	if((aChunk->iRestrictions&EChunkPreventAdjust) && (aChunk->iControllingOwner!=TheCurrentThread->iOwningProcess->iId))
       
   873 		{
       
   874 		r=KErrAccessDenied;
       
   875 		goto done;
       
   876 		}
       
   877 	switch (aType)
       
   878 		{
       
   879 		case EChunkAdjust:
       
   880 			r=aChunk->Adjust(a1);
       
   881 			break;
       
   882 		case EChunkAdjustDoubleEnded:
       
   883 			r=aChunk->AdjustDoubleEnded(a1,a2);
       
   884 			break;
       
   885 		case EChunkCommit:
       
   886 			r=aChunk->Commit(a1,a2);
       
   887 			break;
       
   888 		case EChunkDecommit:
       
   889 			r=aChunk->Decommit(a1,a2);
       
   890 			break;
       
   891 		case EChunkAllocate:
       
   892 			r=aChunk->Allocate(a1);
       
   893 			break;
       
   894 		case EChunkLock:
       
   895 			if(&Kern::CurrentProcess()!=aChunk->iOwningProcess)
       
   896 				r = KErrAccessDenied;	
       
   897 			else
       
   898 				r=aChunk->Lock(a1,a2);
       
   899 			break;
       
   900 		case EChunkUnlock:
       
   901 			if(&Kern::CurrentProcess()!=aChunk->iOwningProcess)
       
   902 				r = KErrAccessDenied;	
       
   903 			else
       
   904 				r=aChunk->Unlock(a1,a2);
       
   905 			break;
       
   906 		default:
       
   907 			r=KErrArgument;
       
   908 			break;
       
   909 		}
       
   910 done:
       
   911 	aChunk->Close(NULL);		// NULL because we didn't up the process access count
       
   912 	NKern::ThreadLeaveCS();
       
   913 	if (s!=KErrNone)
       
   914 		K::PanicKernExec(EAccessDenied);
       
   915 	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ChunkAdjust returns %d",r));
       
   916 	return r;
       
   917 	}
       
   918 
       
   919 
       
   920 /**
       
   921 @return ETrue if the chunk is data paged, EFalse otherwise.
       
   922 */
       
   923 TBool ExecHandler::ChunkIsPaged(DChunk* aChunk)
       
   924 	{
       
   925 	return (aChunk->iAttributes & DChunk::EDataPaged) != 0;
       
   926 	}
       
   927 
       
   928 
       
   929 /**
       
   930 @return ETrue if the process is data paged, EFalse otherwise.
       
   931 */
       
   932 TBool ExecHandler::ProcessDefaultDataPaged(DProcess* aProcess)
       
   933 	{
       
   934 	return (aProcess->iAttributes & DProcess::EDataPaged) != 0;
       
   935 	}
       
   936 
       
   937 
       
   938 
       
   939 TInt ExecHandler::OpenObject(TObjectType aObjType, const TDesC8& aName, TOwnerType aType)
       
   940 	{
       
   941 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::OpenObject %lS",&aName));
       
   942 	TFullName n;
       
   943 	Kern::KUDesGet(n,aName);
       
   944 	if (Kern::ValidateFullName(n)!=KErrNone)
       
   945 		K::PanicKernExec(EBadName);
       
   946 	if ((TUint)aObjType>=(TUint)ENumObjectTypes)
       
   947 		K::PanicKernExec(EBadObjectType);
       
   948 	TInt h=0;
       
   949 	DObject* pO=NULL;
       
   950 	NKern::ThreadEnterCS();
       
   951 	TInt r=TheCurrentThread->OpenObject(aType,n,h,pO,aObjType);
       
   952 	NKern::ThreadLeaveCS();
       
   953 	if(r==KErrNone)
       
   954 		r = h;
       
   955 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::OpenObject returns %d",r));
       
   956 	return r;
       
   957 	}
       
   958 
       
   959 
       
   960 TInt ExecHandler::HandleDuplicate(TInt aThreadHandle, TOwnerType aType, TInt& aHandle)
       
   961 	{
       
   962 	TInt h;
       
   963 	kumemget32(&h, &aHandle, sizeof(h));
       
   964 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate %08x", h));
       
   965 	DThread* pC=TheCurrentThread;
       
   966 	NKern::LockSystem();
       
   967 	DThread* pT=(DThread*)K::ThreadEnterCS(aThreadHandle,EThread);
       
   968 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate source thread %O",pT));
       
   969 	TInt r=KErrBadHandle;
       
   970 	NKern::LockSystem();
       
   971 	DObject* pO=pT->ObjectFromHandle(h);
       
   972 	h = 0;	// now holds value to be returned
       
   973 	if (pO)
       
   974 		r=pO->Open();
       
   975 	NKern::UnlockSystem();
       
   976 	if (r==KErrNone)
       
   977 		{
       
   978 		if (pO->Protection()!=DObject::EGlobal
       
   979 			&& pT->iOwningProcess->iSecurityZone!=pC->iOwningProcess->iSecurityZone)
       
   980 			{
       
   981 #ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
       
   982 			r = PlatSec::ProcessIsolationFail(__PLATSEC_DIAGNOSTIC_STRING("Checked by RHandleBase::Duplicate"));
       
   983 #else //__REMOVE_PLATSEC_DIAGNOSTICS__
       
   984 			r = PlatSec::EmitDiagnostic();
       
   985 #endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
       
   986 			}
       
   987 		if (r==KErrNone)
       
   988 			r = pC->MakeHandle(aType, pO, h);	// this will add to process if necessary
       
   989 		if (r<KErrNone)
       
   990 			pO->Close(NULL);	// can't have been added to process so NULL
       
   991 		}
       
   992 	pT->Close(NULL);
       
   993 	TInt s = KErrNone;
       
   994 	XTRAP(s, XT_DEFAULT, kumemput32(&aHandle, &h, sizeof(h)));
       
   995 	if (s!=KErrNone && r==KErrNone)
       
   996 		pC->HandleClose(h);
       
   997 	NKern::ThreadLeaveCS();
       
   998 	if (r == KErrBadHandle)
       
   999 		K::PanicKernExec(EBadHandle);
       
  1000 	if (s != KErrNone)
       
  1001 		K::PanicKernExec(ECausedException);
       
  1002 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::HandleDuplicate returns %d",r));
       
  1003 	return r;
       
  1004 	}
       
  1005 
       
  1006 TInt ExecHandler::MutexCreate(const TDesC8* aName, TOwnerType aType)
       
  1007 	{
       
  1008 	TKName n;
       
  1009 	DObject* pO=NULL;
       
  1010 	const TDesC* pN=NULL;
       
  1011 	if (aName)
       
  1012 		{
       
  1013 		Kern::KUDesGet(n,*aName);
       
  1014 		pN=&n;
       
  1015 		}
       
  1016 	else if (aType==EOwnerThread)
       
  1017 		pO=TheCurrentThread;
       
  1018 	else
       
  1019 		pO=TheCurrentThread->iOwningProcess;
       
  1020 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::MutexCreate %lS",aName));
       
  1021 	NKern::ThreadEnterCS();
       
  1022 	DMutex* pM;
       
  1023 	TInt r=K::MutexCreate(pM, *pN, pO, ETrue, KMutexOrdUser);
       
  1024 	if (r==KErrNone)
       
  1025 		{
       
  1026 		if(aName)
       
  1027 			pM->SetProtection(n.Length()? DObject::EGlobal : DObject::EProtected);
       
  1028 		r=K::MakeHandle(aType,pM);
       
  1029 		if (r<KErrNone)
       
  1030 			pM->Close(NULL);
       
  1031 		}
       
  1032 	NKern::ThreadLeaveCS();
       
  1033 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::MutexCreate returns %d",r));
       
  1034 	return r;
       
  1035 	}
       
  1036 
       
  1037 TInt ExecHandler::SemaphoreCreate(const TDesC8* aName, TInt aCount, TOwnerType aType)
       
  1038 	{
       
  1039 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::SemaphoreCreate %lS",aName));
       
  1040 	TKName n;
       
  1041 	DObject* pO=NULL;
       
  1042 	const TDesC* pN=NULL;
       
  1043 	if (aName)
       
  1044 		{
       
  1045 		Kern::KUDesGet(n,*aName);
       
  1046 		pN=&n;
       
  1047 		}
       
  1048 	else if (aType==EOwnerThread)
       
  1049 		pO=TheCurrentThread;
       
  1050 	else
       
  1051 		pO=TheCurrentThread->iOwningProcess;
       
  1052 	NKern::ThreadEnterCS();
       
  1053 	TInt r=KErrNoMemory;
       
  1054 	DSemaphore* pS=new DSemaphore;
       
  1055 	if (pS)
       
  1056 		r=pS->Create(pO,pN,aCount);
       
  1057 	if (r==KErrNone)
       
  1058 		{
       
  1059 		if(aName)
       
  1060 			pS->SetProtection(n.Length()? DObject::EGlobal : DObject::EProtected);
       
  1061 		r=K::MakeHandle(aType,pS);
       
  1062 		}
       
  1063 	if (r<KErrNone && pS)
       
  1064 		pS->Close(NULL);
       
  1065 	NKern::ThreadLeaveCS();
       
  1066 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("Exec::SemaphoreCreate returns %d",r));
       
  1067 	return r;
       
  1068 	}
       
  1069 
       
  1070 LOCAL_C TInt OpenById(TUint anId, TOwnerType aType, TBool aProcess)
       
  1071 	{
       
  1072 	NKern::ThreadEnterCS();
       
  1073 	TInt type=aProcess?EProcess:EThread;
       
  1074 	DObjectCon* pC=K::Containers[type];
       
  1075 	pC->Wait();
       
  1076 	DObject* pO=aProcess?(DObject*)Kern::ProcessFromId(anId):(DObject*)Kern::ThreadFromId(anId);
       
  1077 	TInt r=KErrNotFound;
       
  1078 	if (pO && (r=pO->Open())==KErrNone)
       
  1079 		{
       
  1080 		pC->Signal();	// must release this before opening handle
       
  1081 		DProcess* pP;
       
  1082 		if(aProcess)
       
  1083 			pP=(DProcess*)pO;
       
  1084 		else
       
  1085 			pP=((DThread*)pO)->iOwningProcess;
       
  1086 
       
  1087 		if( pO->Protection()!=DObject::EGlobal
       
  1088 			&& pP->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
  1089 			{
       
  1090 #ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
       
  1091 			r = PlatSec::ProcessIsolationFail(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Open(TThreadId)"));
       
  1092 #else //__REMOVE_PLATSEC_DIAGNOSTICS__
       
  1093 			r = PlatSec::EmitDiagnostic();
       
  1094 #endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
       
  1095 			}
       
  1096 		if (r==KErrNone)
       
  1097 			r=K::MakeHandle(aType,pO);
       
  1098 		if (r<KErrNone)
       
  1099 			pO->Close(NULL);
       
  1100 		}
       
  1101 	else
       
  1102 		pC->Signal();
       
  1103 	NKern::ThreadLeaveCS();
       
  1104 	return r;
       
  1105 	}
       
  1106 
       
  1107 TInt ExecHandler::ThreadOpenById(TUint anId, TOwnerType aType)
       
  1108 	{
       
  1109 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ThreadOpenById %d",anId));
       
  1110 	TInt r=OpenById(anId,aType,EFalse);
       
  1111 	__KTRACE_OPT(KTHREAD,Kern::Printf("Exec::ThreadOpenById returns %d",r));
       
  1112 	return r;
       
  1113 	}
       
  1114 
       
  1115 TInt ExecHandler::ProcessOpenById(TUint anId, TOwnerType aType)
       
  1116 	{
       
  1117 	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ProcessOpenById %d",anId));
       
  1118 	TInt r=OpenById(anId,aType,ETrue);
       
  1119 	__KTRACE_OPT(KPROC,Kern::Printf("Exec::ProcessOpenById returns %d",r));
       
  1120 	return r;
       
  1121 	}
       
  1122 
       
  1123 // Enter with system locked, return with system unlocked
       
  1124 void ExecHandler::ThreadLogon(DThread* aThread, TRequestStatus* aStatus, TBool aRendezvous)
       
  1125 	{
       
  1126 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadLogon"));
       
  1127 	aThread->CheckedOpen();
       
  1128 	NKern::ThreadEnterCS();
       
  1129 	NKern::UnlockSystem();
       
  1130 	TInt r=aThread->Logon(aStatus,aRendezvous);
       
  1131 	if (r!=KErrNone)
       
  1132 		{
       
  1133 		if (r==KErrDied)
       
  1134 			r=aThread->iExitReason;
       
  1135 		Kern::RequestComplete(aStatus,r);
       
  1136 		}
       
  1137 	aThread->Close(NULL);
       
  1138 	NKern::ThreadLeaveCS();
       
  1139 	}
       
  1140 
       
  1141 // Enter with system locked, return with system unlocked
       
  1142 TInt ExecHandler::ThreadLogonCancel(DThread* aThread, TRequestStatus* aStatus, TBool aRendezvous)
       
  1143 	{
       
  1144 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadLogonCancel"));
       
  1145 	aThread->CheckedOpen();
       
  1146 	NKern::ThreadEnterCS();
       
  1147 	NKern::UnlockSystem();
       
  1148 	DThread& t = *TheCurrentThread;
       
  1149 	TUint32 type = TLogon::ETargetThread;
       
  1150 	if (aRendezvous)
       
  1151 		type |= TLogon::ERendezvous;
       
  1152 	TInt r = TLogon::Cancel(t.iOwnedLogons, aThread, aStatus, type);
       
  1153 	aThread->Close(NULL);
       
  1154 	NKern::ThreadLeaveCS();
       
  1155 	return r;
       
  1156 	}
       
  1157 
       
  1158 // Enter with system locked, return with system unlocked
       
  1159 void ExecHandler::ProcessLogon(DProcess* aProcess, TRequestStatus* aStatus, TBool aRendezvous)
       
  1160 	{
       
  1161 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessLogon"));
       
  1162 	aProcess->CheckedOpen();
       
  1163 	NKern::ThreadEnterCS();
       
  1164 	NKern::UnlockSystem();
       
  1165 	TInt r=aProcess->Logon(aStatus,aRendezvous);
       
  1166 	if (r!=KErrNone)
       
  1167 		{
       
  1168 		if (r==KErrDied)
       
  1169 			r=aProcess->iExitReason;
       
  1170 		Kern::RequestComplete(aStatus,r);
       
  1171 		}
       
  1172 	aProcess->Close(NULL);
       
  1173 	NKern::ThreadLeaveCS();
       
  1174 	}
       
  1175 
       
  1176 // Enter with system locked, return with system unlocked
       
  1177 TInt ExecHandler::ProcessLogonCancel(DProcess* aProcess, TRequestStatus* aStatus, TBool aRendezvous)
       
  1178 	{
       
  1179 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessLogonCancel"));
       
  1180 	aProcess->CheckedOpen();
       
  1181 	NKern::ThreadEnterCS();
       
  1182 	NKern::UnlockSystem();
       
  1183 	DThread& t = *TheCurrentThread;
       
  1184 	TUint32 type = TLogon::ETargetProcess;
       
  1185 	if (aRendezvous)
       
  1186 		type |= TLogon::ERendezvous;
       
  1187 	TInt r = TLogon::Cancel(t.iOwnedLogons, aProcess, aStatus, type);
       
  1188 	aProcess->Close(NULL);
       
  1189 	NKern::ThreadLeaveCS();
       
  1190 	return r;
       
  1191 	}
       
  1192 
       
  1193 TAny* ExecHandler::DllTls(TInt aHandle, TInt aDllUid)
       
  1194 	{
       
  1195 	// no protection needed since only this thread can access the TLS array
       
  1196 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllTls"));
       
  1197 #ifndef __EPOC32__
       
  1198 	extern TInt LookupDllUid(TInt);
       
  1199 
       
  1200 	if (aDllUid == KDllUid_Special)
       
  1201 		aDllUid = LookupDllUid(aHandle);
       
  1202 #endif
       
  1203 	return TheCurrentThread->Tls(aHandle,aDllUid);
       
  1204 	}
       
  1205 
       
  1206 TInt ExecHandler::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
       
  1207 	{
       
  1208 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllSetTls %08x->%08x", aHandle, aPtr));
       
  1209 #ifndef __EPOC32__
       
  1210 	extern TInt LookupDllUid(TInt);
       
  1211 
       
  1212 	if (aDllUid == KDllUid_Special)
       
  1213 		aDllUid = LookupDllUid(aHandle);
       
  1214 #endif
       
  1215 	NKern::ThreadEnterCS();
       
  1216 	TInt r=TheCurrentThread->SetTls(aHandle,aDllUid,aPtr);
       
  1217 	NKern::ThreadLeaveCS();
       
  1218 	return r;
       
  1219 	}
       
  1220 
       
  1221 void ExecHandler::DllFreeTls(TInt aHandle)
       
  1222 	{
       
  1223 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllFreeTls"));
       
  1224 	NKern::ThreadEnterCS();
       
  1225 	TheCurrentThread->FreeTls(aHandle);
       
  1226 	NKern::ThreadLeaveCS();
       
  1227 	}
       
  1228 
       
  1229 TInt ExecHandler::ThreadRename(TInt aHandle, const TDesC8& aName)
       
  1230 	{
       
  1231 	TKName n;
       
  1232 	Kern::KUDesGet(n,aName);
       
  1233 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRename %lS",&n));
       
  1234 	NKern::LockSystem();
       
  1235 	DThread* pT=(DThread*)K::ThreadEnterCS(aHandle,EThread);
       
  1236 	if (pT!=TheCurrentThread &&
       
  1237 		pT->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
  1238 		{
       
  1239 		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
       
  1240 			{
       
  1241 			pT->Close(NULL);
       
  1242 			K::ThreadLeaveCS();
       
  1243 			}
       
  1244 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Rename"));
       
  1245 		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
       
  1246 			Kern::Fault("ThreadRename",0);
       
  1247 		}
       
  1248 	TInt r=pT->Rename(n);
       
  1249 	pT->Close(NULL);
       
  1250 	NKern::ThreadLeaveCS();
       
  1251 	return r;
       
  1252 	}
       
  1253 
       
  1254 TInt ExecHandler::ProcessRename(TInt aHandle, const TDesC8& aName)
       
  1255 	{
       
  1256 	TKName n;
       
  1257 	Kern::KUDesGet(n,aName);
       
  1258 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessRename %lS",&n));
       
  1259 	NKern::LockSystem();
       
  1260 	DProcess* pP=(DProcess*)K::ThreadEnterCS(aHandle,EProcess);
       
  1261 	if (pP->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
  1262 		{
       
  1263 		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
       
  1264 			{
       
  1265 			pP->Close(NULL);
       
  1266 			K::ThreadLeaveCS();
       
  1267 			}
       
  1268 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RProcess::Rename"));
       
  1269 		if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecEnforcement)
       
  1270 			Kern::Fault("ProcessRename",0);
       
  1271 		}
       
  1272 	TInt r=pP->Rename(n);
       
  1273 	pP->Close(NULL);
       
  1274 	NKern::ThreadLeaveCS();
       
  1275 	return r;
       
  1276 	}
       
  1277 
       
  1278 TInt ExecHandler::ThreadProcess(DThread* aThread)
       
  1279 	{
       
  1280 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadProcess"));
       
  1281 	DProcess* pP=aThread->iOwningProcess;
       
  1282 	pP->Open();	// can't get an error here
       
  1283 	NKern::ThreadEnterCS();
       
  1284 	NKern::UnlockSystem();
       
  1285 	TInt r=K::MakeHandle(EOwnerThread,pP);
       
  1286 	if (r<KErrNone)
       
  1287 		pP->Close(NULL);
       
  1288 	NKern::ThreadLeaveCS();
       
  1289 	return r;
       
  1290 	}
       
  1291 
       
  1292 RAllocator* ExecHandler::ThreadGetHeap(DThread* aThread)
       
  1293 	{
       
  1294 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadGetHeap %O",aThread));
       
  1295 	if (aThread->iOwningProcess->iSecurityZone!=TheCurrentThread->iOwningProcess->iSecurityZone)
       
  1296 		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::Heap"));
       
  1297 	return aThread->iAllocator;
       
  1298 	}
       
  1299 
       
  1300 void ExecHandler::HandleName(TInt aHandle, TDes8& aName)
       
  1301 	{
       
  1302 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleName"));
       
  1303 	DObject* pO=NULL;
       
  1304 	TInt r=K::OpenObjectFromHandle(aHandle,pO);
       
  1305 	if (r!=KErrNone)
       
  1306 		K::PanicKernExec(EBadHandle);
       
  1307 	TKName n;
       
  1308 	pO->Name(n);
       
  1309 	pO->Close(NULL);
       
  1310 	NKern::ThreadLeaveCS();
       
  1311 	Kern::KUDesPut(aName,n);
       
  1312 	}
       
  1313 
       
  1314 void ExecHandler::HandleFullName(TInt aHandle, TDes8& aFullName)
       
  1315 	{
       
  1316 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleFullName"));
       
  1317 	DObject* pO=NULL;
       
  1318 	TInt r=K::OpenObjectFromHandle(aHandle,pO);
       
  1319 	if (r!=KErrNone)
       
  1320 		K::PanicKernExec(EBadHandle);
       
  1321 	TFullName n;
       
  1322 	pO->FullName(n);
       
  1323 	pO->Close(NULL);
       
  1324 	NKern::ThreadLeaveCS();
       
  1325 	Kern::KUDesPut(aFullName,n);
       
  1326 	}
       
  1327 
       
  1328 void ExecHandler::HandleCount(DThread* aThread, TInt& aProcessHandleCount, TInt& aThreadHandleCount)
       
  1329 	{
       
  1330 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleCount"));
       
  1331 	TInt tCount=aThread->iHandles.ActiveCount();
       
  1332 	TInt pCount=aThread->iOwningProcess->iHandles.ActiveCount();
       
  1333 	NKern::UnlockSystem();
       
  1334 	kumemput32(&aProcessHandleCount,&pCount,sizeof(pCount));
       
  1335 	kumemput32(&aThreadHandleCount,&tCount,sizeof(tCount));
       
  1336 	}
       
  1337 
       
  1338 TInt ExecHandler::GetBTraceId(DObject* aObj)
       
  1339 //
       
  1340 // Get the BTraceID of any given RHandleBase-derived object. In practice
       
  1341 // this ID is simply a pointer to the associated DObject.
       
  1342 //
       
  1343 	{
       
  1344 	return (TInt)aObj;
       
  1345 	}
       
  1346 
       
  1347 void ExecHandler::HandleInfo(TInt aHandle, THandleInfo* anInfo)
       
  1348 //
       
  1349 // Find out how many threads and processes have an open handle on the object given by 
       
  1350 // a handle, and whether it's open in this process and thread.
       
  1351 //
       
  1352 	{
       
  1353 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HandleInfo"));
       
  1354 	THandleInfo hinfo;
       
  1355 	memclr(&hinfo, sizeof(hinfo));
       
  1356 	DObject* pO=NULL;
       
  1357 	TInt r=K::OpenObjectFromHandle(aHandle,pO);
       
  1358 	if (r==KErrNone)
       
  1359 		{
       
  1360 		RObjectIx::Wait();
       
  1361 		DProcess* pCurrentProcess=TheCurrentThread->iOwningProcess;
       
  1362 		hinfo.iNumOpenInThread=TheCurrentThread->iHandles.Count(pO);
       
  1363 		hinfo.iNumOpenInProcess=pCurrentProcess->iHandles.Count(pO);
       
  1364 
       
  1365 		DObjectCon& threads=*K::Containers[EThread];
       
  1366 		threads.Wait();
       
  1367 		TInt c=threads.Count();
       
  1368 		TInt i=0;
       
  1369 		for (;i<c;i++)
       
  1370 			{
       
  1371 			DThread *pT=(DThread *)threads[i];
       
  1372 			TInt r=pT->iHandles.At(pO);
       
  1373 			if (r!=KErrNotFound)
       
  1374 				{
       
  1375 				++hinfo.iNumThreads;
       
  1376 				if (pT->iOwningProcess==pCurrentProcess)
       
  1377 					++hinfo.iNumOpenInProcess;
       
  1378 				}
       
  1379 			}
       
  1380 		threads.Signal();
       
  1381 		DObjectCon& processes=*K::Containers[EProcess];
       
  1382 		processes.Wait();
       
  1383 		c=processes.Count();
       
  1384 		for (i=0;i<c;i++)
       
  1385 			{
       
  1386 			DProcess *pP=(DProcess *)processes[i];
       
  1387 			TInt r=pP->iHandles.At(pO);
       
  1388 			if (r!=KErrNotFound)
       
  1389 				++hinfo.iNumProcesses;
       
  1390 			}
       
  1391 		processes.Signal();
       
  1392 		RObjectIx::Signal();
       
  1393 		pO->Close(NULL);
       
  1394 		NKern::ThreadLeaveCS();
       
  1395 		}
       
  1396 	kumemput32(anInfo,&hinfo,sizeof(hinfo));
       
  1397 	}
       
  1398 
       
  1399 TUint ExecHandler::HandleAttributes(TInt /*aHandle*/)
       
  1400 	{
       
  1401 	// NOT YET IMPLEMENTED
       
  1402 	return 0x0f;
       
  1403 	}
       
  1404 
       
  1405 TLibraryFunction ExecHandler::LibraryLookup(TInt aLibraryHandle, TInt aOrdinal)
       
  1406 	{
       
  1407 	TLibraryFunction f = NULL;
       
  1408 	NKern::LockSystem();
       
  1409 
       
  1410 XTRAP_PAGING_RETRY(
       
  1411 	DLibrary* library = (DLibrary*)K::ObjectFromHandle(aLibraryHandle,ELibrary);
       
  1412 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryLookup %O %d",library,aOrdinal));
       
  1413 	DCodeSeg* pS = library->iCodeSeg;
       
  1414 	if(pS)
       
  1415 		f = pS->Lookup(aOrdinal);
       
  1416 )
       
  1417 	NKern::UnlockSystem();
       
  1418 	return f;
       
  1419 	}
       
  1420 
       
  1421 /**
       
  1422 Retrieves pointer to the named symbol export data, if present.
       
  1423 	
       
  1424 @param aProcessHandle Handle to the process whose code seg to search
       
  1425 @return	Pointer to named symbol export data if its present, NULL otherwise
       
  1426 @internalComponent
       
  1427 */
       
  1428 TAny* ExecHandler::ProcessExeExportData(void)
       
  1429 	{
       
  1430 	DProcess* pP = &Kern::CurrentProcess();
       
  1431 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessExeExportData %O",pP));
       
  1432 	DCodeSeg* pS = pP->CodeSeg();	// can't be null if process is running
       
  1433 	
       
  1434 	// Lookup() returns NULL if this is not a stdexe/stddll
       
  1435 	return (TAny*)pS->Lookup(0);
       
  1436 	}
       
  1437 
       
  1438 void ExecHandler::LibraryType(DLibrary* aLibrary, TUidType& aUids)
       
  1439 	{
       
  1440 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryType"));
       
  1441 	TUidType uids;
       
  1442 	memclr(&uids, sizeof(uids));
       
  1443 	DCodeSeg* pS=aLibrary->iCodeSeg;
       
  1444 	if (pS)
       
  1445 		uids=pS->iUids;
       
  1446 	__KTRACE_OPT(KEXEC,Kern::Printf("UIDS: %08x,%08x,%08x",uids.iUid[0],uids.iUid[1],uids.iUid[2]));
       
  1447 	NKern::UnlockSystem();
       
  1448 	kumemput32(&aUids,&uids,sizeof(TUidType));
       
  1449 	}
       
  1450 
       
  1451 void ExecHandler::LibraryFileName(DLibrary* aLibrary, TDes8& aFileName)
       
  1452 	{
       
  1453 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryFileName"));
       
  1454 	TFileName fn;
       
  1455 	DCodeSeg* pS=aLibrary->iCodeSeg;
       
  1456 	if (pS)
       
  1457 		pS->AppendFullFileName(fn);
       
  1458 	NKern::UnlockSystem();
       
  1459 	P::NormalizeExecutableFileName(fn);
       
  1460 	Kern::KUDesPut(aFileName, fn);
       
  1461 	}
       
  1462 
       
  1463 TInt ExecHandler::HalFunction(TInt aGroup, TInt aFunction, TAny* a1, TAny* a2)
       
  1464 	{
       
  1465 	TInt aDeviceNumber = TUint(aGroup)>>16;
       
  1466 	aGroup=aGroup&0xffff;
       
  1467 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::HalFunction(%d,%d,%08x,%08x,%d)",aGroup,aFunction,a1,a2,aDeviceNumber));
       
  1468 	TInt r=KErrNotSupported;
       
  1469 	if(TUint(aDeviceNumber)>=TUint(KMaxHalEntries))
       
  1470 		return r;
       
  1471 	if (aGroup>=0 && aGroup<KMaxHalGroups)
       
  1472 		{
       
  1473 		SHalEntry2* pE=&K::HalEntryArray[aGroup];
       
  1474 		SHalEntry* pBase=(SHalEntry*)pE;
       
  1475 		THalFunc f=NULL;
       
  1476 		TAny* p=NULL;
       
  1477 		if(aDeviceNumber>0)
       
  1478 			{
       
  1479 			if(!pE->iExtendedEntries)
       
  1480 				return r;
       
  1481 			pBase=pE->iExtendedEntries + (aDeviceNumber-1);
       
  1482 			}
       
  1483 		NKern::LockSystem();
       
  1484 		f=pBase->iFunction;
       
  1485 		p=pBase->iPtr;
       
  1486 		NKern::UnlockSystem();
       
  1487 		if (f)
       
  1488 			r=(*f)(p,aFunction,a1,a2);
       
  1489 		}
       
  1490 	return r;
       
  1491 	}
       
  1492 
       
  1493 TUint32 ExecHandler::DebugMask()
       
  1494 	{
       
  1495 	return TheSuperPage().iDebugMask[0];
       
  1496 	}
       
  1497 
       
  1498 TUint32 ExecHandler::DebugMaskIndex(TUint aIndex)
       
  1499  	{
       
  1500 	if (aIndex >= (TUint)KNumTraceMaskWords) 
       
  1501 		return 0;	
       
  1502 	else
       
  1503 		return TheSuperPage().iDebugMask[aIndex];
       
  1504 	}
       
  1505 
       
  1506 void ExecHandler::SetDebugMask(TUint32 aVal)
       
  1507 	{
       
  1508 	TheSuperPage().iDebugMask[0]=(TInt)aVal;
       
  1509 	}
       
  1510 
       
  1511 void ExecHandler::SetDebugMaskIndex(TUint32 aVal, TUint aIndex)
       
  1512 	{
       
  1513 	if (aIndex >= (TUint)KNumTraceMaskWords) return;
       
  1514 	
       
  1515 	// check that we have permission to set KALLTHREADSSYSTEM bit
       
  1516 	if (aIndex == DEBUGMASKWORD2 && (aVal & (1 << (KALLTHREADSSYSTEM%32))))
       
  1517 		{
       
  1518 		DProcess* currentProcess=TheCurrentThread->iOwningProcess;
       
  1519 		if(!currentProcess->HasCapability(ECapabilityProtServ,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetDebugMask(TUint32, TUint)")))
       
  1520 			K::UnlockedPlatformSecurityPanic();
       
  1521 		}
       
  1522 
       
  1523 	TheSuperPage().iDebugMask[aIndex]=(TInt)aVal;
       
  1524 	}
       
  1525 
       
  1526 RAllocator* ExecHandler::HeapSwitch(RAllocator* aA)
       
  1527 	{
       
  1528 	DThread* pT = TheCurrentThread;
       
  1529 	RAllocator* pA = pT->iAllocator;
       
  1530 	pT->iAllocator = aA;
       
  1531 	if (!pT->iCreatedAllocator)
       
  1532 		pT->iCreatedAllocator = aA;
       
  1533 	return pA;
       
  1534 	}
       
  1535 
       
  1536 void ExecHandler::KernelHeapDebug(TInt aFunction, TInt a1, TAny* a2)
       
  1537 	{
       
  1538 	(void)aFunction;
       
  1539 	(void)a1;
       
  1540 	(void)a2;
       
  1541 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::KernelHeapDebug %d,%08x,%08x",aFunction,a1,a2));
       
  1542 #ifdef _DEBUG
       
  1543 	TInt panic=KMinTInt;
       
  1544 	switch (aFunction)
       
  1545 		{
       
  1546 		case EDbgMarkStart:
       
  1547 			NKern::ThreadEnterCS();
       
  1548 			K::Allocator->__DbgMarkStart();
       
  1549 			NKern::ThreadLeaveCS();
       
  1550 			break;
       
  1551 
       
  1552 		case EDbgMarkCheck:
       
  1553 			{
       
  1554 			TBuf8<KMaxFileName> name;
       
  1555 			TKernelHeapMarkCheckInfo info;
       
  1556 			kumemget32(&info,a2,sizeof(info));
       
  1557 			Kern::KUDesGet(name,*info.iFileName);
       
  1558 			NKern::ThreadEnterCS();
       
  1559 			TInt r = K::Allocator->__DbgMarkCheck(info.iCountAll, a1, name, info.iLineNum);
       
  1560 			if (r!=KErrNone)
       
  1561 				panic=EFailedKernelHeapCheck;
       
  1562 			NKern::ThreadLeaveCS();
       
  1563 			break;
       
  1564 			}
       
  1565 
       
  1566 		case EDbgMarkEnd:
       
  1567 			{
       
  1568 			NKern::ThreadEnterCS();
       
  1569 			TInt r = K::Allocator->__DbgMarkEnd(a1);
       
  1570 			if (r!=KErrNone)
       
  1571 				panic=EFailedKernelHeapCheck;
       
  1572 			NKern::ThreadLeaveCS();
       
  1573 			break;
       
  1574 			}
       
  1575 
       
  1576 		case EDbgSetAllocFail:
       
  1577 			NKern::ThreadEnterCS();
       
  1578 			K::Allocator->__DbgSetAllocFail((RAllocator::TAllocFail)a1,(TInt)a2);
       
  1579 			NKern::ThreadLeaveCS();
       
  1580 			break;
       
  1581 
       
  1582 		case EDbgSetBurstAllocFail:
       
  1583 			{
       
  1584 			SRAllocatorBurstFail burstFail;
       
  1585 			kumemget32(&burstFail, a2, sizeof(SRAllocatorBurstFail));
       
  1586 			NKern::ThreadEnterCS();
       
  1587 			K::Allocator->__DbgSetBurstAllocFail((RAllocator::TAllocFail)a1, burstFail.iRate, burstFail.iBurst);
       
  1588 			NKern::ThreadLeaveCS();
       
  1589 			break;
       
  1590 			}
       
  1591 
       
  1592 		case EDbgCheckFailure:
       
  1593 			{
       
  1594 			NKern::ThreadEnterCS();
       
  1595 			TUint failures = K::Allocator->__DbgCheckFailure();
       
  1596 			NKern::ThreadLeaveCS();
       
  1597 			kumemput32(a2, (TAny*)&failures, sizeof(TUint));
       
  1598 			break;
       
  1599 			}
       
  1600 
       
  1601 		default:
       
  1602 			panic=EBadKernelHeapDebugFunction;
       
  1603 			break;
       
  1604 		}
       
  1605 	if (panic>KMinTInt)
       
  1606 		K::PanicKernExec(panic);
       
  1607 #endif
       
  1608 	}
       
  1609 
       
  1610 TExceptionHandler ExecHandler::ExceptionHandler(DThread* aThread)
       
  1611 	{
       
  1612 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ExceptionHandler"));
       
  1613 	if(aThread!=TheCurrentThread)
       
  1614 		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1615 			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1616 			)
       
  1617 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::ExceptionHandler"));
       
  1618 	return aThread->iExceptionHandler;
       
  1619 	}
       
  1620 
       
  1621 TInt ExecHandler::SetExceptionHandler(DThread* aThread, TExceptionHandler aHandler, TUint32 aMask)
       
  1622 	{
       
  1623 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetExceptionHandler"));
       
  1624 	if(aThread!=TheCurrentThread)
       
  1625 		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1626 			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1627 			)
       
  1628 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::SetExceptionHandler"));
       
  1629 	aThread->iExceptionHandler=aHandler;
       
  1630 	aThread->iExceptionMask=aMask;
       
  1631 	return KErrNone;
       
  1632 	}
       
  1633 
       
  1634 void ExecHandler::ModifyExceptionMask(DThread* aThread, TUint32 aClearMask, TUint32 aSetMask)
       
  1635 	{
       
  1636 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ModifyExceptionMask"));
       
  1637 	if(aThread!=TheCurrentThread)
       
  1638 		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1639 			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1640 			)
       
  1641 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::ModifyExceptionMask"));
       
  1642 	TUint& m=aThread->iExceptionMask;
       
  1643 	m=(m&~aClearMask)|aSetMask;
       
  1644 	}
       
  1645 
       
  1646 TInt ExecHandler::RaiseException(DThread* aThread, TExcType aType)
       
  1647 	{
       
  1648 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RaiseException %d on %O",aType,aThread));
       
  1649 	if(aThread!=TheCurrentThread)
       
  1650 		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1651 			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1652 			)
       
  1653 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::RaiseException"));
       
  1654 	return aThread->RaiseException(aType);
       
  1655 	}
       
  1656 
       
  1657 TBool ExecHandler::IsExceptionHandled(DThread* aThread,TExcType aType, TBool aSwExcInProgress)
       
  1658 	{
       
  1659 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::IsExceptionHandled %d %d",aType,aSwExcInProgress));
       
  1660 	if(aThread!=TheCurrentThread)
       
  1661 		if(TheCurrentThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1662 			|| aThread->iOwningProcess->iSecurityZone!=KSecurityZoneLegacyCode
       
  1663 			)
       
  1664 			K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by RThread::IsExceptionHandled"));
       
  1665 	TBool isHandled=aThread->IsExceptionHandled(aType);
       
  1666 	NKern::UnlockSystem();
       
  1667 	if (aSwExcInProgress)
       
  1668 		DKernelEventHandler::Dispatch(EEventSwExc, (TAny*)aType, NULL);
       
  1669 	return isHandled;
       
  1670 	}
       
  1671 
       
  1672 void ExecHandler::ThreadContext(DThread* aThread, TDes8& aDes)
       
  1673 	{
       
  1674 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadContext %O",aThread));
       
  1675 	TBuf8<KMaxThreadContext> c;
       
  1676 	aThread->Context(c);
       
  1677 	NKern::UnlockSystem();
       
  1678 	Kern::InfoCopy(aDes,c);
       
  1679 	}
       
  1680 
       
  1681 TInt ExecHandler::ThreadStackInfo(DThread* aThread, TThreadStackInfo& aInfo)
       
  1682 	{
       
  1683 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadStackInfo %O",aThread));
       
  1684 	TThreadStackInfo info;
       
  1685 	memclr(&info, sizeof(info));
       
  1686 	TInt r=KErrGeneral;
       
  1687 	if(aThread->iUserStackRunAddress)
       
  1688 		{
       
  1689 		info.iBase = aThread->iUserStackRunAddress+aThread->iUserStackSize;
       
  1690 		info.iLimit = aThread->iUserStackRunAddress;
       
  1691 		info.iExpandLimit = aThread->iUserStackRunAddress;
       
  1692 		r = KErrNone;
       
  1693 		}
       
  1694 	NKern::UnlockSystem();
       
  1695 	kumemput32(&aInfo,&info,sizeof(info));
       
  1696 	return r;
       
  1697 	}
       
  1698 
       
  1699 TInt ExecHandler::ProcessGetMemoryInfo(TInt aProcessHandle, TModuleMemoryInfo& aInfo)
       
  1700 	{
       
  1701 	TModuleMemoryInfo info;
       
  1702 	memclr(&info, sizeof(info));
       
  1703 	TInt r = KErrGeneral;
       
  1704 	NKern::LockSystem();
       
  1705 
       
  1706 XTRAP_PAGING_RETRY(
       
  1707 	DProcess* process = (DProcess*)K::ObjectFromHandle(aProcessHandle,EProcess);
       
  1708 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessGetMemoryInfo %O",process));
       
  1709 	DCodeSeg* seg=process->iCodeSeg;
       
  1710 	if(seg)
       
  1711 		r = seg->GetMemoryInfo(info,TheCurrentThread->iOwningProcess);
       
  1712 )
       
  1713 	NKern::UnlockSystem();
       
  1714 	kumemput32(&aInfo, &info, sizeof(info));
       
  1715 	return r;
       
  1716 	}
       
  1717 
       
  1718 TInt ExecHandler::LibraryGetMemoryInfo(TInt aLibraryHandle, TModuleMemoryInfo& aInfo)
       
  1719 	{
       
  1720 	TModuleMemoryInfo info;
       
  1721 	memclr(&info, sizeof(info));
       
  1722 	TInt r = KErrGeneral;
       
  1723 	NKern::LockSystem();
       
  1724 
       
  1725 XTRAP_PAGING_RETRY(
       
  1726 	DLibrary* library = (DLibrary*)K::ObjectFromHandle(aLibraryHandle,ELibrary);
       
  1727 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LibraryGetMemoryInfo %O",library));
       
  1728 	DCodeSeg* seg=library->iCodeSeg;
       
  1729 	if(seg)
       
  1730 		r = seg->GetMemoryInfo(info,TheCurrentThread->iOwningProcess);
       
  1731 )
       
  1732 	NKern::UnlockSystem();
       
  1733 	kumemput32(&aInfo, &info, sizeof(info));
       
  1734 	return r;
       
  1735 	}
       
  1736 
       
  1737 void AccessMachineConfig()
       
  1738 	{
       
  1739 	NKern::ThreadEnterCS();
       
  1740 	Kern::MutexWait(*K::MachineConfigMutex);
       
  1741 	}
       
  1742 
       
  1743 void EndAccessMachineConfig()
       
  1744 	{
       
  1745 	Kern::MutexSignal(*K::MachineConfigMutex);
       
  1746 	NKern::ThreadLeaveCS();
       
  1747 	}
       
  1748 
       
  1749 TInt ExecHandler::MachineConfiguration(TDes8& aConfig, TInt& aSize)
       
  1750 //
       
  1751 // Get the machine configuration
       
  1752 // Enter and leave with system unlocked
       
  1753 //
       
  1754 	{
       
  1755 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::MachineConfiguration"));
       
  1756 	if(!Kern::CurrentThreadHasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::MachineConfiguration")))
       
  1757 		K::UnlockedPlatformSecurityPanic();
       
  1758     const TPtrC8 platConfig(A::MachineConfiguration());
       
  1759     TInt platSize=platConfig.Length();
       
  1760 	TInt usize=sizeof(TUid)+sizeof(TVersion)+sizeof(platSize)+platSize;
       
  1761 
       
  1762 	TInt ulen, umax;
       
  1763 	Kern::KUDesInfo(aConfig,ulen,umax);
       
  1764 	TInt r = KErrArgument;
       
  1765 	if(umax<usize)
       
  1766 		goto done; // user buffer not big enough
       
  1767 
       
  1768 	// create tempory  buffer for config data
       
  1769 	{
       
  1770 	DThread& t=*TheCurrentThread;
       
  1771 	NKern::ThreadEnterCS();
       
  1772 	TUint8* buf=(TUint8*)Kern::Alloc(usize);
       
  1773 	t.iTempAlloc=buf;			// if we are killed, buf will be deleted
       
  1774 	NKern::ThreadLeaveCS();
       
  1775 	r = KErrNoMemory;
       
  1776 	if (!buf)
       
  1777 		goto done; // no memory
       
  1778 
       
  1779 	// get config data
       
  1780 	{
       
  1781 	TUint8* p=buf;
       
  1782 	*((TUid*&)p)++ = KMachineConfigurationUid;
       
  1783 	*((TVersion*&)p)++ = TVersion(KMachineConfigurationMajorVersionNumber,KMachineConfigurationMinorVersionNumber,KMachineConfigurationBuildVersionNumber);
       
  1784 	*((TInt*&)p)++ = platSize;
       
  1785 	AccessMachineConfig();
       
  1786 	NKern::LockSystem();
       
  1787 	memcpy(p,platConfig.Ptr(),platSize);
       
  1788 	NKern::UnlockSystem();
       
  1789 	EndAccessMachineConfig();
       
  1790 
       
  1791 	Kern::KUDesPut(aConfig,TPtrC8(buf,usize));
       
  1792 
       
  1793 	NKern::ThreadEnterCS();
       
  1794 	t.iTempAlloc=NULL;
       
  1795 	delete buf;
       
  1796 	NKern::ThreadLeaveCS();
       
  1797 
       
  1798 	r = KErrNone;
       
  1799 	}
       
  1800 	}
       
  1801 done:
       
  1802 	kumemput32(&aSize,&usize,sizeof(usize));
       
  1803 	return r;
       
  1804 	}
       
  1805 
       
  1806 TInt ExecHandler::SetMachineConfiguration(const TDesC8& aConfig)
       
  1807 //
       
  1808 // Set the machine configuration
       
  1809 // Enter and leave with system unlocked
       
  1810 //
       
  1811 	{
       
  1812 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetMachineConfiguration"));
       
  1813 	if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by User::SetMachineConfiguration")))
       
  1814 		K::UnlockedPlatformSecurityPanic();
       
  1815 	TInt len;
       
  1816 	TInt maxLen;
       
  1817 	const TUint8* pC=Kern::KUDesInfo(aConfig,len,maxLen);
       
  1818 	TInt r=KErrNoMemory;
       
  1819 	TUint8* pB=NULL;
       
  1820     TPckgBuf<TUid> uid;
       
  1821     TPckgBuf<TVersion> version;
       
  1822     TPckgBuf<TInt> platSizeBuf;
       
  1823 	TInt platSize;
       
  1824 	TInt i=0;
       
  1825 	TPtrC8 platConfig;
       
  1826 	DThread& t=*TheCurrentThread;
       
  1827 
       
  1828 	// first allocate a kernel-side buffer big enough to hold the new configuration
       
  1829 	NKern::ThreadEnterCS();
       
  1830 	pB=(TUint8*)Kern::Alloc(len);
       
  1831 	if (!pB)
       
  1832 		goto endSetMachineConfig2;
       
  1833 	t.iTempAlloc=pB;			// if we are killed, pB will be deleted
       
  1834 	NKern::ThreadLeaveCS();
       
  1835 
       
  1836 	// copy the configuration
       
  1837 	kumemget(pB,pC,len);
       
  1838 	r=KErrArgument;
       
  1839 	if (len<(TInt)(sizeof(TUid)+sizeof(TVersion)+sizeof(TInt)))
       
  1840 		goto endSetMachineConfig;
       
  1841 
       
  1842 	// extract and check the UID
       
  1843 	uid.Copy(pB+i,(TInt)sizeof(TUid));
       
  1844     if (uid().iUid!=KMachineConfigurationUidValue)
       
  1845 		goto endSetMachineConfig;
       
  1846 	i+=(TInt)sizeof(TUid);
       
  1847 
       
  1848 	// extract and check the version
       
  1849 	version.Copy(pB+i,(TInt)sizeof(TVersion));
       
  1850 	r=KErrNotSupported;
       
  1851     if(!Kern::QueryVersionSupported(TVersion(KMachineConfigurationMajorVersionNumber,KMachineConfigurationMinorVersionNumber,KMachineConfigurationBuildVersionNumber),version()))
       
  1852 		goto endSetMachineConfig;
       
  1853 	i+=(TInt)sizeof(TVersion);
       
  1854 
       
  1855 	// extract and check the super page size
       
  1856 	platSizeBuf.Copy(pB+i,(TInt)sizeof(TInt));
       
  1857 	i+=(TInt)sizeof(TInt);
       
  1858 	platSize=platSizeBuf();
       
  1859 	r=KErrArgument;
       
  1860     if (platSize>(len-i))
       
  1861 		goto endSetMachineConfig;
       
  1862 
       
  1863 	platConfig.Set(pB+i,platSize);
       
  1864 
       
  1865 	// restore the super page config
       
  1866 	AccessMachineConfig();
       
  1867 	K::SetMachineConfiguration(platConfig);
       
  1868 	r=KErrNone;
       
  1869 	EndAccessMachineConfig();
       
  1870 
       
  1871 endSetMachineConfig:
       
  1872 	NKern::ThreadEnterCS();
       
  1873 	t.iTempAlloc=NULL;
       
  1874 	delete pB;
       
  1875 endSetMachineConfig2:
       
  1876 	NKern::ThreadLeaveCS();
       
  1877 	return r;
       
  1878 	}
       
  1879 
       
  1880 TInt ExecHandler::ThreadCreate(const TDesC8& aName, TOwnerType aType, SThreadCreateInfo& aInfo)
       
  1881 	{
       
  1882 	TKName n;
       
  1883 	Kern::KUDesGet(n,aName);
       
  1884 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadCreate %lS",&n));
       
  1885 	TUint32 infoBuf[KMaxThreadCreateInfo/sizeof(TUint32)];
       
  1886 	SThreadCreateInfo& info = *(SThreadCreateInfo*)infoBuf;
       
  1887 	kumemget32(&info, &aInfo, sizeof(SThreadCreateInfo));
       
  1888 	TInt r = ( (info.iTotalSize < (TInt)sizeof(SThreadCreateInfo)) || (info.iTotalSize > KMaxThreadCreateInfo) || (info.iTotalSize & 7) )
       
  1889 		? KErrArgument : KErrNone;
       
  1890 	if (info.iUserStackSize < KMaxThreadCreateInfo*2)
       
  1891 		r=KErrArgument;
       
  1892 	if (r==KErrNone)
       
  1893 		{
       
  1894 		if (info.iTotalSize > (TInt)sizeof(SThreadCreateInfo))
       
  1895 			kumemget32( (&info)+1, (&aInfo)+1, info.iTotalSize-(TInt)sizeof(SThreadCreateInfo) );
       
  1896 		info.iType=EThreadUser;
       
  1897 		info.iSupervisorStackSize=0;	// zero means use default value
       
  1898 		info.iSupervisorStack=NULL;
       
  1899 		info.iInitialThreadPriority=EThrdPriorityNormal;
       
  1900 		info.iName.Set(n);
       
  1901 		NKern::ThreadEnterCS();
       
  1902 		DThread* pT=NULL;
       
  1903 		TInt h;
       
  1904 		r=TheCurrentThread->iOwningProcess->NewThread(pT, info, &h, aType);
       
  1905 		if(r==KErrNone)
       
  1906 			r = h;
       
  1907 		NKern::ThreadLeaveCS();
       
  1908 		}
       
  1909 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadCreate returns %d",r));
       
  1910 	return r;
       
  1911 	}
       
  1912 
       
  1913 /********************************************
       
  1914  * Kernel-side executive calls
       
  1915  ********************************************/
       
  1916 
       
  1917 TInt K::MutexCreate(DMutex*& aMutex, const TDesC& aName, DObject* anOwner, TBool aVisible, TUint aOrder)
       
  1918 	{
       
  1919 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("K::MutexCreate %lS owner %O visible=%d order=%02x",&aName,anOwner,aVisible,aOrder));
       
  1920 	DMutex* pM=new DMutex;
       
  1921 	TInt r=KErrNoMemory;
       
  1922 	if (pM)
       
  1923 		{
       
  1924 		r=pM->Create(anOwner, &aName, aVisible, aOrder);
       
  1925 		if (r==KErrNone)
       
  1926 			aMutex=pM;
       
  1927 		else
       
  1928 			pM->Close(NULL);
       
  1929 		}
       
  1930 	__KTRACE_OPT(KSEMAPHORE,Kern::Printf("K::MutexCreate returns %d %08x",r,pM));
       
  1931 	return r;
       
  1932 	}
       
  1933 
       
  1934 /**	Creates a new thread.
       
  1935 
       
  1936 	It receives a parameter of type SThreadCreateInfo. The members of this structure have the following meaning for this function:
       
  1937 
       
  1938 	iHandle	[out]	Heap allocated DThread pointer to the new created thread.
       
  1939 					This member is valid only if the return code is KErrNone.
       
  1940 					Do not assume it's NULL if the operation failed.
       
  1941 	iType	[in]	Specifies if the thread will run in User mode or in Kernel mode.
       
  1942 					It can be one of:
       
  1943 						EThreadInitial - this is the initial thread
       
  1944 						EThreadSupervisor - this runs in supervisor mode
       
  1945 						EThreadMinimalSupervisor - this runs in supervisor mode and has no handles array
       
  1946 						EThreadUser - this runs in User Mode
       
  1947 						EThreadAPInitial - this is the initial thread on a non-boot processor (SMP only)
       
  1948 	iFunction [in]	This is the function that will be run in the new thread.
       
  1949 	iPtr	[in]	Extra custom parameters passed to iFunction when it starts running.
       
  1950 	iSupervisorStack	Ignored.
       
  1951 	iSupervisorStackSize [in]	If the thread is a Kernel thread, this parameter will specify the desired supervisor stack size.
       
  1952 								If the size is 0, the size will be specified by K::SupervisorThreadStackSize, which is 4K.
       
  1953 								The size will be rounded up to Page or Block size.
       
  1954 	iUserStack			Ignored.
       
  1955 	iUserStackSize [in]	If the thread is a User Mode thread, this parameter will specify the desired user stack size.
       
  1956 						The size will be rounded up to Page or Block size.
       
  1957 						It will fail with KErrTooBig if the size is greater than PP::MaxUserThreadStack which is usually set to 0x14000 (80K).
       
  1958 	iInitialThreadPriority [in] Initial priority for this thread. Must be in [0,63] interval.
       
  1959 	iName	[in]	Name of the thread. In case you do not specify a name for this thread, it will be created EProtected
       
  1960 					and any attempts to open it will fail with KErrPermissionDenied. Otherwise, the object will be EGlobal.
       
  1961 	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.
       
  1962 
       
  1963 	It can fail with KErrArgument if aInfo.iTotalSize is not set correctly or aInfo.iPriority is not in [0,63] interval
       
  1964 	In x86 port it can fail with KErrArgument if anInfo.iStackBase is NULL or anInfo.iStackSize is less than 0x100
       
  1965 	It can fail with KErrTooBig if aInfo.iUserStackSize is bigger than maximum user stack size
       
  1966 	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
       
  1967 	It can fail with KErrDied if the thread dies during the creation process
       
  1968 	It can fail with KErrNoMemory in OOM scenarios.
       
  1969 	It can fail with KErrGeneral indicating a general malfunction or data corruption.
       
  1970 	
       
  1971 	If it succeeds it will return the heap allocated DThread pointer to the new created thread in iHandle member of aInfo
       
  1972 	  
       
  1973 	@param aInfo Information passed by the caller to specify how to create the thread.
       
  1974 	
       
  1975 	@pre Calling thread must be in a critical section.
       
  1976 	@pre Call in a thread context.
       
  1977 	@pre Kernel must be unlocked.
       
  1978 	@pre interrupts enabled
       
  1979 	@pre No fast mutex can be held
       
  1980 	
       
  1981 	@post Calling thread is in a critical section.
       
  1982 */
       
  1983 EXPORT_C TInt Kern::ThreadCreate(SThreadCreateInfo& aInfo)
       
  1984 	{
       
  1985 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Kern::ThreadCreate");		
       
  1986 	__KTRACE_OPT(KEXEC,Kern::Printf("Kern::ThreadCreate %lS",&aInfo.iName));
       
  1987 	aInfo.iHandle=NULL;
       
  1988 	DThread* pT=NULL;
       
  1989 	TBool svc = aInfo.iType!=EThreadUser;
       
  1990 	DProcess* pP = svc ? K::TheKernelProcess : TheCurrentThread->iOwningProcess;
       
  1991 	aInfo.iSupervisorStack = NULL;
       
  1992 	aInfo.iUserStack = NULL;
       
  1993 	TInt r = pP->NewThread(pT, aInfo, NULL, EOwnerProcess);
       
  1994 	if (r==KErrNone)
       
  1995 		aInfo.iHandle = pT;
       
  1996 	__KTRACE_OPT(KEXEC,Kern::Printf("Kern::ThreadCreate returns %d",r));
       
  1997 	return r;
       
  1998 	}
       
  1999 
       
  2000 #ifdef _UNICODE
       
  2001 void ccopy (TUint16* aDest, const TAny* aSrc)
       
  2002 {
       
  2003 	TUint16* pSrc = (TUint16*)aSrc;
       
  2004 	if(aSrc) {
       
  2005 		TUint16* p = aDest + 1;
       
  2006 		for (;*pSrc;)
       
  2007 			*p++ = *pSrc++;
       
  2008 		*aDest = (TUint16)(p-aDest-1);
       
  2009 	}
       
  2010 	else
       
  2011 		*aDest = 0;	
       
  2012 }
       
  2013 #else
       
  2014 void ccopy (TUint8* aDest, const TAny* aSrc)
       
  2015 {
       
  2016 	TUint8* pSrc = (TUint8*)aSrc;
       
  2017 	if(aSrc) {
       
  2018 		TUint8* p = aDest + 1;
       
  2019 		for (;*pSrc;)
       
  2020 			*p++ = *pSrc++;
       
  2021 		*aDest = (TUint8)(p-aDest-1);
       
  2022 	}
       
  2023 	else
       
  2024 		*aDest = 0;	
       
  2025 }
       
  2026 #endif
       
  2027 
       
  2028 TInt ExecHandler::GetModuleNameFromAddress(TAny* aPtr, TDes8& aModuleName)
       
  2029 	{
       
  2030 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::GetModuleNameFromAddress 0x%X", aPtr));
       
  2031 	TFileName fn;
       
  2032 	Kern::AccessCode();
       
  2033 	DCodeSeg* pSeg = Kern::CodeSegFromAddress( (TLinAddr)aPtr, TheCurrentThread->iOwningProcess );
       
  2034 	if (pSeg)
       
  2035 		pSeg->AppendFullFileName(fn);
       
  2036 	Kern::EndAccessCode();
       
  2037 	if (!pSeg)
       
  2038 		{
       
  2039  		return KErrNotFound;
       
  2040 		}
       
  2041 	Kern::KUDesPut(aModuleName, fn);
       
  2042 	return KErrNone;
       
  2043 	}
       
  2044 
       
  2045 TInt ExecHandler::LocaleExports(TAny* aHandle, TLibraryFunction* aExportList)
       
  2046 //
       
  2047 // Change Locale setups
       
  2048 //
       
  2049 // NOTES
       
  2050 //
       
  2051 // 1. A mutex is NOT used to protect this, so if it is called by more than one thread
       
  2052 //    simultaneousely, the locale info may be garbled.
       
  2053 // 2. Locale libraries are never closed once they have been used. This prevents them from
       
  2054 //    being unloaded whilst other threads are referencing the data contained in them.
       
  2055 // 3. This function doesn't duplicate the EKA1 behaviour of saving the default data for
       
  2056 //    restoring later.
       
  2057 //
       
  2058 // The current use case for this function is that it is called once by WSERV after boot,
       
  2059 // so the above points should never be a problem. ( A generic 'change locale' will cause
       
  2060 // all sorts of problems throught the OS, so current practice won't change before a
       
  2061 // comprehensive rearchitecture occurs anyway.)
       
  2062 //
       
  2063 	{
       
  2064 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::LocaleExports"));
       
  2065 
       
  2066 	DCodeSeg& cs=*DCodeSeg::VerifyCallerAndHandle(aHandle);
       
  2067 
       
  2068   	if(cs.iUids.iUid[1].iUid !=	KLocaleDllUid.iUid)
       
  2069   		return KErrNotSupported;
       
  2070 
       
  2071 	// Increment the code segment's access count
       
  2072 	// This will increment every time the same locale is reloaded, but
       
  2073 	// this doesn't matter since we don't unload locale DLLs.
       
  2074 	NKern::ThreadEnterCS();
       
  2075 	DCodeSeg::Wait();
       
  2076 	cs.CheckedOpen();
       
  2077 	DCodeSeg::Signal();
       
  2078 	NKern::ThreadLeaveCS();
       
  2079 	
       
  2080 	TLibraryFunction data[KNumLocaleExports];
       
  2081 	TInt n;
       
  2082 	for(n=0; n<KNumLocaleExports; n++)
       
  2083 		data[n] = (TLibraryFunction)cs.Lookup(n);
       
  2084   
       
  2085 	kumemput32(aExportList, &data[0], KNumLocaleExports * sizeof(TLibraryFunction));
       
  2086 
       
  2087 	return KErrNone;
       
  2088 	}
       
  2089 
       
  2090 TInt ExecHandler::ResetMachine(TMachineStartupType /*aType*/)
       
  2091 	{
       
  2092 	// Don't implement without considering Platform Security!
       
  2093 	return KErrNotSupported;
       
  2094 	}
       
  2095 
       
  2096 TInt ExecHandler::ExecuteInSupervisorMode(TSupervisorFunction aFunction, TAny* aParameter)
       
  2097 //
       
  2098 // Execute a function in supervisor mode. Only available to F32 - panic anyone else
       
  2099 //
       
  2100 	{
       
  2101 #ifndef __MEMMODEL_FLEXIBLE__
       
  2102 	if (TheCurrentThread->iOwningProcess == K::TheFileServerProcess)
       
  2103 		{
       
  2104 		UNLOCK_USER_MEMORY();
       
  2105 		TInt r = A::CallSupervisorFunction(aFunction,aParameter);
       
  2106 		LOCK_USER_MEMORY();
       
  2107 		return r;
       
  2108 		}
       
  2109 #endif
       
  2110 	K::PanicKernExec(EAccessDenied);
       
  2111 	return 0;
       
  2112 	}
       
  2113 
       
  2114 _LIT(KDriveZed, "Z:");
       
  2115 void ExecHandler::DllFileName(TInt aHandle, TDes8& aFileName)
       
  2116 	{
       
  2117 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::DllFileName %08x",aHandle));
       
  2118 	TFileName n;
       
  2119 	Kern::AccessCode();
       
  2120 	DCodeSeg* pS=DCodeSeg::CodeSegFromEntryPoint(aHandle);
       
  2121 	if (pS)
       
  2122 		pS->AppendFullFileName(n);
       
  2123 	else
       
  2124 		n=KDriveZed;
       
  2125 	Kern::EndAccessCode();
       
  2126 	if (pS)
       
  2127 		P::NormalizeExecutableFileName(n);
       
  2128 	Kern::KUDesPut(aFileName,n);
       
  2129 	}
       
  2130 
       
  2131 #ifdef MONITOR_THREAD_CPU_TIME
       
  2132 TInt ExecHandler::ThreadGetCpuTime(DThread* aThread, Int64& aTime)
       
  2133 	{
       
  2134 #ifndef __SMP__
       
  2135 	TInt64 time = (1000000 * aThread->iNThread.iTotalCpuTime) / NKern::FastCounterFrequency();
       
  2136 	NKern::UnlockSystem();
       
  2137 	kumemput32(&aTime, &time, sizeof(TInt64));
       
  2138 #else
       
  2139 	TUint64 t = NKern::ThreadCpuTime(&aThread->iNThread);
       
  2140 	NKern::UnlockSystem();
       
  2141 	TUint32 f = NKern::CpuTimeMeasFreq();
       
  2142 	TUint64 t2 = t>>32;
       
  2143 	t = ((t<<32)>>32)*1000000;
       
  2144 	t2 *= 1000000;
       
  2145 	t2 += (t>>32);
       
  2146 	t &= TUint64(KMaxTUint32);
       
  2147 	TUint64 q2 = t2/f;
       
  2148 	t2 -= q2*f;
       
  2149 	t += (t2<<32);
       
  2150 	TUint64 q = t/f;
       
  2151 	q += (q2<<32);
       
  2152 	kumemput32(&aTime, &q, sizeof(TInt64));
       
  2153 #endif
       
  2154 	return KErrNone;
       
  2155 	}
       
  2156 #else		
       
  2157 TInt ExecHandler::ThreadGetCpuTime(DThread* /*aThread*/, Int64& /*aTime*/)
       
  2158 	{
       
  2159 	NKern::UnlockSystem();
       
  2160 	return KErrNotSupported;
       
  2161 	}
       
  2162 #endif
       
  2163 
       
  2164 TInt ExecHandler::SetMemoryThresholds(TInt aLowThreshold, TInt aGoodThreshold)
       
  2165 	{
       
  2166 	if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by UserSvr::SetMemoryThresholds")))
       
  2167 		K::LockedPlatformSecurityPanic();
       
  2168 	if (aLowThreshold<0 || aGoodThreshold<aLowThreshold)
       
  2169 		return KErrArgument;
       
  2170 	K::MemoryLowThreshold=aLowThreshold;
       
  2171 	K::MemoryGoodThreshold=aGoodThreshold;
       
  2172 	return KErrNone;
       
  2173 	}
       
  2174 
       
  2175 void ExecHandler::FsRegisterThread()
       
  2176 //
       
  2177 // Register the file server thread
       
  2178 //
       
  2179 	{
       
  2180 
       
  2181 	__KTRACE_OPT(KBOOT,Kern::Printf("File server thread registered"));
       
  2182 	DThread* pT = TheCurrentThread;
       
  2183 	DProcess* pP = pT->iOwningProcess;
       
  2184 	pP->iFlags |= (KThreadFlagProcessCritical | KProcessFlagSystemPermanent);
       
  2185 	pT->iFlags |= KThreadFlagSystemPermanent;
       
  2186 	if (K::TheFileServerProcess && K::TheFileServerProcess!=pP)
       
  2187 		K::PanicCurrentThread(EAccessDenied);
       
  2188 	K::TheFileServerProcess=pP;
       
  2189 	K::ThreadEnterCS();
       
  2190 	pP->SetPriority(EPriorityFileServer);
       
  2191 	M::FsRegisterThread();
       
  2192 	K::ThreadLeaveCS();
       
  2193 	}
       
  2194 
       
  2195 
       
  2196 void ExecHandler::RegisterTrustedChunk(DChunk* aChunk)
       
  2197 //
       
  2198 // Register file server's chunk intended for DMA transfer
       
  2199 //
       
  2200 	{
       
  2201 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RegisterTrustedChunk %x",aChunk));
       
  2202 
       
  2203 	DProcess* pP=TheCurrentThread->iOwningProcess;
       
  2204 	if (K::TheFileServerProcess && K::TheFileServerProcess!=pP)
       
  2205 		{
       
  2206 		K::PanicCurrentThread(EAccessDenied);
       
  2207 		}
       
  2208 	aChunk->iAttributes |= DChunk::ETrustedChunk;
       
  2209 	}
       
  2210 	
       
  2211 void ExecHandler::WsRegisterThread()
       
  2212 //
       
  2213 // Register the window server thread
       
  2214 //
       
  2215 	{
       
  2216 
       
  2217 	__KTRACE_OPT(KBOOT,Kern::Printf("Window server thread registered"));
       
  2218 	DProcess* pP=TheCurrentThread->iOwningProcess;
       
  2219 	if (K::TheWindowServerProcess && K::TheWindowServerProcess!=pP)
       
  2220 		K::PanicCurrentThread(EAccessDenied);
       
  2221 	K::TheWindowServerProcess=pP;
       
  2222 	K::ThreadEnterCS();
       
  2223 	pP->SetPriority(EPriorityWindowServer);
       
  2224 	K::ThreadLeaveCS();
       
  2225 	}
       
  2226 
       
  2227 void ExecHandler::RequestSignal(TInt aCount)
       
  2228 //
       
  2229 // Signal the request semaphore.
       
  2230 //
       
  2231 	{
       
  2232 
       
  2233 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::RequestSignal %d",aCount));
       
  2234 	NKern::ThreadRequestSignal(NULL,aCount);
       
  2235 	}
       
  2236 
       
  2237 TInt ExecHandler::ThreadRequestCount(DThread* aThread)
       
  2238 //
       
  2239 // Get the request semaphores count.
       
  2240 //
       
  2241 	{
       
  2242 
       
  2243 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ThreadRequestCount"));
       
  2244 	return aThread->iNThread.iRequestSemaphore.iCount;
       
  2245 	}
       
  2246 
       
  2247 void CompleteUserAfter(TAny* aPtr)
       
  2248 	{
       
  2249 	DThread* pT=DThread::FromTimer(aPtr);
       
  2250 	if (pT->iTimer.iState==TTimer::EWaiting)
       
  2251 		{
       
  2252 		Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
       
  2253 		pT->iTimer.iState=TTimer::EIdle;
       
  2254 		}
       
  2255 	}
       
  2256 
       
  2257 void CompleteUserAt(TAny* aPtr)
       
  2258 	{
       
  2259 	DThread* pT=DThread::FromTimer(aPtr);
       
  2260 	if (pT->iTimer.iState==TTimer::EWaiting)
       
  2261 		{
       
  2262 		Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
       
  2263 		pT->iTimer.iState=TTimer::EIdle;
       
  2264 		}
       
  2265 	}
       
  2266 
       
  2267 void CompleteUserAfterHighRes(TAny* aPtr)
       
  2268 	{
       
  2269 	DThread* pT=DThread::FromTimer(aPtr);
       
  2270 	NKern::LockSystem();
       
  2271 	pT->iTimer.iState=TTimer::EIdle;
       
  2272 	Kern::QueueRequestComplete(pT,pT->iTimer.iRequest,KErrNone);
       
  2273 	NKern::UnlockSystem();
       
  2274 	}
       
  2275 
       
  2276 void ExecHandler::After(TInt anInterval, TRequestStatus& aStatus)
       
  2277 	{
       
  2278 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::After %d",anInterval));
       
  2279 	TInt iv=anInterval;
       
  2280 	if (iv<=0)
       
  2281 		{
       
  2282 		// just rotate the ready queue for this thread
       
  2283 		NKern::RotateReadyList(-1);
       
  2284 		TRequestStatus* s=&aStatus;
       
  2285 		Kern::RequestComplete(s,KErrNone);
       
  2286 		return;
       
  2287 		}
       
  2288 	NKern::ThreadEnterCS();
       
  2289 	TInt r=TheCurrentThread->iTimer.After(iv,CompleteUserAfter,aStatus);
       
  2290 	NKern::ThreadLeaveCS();
       
  2291 	if (r==KErrInUse)
       
  2292 		K::PanicKernExec(ETimerAlreadyPending);
       
  2293 	else if (r!=KErrNone)
       
  2294 		{
       
  2295 		TRequestStatus* s=&aStatus;
       
  2296 		Kern::RequestComplete(s,r);
       
  2297 		}
       
  2298 	}
       
  2299 
       
  2300 void ExecHandler::AfterHighRes(TInt anInterval, TRequestStatus& aStatus)
       
  2301 	{
       
  2302 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::AfterHighRes %d",anInterval));
       
  2303 	TInt r=TheCurrentThread->iTimer.AfterHighRes(anInterval,CompleteUserAfterHighRes,aStatus);
       
  2304 	if (r==KErrInUse)
       
  2305 		K::PanicCurrentThread(ETimerAlreadyPending);
       
  2306 	}
       
  2307 
       
  2308 void ExecHandler::At(const TTimeK& aTime, TRequestStatus& aStatus)
       
  2309 	{
       
  2310 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::At"));
       
  2311 	TTimeK time;
       
  2312 	kumemget32(&time,&aTime,sizeof(time));
       
  2313 	NKern::ThreadEnterCS();
       
  2314 	TInt r=TheCurrentThread->iTimer.At(time,CompleteUserAt,aStatus);
       
  2315 	NKern::ThreadLeaveCS();
       
  2316 	if (r==KErrInUse)
       
  2317 		K::PanicKernExec(ETimerAlreadyPending);
       
  2318 	else if (r!=KErrNone)
       
  2319 		{
       
  2320 		TRequestStatus* s=&aStatus;
       
  2321 		Kern::RequestComplete(s,r);
       
  2322 		}
       
  2323 	}
       
  2324 
       
  2325 #ifndef __FASTEXEC_MACHINE_CODED__
       
  2326 RAllocator* ExecHandler::Heap()
       
  2327 	{
       
  2328 	return TheCurrentThread->iAllocator;
       
  2329 	}
       
  2330 
       
  2331 extern void InvalidFastExec();
       
  2332 
       
  2333 TTrapHandler* ExecHandler::PushTrapFrame(TTrap* aFrame)
       
  2334 //
       
  2335 // Push a new trap frame.
       
  2336 //
       
  2337 	{
       
  2338 #ifdef __LEAVE_EQUALS_THROW__
       
  2339 #ifdef __WINS__
       
  2340 	// On WINS overload this function to remember when a TWin32SEHTrap is installed
       
  2341 	// over another one
       
  2342 	DThread& t=*TheCurrentThread;
       
  2343 	t.iFrame=aFrame;
       
  2344 	return 0;
       
  2345 #else
       
  2346 	InvalidFastExec();
       
  2347 	return (TTrapHandler*)aFrame; // Prevents compiler warnings
       
  2348 #endif
       
  2349 #else
       
  2350 	DThread& t=*TheCurrentThread;
       
  2351 	aFrame->iHandler=t.iTrapHandler;
       
  2352 	aFrame->iNext=t.iFrame;
       
  2353 	t.iFrame=aFrame;
       
  2354 	return t.iTrapHandler;
       
  2355 #endif
       
  2356 	}
       
  2357 
       
  2358 TTrap* ExecHandler::PopTrapFrame()
       
  2359 //
       
  2360 // Pop the current frame.
       
  2361 //
       
  2362 	{
       
  2363 #ifdef __LEAVE_EQUALS_THROW__
       
  2364 #ifdef __WINS__
       
  2365 	// On WINS overload this function to recall when a TWin32SEHTrap is installed
       
  2366 	// over another one
       
  2367 	DThread& t=*TheCurrentThread;
       
  2368 	return t.iFrame;
       
  2369 #else
       
  2370 	InvalidFastExec();
       
  2371 	return 0;
       
  2372 #endif
       
  2373 #else
       
  2374 	DThread& t=*TheCurrentThread;
       
  2375 	TTrap* pF=t.iFrame;
       
  2376 	if (pF)
       
  2377 		t.iFrame=pF->iNext;
       
  2378 	return pF;
       
  2379 #endif
       
  2380 	}
       
  2381 
       
  2382 CActiveScheduler* ExecHandler::ActiveScheduler()
       
  2383 //
       
  2384 // Return the address of the current active scheduler
       
  2385 //
       
  2386 	{
       
  2387 	DThread& t=*TheCurrentThread;
       
  2388 	return t.iScheduler;
       
  2389 	}
       
  2390 
       
  2391 void ExecHandler::SetActiveScheduler(CActiveScheduler* aScheduler)
       
  2392 //
       
  2393 // Set the address of the current active scheduler
       
  2394 //
       
  2395 	{
       
  2396 	DThread& t=*TheCurrentThread;
       
  2397 	t.iScheduler=aScheduler;
       
  2398 	}
       
  2399 
       
  2400 TTrapHandler* ExecHandler::TrapHandler()
       
  2401 //
       
  2402 // Return the current trap handler.
       
  2403 //
       
  2404 	{
       
  2405 	DThread& t=*TheCurrentThread;
       
  2406 	return t.iTrapHandler;
       
  2407 	}
       
  2408 
       
  2409 TTrapHandler* ExecHandler::SetTrapHandler(TTrapHandler* aHandler)
       
  2410 //
       
  2411 // Set the current trap handler.
       
  2412 //
       
  2413 	{
       
  2414 	DThread& t=*TheCurrentThread;
       
  2415 	TTrapHandler* pH=t.iTrapHandler;
       
  2416 	t.iTrapHandler=aHandler;
       
  2417 	return pH;
       
  2418 	}
       
  2419 
       
  2420 void ExecHandler::SetReentryPoint(TLinAddr a)
       
  2421 	{
       
  2422 	DThread& t = *TheCurrentThread;
       
  2423 	t.iOwningProcess->iReentryPoint = a;
       
  2424 	}
       
  2425 #endif
       
  2426 
       
  2427 #ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
       
  2428 void K::DoProcessIsolationFailure(const char* aContextText)
       
  2429 	{
       
  2430 	// enter with system locked
       
  2431 	if(TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation)
       
  2432 		{
       
  2433 		if(PlatSec::ProcessIsolationFail(aContextText)==KErrNone)
       
  2434 			return;
       
  2435 		LockedPlatformSecurityPanic();
       
  2436 		}
       
  2437 	}
       
  2438 #endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
       
  2439 
       
  2440 void K::DoProcessIsolationFailure()
       
  2441 	{
       
  2442 	// enter with system locked
       
  2443 #ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
       
  2444 	DoProcessIsolationFailure(NULL);
       
  2445 #else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
       
  2446 	if (TheSuperPage().KernelConfigFlags() & EKernelConfigPlatSecProcessIsolation)
       
  2447 		{
       
  2448 		if (PlatSec::EmitDiagnostic() == KErrNone)
       
  2449 			return;
       
  2450 		LockedPlatformSecurityPanic();
       
  2451 		}
       
  2452 #endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
       
  2453 	}
       
  2454 
       
  2455 
       
  2456 void K::UnlockedPlatformSecurityPanic()
       
  2457 	{
       
  2458 	// enter with system unlocked
       
  2459 	NKern::LockSystem();
       
  2460 	K::LockedPlatformSecurityPanic();
       
  2461 	}
       
  2462 
       
  2463 void K::LockedPlatformSecurityPanic()
       
  2464 	{
       
  2465 	// enter with system locked
       
  2466 	K::PanicCurrentThread(EPlatformSecurityTrap);
       
  2467 	}
       
  2468 
       
  2469 void ExecHandler::ThreadRendezvous(TInt aReason)
       
  2470 	{
       
  2471 	NKern::ThreadEnterCS();
       
  2472 	TheCurrentThread->Rendezvous(aReason);
       
  2473 	NKern::ThreadLeaveCS();
       
  2474 	}
       
  2475 
       
  2476 void ExecHandler::ProcessRendezvous(TInt aReason)
       
  2477 	{
       
  2478 	NKern::ThreadEnterCS();
       
  2479 	TheCurrentThread->iOwningProcess->Rendezvous(aReason);
       
  2480 	NKern::ThreadLeaveCS();
       
  2481 	}
       
  2482 
       
  2483 void ExecHandler::DebugPrint(TAny* aDes, TInt aMode)
       
  2484 	{
       
  2485 	TInt l, m;
       
  2486 	const TText* p = Kern::KUDesInfo(*(const TDesC*)aDes, l, m);
       
  2487 
       
  2488 #ifdef __DEBUGGER_SUPPORT__
       
  2489 	TUint r = DKernelEventHandler::Dispatch(EEventUserTrace, (TAny*)p, (TAny*)l);
       
  2490 	if (r & DKernelEventHandler::ETraceHandled)
       
  2491 		l = 0;
       
  2492 #endif
       
  2493 
       
  2494 	TBuf8<256> buffer;
       
  2495 	l = Min(l,256);
       
  2496 	buffer.SetLength(l);
       
  2497 	kumemget((TUint8*)buffer.Ptr(), p, l); //Copy user-side data into kernel memory
       
  2498 	K::TextTrace(buffer,EUserTrace,!aMode);
       
  2499 	}
       
  2500 
       
  2501 
       
  2502 TInt ExecHandler::ProcessSetHandleParameter(DProcess* aProcess, TInt aSlot, TInt aHandle)
       
  2503 	{
       
  2504 	if (aProcess->iCreatorId != TheCurrentThread->iOwningProcess->iId) //check called by creator
       
  2505 		K::LockedPlatformSecurityPanic();
       
  2506 
       
  2507 	if ((aSlot < 0) || (aSlot >= KArgIndex))
       
  2508 		K::PanicCurrentThread(EParameterSlotRange);
       
  2509 
       
  2510 	if (aProcess->iEnvironmentData[aSlot] != 0)
       
  2511 		K::PanicCurrentThread(EParameterSlotInUse);
       
  2512 
       
  2513 	DObject* pObject = K::ObjectFromHandle(aHandle);
       
  2514 
       
  2515 	if (pObject->Protection() == DObject::ELocal) 
       
  2516 		K::LockedPlatformSecurityPanic();
       
  2517 	pObject->CheckedOpen();
       
  2518 
       
  2519 	aProcess->iEnvironmentData[aSlot] = (TInt)pObject | EHandle;
       
  2520 	return KErrNone;
       
  2521 	}
       
  2522 
       
  2523 //no locks held on entry
       
  2524 TInt ExecHandler::ProcessSetDataParameter(TInt aProcess, TInt aSlot, const TUint8* aData, TInt aLen)
       
  2525 	{
       
  2526 
       
  2527 	if ((aSlot < 0) || (aSlot >= KArgIndex))
       
  2528 		K::PanicKernExec(EParameterSlotRange);
       
  2529 
       
  2530 	if (aLen < 0)
       
  2531 		K::PanicKernExec(EParameterSlotDataLength);
       
  2532 
       
  2533 	NKern::ThreadEnterCS();
       
  2534 	HBuf8* pBuf = NULL;
       
  2535 	if (aLen)
       
  2536 		pBuf = HBuf8::New(aLen);
       
  2537 
       
  2538 	DThread* currentThread = TheCurrentThread;
       
  2539 	currentThread->iTempAlloc = pBuf;
       
  2540 	NKern::ThreadLeaveCS();				
       
  2541 
       
  2542 	if (aLen)
       
  2543 		{
       
  2544 		if (!pBuf)
       
  2545 			return KErrNoMemory;
       
  2546 		kumemget((void*)pBuf->Ptr(), aData, aLen);
       
  2547 		pBuf->SetLength(aLen);
       
  2548 		}
       
  2549 
       
  2550 
       
  2551 	NKern::LockSystem();
       
  2552 	DProcess* pProc = (DProcess*)K::ObjectFromHandle(aProcess, EProcess); 
       
  2553 
       
  2554 	if (pProc->iCreatorId != currentThread->iOwningProcess->iId) //check called by creator
       
  2555 		K::LockedPlatformSecurityPanic();
       
  2556 
       
  2557 	if (pProc->iEnvironmentData[aSlot] != 0)
       
  2558 		K::PanicCurrentThread(EParameterSlotInUse);
       
  2559 
       
  2560 	pProc->iEnvironmentData[aSlot] = (TInt)pBuf | EBinaryData;
       
  2561 	currentThread->iTempAlloc = NULL;
       
  2562 	NKern::UnlockSystem();
       
  2563 
       
  2564 	return KErrNone;
       
  2565 	}
       
  2566 
       
  2567 
       
  2568 
       
  2569 //need to have sys locked on way in
       
  2570 TInt ExecHandler::ProcessGetHandleParameter(TInt aSlot, TObjectType aObjectType, TOwnerType aOwnerType)
       
  2571 	{
       
  2572 
       
  2573 	DThread * currentThread = TheCurrentThread;
       
  2574 	DProcess * currentProcess = currentThread->iOwningProcess;
       
  2575 
       
  2576 	if ((aSlot < 0) || (aSlot >= KArgIndex))
       
  2577 		K::PanicCurrentThread(EParameterSlotRange);
       
  2578 
       
  2579 	TInt data = currentProcess->iEnvironmentData[aSlot];
       
  2580 
       
  2581 	if (!data)
       
  2582 		return KErrNotFound;
       
  2583 
       
  2584 	TProcessParameterType type = (TProcessParameterType)(data&3);
       
  2585 
       
  2586 	if (type != EHandle)
       
  2587 		return KErrArgument;
       
  2588 
       
  2589 	DObject* pObject = (DObject*)(data&~3);
       
  2590 
       
  2591 	if ((TInt)aObjectType+1 != pObject->UniqueID())	//check it's the correct type
       
  2592 		return KErrArgument;
       
  2593 
       
  2594 	// zero parameter to prevent race conditions while retrieving the object
       
  2595 	currentProcess->iEnvironmentData[aSlot]=0;
       
  2596 	
       
  2597 	NKern::ThreadEnterCS();
       
  2598 	NKern::UnlockSystem();
       
  2599 	TInt handle = 0;
       
  2600 
       
  2601 	TInt ret = currentThread->MakeHandle(aOwnerType, pObject, handle);
       
  2602 
       
  2603 	NKern::LockSystem();
       
  2604 	NKern::ThreadLeaveCS();
       
  2605 
       
  2606 	if (ret != KErrNone)
       
  2607 		{
       
  2608 		// restore parameter data as 'nothing happened'
       
  2609 		currentProcess->iEnvironmentData[aSlot]=data;
       
  2610 		return ret;
       
  2611 		}
       
  2612 	return handle;
       
  2613 	}
       
  2614 
       
  2615 
       
  2616 //enter with the system lock held, auto release on exit
       
  2617 TInt ExecHandler::ProcessGetDataParameter(TInt aSlot,  TUint8* aData, TInt aLen)
       
  2618 	{
       
  2619 
       
  2620 	DThread * currentThread = TheCurrentThread;
       
  2621 	DProcess * currentProcess = currentThread->iOwningProcess;
       
  2622 
       
  2623 	if ((aSlot < 0) || (aSlot >= KArgIndex))
       
  2624 		K::PanicCurrentThread(EParameterSlotRange);
       
  2625 
       
  2626 	TInt data = currentProcess->iEnvironmentData[aSlot];
       
  2627 	if (!data)
       
  2628 		return KErrNotFound;
       
  2629 
       
  2630 	TProcessParameterType type = (TProcessParameterType)(data&3);
       
  2631 	if (type != EBinaryData)
       
  2632 		return KErrArgument;
       
  2633 
       
  2634 	HBuf8* p = (HBuf8*)(data&~3);
       
  2635 	if (!p)	//we've passed zero length binary data so nothing to copy
       
  2636 		return 0;
       
  2637 
       
  2638 	if (aLen < p->Length())
       
  2639 		return KErrArgument;
       
  2640 
       
  2641 	currentThread->iTempAlloc = p;
       
  2642 	currentProcess->iEnvironmentData[aSlot] = 0;
       
  2643 	NKern::UnlockSystem();
       
  2644 
       
  2645 	TInt len = p->Length();
       
  2646 	kumemput((void*)aData, (void*)p->Ptr(), len);
       
  2647 
       
  2648 	NKern::ThreadEnterCS();
       
  2649 	currentThread->iTempAlloc = NULL;
       
  2650 	delete p;
       
  2651 	NKern::ThreadLeaveCS();
       
  2652 
       
  2653 	NKern::LockSystem();
       
  2654 	return len;
       
  2655 	}
       
  2656 
       
  2657 TInt ExecHandler::ProcessDataParameterLength(TInt aSlot)
       
  2658 	{
       
  2659 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::ProcessDesParameterLength"));
       
  2660 
       
  2661 	DProcess * currentProcess = TheCurrentThread->iOwningProcess;
       
  2662 
       
  2663 	if ((aSlot < 0) || (aSlot >= KArgIndex))
       
  2664 		K::PanicCurrentThread(EParameterSlotRange);
       
  2665 
       
  2666 	TInt data = currentProcess->iEnvironmentData[aSlot];
       
  2667 
       
  2668 	if (!data)
       
  2669 		return KErrNotFound;
       
  2670 
       
  2671 	TProcessParameterType type = (TProcessParameterType)(data&3);
       
  2672 
       
  2673 	if (type != EBinaryData)
       
  2674 		return KErrArgument;
       
  2675 
       
  2676 	const HBuf8* p = (const HBuf8*)(data&~3);
       
  2677 
       
  2678 	return p ? p->Length() : 0;
       
  2679 	}
       
  2680 
       
  2681 
       
  2682 
       
  2683 void ExecHandler::NotifyChanges(TUint aChanges)
       
  2684 //
       
  2685 // Check that the caller has permission to notify the requested changes,
       
  2686 // and pass it on to Kern::NotifyChanges if it's ok
       
  2687 //
       
  2688 	{
       
  2689 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::NotifyChanges"));
       
  2690 	
       
  2691 	if (aChanges & ~EChangesLocale)
       
  2692 		K::UnlockedPlatformSecurityPanic();
       
  2693 	
       
  2694 	NKern::ThreadEnterCS();
       
  2695 	Kern::NotifyChanges(aChanges);
       
  2696 	NKern::ThreadLeaveCS();
       
  2697 	}
       
  2698 
       
  2699 
       
  2700 
       
  2701 static TInt GlobalUserData[EMaxGlobalUserData] = {0};
       
  2702 
       
  2703 TInt ExecHandler::GetGlobalUserData(TInt aIndex)
       
  2704 	{
       
  2705 	if(TUint(aIndex)<TUint(EMaxGlobalUserData))
       
  2706 		return GlobalUserData[aIndex];
       
  2707 	return 0;
       
  2708 	}
       
  2709 
       
  2710 TInt ExecHandler::SetGlobalUserData(TInt aIndex,TInt aValue)
       
  2711 	{
       
  2712 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::SetGlobalUserData %d 0x%8x",aIndex,aValue));
       
  2713 	if(TUint(aIndex)<TUint(EMaxGlobalUserData))
       
  2714 		{
       
  2715 		if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by SetGlobalUserData")))
       
  2716 			return KErrPermissionDenied;
       
  2717 		else
       
  2718 			{
       
  2719 			GlobalUserData[aIndex] = aValue;
       
  2720 			return KErrNone;
       
  2721 			}
       
  2722 		}
       
  2723 	return KErrArgument;
       
  2724 	}
       
  2725 
       
  2726 TBool ExecHandler::UserThreadExiting(TInt aReason)
       
  2727 	{
       
  2728 	// Mark this thread as exiting and check whether there are any other threads in the process that
       
  2729 	// are not already exiting
       
  2730 	
       
  2731 	DThread* thread = TheCurrentThread;
       
  2732 	DProcess* process = thread->iOwningProcess;
       
  2733 	
       
  2734 	NKern::ThreadEnterCS();
       
  2735 
       
  2736 	// If the thread is process permanent then all other threads in the process will be killed -
       
  2737 	// make sure this happens now, so that this thread has a chance to run global object destructors.
       
  2738 	if (thread->iFlags & KThreadFlagProcessPermanent)
       
  2739 		{
       
  2740 		__NK_ASSERT_ALWAYS(process->WaitProcessLock() == KErrNone);
       
  2741 		NKern::LockSystem();
       
  2742 		process->KillAllThreads(EExitKill, aReason, KNullDesC);
       
  2743 		NKern::UnlockSystem();
       
  2744 		process->SignalProcessLock();
       
  2745 		}
       
  2746 
       
  2747 	TBool lastThread = EFalse;
       
  2748 	__NK_ASSERT_DEBUG(thread->iUserThreadState >= DThread::EUserThreadRunning);
       
  2749 	if (thread->iUserThreadState == DThread::EUserThreadRunning)
       
  2750 		{
       
  2751 		thread->iUserThreadState = DThread::EUserThreadExiting;
       
  2752 		lastThread = (__e32_atomic_tas_ord32(&process->iUserThreadsRunning, 1, -1, 0) == 1);
       
  2753 		}
       
  2754 	
       
  2755 	NKern::ThreadLeaveCS();
       
  2756 	
       
  2757 	return lastThread;
       
  2758 	}
       
  2759 
       
  2760 
       
  2761 #include <kernel/cache.h>
       
  2762 
       
  2763 void ExecHandler::IMBRange(TAny* aStart, TUint aSize)
       
  2764 	{
       
  2765 	UNLOCK_USER_MEMORY();
       
  2766 	Cache::IMB_Range((TLinAddr)aStart,aSize);
       
  2767 	LOCK_USER_MEMORY();
       
  2768 	}