dbgagents/trkagent/engine/TrkDispatchLayer.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     1 /*
       
     2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "TrkEngine.h"
       
    20 #include "TrkDispatchLayer.h"
       
    21 #include "DateTimeConverter.h"
       
    22 
       
    23 #ifndef __TEXT_SHELL__
       
    24 #include "TrkSwInstall.h"
       
    25 #endif
       
    26 
       
    27 //
       
    28 // Macros
       
    29 //
       
    30 
       
    31 //
       
    32 // Version Information
       
    33 //
       
    34 
       
    35 #define MAJOR_VERSION_NUMBER	3
       
    36 #define MINOR_VERSION_NUMBER	2
       
    37 #define BUILD_NUMBER			4
       
    38 
       
    39 
       
    40 //
       
    41 // Support Information
       
    42 //
       
    43 
       
    44 #define DS_SUPPORT_MASK_00_07	0x7E	// kDSConnect, kDSDisconnect, kDSReset, kDSVersions, kDSSupportMask, kDSCPUType */
       
    45 #define DS_SUPPORT_MASK_08_0F	0x00
       
    46 #define DS_SUPPORT_MASK_10_17	0x4f	// R/W Memory, R/W Registers, FlushCache
       
    47 #define DS_SUPPORT_MASK_18_1F	0x5f	// kDSContinue, kDSStep, kDSStop, kDSSetBreak, kDSClearBreak
       
    48 #define DS_SUPPORT_MASK_20_27	0x01	// kDSNotifyFileInput
       
    49 #define DS_SUPPORT_MASK_28_2F	0x00
       
    50 #define DS_SUPPORT_MASK_30_37	0x00
       
    51 #define DS_SUPPORT_MASK_38_3F	0x00
       
    52 #define DS_SUPPORT_MASK_40_47	0x0f	// OS Create/Delete Item, OS Read/Write Info
       
    53 #define DS_SUPPORT_MASK_48_4F	0x1f	// OS Read/Write/Open/Close/Position File
       
    54 #define DS_SUPPORT_MASK_50_57	0x00
       
    55 #define DS_SUPPORT_MASK_58_5F	0x00
       
    56 #define DS_SUPPORT_MASK_60_67	0x00
       
    57 #define DS_SUPPORT_MASK_68_6F	0x00
       
    58 #define DS_SUPPORT_MASK_70_77	0x00
       
    59 #define DS_SUPPORT_MASK_78_7F	0x00
       
    60 #define DS_SUPPORT_MASK_80_87	0x01	// kDSReplyACK
       
    61 #define DS_SUPPORT_MASK_88_8F	0x00
       
    62 #define DS_SUPPORT_MASK_90_97	0x11	// kDSNotifyStopped, kDSNotifyStopped2
       
    63 #define DS_SUPPORT_MASK_98_9F	0x00
       
    64 #define DS_SUPPORT_MASK_A0_A7	0x03	// kDSOSNotifyCreated, kDSOSNotifyDeleted
       
    65 #define DS_SUPPORT_MASK_A8_AF	0x00
       
    66 #define DS_SUPPORT_MASK_B0_B7	0x00
       
    67 #define DS_SUPPORT_MASK_B8_BF	0x00
       
    68 #define DS_SUPPORT_MASK_C0_C7	0x00
       
    69 #define DS_SUPPORT_MASK_C8_CF	0x00
       
    70 #define DS_SUPPORT_MASK_D0_D7	0x03	// kDSWriteFile, kDSReadFile
       
    71 #define DS_SUPPORT_MASK_D8_DF	0x00
       
    72 #define DS_SUPPORT_MASK_E0_E7	0x00
       
    73 #define DS_SUPPORT_MASK_E8_EF	0x00
       
    74 #define DS_SUPPORT_MASK_F0_F7	0x00
       
    75 #define DS_SUPPORT_MASK_F8_FF	0x80	// kDSReplyNAK
       
    76 
       
    77 #define KProcessKilled 0x4B696C6C // "Kill"
       
    78 
       
    79 #ifdef EKA2
       
    80 #define EUSER_LIBPATH _L("Z:\\Sys\\Bin\\euser.dll")
       
    81 #else
       
    82 #define EUSER_LIBPATH _L("Z:\\System\\Libs\\euser.dll")
       
    83 #endif
       
    84 
       
    85 #ifdef __OEM_TRK__
       
    86 #define TRK_TYPE_DESCRIPTION _L8("System TRK")
       
    87 #else
       
    88 #define TRK_TYPE_DESCRIPTION _L8("Application TRK")
       
    89 #endif
       
    90 
       
    91 
       
    92 //
       
    93 // Swap2
       
    94 //
       
    95 // Byte-swaps a 2-byte value.  Used to convert to/from little/big endian.
       
    96 //
       
    97 static TUint16 Swap2(TUint16 aSource)
       
    98 {
       
    99 	TUint16 dest = 0;
       
   100 	for (TInt i=0; i<2; i++)
       
   101 	{
       
   102 		dest <<= 8;
       
   103 		dest |= aSource & 0xFF;
       
   104 		aSource >>= 8;
       
   105 	}
       
   106 	
       
   107 	return dest;
       
   108 } 
       
   109 
       
   110 //
       
   111 // Swap4
       
   112 //
       
   113 // Byte-swaps a 4-byte value.  Used to convert to/from little/big endian.
       
   114 //
       
   115 static TUint32 Swap4(TUint32 aSource)
       
   116 {
       
   117 	TUint32 dest = 0;
       
   118 	for (TInt i=0; i<4; i++)
       
   119 	{
       
   120 		dest <<= 8;
       
   121 		dest |= aSource & 0xFF;
       
   122 		aSource >>= 8;
       
   123 	}
       
   124 	
       
   125 	return dest;
       
   126 } 
       
   127 
       
   128 //
       
   129 // Swap4xN
       
   130 //
       
   131 //	Byte-swaps N 4-byte values *in place*.  Used to convert to/from little/big endian.
       
   132 //
       
   133 void Swap4xN(TUint32 *aSource, TInt aCount)
       
   134 {
       
   135 	while (aCount--)
       
   136 	{
       
   137 		TUint32 temp = Swap4(*aSource);
       
   138 		*aSource++ = temp;
       
   139 	}
       
   140 } 
       
   141 
       
   142 
       
   143 //
       
   144 //
       
   145 // CExitTrapper implementation
       
   146 //
       
   147 //
       
   148 
       
   149 //
       
   150 // CExitTrapper constructor
       
   151 //
       
   152 // Accepts CTrkDispatchLayer interface and the process ID of the
       
   153 // process to watch
       
   154 //
       
   155 CExitTrapper::CExitTrapper(CTrkDispatchLayer *aDispatch, TUint32 aProcessId)
       
   156 	: CActive(EPriorityStandard),
       
   157 	  iProcessId(aProcessId),
       
   158 	  iDispatch(aDispatch)
       
   159 {
       
   160 	CActiveScheduler::Add(this);
       
   161 
       
   162 	TInt error = iProcess.Open(iProcessId);
       
   163 	if (KErrNone != error)
       
   164 		User::Panic(_L("Unable to open process"), __LINE__);
       
   165 }
       
   166 
       
   167 //
       
   168 // CExitTrapper destructor
       
   169 //
       
   170 CExitTrapper::~CExitTrapper()
       
   171 {
       
   172 	Cancel();
       
   173 	Deque();
       
   174 	iProcess.Close();
       
   175 }
       
   176 
       
   177 //
       
   178 // CExitTrapper::Watch
       
   179 //
       
   180 // Watch for the process to exit
       
   181 //
       
   182 void CExitTrapper::Watch()
       
   183 {
       
   184 	iProcess.Logon(iStatus);
       
   185 	SetActive();
       
   186 }
       
   187 
       
   188 //
       
   189 // CExitTrapper::RunL
       
   190 //
       
   191 // Called when the process exits
       
   192 //
       
   193 void CExitTrapper::RunL()
       
   194 {
       
   195 	// sometimes this is run when the process has yet to exit
       
   196 	if (iProcess.ExitType() == EExitPending)
       
   197 	{
       
   198 		iProcess.LogonCancel(iStatus);
       
   199 		Watch();
       
   200 	}
       
   201 	else
       
   202 	{
       
   203 		iDispatch->DoNotifyProcessDiedL(iProcessId, iProcess.ExitReason());
       
   204 	}
       
   205 }
       
   206 
       
   207 //
       
   208 // CExitTrapper::DoCancel
       
   209 //
       
   210 // Stop waiting for this process to exit
       
   211 //
       
   212 void CExitTrapper::DoCancel()
       
   213 {
       
   214 	iProcess.LogonCancel(iStatus);
       
   215 }
       
   216 
       
   217 
       
   218 //
       
   219 //
       
   220 // CEventTrapper implementation
       
   221 //
       
   222 //
       
   223 
       
   224 //
       
   225 // CEventTrapper constructor
       
   226 //
       
   227 // Accepts CTrkDispatchLayer interface
       
   228 //
       
   229 CEventTrapper::CEventTrapper(CTrkDispatchLayer *aDispatch)
       
   230 	: CActive(CActive::EPriorityStandard),
       
   231 	  iDispatch(aDispatch)
       
   232 {
       
   233 	CActiveScheduler::Add(this);
       
   234 }
       
   235 
       
   236 //
       
   237 // CEventTrapper destructor
       
   238 //
       
   239 CEventTrapper::~CEventTrapper()
       
   240 {
       
   241 	Cancel();
       
   242 	Deque();
       
   243 }
       
   244 
       
   245 //
       
   246 // CEventTrapper::Watch
       
   247 //
       
   248 // Start listening for events
       
   249 //
       
   250 void CEventTrapper::Watch()
       
   251 {
       
   252 	iDispatch->iKernelDriver.GetEvent(iStatus, iEventInfo);
       
   253 	SetActive();
       
   254 }
       
   255 
       
   256 //
       
   257 // CEventTrapper::RunL
       
   258 //
       
   259 // Called when an event occurs
       
   260 //
       
   261 void CEventTrapper::RunL()
       
   262 {
       
   263 	// determine the type of event and handle accordingly
       
   264 	switch (iEventInfo.iEventType)
       
   265 	{
       
   266 		case SEventInfo::EThreadBreakPoint:
       
   267 		{
       
   268 			iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, KNullDesC8);
       
   269 			break;
       
   270 		}
       
   271 		case SEventInfo::EThreadException:
       
   272 		{
       
   273 			TBuf8<100> buf;
       
   274 			
       
   275 			switch(iEventInfo.iExceptionNumber)
       
   276 			{
       
   277 				case EExcIntegerDivideByZero:
       
   278 				{
       
   279 					buf.Format(_L8("An integer divide by zero exception has occurred."));
       
   280 					break;
       
   281 				}
       
   282 				case EExcIntegerOverflow:
       
   283 				{
       
   284 					buf.Format(_L8("An integer overflow exception has occurred."));
       
   285 					break;
       
   286 				}
       
   287 				case EExcBoundsCheck:
       
   288 				{
       
   289 					buf.Format(_L8("An bounds check exception has occurred."));
       
   290 					break;
       
   291 				}
       
   292 				case EExcInvalidOpCode:
       
   293 				{
       
   294 					buf.Format(_L8("An invalid instruction exception has occurred."));
       
   295 					break;
       
   296 				}
       
   297 				case EExcDoubleFault:
       
   298 				{
       
   299 					buf.Format(_L8("A double fault exception has occurred."));
       
   300 					break;
       
   301 				}
       
   302 				case EExcStackFault:
       
   303 				{
       
   304 					buf.Format(_L8("A stack fault exception has occurred."));
       
   305 					break;
       
   306 				}
       
   307 				case EExcAccessViolation:
       
   308 				{
       
   309 					buf.Format(_L8("An access violation exception has occurred."));
       
   310 					break;
       
   311 				}
       
   312 				case EExcPrivInstruction:
       
   313 				{
       
   314 					buf.Format(_L8("A priveledged instruction exception has occurred."));
       
   315 					break;
       
   316 				}
       
   317 				case EExcAlignment:
       
   318 				{
       
   319 					buf.Format(_L8("An alignment exception has occurred."));
       
   320 					break;
       
   321 				}
       
   322 				case EExcPageFault:
       
   323 				{
       
   324 					buf.Format(_L8("A page fault exception has occurred."));
       
   325 					break;
       
   326 				}
       
   327 				case EExcFloatDenormal:
       
   328 				case EExcFloatDivideByZero:
       
   329 				case EExcFloatInexactResult:
       
   330 				case EExcFloatInvalidOperation:
       
   331 				case EExcFloatOverflow:
       
   332 				case EExcFloatStackCheck:
       
   333 				case EExcFloatUnderflow:
       
   334 				{
       
   335 					buf.Format(_L8("A floating point exception has occurred."));
       
   336 					break;
       
   337 				}
       
   338 				case EExcAbort:
       
   339 				{
       
   340 					buf.Format(_L8("An abort exception has occurred."));
       
   341 					break;
       
   342 				}
       
   343 				case EExcUserInterrupt:
       
   344 				{
       
   345 					buf.Format(_L8("A user interrupt exception has occurred."));
       
   346 					break;
       
   347 				}
       
   348 				case EExcDataAbort:
       
   349 				{
       
   350 					buf.Format(_L8("A data abort exception has occurred."));
       
   351 					break;
       
   352 				}
       
   353 				case EExcCodeAbort:
       
   354 				{
       
   355 					buf.Format(_L8("A code abort exception has occurred."));
       
   356 					break;
       
   357 				}				
       
   358 				case EExcGeneral:
       
   359 				case EExcSingleStep:
       
   360 				case EExcBreakPoint:
       
   361 				case EExcKill:
       
   362 				case EExcMaxNumber:
       
   363 				case EExcInvalidVector:
       
   364 				default:
       
   365 				{
       
   366 					buf.Format(_L8("An unknown exception (%d) has occurred."), iEventInfo.iExceptionNumber);
       
   367 					break;				
       
   368 				}
       
   369 			}
       
   370 			
       
   371 			iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf);
       
   372 			break;
       
   373 		}
       
   374 		case SEventInfo::EThreadPanic:
       
   375 		{
       
   376 			TBuf8<100> buf;
       
   377 //			buf.Format(_L8("Thread 0x%x has panicked.\nCategory: %S\nReason: %d"), iEventInfo.iThreadId, &iEventInfo.iPanicCategory, iEventInfo.iExceptionNumber);
       
   378 			buf.Format(_L8("Thread 0x%x has panicked. Category: %S; Reason: %d"), iEventInfo.iThreadId, &iEventInfo.iPanicCategory, iEventInfo.iPanicReason);
       
   379 			
       
   380 			iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf, true, iEventInfo.iExceptionNumber);
       
   381 			break;
       
   382 		}
       
   383 		case SEventInfo::EProcessPanic:
       
   384 		{
       
   385 			TBuf8<100> buf;
       
   386 			buf.Format(_L8("Process 0x%x has panicked.\nCategory: %S\nReason: %d"), iEventInfo.iProcessId, &iEventInfo.iPanicCategory, iEventInfo.iExceptionNumber);
       
   387 			
       
   388 			iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf);
       
   389 			break;
       
   390 		}
       
   391 		case SEventInfo::ELibraryLoaded:
       
   392 		{
       
   393 			// a library has been loaded.  we get statically linked library loaded notifications
       
   394 			// the very first time the process is created.  we want to ignore these because we
       
   395 			// handle static libs in another way.  if the process the library was loaded for is
       
   396 			// not being debugging, just resume the thread and ignore the event.  if the process
       
   397 			// is being debugged but it hasn't yet been created, then this must be a static lib
       
   398 			// and we ignore it.  note that we do not bother resuming the thread since it has not
       
   399 			// been started yet!
       
   400 
       
   401 			TBool created = EFalse;
       
   402 			TBool found = EFalse;
       
   403 					
       
   404 			for (TInt i=0; i<iDispatch->iDebugProcessList.Count(); i++)
       
   405 			{
       
   406 				if (iDispatch->iDebugProcessList[i]->ProcessId() == iEventInfo.iProcessId)
       
   407 				{
       
   408 					created = iDispatch->iDebugProcessList[i]->iReadyForLibraryLoadNotification;
       
   409 					found = ETrue;
       
   410 					break;
       
   411 				}
       
   412 			}
       
   413 
       
   414 		#ifndef EKA2
       
   415 			if (!iEventInfo.iCodeAddress)
       
   416 			{
       
   417 				TBuf<KMaxPath> libName;
       
   418 				libName.Copy(iEventInfo.iFileName);
       
   419 				
       
   420 				RLibrary lib;
       
   421 				TInt err = lib.LoadRomLibrary(libName, KNullDesC);
       
   422 				if (KErrNone == err)
       
   423 				{
       
   424 					iEventInfo.iCodeAddress = (TUint32)lib.EntryPoint();
       
   425 					lib.Close();
       
   426 				}
       
   427 			}
       
   428 		#endif
       
   429 
       
   430 			if (!created || !iEventInfo.iCodeAddress || !found)
       
   431 			{
       
   432 				iDispatch->iKernelDriver.ResumeThread(iEventInfo.iThreadId);
       
   433 			}
       
   434 			else
       
   435 			{
       
   436 				iDispatch->DoNotifyLibraryLoadedL(iEventInfo.iFileName, iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCodeAddress, iEventInfo.iDataAddress);
       
   437 			}
       
   438 			break;
       
   439 		}
       
   440 		case SEventInfo::ELibraryUnloaded:
       
   441 		{
       
   442 			TBool found = EFalse;
       
   443 			
       
   444 			for (TInt i=0; i<iDispatch->iDebugProcessList.Count(); i++)
       
   445 			{
       
   446 				if (iDispatch->iDebugProcessList[i]->ProcessId() == iEventInfo.iProcessId)
       
   447 				{
       
   448 					found = ETrue;
       
   449 					break;
       
   450 				}
       
   451 			}
       
   452 			
       
   453 			if (!found)
       
   454 			{
       
   455 				iDispatch->iKernelDriver.ResumeThread(iEventInfo.iThreadId);
       
   456 			}
       
   457 			else
       
   458 			{
       
   459 				iDispatch->DoNotifyLibraryUnloadedL(iEventInfo.iFileName, iEventInfo.iProcessId, iEventInfo.iThreadId);
       
   460 			}
       
   461 			
       
   462 			break;
       
   463 		}
       
   464 		case SEventInfo::EUserTrace:
       
   465 		{
       
   466 			iDispatch->DoNotifyUserTraceL(iEventInfo.iTraceData);
       
   467 			break;
       
   468 		}
       
   469 		case SEventInfo::EProcessAdded:
       
   470 		{
       
   471 			iDispatch->DoNotifyProcessAddedL(iEventInfo.iFileName, iEventInfo.iProcessId, 
       
   472 											 iEventInfo.iThreadId, iEventInfo.iUid, 
       
   473 											 iEventInfo.iCodeAddress, iEventInfo.iDataAddress);
       
   474 			break;
       
   475 		}
       
   476 		case SEventInfo::EUnknown:
       
   477 		default:
       
   478 			User::Panic(_L("Unknown event type"), __LINE__);
       
   479 			break;
       
   480 	}
       
   481 
       
   482 	// reset the values
       
   483 	iEventInfo.Reset();
       
   484 
       
   485 	// keep listening for more events
       
   486 	Watch();
       
   487 }
       
   488 
       
   489 //
       
   490 // CEventTrapper::DoCancel
       
   491 //
       
   492 // Stop listening for events
       
   493 //
       
   494 void CEventTrapper::DoCancel()
       
   495 {
       
   496 	iDispatch->iKernelDriver.CancelGetEvent();
       
   497 }
       
   498 
       
   499 
       
   500 //
       
   501 //
       
   502 // CDebugProcess implementation
       
   503 //
       
   504 //
       
   505 
       
   506 //
       
   507 // CDebugProcess::NewL
       
   508 //
       
   509 // Accepts CTrkDispatchLayer interface and the process ID and main
       
   510 // thread ID of a process being debugged
       
   511 //
       
   512 CDebugProcess* CDebugProcess::NewL(CTrkDispatchLayer *aDispatch, TUint32 aProcessId, TUint32 aMainThreadId)
       
   513 {
       
   514 	CDebugProcess* self = new(ELeave) CDebugProcess();
       
   515 	self->ConstructL(aDispatch, aProcessId, aMainThreadId);
       
   516 	return self;
       
   517 }
       
   518 
       
   519 //
       
   520 // CDebugProcess::ConstructL
       
   521 //
       
   522 // Accepts CTrkDispatchLayer interface and the process ID and main
       
   523 // thread ID of a process being debugged
       
   524 //
       
   525 void CDebugProcess::ConstructL(CTrkDispatchLayer *aDispatch, TUint32 aProcessId, TUint32 aMainThreadId)
       
   526 {
       
   527 	iProcessId = aProcessId;
       
   528 	iMainThreadId = aMainThreadId;
       
   529 	iReadyForLibraryLoadNotification = EFalse;
       
   530 	
       
   531 	// start waiting for this process to exit
       
   532 	iExitTrapper = new(ELeave) CExitTrapper(aDispatch, aProcessId);
       
   533 	iExitTrapper->Watch();
       
   534 }
       
   535 
       
   536 //
       
   537 // CDebugProcess destructor
       
   538 //
       
   539 CDebugProcess::~CDebugProcess()
       
   540 {
       
   541 	SafeDelete(iExitTrapper);
       
   542 }
       
   543 
       
   544 #ifndef __TEXT_SHELL__
       
   545 
       
   546 //
       
   547 // CPhoneInfo implementation
       
   548 //
       
   549 CPhoneInfo::CPhoneInfo():
       
   550            CActive(EPriorityStandard),
       
   551            iPhoneIdV1Pckg(iPhoneIdV1),
       
   552            iDispatchLayer(NULL)
       
   553 {
       
   554     CActiveScheduler::Add(this);
       
   555 }
       
   556 
       
   557 CPhoneInfo* CPhoneInfo::NewL()
       
   558 {
       
   559     CPhoneInfo* self = new(ELeave) CPhoneInfo();
       
   560     CleanupStack::PushL(self);
       
   561     self->ConstructL();
       
   562     CleanupStack::Pop();
       
   563     return self;
       
   564 }
       
   565 
       
   566 void CPhoneInfo::ConstructL()
       
   567 {
       
   568     iTelephony = CTelephony::NewL();
       
   569 }
       
   570 
       
   571 CPhoneInfo::~CPhoneInfo() 
       
   572 { 
       
   573     Cancel();
       
   574     Deque();
       
   575     SafeDelete(iTelephony);
       
   576 }
       
   577 
       
   578 void CPhoneInfo::GetPhoneName(CTrkDispatchLayer* aDispatchLayer)
       
   579 {
       
   580     iDispatchLayer = aDispatchLayer;
       
   581     iTelephony->GetPhoneId(iStatus, iPhoneIdV1Pckg);
       
   582     SetActive();
       
   583 }
       
   584 
       
   585 void CPhoneInfo::RunL()
       
   586 {   
       
   587     if(iStatus == KErrNone)
       
   588 	{          
       
   589         iDispatchLayer->UpdatePhoneNameInfo(iPhoneIdV1.iModel);              
       
   590     }
       
   591 }
       
   592 
       
   593 void CPhoneInfo::DoCancel()
       
   594 {
       
   595 	iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel);
       
   596 }
       
   597 #endif
       
   598 
       
   599 //
       
   600 //
       
   601 // CTrkDispatchLayer implementation
       
   602 //
       
   603 //
       
   604 
       
   605 //
       
   606 // CTrkDispatchLayer constructor
       
   607 //
       
   608 CTrkDispatchLayer::CTrkDispatchLayer()
       
   609 	: iEngine(NULL),
       
   610 	  iFramingLayer(NULL),
       
   611 #ifndef __TEXT_SHELL__
       
   612 	  iPhoneInfo(NULL),
       
   613 #endif
       
   614 	  iFileState(EFileUnknown),
       
   615 	  iDebugProcessList(1),
       
   616 	  iProcessList(1),
       
   617 	  iThreadList(1),
       
   618 	  iSuspendedThreadList(1),
       
   619 	  iEventTrapper(NULL),
       
   620 	  iIsConnected(EFalse),
       
   621 	  iPhoneNameInfoAvailable(EFalse)
       
   622 	  
       
   623 #ifdef __OEM_TRK__	  
       
   624 	  ,iUseTcbServer(EFalse)
       
   625 #endif	  
       
   626 {
       
   627 }
       
   628 
       
   629 //
       
   630 // CTrkDispatchLayer::NewL
       
   631 //
       
   632 CTrkDispatchLayer* CTrkDispatchLayer::NewL(CTrkCommPort *aPort, CTrkEngine* aEngine)
       
   633 {
       
   634 	CTrkDispatchLayer* self = new(ELeave) CTrkDispatchLayer();
       
   635 	self->ConstructL(aPort, aEngine);
       
   636 	return self;
       
   637 }
       
   638 
       
   639 //
       
   640 // CTrkDispatchLayer destructor
       
   641 //
       
   642 CTrkDispatchLayer::~CTrkDispatchLayer()
       
   643 {
       
   644 	SafeDelete(iFramingLayer);
       
   645 
       
   646 	SafeDelete(iInputBuffer);
       
   647 	SafeDelete(iReplyBuffer);
       
   648 #ifndef __TEXT_SHELL__
       
   649 	SafeDelete(iPhoneInfo);
       
   650 #endif
       
   651 	// just in case a disconnect never happened
       
   652 	SafeDelete(iEventTrapper);
       
   653 	
       
   654 #ifndef __WINS__
       
   655 	iKernelDriver.Close();
       
   656 #endif
       
   657 
       
   658     CloseTcbServer();
       
   659 	iProcessList.Close();
       
   660 	iThreadList.Close();
       
   661 	iSuspendedThreadList.Close();
       
   662 	
       
   663 	iDebugProcessList.ResetAndDestroy();	
       
   664 	iDebugProcessList.Close();
       
   665 	//Notify the server that Debugging is ended
       
   666     if (iEngine)
       
   667         iEngine->DebuggingEnded();  
       
   668         
       
   669 }
       
   670 //
       
   671 // CTrkDispathcLayer::CloseTcbServer()
       
   672 //
       
   673 void CTrkDispatchLayer::CloseTcbServer()
       
   674 {
       
   675 #ifdef __OEM_TRK__  
       
   676     //Shutdown the tcb server.
       
   677     if (iUseTcbServer)
       
   678     {
       
   679         iTrkTcbSession.ShutDownServer();
       
   680         iTrkTcbSession.Close();
       
   681         iUseTcbServer = EFalse;
       
   682     }
       
   683 #endif  
       
   684 
       
   685 }
       
   686 
       
   687 //
       
   688 // CTrkDispatchLayer::ConstructL
       
   689 //
       
   690 void CTrkDispatchLayer::ConstructL(CTrkCommPort *aPort, CTrkEngine* aEngine)
       
   691 {
       
   692 	iEngine = aEngine;
       
   693 	
       
   694 	// create the framing layer interface
       
   695 	iFramingLayer = new CTrkFramingLayer(aPort);
       
   696 
       
   697 	// At a minimum, we assume that the host debugger supports 3.3 version of the protocol
       
   698 	// From 3.0 to 3.3, TRK is backwards compatible. Starting with version 3.4, TRK sends 
       
   699 	// process created notifications as part of notify created event. Unless the host 
       
   700 	// debugger sets the supported protocol version to 3.4, we are not going to send this 
       
   701 	// new notification. Going forward, we should check for the protocol version before 
       
   702 	// we send new notifications. 
       
   703 	iHostVersion.iMajor = DS_PROTOCOL_MAJOR_VERSION_3;
       
   704 	iHostVersion.iMinor = DS_PROTOCOL_MINOR_VERSION_3;
       
   705 	
       
   706 	//To find the sw version runnning in the phone
       
   707 	FindPhoneSWVersion();
       
   708 		
       
   709 	// On techview, this functionality is not available for some reason.
       
   710 	// This needs to be investigated further, but this functionality is not critical for techview platform right now.
       
   711 #ifdef __S60__
       
   712 	// To find the name of the phone.
       
   713 	TRAPD(err1, FindPhoneNameL());
       
   714 	if (err1 != KErrNone)
       
   715 #endif	   
       
   716 	{
       
   717 	    iPhoneNameInfoAvailable = EFalse;
       
   718 	}
       
   719 }
       
   720 
       
   721 //
       
   722 // CTrkDispathLayer::FindPhoneSWVersion()
       
   723 //
       
   724 // Finds out the software version of the phone
       
   725 //
       
   726 void CTrkDispatchLayer::FindPhoneSWVersion()
       
   727 {
       
   728 #ifndef __TEXT_SHELL__
       
   729     TBuf<KSysUtilVersionTextLength> version;
       
   730     if (SysUtil::GetSWVersion( version ) == KErrNone ) 
       
   731 	{
       
   732         iPhoneVersion.Copy(version);
       
   733 	}                
       
   734 #endif
       
   735 }
       
   736 
       
   737 //
       
   738 // CTrkDispathLayer::FindPhoneName()
       
   739 //
       
   740 // Finds the name of the phone 
       
   741 //
       
   742 void CTrkDispatchLayer::FindPhoneNameL()
       
   743 {
       
   744 #ifndef __TEXT_SHELL__
       
   745     iPhoneInfo = CPhoneInfo::NewL();
       
   746     iPhoneInfo->GetPhoneName(this);
       
   747 #endif             
       
   748 }
       
   749 
       
   750 //
       
   751 // CTrkDispatchLayer::Listen
       
   752 //
       
   753 // Start listening to the communications port for messages from the host debugger
       
   754 //
       
   755 void CTrkDispatchLayer::Listen()
       
   756 {
       
   757 	iFramingLayer->Listen(this);
       
   758 }
       
   759 
       
   760 //
       
   761 // CTrkDispatchLayer::StopListening
       
   762 //
       
   763 // Stop listening to the communications port for messages from the host debugger
       
   764 //
       
   765 void CTrkDispatchLayer::StopListening()
       
   766 {
       
   767 	// just in case the user quit MetroTrk while something was being debugged.
       
   768 	RProcess process;
       
   769 	for (TInt i=0; i<iDebugProcessList.Count(); i++)
       
   770 	{
       
   771 		if (KErrNone == process.Open(iDebugProcessList[i]->ProcessId()))
       
   772 		{
       
   773 		#ifdef EKA2
       
   774 			process.Kill(KErrNone);
       
   775 		#else	
       
   776 			process.Kill(KProcessKilled);
       
   777 		#endif
       
   778 			process.Close();
       
   779 		}
       
   780 	}
       
   781 
       
   782 	iFramingLayer->StopListening();
       
   783 }
       
   784 
       
   785 //
       
   786 // CTrkDispatchLayer::GetVersionInfo
       
   787 //
       
   788 // Get the current version of MetroTrk
       
   789 //
       
   790 void CTrkDispatchLayer::GetVersionInfo(TInt &aMajorVersion, TInt &aMinorVersion, TInt &aMajorAPIVersion, TInt &aMinorAPIVersion, TInt &aBuildNumber)
       
   791 {
       
   792 	aMajorVersion = MAJOR_VERSION_NUMBER;
       
   793 	aMinorVersion = MINOR_VERSION_NUMBER;
       
   794 	aMajorAPIVersion = DS_PROTOCOL_MAJOR_VERSION;
       
   795 	aMinorAPIVersion = DS_PROTOCOL_MINOR_VERSION;
       
   796 	aBuildNumber = BUILD_NUMBER;
       
   797 }
       
   798 
       
   799 //
       
   800 // CTrkDispatchLayer::HandleMsg
       
   801 //
       
   802 // Handle a command sent by the host debugger
       
   803 //
       
   804 void CTrkDispatchLayer::HandleMsg(const TDesC8& aMsg)
       
   805 {
       
   806 	TInt error = KErrNone;
       
   807 
       
   808 	// reset the input buffer and set it to the new unframed message
       
   809 	SafeDelete(iInputBuffer);
       
   810 	iInputBuffer = aMsg.Alloc();
       
   811 
       
   812 	if (!iInputBuffer)
       
   813 		User::Panic(_L("Failed to allocate input buffer"), __LINE__);
       
   814 	
       
   815 	TRAP(error, DispatchMsgL());
       
   816 
       
   817 	if (error < 0)
       
   818 	{
       
   819 		// its a symbian os error
       
   820 		error = kDSReplyOsError;
       
   821 	}
       
   822 	
       
   823 	// handle errors raised during command execution
       
   824 	switch(error)
       
   825 	{
       
   826 		// no error and ack was sent by handler
       
   827  		case kDSReplyNoError:
       
   828  			break;
       
   829 
       
   830 		// there was a problem with the packet received
       
   831 		case kDSReplyPacketSizeError:
       
   832 		case kDSReplyEscapeError:
       
   833 		case kDSReplyBadFCS:
       
   834 		case kDSReplyOverflow:
       
   835 		case kDSReplySequenceMissing:
       
   836 			iFramingLayer->RespondErr(kDSReplyNAK, error);
       
   837 			break;
       
   838 			
       
   839 		// command and format were OK, but failed for some other reason
       
   840  		default:
       
   841 			iFramingLayer->RespondErr(kDSReplyACK, error);
       
   842 	}
       
   843 }
       
   844 
       
   845 //
       
   846 // CTrkDispatchLayer::DispatchMsgL
       
   847 //
       
   848 // Handle the command sent by the host debugger
       
   849 //
       
   850 void CTrkDispatchLayer::DispatchMsgL()
       
   851 {
       
   852 	// make sure the input buffer is setup
       
   853 	User::LeaveIfNull(iInputBuffer);
       
   854 
       
   855 	// iInputBuffer holds the unframed message from the host
       
   856 	switch (iInputBuffer->Ptr()[0])
       
   857 	{
       
   858 		case kDSPing:
       
   859 		{
       
   860 			// nothing to do
       
   861 			iFramingLayer->RespondOkL(KNullDesC8);
       
   862 			break;
       
   863 		}
       
   864 		case kDSConnect:
       
   865 		{
       
   866 			DoConnectL();
       
   867 			break;
       
   868 		}
       
   869 		case kDSDisconnect:
       
   870 		{
       
   871 			DoDisconnectL();
       
   872 			break;
       
   873 		}
       
   874 		case kDSVersions:
       
   875 		{
       
   876 			DoVersionsL();
       
   877 			break;
       
   878 		}
       
   879 		case kDSVersions2:
       
   880 		{
       
   881 			DoVersions2L();
       
   882 			break;
       
   883 		}
       
   884 		case kDSVersions3:
       
   885 		{
       
   886 			DoVersions3L();
       
   887 			break;
       
   888 		}
       
   889 		case kDSHostVersions:
       
   890 		{
       
   891 			DoHostVersionsL();
       
   892 			break;
       
   893 		}
       
   894 		case kDSSupportMask:
       
   895 		{
       
   896 			DoSupportMaskL();
       
   897 			break;
       
   898 		}
       
   899 		case kDSCPUType:
       
   900 		{
       
   901 			DoCPUTypeL();
       
   902 			break;
       
   903 		}
       
   904 		case kDSReadMemory:
       
   905 		{
       
   906 			DoReadMemoryL();
       
   907 			break;
       
   908 		}
       
   909 		case kDSWriteMemory:
       
   910 		{
       
   911 			DoWriteMemoryL();
       
   912 			break;
       
   913 		}
       
   914 		case kDSReadRegisters:
       
   915 		{
       
   916 			DoReadRegistersL();
       
   917 			break;
       
   918 		}
       
   919 		case kDSWriteRegisters:
       
   920 		{
       
   921 			DoWriteRegistersL();
       
   922 			break;
       
   923 		}
       
   924 		case kDSContinue:
       
   925 		{
       
   926 			DoContinueL();
       
   927 			break;
       
   928 		}
       
   929 		case kDSStep:
       
   930 		{
       
   931 			DoStepL();
       
   932 			break;
       
   933 		}
       
   934 		case kDSStop:
       
   935 		{
       
   936 			DoStopL();
       
   937 			break;
       
   938 		}
       
   939 		case kDSSetBreak:
       
   940 		{
       
   941 			DoSetBreakL();
       
   942 			break;
       
   943 		}
       
   944 		case kDSClearBreak:
       
   945 		{
       
   946 			DoClearBreakL();
       
   947 			break;
       
   948 		}
       
   949 		case kDSModifyBreakThread:
       
   950 		{
       
   951 			DoModifyBreakThreadL();
       
   952 			break;
       
   953 		}
       
   954 		case kDSOSCreateItem:
       
   955 		{
       
   956 			DoCreateItemL();
       
   957 			break;
       
   958 		}
       
   959 		case kDSOSDeleteItem:
       
   960 		{
       
   961 			DoDeleteItemL();
       
   962 			break;
       
   963 		}
       
   964 		case kDSOSReadInfo:
       
   965 		{
       
   966 			DoReadInfoL();
       
   967 			break;
       
   968 		}
       
   969 		case kDSOSWriteInfo:
       
   970 		{
       
   971 			DoWriteInfoL();
       
   972 			break;
       
   973 		}
       
   974 		case kDSOSWriteFile:
       
   975 		{
       
   976 			DoWriteFileL();
       
   977 			break;
       
   978 		}
       
   979 		case kDSOSReadFile:
       
   980 		{
       
   981 			DoReadFileL();
       
   982 			break;
       
   983 		}
       
   984 		case kDSOSOpenFile:
       
   985 		{
       
   986 			DoOpenFileL();
       
   987 			break;
       
   988 		}	
       
   989 		case kDSOSCloseFile:
       
   990 		{
       
   991 			DoCloseFileL();
       
   992 			break;
       
   993 		}
       
   994 		case kDSOSPositionFile:
       
   995 		{
       
   996 			DoPositionFileL();
       
   997 			break;
       
   998 		}
       
   999 		case kDSOSInstallFile:
       
  1000 		{
       
  1001 			DoInstallFileL();
       
  1002 			break;
       
  1003 		}
       
  1004 		case kDSOSInstallFile2:
       
  1005 		{
       
  1006 			DoInstallFile2L();
       
  1007 			break;
       
  1008 		}
       
  1009 		case kDSOSPhoneSWVersion:
       
  1010 	    {		    
       
  1011 		    DoGetPhoneSWVersionL();
       
  1012 			break;
       
  1013 		}
       
  1014 		case kDSOSPhoneName:		    
       
  1015 		{
       
  1016 		    DoGetPhoneNameL();
       
  1017 		    break;
       
  1018 		}
       
  1019 		
       
  1020 		case kDSReplyACK:
       
  1021 		case kDSReplyNAK:
       
  1022 			break;
       
  1023 
       
  1024 		case kDSReset:
       
  1025 		case kDSFillMemory:
       
  1026 		case kDSCopyMemory:
       
  1027 		case kDSFlushCache:
       
  1028 		case kDSDownload:
       
  1029 		case kDSNotifyFileInput:			
       
  1030 		default:
       
  1031 		{
       
  1032 			// unsupported command
       
  1033 			iFramingLayer->RespondErr(kDSReplyACK, kDSReplyUnsupportedCommandError);
       
  1034 			break;
       
  1035 		}
       
  1036 	}
       
  1037 }
       
  1038 
       
  1039 //
       
  1040 // CTrkDispatchLayer::DoConnectL
       
  1041 //
       
  1042 // The host debugger is starting a new debug session
       
  1043 //
       
  1044 void CTrkDispatchLayer::DoConnectL()
       
  1045 {	
       
  1046 	// make sure we got here from DispatchMsgL
       
  1047 	TUint8 command = 0;
       
  1048 	GetDataFromBufferL(&command, 1);
       
  1049 	
       
  1050 	if (kDSConnect != command)
       
  1051 		User::Leave(kDSReplyError);
       
  1052 
       
  1053 	// if we're already connected for some reason, we need to cleanup so we're ready
       
  1054 	// for a new debug session
       
  1055 	if (iIsConnected)
       
  1056 	{
       
  1057 		// reset the sequence ids for the next debug session
       
  1058 		iFramingLayer->ResetSequenceIDs();
       
  1059 
       
  1060 		//stop listening for events
       
  1061 		SafeDelete(iEventTrapper);
       
  1062 
       
  1063 		// let the kernel side driver cleanup
       
  1064 		iKernelDriver.Close();
       
  1065 
       
  1066 		iIsConnected = EFalse;
       
  1067 	}
       
  1068 
       
  1069 	// reset the lists so that they are ready for use
       
  1070 	iProcessList.Reset();
       
  1071 	iThreadList.Reset();
       
  1072 	iSuspendedThreadList.Reset();
       
  1073 	iDebugProcessList.ResetAndDestroy();
       
  1074 
       
  1075 	TMetroTrkDriverInfo info;
       
  1076 #ifndef EKA2
       
  1077 	RLibrary euser;
       
  1078 	User::LeaveIfError(euser.Load(EUSER_LIBPATH));
       
  1079 	CleanupClosePushL(euser);
       
  1080 	
       
  1081 	info.iPanic1Address = (TUint32)euser.Lookup(812);			// RThread::Panic
       
  1082 	info.iPanic2Address = (TUint32)euser.Lookup(813);			// RProcess::Panic
       
  1083 	info.iException1Address = (TUint32)euser.Lookup(868);		// RThread::RaiseException
       
  1084 	info.iException2Address = (TUint32)euser.Lookup(520);		// User::HandleException
       
  1085 	info.iLibraryLoadedAddress = (TUint32)euser.Lookup(636);	// UserSvr::LibraryLoaded
       
  1086 
       
  1087 	// calculate the end address of the user library.  breakpoints and stepping will not
       
  1088 	// be allowed from the start of ROM to the end of the user library since stopping a
       
  1089 	// kernel thread could end up freezing the target
       
  1090 	RFs fs;
       
  1091 	User::LeaveIfError(fs.Connect());
       
  1092 	CleanupClosePushL(fs);
       
  1093 
       
  1094 	RFile file;
       
  1095 	User::LeaveIfError(file.Open(fs, EUSER_LIBPATH, EFileStream|EFileRead|EFileShareReadersOnly));
       
  1096 	CleanupClosePushL(file);
       
  1097 
       
  1098 	TInt size;
       
  1099 	User::LeaveIfError(file.Size(size));
       
  1100 	
       
  1101 	info.iUserLibraryEnd = (TUint32)euser.EntryPoint() + size;
       
  1102 
       
  1103 	CleanupStack::PopAndDestroy(); // file
       
  1104 	CleanupStack::PopAndDestroy(); // fs
       
  1105 	CleanupStack::PopAndDestroy(); // euser
       
  1106 #endif	
       
  1107 	
       
  1108 	// start the kernel side driver
       
  1109 	User::LeaveIfError(iKernelDriver.Open(info));
       
  1110 	
       
  1111 	// start listening for events
       
  1112 	iEventTrapper = new(ELeave) CEventTrapper(this);
       
  1113 	iEventTrapper->Watch();
       
  1114 
       
  1115 	iIsConnected = ETrue;	
       
  1116 #ifdef __S60__	
       
  1117 	// now close close crash logger
       
  1118 	CloseCrashLogger();
       
  1119 #endif	
       
  1120 	
       
  1121 	if (iEngine)
       
  1122 		iEngine->DebuggingStarted();
       
  1123 	
       
  1124 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1125 }
       
  1126 
       
  1127 //
       
  1128 // CTrkDispatchLayer::DoDisconnectL
       
  1129 //
       
  1130 // The host debugger is stopping the current debug session
       
  1131 //
       
  1132 void CTrkDispatchLayer::DoDisconnectL()
       
  1133 {
       
  1134 	// make sure we got here from DispatchMsgL
       
  1135 	TUint8 command = 0;
       
  1136 	GetDataFromBufferL(&command, 1);
       
  1137 	
       
  1138 	if (kDSDisconnect != command)
       
  1139 		User::Leave(kDSReplyError);
       
  1140 
       
  1141 	// make sure we're connected
       
  1142 	if (!iIsConnected)
       
  1143 	{
       
  1144 		User::Leave(KErrCouldNotDisconnect);
       
  1145 	}
       
  1146 
       
  1147 	//stop listening for events
       
  1148 	SafeDelete(iEventTrapper);
       
  1149 
       
  1150 	iIsConnected = EFalse;
       
  1151 
       
  1152 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1153 
       
  1154 	// let the kernel side driver cleanup
       
  1155 	iKernelDriver.Close();
       
  1156 
       
  1157 	//Shutdown the tcb server.
       
  1158 	CloseTcbServer();
       
  1159 	
       
  1160 	// send the callback to the trk server
       
  1161 	if (iEngine)
       
  1162 		iEngine->DebuggingEnded();	
       
  1163         
       
  1164 }
       
  1165 
       
  1166 //
       
  1167 // CTrkDispatchLayer::DoVersionsL
       
  1168 //
       
  1169 // The host debugger is requesting MetroTrk version information
       
  1170 //
       
  1171 void CTrkDispatchLayer::DoVersionsL()
       
  1172 {
       
  1173 	// make sure we got here from DispatchMsgL
       
  1174 	TUint8 command = 0;
       
  1175 	GetDataFromBufferL(&command, 1);
       
  1176 	
       
  1177 	if (kDSVersions != command)
       
  1178 		User::Leave(kDSReplyError);
       
  1179 	
       
  1180 	TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER;
       
  1181 	TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER;
       
  1182 	TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION;
       
  1183 	TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION;
       
  1184 
       
  1185 	AddToReplyBufferL(kernelMajorVersion, true);
       
  1186 	AddToReplyBufferL(kernelMinorVersion);
       
  1187 	AddToReplyBufferL(protocolMajorVersion);
       
  1188 	AddToReplyBufferL(protocolMinorVersion);
       
  1189 
       
  1190 	RespondOkL();
       
  1191 }
       
  1192 
       
  1193 //
       
  1194 // CTrkDispatchLayer::DoVersionsL
       
  1195 //
       
  1196 // The host debugger is requesting MetroTrk version information
       
  1197 //
       
  1198 void CTrkDispatchLayer::DoVersions2L()
       
  1199 {
       
  1200 	// make sure we got here from DispatchMsgL
       
  1201 	TUint8 command = 0;
       
  1202 	GetDataFromBufferL(&command, 1);
       
  1203 	
       
  1204 	if (kDSVersions2 != command)
       
  1205 		User::Leave(kDSReplyError);
       
  1206 	
       
  1207 	TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER;
       
  1208 	TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER;
       
  1209 	TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION;
       
  1210 	TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION;
       
  1211 	TUint8 buildNumber = BUILD_NUMBER;
       
  1212 
       
  1213 	AddToReplyBufferL(kernelMajorVersion, true);
       
  1214 	AddToReplyBufferL(kernelMinorVersion);
       
  1215 	AddToReplyBufferL(protocolMajorVersion);
       
  1216 	AddToReplyBufferL(protocolMinorVersion);
       
  1217 	AddToReplyBufferL(buildNumber);
       
  1218 
       
  1219 	RespondOkL();
       
  1220 }
       
  1221 
       
  1222 //
       
  1223 // CTrkDispatchLayer::DoVersions3L
       
  1224 //
       
  1225 // The host debugger is requesting MetroTrk version information
       
  1226 //
       
  1227 void CTrkDispatchLayer::DoVersions3L()
       
  1228 {
       
  1229 	// make sure we got here from DispatchMsgL
       
  1230 	TUint8 command = 0;
       
  1231 	GetDataFromBufferL(&command, 1);
       
  1232 	
       
  1233 	if (kDSVersions3 != command)
       
  1234 		User::Leave(kDSReplyError);
       
  1235 	
       
  1236 	TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER;
       
  1237 	TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER;
       
  1238 	TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION;
       
  1239 	TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION;
       
  1240 	TUint8 buildNumber = BUILD_NUMBER;
       
  1241 
       
  1242 	AddToReplyBufferL(kernelMajorVersion, true);
       
  1243 	AddToReplyBufferL(kernelMinorVersion);
       
  1244 	AddToReplyBufferL(protocolMajorVersion);
       
  1245 	AddToReplyBufferL(protocolMinorVersion);
       
  1246 	AddToReplyBufferL(buildNumber);
       
  1247 	
       
  1248 	TUint16 len = TRK_TYPE_DESCRIPTION.Length();
       
  1249 	
       
  1250 	AddToReplyBufferL(len);
       
  1251 	AddToReplyBufferL(TRK_TYPE_DESCRIPTION);
       
  1252 
       
  1253 	RespondOkL();
       
  1254 }
       
  1255 
       
  1256 //
       
  1257 // CTrkDispatchLayer::DoHostVersionsL
       
  1258 //
       
  1259 // The host debugger is sending the supported protocol version
       
  1260 //
       
  1261 void CTrkDispatchLayer::DoHostVersionsL()
       
  1262 {
       
  1263 	// make sure we got here from DispatchMsgL
       
  1264 	TUint8 command = 0;
       
  1265 	GetDataFromBufferL(&command, 1);
       
  1266 	
       
  1267 	if (kDSHostVersions != command)
       
  1268 		User::Leave(kDSReplyError);
       
  1269 	
       
  1270 	GetDataFromBufferL(&iHostVersion.iMajor, 1);
       
  1271 	GetDataFromBufferL(&iHostVersion.iMinor, 1);
       
  1272 	
       
  1273 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1274 }
       
  1275 
       
  1276 //
       
  1277 // CTrkDispatchLayer::DoSupportMaskL
       
  1278 //
       
  1279 // The host debugger is requesting MetroTrk capabilities
       
  1280 //
       
  1281 void CTrkDispatchLayer::DoSupportMaskL()
       
  1282 {
       
  1283 	// make sure we got here from DispatchMsgL
       
  1284 	TUint8 command = 0;
       
  1285 	GetDataFromBufferL(&command, 1);
       
  1286 	
       
  1287 	if (kDSSupportMask != command)
       
  1288 		User::Leave(kDSReplyError);
       
  1289 	
       
  1290 	TBuf8<32> supportMask;
       
  1291 	TUint8 level = DS_PROTOCOL_RTOS;
       
  1292 	
       
  1293 	supportMask.Zero();
       
  1294 	supportMask.Append(DS_SUPPORT_MASK_00_07);
       
  1295 	supportMask.Append(DS_SUPPORT_MASK_08_0F);
       
  1296 	supportMask.Append(DS_SUPPORT_MASK_10_17);
       
  1297 	supportMask.Append(DS_SUPPORT_MASK_18_1F);
       
  1298 	supportMask.Append(DS_SUPPORT_MASK_20_27);
       
  1299 	supportMask.Append(DS_SUPPORT_MASK_28_2F);
       
  1300 	supportMask.Append(DS_SUPPORT_MASK_30_37);
       
  1301 	supportMask.Append(DS_SUPPORT_MASK_38_3F);
       
  1302 	supportMask.Append(DS_SUPPORT_MASK_40_47);
       
  1303 	supportMask.Append(DS_SUPPORT_MASK_48_4F);
       
  1304 	supportMask.Append(DS_SUPPORT_MASK_50_57);
       
  1305 	supportMask.Append(DS_SUPPORT_MASK_58_5F);
       
  1306 	supportMask.Append(DS_SUPPORT_MASK_60_67);
       
  1307 	supportMask.Append(DS_SUPPORT_MASK_68_6F);
       
  1308 	supportMask.Append(DS_SUPPORT_MASK_70_77);
       
  1309 	supportMask.Append(DS_SUPPORT_MASK_78_7F);
       
  1310 	supportMask.Append(DS_SUPPORT_MASK_80_87);
       
  1311 	supportMask.Append(DS_SUPPORT_MASK_88_8F);
       
  1312 	supportMask.Append(DS_SUPPORT_MASK_90_97);
       
  1313 	supportMask.Append(DS_SUPPORT_MASK_98_9F);
       
  1314 	supportMask.Append(DS_SUPPORT_MASK_A0_A7);
       
  1315 	supportMask.Append(DS_SUPPORT_MASK_A8_AF);
       
  1316 	supportMask.Append(DS_SUPPORT_MASK_B0_B7);
       
  1317 	supportMask.Append(DS_SUPPORT_MASK_B8_BF);
       
  1318 	supportMask.Append(DS_SUPPORT_MASK_C0_C7);
       
  1319 	supportMask.Append(DS_SUPPORT_MASK_C8_CF);
       
  1320 	supportMask.Append(DS_SUPPORT_MASK_D0_D7);
       
  1321 	supportMask.Append(DS_SUPPORT_MASK_D8_DF);
       
  1322 	supportMask.Append(DS_SUPPORT_MASK_E0_E7);
       
  1323 	supportMask.Append(DS_SUPPORT_MASK_E8_EF);
       
  1324 	supportMask.Append(DS_SUPPORT_MASK_F0_F7);
       
  1325 	supportMask.Append(DS_SUPPORT_MASK_F8_FF);
       
  1326 	
       
  1327 	AddToReplyBufferL(supportMask, true);
       
  1328 	AddToReplyBufferL(level);
       
  1329 
       
  1330 	RespondOkL();
       
  1331 }
       
  1332 
       
  1333 //
       
  1334 // CTrkDispatchLayer::DoCPUTypeL
       
  1335 //
       
  1336 // The host debugger is requesting cpu information
       
  1337 //
       
  1338 void CTrkDispatchLayer::DoCPUTypeL()
       
  1339 {
       
  1340 	// make sure we got here from DispatchMsgL
       
  1341 	TUint8 command = 0;
       
  1342 	GetDataFromBufferL(&command, 1);
       
  1343 	
       
  1344 	if (kDSCPUType != command)
       
  1345 		User::Leave(kDSReplyError);
       
  1346 
       
  1347 	TUint8 cpuMajor = DS_CPU_MAJOR_ARM;
       
  1348 	TUint8 cpuMinor = 0;
       
  1349 	TUint8 bigEndian = iFramingLayer->IsBigEndian() ? 1 : 0;
       
  1350 	TUint8 defaultTypeSize = 4;
       
  1351 	TUint8 fpTypeSize = 0;
       
  1352 	TUint8 extended1TypeSize = 0;
       
  1353 	TUint8 extended2TypeSize = 0;
       
  1354 
       
  1355 	AddToReplyBufferL(cpuMajor, true);
       
  1356 	AddToReplyBufferL(cpuMinor);
       
  1357 	AddToReplyBufferL(bigEndian);
       
  1358 	AddToReplyBufferL(defaultTypeSize);
       
  1359 	AddToReplyBufferL(fpTypeSize);
       
  1360 	AddToReplyBufferL(extended1TypeSize);
       
  1361 	AddToReplyBufferL(extended2TypeSize);
       
  1362 
       
  1363 	RespondOkL();
       
  1364 }
       
  1365 
       
  1366 //
       
  1367 // CTrkDispatchLayer::DoReadMemoryL
       
  1368 //
       
  1369 // Read memory from the target device and return to the host
       
  1370 //
       
  1371 void CTrkDispatchLayer::DoReadMemoryL()
       
  1372 {
       
  1373 	// make sure we're connected
       
  1374 	if (!iIsConnected)
       
  1375 	{
       
  1376 		User::Leave(KErrGeneral);
       
  1377 	}
       
  1378 
       
  1379 	// make sure we got here from DispatchMsgL
       
  1380 	TUint8 command = 0;
       
  1381 	GetDataFromBufferL(&command, 1);
       
  1382 	
       
  1383 	if (kDSReadMemory != command)
       
  1384 		User::Leave(kDSReplyError);
       
  1385 
       
  1386  	// get the options
       
  1387 	TUint8 options = 0;
       
  1388 	GetDataFromBufferL(&options, 1);
       
  1389 
       
  1390 	if ((options & DS_MSG_MEMORY_EXTENDED) != 0)
       
  1391 		User::Leave(kDSReplyUnsupportedOptionError);
       
  1392 
       
  1393 	// get the length to read
       
  1394 	TUint16 length = 0;
       
  1395 	GetDataFromBufferL(&length, 2);
       
  1396 
       
  1397 	if (length > DS_MAXREADWRITELENGTH)
       
  1398 		User::Leave(kDSReplyParameterError);
       
  1399 	
       
  1400 	// get the start address
       
  1401 	TUint32 address = 0;
       
  1402 	GetDataFromBufferL(&address, 4);
       
  1403 
       
  1404 	// get the process id
       
  1405 	TUint32 processId = 0;
       
  1406 	GetDataFromBufferL(&processId, 4);
       
  1407 
       
  1408 	// get the thread id
       
  1409 	TUint32 threadId = 0;
       
  1410 	GetDataFromBufferL(&threadId, 4);
       
  1411 
       
  1412 	// allocate enough room for the data
       
  1413 	HBufC8 *data = HBufC8::NewLC(length);
       
  1414 	TPtr8 ptr(data->Des());
       
  1415 
       
  1416 	TInt err = iKernelDriver.ReadMemory(threadId, address, length, ptr);
       
  1417 	if (KErrNone != err)
       
  1418 	{
       
  1419 		CleanupStack::PopAndDestroy(data);
       
  1420 		User::Leave(err);
       
  1421 	}
       
  1422 	
       
  1423 	AddToReplyBufferL(length, true);
       
  1424 	AddToReplyBufferL(ptr);
       
  1425 
       
  1426 	RespondOkL();
       
  1427 
       
  1428 	CleanupStack::PopAndDestroy(data);
       
  1429 }
       
  1430 
       
  1431 //
       
  1432 // CTrkDispatchLayer::DoWriteMemoryL
       
  1433 //
       
  1434 // Write memory from the host to the target device
       
  1435 //
       
  1436 void CTrkDispatchLayer::DoWriteMemoryL()
       
  1437 {
       
  1438 	// make sure we're connected
       
  1439 	if (!iIsConnected)
       
  1440 	{
       
  1441 		User::Leave(KErrGeneral);
       
  1442 	}
       
  1443 
       
  1444 	// make sure we got here from DispatchMsgL
       
  1445 	TUint8 command = 0;
       
  1446 	GetDataFromBufferL(&command, 1);
       
  1447 	
       
  1448 	if (kDSWriteMemory != command)
       
  1449 		User::Leave(kDSReplyError);
       
  1450 
       
  1451  	// get the options
       
  1452 	TUint8 options = 0;
       
  1453 	GetDataFromBufferL(&options, 1);
       
  1454 
       
  1455 	if ((options & DS_MSG_MEMORY_EXTENDED) != 0)
       
  1456 		User::Leave(kDSReplyUnsupportedOptionError);
       
  1457 
       
  1458 	// get the length to write
       
  1459 	TUint16 length = 0;
       
  1460 	GetDataFromBufferL(&length, 2);
       
  1461 
       
  1462 	if (length > DS_MAXREADWRITELENGTH)
       
  1463 		User::Leave(kDSReplyParameterError);
       
  1464 	
       
  1465 	// get the start address
       
  1466 	TUint32 address = 0;
       
  1467 	GetDataFromBufferL(&address, 4);
       
  1468 
       
  1469 	// get the process id
       
  1470 	TUint32 processId = 0;
       
  1471 	GetDataFromBufferL(&processId, 4);
       
  1472 
       
  1473 	// get the thread id
       
  1474 	TUint32 threadId = 0;
       
  1475 	GetDataFromBufferL(&threadId, 4);
       
  1476 
       
  1477 	User::LeaveIfError(iKernelDriver.WriteMemory(threadId, address, length, *iInputBuffer));
       
  1478 	
       
  1479 	AddToReplyBufferL(length, true);
       
  1480 
       
  1481 	RespondOkL();
       
  1482 }
       
  1483 
       
  1484 //
       
  1485 // CTrkDispatchLayer::DoReadRegistersL
       
  1486 //
       
  1487 // Read registers from the target device and return to the host
       
  1488 //
       
  1489 void CTrkDispatchLayer::DoReadRegistersL()
       
  1490 {
       
  1491 	// make sure we're connected
       
  1492 	if (!iIsConnected)
       
  1493 	{
       
  1494 		User::Leave(KErrGeneral);
       
  1495 	}
       
  1496 
       
  1497 	// make sure we got here from DispatchMsgL
       
  1498 	TUint8 command = 0;
       
  1499 	GetDataFromBufferL(&command, 1);
       
  1500 	
       
  1501 	if (kDSReadRegisters != command)
       
  1502 		User::Leave(kDSReplyError);
       
  1503 
       
  1504 	// get the options
       
  1505 	TUint8 options = 0;
       
  1506 	GetDataFromBufferL(&options, 1);
       
  1507 
       
  1508 	if (DS_MSG_REGISTERS_TYPE(options) != kDSRegistersDefault)
       
  1509 		User::Leave(kDSReplyUnsupportedOptionError);
       
  1510 		
       
  1511 	// get the first register
       
  1512 	TInt16 firstRegister = 0;
       
  1513 	GetDataFromBufferL(&firstRegister, 2);
       
  1514 
       
  1515 	// get the last register
       
  1516 	TInt16 lastRegister = 0;
       
  1517 	GetDataFromBufferL(&lastRegister, 2);
       
  1518 
       
  1519 	if ((firstRegister < 0) || (lastRegister > 16))
       
  1520 		User::Leave(kDSReplyInvalidRegisterRange);
       
  1521 	
       
  1522 	// get the process id
       
  1523 	TUint32 processId = 0;
       
  1524 	GetDataFromBufferL(&processId, 4);
       
  1525 
       
  1526 	// get the thread id
       
  1527 	TUint32 threadId = 0;
       
  1528 	GetDataFromBufferL(&threadId, 4);
       
  1529 
       
  1530 	// allocate enough space to hold the values
       
  1531 	HBufC8 *values = HBufC8::NewLC((lastRegister - firstRegister + 1) * 4);
       
  1532 	TPtr8 ptr(values->Des());
       
  1533 	
       
  1534 	TInt err = iKernelDriver.ReadRegisters(threadId, firstRegister, lastRegister, ptr);
       
  1535 	if (KErrNone != err)
       
  1536 	{
       
  1537 		CleanupStack::PopAndDestroy(values);
       
  1538 		User::Leave(err);
       
  1539 	}
       
  1540 	
       
  1541 	for (int i=0; i<=lastRegister - firstRegister; i++)
       
  1542 		AddToReplyBufferL(*(TUint32 *)&ptr.Ptr()[i*4], i==0 ? true : false);
       
  1543 			
       
  1544 	RespondOkL();
       
  1545 
       
  1546 	CleanupStack::PopAndDestroy(values);
       
  1547 }
       
  1548 
       
  1549 //
       
  1550 // CTrkDispatchLayer::DoWriteRegistersL
       
  1551 //
       
  1552 // Write registers from the host to the target device
       
  1553 //
       
  1554 void CTrkDispatchLayer::DoWriteRegistersL()
       
  1555 {
       
  1556 	// make sure we're connected
       
  1557 	if (!iIsConnected)
       
  1558 	{
       
  1559 		User::Leave(KErrGeneral);
       
  1560 	}
       
  1561 
       
  1562 	// make sure we got here from DispatchMsgL
       
  1563 	TUint8 command = 0;
       
  1564 	GetDataFromBufferL(&command, 1);
       
  1565 	
       
  1566 	if (kDSWriteRegisters != command)
       
  1567 		User::Leave(kDSReplyError);
       
  1568 
       
  1569 	// get the options
       
  1570 	TUint8 options = 0;
       
  1571 	GetDataFromBufferL(&options, 1);
       
  1572 
       
  1573 	if (DS_MSG_REGISTERS_TYPE(options) != kDSRegistersDefault)
       
  1574 		User::Leave(kDSReplyUnsupportedOptionError);
       
  1575 
       
  1576 	// get the first register
       
  1577 	TInt16 firstRegister = 0;
       
  1578 	GetDataFromBufferL(&firstRegister, 2);
       
  1579 
       
  1580 	// get the last register
       
  1581 	TInt16 lastRegister = 0;
       
  1582 	GetDataFromBufferL(&lastRegister, 2);
       
  1583 
       
  1584 	if ((firstRegister < 0) || (lastRegister > 16))
       
  1585 		User::Leave(kDSReplyInvalidRegisterRange);
       
  1586 
       
  1587 	// get the process id
       
  1588 	TUint32 processId = 0;
       
  1589 	GetDataFromBufferL(&processId, 4);
       
  1590 
       
  1591 	// get the thread id
       
  1592 	TUint32 threadId = 0;
       
  1593 	GetDataFromBufferL(&threadId, 4);
       
  1594 	
       
  1595 	// MetroTrk register values come in as big endian so we may need to swap them
       
  1596 	if (!iFramingLayer->IsBigEndian())
       
  1597 	{
       
  1598 		Swap4xN((TUint32 *)iInputBuffer->Ptr(), lastRegister-firstRegister + 1);
       
  1599 	}
       
  1600 	
       
  1601 	User::LeaveIfError(iKernelDriver.WriteRegisters(threadId, firstRegister, lastRegister, *iInputBuffer));
       
  1602 	
       
  1603 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1604 }
       
  1605 
       
  1606 //
       
  1607 // CTrkDispatchLayer::DoContinueL
       
  1608 //
       
  1609 // Resume thread execution
       
  1610 //
       
  1611 void CTrkDispatchLayer::DoContinueL()
       
  1612 {
       
  1613 	// make sure we're connected
       
  1614 	if (!iIsConnected)
       
  1615 	{
       
  1616 		User::Leave(KErrGeneral);
       
  1617 	}
       
  1618 
       
  1619 	// make sure we got here from DispatchMsgL
       
  1620 	TUint8 command = 0;
       
  1621 	GetDataFromBufferL(&command, 1);
       
  1622 	
       
  1623 	if (kDSContinue != command)
       
  1624 		User::Leave(kDSReplyError);
       
  1625 
       
  1626 	// get the process id
       
  1627 	TUint32 processId = 0;
       
  1628 	GetDataFromBufferL(&processId, 4);
       
  1629 
       
  1630 	// get the thread id
       
  1631 	TUint32 threadId = 0;
       
  1632 	GetDataFromBufferL(&threadId, 4);
       
  1633 	
       
  1634 	// see if this thread is in the the suspended threads list
       
  1635 	// if so, remove it and resume.  otherwise we need to handle
       
  1636 	// the special case of the first time a thread is resumed
       
  1637 	TInt index = iSuspendedThreadList.Find(threadId);
       
  1638 	if (index >= 0)
       
  1639 	{
       
  1640 		iSuspendedThreadList.Remove(index);
       
  1641 		User::LeaveIfError(iKernelDriver.ResumeThread(threadId));
       
  1642 		iFramingLayer->RespondOkL(KNullDesC8);
       
  1643 	}
       
  1644 	else
       
  1645 	{
       
  1646 		// if it's not in the suspended list then this is the first time it has been
       
  1647 		// resumed (the process has just been created).  see if there are statically
       
  1648 		// linked libraries that we need to report to the host debugger.  if so, we
       
  1649 		// don't really want to resume yet.  let the host debugger set any breakpoints
       
  1650 		// in the libraries first.  it will call resume again once it's done.
       
  1651 
       
  1652 		// since we never mark it as suspended, we'll actually get here when the host
       
  1653 		// debugger calls resume the second time.  we really don't want to mark it as
       
  1654 		// suspended because then the host debugger will try to draw the thread window
       
  1655 		TBool found = EFalse;
       
  1656 		for (TInt i=0; i<iDebugProcessList.Count(); i++)
       
  1657 		{
       
  1658 			if (iDebugProcessList[i]->ProcessId() == processId)
       
  1659 			{
       
  1660 				found = ETrue;
       
  1661 				// if we're already marked it as ready, just resume and return
       
  1662 				if (iDebugProcessList[i]->iReadyForLibraryLoadNotification)
       
  1663 				{
       
  1664 					User::LeaveIfError(iKernelDriver.ResumeThread(threadId));
       
  1665 					iFramingLayer->RespondOkL(KNullDesC8);		
       
  1666 					return;
       
  1667 				}
       
  1668 
       
  1669 				iDebugProcessList[i]->iReadyForLibraryLoadNotification = ETrue;
       
  1670 				break;
       
  1671 			}
       
  1672 		}
       
  1673 		// For RUN mode, we created the process but we didn't put it into the list
       
  1674 		// therefore we do not want to notify the host debugger about static libraries
       
  1675 		// so just resume and return  (see DoCreateExeL)
       
  1676 		// The host debugger will soon disconnect in this mode
       
  1677 		if (!found)
       
  1678 		{
       
  1679 			User::LeaveIfError(iKernelDriver.ResumeThread(threadId));
       
  1680 			iFramingLayer->RespondOkL(KNullDesC8);		
       
  1681 			return;
       
  1682 		}
       
  1683 
       
  1684 		// the process has been created and the host debugger is listening for messages
       
  1685 		// see if there are any statically linked libraries for this process.  if so, let
       
  1686 		// the host debugger know about them now. note that the host debugger will send
       
  1687 		// another resume command once it's handled the static libraries.  if there are
       
  1688 		// not static libraries for this process, we really do need to resume the thread.
       
  1689 		
       
  1690 		TInt err = KErrNone;
       
  1691 		TInt i = 0;
       
  1692 		for (i=0; KErrNone==err; i++)
       
  1693 		{
       
  1694 			SEventInfo info;
       
  1695 			info.iProcessId = processId;
       
  1696 			info.iThreadId = threadId;
       
  1697 			err = iKernelDriver.GetStaticLibraryInfo(i, info);
       
  1698 			
       
  1699 			if (KErrNone == err)
       
  1700 			{
       
  1701 				DoNotifyLibraryLoadedL(info.iFileName, info.iProcessId, 0xFFFFFFFF, info.iCodeAddress, info.iDataAddress);
       
  1702 			}
       
  1703 			//else if (0 == i)
       
  1704 			//{
       
  1705 				// there are no static libraries for this process
       
  1706 				//User::LeaveIfError(iKernelDriver.ResumeThread(threadId));			
       
  1707 			//}
       
  1708 		}
       
  1709 		//Always resume the thread instead of asking the host debugger to resume when sending the last static library notification.
       
  1710 		User::LeaveIfError(iKernelDriver.ResumeThread(threadId));			
       
  1711 		iFramingLayer->RespondOkL(KNullDesC8);		
       
  1712 	}
       
  1713 }
       
  1714 
       
  1715 //
       
  1716 // CTrkDispatchLayer::DoStepL
       
  1717 //
       
  1718 // Execute one instruction in a thread
       
  1719 //
       
  1720 void CTrkDispatchLayer::DoStepL()
       
  1721 {
       
  1722 	// make sure we're connected
       
  1723 	if (!iIsConnected)
       
  1724 	{
       
  1725 		User::Leave(KErrGeneral);
       
  1726 	}
       
  1727 
       
  1728 	// make sure we got here from DispatchMsgL
       
  1729 	TUint8 command = 0;
       
  1730 	GetDataFromBufferL(&command, 1);
       
  1731 	
       
  1732 	if (kDSStep != command)
       
  1733 		User::Leave(kDSReplyError);
       
  1734 
       
  1735 	// get the options
       
  1736 	TUint8 options = 0;
       
  1737 	GetDataFromBufferL(&options, 1);
       
  1738 	
       
  1739 	// we only support stepping out of a range of instructions
       
  1740 	if ((kDSStepIntoRange != options) && (kDSStepOverRange != options))
       
  1741 	{
       
  1742 		User::Leave(kDSReplyUnsupportedOptionError);
       
  1743 	}
       
  1744 
       
  1745 	// get the range start address
       
  1746 	TUint32 startAddress = 0;
       
  1747 	GetDataFromBufferL(&startAddress, 4);
       
  1748 
       
  1749 	// get the range stop address
       
  1750 	TUint32 stopAddress = 0;
       
  1751 	GetDataFromBufferL(&stopAddress, 4);
       
  1752 		
       
  1753 	// get the process id
       
  1754 	TUint32 processId = 0;
       
  1755 	GetDataFromBufferL(&processId, 4);
       
  1756 
       
  1757 	// get the thread id
       
  1758 	TUint32 threadId = 0;
       
  1759 	GetDataFromBufferL(&threadId, 4);
       
  1760 
       
  1761 	User::LeaveIfError(iKernelDriver.StepRange(threadId, startAddress, stopAddress, (kDSStepIntoRange == options)));
       
  1762 
       
  1763 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1764 }
       
  1765 
       
  1766 //
       
  1767 // CTrkDispatchLayer::DoStopL
       
  1768 //
       
  1769 // Stop the execution of a thread
       
  1770 //
       
  1771 void CTrkDispatchLayer::DoStopL()
       
  1772 {
       
  1773 	// make sure we're connected
       
  1774 	if (!iIsConnected)
       
  1775 	{
       
  1776 		User::Leave(KErrGeneral);
       
  1777 	}
       
  1778 
       
  1779 	// make sure we got here from DispatchMsgL
       
  1780 	TUint8 command = 0;
       
  1781 	GetDataFromBufferL(&command, 1);
       
  1782 	
       
  1783 	if (kDSStop != command)
       
  1784 		User::Leave(kDSReplyError);
       
  1785 
       
  1786 	// get the options
       
  1787 	TUint8 options = 0;
       
  1788 	GetDataFromBufferL(&options, 1);
       
  1789 	
       
  1790 	TUint32 processId = 0;
       
  1791 	TUint32 threadId = 0;
       
  1792 	
       
  1793 	switch(options)
       
  1794 	{
       
  1795 		case kDSStopThread:
       
  1796 		{
       
  1797 			// get the process id
       
  1798 			GetDataFromBufferL(&processId, 4);
       
  1799 
       
  1800 			// get the thread id
       
  1801 			GetDataFromBufferL(&threadId, 4);
       
  1802 			
       
  1803 			User::LeaveIfError(iKernelDriver.SuspendThread(threadId));
       
  1804 			
       
  1805 			break;
       
  1806 		}
       
  1807 		case kDSStopSystem:
       
  1808 		case kDSStopProcess:
       
  1809 		default:
       
  1810 		{
       
  1811 			User::Leave(kDSReplyUnsupportedOptionError);
       
  1812 			break;
       
  1813 		}
       
  1814 	}
       
  1815 
       
  1816 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1817 	
       
  1818 	TBuf8<4> currentPC;
       
  1819 	
       
  1820 	User::LeaveIfError(iKernelDriver.ReadRegisters(threadId, 15, 15, currentPC));
       
  1821 	
       
  1822 	DoNotifyStoppedL(processId, threadId, *(TUint32 *)currentPC.Ptr(), KNullDesC8);
       
  1823 }
       
  1824 
       
  1825 //
       
  1826 // CTrkDispatchLayer::DoSetBreakL
       
  1827 //
       
  1828 // Set a breakpoint
       
  1829 //
       
  1830 void CTrkDispatchLayer::DoSetBreakL()
       
  1831 {
       
  1832 	// make sure we're connected
       
  1833 	if (!iIsConnected)
       
  1834 	{
       
  1835 		User::Leave(KErrGeneral);
       
  1836 	}
       
  1837 
       
  1838 	// make sure we got here from DispatchMsgL
       
  1839 	TUint8 command = 0;
       
  1840 	GetDataFromBufferL(&command, 1);
       
  1841 	
       
  1842 	if (kDSSetBreak != command)
       
  1843 		User::Leave(kDSReplyError);
       
  1844 
       
  1845 	// get the options - unused
       
  1846 	TUint8 options = 0;
       
  1847 	GetDataFromBufferL(&options, 1);
       
  1848 
       
  1849 	// get the mode
       
  1850 	TUint8 thumbMode = 0;
       
  1851 	GetDataFromBufferL(&thumbMode, 1);
       
  1852 
       
  1853 	// get the address
       
  1854 	TUint32 address = 0;
       
  1855 	GetDataFromBufferL(&address, 4);
       
  1856 
       
  1857 	// get the length
       
  1858 	TUint32 length = 0;
       
  1859 	GetDataFromBufferL(&length, 4);
       
  1860 
       
  1861 	// get the count
       
  1862 	TUint32 count = 0;
       
  1863 	GetDataFromBufferL(&count, 4);
       
  1864 
       
  1865 	// get the process id
       
  1866 	TUint32 processId = 0;
       
  1867 	GetDataFromBufferL(&processId, 4);
       
  1868 
       
  1869 	// get the thread id
       
  1870 	TUint32 threadId = 0;
       
  1871 	GetDataFromBufferL(&threadId, 4);
       
  1872 	
       
  1873 	TInt32 breakId = 0;
       
  1874 	User::LeaveIfError(iKernelDriver.SetBreak(processId, threadId, address, thumbMode, breakId));
       
  1875 
       
  1876 	// return the id of this breakpoint to the host debugger
       
  1877 	AddToReplyBufferL((TUint32)breakId, true);
       
  1878 	
       
  1879 	RespondOkL();
       
  1880 }
       
  1881 
       
  1882 //
       
  1883 // CTrkDispatchLayer::DoClearBreakL
       
  1884 //
       
  1885 // Clear a breakpoint
       
  1886 //
       
  1887 void CTrkDispatchLayer::DoClearBreakL()
       
  1888 {
       
  1889 	// make sure we're connected
       
  1890 	if (!iIsConnected)
       
  1891 	{
       
  1892 		User::Leave(KErrGeneral);
       
  1893 	}
       
  1894 
       
  1895 	// make sure we got here from DispatchMsgL
       
  1896 	TUint8 command = 0;
       
  1897 	GetDataFromBufferL(&command, 1);
       
  1898 
       
  1899 	if (kDSClearBreak != command)
       
  1900 		User::Leave(kDSReplyError);
       
  1901 
       
  1902 	// get the breakpoint id
       
  1903 	TUint32 breakId = 0;
       
  1904 	GetDataFromBufferL(&breakId, 4);
       
  1905 
       
  1906 	User::LeaveIfError(iKernelDriver.ClearBreak(breakId));
       
  1907 
       
  1908 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1909 }
       
  1910 
       
  1911 //
       
  1912 // CTrkDispatchLayer::DoModifyBreakThreadL
       
  1913 //
       
  1914 // Change the thread(s) that a breakpoint is associated with
       
  1915 //
       
  1916 void CTrkDispatchLayer::DoModifyBreakThreadL()
       
  1917 {
       
  1918 	// make sure we're connected
       
  1919 	if (!iIsConnected)
       
  1920 	{
       
  1921 		User::Leave(KErrGeneral);
       
  1922 	}
       
  1923 
       
  1924 	// make sure we got here from DispatchMsgL
       
  1925 	TUint8 command = 0;
       
  1926 	GetDataFromBufferL(&command, 1);
       
  1927 
       
  1928 	if (kDSModifyBreakThread != command)
       
  1929 		User::Leave(kDSReplyError);
       
  1930 
       
  1931 	// get the breakpoint id
       
  1932 	TUint32 breakId = 0;
       
  1933 	GetDataFromBufferL(&breakId, 4);
       
  1934 
       
  1935 	// get the thread id
       
  1936 	TUint32 threadId = 0;
       
  1937 	GetDataFromBufferL(&threadId, 4);
       
  1938 
       
  1939 	User::LeaveIfError(iKernelDriver.ChangeBreakThread(threadId, breakId));
       
  1940 
       
  1941 	iFramingLayer->RespondOkL(KNullDesC8);
       
  1942 }
       
  1943 
       
  1944 //
       
  1945 // CTrkDispatchLayer::DoCreateItemL
       
  1946 //
       
  1947 // Create a new OS item on the target device
       
  1948 //
       
  1949 void CTrkDispatchLayer::DoCreateItemL()
       
  1950 {
       
  1951 	// make sure we're connected
       
  1952 	if (!iIsConnected)
       
  1953 	{
       
  1954 		User::Leave(KErrGeneral);
       
  1955 	}
       
  1956 
       
  1957 	// make sure we got here from DispatchMsgL
       
  1958 	TUint8 command = 0;
       
  1959 	GetDataFromBufferL(&command, 1);
       
  1960 	
       
  1961 	if (kDSOSCreateItem != command)
       
  1962 		User::Leave(kDSReplyError);
       
  1963 
       
  1964 	// get the item type
       
  1965 	TUint16 type = 0;
       
  1966 	GetDataFromBufferL(&type, 2);
       
  1967 
       
  1968 	switch(type)
       
  1969 	{
       
  1970 		case kDSOSProcessItem:
       
  1971 		{
       
  1972 			DoCreateProcessL();
       
  1973 			break;
       
  1974 		}
       
  1975 		case kDSOSProcRunItem:
       
  1976 		{
       
  1977 			DoCreateProcessL(ETrue);
       
  1978 			break;
       
  1979 		}
       
  1980 		case kDSOSProcAttachItem:
       
  1981 		{
       
  1982 			DoAttachProcessL(kDSOSProcAttachItem);
       
  1983 			break;
       
  1984 		}
       
  1985 		case kDSOSProcAttach2Item:
       
  1986 		{
       
  1987 			DoAttachProcessL(kDSOSProcAttach2Item);
       
  1988 			break;
       
  1989 		}
       
  1990 		case kDSOSProcAttach3Item:
       
  1991 		{
       
  1992 			DoAttachProcessL(kDSOSProcAttach3Item);
       
  1993 			break;
       
  1994 		}
       
  1995 		case kDSOSThreadItem:
       
  1996 		case kDSOSDLLItem:
       
  1997 		case kDSOSAppItem:
       
  1998 		case kDSOSMemBlockItem:
       
  1999 		case kDSOSThreadAttachItem:
       
  2000 		default:
       
  2001 		{
       
  2002 			User::Leave(kDSReplyUnsupportedOptionError);
       
  2003 			break;
       
  2004 		}
       
  2005 	}
       
  2006 }
       
  2007 
       
  2008 //
       
  2009 // CTrkDispatchLayer::DoDeleteItemL
       
  2010 //
       
  2011 // Delete an OS item from the target device
       
  2012 //
       
  2013 void CTrkDispatchLayer::DoDeleteItemL()
       
  2014 {
       
  2015 	// make sure we're connected
       
  2016 	if (!iIsConnected)
       
  2017 	{
       
  2018 		User::Leave(KErrGeneral);
       
  2019 	}
       
  2020 
       
  2021 	// make sure we got here from DispatchMsgL
       
  2022 	TUint8 command = 0;
       
  2023 	GetDataFromBufferL(&command, 1);
       
  2024 	
       
  2025 	if (kDSOSDeleteItem != command)
       
  2026 		User::Leave(kDSReplyError);
       
  2027 
       
  2028 	// get the item type
       
  2029 	TUint16 type = 0;
       
  2030 	GetDataFromBufferL(&type, 2);
       
  2031 
       
  2032 	switch(type)
       
  2033 	{
       
  2034 		case kDSOSProcessItem:
       
  2035 		{
       
  2036 			DoKillProcessL();
       
  2037 			break;
       
  2038 		}
       
  2039 		case kDSOSProcAttachItem:
       
  2040 		{
       
  2041 		    DoDetachProcessL();
       
  2042 			break;
       
  2043 		}
       
  2044 		case kDSOSThreadItem:
       
  2045 		case kDSOSDLLItem:
       
  2046 		case kDSOSAppItem:
       
  2047 		case kDSOSMemBlockItem:
       
  2048 		case kDSOSThreadAttachItem:
       
  2049 		default:
       
  2050 		{
       
  2051 			User::Leave(kDSReplyUnsupportedOptionError);
       
  2052 			break;
       
  2053 		}
       
  2054 	}
       
  2055 }
       
  2056 
       
  2057 //
       
  2058 // CTrkDispatchLayer::DoReadInfoL
       
  2059 //
       
  2060 // Read OS information from the target device
       
  2061 //
       
  2062 void CTrkDispatchLayer::DoReadInfoL()
       
  2063 {	
       
  2064 	// make sure we're connected
       
  2065 	if (!iIsConnected)
       
  2066 	{
       
  2067 		User::Leave(KErrGeneral);
       
  2068 	}
       
  2069 
       
  2070 	// make sure we got here from DispatchMsgL
       
  2071 	TUint8 command = 0;
       
  2072 	GetDataFromBufferL(&command, 1);
       
  2073 
       
  2074 	if (kDSOSReadInfo != command)
       
  2075 		User::Leave(kDSReplyError);
       
  2076 
       
  2077 	// get the type of info requested
       
  2078 	TUint16 type = 0;
       
  2079 	GetDataFromBufferL(&type, 2);
       
  2080 
       
  2081 	// get the start index
       
  2082 	TUint32 index = 0;
       
  2083 	GetDataFromBufferL(&index, 4);	
       
  2084 	
       
  2085 	switch(type)
       
  2086 	{
       
  2087 		case kDSOSProcessList:
       
  2088 		{
       
  2089 			DoReadProcessListL(index);
       
  2090 			break;
       
  2091 		}
       
  2092 		case kDSOSThreadList:
       
  2093 		{
       
  2094 			DoReadThreadListL(index);
       
  2095 			break;
       
  2096 		}
       
  2097 		case kDSOSDLLInfo:
       
  2098 		{
       
  2099 			TUint16 nameLength = 0;
       
  2100 			GetDataFromBufferL(&nameLength, 2);
       
  2101 			
       
  2102 			// make sure the length of the message is correct
       
  2103 			if (iInputBuffer->Length() != nameLength)
       
  2104 				User::Leave(kDSReplyPacketSizeError);
       
  2105 			
       
  2106 			TBuf8<KMaxFileName> fileName;
       
  2107 			fileName.Copy(*iInputBuffer);
       
  2108 			fileName.ZeroTerminate();
       
  2109 
       
  2110 			DoReadLibraryInfoL(fileName);
       
  2111 			break;
       
  2112 		}
       
  2113 		case kDSOSProcessInfo:
       
  2114 		{
       
  2115 			TUint32 uid3 = 0;
       
  2116 			GetDataFromBufferL(&uid3, 4);
       
  2117 			TUint16 nameLength = 0;
       
  2118 			GetDataFromBufferL(&nameLength, 2);
       
  2119 			
       
  2120 			// make sure the length of the message is correct
       
  2121 			if (iInputBuffer->Length() != nameLength)
       
  2122 				User::Leave(kDSReplyPacketSizeError);
       
  2123 			
       
  2124 			TBuf8<KMaxFileName> fileName;
       
  2125 			fileName.Copy(*iInputBuffer);
       
  2126 			fileName.ZeroTerminate();
       
  2127 			
       
  2128 			DoReadProcessInfoL(uid3, fileName);
       
  2129 			break;
       
  2130 		}
       
  2131 		case kDSOSProcessState:
       
  2132 		case kDSOSThreadState:
       
  2133 		case kDSOSDLLList:
       
  2134 		case kDSOSDLLState:
       
  2135 		default:
       
  2136 		{
       
  2137 			User::Leave(kDSReplyUnsupportedOptionError);
       
  2138 			break;
       
  2139 		}
       
  2140 	}
       
  2141 }
       
  2142 
       
  2143 //
       
  2144 // CTrkDispatchLayer::DoWriteInfoL
       
  2145 //
       
  2146 // Set options for the Trk
       
  2147 //
       
  2148 void CTrkDispatchLayer::DoWriteInfoL()
       
  2149 {
       
  2150 	// make sure we got here from DispatchMsgL
       
  2151 	TUint8 command = 0;
       
  2152 	GetDataFromBufferL(&command, 1);
       
  2153 
       
  2154 	if (kDSOSWriteInfo != command)
       
  2155 		User::Leave(kDSReplyError);
       
  2156 
       
  2157 	// get the type of info requested
       
  2158 	TUint16 type = 0;
       
  2159 	GetDataFromBufferL(&type, 2);
       
  2160 
       
  2161 	// get the start index
       
  2162 	TUint32 index = 0;
       
  2163 	GetDataFromBufferL(&index, 4);
       
  2164 
       
  2165 	// no options supported yet.  might add something for auto-target libraries later
       
  2166 	User::Leave(kDSReplyUnsupportedOptionError);
       
  2167 }
       
  2168 
       
  2169 //
       
  2170 // CTrkDispatchLayer::DoOpenFileL
       
  2171 //
       
  2172 // Open or create a file on the target
       
  2173 //
       
  2174 void CTrkDispatchLayer::DoOpenFileL()
       
  2175 {
       
  2176 	// make sure we got here from DispatchMsgL
       
  2177 	TUint8 command = 0;
       
  2178 	GetDataFromBufferL(&command, 1);
       
  2179 	
       
  2180 	if (kDSOSOpenFile != command)
       
  2181 		User::Leave(kDSReplyError);
       
  2182 
       
  2183 	// get the file mode(s)
       
  2184 	TUint8 modes = 0;
       
  2185 	GetDataFromBufferL(&modes, 1);
       
  2186 
       
  2187 	if ((modes & kDSFileOpenAppend) || (modes & kDSFileOpenCreate))
       
  2188 		modes |= kDSFileOpenWrite;
       
  2189 
       
  2190 	TUint16 nameLength = 0;
       
  2191 	GetDataFromBufferL(&nameLength, 2);
       
  2192 	
       
  2193 	// make sure the length of the message is correct
       
  2194 	if (iInputBuffer->Length() != nameLength)
       
  2195 		User::Leave(kDSReplyPacketSizeError);
       
  2196 	
       
  2197 	TBuf<KMaxPath> fullpath;
       
  2198 	fullpath.Copy(*iInputBuffer);
       
  2199 	fullpath.ZeroTerminate();
       
  2200 		
       
  2201 	TUint mode = EFileShareExclusive;
       
  2202 
       
  2203 	// get the file mode(s)
       
  2204 	if (modes & kDSFileOpenRead)
       
  2205 		mode |= EFileRead;
       
  2206 
       
  2207 	if (modes & kDSFileOpenWrite)
       
  2208 		mode |= EFileWrite;
       
  2209 
       
  2210 	if (modes & kDSFileOpenAppend)
       
  2211 		mode |= EFileWrite;
       
  2212 
       
  2213 	if (modes & kDSFileOpenCreate)
       
  2214 		mode |= EFileWrite;
       
  2215 	
       
  2216 
       
  2217 	//for getting the modification date
       
  2218 	TTime time;
       
  2219 	
       
  2220 	OpenFileL(fullpath, mode, time);
       
  2221 	
       
  2222 	TDateTime dateTime = time.DateTime();
       
  2223 
       
  2224 	TDateTimeConverter winTime(dateTime);
       
  2225 	
       
  2226 	TUint32 timestamp = winTime.GetWinTimeDate();
       
  2227 
       
  2228 	TUint32 handle = 1;
       
  2229 	TUint8 err = 0;
       
  2230 
       
  2231 	AddToReplyBufferL(err, true);
       
  2232 	AddToReplyBufferL(handle);
       
  2233 	AddToReplyBufferL(timestamp);
       
  2234 	
       
  2235 	RespondOkL();
       
  2236 }
       
  2237 
       
  2238 //
       
  2239 // CTrkDispatchLayer::OpenFileL
       
  2240 //
       
  2241 // Open a file on the target, if plat security is enabled, uses TrkTcbServer to open the file.
       
  2242 //
       
  2243 void CTrkDispatchLayer::OpenFileL(const TDesC& aFullPath, TUint aMode, TTime& aTime)
       
  2244 {
       
  2245 
       
  2246 #ifdef __OEM_TRK__	
       
  2247 	//Check to see if TCB capability is enforced, if so, connect to the tcb server as well.
       
  2248 	if (!iUseTcbServer && PlatSec::IsCapabilityEnforced(ECapabilityTCB))
       
  2249 	{
       
  2250 		if (!iTrkTcbSession.Connect())
       
  2251 		{
       
  2252 			iUseTcbServer = ETrue;
       
  2253 		}	
       
  2254 	}
       
  2255 
       
  2256 	if (iUseTcbServer)
       
  2257 	{
       
  2258 		User::LeaveIfError(iTrkTcbSession.OpenFile(aFullPath, aMode, aTime));
       
  2259 	}
       
  2260 	else
       
  2261 #endif	
       
  2262 	{
       
  2263 	#ifndef __OEM_TRK__
       
  2264 		if (IsRestrictedFolder(aFullPath))
       
  2265 			User::Leave(KErrAccessDenied);
       
  2266 	#endif
       
  2267 		// connect to the file server
       
  2268 		User::LeaveIfError(iFs.Connect());
       
  2269 
       
  2270 		TInt error = iFs.MkDirAll(aFullPath);
       
  2271 
       
  2272 		if ((KErrNone != error) && (KErrAlreadyExists != error))
       
  2273 		{
       
  2274 			iFs.Close();
       
  2275 			User::Leave(error);
       
  2276 		}
       
  2277 		
       
  2278 		error = iFile.Open(iFs, aFullPath, aMode);
       
  2279 		
       
  2280 		if (KErrNone != error)
       
  2281 			User::LeaveIfError(iFile.Replace(iFs, aFullPath, aMode));
       
  2282 		
       
  2283 		User::LeaveIfError(iFile.Modified(aTime));
       
  2284 		iFileState = EFileOpened;
       
  2285 	}
       
  2286 }
       
  2287 
       
  2288 //
       
  2289 // CTrkDispatchLayer::DoReadFileL
       
  2290 //
       
  2291 // Read data from a file on the target
       
  2292 //
       
  2293 void CTrkDispatchLayer::DoReadFileL()
       
  2294 {
       
  2295 	// make sure we got here from DispatchMsgL
       
  2296 	TUint8 command = 0;
       
  2297 	GetDataFromBufferL(&command, 1);
       
  2298 	
       
  2299 	if (kDSOSReadFile != command)
       
  2300 		User::Leave(kDSReplyError);
       
  2301 
       
  2302 	// make sure the length of the message is correct
       
  2303 	if (iInputBuffer->Length() != 6)
       
  2304 		User::Leave(kDSReplyPacketSizeError);
       
  2305 	
       
  2306 	// remove the handle
       
  2307 	iInputBuffer->Des().Delete(0, 4);
       
  2308 
       
  2309 	// get the length
       
  2310 	TUint8 err = 0;
       
  2311 	TUint16 length = 0;
       
  2312 	GetDataFromBufferL(&length, 2);
       
  2313 	
       
  2314 	// allocate a buffer large enough for the data
       
  2315 	HBufC8 *buffer = HBufC8::NewLC(length);
       
  2316 	TPtr8 ptr(buffer->Des());
       
  2317 	
       
  2318 	//	CleanupStack::PushL(buffer);
       
  2319 	
       
  2320 	TInt error = ReadFileL(length, ptr);	
       
  2321 	if (KErrNone != error)
       
  2322 	{
       
  2323 		CleanupStack::PopAndDestroy(buffer);	
       
  2324 		User::Leave(error);
       
  2325 	}
       
  2326 	
       
  2327 	length = buffer->Length();
       
  2328 	
       
  2329 	AddToReplyBufferL(err, true);
       
  2330 	AddToReplyBufferL(length);
       
  2331 //	AddToReplyBufferL(buffer[0], length);
       
  2332 	AddToReplyBufferL(ptr);
       
  2333 	RespondOkL();
       
  2334 	
       
  2335 	CleanupStack::PopAndDestroy(buffer);
       
  2336 }
       
  2337 
       
  2338 //
       
  2339 // CTrkDispatchLayer::ReadFileL
       
  2340 //
       
  2341 // Reads data from a file on the target
       
  2342 //
       
  2343 TInt CTrkDispatchLayer::ReadFileL(TUint16 aLength, TPtr8& aData)
       
  2344 {
       
  2345 	TInt error = KErrNone;
       
  2346 
       
  2347 #ifdef __OEM_TRK__
       
  2348 	if (iUseTcbServer)
       
  2349 	{
       
  2350 		User::LeaveIfError(iTrkTcbSession.ReadFile(aLength, aData));
       
  2351 	}
       
  2352 	else
       
  2353 #endif	
       
  2354 	{
       
  2355 		iFileState = EFileReading;
       
  2356 		error = iFile.Read(aData);
       
  2357 	}
       
  2358 	return error;
       
  2359 }
       
  2360 
       
  2361 //
       
  2362 // CTrkDispatchLayer::DoWriteFileL
       
  2363 //
       
  2364 // Write data to a file on the target
       
  2365 //
       
  2366 void CTrkDispatchLayer::DoWriteFileL()
       
  2367 {
       
  2368 	// make sure we got here from DispatchMsgL
       
  2369 	TUint8 command = 0;
       
  2370 	GetDataFromBufferL(&command, 1);
       
  2371 	
       
  2372 	if (kDSOSWriteFile != command)
       
  2373 		User::Leave(kDSReplyError);
       
  2374 	
       
  2375 	// get the length
       
  2376 	TUint32 handle = 0;
       
  2377 	GetDataFromBufferL(&handle, 4);
       
  2378 	
       
  2379 	if (handle != 1)
       
  2380 		User::Leave(kDSReplyParameterError);
       
  2381 
       
  2382 	// get the length
       
  2383 	TUint8 err = 0;
       
  2384 	TUint16 length = 0;
       
  2385 	GetDataFromBufferL(&length, 2);
       
  2386 
       
  2387 	// make sure the length of the message is correct
       
  2388 	if (iInputBuffer->Length() != length)
       
  2389 		User::Leave(kDSReplyPacketSizeError);
       
  2390 		
       
  2391 	WriteFileL(*iInputBuffer);
       
  2392 	
       
  2393 	length = iInputBuffer->Length();
       
  2394 	
       
  2395 	AddToReplyBufferL(err, true);
       
  2396 	AddToReplyBufferL(length);
       
  2397 	RespondOkL();
       
  2398 }
       
  2399 
       
  2400 //
       
  2401 // CTrkDispatchLayer::WriteFileL
       
  2402 //
       
  2403 // Write data to a file on the target. If plat sec is enabled, uses Trk Tcb Server.
       
  2404 //
       
  2405 void CTrkDispatchLayer::WriteFileL(TDesC8& aData)
       
  2406 {
       
  2407 #ifdef __OEM_TRK__
       
  2408 	if (iUseTcbServer)
       
  2409 	{
       
  2410 		User::LeaveIfError(iTrkTcbSession.WriteFile(aData));
       
  2411 	}
       
  2412 	else
       
  2413 #endif	
       
  2414 	{	
       
  2415 		if (iFileState == EFileOpened)
       
  2416 		{
       
  2417 			iFile.SetSize(0);
       
  2418 			iFileState = EFileWriting;
       
  2419 		}
       
  2420 		User::LeaveIfError(iFile.Write(aData));
       
  2421 		User::LeaveIfError(iFile.Flush());
       
  2422 	}
       
  2423 }
       
  2424 
       
  2425 //
       
  2426 // CTrkDispatchLayer::DoPositionFileL
       
  2427 //
       
  2428 // Change the current file position of a file on the target
       
  2429 //
       
  2430 void CTrkDispatchLayer::DoPositionFileL()
       
  2431 {
       
  2432 	// make sure we got here from DispatchMsgL
       
  2433 	TUint8 command = 0;
       
  2434 	GetDataFromBufferL(&command, 1);
       
  2435 	
       
  2436 	if (kDSOSPositionFile != command)
       
  2437 		User::Leave(kDSReplyError);
       
  2438 
       
  2439 	// make sure the length of the message is correct
       
  2440 	if (iInputBuffer->Length() != 9)
       
  2441 		User::Leave(kDSReplyPacketSizeError);
       
  2442 	
       
  2443 	// get the positioning mode
       
  2444 	TUint8 mode = 0;
       
  2445 	GetDataFromBufferL(&mode, 1);
       
  2446 
       
  2447 	// remove the handle
       
  2448 	iInputBuffer->Des().Delete(0, 4);
       
  2449 
       
  2450 	TUint8 err = 0;
       
  2451 	TUint32 offset = 0;
       
  2452 	GetDataFromBufferL(&offset, 4);
       
  2453 
       
  2454 	TSeek seek;
       
  2455 	
       
  2456 	// convert mode to native parameter and set the position accordingly
       
  2457 	switch(mode)
       
  2458 	{
       
  2459 		default:
       
  2460 		case kDSFileSeekSet:
       
  2461 		{
       
  2462 			seek = ESeekStart;
       
  2463 			break;
       
  2464 		}
       
  2465 		case kDSFileSeekCur:
       
  2466 		{
       
  2467 			seek = ESeekCurrent;
       
  2468 			break;
       
  2469 		}
       
  2470 		case kDSFileSeekEnd:
       
  2471 		{
       
  2472 			seek = ESeekEnd;
       
  2473 			break;
       
  2474 		}
       
  2475 	}
       
  2476 
       
  2477 	PositionFileL(seek, (TInt &)offset);
       
  2478 
       
  2479 	AddToReplyBufferL(err, true);
       
  2480 	
       
  2481 	RespondOkL();
       
  2482 }
       
  2483 
       
  2484 //
       
  2485 // CTrkDispatchLayer::PositionFileL
       
  2486 //
       
  2487 // Change the current file position of a file on the target. If plat sec is enabled,
       
  2488 // uses Trk Tcb Server.
       
  2489 //
       
  2490 void CTrkDispatchLayer::PositionFileL(TSeek aSeek, TInt& aOffset)
       
  2491 {
       
  2492 #ifdef __OEM_TRK__
       
  2493 	if (iUseTcbServer)
       
  2494 	{
       
  2495 		User::LeaveIfError(iTrkTcbSession.PositionFile(aSeek, aOffset));
       
  2496 	}
       
  2497 	else
       
  2498 #endif	
       
  2499 	{
       
  2500 		User::LeaveIfError(iFile.Seek(aSeek, aOffset));
       
  2501 	}
       
  2502 }
       
  2503 
       
  2504 
       
  2505 //
       
  2506 // CTrkDispatchLayer::DoCloseFileL
       
  2507 //
       
  2508 // Close a file on the target
       
  2509 //
       
  2510 void CTrkDispatchLayer::DoCloseFileL()
       
  2511 {
       
  2512 	// make sure we got here from DispatchMsgL
       
  2513 	TUint8 command = 0;
       
  2514 	GetDataFromBufferL(&command, 1);
       
  2515 	
       
  2516 	if (kDSOSCloseFile != command)
       
  2517 		User::Leave(kDSReplyError);
       
  2518 
       
  2519 	// make sure the length of the message is correct
       
  2520 	if (iInputBuffer->Length() != 8)
       
  2521 		User::Leave(kDSReplyPacketSizeError);
       
  2522 
       
  2523 	// remove the handle
       
  2524 	iInputBuffer->Des().Delete(0, 4);
       
  2525 	
       
  2526 	TUint8 err = 0;
       
  2527 	TUint32 timestamp = 0;
       
  2528 	GetDataFromBufferL(&timestamp, 4);
       
  2529 	
       
  2530 	TDateTimeConverter epocTime(timestamp);
       
  2531 	
       
  2532 	CloseFileL(epocTime.GetEpocTimeDate());
       
  2533 
       
  2534 	AddToReplyBufferL(err, true);
       
  2535 
       
  2536 	RespondOkL();
       
  2537 }
       
  2538 
       
  2539 //
       
  2540 // CTrkDispatchLayer::CloseFileL
       
  2541 //
       
  2542 // Close a file on the target. If plat sec is enabled, uses Trk Tcb Server.
       
  2543 //
       
  2544 void CTrkDispatchLayer::CloseFileL(const TTime& aModifiedTime)
       
  2545 {
       
  2546 #ifdef __OEM_TRK__
       
  2547 	if (iUseTcbServer)
       
  2548 	{
       
  2549 		User::LeaveIfError(iTrkTcbSession.CloseFile(aModifiedTime));
       
  2550 	}
       
  2551 	else
       
  2552 #endif	
       
  2553 	{
       
  2554 		User::LeaveIfError(iFile.SetModified(aModifiedTime));
       
  2555 		User::LeaveIfError(iFile.Flush());
       
  2556 		
       
  2557 		iFile.Close();
       
  2558 		iFs.Close();
       
  2559 		iFileState = EFileClosed;
       
  2560 	}
       
  2561 }
       
  2562 
       
  2563 //
       
  2564 // CTrkDispatchLayer::DoInstallFileL
       
  2565 //
       
  2566 // Install the application, supplied as a SIS file.
       
  2567 //
       
  2568 void CTrkDispatchLayer::DoInstallFileL()
       
  2569 {
       
  2570 	// make sure we're connected
       
  2571 	if (!iIsConnected)
       
  2572 	{
       
  2573 		User::Leave(KErrGeneral);
       
  2574 	}
       
  2575 
       
  2576 #ifndef __TEXT_SHELL__
       
  2577 	// make sure we got here from DispatchMsgL
       
  2578 	TUint8 command = 0;
       
  2579 	GetDataFromBufferL(&command, 1);
       
  2580 	
       
  2581 	if (kDSOSInstallFile != command)
       
  2582 		User::Leave(kDSReplyError);
       
  2583 
       
  2584 	// get the installation drive
       
  2585 	TUint8 drive = 'C';
       
  2586 	GetDataFromBufferL(&drive, 1);
       
  2587 	
       
  2588 	TChar installDrive(drive);
       
  2589 
       
  2590 	TUint16 nameLength = 0;
       
  2591 	GetDataFromBufferL(&nameLength, 2);
       
  2592 	
       
  2593 	// make sure the length of the message is correct
       
  2594 	if (iInputBuffer->Length() != nameLength)
       
  2595 		User::Leave(kDSReplyPacketSizeError);
       
  2596 	
       
  2597 	TBuf<KMaxPath> fullpath;
       
  2598 	fullpath.Copy(*iInputBuffer);
       
  2599 	fullpath.ZeroTerminate();
       
  2600 			
       
  2601 	TUint8 err = 0;
       
  2602 	// Temporarily disable the lib loaded event before launching the SW Installer.
       
  2603 	// This is necessary when launching the SIS installer since  launching the 
       
  2604 	// installer causes several libraries to be loaded. The driver suspends the 
       
  2605 	// thread thats loaded the library. This suspension might potentially cause 
       
  2606 	// a deadlock as the event handling active object will never get a chance to 
       
  2607 	// run as the Install function below blocks until the installation is completed.
       
  2608 	User::LeaveIfError(iKernelDriver.DisableLibLoadedEvent());
       
  2609 	
       
  2610 	// now launch the installer
       
  2611 	User::LeaveIfError(CTrkSwInstall::SilentInstallL(fullpath, installDrive));
       
  2612 
       
  2613 	// now enable the lib loaded event
       
  2614 	iKernelDriver.EnableLibLoadedEvent();
       
  2615 	
       
  2616 	AddToReplyBufferL(err, true);
       
  2617 	RespondOkL();
       
  2618 #else 
       
  2619 	User::LeaveIfError(-1); 
       
  2620 #endif
       
  2621 }
       
  2622 
       
  2623 //
       
  2624 // CTrkDispatchLayer::DoInstallFileL
       
  2625 //
       
  2626 // Install the application, supplied as a SIS file.
       
  2627 //
       
  2628 void CTrkDispatchLayer::DoInstallFile2L()
       
  2629 {
       
  2630 	// make sure we're connected
       
  2631 	if (!iIsConnected)
       
  2632 	{
       
  2633 		User::Leave(KErrGeneral);
       
  2634 	}
       
  2635 
       
  2636 #ifndef __TEXT_SHELL__
       
  2637 	// make sure we got here from DispatchMsgL
       
  2638 	TUint8 command = 0;
       
  2639 	GetDataFromBufferL(&command, 1);
       
  2640 	
       
  2641 	if (kDSOSInstallFile2 != command)
       
  2642 		User::Leave(kDSReplyError);
       
  2643 
       
  2644 	TUint16 nameLength = 0;
       
  2645 	GetDataFromBufferL(&nameLength, 2);
       
  2646 	
       
  2647 	// make sure the length of the message is correct
       
  2648 	if (iInputBuffer->Length() != nameLength)
       
  2649 		User::Leave(kDSReplyPacketSizeError);
       
  2650 	
       
  2651 	TBuf<KMaxPath> fullpath;
       
  2652 	fullpath.Copy(*iInputBuffer);
       
  2653 	fullpath.ZeroTerminate();
       
  2654 			
       
  2655 	TUint8 err = 0;
       
  2656 	// Temporarily disable the lib loaded event before launching the SW Installer.
       
  2657 	// This is necessary when launching the SIS installer since  launching the 
       
  2658 	// installer causes several libraries to be loaded. The driver suspends the 
       
  2659 	// thread thats loaded the library. This suspension might potentially cause 
       
  2660 	// a deadlock as the event handling active object will never get a chance to 
       
  2661 	// run as the Install function below blocks until the installation is completed.
       
  2662 	User::LeaveIfError(iKernelDriver.DisableLibLoadedEvent());
       
  2663 
       
  2664 	// now launch the installer
       
  2665 	User::LeaveIfError(CTrkSwInstall::Install(fullpath));
       
  2666 
       
  2667 	// now enable the lib loaded event
       
  2668 	iKernelDriver.EnableLibLoadedEvent();
       
  2669 	
       
  2670 	AddToReplyBufferL(err);
       
  2671 	RespondOkL();
       
  2672 #else
       
  2673 	User::LeaveIfError(-1);
       
  2674 #endif
       
  2675 }
       
  2676 
       
  2677 
       
  2678 //
       
  2679 // CTrkDispathLayer::DoGetPhoneSWVesionL()
       
  2680 //
       
  2681 // sends  the software version of the phone to reply buffer
       
  2682 //
       
  2683 void CTrkDispatchLayer::DoGetPhoneSWVersionL()
       
  2684 {
       
  2685     // make sure we got here from DispatchMsgL
       
  2686     
       
  2687 	TUint8 command = 0;
       
  2688 	GetDataFromBufferL(&command, 1);
       
  2689 
       
  2690 	if (kDSOSPhoneSWVersion != command)
       
  2691 	{
       
  2692 		User::Leave(kDSReplyError);
       
  2693 	}
       
  2694 #ifndef __TEXT_SHELL__
       
  2695 	if (iPhoneVersion.Size()>0 )
       
  2696 	{
       
  2697 		TUint16 versionNameLength = iPhoneVersion.Length();
       
  2698 		AddToReplyBufferL(versionNameLength, ETrue); 
       
  2699 		AddToReplyBufferL(iPhoneVersion);       
       
  2700 		RespondOkL();
       
  2701 	}
       
  2702 	else
       
  2703 #endif	    
       
  2704 	{
       
  2705 		User::Leave(KErrGeneral);
       
  2706 	}    
       
  2707                 
       
  2708 }
       
  2709 
       
  2710 
       
  2711 //
       
  2712 //CTrkDispathLayer::DoGetPhoneNameL()
       
  2713 //
       
  2714 //sends the phone model name to the reply buffer
       
  2715 //
       
  2716 void CTrkDispatchLayer::DoGetPhoneNameL()
       
  2717 {    
       
  2718     TUint8 command = 0;
       
  2719     GetDataFromBufferL(&command, 1);
       
  2720     
       
  2721     if (kDSOSPhoneName != command)
       
  2722     {
       
  2723     	User::Leave(kDSReplyError);
       
  2724 	}
       
  2725 
       
  2726 #ifndef __TEXT_SHELL__
       
  2727     if (iPhoneNameInfoAvailable)
       
  2728     {
       
  2729      	TUint16 phoneModelLen = iPhoneModel.Length();
       
  2730      	AddToReplyBufferL(phoneModelLen, true);
       
  2731      	AddToReplyBufferL(iPhoneModel);
       
  2732         RespondOkL();
       
  2733     }    
       
  2734     else
       
  2735 #endif
       
  2736     {
       
  2737         User::Leave(KErrGeneral);
       
  2738     }
       
  2739 }
       
  2740 //
       
  2741 //To Update the phone model name 
       
  2742 //
       
  2743 //callback function from the CPhoneInfo
       
  2744 //
       
  2745 void CTrkDispatchLayer::UpdatePhoneNameInfo(TDesC16& aPhoneModel)
       
  2746 {
       
  2747 #ifndef __TEXT_SHELL__
       
  2748     iPhoneModel.Copy(aPhoneModel);
       
  2749     iPhoneNameInfoAvailable = ETrue;    
       
  2750 #endif
       
  2751 }
       
  2752 
       
  2753 //
       
  2754 // CTrkDispatchLayer::DoCreateProcessL
       
  2755 //
       
  2756 // Create a new process on the target device
       
  2757 //
       
  2758 void CTrkDispatchLayer::DoCreateProcessL(TBool aRun)
       
  2759 {
       
  2760 	// remove the options - currently unused
       
  2761 	iInputBuffer->Des().Delete(0, 1);
       
  2762 
       
  2763 	// get the length of the data
       
  2764 	TUint16 length = 0;
       
  2765 	GetDataFromBufferL(&length, 2);
       
  2766 
       
  2767 	// make sure the length of the message is correct
       
  2768 	if (iInputBuffer->Length() != length)
       
  2769 		User::Leave(kDSReplyPacketSizeError);
       
  2770 
       
  2771 	// extract the filename and path, command line args, and working directory
       
  2772 	TPtrC8 exec8(iInputBuffer->Ptr());
       
  2773 	TPtrC8 args8(exec8.Ptr() + exec8.Length() + 1);
       
  2774 		
       
  2775 	// convert the filename and args to unicode descriptors
       
  2776 	HBufC* exec = HBufC::NewLC(exec8.Length());
       
  2777 	exec->Des().Copy(exec8);
       
  2778 
       
  2779 	HBufC* args = HBufC::NewLC(args8.Length());
       
  2780 	args->Des().Copy(args8);
       
  2781 
       
  2782 	// open the file and get the type (app, exe, etc.)
       
  2783 	RFs fs;
       
  2784 	
       
  2785 	// connect to the file server
       
  2786 	User::LeaveIfError(fs.Connect());
       
  2787 	
       
  2788 	TEntry entry;
       
  2789 		
       
  2790 	User::LeaveIfError(fs.Entry(*exec, entry));
       
  2791 	
       
  2792 	fs.Close();
       
  2793 
       
  2794 	TCreateProcessData data;
       
  2795 		
       
  2796 	switch(entry[0].iUid)
       
  2797 	{
       
  2798 		case 0x1000007a:
       
  2799 		{
       
  2800 			// EXE
       
  2801 			DoCreateExeL(*exec, *args, data, aRun);
       
  2802 			break;
       
  2803 		}
       
  2804 		default:
       
  2805 			User::Leave(KErrGeneral);
       
  2806 	}
       
  2807 
       
  2808 	CleanupStack::PopAndDestroy(args);
       
  2809 	CleanupStack::PopAndDestroy(exec);
       
  2810 
       
  2811 	AddToReplyBufferL(data.iProcessId, true);
       
  2812 	AddToReplyBufferL(data.iMainThreadId);
       
  2813 	if (!aRun)
       
  2814 	{
       
  2815 		AddToReplyBufferL(data.iCodeAddr);
       
  2816 		AddToReplyBufferL(data.iDataAddr);
       
  2817 	}
       
  2818 		
       
  2819 	RespondOkL();
       
  2820 }
       
  2821 
       
  2822 //
       
  2823 // CTrkDispatchLayer::DoCreateExeL
       
  2824 //
       
  2825 // Create a new executable on the target device
       
  2826 //
       
  2827 void CTrkDispatchLayer::DoCreateExeL(const TDesC& aPath, const TDesC& aArgs, TCreateProcessData& aData, TBool aRun)
       
  2828 {
       
  2829 	RProcess process;
       
  2830 	User::LeaveIfError(process.Create(aPath, aArgs));
       
  2831 	CleanupClosePushL(process);
       
  2832 
       
  2833 	aData.iProcessId = process.Id();
       
  2834 	
       
  2835 	HBufC* threadName = HBufC::NewLC(KMaxFullName);
       
  2836 
       
  2837 	*threadName = process.Name();
       
  2838 	_LIT(KMainThreadSuffix, "::Main");
       
  2839 	threadName->Des().Append(KMainThreadSuffix);
       
  2840 
       
  2841 	// this function should be (indirectly) called when the debuggee
       
  2842 	// has been created but not yet resumed.  So it should have a main
       
  2843 	// thread whose name ends with "::Main", and so the following call
       
  2844 	// should not fail.
       
  2845 	RThread thread;
       
  2846 	User::LeaveIfError(thread.Open(*threadName));
       
  2847 		
       
  2848 	aData.iMainThreadId = thread.Id();
       
  2849 	thread.Close();
       
  2850 
       
  2851 	if (!aRun)
       
  2852 	{
       
  2853 		CDebugProcess *proc = CDebugProcess::NewL(this, aData.iProcessId, aData.iMainThreadId);
       
  2854 		iDebugProcessList.Append(proc);
       
  2855 
       
  2856 		User::LeaveIfError(iKernelDriver.GetProcessAddresses(aData.iMainThreadId, aData.iCodeAddr, aData.iDataAddr));
       
  2857 	}
       
  2858 		
       
  2859 	CleanupStack::PopAndDestroy(threadName);
       
  2860 	CleanupStack::PopAndDestroy(); // process
       
  2861 }
       
  2862 
       
  2863 //
       
  2864 // CTrkDispatchLayer::DoKillProcessL
       
  2865 //
       
  2866 // Kill an existing process
       
  2867 //
       
  2868 void CTrkDispatchLayer::DoKillProcessL()
       
  2869 {
       
  2870 	// get the process id
       
  2871 	TUint32 processId = 0;
       
  2872 	GetDataFromBufferL(&processId, 4);
       
  2873 	
       
  2874 	RProcess process;
       
  2875 	User::LeaveIfError(process.Open(processId));
       
  2876 #ifdef EKA2
       
  2877 	process.Kill(KErrNone);
       
  2878 #else	
       
  2879 	process.Kill(KProcessKilled);
       
  2880 #endif
       
  2881 	process.Close();
       
  2882 
       
  2883 	iFramingLayer->RespondOkL(KNullDesC8);	
       
  2884 }
       
  2885 
       
  2886 //
       
  2887 // CTrkDispatchLayer::DoAttachProcessL
       
  2888 //
       
  2889 // Create a new process on the target device
       
  2890 //
       
  2891 void CTrkDispatchLayer::DoAttachProcessL(DSOSItemTypes aAttachType)
       
  2892 {
       
  2893 	// remove the options - currently unused
       
  2894 	iInputBuffer->Des().Delete(0, 1);
       
  2895 
       
  2896 	// get the length of the data
       
  2897 	TUint32 processId = 0;
       
  2898 	GetDataFromBufferL(&processId, 4);
       
  2899 
       
  2900 	RProcess process;
       
  2901 	User::LeaveIfError(process.Open(processId));
       
  2902 	CleanupClosePushL(process);
       
  2903 	
       
  2904 	// do not allow attaching to a system, protected, or the MetroTrk process because
       
  2905 	// if the user were to stop the wrong thread, the whole system could stop
       
  2906 #ifdef EKA2
       
  2907 	if ((TUint)processId == RProcess().Id())
       
  2908 #else
       
  2909 	if (process.System() || process.Protected() || ((TUint)processId == RProcess().Id()))
       
  2910 #endif
       
  2911 	{
       
  2912 		User::Leave(kDSReplyUnsupportedOptionError);
       
  2913 	}
       
  2914 
       
  2915 	TMetroTrkTaskInfo threadInfo(processId);
       
  2916 	User::LeaveIfError(iKernelDriver.GetThreadInfo(0, threadInfo));
       
  2917 
       
  2918 	
       
  2919 	TUint32 codeAddr;
       
  2920 	TUint32 dataAddr;
       
  2921 	User::LeaveIfError(iKernelDriver.GetProcessAddresses(threadInfo.iId, codeAddr, dataAddr));	
       
  2922 	//this is necessary to get the process died notifications and also any other event for this process
       
  2923 	CDebugProcess *proc = CDebugProcess::NewL(this, processId, threadInfo.iId);
       
  2924 	// For processes that we are attaching, we need to set this flag to true.
       
  2925 	// otherwise library load notifications for this process will be ignored
       
  2926 	proc->iReadyForLibraryLoadNotification = ETrue;
       
  2927 	iDebugProcessList.Append(proc);	
       
  2928 			
       
  2929 	AddToReplyBufferL(threadInfo.iId, true);
       
  2930 	if (aAttachType == kDSOSProcAttach3Item)
       
  2931 	{
       
  2932 		// now get the UID3 for this process
       
  2933 		// and add it to the reply
       
  2934 		TMetroTrkProcUidInfo procUidInfo(processId);
       
  2935 		User::LeaveIfError(iKernelDriver.GetProcUidInfo(procUidInfo));
       
  2936 		AddToReplyBufferL(procUidInfo.iUid3);
       
  2937 	}
       
  2938 	if (aAttachType == kDSOSProcAttach3Item || aAttachType == kDSOSProcAttach2Item)
       
  2939 	{				
       
  2940 		AddToReplyBufferL(codeAddr);
       
  2941 		AddToReplyBufferL(dataAddr);
       
  2942 		
       
  2943 		TBuf8<KMaxFullName> procName;
       
  2944 		procName.Copy(process.Name());
       
  2945 		TUint16 nameLength = procName.Length();
       
  2946 
       
  2947 		AddToReplyBufferL(nameLength);
       
  2948 		AddToReplyBufferL(procName);		
       
  2949 	}
       
  2950 
       
  2951 	CleanupStack::PopAndDestroy(); // process
       
  2952 	RespondOkL();
       
  2953 }
       
  2954 
       
  2955 //
       
  2956 // CTrkDispatchLayer::DoDetachProcessL
       
  2957 //
       
  2958 // To detach the process from the list of processes
       
  2959 //
       
  2960 void CTrkDispatchLayer::DoDetachProcessL()
       
  2961 {
       
  2962     TUint32 processId = 0;
       
  2963     GetDataFromBufferL(&processId, 4);
       
  2964     
       
  2965     RProcess process;
       
  2966     User::LeaveIfError(process.Open(processId));
       
  2967     
       
  2968 	for (TInt i=0 ; i<iDebugProcessList.Count(); i++)
       
  2969 	{
       
  2970 		if(iDebugProcessList[i]->ProcessId()== processId) 
       
  2971 		{
       
  2972 			SafeDelete(iDebugProcessList[i]);
       
  2973 			iDebugProcessList.Remove(i);
       
  2974 		}
       
  2975 	}
       
  2976     User::LeaveIfError(iKernelDriver.DetachProcess(processId));    
       
  2977 
       
  2978     iFramingLayer->RespondOkL(KNullDesC8);
       
  2979 }
       
  2980 
       
  2981 
       
  2982 //
       
  2983 // CTrkDispatchLayer::DoReadProcessListL
       
  2984 //
       
  2985 // Return a list of the current processes to the host debugger
       
  2986 //
       
  2987 void CTrkDispatchLayer::DoReadProcessListL(TInt32 aIndex)
       
  2988 {
       
  2989 	// remove the options - unused
       
  2990 	iInputBuffer->Des().Delete(0, 1);
       
  2991 
       
  2992 	// remove the filter - unused
       
  2993 	iInputBuffer->Des().Delete(0, 4);
       
  2994 
       
  2995 	// an index of zero means we start fresh.  and index other than zero means
       
  2996 	// we were not able to return all of the processes in the last round due to
       
  2997 	// message size limitations, so we need to pick up where we left off
       
  2998 	if (aIndex == 0)
       
  2999 	{
       
  3000 		DoReBuildProcessList();
       
  3001 	}
       
  3002 	
       
  3003 	TInt32 totalCount = iProcessList.Count();
       
  3004 	TInt32 returnedCount = 0;
       
  3005 	TInt32 bytesRemaining = MAXMESSAGESIZE_V2 - 30; // minus the framing bytes
       
  3006 	TInt32 restOfMsgSize = sizeof(TUint32) // process id
       
  3007 						 + sizeof(TUint32) // priority
       
  3008 						 + sizeof(TUint8); // NULL character
       
  3009 	
       
  3010 	for (TInt32 i=aIndex; i<totalCount; i++)
       
  3011 	{
       
  3012 		// make sure there is enough room left in the message
       
  3013 		if (bytesRemaining >= (iProcessList[i].iName.Length() + restOfMsgSize))
       
  3014 		{
       
  3015 			returnedCount++;
       
  3016 			bytesRemaining -= (iProcessList[i].iName.Length() + restOfMsgSize);
       
  3017 		}
       
  3018 		else
       
  3019 			break;
       
  3020 	}
       
  3021 
       
  3022 	// add values for returnedCount and totalCount
       
  3023 	AddToReplyBufferL((TUint32)returnedCount, true);
       
  3024 	AddToReplyBufferL((TUint32)totalCount);
       
  3025 
       
  3026 	for (TInt32 i=aIndex; i<(aIndex + returnedCount); i++)
       
  3027 	{
       
  3028 		// add this process info to the buffer
       
  3029 		AddToReplyBufferL(iProcessList[i].iId);
       
  3030 		AddToReplyBufferL(iProcessList[i].iPriority);
       
  3031 		AddToReplyBufferL(iProcessList[i].iName);
       
  3032 		
       
  3033 		// host expects the name to be a null terminated string
       
  3034 		AddToReplyBufferL((TUint8)0);
       
  3035 	}
       
  3036 	
       
  3037 	RespondOkL();
       
  3038 }
       
  3039 
       
  3040 //
       
  3041 // CTrkDispatchLayer::DoReadThreadListL
       
  3042 //
       
  3043 // Return a list of the current threads for a process to the host debugger
       
  3044 //
       
  3045 void CTrkDispatchLayer::DoReadThreadListL(TInt32 aIndex)
       
  3046 {
       
  3047 	// remove the options - unused
       
  3048 	iInputBuffer->Des().Delete(0, 1);
       
  3049 
       
  3050 	// get the process id
       
  3051 	TUint32 processId = 0;
       
  3052 	GetDataFromBufferL(&processId, 4);
       
  3053 
       
  3054 	// an index of zero means we start fresh.  and index other than zero means
       
  3055 	// we were not able to return all of the threads in the last round due to
       
  3056 	// message size limitations, so we need to pick up where we left off
       
  3057 	if (aIndex == 0)
       
  3058 	{
       
  3059 		DoReBuildThreadList(processId);
       
  3060 	}
       
  3061 	
       
  3062 	TInt32 totalCount = iThreadList.Count();
       
  3063 	TInt32 returnedCount = 0;
       
  3064 	TInt32 bytesRemaining = MAXMESSAGESIZE_V2 - 30; // minus the framing bytes
       
  3065 	TInt32 restOfMsgSize = sizeof(TUint32) // process id
       
  3066 						 + sizeof(TUint32) // priority
       
  3067 						 + sizeof(TUint8)  // state
       
  3068 						 + sizeof(TUint8); // NULL character
       
  3069 	
       
  3070 	
       
  3071 	for (TInt32 i=aIndex; i<totalCount; i++)
       
  3072 	{
       
  3073 		// make sure there is enough room left in the message
       
  3074 		if (bytesRemaining >= (iThreadList[i].iName.Length() + restOfMsgSize))
       
  3075 		{
       
  3076 			returnedCount++;
       
  3077 			bytesRemaining -= (iThreadList[i].iName.Length() + restOfMsgSize);
       
  3078 		}
       
  3079 		else
       
  3080 			break;
       
  3081 	}
       
  3082 
       
  3083 	// add values for returnedCount and totalCount
       
  3084 	AddToReplyBufferL((TUint32)returnedCount, true);
       
  3085 	AddToReplyBufferL((TUint32)totalCount);
       
  3086 
       
  3087 	for (TInt32 i=aIndex; i<(aIndex + returnedCount); i++)
       
  3088 	{
       
  3089 		// add this thread info to the buffer
       
  3090 		AddToReplyBufferL(iThreadList[i].iId);
       
  3091 		AddToReplyBufferL(iThreadList[i].iPriority);
       
  3092 		AddToReplyBufferL(IsThreadSuspended(iThreadList[i].iId));		
       
  3093 		AddToReplyBufferL(iThreadList[i].iName);
       
  3094 
       
  3095 		// host expects the name to be a null terminated string
       
  3096 		AddToReplyBufferL((TUint8)0);
       
  3097 	}
       
  3098 
       
  3099 	RespondOkL();
       
  3100 }
       
  3101 
       
  3102 //
       
  3103 // CTrkDispatchLayer::DoReBuildProcessList
       
  3104 //
       
  3105 // Build a list of the current processes
       
  3106 //
       
  3107 void CTrkDispatchLayer::DoReBuildProcessList()
       
  3108 {
       
  3109 	TInt err = KErrNone;
       
  3110 
       
  3111 	// reset the process list
       
  3112 	iProcessList.Reset();
       
  3113 	
       
  3114 	// fill up the process list
       
  3115 	for (TInt i=0; KErrNone==err; i++)
       
  3116 	{
       
  3117 		TMetroTrkTaskInfo processInfo(0);
       
  3118 		err = iKernelDriver.GetProcessInfo(i, processInfo);
       
  3119 		
       
  3120 		//Get a Handle to the process
       
  3121 		RProcess proc;
       
  3122 		if(KErrNone == err && KErrNone == proc.Open(TProcessId(processInfo.iId)))
       
  3123 		{			
       
  3124 			//Only display currently running processes
       
  3125 			if(EExitPending == proc.ExitType())
       
  3126 			{
       
  3127 				iProcessList.Append(processInfo);
       
  3128 			}
       
  3129 			proc.Close();
       
  3130 		}
       
  3131 	}
       
  3132 }
       
  3133 
       
  3134 //
       
  3135 // CTrkDispatchLayer::DoReBuildThreadList
       
  3136 //
       
  3137 // Build a list of the current threads for a process
       
  3138 //
       
  3139 void CTrkDispatchLayer::DoReBuildThreadList(TUint32 aProcessId)
       
  3140 {
       
  3141 	TInt err = KErrNone;
       
  3142 
       
  3143 	// reset the thread list
       
  3144 	iThreadList.Reset();
       
  3145 	
       
  3146 	// fill up the thread list
       
  3147 	for (TInt i=0; KErrNone==err; i++)
       
  3148 	{
       
  3149 		TMetroTrkTaskInfo threadInfo(aProcessId);
       
  3150 		err = iKernelDriver.GetThreadInfo(i, threadInfo);
       
  3151 		
       
  3152 		//Get a Handle to the thread
       
  3153 		RThread thread;
       
  3154 		if(KErrNone == err && KErrNone == thread.Open(TThreadId(threadInfo.iId)))
       
  3155 		{			
       
  3156 			//Only display currently running processes
       
  3157 			if(EExitPending == thread.ExitType())
       
  3158 			{
       
  3159 				iThreadList.Append(threadInfo);
       
  3160 			}
       
  3161 			thread.Close();
       
  3162 		}
       
  3163 	}
       
  3164 }
       
  3165 
       
  3166 // CTrkDispatchLayer::DoNotifyStoppedL
       
  3167 //
       
  3168 // Notify the host debugger that a thread has stopped
       
  3169 //
       
  3170 // START_PANIC
       
  3171 //void CTrkDispatchLayer::DoNotifyStoppedL(TUint32 aProcessId, TUint32 aThreadId, TUint32 aCurrentPC, const TDesC8 &aDescription)
       
  3172 void CTrkDispatchLayer::DoNotifyStoppedL(TUint32 aProcessId, TUint32 aThreadId, TUint32 aCurrentPC, const TDesC8 &aDescription, TBool aAddException, const TUint16 aExceptionNumber)
       
  3173 // END_PANIC
       
  3174 {	
       
  3175 	// add this thread to the suspended threads list
       
  3176 	iSuspendedThreadList.Append(aThreadId);
       
  3177 
       
  3178 //	TUint8 event = (aAddException==true) ? kDSNotifyStopped2 : kDSNotifyStopped;
       
  3179 	TUint8 event = kDSNotifyStopped;
       
  3180 	TUint16 descLength = aDescription.Length();
       
  3181 	
       
  3182 	AddToReplyBufferL(event, true);
       
  3183 	AddToReplyBufferL(aCurrentPC);
       
  3184 	AddToReplyBufferL(aProcessId);
       
  3185 	AddToReplyBufferL(aThreadId);
       
  3186 	AddToReplyBufferL(descLength);
       
  3187 
       
  3188 	if (descLength)
       
  3189 	{
       
  3190 		AddToReplyBufferL(aDescription);
       
  3191 
       
  3192 		// host expects the string to be a null terminated string
       
  3193 		AddToReplyBufferL((TUint8)0);
       
  3194 	}
       
  3195 	// START_PANIC
       
  3196 	if (aAddException)
       
  3197 		AddToReplyBufferL(aExceptionNumber);
       
  3198 	// END_PANIC
       
  3199 	
       
  3200 	InformEventL();
       
  3201 }
       
  3202 
       
  3203 //
       
  3204 // CTrkDispatchLayer::DoNotifyProcessDiedL
       
  3205 //
       
  3206 // Notify the host debugger that a process has exited
       
  3207 //
       
  3208 void CTrkDispatchLayer::DoNotifyProcessDiedL(TUint32 aProcessId, TInt aExitCode)
       
  3209 {
       
  3210 	// remove this process from our list
       
  3211 	for (TInt i=0; i<iDebugProcessList.Count(); i++)
       
  3212 	{
       
  3213 		if (iDebugProcessList[i]->ProcessId() == aProcessId)
       
  3214 		{
       
  3215 			SafeDelete(iDebugProcessList[i]);
       
  3216 			iDebugProcessList.Remove(i);
       
  3217 		}
       
  3218 	}
       
  3219 
       
  3220 	TUint8 event = kDSOSNotifyDeleted;
       
  3221 	TUint16 type = kDSOSProcessItem;
       
  3222 
       
  3223 	AddToReplyBufferL(event, true);
       
  3224 	AddToReplyBufferL(type);
       
  3225 	AddToReplyBufferL((TUint32)aExitCode);
       
  3226 	AddToReplyBufferL(aProcessId);
       
  3227 
       
  3228 	InformEventL();
       
  3229 }
       
  3230 
       
  3231 //
       
  3232 // CTrkDispatchLayer::DoNotifyLibraryLoadedL
       
  3233 //
       
  3234 // Notify the host debugger that a library in now loaded
       
  3235 //
       
  3236 void CTrkDispatchLayer::DoNotifyLibraryLoadedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId, TUint32 aCodeBaseAddress, TUint32 aDataBaseAddress)
       
  3237 {
       
  3238 	TUint8 event = kDSOSNotifyCreated;
       
  3239 	TUint16 type = kDSOSDLLItem;
       
  3240 
       
  3241 	TUint16 nameLength = aName.Length();
       
  3242 	
       
  3243 	AddToReplyBufferL(event, true);
       
  3244 	AddToReplyBufferL(type);
       
  3245 	AddToReplyBufferL(aProcessId);
       
  3246 	AddToReplyBufferL(aThreadId);
       
  3247 	AddToReplyBufferL(aCodeBaseAddress);
       
  3248 	AddToReplyBufferL(aDataBaseAddress);
       
  3249 	AddToReplyBufferL(nameLength);
       
  3250 	AddToReplyBufferL(aName);
       
  3251 
       
  3252 	InformEventL();
       
  3253 }
       
  3254 
       
  3255 //
       
  3256 // CTrkDispatchLayer::DoNotifyLibraryUnloadedL
       
  3257 //
       
  3258 // Notify the host debugger that a library has been unloaded
       
  3259 //
       
  3260 void CTrkDispatchLayer::DoNotifyLibraryUnloadedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId)
       
  3261 {
       
  3262 	TUint8 event = kDSOSNotifyDeleted;
       
  3263 	TUint16 type = kDSOSDLLItem;
       
  3264 	
       
  3265 	TUint16 nameLength = aName.Length();
       
  3266 	
       
  3267 	AddToReplyBufferL(event, true);
       
  3268 	AddToReplyBufferL(type);
       
  3269 	AddToReplyBufferL(aProcessId);
       
  3270 	AddToReplyBufferL(aThreadId);
       
  3271 	AddToReplyBufferL(nameLength);
       
  3272 	AddToReplyBufferL(aName);
       
  3273 
       
  3274 	InformEventL();
       
  3275 }
       
  3276 
       
  3277 //
       
  3278 // CTrkDispatchLayer::GetDataFromBufferL
       
  3279 //
       
  3280 // Notify the host debugger that trace data has been recieved
       
  3281 //
       
  3282 void CTrkDispatchLayer::DoNotifyUserTraceL(TDesC8 &aTrace)
       
  3283 {
       
  3284 	if (iIsConnected)
       
  3285 		iFramingLayer->SendRawMsgL(aTrace);
       
  3286 }
       
  3287 
       
  3288 void CTrkDispatchLayer::DoNotifyProcessAddedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId, TUint32 aUid, TUint32 aCodeBaseAddress, TUint32 aDataBaseAddress)
       
  3289 {
       
  3290 	// check to see if the host supported protocol handles this event, 
       
  3291 	// otherwise just resume the thread. If not, this thread would get suspended indefinitely.
       
  3292 	if (iHostVersion.iMajor < 3 || (iHostVersion.iMajor == 3  && iHostVersion.iMinor <= 3))
       
  3293 	{
       
  3294 		iKernelDriver.ResumeThread(aThreadId);				
       
  3295 	}
       
  3296 	else
       
  3297 	{
       
  3298 		TUint8 event = kDSOSNotifyCreated;
       
  3299 		TUint16 type = kDSOSProcessItem;
       
  3300 
       
  3301 		TUint16 nameLength = aName.Length();
       
  3302 		
       
  3303 		AddToReplyBufferL(event, true);
       
  3304 		AddToReplyBufferL(type);
       
  3305 		AddToReplyBufferL(aProcessId);
       
  3306 		AddToReplyBufferL(aThreadId);
       
  3307 		AddToReplyBufferL(aUid);
       
  3308 		AddToReplyBufferL(aCodeBaseAddress);
       
  3309 		AddToReplyBufferL(aDataBaseAddress);
       
  3310 		AddToReplyBufferL(nameLength);
       
  3311 		AddToReplyBufferL(aName);
       
  3312 
       
  3313 		InformEventL();
       
  3314 	}
       
  3315 }
       
  3316 
       
  3317 //
       
  3318 // CTrkDispatchLayer::DoReadLibraryInfoL()
       
  3319 //
       
  3320 void CTrkDispatchLayer::DoReadLibraryInfoL(TDesC8& aFileName)
       
  3321 {
       
  3322 	TMetroTrkLibInfo libInfo(aFileName.Length(), &aFileName);
       
  3323 	
       
  3324 	TInt err = iKernelDriver.GetLibraryInfo(libInfo);
       
  3325 	
       
  3326 	if (err == KErrNone)
       
  3327 	{
       
  3328 		AddToReplyBufferL(libInfo.iCodeAddress, true);
       
  3329 		AddToReplyBufferL(libInfo.iDataAddress);
       
  3330 		AddToReplyBufferL(libInfo.iAttachProcessId);
       
  3331 		AddToReplyBufferL(libInfo.iAttachThreadId);
       
  3332 		
       
  3333 		RespondOkL();
       
  3334 	}
       
  3335 	else
       
  3336 	{
       
  3337 		User::Leave(err);
       
  3338 	}			
       
  3339 }
       
  3340 
       
  3341 //
       
  3342 // CTrkDispatchLayer::DoReadProcessInfoL()
       
  3343 //
       
  3344 void CTrkDispatchLayer::DoReadProcessInfoL(TUint32 aUid, TDesC8& aFileName)
       
  3345 {
       
  3346 	TMetroTrkExeInfo exeInfo(aUid, aFileName.Length(), &aFileName);
       
  3347 	
       
  3348 	TInt err = iKernelDriver.GetExeInfo(exeInfo);
       
  3349 	
       
  3350 	if (err == KErrNone)
       
  3351 	{
       
  3352 		AddToReplyBufferL(exeInfo.iProcessID, true);
       
  3353 		AddToReplyBufferL(exeInfo.iThreadID);
       
  3354 		AddToReplyBufferL(exeInfo.iCodeAddress);
       
  3355 		AddToReplyBufferL(exeInfo.iDataAddress);
       
  3356 		
       
  3357 		RespondOkL();
       
  3358 	}
       
  3359 	else
       
  3360 	{
       
  3361 		User::Leave(err);
       
  3362 	}			
       
  3363 }
       
  3364 
       
  3365 //
       
  3366 // CTrkDispatchLayer::GetDataFromBufferL
       
  3367 //
       
  3368 // Get data from the input buffer
       
  3369 //
       
  3370 void CTrkDispatchLayer::GetDataFromBufferL(TAny* aData, TInt aLength)
       
  3371 {
       
  3372 	if (aLength > iInputBuffer->Length())
       
  3373 		User::Leave(kDSReplyPacketSizeError);
       
  3374 		
       
  3375 	if (iFramingLayer->IsBigEndian())
       
  3376 	{
       
  3377 		Mem::Copy(aData, iInputBuffer->Ptr(), aLength);
       
  3378 	}
       
  3379 	else
       
  3380 	{
       
  3381 		TUint8 *p = (TUint8 *)aData;
       
  3382 		for (int i=aLength-1, j=0; i>=0; i--, j++)
       
  3383 			p[j] = iInputBuffer->Ptr()[i];
       
  3384 	}
       
  3385 	
       
  3386 	// now remove it from the buffer
       
  3387 	iInputBuffer->Des().Delete(0, aLength);
       
  3388 }
       
  3389 
       
  3390 //
       
  3391 // CTrkDispatchLayer::AddToReplyBufferL
       
  3392 //
       
  3393 // Add data to the buffer which will be sent back to the host as a reply
       
  3394 //
       
  3395 void CTrkDispatchLayer::AddToReplyBufferL(TUint8 aData, TBool aReset)
       
  3396 {
       
  3397 	if (aReset)
       
  3398 	{
       
  3399 		// free the memory associated with the old reply buffer and allocate a new one
       
  3400 		SafeDelete(iReplyBuffer);
       
  3401 		iReplyBuffer = HBufC8::New(sizeof(TUint8));
       
  3402 	}
       
  3403 	else
       
  3404 	{
       
  3405 		// reallocate to make enough room for the new data
       
  3406 		iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint8));
       
  3407 	}
       
  3408 	
       
  3409 	// make sure the above worked
       
  3410 	if (!iReplyBuffer)
       
  3411 		User::Leave(KErrNoMemory);
       
  3412 	
       
  3413 	iReplyBuffer->Des().Append(aData);
       
  3414 }
       
  3415 
       
  3416 //
       
  3417 // CTrkDispatchLayer::AddToReplyBufferL
       
  3418 //
       
  3419 // Add data to the buffer which will be sent back to the host as a reply
       
  3420 //
       
  3421 void CTrkDispatchLayer::AddToReplyBufferL(TUint16 aData, TBool aReset)
       
  3422 {
       
  3423 	TUint16 temp = aData;
       
  3424 	
       
  3425 	if (aReset)
       
  3426 	{
       
  3427 		// free the memory associated with the old reply buffer and allocate a new one
       
  3428 		SafeDelete(iReplyBuffer);
       
  3429 		iReplyBuffer = HBufC8::New(sizeof(TUint16));
       
  3430 	}
       
  3431 	else
       
  3432 	{
       
  3433 		// reallocate to make enough room for the new data
       
  3434 		iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint16));
       
  3435 	}
       
  3436 	
       
  3437 	// make sure the above worked
       
  3438 	if (!iReplyBuffer)
       
  3439 		User::Leave(KErrNoMemory);
       
  3440 	
       
  3441 	// the host expects all values except for raw data to be returned in big endian format
       
  3442 	if (!iFramingLayer->IsBigEndian())
       
  3443 	{
       
  3444 		temp = Swap2(aData);
       
  3445 	}
       
  3446 
       
  3447 	iReplyBuffer->Des().Append((TUint8 *)&temp, sizeof(TUint16));
       
  3448 }
       
  3449 
       
  3450 //
       
  3451 // CTrkDispatchLayer::AddToReplyBufferL
       
  3452 //
       
  3453 // Add data to the buffer which will be sent back to the host as a reply
       
  3454 //
       
  3455 void CTrkDispatchLayer::AddToReplyBufferL(TUint32 aData, TBool aReset)
       
  3456 {
       
  3457 	TUint32 temp = aData;
       
  3458 	
       
  3459 	if (aReset)
       
  3460 	{
       
  3461 		// free the memory associated with the old reply buffer and allocate a new one
       
  3462 		SafeDelete(iReplyBuffer);
       
  3463 		iReplyBuffer = HBufC8::New(sizeof(TUint32));
       
  3464 	}
       
  3465 	else
       
  3466 	{
       
  3467 		// reallocate to make enough room for the new data
       
  3468 		iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint32));
       
  3469 	}
       
  3470 	
       
  3471 	// make sure the above worked
       
  3472 	if (!iReplyBuffer)
       
  3473 		User::Leave(KErrNoMemory);
       
  3474 	
       
  3475 	// the host expects all values except for raw data to be returned in big endian format
       
  3476 	if (!iFramingLayer->IsBigEndian())
       
  3477 	{
       
  3478 		temp = Swap4(aData);
       
  3479 	}
       
  3480 
       
  3481 	iReplyBuffer->Des().Append((TUint8 *)&temp, sizeof(TUint32));
       
  3482 }
       
  3483 
       
  3484 //
       
  3485 // CTrkDispatchLayer::AddToReplyBufferL
       
  3486 //
       
  3487 // Add data to the buffer which will be sent back to the host as a reply
       
  3488 //
       
  3489 void CTrkDispatchLayer::AddToReplyBufferL(const TDesC8 &aData, TBool aReset)
       
  3490 {
       
  3491 	if (aReset)
       
  3492 	{
       
  3493 		// free the memory associated with the old reply buffer and allocate a new one
       
  3494 		SafeDelete(iReplyBuffer);
       
  3495 		iReplyBuffer = HBufC8::New(aData.Length());
       
  3496 	}
       
  3497 	else
       
  3498 	{
       
  3499 		// reallocate to make enough room for the new data
       
  3500 		iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + aData.Length());
       
  3501 	}
       
  3502 	
       
  3503 	// make sure the above worked
       
  3504 	if (!iReplyBuffer)
       
  3505 		User::Leave(KErrNoMemory);
       
  3506 	
       
  3507 	iReplyBuffer->Des().Append(aData);
       
  3508 }
       
  3509 
       
  3510 //
       
  3511 // CTrkDispatchLayer::IsThreadSuspended
       
  3512 //
       
  3513 // Determines whether or not a thread is suspended
       
  3514 //
       
  3515 TUint8 CTrkDispatchLayer::IsThreadSuspended(TUint32 aThreadId)
       
  3516 {
       
  3517 	if (iSuspendedThreadList.Find(aThreadId) >= 0)
       
  3518 		return 1;
       
  3519 	
       
  3520 	return 0;
       
  3521 }
       
  3522 
       
  3523 //
       
  3524 // CTrkDispatchLayer::IsRestrictedFolder
       
  3525 //
       
  3526 // Check to see if the path is any of the data caged paths like \sys\ or \private\ or \resource\
       
  3527 //
       
  3528 TBool CTrkDispatchLayer::IsRestrictedFolder(const TDesC& aPath)
       
  3529 {
       
  3530 	_LIT(KSYS, "\\sys\\");
       
  3531 	_LIT(KRESOURCE, "\\resource\\");
       
  3532 	_LIT(KPRIVATE, "\\private\\");
       
  3533 	
       
  3534 	if ( (aPath.FindC(KSYS)>=0) || (aPath.FindC(KRESOURCE)>=0) || (aPath.FindC(KPRIVATE)>=0) )
       
  3535 		return ETrue;
       
  3536 	
       
  3537 	return EFalse;
       
  3538 }
       
  3539 
       
  3540 
       
  3541 TInt CTrkDispatchLayer::CloseCrashLogger()
       
  3542 {
       
  3543     TInt err = KErrNone;
       
  3544     
       
  3545     //The old mobile crash file name is "d_exc_mc.exe" and the new one is "mc_useragent.exe"    
       
  3546     //This is the string that needs to be passed to the RProcess::Open call to get a handle.
       
  3547     //The complete process name actually includes the UID info as well.
       
  3548     //Instead of hard coding the process name, its better to just 
       
  3549     //search for the process and find it that way.      
       
  3550     //_LIT16(KCrashLoggerName, "mc_useragent.exe[1020e519]0001");
       
  3551     _LIT16(KOldCrashLoggerName, "d_exc_mc*");
       
  3552     _LIT16(KCrashLoggerName, "mc_useragent*");
       
  3553     
       
  3554     err = TerminateProcess(KOldCrashLoggerName);
       
  3555     err = TerminateProcess(KCrashLoggerName);
       
  3556 
       
  3557     return err;
       
  3558 }
       
  3559 
       
  3560 TInt CTrkDispatchLayer::TerminateProcess(const TDesC& aProcessName)
       
  3561 {
       
  3562     TFindProcess find(aProcessName);
       
  3563     TFullName name; 
       
  3564         
       
  3565     TInt err = find.Next(name);
       
  3566     if (KErrNone == err)
       
  3567     {   
       
  3568         RProcess process;
       
  3569         err = process.Open(find);
       
  3570     
       
  3571         if (KErrNone == err)
       
  3572         {
       
  3573             process.Kill(KErrNone);
       
  3574         }
       
  3575     }
       
  3576     return err;
       
  3577 }