debugsrv/runmodedebug/securityserver/src/c_security_svr_session.cpp
changeset 42 0ff24a8f6ca2
child 56 aa2539c91954
equal deleted inserted replaced
41:838cdffd57ce 42:0ff24a8f6ca2
       
     1 // Copyright (c) 2006-2010 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 // Provides the debug security server session implementation.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology
       
    21  @released
       
    22 */
       
    23 
       
    24 // Needed so we get the text strings for capabilities
       
    25 #define __INCLUDE_CAPABILITY_NAMES__
       
    26 
       
    27 #include <e32std.h>
       
    28 #include <e32std_private.h>
       
    29 #include <e32btrace.h>
       
    30 #include <d32btrace.h>
       
    31 #include <e32base.h>
       
    32 #include <e32base_private.h>
       
    33 #include <e32uid.h>
       
    34 #include <f32file.h>
       
    35 #include <e32capability.h>
       
    36 #include <rm_debug_api.h>
       
    37 
       
    38 // required for direct parsing of e32image/tromimage headers
       
    39 #include <f32image.h>
       
    40 #include <e32rom.h>
       
    41 
       
    42 //added for direct access to media driver
       
    43 #include <partitions.h>
       
    44 #include <ftlcontrolio.h>
       
    45 
       
    46 #include "c_security_svr_session.h"
       
    47 #include "c_security_svr_server.h"
       
    48 #include "c_security_svr_async.h"
       
    49 #include "rm_debug_logging.h"
       
    50 #ifdef _DEBUG
       
    51 #include "low_mem_requests.h"
       
    52 #endif
       
    53 
       
    54 using namespace Debug;
       
    55 
       
    56 CSecuritySvrSession::CSecuritySvrSession(const TProcessId& aDebugAgentProcessId)
       
    57 	: iDebugAgentProcessId(aDebugAgentProcessId),
       
    58 	  iServerNotified(EFalse),
       
    59 	  iCrashConnected(EFalse)
       
    60 	{
       
    61 	// Ensure that this debug agent has no target capability override
       
    62 	// by default
       
    63 	iOEMDebugCapabilities.SetEmpty();
       
    64 	}
       
    65 
       
    66 void CSecuritySvrSession::ServiceError(const RMessage2 &aMessage, TInt aError)
       
    67 	{
       
    68 	LOG_MSG2("CSecuritySvrSession::ServiceError(), aError: %d\n", aError);
       
    69 
       
    70 	//insert ending heap markers
       
    71 	HeapWatcher(aMessage.Function(), EFalse);
       
    72 
       
    73 	aMessage.Complete(aError);
       
    74 	}
       
    75 
       
    76 /**
       
    77 Called by the client/server framework as part of session creation.
       
    78 
       
    79 Notifies the server that a session is being created
       
    80 */
       
    81 void CSecuritySvrSession::CreateL()
       
    82 	{
       
    83 	LOG_MSG("CSecuritySvrSession::CreateL()\n");
       
    84 
       
    85 	//notify the server that the session has been opened
       
    86 	Server().SessionOpened();
       
    87 	iServerNotified = ETrue;
       
    88 	}
       
    89 
       
    90 /**
       
    91   Returns a reference to the DSS
       
    92 
       
    93   @return a reference to the DSS
       
    94   */
       
    95 CSecuritySvrServer& CSecuritySvrSession::Server() const
       
    96     {
       
    97     return *static_cast<CSecuritySvrServer*>(const_cast<CServer2*>(CSession2::Server()));
       
    98     }
       
    99 
       
   100 /**
       
   101 Session destructor. Performs necessary cleanup and notifies the server that the
       
   102 session is being closed
       
   103 */
       
   104 CSecuritySvrSession::~CSecuritySvrSession()
       
   105 	{
       
   106 	LOG_MSG("CSecuritySvrSession::~CSecuritySvrSession!()\n");
       
   107 
       
   108 	// Cancel any outstanding async objects.
       
   109 	iAsyncHandlers.ResetAndDestroy();
       
   110 		
       
   111 	// Inform the device driver of the agent detach.
       
   112 	Server().iKernelDriver.DetachAgent(iDebugAgentProcessId.Id());
       
   113 
       
   114 	LOG_MSG( "CSecuritySvrSession::~CSecuritySvrSession() : -> securityServer.DetachAllProcesses()\n" );
       
   115 	Server().DetachAllProcesses(iDebugAgentProcessId);
       
   116 
       
   117 	//notify the server that the session has closed
       
   118 	if(iServerNotified)
       
   119 		{
       
   120 		Server().SessionClosed();
       
   121 		}
       
   122 	}
       
   123 
       
   124 void CSecuritySvrSession::ConstructL()
       
   125 	{
       
   126 	// nothing to do
       
   127 	}
       
   128 
       
   129 /**
       
   130   Used to insert heap checking markers.
       
   131 
       
   132   @param aFunction The function that heap markers should be added for
       
   133   @param aEntry if ETrue indicates that heap checking is starting, if EFalse
       
   134   that heap checking is ending.
       
   135   */
       
   136 void CSecuritySvrSession::HeapWatcher(const TUint32 aFunction, const TBool aEntry) const
       
   137 	{
       
   138 	switch(aFunction)
       
   139 		{
       
   140 		case EDebugServAttachExecutable:
       
   141 			return;
       
   142 		case EDebugServDetachExecutable:
       
   143 			return;
       
   144 		case EDebugServSuspendThread:
       
   145 			return;
       
   146 		case EDebugServResumeThread:
       
   147 			return;
       
   148 		case EDebugServAttachAll:
       
   149 			return;
       
   150 		case EDebugServDetachAll:
       
   151 			return;
       
   152 // used for out-of-memory testing in debug mode
       
   153 #ifdef _DEBUG
       
   154 		// start heap marking in on entry, do nothing on exit
       
   155 		case EDebugServMarkHeap:
       
   156 			{
       
   157 			if(aEntry)
       
   158 				{
       
   159 				__UHEAP_MARK;
       
   160 				}
       
   161 			return;
       
   162 			}
       
   163 		// stop heap marking on exit, do nothing on entry
       
   164 		case EDebugServMarkEnd:
       
   165 			{
       
   166 			if(!aEntry)
       
   167 				{
       
   168 				__UHEAP_MARKEND;
       
   169 				}
       
   170 			return;
       
   171 			}
       
   172 #endif
       
   173 		default:
       
   174 			if(aEntry)
       
   175 				{
       
   176 				__UHEAP_MARK;
       
   177 				}
       
   178 			else
       
   179 				{
       
   180 				__UHEAP_MARKEND;
       
   181 				}
       
   182 			return;
       
   183 		}
       
   184 	}
       
   185 
       
   186 void CSecuritySvrSession::ServiceL(const RMessage2& aMessage)
       
   187 //
       
   188 // Session service handler
       
   189 //
       
   190 	{
       
   191 	//insert starting heap markers
       
   192 	HeapWatcher(aMessage.Function(), ETrue);
       
   193 
       
   194 	switch(aMessage.Function())
       
   195 		{
       
   196 		case EDebugServResumeThread:
       
   197 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServResumeThread\n" );
       
   198 			ResumeThreadL(aMessage);
       
   199 			break;
       
   200 
       
   201 		case EDebugServSuspendThread:
       
   202 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServSuspendThread\n" );
       
   203 			SuspendThreadL(aMessage);
       
   204 			break;
       
   205 
       
   206 		case EDebugServReadMemory:
       
   207 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServReadMemory\n" );
       
   208 			ReadMemoryL(aMessage);
       
   209 			break;
       
   210 
       
   211 		case EDebugServWriteMemory:
       
   212 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServWriteMemory\n" );
       
   213 			WriteMemoryL(aMessage);
       
   214 			break;
       
   215 
       
   216 		case EDebugServSetBreak:
       
   217 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServSetBreak\n" );
       
   218 			SetBreakL(aMessage);
       
   219 			break;
       
   220 
       
   221 		case EDebugServClearBreak:
       
   222 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServClearBreak\n" );
       
   223 			ClearBreakL(aMessage);
       
   224 			break;
       
   225 
       
   226 		case EDebugServModifyBreak:
       
   227 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServModifyBreak\n" );
       
   228 			ModifyBreakL(aMessage);
       
   229 			break;
       
   230 
       
   231 		case EDebugServModifyProcessBreak:
       
   232 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServModifyProcessBreak\n" );
       
   233 			ModifyProcessBreakL(aMessage);
       
   234 			break;
       
   235 
       
   236 		case EDebugServBreakInfo:
       
   237 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServBreakInfo\n" );
       
   238 			BreakInfoL(aMessage);
       
   239 			break;
       
   240 
       
   241 		case EDebugServReadRegisters:
       
   242 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServReadRegisters\n" );
       
   243 			ReadRegistersL(aMessage);
       
   244 			break;
       
   245 
       
   246 		case EDebugServWriteRegisters:
       
   247 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServWriteRegisters\n" );
       
   248 			WriteRegistersL(aMessage);
       
   249 			break;
       
   250 
       
   251 		case EDebugServGetEvent:
       
   252 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServGetEvent\n" );
       
   253 			GetEventL(aMessage);
       
   254 			break;
       
   255 
       
   256 		case EDebugServCancelGetEvent:
       
   257 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServCancelGetEvent\n" );
       
   258 			CancelGetEventL(aMessage);
       
   259 			break;
       
   260 
       
   261 		case EDebugServAttachExecutable:
       
   262 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServAttachExecutable\n" );
       
   263 			AttachProcessL(aMessage);
       
   264 			break;
       
   265 
       
   266 		case EDebugServDetachExecutable:
       
   267 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServDetachExecutable\n" );
       
   268 			DetachProcessL(aMessage);
       
   269 			break;
       
   270 
       
   271 		case EDebugServAttachAll:
       
   272 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServAttachAll\n" );
       
   273 			AttachAllL(aMessage);
       
   274 			break;
       
   275 
       
   276 		case EDebugServDetachAll:
       
   277 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServDetachAll\n" );
       
   278 			DetachAllL(aMessage);
       
   279 			break;			
       
   280 			
       
   281 		case EDebugServGetDebugFunctionalityBufSize:
       
   282 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServGetDebugFunctionalityBufSize\n" );
       
   283 			GetDebugFunctionalityBufSizeL(aMessage);
       
   284 			break;
       
   285 
       
   286 		case EDebugServGetDebugFunctionality:
       
   287 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServGetDebugFunctionality\n" );
       
   288 			GetDebugFunctionalityL(aMessage);
       
   289 			break;
       
   290 
       
   291 		case EDebugServSetEventAction:
       
   292 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServSetEventAction\n" );
       
   293 			SetEventActionL(aMessage);
       
   294 			break;
       
   295 
       
   296 		case EDebugServGetList:
       
   297 			LOG_MSG( "CSecuritySvrSession::ServiceL() EDebugServGetList\n" );
       
   298 			GetListL(aMessage);
       
   299 			break;
       
   300 
       
   301 		case EDebugServStep:
       
   302 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServStep\n");
       
   303 			StepL(aMessage);
       
   304 			break;
       
   305 
       
   306 		case EDebugServSetProcessBreak:
       
   307 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServSetProcessBreak\n");
       
   308 			SetProcessBreakL(aMessage);
       
   309 			break;
       
   310 		
       
   311 		case EDebugServProcessBreakInfo:
       
   312 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServProcessBreakInfo\n");
       
   313 			ProcessBreakInfoL(aMessage);
       
   314 			break;
       
   315 
       
   316 		case EDebugServKillProcess:
       
   317 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServKillProcess\n");
       
   318 			KillProcessL(aMessage);
       
   319 			break;
       
   320 
       
   321 #ifdef _DEBUG
       
   322 		case EDebugServMarkHeap:
       
   323 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServMarkHeap\n");
       
   324 			// all taken care of in HeapWatcher
       
   325 			aMessage.Complete(KErrNone);
       
   326 			break;
       
   327 
       
   328 		case EDebugServMarkEnd:
       
   329 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServMarkEnd\n");
       
   330 			// all taken care of in HeapWatcher
       
   331 			aMessage.Complete(KErrNone);
       
   332 			break;
       
   333 
       
   334 		case EDebugServFailAlloc:
       
   335 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServFailAlloc\n");
       
   336 			DoFailAlloc(aMessage);
       
   337 			break;
       
   338 #endif
       
   339 		case EDebugServReadCrashFlash:
       
   340 			ReadCrashLogL(aMessage);
       
   341 			break;		
       
   342 		case EDebugServWriteCrashFlash:
       
   343 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServWriteCrashFlash\n");
       
   344 			WriteCrashConfigL(aMessage);
       
   345 			break;
       
   346 		case EDebugServEraseCrashFlash:
       
   347 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServEraseCrashFlash\n");
       
   348 			EraseCrashLogL(aMessage);
       
   349 			break;
       
   350 		case EDebugServEraseEntireCrashFlash:
       
   351 			LOG_MSG("CSecuritySvrSession::ServiceL() EDebugServEraseEntireCrashFlash\n");
       
   352 			EraseEntireCrashLogL(aMessage);
       
   353 			break;
       
   354 		default:
       
   355 			LOG_MSG( "CSecuritySvrSession::ServiceL() Unknown request, calling User::Leave(KErrNotSupported);\n" );
       
   356 			User::Leave(KErrNotSupported);
       
   357 			break;
       
   358 		}
       
   359 
       
   360 	//insert ending heap markers
       
   361 	HeapWatcher(aMessage.Function(), EFalse);
       
   362 	
       
   363 	LOG_EXIT();
       
   364 	}
       
   365 
       
   366 #ifdef _DEBUG
       
   367 /**
       
   368   Used to control heap failure in debug mode.
       
   369   @param aMessage If aMessage.Int0 is non-zero then heap will be set to fail on that allocation.
       
   370   If aMessage.Int0 is zero then the heap failure count is reset
       
   371   */
       
   372 void CSecuritySvrSession::DoFailAlloc(const RMessage2& aMessage)
       
   373 	{
       
   374 	TInt count = aMessage.Int0();
       
   375 	if(count == 0)
       
   376 		{
       
   377 		__UHEAP_RESET;
       
   378 		}
       
   379 	else
       
   380 		{
       
   381 		__UHEAP_FAILNEXT(count);
       
   382 		}
       
   383 	aMessage.Complete(KErrNone);
       
   384 	}
       
   385 #endif
       
   386 
       
   387 /**
       
   388 Suspends execution of the specified thread.
       
   389 
       
   390 @param aMessage contains an integer representation of the target thread's
       
   391        thread ID at offset 0.
       
   392 
       
   393 @leave KErrPermissionDenied if security check fails or KErrArgument if the
       
   394        thread does not exist
       
   395 */
       
   396 void CSecuritySvrSession::SuspendThreadL(const RMessage2& aMessage)
       
   397 	{
       
   398 
       
   399 	LOG_MSG( "CSecuritySvrSession::SuspendThreadL()\n" );
       
   400 
       
   401 	//get thread ID
       
   402 	TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   403 	//check attached
       
   404 	CheckAttachedL(threadId, aMessage, EFalse);
       
   405 
       
   406 	//security check passed so can perform actions
       
   407 	User::LeaveIfError(Server().iKernelDriver.SuspendThread(threadId));
       
   408 
       
   409 	aMessage.Complete(KErrNone);
       
   410 	}
       
   411 
       
   412 /**
       
   413 Resumes execution of the specified thread.
       
   414 
       
   415 @param aMessage contains an integer representation of the target thread's
       
   416        thread ID at offset 0.
       
   417 
       
   418 @leave KErrPermissionDenied if security check fails or KErrArgument if the
       
   419        thread does not exist
       
   420 */
       
   421 void CSecuritySvrSession::ResumeThreadL(const RMessage2& aMessage)
       
   422 	{
       
   423 	LOG_MSG( "CSecuritySvrSession::ResumeThreadL()\n" );
       
   424 
       
   425 	//get thread ID
       
   426 	TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   427 
       
   428 	//check attached
       
   429 	CheckAttachedL(threadId, aMessage, EFalse);
       
   430 	
       
   431 	//security check passed so can perform actions
       
   432 	TInt err = Server().iKernelDriver.ResumeThread(threadId);
       
   433 	aMessage.Complete(err);
       
   434 	}
       
   435 
       
   436 void CSecuritySvrSession::GetDebugFunctionalityBufSizeL(const RMessage2& aMessage)
       
   437 //
       
   438 // Retrieve size of functionality data buffer in bytes which must be allocated
       
   439 // by the client
       
   440 //
       
   441 	{
       
   442 	LOG_MSG( "CSecuritySvrSession::GetDebugFunctionalityBufSizeL()\n" );
       
   443 
       
   444 	TUint32 result = 0;
       
   445 	// Get Buffer size from the kernel driver
       
   446 	User::LeaveIfError(Server().iKernelDriver.GetDebugFunctionalityBufSize(result));
       
   447 
       
   448 	TPtr8 stuff((TUint8*)&result,4, 4);
       
   449 
       
   450 	aMessage.WriteL(0,stuff);
       
   451 
       
   452 	aMessage.Complete(KErrNone);
       
   453 	}
       
   454 
       
   455 void CSecuritySvrSession::GetDebugFunctionalityL(const RMessage2& aMessage)
       
   456 //
       
   457 // Retrieve the functionality data and place it in a buffer
       
   458 // allocated by the client.
       
   459 //
       
   460 	{
       
   461 	LOG_MSG( "CSecuritySvrSession::GetDebugFunctionalityL()\n" );
       
   462 
       
   463 	TUint32 dfsize = 0;
       
   464 
       
   465 	// Get Buffer size from the kernel driver
       
   466 	User::LeaveIfError(Server().iKernelDriver.GetDebugFunctionalityBufSize(dfsize));
       
   467 
       
   468 	// Allocate space for the functionality data
       
   469 	HBufC8* dftext = HBufC8::NewLC(dfsize);
       
   470 
       
   471 	const TPtr8& dfPtr = dftext->Des();
       
   472 
       
   473 	// Extract said data from the device driver
       
   474 	User::LeaveIfError(Server().iKernelDriver.GetDebugFunctionality((TDes8&)dfPtr));
       
   475 
       
   476 	// Return data to client
       
   477 	aMessage.WriteL(0,dfPtr);
       
   478 
       
   479 	// Free buffer
       
   480 	CleanupStack::PopAndDestroy(dftext);
       
   481 
       
   482 	aMessage.Complete(KErrNone);
       
   483 	}
       
   484 
       
   485 /**
       
   486 Reads memory from a specified thread using the passed parameters. The user 
       
   487 should ensure that the TPtr8 that is passed in has size greater than or equal
       
   488 to the size of the memory that is trying to be read.
       
   489 
       
   490 @param aMessage The RMessage2 object should be constructed as follows:
       
   491     * aMessage.Int0() is the thread ID of the target debug app
       
   492     * aMessage.Ptr1() is a TMemoryInfo object which contains the following:
       
   493         * the address of the memory to be read from the target debug thread
       
   494         * the size of the memory block to be read from the target debug thread
       
   495 	* the access size to use
       
   496 	* the endianess to interpret the data as
       
   497     * aMessage.Ptr2() is the address of the buffer in the debug agent thread 
       
   498       that the data from the target debug app should be written into 
       
   499 
       
   500 @leave KErrPermissionDenied if client is not attached to the target
       
   501        thread's process,
       
   502        KErrNoMemory if memory could not be allocated,
       
   503        KErrArgument if there are problems with the aMessage object,
       
   504        KErrBadHandle if the thread represented by aMessage.Ptr0() is invalid,
       
   505        an error value from CSecuritySvrSession::ValidateMemoryInfo if checking
       
   506        the memory attributes failed,
       
   507        or another of the system wide error codes
       
   508 */
       
   509 void CSecuritySvrSession::ReadMemoryL(const RMessage2& aMessage)
       
   510 	{
       
   511 	LOG_MSG( "CSecuritySvrSession::ReadMemoryL()\n" );
       
   512 
       
   513 	//get debug app thread ID
       
   514 	TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   515 
       
   516 	CheckAttachedL(threadId, aMessage, ETrue);
       
   517 
       
   518 	//create and initialise the memory info object
       
   519 	TMemoryInfo targetMemory;
       
   520 	TPtr8 targetMemoryPtr( (TUint8 *)&targetMemory, sizeof(TMemoryInfo) );
       
   521 
       
   522 	aMessage.ReadL(1,targetMemoryPtr);
       
   523 
       
   524 	//check memory info is acceptable
       
   525 	ValidateMemoryInfoL(threadId, targetMemory, ETrue);
       
   526 
       
   527 	RBuf8 data;
       
   528 	data.CreateL(targetMemory.iSize);
       
   529 	data.CleanupClosePushL();
       
   530 
       
   531 	//fill buffer with data from target debug thread
       
   532 	User::LeaveIfError(Server().iKernelDriver.ReadMemory(threadId, targetMemory.iAddress, targetMemory.iSize, data));
       
   533 
       
   534 	//attempt to write the data from the target debug thread back to the agent
       
   535 	aMessage.WriteL(2, data);
       
   536 
       
   537 	//delete temporary buffer
       
   538 	CleanupStack::PopAndDestroy(&data);
       
   539 
       
   540 	aMessage.Complete(KErrNone);
       
   541 	}
       
   542 
       
   543 /**
       
   544 Writes memory to a specified thread using the passed parameters. 
       
   545 
       
   546 @param aMessage The RMessage2 object should be constructed as follows:
       
   547     * aMessage.Ptr0() is the thread ID of the target debug app
       
   548     * aMessage.Ptr1() is a TMemoryInfo object which contains the following:
       
   549         * the address of the memory to be written to the target debug thread
       
   550         * the size of the memory block to be written to the target debug thread
       
   551 	* the access size to use
       
   552 	* the endianess to interpret the data as
       
   553     * aMessage.Ptr2() is the address of the buffer in the debug agent thread 
       
   554       that the data to write to the target debug app should be read from
       
   555 
       
   556 @leave KErrPermissionDenied if client is not attached (actively) to the target
       
   557        thread's process,
       
   558        KErrNoMemory if memory could not be allocated,
       
   559        KErrArgument if there are problems with the aMessage object,
       
   560        KErrBadHandle if the thread represented by aMessage.Ptr0() is invalid,
       
   561        an error value from CSecuritySvrSession::ValidateMemoryInfo if checking
       
   562        the memory attributes failed,
       
   563        or another of the system wide error codes
       
   564 */
       
   565 void CSecuritySvrSession::WriteMemoryL(const RMessage2& aMessage)
       
   566 	{
       
   567 	LOG_MSG( "CSecuritySvrSession::WriteMemoryL()\n" );
       
   568 
       
   569 	//get debug app thread ID
       
   570 	TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   571 
       
   572 	CheckAttachedL(threadId, aMessage, EFalse);
       
   573 
       
   574 	//create and initialise the memory info object
       
   575 	TMemoryInfo targetMemory;
       
   576 	TPtr8 targetMemoryPtr( (TUint8 *)&targetMemory, sizeof(TMemoryInfo) );
       
   577 
       
   578 	aMessage.ReadL(1,targetMemoryPtr);
       
   579 
       
   580 	//check memory info is acceptable
       
   581 	ValidateMemoryInfoL(threadId, targetMemory, EFalse);
       
   582 
       
   583 	//create temporary buffer and read data from client
       
   584 	RBuf8 data;
       
   585 	data.CreateL(targetMemory.iSize);
       
   586 	data.CleanupClosePushL();
       
   587 	
       
   588 	aMessage.ReadL(2, data);
       
   589 
       
   590 	// what about telling the driver about endianess/access size?
       
   591 	User::LeaveIfError(Server().iKernelDriver.WriteMemory(threadId, targetMemory.iAddress, targetMemory.iSize, data));
       
   592 
       
   593 	//free temporary buffer
       
   594 	CleanupStack::PopAndDestroy(&data);
       
   595 
       
   596 	aMessage.Complete(KErrNone);
       
   597 	}
       
   598 
       
   599 /**
       
   600 @internalTechnology
       
   601 
       
   602 Notes: This call is used to set a thread specific breakpoint. Its input arguments
       
   603 are the thread id, address and architecture type of the breakpoint. It returns success
       
   604 or failure, and if successful, it sets the TBreakId in the Debug Agent to the 
       
   605 breakpoint id by which it can be referenced in future calls to ModifyBreak,ClearBreak and
       
   606 BreakInfo.
       
   607 
       
   608 @param aMessage.Ptr0() - aThreadId is thread id of the target debug process
       
   609 @param aMessage.Ptr1() - Address of a TBreakInfo in the Debug Agent
       
   610 @param aMessage.Ptr2() - Address of a TBreakId in the Debug Agent
       
   611 @leave KErrPermissionDenied if the security check fails.
       
   612  KErrAlreadyExists if there is a breakpoint overlapping the desired address.
       
   613  KErrNotSupported if the architecture type is unrecognised.
       
   614  KErrNoMemory if there is no more memory to complete the operation.
       
   615  KErrArgument if the breakpoint address alignment is unsuitable for the requested
       
   616  breakpoint.
       
   617  KErrOverflow if there are too many breakpoints set.
       
   618 */
       
   619 void CSecuritySvrSession::SetBreakL(const RMessage2& aMessage)
       
   620 	{
       
   621 	LOG_MSG( "CSecuritySvrSession::SetBreakL!()\n" );
       
   622 
       
   623 	//get debug app thread ID
       
   624 	TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   625 
       
   626 	//check that the agent has attached to the target process
       
   627 	CheckAttachedL(threadId, aMessage, EFalse);
       
   628 
       
   629 	//create and initialise the break info object
       
   630 	TBreakInfo breakInfo;
       
   631 	TPtr8 breakInfoPtr( (TUint8 *)&breakInfo, sizeof(TBreakInfo) );
       
   632 
       
   633 	aMessage.ReadL(1,breakInfoPtr);
       
   634 
       
   635 	LOG_MSG4( "CSecuritySvrSession::SetBreakL, threadId=0x%lx, addr=0x%x, mode=%d", 
       
   636 			threadId.Id(), breakInfo.iAddress, breakInfo.iArchitectureMode);
       
   637 			
       
   638 	//set break in target app
       
   639 	TBreakId breakId = 0;
       
   640 	User::LeaveIfError(Server().iKernelDriver.SetBreak(breakId, threadId, breakInfo.iAddress, breakInfo.iArchitectureMode));
       
   641 
       
   642 	//attempt to write the break id back to the debug agent
       
   643 	WriteDataL(aMessage, 2, &breakId, sizeof(breakId));
       
   644 
       
   645 	aMessage.Complete(KErrNone);
       
   646 	}
       
   647 
       
   648 /**
       
   649 Clears a breakpoint previously set by a SetBreak() call.
       
   650 
       
   651 @param aMessage.Int0() - TBreakId of the breakpoint to be removed.
       
   652 */
       
   653 void CSecuritySvrSession::ClearBreakL(const RMessage2& aMessage)
       
   654 	{
       
   655 	LOG_MSG( "CSecuritySvrSession::ClearBreakL()\n" );
       
   656 
       
   657 	const TInt breakId = aMessage.Int0();
       
   658 
       
   659 	// Check that the breakpoint exists
       
   660 	TUint64 objectId;
       
   661 	TUint32 address;
       
   662 	TArchitectureMode mode;
       
   663 	TBool threadSpecific = EFalse;
       
   664 
       
   665 	User::LeaveIfError(Server().iKernelDriver.BreakInfo(breakId,objectId,address,mode,threadSpecific));
       
   666 
       
   667 	if(threadSpecific)
       
   668 		{
       
   669 		// Check that the debug agent is attached to the thread for which the
       
   670 		// breakpoint is currently set.
       
   671 		LOG_MSG4( "CSecuritySvrSession::ClearBreakL( brkId=%d), addr=0x%x, tId=0x%x", 
       
   672 			breakId, address, I64LOW(objectId) );		
       
   673 		CheckAttachedL(TThreadId(objectId), aMessage, EFalse);		
       
   674 		}
       
   675 	else
       
   676 		{
       
   677 		// Check that the debug agent is attached to the process for which the
       
   678 		// breakpoint is currently set.
       
   679 		LOG_MSG4( "CSecuritySvrSession::ClearBreakL( brkId=%d), addr=0x%x, pId=0x%x", 
       
   680 			breakId, address, I64LOW(objectId) );		
       
   681 		CheckAttachedL(TProcessId(objectId), aMessage, EFalse);
       
   682 		}
       
   683 
       
   684 	// Finally clear the breakpoint
       
   685 	User::LeaveIfError(Server().iKernelDriver.ClearBreak(breakId));
       
   686 
       
   687 	aMessage.Complete(KErrNone);
       
   688 	}
       
   689 
       
   690 /**
       
   691 @param aMessage.Int0() - Breakpoint Id of interest
       
   692 @param aMessage.Ptr1() - Address in Debug Agent to place threadId of the breakpoint
       
   693 @param aMessage.Ptr2() - Address in Debug Agent to place address of the breakpoint
       
   694 @param aMessage.Ptr3() - Address in Debug Agent to place the architecture mode of the breakpoint
       
   695 @leave Any error which may be returned by RSessionBase::SendReceive()
       
   696 */
       
   697 void CSecuritySvrSession::BreakInfoL(const RMessage2& aMessage)
       
   698 	{
       
   699 	const TBreakId breakId = (TBreakId)aMessage.Int0();
       
   700 
       
   701 	TThreadId threadId;
       
   702 	TUint32 address;
       
   703 	TArchitectureMode mode;
       
   704 	TBool threadSpecific = ETrue;
       
   705 
       
   706 	TUint64 threadIdData;
       
   707 	User::LeaveIfError(Server().iKernelDriver.BreakInfo(breakId,threadIdData,address,mode,threadSpecific));
       
   708 
       
   709 	if(!threadSpecific)
       
   710 		{
       
   711 		User::Leave(KErrNotFound);
       
   712 		}
       
   713 
       
   714 	threadId = TThreadId(threadIdData);
       
   715 
       
   716 	//check that the agent has attached to the target process
       
   717 	CheckAttachedL(threadId, aMessage, EFalse);
       
   718 
       
   719 	// return the threadId
       
   720 	WriteDataL(aMessage, 1, &threadId, sizeof(threadId));
       
   721 
       
   722 	// return the address
       
   723 	WriteDataL(aMessage, 2, &address, sizeof(address));
       
   724 
       
   725 	// return the mode
       
   726 	WriteDataL(aMessage, 3, &mode, sizeof(mode));
       
   727 
       
   728 	aMessage.Complete(KErrNone);
       
   729 	}
       
   730 
       
   731 /**
       
   732 @internalTechnology
       
   733 
       
   734 Modify a previously set breakpoint.
       
   735 
       
   736 @param aMessage.Int0() - The breakpoint id of the breakpoint to modify
       
   737 @param aMessage.Ptr1() - The new Thread Id for the breakpoint
       
   738 @param aMessage.Int2() - The new virtual memory address for the breakpoint
       
   739 @param aMessage.Int3() - The new architecture mode for the breakpoint
       
   740 @return KErrNone if succesful. KErrPermissionDenied if the security check fails.
       
   741  KErrAlreadyExists if there is a breakpoint overlapping the desired address.
       
   742  KErrNotSupported if the architecture type is unrecognised.
       
   743  KErrNoMemory if there is no more memory to complete the operation.
       
   744  KErrArgument if the breakpoint address alignment is unsuitable for the requested
       
   745  breakpoint.
       
   746  KErrOverflow if there are too many breakpoints set.
       
   747 */
       
   748 void CSecuritySvrSession::ModifyBreakL(const RMessage2& aMessage)
       
   749 	{
       
   750 	const TBreakId breakId = (TBreakId)aMessage.Int0();
       
   751 	const TThreadId threadId = ReadTThreadIdL(aMessage, 1);
       
   752 	const TUint32 address = aMessage.Int2();
       
   753 	const TArchitectureMode mode = (TArchitectureMode)aMessage.Int3();
       
   754 
       
   755 	// Get information on the breakpoint to check the security status
       
   756 	TUint64 checkThreadId;
       
   757 	TUint32 checkAddress;
       
   758 	TArchitectureMode checkMode;
       
   759 	TBool threadSpecific;
       
   760 
       
   761 	User::LeaveIfError(Server().iKernelDriver.BreakInfo(breakId,checkThreadId,checkAddress,checkMode,threadSpecific));
       
   762 
       
   763 	LOG_MSG4( "CSecuritySvrSession::ModifyBreakL(brkId=%d) tId=0x%x, addr=0x%x", 
       
   764 			breakId, I64LOW(threadId.Id()), address );
       
   765 			
       
   766 	// Security check that the thread Id is associated with the debug agent
       
   767 
       
   768 	//check that the agent has attached to the target process
       
   769 	CheckAttachedL(TThreadId(checkThreadId), aMessage, EFalse);
       
   770 
       
   771 	// now check that the thread Id which is being set is permitted
       
   772 	//check that the agent has attached to the target process
       
   773 	CheckAttachedL(threadId, aMessage, EFalse);
       
   774 
       
   775 	User::LeaveIfError(Server().iKernelDriver.ModifyBreak(breakId,threadId,address,mode));
       
   776 
       
   777 	aMessage.Complete(KErrNone);
       
   778 	}
       
   779 
       
   780 /**
       
   781 @internalTechnology
       
   782 
       
   783 Notes: This call is used to set a process wide breakpoint. Its input arguments
       
   784 are the process id, address and architecture type of the breakpoint. It returns success
       
   785 or failure, and if successful, it sets the TBreakId in the Debug Agent to the 
       
   786 breakpoint id by which it can be referenced in future calls to ModifyBreak,ClearBreak and
       
   787 BreakInfo.
       
   788 
       
   789 @param aMessage.Ptr0() - aProcessId is process id of the target debug process
       
   790 @param aMessage.Ptr1() - Address of a TBreakInfo in the Debug Agent
       
   791 @param aMessage.Ptr2() - Address of a TBreakId in the Debug Agent
       
   792 @leave KErrPermissionDenied if the security check fails.
       
   793  KErrAlreadyExists if there is a breakpoint overlapping the desired address.
       
   794  KErrNotSupported if the architecture type is unrecognised.
       
   795  KErrNoMemory if there is no more memory to complete the operation.
       
   796  KErrArgument if the breakpoint address alignment is unsuitable for the requested
       
   797  breakpoint.
       
   798  KErrOverflow if there are too many breakpoints set.
       
   799 */
       
   800 void CSecuritySvrSession::SetProcessBreakL(const RMessage2& aMessage)
       
   801 	{
       
   802 	LOG_MSG( "CSecuritySvrSession::SetProcessBreakL()\n" );
       
   803 
       
   804 	//get debug app thread ID
       
   805 	TProcessId procId = ReadTProcessIdL(aMessage, 0);
       
   806 
       
   807 	//check that the agent has attached to the target process
       
   808 	CheckAttachedL(procId, aMessage, EFalse);
       
   809 
       
   810 	//create and initialise the memory info object
       
   811 	TBreakInfo breakInfo;
       
   812 	TPtr8 breakInfoPtr( (TUint8 *)&breakInfo, sizeof(TBreakInfo) );
       
   813 
       
   814 	aMessage.ReadL(1,breakInfoPtr);
       
   815 
       
   816 	LOG_MSG4( "CSecuritySvrSession::SetProcessBreakL pId=0x%x, addr=0x%x, mode=%d ", 
       
   817 			I64LOW(procId.Id()), breakInfo.iAddress, breakInfo.iArchitectureMode );
       
   818 
       
   819 	//set break in target app
       
   820 	TBreakId breakId = 0;
       
   821 	User::LeaveIfError(Server().iKernelDriver.SetProcessBreak(breakId, procId, breakInfo.iAddress, breakInfo.iArchitectureMode));
       
   822 
       
   823 	//attempt to write the break id back to the debug agent
       
   824 	WriteDataL(aMessage, 2, &breakId, sizeof(breakId));
       
   825 
       
   826 	aMessage.Complete(KErrNone);
       
   827 	}
       
   828 
       
   829 /**
       
   830 @internalTechnology
       
   831 
       
   832 Modify a previously set process breakpoint.
       
   833 
       
   834 @param aMessage.Int0() - The breakpoint id of the breakpoint to modify
       
   835 @param aMessage.Ptr1() - The new Process Id for the breakpoint
       
   836 @param aMessage.Int2() - The new virtual memory address for the breakpoint
       
   837 @param aMessage.Int3() - The new architecture mode for the breakpoint
       
   838 @return KErrNone if succesful. KErrPermissionDenied if the security check fails.
       
   839  KErrAlreadyExists if there is a breakpoint overlapping the desired address.
       
   840  KErrNotSupported if the architecture type is unrecognised.
       
   841  KErrNoMemory if there is no more memory to complete the operation.
       
   842  KErrArgument if the breakpoint address alignment is unsuitable for the requested
       
   843  breakpoint.
       
   844  KErrOverflow if there are too many breakpoints set.
       
   845 */
       
   846 void CSecuritySvrSession::ModifyProcessBreakL(const RMessage2& aMessage)
       
   847 	{
       
   848 	const TBreakId breakId = (TBreakId)aMessage.Int0();
       
   849 	const TProcessId processId = ReadTProcessIdL(aMessage, 1);
       
   850 	const TUint32 address = aMessage.Int2();
       
   851 	const TArchitectureMode mode = (TArchitectureMode)aMessage.Int3();
       
   852 
       
   853 	// Get information on the breakpoint to check the security status
       
   854 	TUint64 checkProcessId;
       
   855 	TUint32 checkAddress;
       
   856 	TArchitectureMode checkMode;
       
   857 	TBool threadSpecific;
       
   858 
       
   859 	User::LeaveIfError(Server().iKernelDriver.BreakInfo(breakId,checkProcessId,checkAddress,checkMode,threadSpecific));
       
   860 
       
   861 	LOG_MSG4( "CSecuritySvrSession::ModifyProcessBreakL(brkId=%d) pId=0x%x, addr=0x%x", 
       
   862 			breakId, I64LOW(processId.Id()), address );
       
   863 
       
   864 
       
   865 	// Security check that the process Id is associated with the debug agent
       
   866 
       
   867 	//check that the agent has attached to the target process
       
   868 	CheckAttachedL(TProcessId(checkProcessId), aMessage, EFalse);
       
   869 
       
   870 	// now check that the process Id which is being set is permitted
       
   871 	//check that the agent has attached to the target process
       
   872 	CheckAttachedL(processId, aMessage, EFalse);
       
   873 
       
   874 	User::LeaveIfError(Server().iKernelDriver.ModifyProcessBreak(breakId,processId,address,mode));
       
   875 
       
   876 	aMessage.Complete(KErrNone);
       
   877 	}
       
   878 
       
   879 /**
       
   880 @param aMessage.Int0() - Breakpoint Id of interest
       
   881 @param aMessage.Ptr1() - Address in Debug Agent to place process Id of the breakpoint
       
   882 @param aMessage.Ptr2() - Address in Debug Agent to place address of the breakpoint
       
   883 @param aMessage.Ptr3() - Address in Debug Agent to place the architecture mode of the breakpoint
       
   884 @leave Any error which may be returned by RSessionBase::SendReceive()
       
   885 */
       
   886 void CSecuritySvrSession::ProcessBreakInfoL(const RMessage2& aMessage)
       
   887 	{
       
   888 	const TBreakId breakId = (TBreakId)aMessage.Int0();
       
   889 
       
   890 	TProcessId procId;
       
   891 	TUint32 address;
       
   892 	TArchitectureMode mode;
       
   893 	TBool threadSpecific;
       
   894 
       
   895 	TUint64 procIdData;
       
   896 	User::LeaveIfError(Server().iKernelDriver.BreakInfo(breakId,procIdData,address,mode,threadSpecific));
       
   897 	if(threadSpecific)
       
   898 		{
       
   899 		User::Leave(KErrNotFound);
       
   900 		}
       
   901 	procId = TProcessId(procIdData);
       
   902 
       
   903 	//check that the agent has attached to the target process
       
   904 	CheckAttachedL(procId, aMessage, EFalse);
       
   905 
       
   906 	// return the processId
       
   907 	WriteDataL(aMessage, 1, &procId, sizeof(procId));
       
   908 
       
   909 	// return the address
       
   910 	WriteDataL(aMessage, 2, &address, sizeof(address));
       
   911 
       
   912 	// return the mode
       
   913 	WriteDataL(aMessage, 3, &mode, sizeof(mode));
       
   914 
       
   915 	aMessage.Complete(KErrNone);
       
   916 	}
       
   917 
       
   918 /**
       
   919 Read register values.
       
   920 
       
   921 @param aMessage should contain:
       
   922         * at offset 0 a pointer to the thread ID of the target thread
       
   923         * at offset 1 a descriptor representing an array of TRegisterInfo 
       
   924           register IDs
       
   925         * at offset 2 a descriptor representing an array into which TRegister 
       
   926           register values will be written
       
   927         * at offset 3 a descriptor representing an array into which TUint8 
       
   928           register flags will be written
       
   929 
       
   930 @leave KErrArgument if the max length of the array at offset 1 is not a 
       
   931        multiple of sizeof(TRegisterInfo), if the max length of the array 
       
   932        at offset 2 is not a multiple of sizeof(TRegister), if the max 
       
   933        length of the array at offset 3 is not a multiple of sizeof(TUint8), if
       
   934        any of the descriptors have max length of 0, or if the three 
       
   935        descriptors do not represent the same number of registers,
       
   936        KErrNoMemory if there is insufficient memory,
       
   937        KErrDied, if the thread with thread ID aThreadId is dead
       
   938 */
       
   939 void CSecuritySvrSession::ReadRegistersL(const RMessage2& aMessage)
       
   940 	{
       
   941 	LOG_MSG( "CSecuritySvrSession::ReadRegistersL()\n" );
       
   942 
       
   943 	const TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
   944 
       
   945 	//check the agent is attached to the thread
       
   946 	CheckAttachedL(threadId, aMessage, ETrue);
       
   947 
       
   948 	//number of registers being requested
       
   949 	TUint32 numberOfRegisters;
       
   950 
       
   951 	//check length of descriptors is acceptable
       
   952 	ValidateRegisterBuffersL(aMessage, numberOfRegisters);
       
   953 
       
   954 	// Passed data will be saved in this descriptor.
       
   955 	RBuf8 ids;
       
   956 	ids.CreateL(numberOfRegisters * sizeof(TRegisterInfo));
       
   957 	// Do the right cleanup if anything subsequently goes wrong
       
   958 	ids.CleanupClosePushL();
       
   959 	
       
   960 	//read the data from the client thread
       
   961 	aMessage.ReadL(1, ids);
       
   962 
       
   963 	//create buffer to fill with data from target debug thread
       
   964 	HBufC8 *data = HBufC8::NewLC(aMessage.GetDesMaxLength(2));
       
   965 	TPtr8 values(data->Des());   
       
   966 	
       
   967 	HBufC8 *flagsData = HBufC8::NewLC(numberOfRegisters * sizeof(TUint8));
       
   968 	TPtr8 flags(flagsData->Des());   
       
   969 	
       
   970 	//get register info and return relevant parts back to agent
       
   971 	User::LeaveIfError(Server().iKernelDriver.ReadRegisters(threadId, ids, values, flags));
       
   972 	aMessage.WriteL(2, values);
       
   973 	aMessage.WriteL(3, flags);
       
   974 	
       
   975 	//delete temporary buffers and return status
       
   976 	CleanupStack::PopAndDestroy(flagsData);
       
   977 	CleanupStack::PopAndDestroy(data);
       
   978 	CleanupStack::PopAndDestroy(&ids);
       
   979 
       
   980 	aMessage.Complete(KErrNone);
       
   981 	}
       
   982 
       
   983 /**
       
   984 Write register values.
       
   985 
       
   986 @param aMessage should contain:
       
   987         * at offset 0 a pointer to the thread ID of the target thread
       
   988         * at offset 1 a descriptor representing an array of TRegisterInfo 
       
   989           register IDs
       
   990         * at offset 2 a descriptor representing an array of TRegister register 
       
   991           values
       
   992         * at offset 3 a descriptor representing an array into which TUint8 
       
   993           register flags will be written
       
   994 
       
   995 @leave KErrArgument if the max length of the array at offset 1 is not a 
       
   996        multiple of sizeof(TRegisterInfo), if the max length of the array 
       
   997        at offset 2 is not a multiple of sizeof(TRegister), if the max 
       
   998        length of the array at offset 3 is not a multiple of sizeof(TUint8), if
       
   999        any of the descriptors have max length of 0, or if the three 
       
  1000        descriptors do not represent the same number of registers,
       
  1001        KErrNoMemory if there is insufficient memory,
       
  1002        KErrDied, if the thread with thread ID aThreadId is dead
       
  1003 */
       
  1004 void CSecuritySvrSession::WriteRegistersL(const RMessage2& aMessage)
       
  1005 	{
       
  1006 	LOG_MSG( "CSecuritySvrSession::WriteRegistersL()\n" );
       
  1007 
       
  1008 	const TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
  1009 
       
  1010 	CheckAttachedL(threadId, aMessage, EFalse);
       
  1011 
       
  1012 	//number of registers attempting to set
       
  1013 	TUint32 numberOfRegisters;
       
  1014 
       
  1015 	//check length of descriptors is acceptable
       
  1016 	ValidateRegisterBuffersL(aMessage, numberOfRegisters);
       
  1017 
       
  1018 	// Passed register ids will be saved in this descriptor.
       
  1019 	RBuf8 ids;
       
  1020 
       
  1021 	//allocate buffer
       
  1022 	ids.CreateL(numberOfRegisters * sizeof(TRegisterInfo));
       
  1023 
       
  1024 	// Do the right cleanup if anything subsequently goes wrong
       
  1025 	ids.CleanupClosePushL();
       
  1026 
       
  1027 	//read the data from the client thread
       
  1028 	aMessage.ReadL(1, ids);
       
  1029 
       
  1030 	// Passed register values will be saved in this descriptor.
       
  1031 	RBuf8 values;
       
  1032 
       
  1033 	//allocate buffer
       
  1034 	values.CreateL(aMessage.GetDesMaxLength(2));
       
  1035 	// Do the right cleanup if anything subsequently goes wrong
       
  1036 	values.CleanupClosePushL();
       
  1037 	//read the data from the client thread
       
  1038 	aMessage.ReadL(2,values);
       
  1039 
       
  1040 	HBufC8 *flagsData = HBufC8::NewLC(numberOfRegisters*sizeof(TUint8));
       
  1041 	TPtr8 flags(flagsData->Des());
       
  1042 
       
  1043 	//get register info and return relevant parts back to agent
       
  1044 	User::LeaveIfError(Server().iKernelDriver.WriteRegisters(threadId, ids, values, flags));
       
  1045 
       
  1046 	//write flags data back
       
  1047 	aMessage.WriteL(3, flags);
       
  1048 
       
  1049 	CleanupStack::PopAndDestroy(flagsData);
       
  1050 	CleanupStack::PopAndDestroy(&values);
       
  1051 	CleanupStack::PopAndDestroy(&ids);
       
  1052 
       
  1053 	aMessage.Complete(KErrNone);
       
  1054 	}
       
  1055 
       
  1056 /**
       
  1057 Processes an attach request from a debug agent. Gets the target debug
       
  1058 processes' original FileName as an argument. The method sets completion
       
  1059 status of the aMessage argument to KErrNone if successfully attached and to
       
  1060 another of the system wide error codes if there were problems.
       
  1061 
       
  1062 @param aMessage contains:
       
  1063        * a boolean at offset 0 which indicates whether the agent wishes to
       
  1064        attach passively
       
  1065        * a buffer at offset 1 which contains the FileName
       
  1066        of the target debug process.
       
  1067 */
       
  1068 void CSecuritySvrSession::AttachProcessL(const RMessage2& aMessage)
       
  1069 	{
       
  1070 	LOG_MSG( "CSecuritySvrSession::AttachProcessL()\n" );
       
  1071 
       
  1072 	const TBool passive = aMessage.Int0();
       
  1073 
       
  1074 	TInt deslen = aMessage.GetDesLengthL(1);
       
  1075 
       
  1076 	// Passed data will be saved in this descriptor.
       
  1077 	RBuf processName;
       
  1078 
       
  1079 	// Max length set to the value of "deslen", but current length is zero
       
  1080 	processName.CreateL(deslen);
       
  1081 
       
  1082 	// Do the right cleanup if anything subsequently goes wrong
       
  1083 	processName.CleanupClosePushL();
       
  1084 
       
  1085 	// Copy the client's descriptor data into our buffer.
       
  1086 	aMessage.ReadL(1,processName);
       
  1087 
       
  1088 	//
       
  1089 	// Security Check
       
  1090 	//
       
  1091 	// It is not permitted to debug the debug security server!
       
  1092 	//
       
  1093 	// get the secure id of the executable
       
  1094 	TUid secureId(TUid::Null());
       
  1095 	GetSecureIdL(processName, secureId);
       
  1096 	if (KUidDebugSecurityServer.iUid == secureId.iUid)
       
  1097 		{
       
  1098 		// The debug agent has requested to debug the Debug Security Server
       
  1099 		// This is either an error, or an attempt to breach security. We
       
  1100 		// therefore refuse to agree to this request, and return KErrPermissionDenied
       
  1101 		LOG_MSG("Debug Agent attempted to debug the Debug Security Server");
       
  1102 		User::Leave(KErrPermissionDenied);
       
  1103 		}
       
  1104 
       
  1105 	// Check the OEM Debug token capabilities 
       
  1106 	GetDebugAgentOEMTokenCapsL();
       
  1107 	
       
  1108 	// Get the Security info via rlibrary::getinfo
       
  1109 	RLibrary::TInfo info;
       
  1110 	TPckg<RLibrary::TInfo> infoBuf(info);
       
  1111 
       
  1112 	TInt err = RLibrary::GetInfo(processName, infoBuf);
       
  1113 	if (err != KErrNone)
       
  1114 		{
       
  1115 		LOG_MSG2("Cannot parse the target executable header, err=%d", err);
       
  1116 		// Could not read the header for this executable :-(
       
  1117 		CleanupStack::PopAndDestroy(&processName);
       
  1118 		aMessage.Complete(err);
       
  1119 		return;
       
  1120 		}
       
  1121 	
       
  1122 	// Special case for AllFiles - OEM Debug tokens MUST have
       
  1123 	// AllFiles, as this is what allows them to read contents
       
  1124 	// of other executables.
       
  1125 	TBool checkDebuggable = ETrue;
       
  1126 
       
  1127 	// Does an OEM Debug Token permit debug where it would normally not be
       
  1128 	// permitted?
       
  1129 	if ( Server().OEMTokenPermitsDebugL(iOEMDebugCapabilities, info.iSecurityInfo.iCaps) )
       
  1130 		{
       
  1131 		// OEM Debug token is valid and has sufficient capabilities
       
  1132 		LOG_MSG("CSecuritySvrSession::AttachProcessL() - Debug Agent has sufficient capabilites based on OEM Debug Token");	
       
  1133 		
       
  1134 		checkDebuggable = EFalse;
       
  1135 		}
       
  1136 
       
  1137 	if (checkDebuggable)
       
  1138 		{
       
  1139 		// OEM Debug token (if any), does not confer sufficient capabilities to
       
  1140 		// debug the specified target executable. Therefore debugging can only
       
  1141 		// be permitted if the target executable itself has been built as 'Debuggable'
       
  1142 		LOG_MSG("CSecuritySvrSession::AttachProcessL() - Debug Agent has insufficient capabilites based on OEM Debug Token");	
       
  1143 
       
  1144 		IsDebuggableL(processName);
       
  1145 		}
       
  1146 
       
  1147 	User::LeaveIfError(Server().AttachProcessL(processName, iDebugAgentProcessId, passive));
       
  1148 
       
  1149 	// Inform the kernel driver about the attachment, so that it
       
  1150 	// can track per-agent data about the process.
       
  1151 	RBuf8 processName8;
       
  1152 
       
  1153 	processName8.CreateL(deslen);
       
  1154 
       
  1155 	processName8.CleanupClosePushL();
       
  1156 
       
  1157 	processName8.Copy(processName);
       
  1158 
       
  1159 	User::LeaveIfError(Server().iKernelDriver.AttachProcess(processName8, iDebugAgentProcessId.Id()));
       
  1160 
       
  1161 	// Create an Active Object to handle asynchronous calls to GetEvent
       
  1162 	CSecuritySvrAsync* handler = CSecuritySvrAsync::NewL(this,processName8,iDebugAgentProcessId);
       
  1163 
       
  1164 	err = iAsyncHandlers.Insert(handler,0);
       
  1165 	if (err != KErrNone)
       
  1166 		{
       
  1167 		// If we don't have an asynchronous handler, we should detach
       
  1168 		// the driver as well.
       
  1169 		Server().iKernelDriver.DetachProcess(processName8,iDebugAgentProcessId.Id());
       
  1170 		Server().DetachProcess(processName, iDebugAgentProcessId);
       
  1171 		// The DSS should NEVER panic itself. If the above calls fail, so be it we will attempt to limp on
       
  1172 		}
       
  1173 
       
  1174 	User::LeaveIfError(err);
       
  1175 
       
  1176 	CleanupStack::PopAndDestroy(&processName8);
       
  1177 
       
  1178 	CleanupStack::PopAndDestroy(&processName);
       
  1179 
       
  1180 	aMessage.Complete(KErrNone);
       
  1181 	}
       
  1182 
       
  1183 
       
  1184 /**
       
  1185 Processes an attach request from a debug agent from all processes. 
       
  1186 The method sets completion status of the aMessage argument to KErrNone 
       
  1187 if successfully attached and to another of the system wide error codes 
       
  1188 if there were problems.
       
  1189 
       
  1190 @param aMessage contains no data
       
  1191 */
       
  1192 void CSecuritySvrSession::AttachAllL(const RMessage2& aMessage)
       
  1193 	{
       
  1194 	LOG_MSG( "CSecuritySvrSession::AttachAllL()\n" );
       
  1195 
       
  1196 
       
  1197 	// Run the OEM Debug token, if run ok then sets iOEMDebugCapabilities
       
  1198 	GetDebugAgentOEMTokenCapsL();
       
  1199 
       
  1200 	// Debug token must have All caps to use AttachToAll
       
  1201 	TCapabilitySet allCaps;
       
  1202 	allCaps.SetAllSupported();
       
  1203 	if (!Server().OEMTokenPermitsDebugL(iOEMDebugCapabilities, allCaps))
       
  1204 		{
       
  1205 		LOG_MSG("Client's OEM token doesn't have capability ALL required for AttachAll()");
       
  1206 		User::Leave(KErrPermissionDenied);
       
  1207 		}
       
  1208 
       
  1209 
       
  1210 	User::LeaveIfError(Server().AttachProcessL(_L("*"), iDebugAgentProcessId, EFalse));
       
  1211 
       
  1212     TBuf8<1> KStar8=_L8("*");
       
  1213 
       
  1214     User::LeaveIfError(Server().iKernelDriver.AttachProcess(KStar8, iDebugAgentProcessId.Id()));
       
  1215 
       
  1216     // Create an Active Object to handle asynchronous calls to GetAllEvent
       
  1217     CSecuritySvrAsync* handler = CSecuritySvrAsync::NewL(this,KStar8,iDebugAgentProcessId);    
       
  1218     TInt err = iAsyncHandlers.Insert(handler,0);
       
  1219     if (err != KErrNone)
       
  1220         {
       
  1221         // If we don't have an asynchronous handler, we should detach
       
  1222         // the driver as well.
       
  1223         Server().iKernelDriver.DetachProcess(KStar8,iDebugAgentProcessId.Id());
       
  1224         Server().DetachProcess(_L("*"), iDebugAgentProcessId);
       
  1225         }
       
  1226 
       
  1227     User::LeaveIfError(err);
       
  1228 
       
  1229 	aMessage.Complete(KErrNone);   
       
  1230 	}
       
  1231 
       
  1232 
       
  1233 /**
       
  1234 Reads the OEM Debug Token associated with the debug agent if any. The OEM Debug Token
       
  1235 allows the Debug Agent to debug certain executables which have not been built as
       
  1236 'Debuggable'.
       
  1237 
       
  1238 This works as follows: The OEM Debug Token is an executable with a special name
       
  1239 of the form "OEMDebug_<DA_SID>.exe" where <DA_SID> is the Secure ID of the Debug Agent
       
  1240 in hexadecimal. For example: "OEMDebug_F123ABCD.exe" would be a valid name. This token executable
       
  1241 must be signed with 'AllFiles' + X, where X is the set of PlatSec capabilities that are
       
  1242 possessed by the target executable to be debugged.
       
  1243 
       
  1244 This function reads the capabilities possessed by the token by creating a process based
       
  1245 on the executable, and reading the TSecurityInfo associated with the process. This ensures
       
  1246 that the loader has validated the token has not been tampered with and that the security
       
  1247 information is valid.
       
  1248 
       
  1249 The security information is then stored for future use as member data in iOEMDebugCapabilities.
       
  1250 
       
  1251 Leaves if there is an error, otherwise simply fills in the capabilities
       
  1252 in iOEMDebugCapabilities.
       
  1253 
       
  1254 It is not an error for the OEM Debug token not to exist. In this case, the function simply returns.
       
  1255 */
       
  1256 void CSecuritySvrSession::GetDebugAgentOEMTokenCapsL(void)
       
  1257 	{
       
  1258 	if (iOEMDebugCapabilities.HasCapability(ECapabilityAllFiles))
       
  1259 		{
       
  1260 		// Then we've already read the caps - wasteful to read them again
       
  1261 		return;
       
  1262 		}
       
  1263 
       
  1264 	// Obtain the security info about the debug agent process
       
  1265 	//get the debug agent's process
       
  1266 	RProcess debugAgentProcess;
       
  1267 
       
  1268 	CleanupClosePushL(debugAgentProcess);
       
  1269 
       
  1270 	debugAgentProcess.Open(iDebugAgentProcessId);
       
  1271 
       
  1272 	// We have now obtained a process handle based on the token executable, so we can check its security properties.
       
  1273 	TSecurityInfo secInfo(debugAgentProcess);
       
  1274 
       
  1275 	// Compute the name of the OEM debug token based on the SID of the debug agent
       
  1276 	_LIT(KDSSOEMDebugTokenPrefix,"OEMDebug_");
       
  1277 	_LIT(KDSSOEMDebugTokenAppendFmt,"%08X.exe");
       
  1278 
       
  1279 	RBuf agentTokenName;
       
  1280 	agentTokenName.CreateL(KDSSOEMDebugTokenPrefix().Size()+8+1);	// allow space for SID+null terminator
       
  1281 	agentTokenName.CleanupClosePushL();
       
  1282 
       
  1283 	agentTokenName.SetLength(0);
       
  1284 
       
  1285 	// Add OEMDebug_
       
  1286 	agentTokenName.Append(KDSSOEMDebugTokenPrefix());
       
  1287 
       
  1288 	// Add debug agent Secure ID
       
  1289 	agentTokenName.AppendFormat(KDSSOEMDebugTokenAppendFmt,secInfo.iSecureId.iId);
       
  1290 	
       
  1291 	// just log the token name for the moment.
       
  1292 	RBuf8 agentTokenName8;
       
  1293 
       
  1294 	agentTokenName8.CreateL(agentTokenName.Length()+1);
       
  1295 
       
  1296 	agentTokenName8.CleanupClosePushL();
       
  1297 
       
  1298 	agentTokenName8.Copy(agentTokenName);
       
  1299 
       
  1300 	agentTokenName8.Append(TChar(0));
       
  1301 
       
  1302 	LOG_MSG2("CSecuritySvrSession::GetDebugAgentOEMTokenCapsL() - OEM Debug Token Name is %s",agentTokenName8.Ptr()); 
       
  1303 
       
  1304 	// Cleanup
       
  1305 	CleanupStack::PopAndDestroy(&agentTokenName8);
       
  1306 
       
  1307 	// Now locate and start the executable...
       
  1308 	RProcess agentToken;
       
  1309 	TInt err = agentToken.Create(agentTokenName, KNullDesC);
       
  1310 	if (KErrNone != err)
       
  1311 		{
       
  1312 		// Failed to create a process based on the token, just give up
       
  1313 		LOG_MSG2("CSecuritySvrSession::GetDebugAgentOEMTokenCapsL() - Could not create process based on token due to err 0x%8x\n",err);
       
  1314 		
       
  1315 		// Cleanup remaining items from the stack
       
  1316 		CleanupStack::PopAndDestroy(&agentTokenName);
       
  1317 
       
  1318 		CleanupStack::PopAndDestroy(&debugAgentProcess);
       
  1319 		return;
       
  1320 		}
       
  1321 
       
  1322 	// Synchronise with the process to make sure it hasn't died straight away
       
  1323 	TRequestStatus stat;
       
  1324 	agentToken.Rendezvous(stat);
       
  1325 	if (stat != KRequestPending)
       
  1326 		{
       
  1327 		// logon failed - agentToken is not yet running, so cannot have terminated
       
  1328 		agentToken.Kill(0);             // Abort startup
       
  1329 		}
       
  1330 
       
  1331 	// store the OEM Debug Token security data 
       
  1332 	TSecurityInfo agentSecInfo(agentToken);
       
  1333 
       
  1334 	// Note capabilities for future use
       
  1335 	iOEMDebugCapabilities=agentSecInfo.iCaps;
       
  1336 	
       
  1337 	// resume the token. It _should_ just exit, but we don't really care.
       
  1338 	agentToken.Resume();
       
  1339 
       
  1340 	// Wait to synchronise with agentToken - if it dies in the meantime, it
       
  1341 	// also gets completed
       
  1342 	User::WaitForRequest(stat);
       
  1343 
       
  1344 	// Just close the handle to it again.
       
  1345 	agentToken.Close();
       
  1346 
       
  1347 	// Cleanup remaining items from the stack
       
  1348 	CleanupStack::PopAndDestroy(&agentTokenName);
       
  1349 
       
  1350 	CleanupStack::PopAndDestroy(&debugAgentProcess);
       
  1351 
       
  1352 	}
       
  1353 
       
  1354 /**
       
  1355   Checks whether the file passed in as aExecutable is XIP or not
       
  1356 
       
  1357   @param aExecutable file to check
       
  1358   @return ETrue if the file is XIP, EFalse otherwise
       
  1359   */
       
  1360 TBool CSecuritySvrSession::IsExecutableXipL(RFile& aExecutable)
       
  1361 	{
       
  1362 	TUint atts;
       
  1363 	User::LeaveIfError(aExecutable.Att(atts));
       
  1364 
       
  1365 	return atts & KEntryAttXIP;
       
  1366 	}
       
  1367 
       
  1368 /**
       
  1369   Gets access to the symbian crash partition for crash access operation.
       
  1370   */
       
  1371 void CSecuritySvrSession::ConnectCrashPartitionL (void)
       
  1372 	{
       
  1373 	LOG_MSG("CSecuritySvrSession::ConnectCrashPartitionL()");
       
  1374 	
       
  1375 	TBool changed;
       
  1376 	TInt error = KErrNone;
       
  1377 	TInt i=0;
       
  1378 	
       
  1379 	//Intialising to EFalse
       
  1380 	iCrashConnected = EFalse;
       
  1381 	
       
  1382 	TPckg<TLocalDriveCapsV2> capsBuf(iCaps);
       
  1383 	
       
  1384 	//check for the symbian crash partition
       
  1385 	for (i=0; i<KMaxLocalDrives; i++)
       
  1386 		{
       
  1387 		error = iLocalDrive.Connect (i, changed);
       
  1388 		if ( error == KErrNone)
       
  1389 			{
       
  1390 			error = iLocalDrive.Caps(capsBuf);
       
  1391 			if ( error != KErrNone)
       
  1392 				{
       
  1393 				//continue if not found
       
  1394 				continue;
       
  1395 				}
       
  1396 			if ( iCaps.iPartitionType == (TUint16)KPartitionTypeSymbianCrashLog)
       
  1397 				{				
       
  1398 				LOG_MSG2("Found Symbian crash log partition on drive: %d",i);
       
  1399 				iCrashConnected = ETrue;
       
  1400 				break;
       
  1401 				}			
       
  1402 			}
       
  1403 		}
       
  1404 	if ( i == KMaxLocalDrives)
       
  1405 		{
       
  1406 		LOG_MSG("No crash log partition found with valid crash log signature found.  Exiting...");
       
  1407 		User::Leave (KErrNotFound);
       
  1408 		}
       
  1409 
       
  1410 	// Nand Flash not currently supported.
       
  1411 	if (iCaps.iType == EMediaNANDFlash)
       
  1412 		{
       
  1413 		LOG_MSG( "CSecuritySvrSession::ConnectCrashPartitionL()  Nand Flash not currently supported\n" );
       
  1414 		User::Leave (KErrNotSupported);
       
  1415 		}
       
  1416 	}
       
  1417 /** Checks that aHeaderData contains enough data to cast it to the
       
  1418   appropriate header type.
       
  1419 
       
  1420   @param aHeaderData buffer containing header data read from a file
       
  1421   @param aXip boolean indicating whether the header data is for an XIP image
       
  1422 
       
  1423   @return ETrue if enough data in buffer, EFalse otherwise
       
  1424   */
       
  1425 TBool CSecuritySvrSession::CheckSufficientData(const TDesC8& aHeaderData, const TBool aXip) const
       
  1426 	{
       
  1427 	TUint minimumHeaderSize = aXip ? sizeof(TRomImageHeader) : sizeof(E32ImageHeaderV);
       
  1428 	return (aHeaderData.Length() >= minimumHeaderSize);
       
  1429 	}
       
  1430 
       
  1431 /**
       
  1432   Opens a file handle to aFileName using aFileHandle
       
  1433   @param aFileName file to open handle to
       
  1434   @param aFs file system to use to open the handle
       
  1435   @param aFileHandle file handle to open
       
  1436 
       
  1437   @leave one of the system wide error codes
       
  1438   */
       
  1439 void CSecuritySvrSession::OpenFileHandleL(const TDesC& aFileName, RFs& aFs, RFile& aFileHandle)
       
  1440 	{
       
  1441 	TInt err = aFileHandle.Open(aFs, aFileName, EFileRead | EFileShareReadersOnly);
       
  1442 	if (err != KErrNone)
       
  1443 		{
       
  1444 		// Could not open the file for reading
       
  1445 		LOG_MSG("CSecuritySvrSession::OpenFileHandleL - Failed to open executable\n");
       
  1446 
       
  1447 		User::Leave(err);
       
  1448 		}
       
  1449 	}
       
  1450 
       
  1451 /**
       
  1452   Checks whether an executable has the debug bit set
       
  1453 
       
  1454   @param aHeaderData buffer containing the header of the executable
       
  1455   @param aXip indication of whether the executable is XIP or not
       
  1456 
       
  1457   @return ETrue if debug bit is set, EFalse otherwise
       
  1458   */
       
  1459 TBool CSecuritySvrSession::IsDebugBitSet(const TDesC8& aHeaderData, const TBool aXip)
       
  1460 	{
       
  1461 	if(!CheckSufficientData(aHeaderData, aXip))
       
  1462 		{
       
  1463 		return EFalse;
       
  1464 		}
       
  1465 
       
  1466 	if (aXip)
       
  1467 		{
       
  1468 		TRomImageHeader* hdr = (TRomImageHeader*)aHeaderData.Ptr();
       
  1469 		return (hdr->iFlags & KRomImageDebuggable);
       
  1470 		}
       
  1471 	else
       
  1472 		{
       
  1473 		// it is an epoc32 image
       
  1474 		E32ImageHeaderV* hdr = (E32ImageHeaderV*)aHeaderData.Ptr();
       
  1475 		return (hdr->iFlags & KImageDebuggable);
       
  1476 		}
       
  1477 	}
       
  1478 
       
  1479 /**
       
  1480 Determines whether a particular executable is marked as 'debuggable'
       
  1481 
       
  1482 Notes:
       
  1483 This function is currently hard coded to understand the format of e32 and
       
  1484 TRomImage file headers. Ideally this will be replaced by a call to RLibrary::GetInfo
       
  1485 which can return the 'debuggable' information. Unfortunately, this call currently
       
  1486 does not provide the information for XIP executables :-(
       
  1487 
       
  1488 @leave KErrPermissionDenied if the debug bit is not set, or one of the other
       
  1489 system wide error codes
       
  1490 */
       
  1491 void CSecuritySvrSession::IsDebuggableL(const TDesC& aFileName)
       
  1492 	{
       
  1493 #ifndef IGNORE_DEBUGGABLE_BIT
       
  1494 
       
  1495 	RFs fs;
       
  1496 	User::LeaveIfError(fs.Connect());
       
  1497 	CleanupClosePushL(fs);
       
  1498 
       
  1499 	RFile targetExe;
       
  1500 	OpenFileHandleL(aFileName, fs, targetExe);
       
  1501 	CleanupClosePushL(targetExe);
       
  1502 
       
  1503 	// Read in the entire header
       
  1504 	RBuf8 e32HdrBuf;
       
  1505 	e32HdrBuf.CreateL(RLibrary::KRequiredImageHeaderSize);
       
  1506 	e32HdrBuf.CleanupClosePushL();
       
  1507 
       
  1508 	// Read the entire header as far as possible
       
  1509 	TInt err = targetExe.Read(e32HdrBuf);
       
  1510 	if (err != KErrNone)
       
  1511 		{
       
  1512 		// Could not read the file 
       
  1513 		LOG_MSG("CSecuritySvrSession::IsDebuggableL - Failed to read executable\n");
       
  1514 
       
  1515 		User::Leave(err);
       
  1516 		}
       
  1517 
       
  1518 	if(!CheckSufficientData(e32HdrBuf, IsExecutableXipL(targetExe)))
       
  1519 		{
       
  1520 		User::Leave(KErrGeneral);
       
  1521 		}
       
  1522 
       
  1523 	if(! IsDebugBitSet(e32HdrBuf, IsExecutableXipL(targetExe)))
       
  1524 		{
       
  1525 		User::Leave(KErrPermissionDenied);
       
  1526 		}
       
  1527 	CleanupStack::PopAndDestroy(3, &fs);
       
  1528 
       
  1529 #else
       
  1530 	LOG_MSG("CSecuritySvrSession::IsDebuggableL() Debuggable bit temporarily ignored!!!");
       
  1531 #endif
       
  1532 	}
       
  1533 
       
  1534 /**
       
  1535 Processes a detach request from a debug agent. Gets the target debug
       
  1536 processes' original FileName as an argument. The method sets completion
       
  1537 status of the aMessage argument to KErrNone if successfully detached and to
       
  1538 another of the system wide error codes if there were problems.
       
  1539 
       
  1540 @param aMessage contains:
       
  1541        * a buffer at offset 0 which contains the FileName
       
  1542        of the target debug process.
       
  1543 */
       
  1544 void CSecuritySvrSession::DetachProcessL(const RMessage2& aMessage)
       
  1545 	{
       
  1546 	LOG_MSG( "CSecuritySvrSession::DetachProcessL()\n" );
       
  1547 
       
  1548 	TInt deslen = aMessage.GetDesLengthL(0);
       
  1549 	// Passed data will be saved in this descriptor.
       
  1550 	RBuf processName;
       
  1551 
       
  1552 	// Max length set to the value of "deslen", but current length is zero
       
  1553 	processName.CreateL(deslen);
       
  1554 
       
  1555 	// Do the right cleanup if anything subsequently goes wrong
       
  1556 	processName.CleanupClosePushL();
       
  1557 
       
  1558 	// Copy the client's descriptor data into our buffer.
       
  1559 	aMessage.ReadL(0,processName);
       
  1560 
       
  1561 	User::LeaveIfError(Server().DetachProcess(processName, iDebugAgentProcessId));
       
  1562 
       
  1563 	// Inform the kernel driver about the detachment, so that
       
  1564 	// it can stop tracking per-agent data for the debugged process.
       
  1565 	RBuf8 processName8;
       
  1566 
       
  1567 	processName8.CreateL(deslen);
       
  1568 
       
  1569 	processName8.CleanupClosePushL();
       
  1570 
       
  1571 	processName8.Copy(processName);
       
  1572 
       
  1573 	// Remove the Asynchronous Object associated with this process
       
  1574 	for(TInt i=0; i<iAsyncHandlers.Count(); i++)
       
  1575 		{
       
  1576 		if (processName8.Compare(iAsyncHandlers[i]->ProcessName()) == 0)
       
  1577 			{
       
  1578 			delete iAsyncHandlers[i];
       
  1579 			iAsyncHandlers.Remove(i);
       
  1580 
       
  1581 			break;
       
  1582 			}
       
  1583 		}
       
  1584 	
       
  1585 	// Inform the driver that we are no longer attached to this process
       
  1586 	User::LeaveIfError(Server().iKernelDriver.DetachProcess(processName8,iDebugAgentProcessId.Id()));
       
  1587 	
       
  1588 	CleanupStack::PopAndDestroy(&processName8);
       
  1589 	CleanupStack::PopAndDestroy(&processName);
       
  1590 
       
  1591 	aMessage.Complete(KErrNone);
       
  1592 	}
       
  1593 
       
  1594 /**
       
  1595 Processes a DetachAll request from a debug agent.
       
  1596 The method sets completion status of the aMessage argument to 
       
  1597 KErrNone if successfully detached and to
       
  1598 another of the system wide error codes if there were problems.
       
  1599 
       
  1600 @param aMessage contains:
       
  1601        * a buffer at offset 0 which contains the FileName
       
  1602        of the target debug process.
       
  1603 */
       
  1604 void CSecuritySvrSession::DetachAllL(const RMessage2& aMessage)
       
  1605 	{
       
  1606 	LOG_MSG( "CSecuritySvrSession::DetachAllL()" );
       
  1607 
       
  1608 	User::LeaveIfError(Server().DetachProcess(_L("*"), iDebugAgentProcessId));
       
  1609 
       
  1610 	TBuf8<1> KStar8=_L8("*");
       
  1611     
       
  1612 	TBool found = EFalse;
       
  1613 
       
  1614 	// Remove the Asynchronous Object associated with the AttachAll, not the rest
       
  1615 	for(TInt i=0; i<iAsyncHandlers.Count(); i++)
       
  1616 		{
       
  1617 		if (iAsyncHandlers[i]->ProcessName().Compare(KStar8) == 0)
       
  1618 			{
       
  1619 			delete iAsyncHandlers[i];
       
  1620 			iAsyncHandlers.Remove(i);
       
  1621 			User::LeaveIfError(Server().iKernelDriver.DetachProcess(KStar8,iDebugAgentProcessId.Id()));
       
  1622 			found = ETrue;
       
  1623 			break;
       
  1624 			}
       
  1625 		}
       
  1626 
       
  1627 	if( !found )
       
  1628 		{
       
  1629 		LOG_MSG2( "CSecuritySvrSession::DetachAllL() : Did not find the asynch handler for agent 0x%lx",
       
  1630 				iDebugAgentProcessId.Id() );
       
  1631 		User::Leave(KErrNotFound);
       
  1632 		}
       
  1633 
       
  1634 	aMessage.Complete(KErrNone);
       
  1635 	}
       
  1636 
       
  1637 /**
       
  1638 @param aMessage The RMessage2 object is expected to contain:
       
  1639   * aMessage.Int0() - TDes8 Containing the process name.
       
  1640   * aMessage.Int1() - Address of TPtr8 containing TEventInfo
       
  1641 
       
  1642 */
       
  1643 void CSecuritySvrSession::GetEventL(const RMessage2& aMessage)
       
  1644 	{
       
  1645 	LOG_MSG( "CSecuritySvrSession::GetEventL()\n" );
       
  1646 
       
  1647 	// Local descriptor to contain target process name
       
  1648 	TInt deslen = aMessage.GetDesLengthL(0);
       
  1649 
       
  1650 	RBuf processName;
       
  1651 
       
  1652 	processName.CreateL(deslen);
       
  1653 	
       
  1654 	processName.CleanupClosePushL();
       
  1655 
       
  1656 	// Read the target process name into processName
       
  1657 	aMessage.ReadL(0,processName);
       
  1658 
       
  1659 	// Check if debug agent is attached to process
       
  1660 	if(!Server().CheckAttachedProcess(processName, aMessage, EFalse))
       
  1661 		{
       
  1662 		LOG_MSG("CSecuritySvrSession::GetEventL() - Not attached to this process\n");
       
  1663 
       
  1664 		// Debug Agent is not attached at all to the requested process
       
  1665 		User::Leave(KErrPermissionDenied);
       
  1666 		}
       
  1667 
       
  1668 	// Identify which process is being debugged, so that
       
  1669 	// we can locate the appropriate active object handler.
       
  1670 	RBuf8 processName8;
       
  1671 
       
  1672 	processName8.CreateL(processName.Length());
       
  1673 
       
  1674 	processName8.CleanupClosePushL();
       
  1675 
       
  1676 	processName8.Copy(processName);
       
  1677 
       
  1678 	// Find the Asynchronous Object associated with this process,
       
  1679 	// as it is permissible to have an outstanding GetEvent call
       
  1680 	// for each attached process.
       
  1681 	TBool foundHandler = EFalse;
       
  1682 	for(TInt i=0; i<iAsyncHandlers.Count(); i++)
       
  1683 		{
       
  1684 		if (processName8.Compare(iAsyncHandlers[i]->ProcessName()) == 0)
       
  1685 			{
       
  1686 			iAsyncHandlers[i]->GetEvent(aMessage);
       
  1687 			foundHandler = ETrue;
       
  1688 			break;
       
  1689 			}
       
  1690 		}
       
  1691 
       
  1692 	if (foundHandler == EFalse)
       
  1693 		{
       
  1694 		// could not find an async handler object. Report the problem.
       
  1695 		LOG_MSG("CSecuritySvrSessionL - Could not find a handler object\n");
       
  1696 		User::Leave(KErrNotFound);
       
  1697 		}
       
  1698 
       
  1699 	// Actually make the driver call, passing in the agent Id
       
  1700 	// so that the driver knows which per-agent event queue
       
  1701 	// to interrogate to retrieve the latest event.
       
  1702 	CleanupStack::PopAndDestroy(&processName8);
       
  1703 	CleanupStack::PopAndDestroy(&processName);
       
  1704 	}
       
  1705 
       
  1706 /**
       
  1707 Cancels a pre-issued GetEvent call for a specific debugged process.
       
  1708 
       
  1709 @param aMessage.Int0() - TDes8 containing aProcessName
       
  1710 */
       
  1711 void CSecuritySvrSession::CancelGetEventL(const RMessage2& aMessage)
       
  1712 	{
       
  1713 	LOG_MSG( "CSecuritySvrSession::CancelGetEventL()\n" );
       
  1714 
       
  1715 	// Local descriptor to contain target process name
       
  1716 	TInt deslen = aMessage.GetDesLengthL(0);
       
  1717 
       
  1718 	RBuf processName;
       
  1719 
       
  1720 	processName.CreateL(deslen);
       
  1721 
       
  1722 	processName.CleanupClosePushL();
       
  1723 
       
  1724 	// Read the target process name into processName
       
  1725 	aMessage.ReadL(0,processName,0);
       
  1726 
       
  1727 	// Debug Agent is not an active debugger. Check if the DA is passively attached
       
  1728 	if(!Server().CheckAttachedProcess(processName, aMessage, EFalse))
       
  1729 		{
       
  1730 		// Debug Agent is not attached at all to the requested process
       
  1731 		User::Leave(KErrPermissionDenied);
       
  1732 		}
       
  1733 
       
  1734 	// Identify the appropriate active object associate
       
  1735 	// with this process.
       
  1736 	RBuf8 processName8;
       
  1737 
       
  1738 	processName8.CreateL(processName.Length());
       
  1739 
       
  1740 	processName8.CleanupClosePushL();
       
  1741 
       
  1742 	processName8.Copy(processName);
       
  1743 
       
  1744 	// Find the Asynchronous Object associated with this process
       
  1745 	TBool foundHandler = EFalse;
       
  1746 	for(TInt i=0; i<iAsyncHandlers.Count(); i++)
       
  1747 		{
       
  1748 		if (processName8.Compare(iAsyncHandlers[i]->ProcessName()) == 0)
       
  1749 			{
       
  1750 
       
  1751 			// Found the AO handler, so cancel the outstanding getevent call.
       
  1752 			iAsyncHandlers[i]->Cancel();
       
  1753 			foundHandler = ETrue;
       
  1754 			break;
       
  1755 			}
       
  1756 		}
       
  1757 
       
  1758 	if(!foundHandler)
       
  1759 		{
       
  1760 		// We could not found a handler, so report the problem to the debug agent
       
  1761 		User::Leave(KErrNotFound);
       
  1762 		}
       
  1763 
       
  1764 	//do cleanup
       
  1765 	CleanupStack::PopAndDestroy(&processName8);
       
  1766 	CleanupStack::PopAndDestroy(&processName);
       
  1767 
       
  1768 	aMessage.Complete(KErrNone);
       
  1769 	}
       
  1770 
       
  1771 /*
       
  1772  Purpose: Sets the required event action to be taken for a specific
       
  1773  process and event combination
       
  1774 
       
  1775 @param aMessage The RMessage2 object is expected to contain:
       
  1776   * aMessage.Int0() - TDes8 Containing the process name.
       
  1777   * aMessage.Int1() - TEventType
       
  1778   * aMessage.Int2() - TKernelEventAction
       
  1779   *
       
  1780 */
       
  1781 void CSecuritySvrSession::SetEventActionL(const RMessage2& aMessage)
       
  1782 	{
       
  1783 	LOG_MSG( "CSecuritySvrSession::SetEventActionL()\n" );
       
  1784 
       
  1785 	// Local descriptor to contain target process name
       
  1786 	TInt deslen = aMessage.GetDesLengthL(0);
       
  1787 
       
  1788 	RBuf processName;
       
  1789 
       
  1790 	processName.CreateL(deslen);
       
  1791 
       
  1792 	processName.CleanupClosePushL();
       
  1793 
       
  1794 	// Read the target process name into processName
       
  1795 	aMessage.ReadL(0,processName);
       
  1796 
       
  1797 	//check that the agent has attached to the target process
       
  1798 	if(!Server().CheckAttachedProcess(processName, aMessage, EFalse))
       
  1799 		{
       
  1800 		// Debug Agent is not attached at all to the requested process
       
  1801 		User::Leave(KErrPermissionDenied);
       
  1802 		}
       
  1803 
       
  1804 	// Extract and validate the arguments from aMessage
       
  1805 	TUint32 event  = aMessage.Int1();
       
  1806 	if (event >= EEventsLast)
       
  1807 		{
       
  1808 		// Supplied event Id was not recognised
       
  1809 		User::Leave(KErrArgument);
       
  1810 		}
       
  1811 
       
  1812 	TUint32 action = aMessage.Int2();
       
  1813 	if(action >= EActionLast)
       
  1814 	{
       
  1815 		// Supplied event action was not recognised
       
  1816 		User::Leave(KErrArgument);
       
  1817 	}
       
  1818 
       
  1819 	RBuf8 processName8;
       
  1820 
       
  1821 	processName8.CreateL(processName.Length());
       
  1822 
       
  1823 	processName8.CleanupClosePushL();
       
  1824 
       
  1825 	processName8.Copy(processName);
       
  1826 
       
  1827 	// Make the call to the device driver
       
  1828 	TInt err = Server().iKernelDriver.SetEventAction(processName8, \
       
  1829 		(TEventType)event,\
       
  1830 		(TKernelEventAction)action,\
       
  1831 		iDebugAgentProcessId.Id());
       
  1832 
       
  1833 	User::LeaveIfError(err);
       
  1834 
       
  1835 	CleanupStack::PopAndDestroy(&processName8);
       
  1836 	CleanupStack::PopAndDestroy(&processName);
       
  1837 
       
  1838 	aMessage.Complete(KErrNone);
       
  1839 }
       
  1840 
       
  1841 /**
       
  1842 Purpose: Single-step a thread for a specified number of instructions
       
  1843 
       
  1844 @param aMessage.Ptr0() - Thread Id of the thread to be stepped
       
  1845 @param aMessage.Int1() - Number of instructions to step.
       
  1846 
       
  1847 @leave one of the system wide error codes
       
  1848 
       
  1849 */
       
  1850 void CSecuritySvrSession::StepL(const RMessage2& aMessage)
       
  1851 	{
       
  1852 	LOG_MSG( "CSecuritySvrSession::StepL()\n" );
       
  1853 
       
  1854 	const TThreadId threadId = ReadTThreadIdL(aMessage, 0);
       
  1855 	const TInt32 numSteps = aMessage.Int1();
       
  1856 
       
  1857 	CheckAttachedL(threadId, aMessage, EFalse);
       
  1858 
       
  1859 	User::LeaveIfError(Server().iKernelDriver.Step( threadId, numSteps ));
       
  1860 
       
  1861 	aMessage.Complete(KErrNone);
       
  1862 	}
       
  1863 
       
  1864 /**
       
  1865  * This checks whether or not the agent is permitted access to the flash partition
       
  1866  * @return KErrNone if allowed, otherwise one of the system wide error codes
       
  1867  * @leave one of the system wide error codes
       
  1868  */
       
  1869 TInt CSecuritySvrSession::CheckFlashAccessPermissionL(const RThread& aClientThread)
       
  1870 	{
       
  1871 	// Read the OEM Debug token capabilities (if any)
       
  1872 	GetDebugAgentOEMTokenCapsL();
       
  1873 	
       
  1874 	if(Server().OEMTokenPermitsFlashAccessL((iOEMDebugCapabilities)))
       
  1875 		{
       
  1876 		return KErrNone;
       
  1877 		}
       
  1878 
       
  1879 	return KErrPermissionDenied;
       
  1880 	}
       
  1881 
       
  1882 /**
       
  1883 Purpose: Read the crash log from the crash flash partition
       
  1884 @param aMessage.Int0() - Position to read from.
       
  1885 @param aMessage.Ptr1() - Buffer to hold the data retrieved
       
  1886 @param aMessage.Int2() - Size of the data to read.
       
  1887 
       
  1888 @leave one of the system wide error codes
       
  1889 */
       
  1890 void CSecuritySvrSession::ReadCrashLogL (const RMessage2& aMessage)
       
  1891 	{	
       
  1892 	//get the debug agent's thread and push handle onto clean up stack
       
  1893 	RThread clientThread;
       
  1894 	User::LeaveIfError(aMessage.Client(clientThread));
       
  1895 	CleanupClosePushL(clientThread);
       
  1896 	
       
  1897 	TInt err = CheckFlashAccessPermissionL(clientThread);
       
  1898 	
       
  1899 	CleanupStack::PopAndDestroy(&clientThread);
       
  1900 	
       
  1901 	if(KErrNone != err)
       
  1902 		{
       
  1903 		LOG_MSG2( "CSecuritySvrSession::ReadCrashLogL()  Access Not Granted - [%d]\n", err );
       
  1904 		aMessage.Complete(err);
       
  1905 		return;
       
  1906 		}
       
  1907 	
       
  1908 	//Check whether drive connected.
       
  1909 	if(!iCrashConnected)
       
  1910 		ConnectCrashPartitionL();	
       
  1911 
       
  1912 	TInt readPosition = aMessage.Int0(); //read position
       
  1913 	
       
  1914 	TInt readSize = aMessage.Int2(); //read size
       
  1915 	
       
  1916 	RBuf8 readBuf;
       
  1917 	readBuf.CreateL(readSize);
       
  1918 	readBuf.CleanupClosePushL();
       
  1919 	
       
  1920 	err = iLocalDrive.Read (readPosition, readSize, readBuf);
       
  1921 	
       
  1922 	//write the list data back
       
  1923 	aMessage.WriteL (1, readBuf);	
       
  1924 	
       
  1925 	CleanupStack::PopAndDestroy (&readBuf);	
       
  1926 	
       
  1927 	//Complete message
       
  1928 	aMessage.Complete(err);	
       
  1929 	}
       
  1930 /**
       
  1931 Purpose: Function to write the crash config to the crash flash partition
       
  1932 
       
  1933 @param aMessage.Int0() - write position in bytes from start position in flash partition.
       
  1934 @param aMessage.Ptr1() - Buffer containing the data to be written onto the flash. 
       
  1935                          The size could be 0 if only flash partition size is needed. 
       
  1936 @param aMessage.Int2() - returns the size of the flash partition.
       
  1937 
       
  1938 @leave one of the system wide error codes
       
  1939 */
       
  1940 void CSecuritySvrSession::WriteCrashConfigL(const RMessage2& aMessage)
       
  1941 	{
       
  1942 	LOG_MSG( "CSecuritySvrSession::WriteCrashConfigL()\n" );
       
  1943 	
       
  1944 	//get the debug agent's thread and push handle onto clean up stack
       
  1945 	RThread clientThread;
       
  1946 	User::LeaveIfError(aMessage.Client(clientThread));
       
  1947 	CleanupClosePushL(clientThread);
       
  1948 	
       
  1949 	TInt err = CheckFlashAccessPermissionL(clientThread);
       
  1950 	
       
  1951 	CleanupStack::PopAndDestroy(&clientThread);
       
  1952 	
       
  1953 	if(KErrNone != err)
       
  1954 		{
       
  1955 		LOG_MSG2( "CSecuritySvrSession::WriteCrashConfigL()  Access Not Granted - [%d]\n", err );
       
  1956 		aMessage.Complete(err);
       
  1957 		return;
       
  1958 		}
       
  1959 	
       
  1960 	//Check whether drive connected.
       
  1961 	if(!iCrashConnected)
       
  1962 		ConnectCrashPartitionL();	
       
  1963 	
       
  1964 	// Get the length of the buffer
       
  1965 	TInt deslen = aMessage.GetDesLengthL(1);
       
  1966 
       
  1967 	RBuf8 dataBuf;
       
  1968 	dataBuf.CreateL(deslen);
       
  1969 	dataBuf.CleanupClosePushL();
       
  1970 
       
  1971 	// data to be written to flash
       
  1972 	aMessage.ReadL(1,dataBuf);
       
  1973 	
       
  1974 	TUint32 position = aMessage.Int0(); //position to start from
       
  1975 		
       
  1976 	err = iLocalDrive.Write(position,(const TDesC8&)dataBuf);
       
  1977 	
       
  1978 	TPtr8 dataSize((TUint8*)&deslen,4, 4);
       
  1979 	
       
  1980 	//write the size of the data written back
       
  1981 	aMessage.WriteL(2,dataSize);
       
  1982 		
       
  1983 	//destroy buffer
       
  1984 	CleanupStack::PopAndDestroy(&dataBuf); 
       
  1985 	
       
  1986 	aMessage.Complete(err);	
       
  1987 	}
       
  1988 /**
       
  1989 Purpose: Method to erase the crash flash block
       
  1990 
       
  1991 @param aMessage.Int0() - write position in bytes from start position in flash partition.
       
  1992 @param aMessage.Int2() - Number of blocks to erase.
       
  1993 
       
  1994 @leave one of the system wide error codes
       
  1995 */
       
  1996 
       
  1997 void CSecuritySvrSession::EraseCrashLogL(const RMessage2& aMessage)
       
  1998 	{	
       
  1999 	LOG_MSG( "CSecuritySvrSession::EraseCrashLogL()\n" );
       
  2000 	
       
  2001 	//get the debug agent's thread and push handle onto clean up stack
       
  2002 	RThread clientThread;
       
  2003 	User::LeaveIfError(aMessage.Client(clientThread));
       
  2004 	CleanupClosePushL(clientThread);
       
  2005 	
       
  2006 	TInt err = CheckFlashAccessPermissionL(clientThread);
       
  2007 	
       
  2008 	CleanupStack::PopAndDestroy(&clientThread);
       
  2009 	
       
  2010 	if(KErrNone != err)
       
  2011 		{
       
  2012 		LOG_MSG2( "CSecuritySvrSession::EraseCrashLogL()  Access Not Granted - [%d]\n", err );
       
  2013 		aMessage.Complete(err);
       
  2014 		return;
       
  2015 		}
       
  2016 			
       
  2017 	//Check whether drive connected.
       
  2018 	if(!iCrashConnected)
       
  2019 		ConnectCrashPartitionL();	
       
  2020 	
       
  2021 	TInt64 position = aMessage.Int0();	
       
  2022 	TInt size = aMessage.Int1();
       
  2023 	
       
  2024 	//Format drive
       
  2025 	err = iLocalDrive.Format(position,size*iCaps.iEraseBlockSize);		
       
  2026  
       
  2027 	aMessage.Complete(err);	
       
  2028 	}
       
  2029 
       
  2030 /**
       
  2031 Purpose: Method to erase the entire crash flash block
       
  2032 @leave one of the system wide error codes
       
  2033 */
       
  2034 
       
  2035 void CSecuritySvrSession::EraseEntireCrashLogL(const RMessage2& aMessage)
       
  2036 	{
       
  2037 	LOG_MSG( "CSecuritySvrSession::EraseEntireCrashLogL()\n" );
       
  2038 	
       
  2039 	//get the debug agent's thread and push handle onto clean up stack
       
  2040 	RThread clientThread;
       
  2041 	User::LeaveIfError(aMessage.Client(clientThread));
       
  2042 	CleanupClosePushL(clientThread);
       
  2043 	
       
  2044 	TInt err = CheckFlashAccessPermissionL(clientThread);
       
  2045 	
       
  2046 	CleanupStack::PopAndDestroy(&clientThread);
       
  2047 	
       
  2048 	if(KErrNone != err)
       
  2049 		{
       
  2050 		LOG_MSG2( "CSecuritySvrSession::EraseEntireCrashLogL()  Access Not Granted - [%d]\n", err );
       
  2051 		aMessage.Complete(err);
       
  2052 		return;
       
  2053 		}	
       
  2054 	
       
  2055 	//Check whether drive connected.
       
  2056 	if(!iCrashConnected)
       
  2057 		ConnectCrashPartitionL();
       
  2058 	
       
  2059 	TUint numberBlocks = iCaps.iSize /iCaps.iEraseBlockSize;
       
  2060 	
       
  2061 	//Format drive
       
  2062 	for(TInt i = 0; i < numberBlocks; i++)
       
  2063 		{
       
  2064 		err = iLocalDrive.Format(i*iCaps.iEraseBlockSize,iCaps.iEraseBlockSize);
       
  2065 		if(KErrNone != err)
       
  2066 			{
       
  2067 			RDebug::Printf("err = %d", err);
       
  2068 			aMessage.Complete(err);
       
  2069 			return;
       
  2070 			}
       
  2071 		}
       
  2072 	
       
  2073 	
       
  2074 	aMessage.Complete(err);
       
  2075 	}
       
  2076 
       
  2077 
       
  2078 /**
       
  2079 Purpose: Kill a specified process
       
  2080 
       
  2081 @param aMessage.Ptr0() - Process Id of the thread to be stepped
       
  2082 @param aMessage.Int1() - Reason code to supply when killing the process.
       
  2083 
       
  2084 @leave one of the system wide error codes
       
  2085 
       
  2086 */
       
  2087 void CSecuritySvrSession::KillProcessL(const RMessage2& aMessage)
       
  2088 	{
       
  2089 	LOG_MSG( "CSecuritySvrSession::KillProcessL()\n" );
       
  2090 
       
  2091 	const TProcessId processId = ReadTProcessIdL(aMessage, 0);
       
  2092 	const TInt32 reason = aMessage.Int1();
       
  2093 
       
  2094 	CheckAttachedL(processId, aMessage, EFalse);
       
  2095 
       
  2096 	User::LeaveIfError(Server().iKernelDriver.KillProcess( processId, reason ));
       
  2097 
       
  2098 	aMessage.Complete(KErrNone);
       
  2099 	}
       
  2100 
       
  2101 /** Gets the secure id of aFileName
       
  2102   @param aFileName file name of executable to get SID for
       
  2103   @param aSecureId on return will contain the SID of aFileName
       
  2104 
       
  2105   @leave one of the system wide error codes
       
  2106   */
       
  2107 void CSecuritySvrSession::GetSecureIdL(const TDesC& aFileName, TUid& aSecureId)
       
  2108 	{
       
  2109 	RFs fs;
       
  2110 	User::LeaveIfError(fs.Connect());
       
  2111 	CleanupClosePushL(fs);
       
  2112 
       
  2113 	RFile targetExe;
       
  2114 	OpenFileHandleL(aFileName, fs, targetExe);
       
  2115 	CleanupClosePushL(targetExe);
       
  2116 
       
  2117 	// Read in the entire header
       
  2118 	RBuf8 e32HdrBuf;
       
  2119 	e32HdrBuf.CreateL(RLibrary::KRequiredImageHeaderSize);
       
  2120 	e32HdrBuf.CleanupClosePushL();
       
  2121 
       
  2122 	// Read the entire header as far as possible
       
  2123 	TInt err = targetExe.Read(e32HdrBuf);
       
  2124 	if (err != KErrNone)
       
  2125 		{
       
  2126 		// Could not read the file 
       
  2127 		LOG_MSG("CSecuritySvrSession::GetSecureIdL - Failed to read executable\n");
       
  2128 
       
  2129 		User::Leave(err);
       
  2130 		}
       
  2131 
       
  2132 	if(!CheckSufficientData(e32HdrBuf, IsExecutableXipL(targetExe)))
       
  2133 		{
       
  2134 		User::Leave(KErrGeneral);
       
  2135 		}
       
  2136 
       
  2137 	aSecureId = GetSecureIdL(e32HdrBuf, IsExecutableXipL(targetExe));
       
  2138 
       
  2139 	CleanupStack::PopAndDestroy(3, &fs);
       
  2140 	}
       
  2141 
       
  2142 /** Get the secure id from aHeaderData
       
  2143   @param aHeaderData an executable's header data to read SID from
       
  2144   @param aXip indication of whether the header data is from an XIP file
       
  2145 
       
  2146   @return secure ID from aHeaderData
       
  2147   */
       
  2148 TUid CSecuritySvrSession::GetSecureIdL(const TDesC8& aHeaderData, TBool aXip)
       
  2149 	{
       
  2150 	if(!CheckSufficientData(aHeaderData, aXip))
       
  2151 		{
       
  2152 		User::Leave(KErrGeneral);
       
  2153 		}
       
  2154 
       
  2155 	if (aXip)
       
  2156 		{
       
  2157 		TRomImageHeader* hdr = (TRomImageHeader*)aHeaderData.Ptr();
       
  2158 		return TUid::Uid(hdr->iS.iSecureId);
       
  2159 		}
       
  2160 	else
       
  2161 		{
       
  2162 		// it is an epoc32 image
       
  2163 		E32ImageHeaderV* hdr = (E32ImageHeaderV*)aHeaderData.Ptr();
       
  2164 		return TUid::Uid(hdr->iS.iSecureId);
       
  2165 		}
       
  2166 	}
       
  2167 
       
  2168 /**
       
  2169 @param aMessage contains:
       
  2170  * aMessage.Ptr0() a TListDetails object
       
  2171  * aMessage.Ptr1() a client supplied TDes8 for the driver to return data in
       
  2172  * aMessage.Ptr2() a TUint32 for the driver to return the size of the requested listing's data in
       
  2173 
       
  2174 @leave KErrTooBig if the buffer passed as argument 1 of aMessage is too
       
  2175        small to contain the requested data,
       
  2176        KErrNoMemory if a temporary buffer could not be allocated,
       
  2177        or one of the other system wide error codes
       
  2178 */
       
  2179 void CSecuritySvrSession::GetListL(const RMessage2& aMessage)
       
  2180 	{
       
  2181 	LOG_MSG("CSecuritySvrSession::GetListL()");
       
  2182 
       
  2183 	// buffer to write list data into before copying back to agent
       
  2184 	RBuf8 listDetailsBuf;
       
  2185 
       
  2186 	//allocate buffer
       
  2187 	listDetailsBuf.CreateL(sizeof(TListDetails));
       
  2188 
       
  2189 	// Do the right cleanup if anything subsequently goes wrong
       
  2190 	listDetailsBuf.CleanupClosePushL();
       
  2191 
       
  2192 	//read the data from the client thread
       
  2193 	aMessage.ReadL(0, listDetailsBuf);
       
  2194 	TListDetails* listDetails = (TListDetails*)listDetailsBuf.Ptr();
       
  2195 
       
  2196 	//get the type of list requested
       
  2197 	TListId type = (TListId)aMessage.Int0();
       
  2198 
       
  2199 	//create a buffer to store the data in
       
  2200 	RBuf8 buffer;
       
  2201 	buffer.CreateL(aMessage.GetDesMaxLength(1));
       
  2202 	buffer.CleanupClosePushL();
       
  2203 
       
  2204 	//create a temporary variable to potentially store data length in
       
  2205 	TUint32 size = 0;
       
  2206 
       
  2207 	TInt err = KErrNone;
       
  2208 
       
  2209 	// the executables list is generated in the DSS rather than in the driver
       
  2210 	// so is treated separately
       
  2211 	if(listDetails->iListId == EExecutables)
       
  2212 		{
       
  2213 		if(listDetails->iListScope != EScopeGlobal)
       
  2214 			{
       
  2215 			User::Leave(KErrArgument);
       
  2216 			}
       
  2217 		if(listDetails->iTargetId != 0)
       
  2218 			{
       
  2219 			User::Leave(KErrArgument);
       
  2220 			}
       
  2221 		err = GetExecutablesListL(buffer, size);
       
  2222 		}
       
  2223 	else
       
  2224 		{
       
  2225 		err = Server().iKernelDriver.GetList(listDetails->iListId, listDetails->iListScope, listDetails->iTargetId, iDebugAgentProcessId, buffer, size);
       
  2226 		}
       
  2227 
       
  2228 	if(err == KErrNone)
       
  2229 		{
       
  2230 		//write the list data back
       
  2231 		aMessage.WriteL(1, buffer);
       
  2232 		}
       
  2233 
       
  2234 	TPtr8 sizePtr((TUint8*)&size, sizeof(TUint32), sizeof(TUint32));
       
  2235 	//write size back to agent
       
  2236 	aMessage.WriteL(2, sizePtr);
       
  2237 
       
  2238 	CleanupStack::PopAndDestroy(&buffer);
       
  2239 	CleanupStack::PopAndDestroy(&listDetailsBuf);
       
  2240 
       
  2241 	aMessage.Complete(err);
       
  2242 	}
       
  2243 
       
  2244 /**
       
  2245 Gets the executables list and returns it in aBuffer if it's big enough
       
  2246 
       
  2247 @param aBuffer caller supplied buffer to write data into
       
  2248 @param aSize on return contains the size of the data in the buffer, or the
       
  2249        size that the buffer would need to be to contain the data
       
  2250 
       
  2251 @return KErrNone on success, or KErrTooBig if the requested data will not fit in aBuffer
       
  2252 
       
  2253 @leave one of the system wide error codes
       
  2254 */
       
  2255 TInt CSecuritySvrSession::GetExecutablesListL(TDes8& aBuffer, TUint32& aSize) const
       
  2256 	{
       
  2257 	LOG_MSG("CSecuritySvrSession::GetExecutablesList()");
       
  2258 
       
  2259 	//initialise values and connect to file system
       
  2260 	aSize = 0;
       
  2261 	aBuffer.SetLength(0);
       
  2262 	RFs fs;
       
  2263 	User::LeaveIfError(fs.Connect());
       
  2264 	CleanupClosePushL(fs);
       
  2265 
       
  2266 	// uids corresponding to executable image
       
  2267 	TUidType uids(KExecutableImageUid, KNullUid, KNullUid);
       
  2268 
       
  2269 	//create a string containing the directory name. The drive letter is represented
       
  2270 	//by X but will be replaced by the appropriate drive letter for each drive
       
  2271 	_LIT(KColonSysBin,":\\sys\\bin\\");
       
  2272 
       
  2273 	//create a modifiable copy of KColonSysBin, preceeded by an empty space for the drive letter
       
  2274 	RBuf dirName;
       
  2275 	dirName.CreateL(1 + KColonSysBin().Length());
       
  2276 	dirName.CleanupClosePushL();
       
  2277 
       
  2278 	//set the length to 1 (to later fill with the drive letter) and then append KColonSysBin
       
  2279 	dirName.SetLength(1);
       
  2280 	dirName.Append(KColonSysBin());
       
  2281 
       
  2282 	//get the list of valid drives for the device
       
  2283 	TDriveList driveList;
       
  2284 	User::LeaveIfError(fs.DriveList(driveList));
       
  2285 
       
  2286 	//check each valid sys/bin directory for executables
       
  2287 	for(TInt i=0; i<KMaxDrives; i++)
       
  2288 		{
       
  2289 		//if the drive is not valid then skip this drive
       
  2290 		if(!driveList[i])
       
  2291 			{
       
  2292 			//skip processing this drive
       
  2293 			continue;
       
  2294 			}
       
  2295 
       
  2296 		//get the drive letter and insert it as the drive letter for dirName
       
  2297 		TChar driveLetter;
       
  2298 		User::LeaveIfError(fs.DriveToChar(i, driveLetter));
       
  2299 		dirName[0] = (TUint)driveLetter;
       
  2300 
       
  2301 		//get a list of the exes in this drive's sys/bin directory
       
  2302 		CDir* localDir = NULL;
       
  2303 		TInt err = fs.GetDir(dirName, uids, ESortByName, localDir);
       
  2304 		if(KErrNoMemory == err)
       
  2305 			{
       
  2306 			User::Leave(err);
       
  2307 			}
       
  2308 		if(!localDir)
       
  2309 			{
       
  2310 			//skip processing this drive
       
  2311 			continue;
       
  2312 			}
       
  2313 
       
  2314 		//push onto cleanup stack in case we leave
       
  2315 		CleanupStack::PushL(localDir);
       
  2316 
       
  2317 		//iterate through the files
       
  2318 		for(TInt j=0; j<localDir->Count(); j++)
       
  2319 			{
       
  2320 			//will store x:\sys\bin\<file-name> type string
       
  2321 			RBuf fullPathName;
       
  2322 
       
  2323 			TUint16 nameLength = dirName.Length() + (*localDir)[j].iName.Length();
       
  2324 			fullPathName.CreateL(nameLength);
       
  2325 			fullPathName.CleanupClosePushL();
       
  2326 			fullPathName.Copy(dirName);
       
  2327 			fullPathName.Append((*localDir)[j].iName);
       
  2328 
       
  2329 			//add the data to the buffer
       
  2330 			AppendExecutableData(aBuffer, aSize, fullPathName);
       
  2331 
       
  2332 			//do cleanup
       
  2333 			CleanupStack::PopAndDestroy(&fullPathName);
       
  2334 			}
       
  2335 
       
  2336 		//do cleanup
       
  2337 		CleanupStack::PopAndDestroy(localDir);
       
  2338 		}
       
  2339 
       
  2340 	//do cleanup
       
  2341 	CleanupStack::PopAndDestroy(2, &fs);
       
  2342 
       
  2343 	//return appropriate value as to whether the kernel's data was too big
       
  2344 	return (aSize <= aBuffer.MaxLength()) ? KErrNone : KErrTooBig;
       
  2345 	}
       
  2346 
       
  2347 
       
  2348 /**
       
  2349   Append data to aBuffer and update size of aSize if the data will fit. If it will
       
  2350   not fit then just puts the nee size in aSize.
       
  2351 
       
  2352   @param aBuffer buffer to append the data to
       
  2353   @param aSize on return contains the new size of the buffer if the data could be
       
  2354   appended, otherwise aSize is updated to reflect the size the buffer would have if
       
  2355   the data had fitted.
       
  2356   @param aEntryName file name of the entry to add to the buffer
       
  2357   */
       
  2358 void CSecuritySvrSession::AppendExecutableData(TDes8& aBuffer, TUint32& aSize, const TDesC& aEntryName) const
       
  2359 	{
       
  2360 	//update aSize to include the size of the data for this entry
       
  2361 	aSize = Align4(aSize + sizeof(TExecutablesListEntry) + (2*aEntryName.Length()) - sizeof(TUint16));
       
  2362 
       
  2363 	//if the data will fit, and we haven't already stopped putting data in, then append the data,
       
  2364 	//if we've stopped putting data in then aSize will be bigger than aBuffer.MaxLength()
       
  2365 	if(aSize <= aBuffer.MaxLength())
       
  2366 		{
       
  2367 		TExecutablesListEntry& entry = *(TExecutablesListEntry*)(aBuffer.Ptr() + aBuffer.Length());
       
  2368 		//check whether an agent has registered to actively debug fullPathName
       
  2369 		TBool activelyDebugged = IsDebugged(aEntryName, EFalse);
       
  2370 		entry.iIsActivelyDebugged = activelyDebugged ? 1 : 0;
       
  2371 
       
  2372 		//check whether any agents have registered to passively debug fullPathName
       
  2373 		TBool passivelyDebugged = IsDebugged(aEntryName, ETrue);
       
  2374 		entry.iIsPassivelyDebugged = passivelyDebugged ? 1 : 0;
       
  2375 
       
  2376 		entry.iNameLength = aEntryName.Length();
       
  2377 		TPtr name(&(entry.iName[0]), aEntryName.Length(), aEntryName.Length());
       
  2378 		name = aEntryName;
       
  2379 		//pad the buffer to a four byte boundary
       
  2380 		aBuffer.SetLength(aSize);
       
  2381 		}
       
  2382 	}
       
  2383 /**
       
  2384 Helper function
       
  2385 
       
  2386 Write data back to the thread that owns aMessage
       
  2387 
       
  2388 @param aMessage the message which is passed between processes
       
  2389 @param aIndex the message slot which the data will be passed back in
       
  2390 @param aPtr pointer to data in this thread to be written into aMessage
       
  2391 @param aPtrSize size in bytes of the data to be written
       
  2392 
       
  2393 @leave one of the system wide error codes
       
  2394 */
       
  2395 void CSecuritySvrSession::WriteDataL(const RMessage2& aMessage, const TInt aIndex, const TAny* aPtr, const TUint32 aPtrSize) const
       
  2396 	{
       
  2397 	TPtr8 dataPtr((TUint8*)aPtr, aPtrSize, aPtrSize);
       
  2398 
       
  2399 	aMessage.WriteL(aIndex, dataPtr);
       
  2400 	}
       
  2401 
       
  2402 /**
       
  2403 Helper function.
       
  2404 
       
  2405 Checks whether the debug agent (the owner of the aMessage) is attached to the
       
  2406 thread with thread id of aThreadId.
       
  2407 
       
  2408 @param aThreadId thread ID of target debug thread
       
  2409 @param aMessage message owned by the debug agent
       
  2410 @param aPassive indicates whether to check if attached passively or actively
       
  2411 
       
  2412 @leave KErrPermissionDenied if the agent is not attached to the process,
       
  2413        KErrNoMemory if the security server could not be accessed
       
  2414 */
       
  2415 void CSecuritySvrSession::CheckAttachedL(const TThreadId aThreadId, const RMessage2& aMessage, const TBool aPassive) const
       
  2416 	{
       
  2417 	//check that the agent has attached to the target process
       
  2418 	if(! Server().CheckAttached(aThreadId, aMessage, aPassive))
       
  2419 		{
       
  2420 		LOG_MSG("CSecuritySvrSession::CheckAttachedL() failed");
       
  2421 		User::Leave(KErrPermissionDenied);
       
  2422 		}
       
  2423 	}
       
  2424 
       
  2425 /**
       
  2426 Helper function.
       
  2427 
       
  2428 Checks whether the debug agent (the owner of the aMessage) is attached to the
       
  2429 process with process id of aProcessId.
       
  2430 
       
  2431 @param aProcessId process ID of target debug thread
       
  2432 @param aMessage message owned by the debug agent
       
  2433 @param aPassive indicates whether to check if attached passively or actively
       
  2434 
       
  2435 @leave KErrPermissionDenied if the agent is not attached to the process,
       
  2436        KErrNoMemory if the security server could not be accessed
       
  2437 */
       
  2438 void CSecuritySvrSession::CheckAttachedL(const TProcessId aProcessId, const RMessage2& aMessage, const TBool aPassive) const
       
  2439 	{
       
  2440 	
       
  2441 	//check that the agent has attached to the target process
       
  2442 	if(! Server().CheckAttached(aProcessId, aMessage, aPassive))
       
  2443 		{
       
  2444 		LOG_MSG("CSecuritySvrSession::CheckAttachedL() (process) failed");
       
  2445 		User::Leave(KErrPermissionDenied);
       
  2446 		}
       
  2447 	}
       
  2448 
       
  2449 /**
       
  2450 Check whether the debug agent is permitted to attach to the target process.
       
  2451 Note that this function does not actually attach the agent to the process, it
       
  2452 simply tests whether an attach call would potentially be successful.
       
  2453 
       
  2454 Currently this method returns ETrue in all cases but will be updated once
       
  2455 the security checking framework is in place.
       
  2456 
       
  2457 @param aDebugAgentProcessId process id of the debug agent
       
  2458 @param aTargetProcessName original file name of the target process
       
  2459 
       
  2460 @return ETrue if the debug agent would be allowed to attch to the target process,
       
  2461         EFalse otherwise
       
  2462 */
       
  2463 TBool CSecuritySvrSession::PermitDebugL(const TProcessId aDebugAgentProcessId, const TDesC& aTargetProcessName) const
       
  2464 	{
       
  2465 	return ETrue;
       
  2466 	}
       
  2467 
       
  2468 /**
       
  2469 Helper function
       
  2470 
       
  2471 Validates that the memory info passed in meets the debug driver's requirements
       
  2472 
       
  2473 @param aMemoryInfo memory info passed in from client
       
  2474 
       
  2475 @leave KErrArgument if:
       
  2476 	  * size is zero
       
  2477 	  * size is greater than the max block size
       
  2478 	  * size + address > 0xffffffff
       
  2479 	  * address is not access size aligned
       
  2480 	  * size is not a multiple of the access size
       
  2481 	KErrNotSupported if:
       
  2482 	  * iAccess is not TAccess::EAccess32
       
  2483 	  * iEndianess is not TEndianess::EEndLE8
       
  2484 	KErrUnknown if:
       
  2485 	  * the max memory block size cannot be determined
       
  2486         or one of the other system wide error codes
       
  2487 */
       
  2488 void CSecuritySvrSession::ValidateMemoryInfoL(const TThreadId aThreadId, const TMemoryInfo &aMemoryInfo, const TBool aReadOperation)
       
  2489 	{
       
  2490 	//check size is not 0
       
  2491 	if(aMemoryInfo.iSize == 0)
       
  2492 		User::Leave(KErrArgument);
       
  2493 
       
  2494 	//get the max block size supported
       
  2495 	TUint32 maxSize = 0;
       
  2496 	User::LeaveIfError(Server().iKernelDriver.GetMemoryOperationMaxBlockSize(maxSize));
       
  2497 
       
  2498 	//check that the block size given is less than the max block size
       
  2499 	if(aMemoryInfo.iSize > maxSize)
       
  2500 		User::Leave(KErrArgument);
       
  2501 
       
  2502 	//must ensure that address + size <= 0xffffffff as will attempt to
       
  2503 	//read past 0xffffffff, which wouldn't be good
       
  2504 	TUint32 maxAddress = (~aMemoryInfo.iSize) + 1;
       
  2505 	if(aMemoryInfo.iAddress > maxAddress)
       
  2506 		User::Leave(KErrArgument);
       
  2507 
       
  2508 	//check that arguments are supported
       
  2509 	if(aMemoryInfo.iAccess != EAccess32)
       
  2510 		User::Leave(KErrNotSupported);
       
  2511 
       
  2512 	if(aMemoryInfo.iEndianess != EEndLE8)
       
  2513 		User::Leave(KErrNotSupported);
       
  2514 
       
  2515 	//check that address is multiple of access size
       
  2516 	TInt addressIndicator = aMemoryInfo.iAddress % aMemoryInfo.iAccess;
       
  2517 	if(addressIndicator != 0)
       
  2518 		{
       
  2519 		User::Leave(KErrArgument);
       
  2520 		}
       
  2521 
       
  2522 	//check that size is multiple of access size
       
  2523 	TInt sizeIndicator = aMemoryInfo.iSize % aMemoryInfo.iAccess;
       
  2524 	if(sizeIndicator != 0)
       
  2525 		User::Leave(KErrArgument);
       
  2526 	}
       
  2527 
       
  2528 /**
       
  2529 Helper function
       
  2530 
       
  2531 Validates that the three buffers relating to reading register data are of
       
  2532 appropriate sizes, and calculates the number of registers being requested.
       
  2533 
       
  2534 @param aMessage message which in offsets 1, 2 and 3 contains descriptors
       
  2535 @param aNumberOfRegisters if the function returns with KErrNone this will
       
  2536        contain the number of registers being requested, guaranteed to be non-zero
       
  2537 
       
  2538 @leave KErrArgument if descriptors do not represent the same number of
       
  2539        registers, if any of the descriptors have max length of 0, if any of
       
  2540        the descriptors have max lengths which are not multiples of their data
       
  2541        type's size or if any of the descriptors have max lengths greater than
       
  2542        the max block size for memory operations
       
  2543        or one of the other system wide error codes if there were problems 
       
  2544        in getting the descriptors' lengths.
       
  2545 */
       
  2546 void CSecuritySvrSession::ValidateRegisterBuffersL(const RMessage2& aMessage, TUint32& aNumberOfRegisters)
       
  2547 	{
       
  2548 	//get lengths of buffers, if error occurs returned value will be less then zero
       
  2549 	TInt idsBufferLength = aMessage.GetDesMaxLength(1);
       
  2550 	if(idsBufferLength < 0)
       
  2551 		{
       
  2552 		User::Leave(idsBufferLength);
       
  2553 		}
       
  2554 	TInt valuesBufferLength = aMessage.GetDesMaxLength(2);
       
  2555 	if(valuesBufferLength < 0)
       
  2556 		{
       
  2557 		User::Leave(valuesBufferLength);
       
  2558 		}
       
  2559 	TInt flagsBufferLength = aMessage.GetDesMaxLength(3);
       
  2560 	if(flagsBufferLength < 0)
       
  2561 		{
       
  2562 		User::Leave(flagsBufferLength);
       
  2563 		}
       
  2564 
       
  2565 	//get the max block size supported
       
  2566 	TUint32 maxSize = 0;
       
  2567 	User::LeaveIfError(Server().iKernelDriver.GetMemoryOperationMaxBlockSize(maxSize));
       
  2568 
       
  2569 	//check none of the descriptors have size greater than the max block size
       
  2570 	if((idsBufferLength > maxSize) || (valuesBufferLength > maxSize) || (flagsBufferLength > maxSize))
       
  2571 		User::Leave(KErrArgument);
       
  2572 
       
  2573 	//get sizes of the three types of data the buffers represent arrays of
       
  2574 	//and validate that the buffer lengths are multiples of the data sizes
       
  2575 	TUint idSize = sizeof(TRegisterInfo);
       
  2576 	if(idsBufferLength % idSize != 0)
       
  2577 		User::Leave(KErrArgument);
       
  2578 
       
  2579 	TUint flagSize = sizeof(TUint8);
       
  2580 	if(flagsBufferLength % flagSize != 0)
       
  2581 		User::Leave(KErrArgument);
       
  2582 
       
  2583 	//perform check on id buffer length
       
  2584 	if(idsBufferLength == 0)
       
  2585 		User::Leave(KErrArgument);
       
  2586 
       
  2587 	//calculate number of registers being requested
       
  2588 	aNumberOfRegisters = idsBufferLength / idSize;
       
  2589 
       
  2590 	//check flags buffer is of appropriate size
       
  2591 	if(flagsBufferLength != (aNumberOfRegisters * flagSize))
       
  2592 		User::Leave(KErrArgument);
       
  2593 	}
       
  2594 
       
  2595 /**
       
  2596 Establish whether any agents have registered to debug the specified aFileName
       
  2597 
       
  2598 @param aFileName originating file name of the target process
       
  2599 @param aPassive indicates whether to check if there has been active attachment,
       
  2600 or passive attachment.
       
  2601 
       
  2602 @return ETrue if aFileName is being debugged, EFalse otherwise
       
  2603 
       
  2604 */
       
  2605 TBool CSecuritySvrSession::IsDebugged(const TDesC& aFileName, const TBool aPassive) const
       
  2606 	{
       
  2607 	//check whether the target process is being debugged
       
  2608 	return Server().IsDebugged(aFileName, aPassive);
       
  2609 	}
       
  2610 
       
  2611 /**
       
  2612   Helper function which reads a TThreadId object from a client
       
  2613 
       
  2614   @param aMessage the message object containing the reference to the TThreadId
       
  2615   @param aIndex the message argument containing the reference
       
  2616 
       
  2617   @return the TThreadId passed in by the client
       
  2618   @leave KErrArgument if aIndex is outside of the valid range
       
  2619   */
       
  2620 TThreadId CSecuritySvrSession::ReadTThreadIdL(const RMessagePtr2& aMessage, const TInt aIndex) const
       
  2621 	{
       
  2622 	//create a temporary TThreadId to read the data into
       
  2623 	TThreadId tempThreadId;
       
  2624 	TPtr8 threadIdPtr((TUint8*)&tempThreadId, sizeof(TThreadId));
       
  2625 
       
  2626 	// read the data in from the client
       
  2627 	aMessage.ReadL(aIndex, threadIdPtr);
       
  2628 
       
  2629 	return tempThreadId;
       
  2630 	}
       
  2631 
       
  2632 /**
       
  2633   Helper function which reads a TProcessId object from a client
       
  2634 
       
  2635   @param aMessage the message object containing the reference to the TProcessId
       
  2636   @param aIndex the message argument containing the reference
       
  2637 
       
  2638   @return the TProcessId passed in by the client
       
  2639   @leave KErrArgument if aIndex is outside of the valid range
       
  2640   */
       
  2641 TProcessId CSecuritySvrSession::ReadTProcessIdL(const RMessagePtr2& aMessage, const TInt aIndex) const
       
  2642 	{
       
  2643 	//create a temporary TProcessId to read the data into
       
  2644 	TProcessId tempProcessId;
       
  2645 	TPtr8 processIdPtr((TUint8*)&tempProcessId, sizeof(TProcessId));
       
  2646 
       
  2647 	// read the data in from the client
       
  2648 	aMessage.ReadL(aIndex, processIdPtr);
       
  2649 
       
  2650 	return tempProcessId;
       
  2651 	}
       
  2652 
       
  2653 // End of file - c_security_svr_session.cpp