os/kernelhwsrv/kerneltest/e32test/secure/t_sthread.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2001-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 // e32test\secure\t_sthread.cpp
    15 // Overview:
    16 // Test the platform security aspects of the RThread class
    17 // API Information:
    18 // RThread
    19 // Details:
    20 // - Test renaming the current thread and renaming a thread from 
    21 // another thread. Verify results are as expected.
    22 // - Test resuming a thread from a different process and from the
    23 // process that created the thread. Verify results are as expected.
    24 // - Verify that other processes can not suspend a thread and that the
    25 // creating process can.
    26 // - Perform a variety of tests on killing, terminating and panicking
    27 // a thread. Verify results are as expected.
    28 // - Test setting thread priority in a variety of ways, verify results
    29 // are as expected. Includes ensuring real-time priorities are
    30 // unavailable to processes without capability ProtServ.
    31 // - Test RequestComplete and RequestSignal on a thread in a variety 
    32 // of ways, verify results are as expected.
    33 // - Test SetProcessPriority on a thread in a variety of ways, verify 
    34 // results are as expected.
    35 // - Test the Heap, ExceptionHandler, SetExceptionHandler, 
    36 // ModifyExceptionMask, RaiseException, IsExceptionHandled, 
    37 // SetProtected and SetSystem methods. Verify results as expected.
    38 // Platforms/Drives/Compatibility:
    39 // All.
    40 // Assumptions/Requirement/Pre-requisites:
    41 // Failures and causes:
    42 // Base Port information:
    43 // 
    44 //
    45 
    46 #include <e32test.h>
    47 
    48 LOCAL_D RTest test(_L("T_STHREAD"));
    49 
    50 _LIT(KSyncMutex,"T_STHREAD-sync-mutex");
    51 RMutex SyncMutex;
    52 
    53 void Wait()
    54 	{
    55 	RMutex syncMutex;
    56 	if(syncMutex.OpenGlobal(KSyncMutex)!=KErrNone)
    57 		User::Invariant();
    58 	syncMutex.Wait();
    59 	syncMutex.Signal();
    60 	syncMutex.Close();
    61 	}
    62 
    63 enum TTestProcessFunctions
    64 	{
    65 	ETestProcessResume,
    66 	ETestProcessSuspend,
    67 	ETestProcessKill,
    68 	ETestProcessTerminate,
    69 	ETestProcessPanic,
    70 	ETestProcessRequestComplete,
    71 	ETestProcessRequestSignal,
    72 	ETestProcessPriorityControlOff,
    73 	ETestProcessPriorityControlOn,
    74 	ETestProcessSetPriority,
    75 	ETestProcessSetPrioritiesWithoutProtServ,
    76 	ETestProcessSetPrioritiesWithProtServ
    77 	};
    78 
    79 #include "testprocess.h"
    80 
    81 _LIT(KTestPanicCategory,"TEST PANIC");
    82 _LIT(KTestThreadName,"TestName");
    83 
    84 
    85 class RTestThread : public RThread
    86 	{
    87 public:
    88 	void Create(TThreadFunction aFunction,TAny* aArg=0);
    89 	};
    90 
    91 volatile TInt TestThreadCount = 0;
    92 
    93 TInt TestThreadNull(TAny*)
    94 	{
    95 	++TestThreadCount;
    96 	Wait();
    97 	return KErrNone;
    98 	}
    99 
   100 void RTestThread::Create(TThreadFunction aFunction,TAny* aArg)
   101 	{
   102 	TInt r=RThread::Create(_L("TestThread"),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,aArg);
   103 	test(r==KErrNone);
   104 	}
   105 
   106 
   107 // these priorities are available to any process
   108 void TestSetNormalApplicationPriorities(RThread& aThread)
   109 	{
   110 	TThreadPriority priority = aThread.Priority(); // save priority to restore before return
   111 	aThread.SetPriority(EPriorityAbsoluteVeryLow);
   112 	test(aThread.Priority()==EPriorityAbsoluteVeryLow);
   113 	aThread.SetPriority(EPriorityAbsoluteLowNormal);
   114 	test(aThread.Priority()==EPriorityAbsoluteLowNormal);
   115 	aThread.SetPriority(EPriorityAbsoluteLow);
   116 	test(aThread.Priority()==EPriorityAbsoluteLow);
   117 	aThread.SetPriority(EPriorityAbsoluteBackgroundNormal);
   118 	test(aThread.Priority()==EPriorityAbsoluteBackgroundNormal);
   119 	aThread.SetPriority(EPriorityAbsoluteBackground);
   120 	test(aThread.Priority()==EPriorityAbsoluteBackground);
   121 	aThread.SetPriority(EPriorityAbsoluteForegroundNormal);
   122 	test(aThread.Priority()==EPriorityAbsoluteForegroundNormal);
   123 	aThread.SetPriority(EPriorityAbsoluteForeground);
   124 	test(aThread.Priority()==EPriorityAbsoluteForeground);
   125 	aThread.SetPriority(EPriorityAbsoluteHighNormal);
   126 	test(aThread.Priority()==EPriorityAbsoluteHighNormal);
   127 	aThread.SetPriority(EPriorityAbsoluteHigh);
   128 	test(aThread.Priority()==EPriorityAbsoluteHigh);
   129 	aThread.SetPriority(priority);
   130 	}
   131 
   132 TInt TestThreadSetPriority(TAny* aArg)
   133 	{
   134 	RThread thisThread;
   135 	thisThread.SetPriority((TThreadPriority)(reinterpret_cast<TInt>(aArg)));
   136 	return KErrNone;
   137 	}
   138 
   139 void TestSetPriorityPanic(TThreadPriority aPriority)
   140 	{
   141 	RTestThread thread;
   142 	TRequestStatus status;
   143 	thread.Create(TestThreadSetPriority, reinterpret_cast<TAny*>(aPriority));
   144 	thread.Logon(status);
   145 	thread.Resume();
   146 	User::WaitForRequest(status);
   147 	test(thread.ExitType()==EExitPanic);
   148 	test(thread.ExitCategory()==_L("KERN-EXEC"));
   149 	test(thread.ExitReason()==46);
   150 	CLOSE_AND_WAIT(thread);
   151 	}
   152 
   153 void TestSetPrioritySuccess(TThreadPriority aPriority)
   154 	{
   155 	RTestThread thread;
   156 	TRequestStatus status;
   157 	thread.Create(TestThreadSetPriority, reinterpret_cast<TAny*>(aPriority));
   158 	thread.Logon(status);
   159 	thread.Resume();
   160 	User::WaitForRequest(status);
   161 	test(thread.Priority()==aPriority);
   162 	test(thread.ExitCategory()==_L("Kill"));
   163 	test(thread.ExitReason()==0);
   164 	CLOSE_AND_WAIT(thread);
   165 	}
   166 
   167 TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
   168 	{
   169 	RThread thread;
   170 	TInt r;
   171 
   172 	switch(aTestNum)
   173 		{
   174 
   175 	case ETestProcessResume:
   176 		{
   177 		r = thread.Open(aArg1);
   178 		if(r==KErrNone)
   179 			thread.Resume(); // Should panic us
   180 		return r;
   181 		}
   182 
   183 	case ETestProcessSuspend:
   184 		{
   185 		r = thread.Open(aArg1);
   186 		if(r==KErrNone)
   187 			thread.Suspend(); // Should panic us
   188 		return r;
   189 		}
   190 
   191 	case ETestProcessKill:
   192 		{
   193 		r = thread.Open(aArg1);
   194 		if(r==KErrNone)
   195 			thread.Kill(999); // Should panic us
   196 		return r;
   197 		}
   198 
   199 	case ETestProcessTerminate:
   200 		{
   201 		r = thread.Open(aArg1);
   202 		if(r==KErrNone)
   203 			thread.Terminate(999); // Should panic us
   204 		return r;
   205 		}
   206 
   207 	case ETestProcessPanic:
   208 		{
   209 		r = thread.Open(aArg1);
   210 		if(r==KErrNone)
   211 			thread.Panic(KTestPanicCategory,999); // Should panic us
   212 		return r;
   213 		}
   214 
   215 	case ETestProcessSetPriority:
   216 		{
   217 		r = thread.Open(aArg1);
   218 		if(r==KErrNone)
   219 			thread.SetPriority((TThreadPriority)aArg2);
   220 		return r;
   221 		}
   222 
   223 	case ETestProcessRequestComplete:
   224 		{
   225 		r = thread.Open(aArg1);
   226 		if(r==KErrNone)
   227 			{
   228 			// use a local request status because Thread::RequestComplete is
   229 			// implemented to write to it in our context
   230 			TRequestStatus myStatus;
   231 			TRequestStatus* status = &myStatus;
   232 			thread.RequestComplete(status,KErrNone);
   233 			}
   234 		return r;
   235 		}
   236 
   237 	case ETestProcessRequestSignal:
   238 		{
   239 		r = thread.Open(aArg1);
   240 		if(r==KErrNone)
   241 			thread.RequestSignal();
   242 		return r;
   243 		}
   244 
   245 	case ETestProcessPriorityControlOn:
   246 		User::SetPriorityControl(ETrue);
   247 		// fall through...
   248 	case ETestProcessPriorityControlOff:
   249 		RProcess::Rendezvous(RThread().Id());
   250 		Wait();
   251 		return KErrNone;
   252 
   253 	case ETestProcessSetPrioritiesWithoutProtServ:
   254 		{
   255 		RThread thread;
   256 		TestSetNormalApplicationPriorities(thread);
   257 		TestSetPriorityPanic(EPriorityAbsoluteRealTime1);
   258 		TestSetPriorityPanic(EPriorityAbsoluteRealTime2);
   259 		TestSetPriorityPanic(EPriorityAbsoluteRealTime3);
   260 		TestSetPriorityPanic(EPriorityAbsoluteRealTime4);
   261 		TestSetPriorityPanic(EPriorityAbsoluteRealTime5);
   262 		TestSetPriorityPanic(EPriorityAbsoluteRealTime6);
   263 		TestSetPriorityPanic(EPriorityAbsoluteRealTime7);
   264 		TestSetPriorityPanic(EPriorityAbsoluteRealTime8);	
   265 		return KErrNone;
   266 		}
   267 		
   268 	case ETestProcessSetPrioritiesWithProtServ:
   269 		{
   270 		RThread thread;
   271 		TestSetNormalApplicationPriorities(thread);
   272 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime1);
   273 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime2);
   274 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime3);
   275 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime4);
   276 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime5);
   277 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime6);
   278 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime7);
   279 		TestSetPrioritySuccess(EPriorityAbsoluteRealTime8);	
   280 		return KErrNone;
   281 		}
   282 
   283 	default:
   284 		User::Panic(_L("T_STHREAD"),1);
   285 		}
   286 
   287 	return KErrNone;
   288 	}
   289 
   290 
   291 
   292 void TestThreadForPlatformSecurityTrap(TThreadFunction aFunction)
   293 	{
   294 	TBool jit = User::JustInTime();
   295 	TRequestStatus logonStatus;
   296 	RTestThread thread;
   297 	thread.Create(aFunction,(TAny*)(TUint)RThread().Id());
   298 	thread.Logon(logonStatus);
   299 	User::SetJustInTime(EFalse);
   300 	thread.Resume();
   301 	User::WaitForRequest(logonStatus);
   302 	User::SetJustInTime(jit);
   303 	test(thread.ExitType()==EExitPanic);
   304 	test(logonStatus==EPlatformSecurityTrap);
   305 	CLOSE_AND_WAIT(thread);
   306 	}
   307 
   308 
   309 void TestProcessForPlatformSecurityTrap(TTestProcessFunctions aFunction)
   310 	{
   311 	TRequestStatus logonStatus2;
   312 	RTestProcess process;
   313 	process.Create(~0u,aFunction,RThread().Id(),EPriorityAbsoluteLow);
   314 	process.Logon(logonStatus2);
   315 	process.Resume();
   316 	User::WaitForRequest(logonStatus2);
   317 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   318 	test(logonStatus2==EPlatformSecurityTrap);
   319 	CLOSE_AND_WAIT(process);
   320 	}
   321 
   322 
   323 void TestRename()
   324 	{
   325 	TName name;
   326 
   327 	test.Start(_L("Renaming the current thread"));
   328 	name = RThread().Name();
   329 	name.SetLength(KTestThreadName().Length());
   330 	test(name.CompareF(KTestThreadName)!=0);
   331 	User::RenameThread(KTestThreadName);
   332 	name = RThread().Name();
   333 	name.SetLength(KTestThreadName().Length());
   334 	test(name.CompareF(KTestThreadName)==0);
   335 
   336 
   337 	test.End();
   338 	}
   339 
   340 
   341 
   342 void TestResume()
   343 	{
   344 	RTestProcess process;
   345 	RTestThread thread;
   346 	TRequestStatus logonStatus;
   347 	TInt testCount = TestThreadCount;
   348 
   349 	test.Start(_L("Try to get another process to resume one we've created"));
   350 	thread.Create(TestThreadNull);
   351 	process.Create(~0u,ETestProcessResume,thread.Id());
   352 	process.Logon(logonStatus);
   353 	process.Resume();
   354 	User::WaitForRequest(logonStatus);
   355 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   356 	test(logonStatus==EPlatformSecurityTrap);
   357 	User::After(1000000); // Give time for thread to run (if it had been resumed)...
   358 	test(TestThreadCount==testCount); // it shouldn't have, so count will be unchanged.
   359 
   360 	test.Next(_L("Test resuming a thread we've created"));
   361 	thread.Logon(logonStatus);
   362 	test(logonStatus==KRequestPending);
   363 	thread.Resume();
   364 	User::WaitForRequest(logonStatus);
   365 	test(logonStatus==KErrNone);
   366 	test(TestThreadCount==testCount+1); // Thread should have run and incremented the count
   367 	CLOSE_AND_WAIT(thread);
   368 	CLOSE_AND_WAIT(process);
   369 
   370 	test.End();
   371 	}
   372 
   373 
   374 
   375 TInt TestThreadCounting(TAny*)
   376 	{
   377 	RThread().SetPriority(EPriorityAbsoluteVeryLow);
   378 	for(;;)
   379 		++TestThreadCount;
   380 	}
   381 
   382 TBool IsTestThreadRunning()
   383 	{
   384 	 // Thread should have been busy incrementing the count if it is running
   385 	TInt testCount = TestThreadCount;
   386 	User::After(100000);
   387 	if(testCount!=TestThreadCount)
   388 		return ETrue;
   389 	User::After(1000000);
   390 	return testCount!=TestThreadCount;
   391 	}
   392 
   393 void TestSuspend()
   394 	{
   395 	RTestProcess process;
   396 	RTestThread thread;
   397 	TRequestStatus logonStatus;
   398 
   399 	test.Start(_L("Creating a never ending thread..."));
   400 	thread.Create(TestThreadCounting);
   401 	thread.Resume();
   402 	test(IsTestThreadRunning());  // Thread should still be running
   403 
   404 	test.Next(_L("Checking other process can't supspend it"));
   405 	process.Create(~0u,ETestProcessSuspend,thread.Id());
   406 	process.Logon(logonStatus);
   407 	process.Resume();
   408 	User::WaitForRequest(logonStatus);
   409 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   410 	test(logonStatus==EPlatformSecurityTrap);
   411 	test(IsTestThreadRunning());  // Thread should still be running
   412 
   413 	test.Next(_L("Test suspending a thread in same process"));
   414 	thread.Logon(logonStatus);
   415 	thread.Suspend();
   416 	test(!IsTestThreadRunning()); // Thread should have stopped...
   417 	test(logonStatus==KRequestPending); // but not have died
   418 	thread.LogonCancel(logonStatus);
   419 	User::WaitForRequest(logonStatus);
   420 	
   421 	test.Next(_L("Kill thread"));
   422 	thread.Kill(0);
   423 	CLOSE_AND_WAIT(thread);
   424 	CLOSE_AND_WAIT(process);
   425 
   426 	test.End();
   427 	}
   428 
   429 
   430 
   431 TInt TestThreadKillSelf(TAny* )
   432 	{
   433 	RThread().Kill(999);
   434 	return KErrGeneral;
   435 	}
   436 
   437 TInt TestThreadTerminateSelf(TAny*)
   438 	{
   439 	RThread().Terminate(999);
   440 	return KErrGeneral;
   441 	}
   442 
   443 TInt TestThreadPanicSelf(TAny*)
   444 	{
   445 	RThread().Panic(KTestPanicCategory,999);
   446 	return KErrGeneral;
   447 	}
   448 
   449 void TestKill()
   450 	{
   451 	RTestProcess process;
   452 	RTestThread thread;
   453 	TRequestStatus logonStatus;
   454 	TRequestStatus logonStatus2;
   455 	TBool jit = User::JustInTime();
   456 
   457 	// Test RProcess::Kill()
   458 
   459 	test.Start(_L("Test killing an un-resumed thread created by us"));
   460 	thread.Create(TestThreadNull);
   461 	thread.Logon(logonStatus);
   462 	thread.Kill(999);
   463 	User::WaitForRequest(logonStatus);
   464 	test(thread.ExitType()==EExitKill);
   465 	test(logonStatus==999);
   466 	CLOSE_AND_WAIT(thread);
   467 
   468 	test.Next(_L("Test killing a resumed thread created by us"));
   469 	thread.Create(TestThreadNull);
   470 	thread.Logon(logonStatus);
   471 	SyncMutex.Wait();
   472 	thread.Resume();
   473 	thread.Kill(999);
   474 	SyncMutex.Signal();
   475 	User::WaitForRequest(logonStatus);
   476 	test(thread.ExitType()==EExitKill);
   477 	test(logonStatus==999);
   478 	CLOSE_AND_WAIT(thread);
   479 
   480 	test.Next(_L("Try killing un-resumed thread not created by self"));
   481 	thread.Create(TestThreadNull);
   482 	process.Create(~0u,ETestProcessKill,thread.Id());
   483 	thread.Logon(logonStatus2);
   484 	process.Logon(logonStatus);
   485 	process.Resume();
   486 	User::WaitForRequest(logonStatus);
   487 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   488 	test(logonStatus==EPlatformSecurityTrap);
   489 	test(logonStatus2==KRequestPending); // the thread should still be alive
   490 	thread.Resume();
   491 	User::WaitForRequest(logonStatus2);
   492 	test(logonStatus2==KErrNone);
   493 	CLOSE_AND_WAIT(thread);
   494 	CLOSE_AND_WAIT(process);
   495 
   496 	test.Next(_L("Try killing resumed thread not created by self"));
   497 	thread.Create(TestThreadNull);
   498 	process.Create(~0u,ETestProcessKill,thread.Id());
   499 	thread.Logon(logonStatus2);
   500 	process.Logon(logonStatus);
   501 	SyncMutex.Wait();
   502 	thread.Resume();
   503 	process.Resume();
   504 	User::WaitForRequest(logonStatus);
   505 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   506 	test(logonStatus==EPlatformSecurityTrap);
   507 	test(logonStatus2==KRequestPending); // the thread should still be alive
   508 	SyncMutex.Signal();
   509 	User::WaitForRequest(logonStatus2);
   510 	test(logonStatus2==KErrNone);
   511 	CLOSE_AND_WAIT(thread);
   512 	CLOSE_AND_WAIT(process);
   513 
   514 	test.Next(_L("Test a thread killing itself"));
   515 	thread.Create(TestThreadKillSelf);
   516 	thread.Logon(logonStatus);
   517 	thread.Resume();
   518 	User::WaitForRequest(logonStatus);
   519 	test(thread.ExitType()==EExitKill);
   520 	test(logonStatus==999);
   521 	CLOSE_AND_WAIT(thread);
   522 
   523 	// Test RProcess::Teminate()
   524 
   525 	test.Next(_L("Test terminating an un-resumed thread created by us"));
   526 	thread.Create(TestThreadNull);
   527 	thread.Logon(logonStatus);
   528 	thread.Terminate(999);
   529 	User::WaitForRequest(logonStatus);
   530 	test(thread.ExitType()==EExitTerminate);
   531 	test(logonStatus==999);
   532 	CLOSE_AND_WAIT(thread);
   533 
   534 	test.Next(_L("Test terminating a resumed thread created by us"));
   535 	thread.Create(TestThreadNull);
   536 	thread.Logon(logonStatus);
   537 	SyncMutex.Wait();
   538 	thread.Resume();
   539 	thread.Terminate(999);
   540 	SyncMutex.Signal();
   541 	User::WaitForRequest(logonStatus);
   542 	test(thread.ExitType()==EExitTerminate);
   543 	test(logonStatus==999);
   544 	CLOSE_AND_WAIT(thread);
   545 
   546 	test.Next(_L("Try terminating un-resumed thread not created by self"));
   547 	thread.Create(TestThreadNull);
   548 	process.Create(~0u,ETestProcessTerminate,thread.Id());
   549 	thread.Logon(logonStatus2);
   550 	process.Logon(logonStatus);
   551 	process.Resume();
   552 	User::WaitForRequest(logonStatus);
   553 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   554 	test(logonStatus==EPlatformSecurityTrap);
   555 	test(logonStatus2==KRequestPending); // the thread should still be alive
   556 	thread.Resume();
   557 	User::WaitForRequest(logonStatus2);
   558 	test(logonStatus2==KErrNone);
   559 	CLOSE_AND_WAIT(thread);
   560 	CLOSE_AND_WAIT(process);
   561 
   562 	test.Next(_L("Try terminating resumed thread not created by self"));
   563 	thread.Create(TestThreadNull);
   564 	process.Create(~0u,ETestProcessTerminate,thread.Id());
   565 	thread.Logon(logonStatus2);
   566 	process.Logon(logonStatus);
   567 	SyncMutex.Wait();
   568 	thread.Resume();
   569 	process.Resume();
   570 	User::WaitForRequest(logonStatus);
   571 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   572 	test(logonStatus==EPlatformSecurityTrap);
   573 	test(logonStatus2==KRequestPending); // the thread should still be alive
   574 	SyncMutex.Signal();
   575 	User::WaitForRequest(logonStatus2);
   576 	test(logonStatus2==KErrNone);
   577 	CLOSE_AND_WAIT(thread);
   578 	CLOSE_AND_WAIT(process);
   579 
   580 	test.Next(_L("Test a thread terminating itself"));
   581 	thread.Create(TestThreadTerminateSelf);
   582 	thread.Logon(logonStatus);
   583 	thread.Resume();
   584 	User::WaitForRequest(logonStatus);
   585 	test(thread.ExitType()==EExitTerminate);
   586 	test(logonStatus==999);
   587 	CLOSE_AND_WAIT(thread);
   588 
   589 	// Test RProcess::Panic()
   590 
   591 	test.Next(_L("Test panicking an un-resumed thread created by us"));
   592 	thread.Create(TestThreadNull);
   593 	thread.Logon(logonStatus);
   594 	User::SetJustInTime(EFalse);
   595 	thread.Panic(KTestPanicCategory,999);
   596 	User::WaitForRequest(logonStatus);
   597 	User::SetJustInTime(jit);
   598 	test(thread.ExitType()==EExitPanic);
   599 	test(logonStatus==999);
   600 	CLOSE_AND_WAIT(thread);
   601 
   602 	test.Next(_L("Test panicking a resumed thread created by us"));
   603 	thread.Create(TestThreadNull);
   604 	thread.Logon(logonStatus);
   605 	SyncMutex.Wait();
   606 	thread.Resume();
   607 	User::SetJustInTime(EFalse);
   608 	thread.Panic(KTestPanicCategory,999);
   609 	SyncMutex.Signal();
   610 	User::WaitForRequest(logonStatus);
   611 	User::SetJustInTime(jit);
   612 	test(thread.ExitType()==EExitPanic);
   613 	test(logonStatus==999);
   614 	CLOSE_AND_WAIT(thread);
   615 
   616 	test.Next(_L("Try panicking un-resumed thread not created by self"));
   617 	thread.Create(TestThreadNull);
   618 	process.Create(~0u,ETestProcessPanic,thread.Id());
   619 	thread.Logon(logonStatus2);
   620 	process.Logon(logonStatus);
   621 	process.Resume();
   622 	User::WaitForRequest(logonStatus);
   623 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   624 	test(logonStatus==EPlatformSecurityTrap);
   625 	test(logonStatus2==KRequestPending); // the thread should still be alive
   626 	thread.Resume();
   627 	User::WaitForRequest(logonStatus2);
   628 	test(logonStatus2==KErrNone);
   629 	CLOSE_AND_WAIT(thread);
   630 	CLOSE_AND_WAIT(process);
   631 
   632 	test.Next(_L("Try panicking resumed thread not created by self"));
   633 	thread.Create(TestThreadNull);
   634 	process.Create(~0u,ETestProcessPanic,thread.Id());
   635 	thread.Logon(logonStatus2);
   636 	process.Logon(logonStatus);
   637 	SyncMutex.Wait();
   638 	thread.Resume();
   639 	process.Resume();
   640 	User::WaitForRequest(logonStatus);
   641 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   642 	test(logonStatus==EPlatformSecurityTrap);
   643 	test(logonStatus2==KRequestPending); // the thread should still be alive
   644 	SyncMutex.Signal();
   645 	User::WaitForRequest(logonStatus2);
   646 	test(logonStatus2==KErrNone);
   647 	CLOSE_AND_WAIT(thread);
   648 	CLOSE_AND_WAIT(process);
   649 
   650 	test.Next(_L("Test a thread panicking itself"));
   651 	thread.Create(TestThreadPanicSelf);
   652 	thread.Logon(logonStatus);
   653 	User::SetJustInTime(EFalse);
   654 	thread.Resume();
   655 	User::WaitForRequest(logonStatus);
   656 	User::SetJustInTime(jit);
   657 	test(thread.ExitType()==EExitPanic);
   658 	test(logonStatus==999);
   659 	CLOSE_AND_WAIT(thread);
   660 
   661 	// 
   662 
   663 	test.End();
   664 	}
   665 
   666 
   667 //---------------------------------------------
   668 //! @SYMTestCaseID KBASE-T_STHREAD-0120
   669 //! @SYMTestCaseDesc Set thread priority
   670 //! @SYMTestType UT
   671 //! @SYMREQ historical, enhanced under PREQ955
   672 //! @SYMTestActions Test setting all thread priority values to threads in this process,
   673 //!     and in another process, resumed and not.
   674 //! @SYMTestExpectedResults Confirm can set and get "normal application" thread priorities
   675 //!     for threads in this process, whether resumed or not. Confirm thread is panicked
   676 //!     if attempts to set priority of thread in another process. Confirm can set and get
   677 //!     "real-time" thread priorities if this process has ProtServ capability, and that
   678 //!     calling thread is panicked if not.
   679 //! @SYMTestPriority Critical
   680 //! @SYMTestStatus Implemented
   681 //---------------------------------------------
   682 void TestSetPriority()
   683 	{
   684 	RTestThread thread;
   685 	RTestProcess process;
   686 	TRequestStatus logonStatus;
   687 	TRequestStatus logonStatus2;
   688 
   689 	test.Start(_L("Test changing our own threads priority"));
   690 	TestSetNormalApplicationPriorities(thread);
   691 
   692 	test.Next(_L("Test changing priority of un-resumed thread in our process"));
   693 	thread.Create(TestThreadNull);
   694 	thread.Logon(logonStatus);
   695 	TestSetNormalApplicationPriorities(thread);
   696 
   697 	test.Next(_L("Test changing priority of resumed thread in our process"));
   698 	SyncMutex.Wait();
   699 	thread.Resume();
   700 	TestSetNormalApplicationPriorities(thread);
   701 	SyncMutex.Signal();
   702 	User::WaitForRequest(logonStatus);
   703 	test(logonStatus==KErrNone);
   704 	CLOSE_AND_WAIT(thread);
   705 
   706 	test.Next(_L("Try changing priority of an un-resumed thread in other process"));
   707 	thread.Create(TestThreadNull);
   708 	thread.Logon(logonStatus);
   709 	thread.SetPriority(EPriorityAbsoluteHigh);
   710 	process.Create(~0u,ETestProcessSetPriority,thread.Id(),EPriorityAbsoluteLow);
   711 	process.Logon(logonStatus2);
   712 	process.Resume();
   713 	User::WaitForRequest(logonStatus2);
   714 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   715 	test(logonStatus2==EPlatformSecurityTrap);
   716 	test(thread.Priority()==EPriorityAbsoluteHigh); // Priority should be unaltered
   717 
   718 	test.Next(_L("Try changing priority of a resumed thread in other process"));
   719 	process.Create(~0u,ETestProcessSetPriority,thread.Id(),EPriorityAbsoluteLow);
   720 	process.Logon(logonStatus2);
   721 	SyncMutex.Wait();
   722 	thread.Resume();
   723 	process.Resume();
   724 	User::WaitForRequest(logonStatus2);
   725 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   726 	test(logonStatus2==EPlatformSecurityTrap);
   727 	test(thread.Priority()==EPriorityAbsoluteHigh); // Priority should be unaltered
   728 	SyncMutex.Signal();
   729 	User::WaitForRequest(logonStatus);
   730 	test(logonStatus==KErrNone);
   731 	CLOSE_AND_WAIT(thread);
   732 
   733 	test.Next(_L("Test setting thread priorities without ECapabilityProtServ"));
   734 	process.Create(~(1u<<ECapabilityProtServ), ETestProcessSetPrioritiesWithoutProtServ);
   735 	process.Run();
   736 	
   737 	test.Next(_L("Test setting thread priorities with ECapabilityProtServ"));
   738 	process.Create(1<<ECapabilityProtServ, ETestProcessSetPrioritiesWithProtServ);
   739 	process.Run();
   740 
   741 	test.End();
   742 	}
   743 
   744 
   745 TRequestStatus TestRequest;
   746 
   747 TInt TestThreadRequestComplete(TAny* aArg)
   748 	{
   749 	RThread thread;
   750 	TInt r = thread.Open((TInt)aArg);
   751 	if(r==KErrNone)
   752 		{
   753 		TRequestStatus* status = &TestRequest;
   754 		thread.RequestComplete(status,KErrNone);
   755 		}
   756 	return r;
   757 	}
   758 
   759 void TestRequestComplete()
   760 	{
   761 	RTestThread thread;
   762 	RTestProcess process;
   763 	TRequestStatus logonStatus;
   764 
   765 	test.Start(_L("Test RequestComplete on thread in current process"));
   766 	TestRequest = KRequestPending;
   767 	thread.Create(TestThreadRequestComplete,(TAny*)(TUint)RThread().Id());
   768 	thread.Logon(logonStatus);
   769 	thread.Resume();
   770 	User::WaitForRequest(TestRequest);
   771 	test(TestRequest==KErrNone);
   772 	User::WaitForRequest(logonStatus);
   773 	test(logonStatus==KErrNone);
   774 	CLOSE_AND_WAIT(thread);
   775 
   776 	test.Next(_L("Test RequestComplete on with NULL request pointer"));
   777 	test(RThread().RequestCount()==0); // No signals
   778 	TRequestStatus* nullReq = 0;
   779 	RThread().RequestComplete(nullReq,0);
   780 	test(RThread().RequestCount()==0); // No signals
   781 
   782 	test.Next(_L("Test RequestComplete on thread in different process"));
   783 	TestRequest = KRequestPending;
   784 	process.Create(~0u,ETestProcessRequestComplete,RThread().Id(),(TInt)&TestRequest);
   785 	process.Logon(logonStatus);
   786 	process.Resume();
   787 	User::WaitForRequest(logonStatus);
   788 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   789 	test(logonStatus==EPlatformSecurityTrap);
   790 	test(TestRequest==KRequestPending);
   791 	CLOSE_AND_WAIT(process);
   792 
   793 	test.End();
   794 	}
   795 
   796 
   797 
   798 TInt TestThreadRequestSignal(TAny* aArg)
   799 	{
   800 	RThread thread;
   801 	TInt r = thread.Open((TInt)aArg);
   802 	if(r==KErrNone)
   803 		thread.RequestSignal();
   804 	return r;
   805 	}
   806 
   807 void TestRequestSignal()
   808 	{
   809 	RTestThread thread;
   810 	RTestProcess process;
   811 	TRequestStatus logonStatus;
   812 	TInt count;
   813 
   814 	test.Start(_L("Test RequestSignal on thread in current process"));
   815 	thread.Create(TestThreadRequestSignal,(TAny*)(TUint)RThread().Id());
   816 	thread.Logon(logonStatus);
   817 	count = RThread().RequestCount();
   818 	test(count==0); // No signals yet
   819 	thread.Resume();
   820 	User::WaitForRequest(logonStatus);
   821 	test(logonStatus==KErrNone);
   822 	count = RThread().RequestCount();
   823 	test(count==1); // We should have been signalled
   824 	User::WaitForAnyRequest();	// eat signal
   825 	CLOSE_AND_WAIT(thread);
   826 
   827 	test.Next(_L("Test RequestSignal on thread in different process"));
   828 	process.Create(~0u,ETestProcessRequestSignal,RThread().Id(),0);
   829 	process.Logon(logonStatus);
   830 	process.Resume();
   831 	User::WaitForRequest(logonStatus);
   832 	test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic
   833 	test(logonStatus==EPlatformSecurityTrap);
   834 	count = RThread().RequestCount();
   835 	test(count==0); // We shouldn't have been signalled
   836 	CLOSE_AND_WAIT(process);
   837 
   838 	test.End();
   839 	}
   840 
   841 
   842 
   843 void TestSetProcessPriority()
   844 	{
   845 	RTestThread thread;
   846 	RTestProcess process;
   847 	TProcessPriority priority;
   848 	TRequestStatus rendezvousStatus;
   849 	TRequestStatus logonStatus;
   850 	TInt r;
   851 
   852 	test.Start(_L("Test changing our own process priority"));
   853 	priority = process.Priority();
   854 	thread.SetProcessPriority(EPriorityLow);
   855 	test(process.Priority()==EPriorityLow);
   856 	thread.SetProcessPriority(EPriorityBackground);
   857 	test(process.Priority()==EPriorityBackground);
   858 	thread.SetProcessPriority(EPriorityForeground);
   859 	test(process.Priority()==EPriorityForeground);
   860 	thread.SetProcessPriority(priority);
   861 
   862 	test.Next(_L("Try changing other process's priority (no priority-control enabled)"));
   863 	process.Create(~0u,ETestProcessPriorityControlOff);
   864 	process.Rendezvous(rendezvousStatus);
   865 	process.Logon(logonStatus);
   866 	SyncMutex.Wait();
   867 	process.Resume();
   868 	User::WaitForRequest(rendezvousStatus); // Process has started
   869 	r = thread.Open(rendezvousStatus.Int()); // Process returned Id of main thread as status value
   870 	test(r==KErrNone);
   871 	priority = process.Priority();
   872 	thread.SetProcessPriority(EPriorityLow);
   873 	test(process.Priority()==priority); // priority shouldn't have changed
   874 	thread.SetProcessPriority(EPriorityBackground);
   875 	test(process.Priority()==priority); // priority shouldn't have changed
   876 	thread.SetProcessPriority(EPriorityForeground);
   877 	test(process.Priority()==priority); // priority shouldn't have changed
   878 	test(logonStatus==KRequestPending); // wait for process to end
   879 	SyncMutex.Signal();
   880 	User::WaitForRequest(logonStatus);
   881 	CLOSE_AND_WAIT(thread);
   882 	CLOSE_AND_WAIT(process);
   883 
   884 	test.Next(_L("Try changing other process's priority (priority-control enabled)"));
   885 	process.Create(~0u,ETestProcessPriorityControlOn);
   886 	process.Rendezvous(rendezvousStatus);
   887 	process.Logon(logonStatus);
   888 	SyncMutex.Wait();
   889 	process.Resume();
   890 	User::WaitForRequest(rendezvousStatus); // Process has started
   891 	r = thread.Open(rendezvousStatus.Int()); // Process returned Id of main thread as status value
   892 	test(r==KErrNone);
   893 	priority = process.Priority();
   894 	thread.SetProcessPriority(EPriorityForeground);
   895 	test(process.Priority()==EPriorityForeground);
   896 	thread.SetProcessPriority(EPriorityBackground);
   897 	test(process.Priority()==EPriorityBackground);
   898 	thread.SetProcessPriority(EPriorityForeground);
   899 	test(process.Priority()==EPriorityForeground);
   900 	thread.SetProcessPriority(EPriorityLow);
   901 	test(process.Priority()==EPriorityForeground); // should still be foreground priority
   902 	thread.SetProcessPriority(priority);
   903 	test(logonStatus==KRequestPending); // wait for process to end
   904 	SyncMutex.Signal();
   905 	User::WaitForRequest(logonStatus);
   906 	CLOSE_AND_WAIT(thread);
   907 	CLOSE_AND_WAIT(process);
   908 
   909 	test.End();
   910 	}
   911 
   912 
   913 
   914 GLDEF_C TInt E32Main()
   915     {
   916 	TBuf16<512> cmd;
   917 	User::CommandLine(cmd);
   918 	if(cmd.Length() && TChar(cmd[0]).IsDigit())
   919 		{
   920 		TInt function = -1;
   921 		TInt arg1 = -1;
   922 		TInt arg2 = -1;
   923 		TLex lex(cmd);
   924 
   925 		lex.Val(function);
   926 		lex.SkipSpace();
   927 		lex.Val(arg1);
   928 		lex.SkipSpace();
   929 		lex.Val(arg2);
   930 		return DoTestProcess(function,arg1,arg2);
   931 		}
   932 
   933 	test.Title();
   934 
   935 	if((!PlatSec::ConfigSetting(PlatSec::EPlatSecProcessIsolation))||(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)))
   936 		{
   937 		test.Start(_L("TESTS NOT RUN - PlatSecProcessIsolation is not enforced"));
   938 		test.End();
   939 		return 0;
   940 		}
   941 
   942 	test(SyncMutex.CreateGlobal(KSyncMutex)==KErrNone);
   943 	
   944 	test.Start(_L("Test Rename"));
   945 	TestRename();
   946 
   947 	test.Next(_L("Test Resume"));
   948 	TestResume();
   949 
   950 	test.Next(_L("Test Suspend"));
   951 	TestSuspend();
   952 
   953 	test.Next(_L("Test Kill, Panic and Teminate"));
   954 	TestKill();
   955 
   956 	test.Next(_L("Test SetPriority"));
   957 	TestSetPriority();
   958 
   959 	test.Next(_L("Test RequestComplete"));
   960 	TestRequestComplete();
   961 
   962 	test.Next(_L("Test RequestSignal"));
   963 	TestRequestSignal();
   964 
   965 	test.Next(_L("Test SetProcessPriority"));
   966 	TestSetProcessPriority();
   967 
   968 
   969 	SyncMutex.Close();
   970 	test.End();
   971 
   972 	return(0);
   973     }
   974