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