dbgsrv/coredumpserver/server/src/coredumpsessioncalls.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // core_dump_session_calls.cpp
       
    15 //
       
    16 
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @released
       
    23 */
       
    24 
       
    25 #include <crashlogwalker.h>
       
    26 #include <scmconfigitem.h>
       
    27 #include "coredumpsession.h"
       
    28 
       
    29 using namespace Debug;
       
    30 
       
    31 // Creates and returns a heap descriptor which holds contents of list
       
    32 HBufC8* CCoreDumpSession::MarshalListL( TListRequest & req, TAny * list )
       
    33 	{
       
    34 
       
    35 	LOG_MSG("->CCoreDumpSession::MarshalListL()\n" );
       
    36 
       
    37 	// Create a dynamic flat buffer to hold this object's member data	
       
    38 	// Can only use CBufFlat due to Store supporting CBufFlat and CBufSeg
       
    39 	// See Symbian OS guide » System libraries » Using Store » Streaming » Templated stream operators
       
    40 
       
    41 	const TInt KExpandSize = 128; // "Granularity" of dynamic buffer
       
    42 
       
    43 	CBufFlat* buf = CBufFlat::NewL( KExpandSize );
       
    44 	CleanupStack::PushL( buf );
       
    45 
       
    46 	RBufWriteStream stream( *buf ); // Stream over the buffer
       
    47 	CleanupClosePushL( stream );
       
    48 
       
    49 	for( TInt i = 0; i < req.iRemaining; i ++ )
       
    50 		{		
       
    51 		switch( req.iListType )
       
    52 			{
       
    53 			case TListRequest::EThreadList:
       
    54 				{
       
    55 				//LOG_MSG2( "  -> ((*threadPointerList)[%d])->ExternalizeL( )\n", i );
       
    56 				iThreadPointerList[i]->ExternalizeL( stream, buf );
       
    57 				//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    58 				break;
       
    59 				}
       
    60 			case TListRequest::EProcessList:
       
    61 				{
       
    62 				//LOG_MSG2( "  -> ((*processPointerList)[%d])->ExternalizeL( )\n", i );
       
    63 				iProcessPointerList[i]->ExternalizeL( stream, buf );
       
    64 				//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    65 				break;
       
    66 				}
       
    67 
       
    68 			case TListRequest::EExecutableList:
       
    69 				{
       
    70 				//LOG_MSG2( "  -> ((*processPointerList)[%d])->ExternalizeL( )\n", i );
       
    71 				iExecutablePointerList[i]->ExternalizeL( stream, buf );
       
    72 				//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    73 				break;
       
    74 				}
       
    75             case TListRequest::EFormatterList:
       
    76                 {
       
    77 				LOG_MSG2( "  -> ((*formatterInfos)[%d])->ExternalizeL( )\n", i );
       
    78 				iFormatterInfos[i]->ExternalizeL( stream, buf );
       
    79 				//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    80 				break;
       
    81                 }
       
    82             case TListRequest::EWriterList:
       
    83                 {
       
    84 				LOG_MSG2( "  -> ((*writerInfos)[%d])->ExternalizeL( )\n", i );
       
    85 				iWriterInfos[i]->ExternalizeL( stream, buf );
       
    86 				//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    87 				break;
       
    88                 }
       
    89             case TListRequest::ECrashList:
       
    90             	{
       
    91             	LOG_MSG2( "  -> ((*iCrashList)[%d])->ExternalizeL( )\n", i );
       
    92             	iCrashList[i]->ExternalizeL(stream, buf);
       
    93             	//LOG_MSG2( "  buf->Size()=%d\n", buf->Size() );
       
    94             	break;
       
    95             	}
       
    96 			default:
       
    97 				{
       
    98 				LOG_MSG("CCoreDumpSession::MarshalListL : Received unknown list type");				
       
    99 				User::Leave( KErrNotSupported );
       
   100 				}
       
   101 			}
       
   102 		}
       
   103 
       
   104 	stream.CommitL();
       
   105 
       
   106 	TInt bufSize = buf->Size();
       
   107 
       
   108 	// Create a heap descriptor from the buffer
       
   109 	HBufC8* des = HBufC8::NewL( buf->Size() );
       
   110 	TPtr8 ptr( des->Des() );
       
   111 
       
   112 	buf->Read( 0, ptr, buf->Size() );
       
   113 	
       
   114 	CleanupStack::PopAndDestroy( &stream );
       
   115 	CleanupStack::PopAndDestroy( buf ); 
       
   116 	
       
   117 	return des;
       
   118 	}
       
   119 
       
   120 
       
   121 void CCoreDumpSession::GetListL( const RMessage2& aMessage )
       
   122 	{
       
   123 	LOG_MSG( "CCoreDumpSession::GetListL()\n" );
       
   124 
       
   125 	TListRequest listRequest; 
       
   126 	HBufC8 *listDes = NULL;
       
   127 
       
   128 	TPtr8 listReqPtr( (TUint8 *)&listRequest, sizeof(TListRequest) );
       
   129 
       
   130 	aMessage.ReadL( 0, listReqPtr );
       
   131 
       
   132 	switch( listRequest.iListType )
       
   133 		{
       
   134 		case TListRequest::EThreadList :
       
   135 			{
       
   136 			if( listRequest.iRequiredDescriptorSize != iTotalThreadListDescSize )
       
   137 				{
       
   138 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalThreadListDescSize\n" );
       
   139 				User::Leave( KErrBadDescriptor );
       
   140 				}
       
   141 			listDes = iMarshalledThreadList;
       
   142 			break;
       
   143 			}
       
   144 		case TListRequest::EProcessList :
       
   145 			{
       
   146 			if( listRequest.iRequiredDescriptorSize != iTotalProcessListDescSize )
       
   147 				{
       
   148 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalProcessListDescSize\n" );
       
   149 				User::Leave( KErrBadDescriptor );
       
   150 				}
       
   151 			listDes = iMarshalledProcessList;
       
   152 			break;
       
   153 			}
       
   154 		case TListRequest::EExecutableList :
       
   155 			{
       
   156 			if( listRequest.iRequiredDescriptorSize != iTotalExecutableListDescSize )
       
   157 				{
       
   158 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalExecutableListDescSize\n" );
       
   159 				User::Leave( KErrBadDescriptor );
       
   160 				}
       
   161 			listDes = iMarshalledExecutableList;
       
   162 			break;
       
   163 			}
       
   164 		case TListRequest::EFormatterList :
       
   165 			{
       
   166 			if( listRequest.iRequiredDescriptorSize != iTotalFormatterListDescSize )
       
   167 				{
       
   168 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalFormatterListDescSize\n" );
       
   169 				User::Leave( KErrBadDescriptor );
       
   170 				}
       
   171 			listDes = iMarshalledFormatterList;
       
   172 			break;
       
   173 			}
       
   174 		case TListRequest::EWriterList :
       
   175 			{
       
   176 			if( listRequest.iRequiredDescriptorSize != iTotalWriterListDescSize )
       
   177 				{
       
   178 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalWriterListDescSize\n" );
       
   179 				User::Leave( KErrBadDescriptor );
       
   180 				}
       
   181 			listDes = iMarshalledWriterList;
       
   182 			break;
       
   183 			}
       
   184 		case TListRequest::ECrashList :
       
   185 			{
       
   186 			if( listRequest.iRequiredDescriptorSize != iTotalCrashInfoDescSize )
       
   187 				{
       
   188 				LOG_MSG( "  ERROR !* listReq.iRequiredDescriptorSize != iTotalWriterListDescSize\n" );
       
   189 				User::Leave( KErrBadDescriptor );
       
   190 				}
       
   191 			listDes = iMarshalledCrashList;
       
   192 			break;
       
   193 			}
       
   194 		default :
       
   195 			{
       
   196 			LOG_MSG2( " ERROR !* : CCoreDumpSession::ListInfoL() : invalid TListRequestType %d\n", 	listRequest.iListType );
       
   197 			User::Leave( KErrArgument );
       
   198 			}
       
   199 		}
       
   200 
       
   201 	if ( listDes == NULL )
       
   202 		{
       
   203 
       
   204 		LOG_MSG( "  ERROR !* MarshalData returned null buf\n" );
       
   205 		User::Leave( KErrBadDescriptor );
       
   206 
       
   207 		}
       
   208 	else
       
   209 		{
       
   210 
       
   211 		//LOG_MSG( "  -> TPtr8 lsitPtr( listDes->Des() )\n" );
       
   212 		TPtr8 listPtr( listDes->Des() );
       
   213 		//LOG_MSG2( "  listPtr->Size()=%d\n", listPtr.Size() );
       
   214 
       
   215 		if( listPtr.Size() == 0 )
       
   216 			{
       
   217 			LOG_MSG( "  ERROR !* : if( lsitPtr.Size() == 0 )\n" );
       
   218 			User::Leave( KErrBadDescriptor );
       
   219 			}
       
   220 
       
   221 		//LOG_MSG( "  -> WriteL( 1, listPtr )\n" );
       
   222 		aMessage.WriteL( 1, listPtr );
       
   223 
       
   224 		}
       
   225 
       
   226 	}
       
   227 
       
   228 
       
   229 void CCoreDumpSession::ListInfoL( const RMessage2& aMessage )
       
   230 	{
       
   231     LOG_MSG( "CCoreDumpSession::ListInfoL()\n" );
       
   232 
       
   233 	TListRequest listRequest; 
       
   234 	TUint64 procId;
       
   235 	
       
   236 	TPtr8 listReqPtr( (TUint8 *)&listRequest, sizeof(TListRequest) );
       
   237 
       
   238 	aMessage.ReadL( 0, listReqPtr );
       
   239 
       
   240 	switch( listRequest.iListType )
       
   241 		{
       
   242 		    case TListRequest::EThreadList :
       
   243 				{
       
   244 				procId = MAKE_TUINT64( listRequest.iSubId2, listRequest.iSubId1 );				
       
   245 				iDataSource->GetThreadListL( procId, iThreadPointerList, iTotalThreadListDescSize );
       
   246 	
       
   247 				listRequest.iRemaining = iThreadPointerList.Count();
       
   248 	
       
   249 	            //mark those that we observe
       
   250 	            for(TInt i = 0; i < iObservationList.Count(); i++)
       
   251 	                {
       
   252 	                for(TInt j = 0; j < iThreadPointerList.Count(); j++)
       
   253 	                    {
       
   254 	                    if(iObservationList[i]->HasThread(iThreadPointerList[j]->Name()))
       
   255 	                        {
       
   256 	                        iThreadPointerList[j]->Observed(ETrue); 
       
   257 	                        }
       
   258 	                    }
       
   259 	                }
       
   260 	
       
   261 				if( NULL != iMarshalledThreadList )
       
   262 					{
       
   263 					delete iMarshalledThreadList;
       
   264 					}
       
   265 	
       
   266 				//LOG_MSG( " EThreadList -> MarshalDataL()\n" );
       
   267 				iMarshalledThreadList = MarshalListL( listRequest, (TAny*) &iThreadPointerList );
       
   268 				listRequest.iRequiredDescriptorSize = iMarshalledThreadList->Des().Size();
       
   269 				iTotalThreadListDescSize = listRequest.iRequiredDescriptorSize;
       
   270 								
       
   271 				break;
       
   272 				}
       
   273 		case TListRequest::EProcessList :
       
   274             {
       
   275 			iDataSource->GetProcessListL( iProcessPointerList, iTotalProcessListDescSize );
       
   276 
       
   277 			listRequest.iRemaining = iProcessPointerList.Count();
       
   278 
       
   279             //mark those that we observe
       
   280             for(TInt i = 0; i < iObservationList.Count(); i++)
       
   281                 {
       
   282                 for(TInt j = 0; j < iProcessPointerList.Count(); j++)
       
   283                     {
       
   284                     if( (iObservationList[i]->TargetName() == iProcessPointerList[j]->Name()) && //attached to it
       
   285                         (iObservationList[i]->ThreadCount() == 0) ) //and no threads on the list 
       
   286                         {
       
   287                         iProcessPointerList[j]->Observed(ETrue); 
       
   288                         }
       
   289                     }
       
   290                 }
       
   291 
       
   292 			if( NULL != iMarshalledProcessList )
       
   293 				{
       
   294 				delete iMarshalledProcessList;
       
   295 				}
       
   296 
       
   297 			//LOG_MSG( " EProcessList -> MarshalDataL()\n" );
       
   298 			iMarshalledProcessList = MarshalListL( listRequest, (TAny*) &iProcessPointerList );
       
   299 			listRequest.iRequiredDescriptorSize = iMarshalledProcessList->Des().Size();
       
   300 			iTotalProcessListDescSize = listRequest.iRequiredDescriptorSize;
       
   301 						
       
   302 			break;
       
   303 			}			
       
   304 		case TListRequest::EExecutableList :
       
   305             {
       
   306 			iDataSource->GetExecutableListL( iExecutablePointerList, iTotalExecutableListDescSize );
       
   307 
       
   308 			listRequest.iRemaining = iExecutablePointerList.Count();
       
   309 			//LOG_MSG2( "  listRequest.iRemaining=%d\n", listRequest.iRemaining );
       
   310 
       
   311             //mark those that we observe
       
   312             for(TInt i = 0; i < iObservationList.Count(); i++)
       
   313                 {
       
   314                 for(TInt j = 0; j < iExecutablePointerList.Count(); j++)
       
   315                     {
       
   316                     if( iObservationList[i]->TargetName() == iExecutablePointerList[j]->Name() )//attached to it
       
   317                         {
       
   318                         iExecutablePointerList[j]->Observed(ETrue); 
       
   319                         }
       
   320                     }
       
   321                 }
       
   322 
       
   323 			if( NULL != iMarshalledExecutableList )
       
   324 				{
       
   325 				delete iMarshalledExecutableList;
       
   326 				}
       
   327 
       
   328 			//LOG_MSG( " EExecutableList -> MarshalDataL()\n" );
       
   329 			iMarshalledExecutableList = MarshalListL( listRequest, (TAny*) &iExecutablePointerList );
       
   330 			listRequest.iRequiredDescriptorSize = iMarshalledExecutableList->Des().Size();
       
   331 			iTotalExecutableListDescSize = listRequest.iRequiredDescriptorSize;
       
   332 			
       
   333 			break;
       
   334 			}		
       
   335 		case TListRequest::EFormatterList :
       
   336             {
       
   337 			listRequest.iRemaining = iFormatterInfos.Count();
       
   338 
       
   339             if(iMarshalledFormatterList)
       
   340                 {
       
   341                 delete iMarshalledFormatterList;
       
   342                 }
       
   343 
       
   344             iMarshalledFormatterList = MarshalListL( listRequest, (TAny*) &iFormatterInfos );
       
   345 			listRequest.iRequiredDescriptorSize = iMarshalledFormatterList->Des().Size();
       
   346 			iTotalFormatterListDescSize = listRequest.iRequiredDescriptorSize;
       
   347 			
       
   348             break;
       
   349             }
       
   350 		case TListRequest::EWriterList :
       
   351             {
       
   352 			listRequest.iRemaining = iWriterInfos.Count();
       
   353 
       
   354             if(iMarshalledWriterList)
       
   355                 {
       
   356                 delete iMarshalledWriterList;
       
   357                 }
       
   358 
       
   359             iMarshalledWriterList = MarshalListL( listRequest, (TAny*) &iWriterInfos );
       
   360 			listRequest.iRequiredDescriptorSize = iMarshalledWriterList->Des().Size();
       
   361 			iTotalWriterListDescSize = listRequest.iRequiredDescriptorSize;
       
   362 			
       
   363             break;
       
   364             }
       
   365 		case TListRequest::ECrashList :
       
   366 			{
       
   367 			//Dealing with listing crashes from flash. Refresh the list and then
       
   368 			//serialise the list onto iMarshalledCrashList
       
   369 			
       
   370 			RefreshCrashListFromFlashL();			
       
   371 			listRequest.iRemaining = iCrashList.Count();
       
   372 			
       
   373 			if(iMarshalledCrashList)
       
   374 				{
       
   375 				delete iMarshalledCrashList;
       
   376 				iMarshalledCrashList = NULL;
       
   377 				}
       
   378 			
       
   379 			iMarshalledCrashList = MarshalListL(listRequest, (TAny*)&iCrashList);
       
   380 			listRequest.iRequiredDescriptorSize = iMarshalledCrashList->Des().Size();
       
   381 			iTotalCrashInfoDescSize = listRequest.iRequiredDescriptorSize;
       
   382 			
       
   383 			break;
       
   384 			}
       
   385 		default :
       
   386 			{
       
   387 			LOG_MSG2( " ERROR !* : CCoreDumpSession::ListInfoL() : invalid TListRequestType %d\n", listRequest.iListType );			
       
   388 			User::Leave( KErrArgument );
       
   389 			}
       
   390 		}
       
   391 
       
   392 	aMessage.WriteL( 0, listReqPtr );
       
   393 
       
   394 	}
       
   395 
       
   396 /**
       
   397  * This method looks at the crash logs in the flash partition
       
   398  * and caches them
       
   399  */
       
   400 void CCoreDumpSession::RefreshCrashListFromFlashL()
       
   401 	{	
       
   402 	LOG_MSG("CCoreDumpSession::RefreshCrashListFromFlashL()");
       
   403 	
       
   404 	TBuf8<Debug::KMaxCoreHeaderSize> buf;	
       
   405 	iCrashList.ResetAndDestroy();
       
   406 	
       
   407 	//Start looking where the config ends if it exists
       
   408 	TInt crashLogPos = 0;
       
   409 	SCMConfiguration* config = FlashDataSource()->GetSCMConfigFromFlashL();
       
   410 	if(config)
       
   411 		{
       
   412 		crashLogPos = config->GetSize();
       
   413 		}
       
   414 	
       
   415 	delete config;
       
   416 	
       
   417 	do
       
   418 		{
       
   419 		LOG_MSG3("Looking for crash at [%d]   [0x%X]", crashLogPos, crashLogPos);
       
   420 
       
   421 		//Read in the 2 headers and the context, while we are in the crash log		
       
   422 		TInt err = iSecSess.ReadCrashLog(crashLogPos, buf, Debug::KMaxCoreHeaderSize);
       
   423 		if(err != KErrNone)
       
   424 			{
       
   425 			if(err == KErrPermissionDenied)
       
   426 				{
       
   427 				User::Leave(err);
       
   428 				}
       
   429 			
       
   430 			//We have reached the end of the crash partition
       
   431 			return;
       
   432 			}
       
   433 		
       
   434 		TCrashLogWalker wlk(buf);
       
   435 					
       
   436 		if(KErrNone == wlk.ReadLogHeader(0))
       
   437 			{
       
   438 			LOG_MSG("Found a valid crash");
       
   439 			const TCrashInfoHeader hdr = wlk.GetCrashHeader();
       
   440 			TCrashInfo* inf = TCrashInfo::NewL(hdr);
       
   441 			inf->iCrashSource = TCrashInfo::ESystemCrash;
       
   442 			inf->iContext = wlk.GetCrashContext();
       
   443 			
       
   444 			iCrashList.Append(inf);
       
   445 			
       
   446 			//Increment this so it goes up by the log size AND then enough to align it to a flash block
       
   447 			TUint32 flashPadding = 0x20000 - (crashLogPos + hdr.iLogSize)%0x20000;
       
   448 			crashLogPos += (hdr.iLogSize + flashPadding);
       
   449 			}
       
   450 		else
       
   451 			{			
       
   452 			//otherwise we dont have any more crashes			
       
   453 			return;
       
   454 			}
       
   455 		
       
   456 		}
       
   457 	while(true);		
       
   458 	
       
   459 	}
       
   460 
       
   461 
       
   462 /**
       
   463  * Processes the crash log in the flash partition corrosponding to the crash ID of the parameter 
       
   464  * passed through. If this doesnt match a crash in the partition, or the flash cannot be read 
       
   465  * this will leave with KErrCorrupted
       
   466  * @param aMessage
       
   467  * @leave one of the OS wide codes
       
   468  */
       
   469 void CCoreDumpSession::ProcessCrashLogL(const RMessage2& aMessage)
       
   470 	{
       
   471 	TInt crashId = aMessage.Int0();	
       
   472 	LOG_MSG2("->CCoreDumpSession::ProcessCrashLogL(ID = [%d])\n",  crashId);
       
   473 	
       
   474 	RefreshCrashListFromFlashL();
       
   475 	
       
   476 	for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++)
       
   477 		{
       
   478 		if(iCrashList[cnt]->iCrashId == crashId)
       
   479 			{
       
   480 			RDebug::Printf("Going to the crash handler");
       
   481 			iCrashHandler->HandleCrashFromFlashL(*(iCrashList[cnt]));
       
   482 			}
       
   483 		}
       
   484 	}
       
   485 
       
   486 /**
       
   487  * Processes the crash log in the flash partition Asynchronously corrosponding to the crash ID of the parameter 
       
   488  * passed through. It refreshes the crash list and then calls the crash handler. Leaves with standard leave codes 
       
   489  * when the underlying methods leave.  
       
   490  * @param aMessage
       
   491  * @leave one of the OS wide codes
       
   492  */
       
   493 void CCoreDumpSession::ProcessCrashLogAsyncL(const RMessage2& aMessage)
       
   494 	{
       
   495 	TInt crashId = aMessage.Int0();	
       
   496 	LOG_MSG2("->CCoreDumpSession::ProcessCrashLogAsyncL(ID = [%d])\n",  crashId);
       
   497 	
       
   498 	RefreshCrashListFromFlashL();
       
   499 	
       
   500 	for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++)
       
   501 		{
       
   502 		if(iCrashList[cnt]->iCrashId == crashId)
       
   503 			{
       
   504 			LOG_MSG("Going to the crash handler using the async mechanism");
       
   505 			iCrashHandler->HandleCrashFromFlashL(*(iCrashList[cnt]), aMessage);
       
   506 			}
       
   507 		}
       
   508 	}
       
   509 
       
   510 /**
       
   511  * Cancels asynchronous processing of the crash log in the flash partition  
       
   512  * @param aMessage
       
   513  */
       
   514 void CCoreDumpSession::CancelProcessCrashLogAsync(const RMessage2& aMessage)
       
   515 	{
       
   516 	TInt crashId = aMessage.Int0();	
       
   517 	LOG_MSG2("->CCoreDumpSession::CancelProcessCrashLogAsyncL(ID = [%d])\n",  crashId);
       
   518 	
       
   519 	for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++)
       
   520 		{
       
   521 		if(iCrashList[cnt]->iCrashId == crashId)
       
   522 			{
       
   523 			LOG_MSG("Going to the cancel async crash handler processing");
       
   524 			iCrashHandler->CancelHandleCrashFromFlash(*(iCrashList[cnt]));
       
   525 			}
       
   526 		}
       
   527 	}
       
   528 
       
   529 /**
       
   530  * From a crash ID gets a TCrashInfo
       
   531  * @param aCrashId crash ID to search for
       
   532  * @param aCrashInfo the crash info for supplied crash ID
       
   533  * @leave one of the OS wide codes
       
   534  */
       
   535 void CCoreDumpSession::GetCrashInfoL(TInt aCrashId, TCrashInfo& aCrashInfo)
       
   536 	{
       
   537 	for(TInt i = 0; i<iCrashList.Count(); i++)
       
   538 		{
       
   539 		if(iCrashList[i]->iCrashId == aCrashId)
       
   540 			{
       
   541 			aCrashInfo = *(iCrashList[i]);
       
   542 			return;
       
   543 			}
       
   544 		}
       
   545 	
       
   546 	User::Leave(KErrNotFound);
       
   547 	}
       
   548 
       
   549 /**
       
   550     Retrives the 'cancel crash' property value and checks if required to abort the crash dump. Updates 'crash progress' property. 
       
   551 
       
   552 @param aProgress descriptor with the crash progress value.
       
   553 @leave KErrAbort if crash cancel property has been set
       
   554  */
       
   555 void CCoreDumpSession::UpdateProgressL(const TDesC &aProgress) const
       
   556     {
       
   557     LOG_MSG("->CCoreDumpSession::UpdateProgressL()\n");
       
   558     TInt cancelCrash = EFalse;
       
   559     TInt err = RProperty::Get(KCoreDumpServUid, ECrashProgress, cancelCrash);
       
   560     if(err != KErrNone)
       
   561         {
       
   562         LOG_MSG2("CCoreDumpSession::UpdateProgressL - unable to retrive 'ECrashProgress' value! err:%d\n", err);
       
   563         }
       
   564 
       
   565     if(cancelCrash)
       
   566         {
       
   567         LOG_MSG("CCoreDumpSession::UpdateProgressL - aborting dump in progress\n");
       
   568         User::Leave(KErrNotReady);
       
   569         }
       
   570 
       
   571     err = RProperty::Set(KCoreDumpServUid, ECrashProgress, aProgress);
       
   572     if(err != KErrNone)
       
   573         {
       
   574         LOG_MSG2("CCoreDumpSession::UpdateProgressL - unable to retrive 'crash progress' value! err:%d\n", err);
       
   575         }
       
   576 #ifdef DEBUG 
       
   577     User::After(1000000);
       
   578 #endif
       
   579   }
       
   580 
       
   581 /**
       
   582  * This method removes a crash log from the flash partition
       
   583  * @param aMessage
       
   584  * @leave one of the OS wide codes
       
   585  */
       
   586 void CCoreDumpSession::DeleteCrashLogL(const RMessage2& aMessage) 
       
   587 	{
       
   588 	User::Leave(KErrNotSupported);
       
   589 	}
       
   590 
       
   591 void CCoreDumpSession::DeleteCrashPartitionL()
       
   592 	{
       
   593 	LOG_MSG("CCoreDumpSession::DeleteCrashPartitionL()");
       
   594 	
       
   595 	UpdateProgressL(_L("Erasing Entire Log"));
       
   596 
       
   597 	//Read in config first
       
   598 	SCMConfiguration* config = FlashDataSource()->GetSCMConfigFromFlashL();
       
   599 	TCleanupItem scmCleanup(CCoreDumpSession::CleanupSCMConfiguration, (TAny*)config);
       
   600 	if(config)
       
   601 		CleanupStack::PushL(scmCleanup);
       
   602 	
       
   603 	TInt err = iSecSess.EraseCrashFlashPartition();	
       
   604 	User::LeaveIfError(err);	
       
   605 	
       
   606 	if(config)
       
   607 		{
       
   608 		//Now we rewrite the config
       
   609 		RBuf8 data;	
       
   610 		data.CreateL(config->GetSize());
       
   611 		data.SetLength(config->GetSize());
       
   612 		data.CleanupClosePushL();
       
   613 			
       
   614 		TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse);	
       
   615 		config->Serialize(writer);
       
   616 			
       
   617 		TUint32 written = 0;
       
   618 		User::LeaveIfError(iSecSess.WriteCrashConfig(0, data, written));
       
   619 		
       
   620 		CleanupStack::PopAndDestroy(2);//data and scmCleanup
       
   621 		}
       
   622 	
       
   623 	RefreshCrashListFromFlashL();	
       
   624 
       
   625 	UpdateProgressL(_L("Idle"));
       
   626 	}
       
   627 
       
   628 void CCoreDumpSession::CreateWriterL( const TUid loadRequestUid )
       
   629 	{
       
   630 	LOG_MSG("->CCoreDumpSession::CreateWriterL()\n" );
       
   631 
       
   632 	ValidatePluginL( loadRequestUid );
       
   633 
       
   634     if(iPluginList.Count() == 0)
       
   635         {
       
   636         RefreshPluginListL();
       
   637         }
       
   638 
       
   639     CPluginInfo *info = NULL;
       
   640     for(TInt i = 0; i < iPluginList.Count(); i++)
       
   641         {
       
   642         if(iPluginList[i].iUid == loadRequestUid)
       
   643             {
       
   644                 info = CPluginInfo::NewL(iPluginList[i].iName,
       
   645                                          loadRequestUid.iUid,
       
   646                                          iPluginList[i].iVersion,
       
   647                                          TPluginRequest::EWriter);        
       
   648                 CleanupStack::PushL(info);
       
   649                 break;
       
   650             }
       
   651         }
       
   652 
       
   653     if(!info)
       
   654         {
       
   655         LOG_MSG2("CCoreDumpSession::CreateWriterL - unable to find writer uid:%d on plugin type list!\n", loadRequestUid);
       
   656         User::Leave(KErrArgument); 
       
   657         }
       
   658 
       
   659     iWriterInfos.AppendL(info);
       
   660     CleanupStack::Pop(info);
       
   661     
       
   662 	CCrashDataSave *writer = CCrashDataSave::NewL( (TUid)( loadRequestUid ) );
       
   663 
       
   664     CleanupStack::PushL(writer);
       
   665     iWriterPlugins.AppendL(writer);
       
   666     CleanupStack::Pop(writer);
       
   667 
       
   668     LOG_MSG3("CCoreDumpSession::CreateFormatter fmt:%d, wrt:%d\n", iFormatterPlugins.Count(), iWriterPlugins.Count());
       
   669     //for compatibility, first pair is bound by default
       
   670     if( (iFormatterPlugins.Count() == 1) && (iWriterPlugins.Count() == 1) )
       
   671         {
       
   672 	        LOG_MSG("CCoreDumpSession::CreateFormatter binding default plugin pair\n" );
       
   673             iFormatterInfos[0]->Pair(0);
       
   674             iFormatterPlugins[0]->ConfigureDataSaveL(iWriterPlugins[0]);
       
   675         }
       
   676 	}
       
   677 
       
   678 void CCoreDumpSession::CreateFormatterL( const TUid loadRequestUid )
       
   679 	{	
       
   680 	LOG_MSG( "->CCoreDumpSession::CreateFormatter()\n" );
       
   681 
       
   682 	ValidatePluginL( loadRequestUid );
       
   683 	
       
   684 	if(iPluginList.Count() == 0)
       
   685 		{		
       
   686 		RefreshPluginListL();
       
   687 		}
       
   688 
       
   689     CPluginInfo *info = NULL;
       
   690     for(TInt i = 0; i < iPluginList.Count(); i++)
       
   691         {    	
       
   692         if(iPluginList[i].iUid == loadRequestUid)
       
   693             {
       
   694                 info = CPluginInfo::NewL(iPluginList[i].iName,
       
   695                                          loadRequestUid.iUid,
       
   696                                          iPluginList[i].iVersion,
       
   697                                          TPluginRequest::EFormatter);        
       
   698                 CleanupStack::PushL(info);
       
   699                 break;
       
   700             }
       
   701         }
       
   702 
       
   703     if(!info)
       
   704         {
       
   705         LOG_MSG2("CCoreDumpSession::CreateFormatterL - unable to find formatter uid:%X on plugin type list!\n", loadRequestUid);
       
   706         User::Leave(KErrArgument);
       
   707         }
       
   708 
       
   709     iFormatterInfos.AppendL(info);
       
   710     CleanupStack::Pop(info);
       
   711 
       
   712 	CCoreDumpFormatter *formatter = CCoreDumpFormatter::NewL( (TUid)( loadRequestUid ) );
       
   713 
       
   714     CleanupStack::PushL(formatter);
       
   715     iFormatterPlugins.AppendL(formatter);
       
   716     CleanupStack::Pop(formatter);
       
   717 
       
   718     LOG_MSG3("CCoreDumpSession::CreateFormatter fmt:%d, wrt:%d\n", iFormatterPlugins.Count(), iWriterPlugins.Count());
       
   719     //for compatibility, first pair is bound by default
       
   720     if( (iFormatterPlugins.Count() == 1) && (iWriterPlugins.Count() == 1) )
       
   721         {
       
   722 	        LOG_MSG("CCoreDumpSession::CreateFormatter binding default plugin pair\n" );
       
   723             iFormatterInfos[0]->Pair(0);
       
   724             iFormatterPlugins[0]->ConfigureDataSaveL(iWriterPlugins[0]);
       
   725         }
       
   726 	}
       
   727 
       
   728 void CCoreDumpSession::DeleteFormatterL( const TUid aFreeRequestUid, const TUint aIndex )
       
   729 {
       
   730     LOG_MSG("->CCoreDumpSession::DeleteFormatterL()\n");
       
   731     if( (iFormatterInfos.Count() > aIndex) && (iFormatterInfos[aIndex]->Uid() == aFreeRequestUid.iUid) )
       
   732     {
       
   733         delete iFormatterPlugins[aIndex];
       
   734         iFormatterPlugins.Remove(aIndex);
       
   735 
       
   736         delete iFormatterInfos[aIndex];
       
   737         iFormatterInfos.Remove(aIndex);
       
   738     }
       
   739     else
       
   740     {
       
   741         User::Leave(KErrArgument);
       
   742     }
       
   743 }
       
   744 
       
   745 void CCoreDumpSession::DeleteWriterL( const TUid aFreeRequestUid, const TUint aIndex )
       
   746 {
       
   747     LOG_MSG("->CCoreDumpSession::DeleteWriterL()\n");
       
   748     if( (iWriterInfos.Count() > aIndex) && (iWriterInfos[aIndex]->Uid() == aFreeRequestUid.iUid) )
       
   749     {
       
   750         for(TInt i = 0; i < iFormatterInfos.Count(); i++)
       
   751         {
       
   752             if(iFormatterInfos[i]->Pair() == aIndex)
       
   753             {
       
   754                 iFormatterInfos[i]->Pair(KMaxTUint32);
       
   755             }
       
   756         }
       
   757 
       
   758         delete iWriterPlugins[aIndex];
       
   759         iWriterPlugins.Remove(aIndex);
       
   760 
       
   761         delete iWriterInfos[aIndex];
       
   762         iWriterInfos.Remove(aIndex);
       
   763     }
       
   764     else
       
   765     {
       
   766         User::Leave(KErrArgument);
       
   767     }
       
   768 }
       
   769 
       
   770 void CCoreDumpSession::PluginRequestL(const RMessage2& aMessage)
       
   771 {
       
   772 	LOG_MSG("->CCoreDumpSession::PluginRequestL()\n");
       
   773 
       
   774 	TPluginRequest request;
       
   775 	TPtr8 pluginReqPtr((TUint8 *)&request, sizeof(TPluginRequest));
       
   776 	aMessage.ReadL(0, pluginReqPtr);
       
   777 	
       
   778     if(request.iUid.iUid != 0) //(un)load a plugin
       
   779     { 
       
   780         if(request.iPluginType == TPluginRequest::EFormatter)
       
   781         {
       
   782             if(request.iLoad)
       
   783             {
       
   784                 CreateFormatterL(request.iUid);
       
   785             }
       
   786             else
       
   787             {
       
   788                 //index mapping compatibility  - one plugin at a time case
       
   789                 TUint index = (request.iIndex == request.iPair) ? request.iIndex : 0;
       
   790                 DeleteFormatterL(request.iUid, index);
       
   791             }
       
   792         }
       
   793         else if(request.iPluginType == TPluginRequest::EWriter)
       
   794         {
       
   795             if(request.iLoad)
       
   796             {
       
   797                 CreateWriterL(request.iUid);
       
   798             }
       
   799             else
       
   800             {
       
   801                 //index mapping compatibility - one plugin at a time case
       
   802                 TUint index = (request.iIndex == request.iPair) ? request.iIndex : 0;
       
   803                 DeleteWriterL(request.iUid, index);
       
   804             }
       
   805         }
       
   806         else
       
   807         {
       
   808             LOG_MSG2("CCoreDumpSession::PluginRequestL() - invalid plugin type:%d!\n", request.iPluginType);
       
   809             User::Leave(KErrNotSupported);
       
   810         }
       
   811 	    UpdateConfigParametersL();
       
   812     }
       
   813     else //bind a plugin pair
       
   814     {
       
   815         BindPluginsL(request.iIndex, request.iPair);
       
   816     }
       
   817 }
       
   818 
       
   819 void CCoreDumpSession::BindPluginsL(const TUint aFormatterIndex, const TUint aWriterIndex)
       
   820 {
       
   821    LOG_MSG3("->CCoreDumpSession::BindPluginsL(fmt=%d, wrt=%d)\n", aFormatterIndex, aWriterIndex);
       
   822    if( (aFormatterIndex < iFormatterInfos.Count()) && (aWriterIndex < iWriterInfos.Count()) )
       
   823    {
       
   824         iFormatterInfos[aFormatterIndex]->Pair(aWriterIndex);
       
   825         iFormatterPlugins[aFormatterIndex]->ConfigureDataSaveL(iWriterPlugins[aWriterIndex]);
       
   826    }
       
   827    else
       
   828    {
       
   829         LOG_MSG5("CCoreDumpSession::BindPluginsL -> fmtIndex:%d/%d wrtIndex:%d/%d\n", aFormatterIndex, iFormatterInfos.Count(),
       
   830                                                                                      aWriterIndex, iWriterInfos.Count());
       
   831         User::Leave(KErrNotFound);
       
   832    }
       
   833 }
       
   834 
       
   835 CCoreDumpFormatter* CCoreDumpSession::GetValidFormatter(const TUint aCount)
       
   836 {
       
   837     LOG_MSG2("->CCoreDumpSession::ValidFormatter(aCount=%d)", aCount);
       
   838     TUint counter = 0;
       
   839 
       
   840     for(TInt i = 0; i < iFormatterInfos.Count(); i++)
       
   841     {
       
   842         LOG_MSG3("CCoreDumpSession::ValidFormatter() - fmt[%d]->pair=%d", i, iFormatterInfos[i]->Pair());
       
   843         if( (iFormatterInfos[i]->Pair() < iWriterInfos.Count()) && ( counter++ == aCount))
       
   844         {
       
   845             LOG_MSG2("CCoreDumpSession::ValidFormatter() - found valid formatter=%d", iFormatterPlugins[i]);
       
   846             return iFormatterPlugins[i];
       
   847         }
       
   848     }
       
   849     return NULL;
       
   850 }
       
   851 
       
   852 static void CleanupEComArray(TAny* aArray)
       
   853 {
       
   854 	(static_cast<RImplInfoPtrArray*> (aArray))->ResetAndDestroy();
       
   855 	(static_cast<RImplInfoPtrArray*> (aArray))->Close();
       
   856 }
       
   857 
       
   858 void CCoreDumpSession::RefreshPluginListL()
       
   859 {
       
   860 	LOG_MSG("->CCoreDumpSession::RefreshPluginList()\n");
       
   861 
       
   862 	iPluginList.Close();
       
   863 	TPluginInfo ref;
       
   864 
       
   865 	RImplInfoPtrArray infoArray;
       
   866 	TCleanupItem cleanup(CleanupEComArray, &infoArray);
       
   867 	CleanupStack::PushL(cleanup);
       
   868     
       
   869 	CCoreDumpFormatter::ListAllImplementationsL( infoArray );
       
   870 
       
   871 	for ( TInt i = 0; i < infoArray.Count(); i++ )
       
   872 		{
       
   873 		ref.iVersion = infoArray[i]->Version();
       
   874 		ref.iName = infoArray[i]->DisplayName();
       
   875 		ref.iUid = infoArray[i]->ImplementationUid();
       
   876 		ref.iType = TPluginRequest::EFormatter;
       
   877 
       
   878         ref.iLoaded = EFalse; //iLoaded on this list means we have an instance of that plugin
       
   879         for(TInt j = 0; j < iFormatterInfos.Count(); j++)
       
   880         {
       
   881             if(iFormatterInfos[j]->Uid() == ref.iUid.iUid)
       
   882             {
       
   883                 ref.iLoaded = ETrue;
       
   884                 break;
       
   885             }
       
   886         }
       
   887 
       
   888 		iPluginList.AppendL(ref);
       
   889 		}
       
   890 	
       
   891 	infoArray.ResetAndDestroy();
       
   892 
       
   893 	CCrashDataSave::ListAllImplementationsL( infoArray );
       
   894 
       
   895 	for ( TInt i = 0; i < infoArray.Count(); i++ )
       
   896 		{
       
   897 		ref.iVersion = infoArray[i]->Version();
       
   898 		ref.iName = infoArray[i]->DisplayName();
       
   899 		ref.iUid = infoArray[i]->ImplementationUid();
       
   900 		ref.iType = TPluginRequest::EWriter;
       
   901 
       
   902         ref.iLoaded = EFalse; //iLoaded on this list means we have an instance of that plugin
       
   903         for(TInt j = 0; j < iWriterInfos.Count(); j++)
       
   904         {
       
   905             if(iWriterInfos[j]->Uid() == ref.iUid.iUid)
       
   906             {
       
   907                 ref.iLoaded = ETrue;
       
   908                 break;
       
   909             }
       
   910         }
       
   911 
       
   912 		iPluginList.AppendL(ref);
       
   913 		}
       
   914 
       
   915 	CleanupStack::PopAndDestroy();
       
   916 }
       
   917 
       
   918 void CCoreDumpSession::GetPluginListL(const RMessage2& aMessage)
       
   919 	{
       
   920 	//LOG_MSG("->CCoreDumpSession::GetPluginList()\n");
       
   921 
       
   922 	TListRequest listRequest; 
       
   923 
       
   924 	TPtr8 pluginReqPtr((TUint8 *)&listRequest, sizeof(TListRequest));
       
   925 
       
   926 	//read target debug app address and size from debug agent
       
   927 	aMessage.ReadL(0, pluginReqPtr);
       
   928 
       
   929 	TPluginInfoBlock * plugins = new (ELeave) TPluginInfoBlock;
       
   930     CleanupStack::PushL(plugins);
       
   931 
       
   932 	if( 0 == listRequest.iIndex )
       
   933 		{
       
   934 		iPluginList.Reset();
       
   935 		RefreshPluginListL();
       
   936 		}
       
   937 
       
   938 	TUint toSupply = iPluginList.Count() - listRequest.iIndex;
       
   939 	if ( toSupply > KNumPluginDetails )
       
   940 		{
       
   941 		toSupply = KNumPluginDetails;
       
   942 		}
       
   943 
       
   944 	for( TUint index = 0; index < toSupply; index ++ )
       
   945 		{
       
   946 		plugins->plugins[index].iVersion		= iPluginList[index+listRequest.iIndex].iVersion;
       
   947 		plugins->plugins[index].iName			= iPluginList[index+listRequest.iIndex].iName;
       
   948 		plugins->plugins[index].iDescription	= iPluginList[index+listRequest.iIndex].iDescription;
       
   949 		plugins->plugins[index].iUid			= iPluginList[index+listRequest.iIndex].iUid;
       
   950 		plugins->plugins[index].iType			= iPluginList[index+listRequest.iIndex].iType;
       
   951 		plugins->plugins[index].iLoaded			= iPluginList[index+listRequest.iIndex].iLoaded;
       
   952 		//RDebug::Print( _L("  loaded[%d]=%d\n"), index, plugins->plugins[index].iLoaded );
       
   953 		}
       
   954 
       
   955 	listRequest.iSupplied = toSupply;
       
   956 	listRequest.iRemaining = iPluginList.Count() - (listRequest.iIndex + listRequest.iSupplied);
       
   957 
       
   958 	//RDebug::Print( _L("  supplying=%d, remaining=%d\n"), toSupply, listRequest.iRemaining );
       
   959 
       
   960 	aMessage.WriteL(0, pluginReqPtr);
       
   961 	TPtr8 pluginArrPtr( (TUint8 *)plugins, sizeof(TPluginInfoBlock) );
       
   962 	pluginArrPtr.Set( (TUint8 *)plugins, sizeof(TPluginInfoBlock), sizeof(TPluginInfoBlock) );
       
   963 
       
   964 	aMessage.WriteL(1, pluginArrPtr);
       
   965     CleanupStack::PopAndDestroy(plugins);
       
   966 	}
       
   967 
       
   968 void CCoreDumpSession::ObservationRequestL( const RMessage2& aMessage )
       
   969     {
       
   970 	//RDebug::Print(_L("->CCoreDumpSession::ObservationRequestL()\n"));
       
   971     TInt deslen;
       
   972     deslen = aMessage.GetDesLengthL(0);
       
   973 	if (deslen == 0)
       
   974 		{
       
   975 		// Zero-length target name supplied
       
   976 		User::Leave(KErrArgument);
       
   977 		}
       
   978 
       
   979 	RBuf targetName;
       
   980 	targetName.CleanupClosePushL();
       
   981 	targetName.CreateL(deslen);
       
   982 	// Read the target name into targetName
       
   983 	aMessage.ReadL(0, targetName);
       
   984 
       
   985     deslen = aMessage.GetDesLengthL(1);
       
   986 	if (deslen == 0)
       
   987 		{
       
   988 		// Zero-length target owner name supplied
       
   989 		User::Leave(KErrArgument);
       
   990 		}
       
   991 
       
   992 	RBuf targetOwnerName;
       
   993 	targetOwnerName.CleanupClosePushL();
       
   994 	targetOwnerName.CreateL(deslen);
       
   995 	// Read the target owner name into targetOwnerName
       
   996 	aMessage.ReadL(1, targetOwnerName);
       
   997 
       
   998     TBool observe = static_cast<TBool>(aMessage.Int2());
       
   999     if(observe)
       
  1000         {
       
  1001         LOG_MSG("CCoreDumpSession::ObservationRequestL - KAttach\n" );
       
  1002         AttachTargetL(targetName, targetOwnerName);
       
  1003         }
       
  1004     else
       
  1005         {
       
  1006         LOG_MSG("CCoreDumpSession::ObservationRequestL - KDetach\n");
       
  1007         DetachTargetL(targetName, targetOwnerName);
       
  1008         }
       
  1009 
       
  1010     CleanupStack::PopAndDestroy(&targetOwnerName);
       
  1011     CleanupStack::PopAndDestroy(&targetName);
       
  1012     }
       
  1013 
       
  1014 void CCoreDumpSession::AttachTargetL( const TDesC &aTargetName, const TDesC &aTargetOwnerName )
       
  1015     {
       
  1016 	//LOG_MSG("->CoreDumpSession::AttachTargetL()\n");
       
  1017     TBool found = EFalse;
       
  1018 
       
  1019     for(TInt i = 0; i < iObservationList.Count(); ++i)
       
  1020         {
       
  1021         if(iObservationList[i]->TargetName() == aTargetOwnerName)
       
  1022             {
       
  1023             if(aTargetName != aTargetOwnerName) //attach thread
       
  1024                 {
       
  1025                 iObservationList[i]->AddThreadL(aTargetName);
       
  1026                 //LOG_MSG("CoreDumpSession::AttachTargetL - thread added\n");
       
  1027                 }
       
  1028             else
       
  1029                 {
       
  1030                 LOG_MSG("CoreDumpSession::AttachTargetL - process added\n");
       
  1031                 iObservationList[i]->ClearThreads();
       
  1032                 } 
       
  1033             found = ETrue;
       
  1034             break;
       
  1035             }
       
  1036         }
       
  1037 
       
  1038     if(!found)
       
  1039         {
       
  1040         //RDebug::Printf( "CoreDumpSession::AttachTargetL - creating new observer", &aTargetOwnerName );
       
  1041         CTargetObserver *observer = CTargetObserver::NewLC( iSecSess, *iCrashHandler, aTargetOwnerName ); 
       
  1042         User::LeaveIfError( iObservationList.Insert(observer, 0) );
       
  1043         
       
  1044         if(aTargetName != aTargetOwnerName) //attach thread
       
  1045             {
       
  1046             observer->AddThreadL(aTargetName);
       
  1047             //LOG_MSG("CoreDumpSession::AttachTargetL - thread added\n");
       
  1048             }
       
  1049 
       
  1050         if( (iPreCrashEventAction & ESuspendThread) || 
       
  1051 			(iPreCrashEventAction & ESuspendProcess) )
       
  1052 			{
       
  1053 			LOG_MSG("CCoreDumpSession::AttachTargetL() ->SetCrashEventsL(EActionSuspend)\n" );
       
  1054             SetCrashEventsL(*observer, EActionSuspend);
       
  1055 			}
       
  1056         else
       
  1057 			{
       
  1058 			LOG_MSG("CCoreDumpSession::AttachTargetL() ->SetCrashEventsL(EActionContinue)\n" );
       
  1059             SetCrashEventsL(*observer, EActionContinue);
       
  1060 			}
       
  1061 
       
  1062         observer->Observe();
       
  1063 
       
  1064 	    //LOG_MSG("CoreDumpSession::AttachTargetL - observer started\n");
       
  1065         CleanupStack::Pop(); //observer is now in the iObservationList 
       
  1066         }
       
  1067     }
       
  1068 
       
  1069 void CCoreDumpSession::SetCrashEventsL(CTargetObserver &aObserver, TKernelEventAction aAction)
       
  1070 {
       
  1071 	LOG_MSG2("CCoreDumpSession::SetCrashEventsL(aAction=%d)\n", aAction);
       
  1072 
       
  1073     if(iCrashEventTypes & ECrashHwExc)
       
  1074 		{
       
  1075 		LOG_MSG2("  aObserver.SetCrashEventL(EEventsHwExc, aAction=%d)\n", aAction);
       
  1076         aObserver.SetCrashEventL(EEventsHwExc, aAction);
       
  1077 		}
       
  1078     else
       
  1079 		{
       
  1080 		LOG_MSG("  aObserver.SetCrashEventL(EEventsHwExc, EActionIgnore)\n");
       
  1081         aObserver.SetCrashEventL(EEventsHwExc, EActionIgnore);
       
  1082 		}
       
  1083 
       
  1084     if(iCrashEventTypes & ECrashKillThread)
       
  1085 		{
       
  1086 		LOG_MSG2("  aObserver.SetCrashEventL(EEventsKillThread, aAction=%d)\n", aAction);
       
  1087         aObserver.SetCrashEventL(EEventsKillThread, aAction);
       
  1088 		}
       
  1089     else
       
  1090 		{
       
  1091 		LOG_MSG("  aObserver.SetCrashEventL(EEventsKillThread, EActionIgnore)\n");
       
  1092         aObserver.SetCrashEventL(EEventsKillThread, EActionIgnore);
       
  1093 		}
       
  1094 }
       
  1095 
       
  1096 void CCoreDumpSession::DetachTargetL( const TDesC &aTargetName, const TDesC &aTargetOwnerName )
       
  1097     {
       
  1098 	//LOG_MSG("->CoreDumpSession::DetachTargetL()\n");
       
  1099     TBool found = EFalse;
       
  1100 
       
  1101     RBuf ton;
       
  1102     ton.CreateL(aTargetName);
       
  1103     char *tonp = (char*) ton.Collapse().PtrZ();
       
  1104     LOG_MSG2("CCoreDumpSession::DetachTargetL(%s)\n", tonp);
       
  1105     ton.Close();
       
  1106 
       
  1107     RBuf otn;
       
  1108     TInt count = iObservationList.Count();
       
  1109     for(TInt i = 0; i < count; ++i)
       
  1110         {
       
  1111         otn.CreateL(iObservationList[i]->TargetName());
       
  1112         char* otnp = (char*) otn.Collapse().PtrZ();
       
  1113         LOG_MSG3("CCoreDumpSession::DetachTargetL - iObservationList[%d]->TargetName=%s\n", i, otnp);
       
  1114         otn.Close();
       
  1115         if (iObservationList[i]->TargetName() == aTargetOwnerName)
       
  1116             {
       
  1117             if(aTargetName != aTargetOwnerName) //detach thread
       
  1118                 {
       
  1119                 iObservationList[i]->DelThreadL(aTargetName);
       
  1120                 LOG_MSG("CoreDumpSession::DetachTargetL - thread removed\n");
       
  1121                 }
       
  1122             if(iObservationList[i]->ThreadCount() == 0) //no more threads to observe or detach process
       
  1123                 {
       
  1124                 LOG_MSG("CoreDumpSession::DetachTargetL - destroying observer\n");
       
  1125                 delete iObservationList[i]; 
       
  1126                 iObservationList.Remove(i);
       
  1127                 }
       
  1128             found = ETrue;
       
  1129             break;
       
  1130             }
       
  1131         }
       
  1132 
       
  1133     if(!found)
       
  1134         {
       
  1135         LOG_MSG("CoreDumpSession::DetachTargetL - target not found\n");
       
  1136         User::Leave(KErrNotFound);
       
  1137         }
       
  1138     }
       
  1139 
       
  1140 void CCoreDumpSession::UpdateConfigParametersL()
       
  1141 {
       
  1142 	LOG_MSG( "->CCoreDumpSession::UpdateConfigParametersL()\n" );
       
  1143 
       
  1144     COptionConfig *config = NULL;
       
  1145     iTotalConfigList.Reset();
       
  1146     TUint configParamSize;
       
  1147     
       
  1148     TInt paramNum = iConfigList.Count();
       
  1149 	for(TInt i = 0; i < paramNum; i++ )
       
  1150 		{
       
  1151         config = iConfigList[i];
       
  1152         
       
  1153         if(!config)
       
  1154             {
       
  1155             User::Leave(KErrBadHandle);
       
  1156             }
       
  1157 
       
  1158         configParamSize = config->Size();
       
  1159         if(configParamSize > iMaxConfigParamSize)
       
  1160             {
       
  1161             iMaxConfigParamSize = configParamSize ;
       
  1162             }
       
  1163         iTotalConfigList.AppendL(config);
       
  1164 		}
       
  1165 
       
  1166 
       
  1167     for(TInt i = 0; i < iFormatterPlugins.Count(); i++)
       
  1168         {
       
  1169         paramNum = iFormatterPlugins[i]->GetNumberConfigParametersL();
       
  1170         for(TInt index = 0; index < paramNum; index++)
       
  1171             {
       
  1172             config = iFormatterPlugins[i]->GetConfigParameterL(index);
       
  1173             if(!config)
       
  1174                 {
       
  1175                 User::Leave(KErrBadHandle);
       
  1176                 }
       
  1177 
       
  1178             configParamSize = config->Size();
       
  1179             if(configParamSize > iMaxConfigParamSize)
       
  1180                 {
       
  1181                 iMaxConfigParamSize = configParamSize ;
       
  1182                 }
       
  1183 
       
  1184             config->Instance(i); 
       
  1185             iTotalConfigList.AppendL(config);
       
  1186             }
       
  1187         }
       
  1188 
       
  1189     for(TInt i = 0; i < iWriterPlugins.Count(); i++)
       
  1190         {
       
  1191         paramNum = iWriterPlugins[i]->GetNumberConfigParametersL();
       
  1192         for(TInt index = 0; index < paramNum; index++)
       
  1193             {
       
  1194             config = iWriterPlugins[i]->GetConfigParameterL(index);
       
  1195             if(!config)
       
  1196                 {
       
  1197                 User::Leave(KErrBadHandle);
       
  1198                 }
       
  1199 
       
  1200             configParamSize = config->Size();
       
  1201             if(configParamSize > iMaxConfigParamSize)
       
  1202                 {
       
  1203                 iMaxConfigParamSize = configParamSize ;
       
  1204                 }
       
  1205 
       
  1206             config->Instance(i); 
       
  1207             iTotalConfigList.AppendL(config);
       
  1208             }
       
  1209         }
       
  1210     
       
  1211     
       
  1212 	TRAPD(err, iFlashDataSource->ReadSCMConfigL(iScmConfigList));
       
  1213 	if(err != KErrNone)
       
  1214 		{
       
  1215 		LOG_MSG("Unable to retrieve config params for the SCM: [%d]");
       
  1216 		return;
       
  1217 		}
       
  1218 	
       
  1219     for(TInt i=0;i<iScmConfigList.Count();i++)
       
  1220     	{
       
  1221     	iTotalConfigList.AppendL(iScmConfigList[i]);
       
  1222     	} 
       
  1223 	}
       
  1224 
       
  1225 /**
       
  1226  * This logs the current SCM Config to serial 
       
  1227  */
       
  1228 void CCoreDumpSession::PrintScmConfigL()
       
  1229 	{	
       
  1230     for(TInt i=0;i<iScmConfigList.Count();i++)
       
  1231     	{
       
  1232     	COptionConfig* optCon = iScmConfigList[i];
       
  1233     	LOG_DES(optCon->Prompt());
       
  1234     	LOG_MSG2("\t\tHas a value of %d", optCon->Value());
       
  1235     	} 
       
  1236 	}
       
  1237 
       
  1238 // Gather all conifg params from CDS, formatter and iWriter, 
       
  1239 // collent into an array and set num to the number of configs avaliable
       
  1240 void CCoreDumpSession::GetNumberConfigParametersL( const RMessage2& aMessage )
       
  1241 	{
       
  1242 	//LOG_MSG( "->CCoreDumpSession::GetNumberConfigParametersL()\n" );
       
  1243 	 UpdateConfigParametersL( );
       
  1244 
       
  1245 	TInt numConfigParams = iTotalConfigList.Count();
       
  1246 	//LOG_MSG2( "  numConfigParams=%d", numConfigParams );
       
  1247 
       
  1248 	TPtr8 numParamPtr( (TUint8 *) & numConfigParams, sizeof(TInt) );
       
  1249 	// Else it does not get passed back
       
  1250 	numParamPtr.Set( (TUint8 *)& numConfigParams, sizeof(TInt), sizeof(TInt) ); 
       
  1251 
       
  1252 	TPtr8 maxParamSizePtr( (TUint8 *) & iMaxConfigParamSize, sizeof(TInt) );
       
  1253 	// Else it does not get passed back
       
  1254 	maxParamSizePtr.Set( (TUint8 *)& iMaxConfigParamSize, sizeof(TInt), sizeof(TInt) ); 
       
  1255 
       
  1256 	/*
       
  1257 	RDebug::Printf( " CCoreDumpSession::GetNumberConfigParameters(): iConfigList.Count()=%d, passing back nParams=%d, iMaxConfigParamSize=%d \n", 
       
  1258 		iConfigList.Count(), numConfigParams, iMaxConfigParamSize );
       
  1259 	*/
       
  1260 
       
  1261 	aMessage.WriteL( 0, numParamPtr );
       
  1262 
       
  1263 	aMessage.WriteL( 1, maxParamSizePtr );
       
  1264 	}
       
  1265 
       
  1266 void CCoreDumpSession::GetConfigParameterL( const RMessage2& aMessage )
       
  1267 	{
       
  1268 //	LOG_MSG( "->CCoreDumpSession::GetConfigParameterL()\n" );
       
  1269 
       
  1270 
       
  1271 	if(	iTotalConfigList.Count() == 0 )
       
  1272 		{
       
  1273 		// The user has never called GetNumberConfigParametersL(), 
       
  1274 		// so update the parameters first.
       
  1275 		UpdateConfigParametersL( );
       
  1276 		}
       
  1277 
       
  1278 	if( iTotalConfigList.Count() == 0 )
       
  1279 		{
       
  1280 		RDebug::Printf( "  ERROR !* : Have not gathered the configuration parameters\n" );
       
  1281 		User::Leave( KErrBadHandle );
       
  1282 		}
       
  1283 
       
  1284 	TInt configIndex = aMessage.Int0();
       
  1285 	//RDebug::Printf( "  configIndex=%d\n", configIndex );
       
  1286 
       
  1287 	if ( ( configIndex < 0 ) || ( configIndex >= iTotalConfigList.Count() ) )
       
  1288 		{
       
  1289 		RDebug::Printf( "  ERROR !* : config Index out of bounds\n" );
       
  1290 		User::Leave( KErrBadHandle );
       
  1291 		}
       
  1292 
       
  1293 	COptionConfig * config = iTotalConfigList[configIndex];
       
  1294 	
       
  1295 	HBufC8 * configDes = config->MarshalDataL();
       
  1296 	CleanupStack::PushL( configDes );
       
  1297 	
       
  1298 	if ( configDes == NULL )
       
  1299 		{
       
  1300 		RDebug::Printf( "  ERROR !* MarshalData returned null buf\n" );
       
  1301 		User::Leave( KErrBadDescriptor );
       
  1302 		}
       
  1303 	else
       
  1304 		{
       
  1305 		TPtr8 configPtr( configDes->Des() );
       
  1306 		if( configPtr.Size() == 0 )
       
  1307 			{
       
  1308 			RDebug::Printf( "  ERROR !* : if( configPtr.Size() == 0 )\n" );
       
  1309 			User::Leave( KErrBadDescriptor );
       
  1310 			}
       
  1311 
       
  1312 		aMessage.WriteL( 1, configPtr );
       
  1313 		}
       
  1314 
       
  1315 	CleanupStack::PopAndDestroy( configDes );
       
  1316 	}
       
  1317 
       
  1318 void CCoreDumpSession::SetConfigParameterL( const RMessage2& aMessage )
       
  1319 	{
       
  1320 	LOG_MSG( "->CCoreDumpSession::SetConfigParameterL()\n" );
       
  1321 
       
  1322 	TConfigRequest configRequest; 
       
  1323 	
       
  1324 	TPtr8 configReqPtr( (TUint8 *)&configRequest, sizeof(TConfigRequest) );
       
  1325 	aMessage.ReadL( 0, configReqPtr );
       
  1326 
       
  1327 	TInt32 value = aMessage.Int1();
       
  1328 
       
  1329 	HBufC *valueDesc = NULL;
       
  1330 	TInt valueDesLen = aMessage.GetDesLength( 2 );
       
  1331 	if( valueDesLen > 0 )
       
  1332 		{
       
  1333 		valueDesc = HBufC::NewL( valueDesLen );
       
  1334 		CleanupStack::PushL( valueDesc );
       
  1335 		TPtr ptr( valueDesc->Des() );
       
  1336 		aMessage.ReadL( 2, ptr );
       
  1337 		}
       
  1338 	else
       
  1339 		{
       
  1340 		valueDesc = KNullDesC().AllocL();
       
  1341 		CleanupStack::PushL( valueDesc );
       
  1342 		}
       
  1343 
       
  1344 	switch(configRequest.iSource)
       
  1345 		{
       
  1346 		case COptionConfig::ECoreDumpServer:
       
  1347 
       
  1348 			SetConfigParameterL( configRequest.iIndex, value, *valueDesc );
       
  1349 			break;
       
  1350 
       
  1351 		case COptionConfig::EFormatterPlugin:
       
  1352             {
       
  1353                 if(configRequest.iInstance < iFormatterPlugins.Count())
       
  1354                     {
       
  1355                     iFormatterPlugins[configRequest.iInstance]->SetConfigParameterL(configRequest.iIndex, value, *valueDesc); 
       
  1356                     break;
       
  1357                     }
       
  1358 			break;
       
  1359             }
       
  1360 		case COptionConfig::EWriterPlugin:
       
  1361             {	
       
  1362                 if(configRequest.iInstance < iWriterPlugins.Count())
       
  1363                     {
       
  1364                     iWriterPlugins[configRequest.iInstance]->SetConfigParameterL(configRequest.iIndex, value, *valueDesc); 
       
  1365                     break;
       
  1366                     }
       
  1367 			break;
       
  1368             }
       
  1369 		case COptionConfig::ESCMConfig:
       
  1370 			{
       
  1371 							
       
  1372     		LOG_MSG4("(CCoreDumpSession::SetConfigParameterL) Updating config param instance %d  value %d index =%d"
       
  1373     				, configRequest.iInstance , value, configRequest.iIndex);
       
  1374     		iFlashDataSource->ModifySCMConfigItemL(configRequest.iInstance, value);
       
  1375             break;
       
  1376             }
       
  1377             
       
  1378 		default:
       
  1379             User::Leave(KErrArgument);
       
  1380 		}
       
  1381 
       
  1382 	    CleanupStack::PopAndDestroy( valueDesc );
       
  1383 	}
       
  1384 
       
  1385 
       
  1386 TInt32 CCoreDumpSession::PreProcessingAction() const
       
  1387 	{
       
  1388     return iConfigList[EPreCrashEventAction]->Value();
       
  1389 	}
       
  1390 
       
  1391 TInt32 CCoreDumpSession::PostProcessingAction() const
       
  1392 	{
       
  1393     return iConfigList[EPostCrashEventAction]->Value();
       
  1394 	}
       
  1395 
       
  1396 void CCoreDumpSession::SetConfigParameterL( const TInt aIndex, 
       
  1397 										 const TInt32 & aValue, 
       
  1398 										 const TDesC & aDescValue )
       
  1399 	{
       
  1400 	LOG_MSG3( "->CCoreDumpSession::SetConfigParameterL( aIndex=%d, aValue=0x%X )\n", aIndex, aValue );
       
  1401 
       
  1402 	if ( ( aIndex < 0 ) || ( aIndex >= iConfigList.Count() ) )
       
  1403 		{
       
  1404 		LOG_MSG2( "  ERROR !* : config Index out of bounds, max=%d\n", iConfigList.Count() - 1 );
       
  1405 		User::Leave( KErrBadHandle );
       
  1406 		}
       
  1407 
       
  1408 	//Match the parameter passed in to one of our own parameters via the index
       
  1409 	COptionConfig &config = *iConfigList[aIndex];
       
  1410 
       
  1411 	if( config.Index() != aIndex )
       
  1412 		{
       
  1413 		RDebug::Printf( "  ERROR !* : config Index %d does not match internal index %d\n", aIndex, config.Index() );
       
  1414 		User::Leave( KErrBadHandle );
       
  1415 		}
       
  1416 
       
  1417 	if( aIndex == (TInt)EPreCrashEventAction )
       
  1418 	    {
       
  1419 		switch( aValue )
       
  1420 			{
       
  1421 			case ENoPreAction:
       
  1422 			case ESuspendThread:
       
  1423 			case ESuspendProcess:
       
  1424 
       
  1425 				LOG_MSG2("  Changing EPreCrashEventAction to =%d\n", aValue );
       
  1426 
       
  1427 				iPreCrashEventAction = aValue;
       
  1428 
       
  1429                 for(TInt i = 0; i < iObservationList.Count(); i++)
       
  1430                     {
       
  1431                     if( (iPreCrashEventAction & ESuspendThread) || 
       
  1432 						(iPreCrashEventAction & ESuspendProcess) )
       
  1433 						{
       
  1434 						LOG_MSG2("  SetCrashEventsL(*iObservationList[%d], EActionSuspend)\n", i );
       
  1435                         SetCrashEventsL(*iObservationList[i], EActionSuspend);
       
  1436 						}
       
  1437                     else
       
  1438 						{
       
  1439 						LOG_MSG2("  SetCrashEventsL(*iObservationList[%d], EActionContinue);\n", i );
       
  1440                         SetCrashEventsL(*iObservationList[i], EActionContinue);
       
  1441 						}
       
  1442                     }
       
  1443                 
       
  1444 				break;
       
  1445 			default:
       
  1446 				RDebug::Printf(" ERROR !* EPreCrashEventAction cannot be %d\n", aValue );
       
  1447 				User::Leave(KErrArgument);
       
  1448 			}
       
  1449 	    }
       
  1450 	else if( aIndex == (TInt)EPostCrashEventAction )
       
  1451 	    {
       
  1452 		switch( aValue )
       
  1453 			{
       
  1454 			case ENoPostAction:
       
  1455 			case EResumeThread:
       
  1456 			case EResumeProcess:
       
  1457 			case EKillProcess:
       
  1458 				iPostCrashEventAction = aValue;
       
  1459 				break;
       
  1460 			default:
       
  1461 				RDebug::Printf(" ERROR !* EPostCrashEventAction cannot be %d\n", aValue );
       
  1462 				User::Leave(KErrArgument);
       
  1463 			}
       
  1464 	    }
       
  1465     else if( aIndex == (TInt)ECrashEventTypes )
       
  1466         {
       
  1467 		switch( aValue )
       
  1468 			{
       
  1469 			case ECrashHwExc:
       
  1470 			case ECrashKillThread:
       
  1471 			case ECrashHwExcAndKillThread:
       
  1472 
       
  1473 				LOG_MSG2("  Changing trigger ECrashEventTypes to =%d\n", aValue );
       
  1474 				iCrashEventTypes = aValue;
       
  1475 
       
  1476 				for(TInt i = 0; i < iObservationList.Count(); i++)
       
  1477                     {
       
  1478                     if( (iPreCrashEventAction & ESuspendThread) || 
       
  1479 						(iPreCrashEventAction & ESuspendProcess) )
       
  1480                         SetCrashEventsL(*iObservationList[i], EActionSuspend);
       
  1481                     else
       
  1482                         SetCrashEventsL(*iObservationList[i], EActionContinue);
       
  1483                     }
       
  1484 
       
  1485 				break;
       
  1486 			default:
       
  1487 				RDebug::Printf( " ERROR !* ECrashEventTypes  cannot be %d\n", aValue );
       
  1488 				User::Leave(KErrArgument);
       
  1489 			}
       
  1490         }
       
  1491 	else
       
  1492 		{
       
  1493 		RDebug::Printf(
       
  1494 			"CCoreDumpSession::SetConfigParameterL() : parameter with index %d does is not valid\n", 
       
  1495 				aIndex );
       
  1496 		User::Leave(KErrArgument);
       
  1497 		}
       
  1498 
       
  1499 	// Change our internal values
       
  1500 	config.Value( aValue );
       
  1501 	//LOG_MSG( "  config->ValueL( aDescValue )\n" );
       
  1502 	config.ValueL( aDescValue );
       
  1503 
       
  1504 	}
       
  1505 
       
  1506 
       
  1507 
       
  1508 /**
       
  1509 Save one parameter for a specific section. 
       
  1510 @param aParam COptionConfig pointer to save
       
  1511 @param aSectName Section name in the file to save this parameter to
       
  1512 @param aSaveIndex This parameter is only used to create key strings that are unique.
       
  1513 @param aPersistConfigData Object used to save the configuration to. 
       
  1514 */
       
  1515 void CCoreDumpSession::SaveConfigParamL( const COptionConfig * aParam, 
       
  1516 									   const TPtrC	&	aSectName,
       
  1517 									   const TInt		aSaveIndex,
       
  1518 									   CIniDocument16 * aPersistConfigData )
       
  1519 	{
       
  1520 
       
  1521 	LOG_MSG2( "CCoreDumpSession::SaveConfigParamL( aSaveIndex=%d )\n", aSaveIndex );
       
  1522 
       
  1523 	HBufC * iniStringKey;
       
  1524 	TInt err;
       
  1525 
       
  1526 	// Save the Configuration Parameter Value
       
  1527 		{
       
  1528 		iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyValue );
       
  1529 		TInt keyIntValue = aParam->Value();
       
  1530 
       
  1531 		// Size of character buffer required to represent a 32bit 
       
  1532 		// interger as decimal should be 10.
       
  1533 		TBuf<16> intValueBuf; 
       
  1534 				
       
  1535 		switch( aParam->Type() )
       
  1536 			{
       
  1537 			case COptionConfig::ETInt:
       
  1538 			case COptionConfig::ETUInt:
       
  1539 			case COptionConfig::ETBool:
       
  1540 
       
  1541 				LOG_MSG2( "  -> SetKey( int value=%d)\n", keyIntValue );
       
  1542 				intValueBuf.AppendNum( keyIntValue );
       
  1543 				err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intValueBuf );
       
  1544 				
       
  1545                 /*
       
  1546 				const TDesC & paramV = intValueBuf;
       
  1547 				RBuf valueV;
       
  1548 				valueV.Create( paramV );
       
  1549 				char* cl = (char*) valueV.Collapse().PtrZ();
       
  1550 				RDebug::Printf("  saving integer value=%s\n", cl );
       
  1551                 */
       
  1552 
       
  1553 				break;
       
  1554 
       
  1555 			case COptionConfig::ETString:
       
  1556 			case COptionConfig::ETFileName:
       
  1557 			case COptionConfig::ETMultiEntryEnum:
       
  1558 			case COptionConfig::ETSingleEntryEnum:
       
  1559 				{
       
  1560 				const TDesC & paramValue = aParam->ValueAsDesc();
       
  1561 
       
  1562 				if( paramValue == KNullDesC )
       
  1563 					{
       
  1564 					LOG_MSG( "  Cannot save parameter value that is NULL\n" );	
       
  1565 					CleanupStack::PopAndDestroy( iniStringKey );
       
  1566 					return;
       
  1567 					}
       
  1568                 /*
       
  1569 				RBuf value;
       
  1570 				value.Create( paramValue );
       
  1571 				char* cl = (char*) value.Collapse().PtrZ();
       
  1572 				RDebug::Printf("  saving string value=%s\n", cl );
       
  1573                 */
       
  1574 
       
  1575 				LOG_MSG( "  -> SetKey( string value )\n" );
       
  1576 				err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), paramValue );
       
  1577 				}
       
  1578 				break;
       
  1579 			default:
       
  1580 				{
       
  1581 				// unknown type, Leave since the file could be corrupt or malformed
       
  1582 				LOG_MSG2( "  Invalid COptionConfig parameter type %d\n", aParam->Type() );
       
  1583 				CleanupStack::PopAndDestroy( iniStringKey );
       
  1584 				User::Leave( KErrCorrupt );
       
  1585 				}
       
  1586 			}// switch (COptionConfig::TOptionType)
       
  1587 
       
  1588 		LOG_MSG( "  CleanupStack::PopAndDestroy( iniStringKey )" );
       
  1589 		CleanupStack::PopAndDestroy( iniStringKey );
       
  1590 		}
       
  1591 
       
  1592 
       
  1593 
       
  1594 	// Save the Configuration Parameter Index
       
  1595 		{
       
  1596 		iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyIndex );
       
  1597 
       
  1598 		TInt keyIndex = aParam->Index();
       
  1599 		TBuf<4> intIndexBuf;
       
  1600 		LOG_MSG3( "  -> keyIndex%d = parameter index %d\n", aSaveIndex, keyIndex );
       
  1601 		intIndexBuf.AppendNum( keyIndex );
       
  1602 
       
  1603 		err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intIndexBuf );
       
  1604 
       
  1605 		CleanupStack::PopAndDestroy( iniStringKey );
       
  1606 		
       
  1607 		if( KErrNone != err )
       
  1608 			{
       
  1609 			LOG_MSG2( "  ERROR !* aPersistConfigData->AddValue() returned %d\n", err );
       
  1610 			}
       
  1611 		User::LeaveIfError( err );
       
  1612 		}
       
  1613 
       
  1614 
       
  1615 	// Save the Configuration Parameter Type
       
  1616 		{
       
  1617 		iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyType );
       
  1618 
       
  1619 		TInt keyType = aParam->Type();
       
  1620 		TBuf<8> intTypeBuf;
       
  1621 		LOG_MSG3( "  -> KeyType%d = parameter type %d\n", aSaveIndex, keyType );
       
  1622 		intTypeBuf.AppendNum( keyType );
       
  1623 
       
  1624 		err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intTypeBuf );
       
  1625 
       
  1626 		CleanupStack::PopAndDestroy( iniStringKey );
       
  1627 		if( KErrNone != err )
       
  1628 			{
       
  1629 			LOG_MSG2( "  ERROR !* aPersistConfigData->AddValue() returned %d\n", err );
       
  1630 			}
       
  1631 		User::LeaveIfError( err );
       
  1632 		}
       
  1633 	}
       
  1634 
       
  1635 
       
  1636 
       
  1637 _LIT( KPluginExtension, ".plugin" );
       
  1638 #define KPluginUIDCharsPerLine 8
       
  1639 
       
  1640 
       
  1641 _LIT( KCDSConfig,				"CoreDumpServerConfiguration"			 );
       
  1642 _LIT( KWriterConfig,			"WriterConfiguration"					 );
       
  1643 _LIT( KFormatterConfig,			"FormatterConfiguration"				 );
       
  1644 _LIT( KObservedConfig,			"ObservedConfiguration"					 );
       
  1645 
       
  1646 _LIT( KDefaultIniFile, "coredumpserver.ini" );
       
  1647 _LIT( KUID, "UID" );
       
  1648 _LIT( KPluginPair, "Pair" );
       
  1649 
       
  1650 
       
  1651 
       
  1652 
       
  1653 
       
  1654 /**
       
  1655 Method to parse the set of files that contain the UIDs of the allowed plugins. 
       
  1656 The files are read our private directory in all drives. Thus installed .plugin
       
  1657 files are also checked. 
       
  1658 
       
  1659 The plugin files must have the extension ".plugin". The content must be in 
       
  1660 ASCII-8. The format must be one UID per line, with no empty lines. 
       
  1661 The EOL can be CR+LF or just CR.
       
  1662 */
       
  1663 void CCoreDumpSession::ReadPluginUidFilesL( )
       
  1664 	{
       
  1665 
       
  1666 	RFs	fsSession;
       
  1667 	CleanupClosePushL( fsSession );
       
  1668 	User::LeaveIfError( fsSession.Connect() );
       
  1669 
       
  1670 	//RProcess thisProc;
       
  1671 	
       
  1672 	TDriveList driveList;
       
  1673     TVolumeInfo volInfo;
       
  1674 
       
  1675     User::LeaveIfError( fsSession.DriveList( driveList ) );
       
  1676 
       
  1677 	HBufC* sessionPath = HBufC::NewLC( KMaxFileName );
       
  1678 	TPtr privPath( sessionPath->Des() );
       
  1679 
       
  1680 	RBuf8 allowedPluginUidStr;
       
  1681 	allowedPluginUidStr.CleanupClosePushL();
       
  1682 	allowedPluginUidStr.CreateL( KPluginUIDCharsPerLine );
       
  1683 
       
  1684 	RFile pluginFile;
       
  1685 	CleanupClosePushL( pluginFile );
       
  1686 
       
  1687     for( TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ )
       
  1688     {
       
  1689         if( ( !driveList[driveNumber] ) || 
       
  1690 			( KErrNone != fsSession.Volume( volInfo, driveNumber) ) ||
       
  1691 			( volInfo.iDrive.iType==EMediaNotPresent ) )
       
  1692             {
       
  1693             continue;
       
  1694             }
       
  1695 
       
  1696 		// Get a list of the files in the private directory of drive <driveNumber> 
       
  1697 
       
  1698 		fsSession.SetSessionToPrivate( driveNumber );
       
  1699 		User::LeaveIfError( fsSession.SessionPath( privPath ) );
       
  1700 		CDir * fileList = NULL;
       
  1701 
       
  1702 		// KEntryAttNormal gets only files (not dirs, hidden or system files)
       
  1703 		TInt ret = fsSession.GetDir( privPath, KEntryAttNormal, ESortByName, fileList );
       
  1704 		if( ( KErrNone != ret ) || ( !fileList ) )
       
  1705 			{
       
  1706 	if( fileList )
       
  1707 				delete fileList;
       
  1708 			continue;
       
  1709 			}
       
  1710 
       
  1711 		CleanupStack::PushL( fileList );
       
  1712 
       
  1713 		for( TInt i = 0; i < fileList->Count(); i++ )
       
  1714 			{
       
  1715 			TEntry fileEntry = (*fileList)[i];
       
  1716 			TParse fileNameParser;
       
  1717 			fileNameParser.Set( fileEntry.iName, NULL, NULL );
       
  1718 			if( fileNameParser.Ext() != KPluginExtension )
       
  1719 				{
       
  1720 				continue;
       
  1721 				}
       
  1722 
       
  1723             /*
       
  1724 			RBuf8 pluginFilePrint;
       
  1725 			pluginFilePrint.CreateL( fileEntry.iName.Length() + 1 );
       
  1726 			pluginFilePrint.Copy( fileEntry.iName );
       
  1727 			char* cl = (char*) pluginFilePrint.PtrZ();
       
  1728 			LOG_MSG2("    Reading .plugin file %s\n", cl );
       
  1729             */
       
  1730 
       
  1731 			// File extension is .plugin, so add the list of UIDs contained inside 
       
  1732 			// the file to our list of allowed plugins
       
  1733 			//
       
  1734 			ret = pluginFile.Open( fsSession, fileEntry.iName, EFileRead );
       
  1735 			if( KErrNone != ret )
       
  1736 				{
       
  1737 				LOG_MSG("  Error openning file. Ignoring this file\n" );
       
  1738 				continue;
       
  1739 				}
       
  1740 
       
  1741 			while( KErrNone == ret )
       
  1742 				{
       
  1743 				// Read the UID characters on a line. Exactly 8 * 1 byte non-UNICODE chars per line
       
  1744 				ret = pluginFile.Read( allowedPluginUidStr, KPluginUIDCharsPerLine );
       
  1745 				if( ( KErrNone != ret ) || (allowedPluginUidStr.Length() != KPluginUIDCharsPerLine ) )
       
  1746 					{
       
  1747 					// Reached the end of file, so go to the next file
       
  1748 					break;
       
  1749 					}
       
  1750 
       
  1751 				TLex8 uidLex( allowedPluginUidStr );
       
  1752 				TUint pluginUidValue = 0;
       
  1753 				uidLex.Val( pluginUidValue, EHex );
       
  1754 				TUid allowedUid = TUid::Uid( pluginUidValue );
       
  1755 				iAllowedPlugins.AppendL( allowedUid );
       
  1756 
       
  1757 				// Now skip the end of line character/s CR 0x0D and possibly LF 0x0A
       
  1758 				ret = pluginFile.Read( allowedPluginUidStr, 1 );
       
  1759 				if( ( KErrNone == ret ) && (allowedPluginUidStr.Length() == 1) )
       
  1760 					{
       
  1761 					//Could have read the CR or LF
       
  1762 					if( 0x0D == *(allowedPluginUidStr.Ptr()) )
       
  1763 						{
       
  1764 						// CR should be followed by LF, so read that too
       
  1765 						ret = pluginFile.Read( allowedPluginUidStr, 1 );
       
  1766 						}
       
  1767 					}
       
  1768 
       
  1769 				if( allowedPluginUidStr.Length() == 0 )
       
  1770 					{
       
  1771 					ret = KErrEof;
       
  1772 					}
       
  1773 
       
  1774 				} // while have read 8 bytes
       
  1775 
       
  1776 			pluginFile.Close();
       
  1777 			} // for each file in file list
       
  1778 
       
  1779 		CleanupStack::PopAndDestroy( fileList );
       
  1780 		}
       
  1781 	
       
  1782 	CleanupStack::PopAndDestroy( &pluginFile );
       
  1783 	CleanupStack::PopAndDestroy( &allowedPluginUidStr );
       
  1784 	CleanupStack::PopAndDestroy( sessionPath );
       
  1785 	CleanupStack::PopAndDestroy( &fsSession );
       
  1786 
       
  1787 	if( 0 == iAllowedPlugins.Count() )
       
  1788 		{
       
  1789 		LOG_MSG( "  Warning : No plugins will be allowed\n" );
       
  1790 		}
       
  1791 	else
       
  1792 		{
       
  1793 		for( TInt i=0; i < iAllowedPlugins.Count(); i++ )
       
  1794 			{
       
  1795 			LOG_MSG2( "  Plugin 0x%X allowed\n", iAllowedPlugins[i] );
       
  1796 			}
       
  1797 		}
       
  1798 
       
  1799 	}
       
  1800 
       
  1801 void CCoreDumpSession::ValidatePluginL( const TUid aPluginUid ) const
       
  1802 	{
       
  1803 
       
  1804 	LOG_MSG2( "->CCoreDumpSession::ValidatePlugin(aPluginId=0x%X)\n", aPluginUid.iUid );
       
  1805 
       
  1806 	for( TInt i = 0; i < iAllowedPlugins.Count(); i++ )
       
  1807 		{
       
  1808 		if( iAllowedPlugins[i] == aPluginUid )
       
  1809 			{
       
  1810 			LOG_MSG( "  Plugin Allowed\n" );
       
  1811 			return;
       
  1812 			}
       
  1813 		}
       
  1814 	LOG_MSG( "  Plugin Not Allowed\n" );
       
  1815     User::Leave(KErrPermissionDenied);
       
  1816 	}
       
  1817 
       
  1818 /**
       
  1819 @pre aFsSession FileSystem session must have been connected to and still be active
       
  1820 @post aFileName and aPersistConfigData pushed onto the stack
       
  1821 */
       
  1822 void CCoreDumpSession::OpenIniFileLC( const RMessage2	* aMessage, 
       
  1823 									const TBool		  aSaving,
       
  1824 									RFs				& aFsSession,
       
  1825 									HBufC		   *& aFileName,
       
  1826 									CIniDocument16 *& aPersistConfigData )
       
  1827 	{
       
  1828 
       
  1829 
       
  1830 	LOG_MSG( "CCoreDumpSession::OpenIniFileLC(RMessage2)\n" );
       
  1831 
       
  1832 	TInt ret;
       
  1833 
       
  1834 	TInt iniFileDesLen = 0;
       
  1835 
       
  1836 	if( aMessage )
       
  1837 		{
       
  1838 		LOG_MSG( " RMessage2 != NULL\n" );
       
  1839 		iniFileDesLen = aMessage->GetDesLength( 0 );
       
  1840 		if( iniFileDesLen > 0 )
       
  1841 			{
       
  1842 			//LOG_MSG( "  User supplied ini file name\n" );
       
  1843 			aFileName = HBufC::NewL( iniFileDesLen );
       
  1844 
       
  1845 			//LOG_MSG( "  CleanupStack::PushL( aFileName )\n" );
       
  1846 			CleanupStack::PushL( aFileName );
       
  1847 
       
  1848 			TPtr ptr( aFileName->Des() );
       
  1849 			aMessage->ReadL( 0, ptr );
       
  1850 			if( !aSaving && !aFsSession.IsValidName( ptr ) )
       
  1851 				{
       
  1852 				// If we are loading and the file and path are incorrect
       
  1853 				//LOG_MSG( "  IsValidName() == EFalse\n" );
       
  1854 				User::Leave( KErrPathNotFound );
       
  1855 				}
       
  1856 			}
       
  1857 		}
       
  1858 
       
  1859 	if( 0 == iniFileDesLen )
       
  1860 		{
       
  1861 		aFsSession.SetSessionToPrivate( EDriveE );
       
  1862 
       
  1863 		RBuf privPath;
       
  1864 		privPath.CleanupClosePushL();
       
  1865 		privPath.CreateL( KMaxFileName );
       
  1866 		
       
  1867 		aFsSession.SessionPath( privPath );
       
  1868 
       
  1869 		privPath.Append( KDefaultIniFile );
       
  1870 		aFileName = HBufC::NewL( privPath.Length() );
       
  1871 		*aFileName = privPath;// Copy name
       
  1872         
       
  1873 		CleanupStack::PopAndDestroy( &privPath );
       
  1874 
       
  1875 		CleanupStack::PushL( aFileName );
       
  1876 
       
  1877 		if( aSaving )
       
  1878 			{
       
  1879 			//LOG_MSG( " aFsSession.CreatePrivatePath( EDriveE )\n" );
       
  1880 			ret = aFsSession.CreatePrivatePath( EDriveE );
       
  1881 			if( ( KErrNone  != ret ) && ( KErrAlreadyExists != ret ) )
       
  1882 				{
       
  1883 				LOG_MSG2( " aFsSession.CreatePrivatePath( EDriveE ) returned ERROR %d\n", ret );
       
  1884 				User::Leave( ret );
       
  1885 				}
       
  1886 			}
       
  1887 		}
       
  1888 
       
  1889 	if( aSaving  ) 
       
  1890 		{
       
  1891 		// delete existing file since CIniDocument16::NewL expects a correctly formed 
       
  1892 		// file or no file at all. An empty file makes the NewL Leave
       
  1893 		//
       
  1894 		//LOG_MSG( "  -> aFsSession.Delete( aFileName->Des() )\n");
       
  1895 		aFsSession.Delete( aFileName->Des() );
       
  1896 		}
       
  1897     else
       
  1898     {
       
  1899         TEntry entry;
       
  1900         User::LeaveIfError(aFsSession.Entry(aFileName->Des(), entry));
       
  1901     }
       
  1902 	//LOG_MSG( "  ->CIniDocument16::NewL( aFsSession, aFileName->Des() )\n");
       
  1903 	TRAPD(err, aPersistConfigData = CIniDocument16::NewL( aFsSession, aFileName->Des() ));
       
  1904 
       
  1905 	if( KErrNone != err )
       
  1906 		{
       
  1907 		LOG_MSG2( "  <- CIniDocument16::NewL( ) left with %d\n", err );
       
  1908 		}
       
  1909 
       
  1910 	CleanupStack::PushL( aPersistConfigData );
       
  1911 	}
       
  1912 
       
  1913 
       
  1914 
       
  1915 _LIT( KIniFileCommentTitle,	"CoreDumpServerSettingsFile" );
       
  1916 _LIT( KIniFileCommentSymbian, "Symbian_Software_Ltd" );
       
  1917 _LIT( KIniFileCommentSymbianYear, "2007" );
       
  1918 _LIT( KIniFileCommentVersionString,	"Version" );
       
  1919 _LIT( KIniFileCommentVersionNumber,	"1.0.0" );
       
  1920 
       
  1921 
       
  1922 /*
       
  1923 * Client request to load system configuration file
       
  1924 */
       
  1925 void CCoreDumpSession::SaveConfigFileL( const RMessage2* aMessage )
       
  1926 	{
       
  1927 	
       
  1928 	LOG_MSG( "CCoreDumpSession::SaveConfigFileL(RMessage2)\n");
       
  1929 
       
  1930 	RFs	fsSession;
       
  1931 	CleanupClosePushL( fsSession );
       
  1932 	User::LeaveIfError( fsSession.Connect() );
       
  1933 
       
  1934 
       
  1935 	HBufC * fileName = NULL;
       
  1936 	CIniDocument16 * persistConfigData = NULL;
       
  1937 
       
  1938 	OpenIniFileLC( aMessage, ETrue, fsSession, fileName, persistConfigData );
       
  1939 
       
  1940 	// persistConfigData is on top of the stack, and under it is fileName
       
  1941 
       
  1942 	TInt ret;
       
  1943   	TPtrC uidString;
       
  1944 	uidString.Set( KUID );
       
  1945 	TPtrC sectName;
       
  1946 
       
  1947 	sectName.Set( KIniFileCommentTitle );
       
  1948 	ret = persistConfigData->AddSection( sectName );
       
  1949 	User::LeaveIfError( ret );
       
  1950 
       
  1951 	ret = persistConfigData->SetKey( sectName, KIniFileCommentSymbian, KIniFileCommentSymbianYear );
       
  1952 	User::LeaveIfError( ret );
       
  1953 
       
  1954 	ret = persistConfigData->SetKey( sectName, KIniFileCommentVersionString, KIniFileCommentVersionNumber );
       
  1955 	User::LeaveIfError( ret );
       
  1956 
       
  1957 	
       
  1958 	sectName.Set( KCDSConfig );
       
  1959 	//LOG_MSG( "    persistConfigData->AddSection( KCDSConfig )\n" );
       
  1960 	ret = persistConfigData->AddSection( sectName );
       
  1961 	//LOG_MSG2( "    AddSection( KCDSConfig ) returned %d", ret );
       
  1962 	User::LeaveIfError( ret );
       
  1963 
       
  1964 	RBuf cdsUidNumberString;
       
  1965     cdsUidNumberString.CleanupClosePushL();
       
  1966 	cdsUidNumberString.CreateL( 8 );
       
  1967 	cdsUidNumberString.AppendNumFixedWidth( (TUint)iOurSecureID.iUid, EHex, 8 );  // Width = 8 chars
       
  1968 
       
  1969 	//LOG_MSG( "    persistConfigData->SetKey( KCDSConfig, uidString, cdsUidNumberString )\n" );
       
  1970 	ret = persistConfigData->SetKey( sectName, uidString, cdsUidNumberString );
       
  1971 	User::LeaveIfError( ret );
       
  1972 
       
  1973 	for( TInt i = 0; i < iConfigList.Count(); i++ )
       
  1974 		{
       
  1975 		SaveConfigParamL( iConfigList[i], sectName, i, persistConfigData );
       
  1976 		}
       
  1977     CleanupStack::PopAndDestroy(&cdsUidNumberString);	
       
  1978 
       
  1979 	if( iObservationList.Count() > 0 )
       
  1980 		{
       
  1981 
       
  1982 		//LOG_MSG( "  Saving Observed section\n");
       
  1983 
       
  1984 		// There is no point in saving the id of a thread since the id is not predictable 
       
  1985 		// and could be used in another boot session. Thus only save the names
       
  1986 		// EIniKeyValue holds Target Name EIniKeyType holds TargetOwnerName
       
  1987 		// Thus a process will have both the same, so we can differentiate them
       
  1988 		HBufC * iniStringTargetValue;
       
  1989 		HBufC * iniStringOwnerType;
       
  1990 
       
  1991 		TPtrC observationSection;
       
  1992 		observationSection.Set( KObservedConfig );
       
  1993 		//LOG_MSG( "  persistConfigData->AddSection( KObservedConfig )\n" );
       
  1994 		ret = persistConfigData->AddSection( observationSection );
       
  1995 		User::LeaveIfError( ret );
       
  1996 
       
  1997 		TInt observeKey = 0;
       
  1998 
       
  1999 		for( TInt i = 0; i < iObservationList.Count(); i ++ )
       
  2000 			{
       
  2001             CTargetObserver *observer = iObservationList[i];
       
  2002             TInt count = observer->ThreadCount();
       
  2003             TInt j = 0;
       
  2004             do
       
  2005                 {
       
  2006                 // Key string for target name
       
  2007                 iniStringTargetValue = GenerateKeyStringLC( observeKey, EIniKeyValue );
       
  2008                 TPtrC targetName;
       
  2009                 if(count == 0) //whole process, no threads on list => targetName == targetOwnerName
       
  2010                     {
       
  2011                     targetName.Set(observer->TargetName());
       
  2012                     }
       
  2013                 else
       
  2014                     {
       
  2015                     targetName.Set(observer->Thread(j));
       
  2016                     }
       
  2017 
       
  2018                 //LOG_MSG2( " iPersistConfigData->SetKey( KObservedConfig, target.Length()=%d )\n", targetName.Length() );
       
  2019                 ret = persistConfigData->SetKey( observationSection, 
       
  2020                                                  iniStringTargetValue->Des(), 
       
  2021                                                  targetName );
       
  2022 
       
  2023                 CleanupStack::PopAndDestroy( iniStringTargetValue );
       
  2024                 if( KErrNone != ret )
       
  2025                     {
       
  2026                     LOG_MSG2( "  ERROR !* iPersistConfigData->AddValue() for observed target returned %d\n", ret );
       
  2027                     User::Leave( ret );
       
  2028                     }
       
  2029 
       
  2030                 // Key string for target owner name
       
  2031                 iniStringOwnerType = GenerateKeyStringLC( observeKey, EIniKeyType ); 
       
  2032                 TPtrC targetOwnerName( observer->TargetName() );
       
  2033 
       
  2034                 LOG_MSG2( " iPersistConfigData->SetKey( KObservedConfig, targetOwner.Length()=%d )\n", targetOwnerName.Length() );
       
  2035                 ret = persistConfigData->SetKey( observationSection, 
       
  2036                                                  iniStringOwnerType->Des(), 
       
  2037                                                  targetOwnerName );
       
  2038 
       
  2039                 CleanupStack::PopAndDestroy( iniStringOwnerType );
       
  2040                 if( KErrNone != ret )
       
  2041                     {
       
  2042                     LOG_MSG2( "  ERROR !* iPersistConfigData->AddValue() for observed target owner returned %d\n", ret );
       
  2043                     User::Leave( ret );
       
  2044                     }
       
  2045 
       
  2046                 j++;
       
  2047 				observeKey ++;
       
  2048 
       
  2049                 } while(j < count);
       
  2050 
       
  2051 			} //for(i)
       
  2052 		}
       
  2053 
       
  2054     TBuf<63> sectionName;
       
  2055 
       
  2056 
       
  2057     for(TInt i = 0; i < iFormatterPlugins.Count(); i++)
       
  2058     {
       
  2059         sectionName = KFormatterConfig;
       
  2060         sectionName.AppendFormat(_L("%d"), i);
       
  2061 
       
  2062 		ret = persistConfigData->AddSection( sectionName );
       
  2063         User::LeaveIfError(ret);
       
  2064 
       
  2065 
       
  2066    		// Add a key "UID" with a value equal to the UID of the writer, so we can load it again
       
  2067 		RBuf uidNumberString;
       
  2068         uidNumberString.CleanupClosePushL();
       
  2069 		uidNumberString.CreateL( 8 );
       
  2070 		uidNumberString.AppendNumFixedWidth( (TUint)iFormatterInfos[i]->Uid(), EHex, 8 ); // Width = 8 chars
       
  2071 		ret = persistConfigData->SetKey( sectionName, uidString, uidNumberString );
       
  2072 		User::LeaveIfError( ret );
       
  2073         CleanupStack::PopAndDestroy(&uidNumberString);
       
  2074 
       
  2075         TPtrC pairString;
       
  2076         pairString.Set( KPluginPair );
       
  2077 
       
  2078         //Add pair key with value equal to the paired writer plugin
       
  2079 		RBuf pairNumberString;
       
  2080         pairNumberString.CleanupClosePushL();
       
  2081 		pairNumberString.CreateL( 8 );
       
  2082 		pairNumberString.AppendNumFixedWidth( (TUint)iFormatterInfos[i]->Pair(), EHex, 8 ); // Width = 8 chars
       
  2083 		ret = persistConfigData->SetKey( sectionName, pairString, pairNumberString );
       
  2084 		User::LeaveIfError( ret );
       
  2085         CleanupStack::PopAndDestroy(&pairNumberString);
       
  2086 
       
  2087    		for( TInt j = 0; j < iTotalConfigList.Count(); j++ )
       
  2088 			{
       
  2089 			if( iTotalConfigList[j] && (COptionConfig::EFormatterPlugin == iTotalConfigList[j]->Source()) && (i == iTotalConfigList[j]->Instance()))
       
  2090 				{
       
  2091 				SaveConfigParamL( iTotalConfigList[j], sectionName, iTotalConfigList[j]->Index(), persistConfigData );
       
  2092 				}
       
  2093 			}
       
  2094     }
       
  2095 
       
  2096     for(TInt i = 0; i < iWriterPlugins.Count(); i++)
       
  2097     {
       
  2098         sectionName = KWriterConfig;
       
  2099         sectionName.AppendFormat(_L("%d"), i);
       
  2100 
       
  2101 		ret = persistConfigData->AddSection( sectionName );
       
  2102         User::LeaveIfError(ret);
       
  2103 
       
  2104    		// Add a key "UID" with a value equal to the UID of the writer, so we can load it again
       
  2105 		RBuf uidNumberString;
       
  2106         uidNumberString.CleanupClosePushL();
       
  2107 		uidNumberString.CreateL( 8 );
       
  2108 		uidNumberString.AppendNumFixedWidth( (TUint)iWriterInfos[i]->Uid(), EHex, 8 ); // Width = 8 chars
       
  2109 		ret = persistConfigData->SetKey( sectionName, uidString, uidNumberString );
       
  2110 		User::LeaveIfError( ret );
       
  2111         CleanupStack::PopAndDestroy(&uidNumberString);
       
  2112 
       
  2113    		for( TInt j = 0; j < iTotalConfigList.Count(); j++ )
       
  2114 			{
       
  2115 			if( iTotalConfigList[j] && (COptionConfig::EWriterPlugin == iTotalConfigList[j]->Source()) && (i == iTotalConfigList[j]->Instance()))
       
  2116 				{
       
  2117 				SaveConfigParamL( iTotalConfigList[j], sectionName, iTotalConfigList[j]->Index(), persistConfigData );
       
  2118 				}
       
  2119 			}
       
  2120     }
       
  2121 
       
  2122 	if( NULL == persistConfigData )
       
  2123 		{
       
  2124 		LOG_MSG( "  persistConfigData == NULL\n" );
       
  2125 		}
       
  2126 
       
  2127 	// Now save the config to file
       
  2128 	ret = persistConfigData->Externalise( fileName->Des() );
       
  2129 	//LOG_MSG2( "  <- iPersistConfigData->Externalise() returned %d\n", ret );
       
  2130 
       
  2131 	//LOG_MSG( "  CleanupStack::PopAndDestroy( iPersistConfigData )" );
       
  2132 	CleanupStack::PopAndDestroy( persistConfigData );
       
  2133 
       
  2134 	//LOG_MSG( "  CleanupStack::PopAndDestroy( fileName )" );
       
  2135 	CleanupStack::PopAndDestroy( fileName );
       
  2136 
       
  2137 	//LOG_MSG( "  ->CleanupStack::PopAndDestroy( fsSession )" );
       
  2138 	CleanupStack::PopAndDestroy( & fsSession );
       
  2139 	//LOG_MSG( "  <-CleanupStack::PopAndDestroy( fsSession )" );
       
  2140 
       
  2141 	}
       
  2142 
       
  2143 /*
       
  2144 * Client request to load system configuration file
       
  2145 */
       
  2146 void CCoreDumpSession::LoadConfigFileL( const RMessage2* aMessage )
       
  2147 	{
       
  2148 	
       
  2149 
       
  2150 	LOG_MSG( "CCoreDumpSession::LoadConfigFileL(RMessage2)" );
       
  2151 
       
  2152 	RFs	fsSession;
       
  2153 	//LOG_MSG( "  User::LeaveIfError( fsSession.Connect() )\n" );
       
  2154 	User::LeaveIfError( fsSession.Connect() );
       
  2155 	CleanupClosePushL( fsSession );
       
  2156 
       
  2157 	TPtrC16 value;
       
  2158 
       
  2159 	HBufC * fileName = NULL;
       
  2160 	CIniDocument16 * persistConfigData = NULL;
       
  2161 
       
  2162 	//LOG_MSG( "   -> CIniDocument16 * iPersistConfigData = OpenIniFileLC()" );
       
  2163 	OpenIniFileLC( aMessage, EFalse, fsSession, fileName, persistConfigData );
       
  2164 
       
  2165 	//LOG_MSG( "   -> RecreateConfigurationL( iPersistConfigData )\n" );
       
  2166 	RecreateConfigurationL( persistConfigData );
       
  2167 
       
  2168 	//LOG_MSG( "   -> CleanupStack::PopAndDestroy( iPersistConfigData )" );
       
  2169 	CleanupStack::PopAndDestroy( persistConfigData );
       
  2170 	//LOG_MSG( "   -> CleanupStack::PopAndDestroy( fileName )" );
       
  2171 	CleanupStack::PopAndDestroy( fileName );
       
  2172 	//LOG_MSG( "   -> CleanupStack::PopAndDestroy( & fsSession )" );
       
  2173 	CleanupStack::PopAndDestroy( & fsSession );
       
  2174 	//LOG_MSG( "   returning from CCoreDumpSession::LoadConfigFileL(RMessage2)" );
       
  2175 	}
       
  2176 
       
  2177 
       
  2178 /**
       
  2179 Method used to load and unload the formatter and writer plugins as a pair.
       
  2180 Also configures the data source and data save for the formatter.
       
  2181 If unloading the UIDs are still checked.
       
  2182 */
       
  2183 void CCoreDumpSession::SetPluginsL( const TUid aFormatterUID, 
       
  2184 								  const TUid aWriterUID, 
       
  2185 								  const TBool aLoad )
       
  2186 	{
       
  2187 	ValidatePluginL( aFormatterUID );
       
  2188 
       
  2189 	ValidatePluginL( aWriterUID );
       
  2190 
       
  2191     /*
       
  2192 	if( iFormatter )
       
  2193 		{
       
  2194 		delete iFormatter;
       
  2195 		iFormatterUid = TUid::Uid(0);
       
  2196 		}
       
  2197 
       
  2198 	if( iWriter )
       
  2199 		{
       
  2200 		delete iWriter;
       
  2201 		iWriterUid = TUid::Uid(0);
       
  2202 		}
       
  2203 
       
  2204 	if( !aLoad )
       
  2205 		{
       
  2206 		return;
       
  2207 		}
       
  2208 
       
  2209 	// We push the plugins onto the cleanup stack since if we leave here we 
       
  2210 	// want them destroyed so that there is always a valid pair or none are loaded
       
  2211 	iWriter = CCrashDataSave::NewL( aWriterUID );
       
  2212 	CleanupStack::PushL( iWriter );
       
  2213 
       
  2214 	iFormatter = CCoreDumpFormatter::NewL( aFormatterUID );
       
  2215 	CleanupStack::PushL( iFormatter );
       
  2216 
       
  2217 	iFormatter->ConfigureDataSourceL( iDataSource );
       
  2218 	iFormatter->ConfigureDataSaveL( iWriter );
       
  2219 
       
  2220 	iFormatterUid = aFormatterUID;
       
  2221 	iWriterUid = aWriterUID;
       
  2222 
       
  2223 	// We can pop the plugins
       
  2224 	CleanupStack::Pop( 2, iWriter );
       
  2225 
       
  2226     */
       
  2227 	}
       
  2228 
       
  2229 
       
  2230 
       
  2231 /**
       
  2232 Look through the iPersistConfigData object (initialised from the ini file)
       
  2233 and attempt to recreate the state described by the object.
       
  2234 This means 
       
  2235  - unloading current plugins, 
       
  2236  - loading new plugins, 
       
  2237  - updating the configuration list by calling UpdateConfigParametersL()
       
  2238  - recreating the configuration for section (CDS, formatter, writer )
       
  2239 
       
  2240 We have to be lax about the errors since we do not want to stop the 
       
  2241 loading of a configuration if there is a non-fatal error. This applies to 
       
  2242 loading of the plugins.
       
  2243 */
       
  2244 void CCoreDumpSession::RecreateConfigurationL( CIniDocument16 * iPersistConfigData )
       
  2245 	{
       
  2246 
       
  2247 	// for each section in ini file, 
       
  2248 	//  read section's SID
       
  2249 	//  load plugins
       
  2250 	//  for each (type, index, value) triplet, 
       
  2251 	//    create a COptionConfig 
       
  2252 	//    append to aIniFileConfigList
       
  2253 	//
       
  2254 
       
  2255 
       
  2256 	TInt ret;
       
  2257 	TBool foundCdsSection = EFalse;
       
  2258 	TBool foundFormatterSection = EFalse;
       
  2259 	TBool foundWriterSection = EFalse;
       
  2260 
       
  2261 	TPtrC uidString;
       
  2262 	uidString.Set( KUID );
       
  2263 
       
  2264 	// Recreate CDS section
       
  2265 		{
       
  2266 		TPtrC cdsUidString;
       
  2267 		//LOG_MSG("  iPersistConfigData->GetKeyValue( KCDSConfig, uidString, cdsUidString )\n" );
       
  2268 		ret = iPersistConfigData->GetKeyValue( KCDSConfig, uidString, cdsUidString );
       
  2269 		//LOG_MSG2("  iPersistConfigData->GetKeyValue( ) returned %d\n", ret );
       
  2270 
       
  2271 		if( KErrNone == ret )
       
  2272 			{
       
  2273 			foundCdsSection = ETrue;
       
  2274 			}
       
  2275 		else
       
  2276 			{
       
  2277 			// It an error for there to be no saved CDS configuration 
       
  2278 			User::Leave( ret );
       
  2279 			}
       
  2280 
       
  2281 		if( foundCdsSection )
       
  2282 			{
       
  2283 			TLex cdsUidLex( cdsUidString );
       
  2284 			TUint cdsUidValue;
       
  2285 			cdsUidLex.Val( cdsUidValue, EHex );
       
  2286 			TUid savedCdsUid = TUid::Uid( cdsUidValue );
       
  2287 			//LOG_MSG2("  Found CDS Config Section with UID 0x%X\n", cdsUidValue );
       
  2288 			//LOG_MSG2("  Current UID is 0x%X\n", iOurSecureID.iUid );
       
  2289 			if( savedCdsUid != iOurSecureID )
       
  2290 				{
       
  2291 				// The UID for the CDS does not match our current CDS SID.
       
  2292 				// This could arise if the config file was created by a previous version 
       
  2293 				// of the CDS, but more likely we are reading a corrupt file.
       
  2294 				// Thus the safe option is to leave
       
  2295 				LOG_MSG2( "  ERROR !* Read CDS UID from ini file as 0x%X, which is not same as our current value\n",
       
  2296 					cdsUidValue );
       
  2297 				User::Leave( KErrCorrupt );
       
  2298 				}
       
  2299 			}//foundCdsSection
       
  2300 		}
       
  2301 
       
  2302     TBuf<63> sectionName;
       
  2303 
       
  2304 
       
  2305     foundWriterSection = -1;
       
  2306     for(TInt i = 0;;i++)
       
  2307     {
       
  2308         sectionName = KWriterConfig;
       
  2309         sectionName.AppendFormat(_L("%d"), i);
       
  2310 
       
  2311 		TPtrC writerUidString;
       
  2312 		ret = iPersistConfigData->GetKeyValue( sectionName, uidString, writerUidString );
       
  2313 
       
  2314    		TUint writerUidValue;
       
  2315 		if( KErrNone == ret )
       
  2316 			{
       
  2317             foundWriterSection++;
       
  2318 			TLex writerUidLex( writerUidString );
       
  2319 			writerUidLex.Val( writerUidValue, EHex );
       
  2320 			CreateWriterL( TUid::Uid( writerUidValue ) );
       
  2321 			}
       
  2322 		else
       
  2323 			{
       
  2324                 break;
       
  2325 			}
       
  2326 
       
  2327     } 
       
  2328 
       
  2329 
       
  2330     foundFormatterSection = -1;
       
  2331     for(TInt i = 0;;i++)
       
  2332     {
       
  2333         sectionName = KFormatterConfig;
       
  2334         sectionName.AppendFormat(_L("%d"), i);
       
  2335 
       
  2336 		TPtrC formatterUidString;
       
  2337 		ret = iPersistConfigData->GetKeyValue( sectionName, uidString, formatterUidString );
       
  2338 
       
  2339    		TUint formatterUidValue;
       
  2340 		if( KErrNone == ret )
       
  2341 			{
       
  2342 			foundFormatterSection++;
       
  2343 			TLex fromatterUidLex( formatterUidString );
       
  2344 			fromatterUidLex.Val( formatterUidValue, EHex );
       
  2345 			CreateFormatterL( TUid::Uid( formatterUidValue ) );
       
  2346 
       
  2347             TPtrC pairString;
       
  2348             pairString.Set( KPluginPair );
       
  2349             TPtrC formatterPairString;
       
  2350             ret = iPersistConfigData->GetKeyValue(sectionName, pairString, formatterPairString);
       
  2351             if(ret == KErrNone)
       
  2352                 {
       
  2353 			    TLex fromatterPairLex( formatterPairString );
       
  2354                 TUint formatterPairValue;
       
  2355 			    fromatterPairLex.Val( formatterPairValue, EHex );
       
  2356                 BindPluginsL(i, formatterPairValue);
       
  2357                 }
       
  2358             }
       
  2359 		else
       
  2360 			{
       
  2361                 break;
       
  2362 			}
       
  2363 
       
  2364     }
       
  2365 
       
  2366     
       
  2367 	// Now that the old plugins are unloaded (if a new one was specified in the ini file),
       
  2368 	// and the new ones loaded, reconstruct the list of configuration parameters. 
       
  2369 	// We will then change them with the ini file values that we are about to read.
       
  2370 	// For plugins that have not been unloaded (because there was no mention in the init file)
       
  2371 	// we will simply ask for the config params again, and we should get the current values.
       
  2372 
       
  2373 	UpdateConfigParametersL();
       
  2374 
       
  2375 	if( foundCdsSection )
       
  2376 		{
       
  2377 		//LOG_MSG( "  -> ChangeConfigParamsL( COptionConfig::ECoreDumpServer\n" );
       
  2378 		ChangeConfigParamsL( COptionConfig::ECoreDumpServer, iPersistConfigData );
       
  2379 		}
       
  2380 
       
  2381     for(TInt i = 0; i <= foundFormatterSection; i++)
       
  2382 		{
       
  2383 		//LOG_MSG( "  -> ChangeConfigParamsL( COptionConfig::EFormatterPlugin\n" );
       
  2384 		ChangeConfigParamsL( COptionConfig::EFormatterPlugin, iPersistConfigData, foundFormatterSection );
       
  2385 		}
       
  2386 
       
  2387     for(TInt i = 0; i <= foundWriterSection; i++)
       
  2388 		{
       
  2389 		//LOG_MSG( "  -> ChangeConfigParamsL( COptionConfig::EWriterPlugin\n" );
       
  2390 		ChangeConfigParamsL( COptionConfig::EWriterPlugin, iPersistConfigData, foundWriterSection );
       
  2391 		}
       
  2392 
       
  2393 	// Now rebuild the Observed list from the file
       
  2394 		{
       
  2395 
       
  2396 		//LOG_MSG( "  About to Rebuild Observed Target List from Ini File\n" );
       
  2397 		
       
  2398 		HBufC * iniTargetValue;
       
  2399 		HBufC * iniOwnerType;
       
  2400 		TInt observeIndex = 0;
       
  2401 		TBool targetFound = ETrue;
       
  2402 		while( targetFound )
       
  2403 			{
       
  2404 
       
  2405 			// Each value obtained via EIniKeyIndex from the file is the CConfigOption index 
       
  2406 			// and is used to tie the saved to the live index.
       
  2407 
       
  2408 			//LOG_MSG2("  GenerateKeyStringLC( EIniKeyValue =%d)\n", observeIndex );
       
  2409 			iniTargetValue = GenerateKeyStringLC( observeIndex, EIniKeyValue );
       
  2410 
       
  2411 			TPtrC observeTargetValue;
       
  2412 
       
  2413 			//LOG_MSG("  iPersistConfigData->GetKeyValue( KObservedConfig, targetName )\n" );
       
  2414 			ret = iPersistConfigData->GetKeyValue( KObservedConfig, 
       
  2415 													iniTargetValue->Des(), 
       
  2416 													observeTargetValue );
       
  2417 			//LOG_MSG2("  iPersistConfigData->GetKeyValue( ) returned %d\n", ret );
       
  2418 
       
  2419 			CleanupStack::PopAndDestroy( iniTargetValue );
       
  2420 		
       
  2421 			if( KErrNone != ret )
       
  2422 				{
       
  2423 				LOG_MSG2( "  Could not find a target : FindVar(EIniKeyValue) index %d returned false\n", 
       
  2424 					observeIndex );
       
  2425 				break;
       
  2426 				}
       
  2427 
       
  2428 			//LOG_MSG2("  GenerateKeyStringLC( EIniKeyType =%d)\n", observeIndex );
       
  2429 			iniOwnerType = GenerateKeyStringLC( observeIndex, EIniKeyType );
       
  2430 
       
  2431 			TPtrC observeTargetOwner;
       
  2432 
       
  2433 			/*
       
  2434 			LOG_MSG3( "  ->FindVar( KObservedConfig, target owner %d. iniOwnerType.Length()=%d\n", 
       
  2435 				observeIndex, iniOwnerType->Des().Length() );
       
  2436 			*/
       
  2437 
       
  2438 			ret = iPersistConfigData->GetKeyValue( KObservedConfig, 
       
  2439 													iniOwnerType->Des(), 
       
  2440 													observeTargetOwner );
       
  2441 			//LOG_MSG2("  iPersistConfigData->GetKeyValue( ) returned %d\n", ret );
       
  2442 
       
  2443 			CleanupStack::PopAndDestroy( iniOwnerType );
       
  2444 
       
  2445 			if( KErrNone != ret )
       
  2446 				{
       
  2447 				LOG_MSG2( "  Could not find a target owner: FindVar(EIniKeyValue) index %d returned false\n", 
       
  2448 					observeIndex );
       
  2449 				break;
       
  2450 				}
       
  2451 
       
  2452 			//LOG_MSG("  Creating observation request\n" );
       
  2453 
       
  2454             AttachTargetL(observeTargetValue, observeTargetOwner);
       
  2455 
       
  2456 			observeIndex++;
       
  2457 			
       
  2458 			}// while targetFound
       
  2459 
       
  2460 		} // Now rebuild the Observed list from the file
       
  2461 
       
  2462 	//LOG_MSG( "  <- returning from RecreateConfigurationL()\n" );
       
  2463 
       
  2464 	}
       
  2465 
       
  2466 
       
  2467 /**
       
  2468 Method that reads the saved configuration and attempts to recreate that state.
       
  2469 For a given section of the ini file (indicated by the parameter aSource), 
       
  2470 recreate each parameter from a triplet of settings (index, type, value) 
       
  2471 and then apply the setting by calling SetConfigParameterL().
       
  2472 
       
  2473 @param aSource Section of the config file to read and update state for. 
       
  2474 @param aPersistConfigData Pointer to CIniDocument16 object that contains 
       
  2475 the parameters to restore
       
  2476 
       
  2477 @see CIniDocument16 
       
  2478 */
       
  2479 void CCoreDumpSession::ChangeConfigParamsL( const COptionConfig::TParameterSource aSource,
       
  2480 										  CIniDocument16 * aPersistConfigData, const TInt aInstance)
       
  2481 	{
       
  2482 
       
  2483 	//LOG_MSG2( "ChangeConfigParamsL( source=%d )\n", aSource );
       
  2484 
       
  2485 	TPtrC sectName;
       
  2486 	TInt ret = KErrNone;
       
  2487 
       
  2488 	switch(  aSource )
       
  2489 		{
       
  2490 		case COptionConfig::ECoreDumpServer:
       
  2491 			sectName.Set( KCDSConfig );
       
  2492 			break;
       
  2493 		case COptionConfig::EFormatterPlugin:
       
  2494 			sectName.Set( KFormatterConfig );
       
  2495 			break;
       
  2496 		case COptionConfig::EWriterPlugin:
       
  2497 			sectName.Set( KWriterConfig );
       
  2498 			break;
       
  2499 		default:
       
  2500 			User::Leave( KErrArgument );
       
  2501 		}
       
  2502 
       
  2503 
       
  2504 	HBufC * iniStringKey;
       
  2505 	TUint index = 0;
       
  2506 
       
  2507 	// Loop to recreate all the parameters for a given section and then 
       
  2508 	// call SetConfigParameterL() for each parameter
       
  2509 	// As soon as one of the FindVar fails, we assume that there are no more entries for
       
  2510 	// this section, and thus give up.
       
  2511 
       
  2512 	// Parameter index
       
  2513 	TInt keyIndex;
       
  2514 
       
  2515 	// Parameter type
       
  2516 	TInt keyType;
       
  2517 
       
  2518 	// Parameter integer value
       
  2519 	TInt keyIntValue;
       
  2520 	
       
  2521 	TLex paramLex;
       
  2522 
       
  2523 	while( KErrNone == ret )
       
  2524 		{
       
  2525 
       
  2526 		keyIndex = ELastParam;
       
  2527 		keyType = -1;
       
  2528 		keyIntValue = 0;
       
  2529 		TPtrC keyStringValue;
       
  2530 
       
  2531 		// Get parameter index
       
  2532 			{
       
  2533 			// Each value obtained via EIniKeyIndex from the file is the CConfigOption index 
       
  2534 			// and is used to tie the saved to the live index.
       
  2535 			//LOG_MSG2("  ->GenerateKeyStringLC( index=%d, EIniKeyIndex )\n", index );
       
  2536 			iniStringKey = GenerateKeyStringLC( index, EIniKeyIndex );
       
  2537 			TPtrC keyIndexString;
       
  2538 
       
  2539 			//LOG_MSG("  ->aPersistConfigData->GetKeyValue( EIniKeyIndex )\n" );
       
  2540 			ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyIndexString );
       
  2541 			CleanupStack::PopAndDestroy( iniStringKey );
       
  2542 			if( KErrNone != ret )
       
  2543 				{
       
  2544 				LOG_MSG3("  aPersistConfigData->GetKeyValue( EIniKeyIndex ) returned %d for index %d\n", ret, index );
       
  2545 				break;
       
  2546 				}
       
  2547 			
       
  2548 			paramLex.Assign( keyIndexString );
       
  2549 			keyIndex = 0;
       
  2550 			paramLex.Val( keyIndex );
       
  2551 			//LOG_MSG2( "  found EIniKeyIndex =%d\n", keyIndex );
       
  2552 			}
       
  2553 
       
  2554 
       
  2555 		// Get parameter type
       
  2556 			{
       
  2557 
       
  2558 			//LOG_MSG2("  ->GenerateKeyStringLC( index=%d, EIniKeyType )\n", index );
       
  2559 			iniStringKey = GenerateKeyStringLC( index, EIniKeyType );
       
  2560 			TPtrC keyTypeString;
       
  2561 			
       
  2562 			//LOG_MSG("  ->aPersistConfigData->GetKeyValue( EIniKeyType )\n" );
       
  2563 			ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyTypeString );
       
  2564 			CleanupStack::PopAndDestroy( iniStringKey );
       
  2565 			if( KErrNone != ret )
       
  2566 				{
       
  2567 				LOG_MSG3("  aPersistConfigData->GetKeyValue( EIniKeyType ) returned %d for index %d\n", ret, index );
       
  2568 				break;
       
  2569 				}
       
  2570 
       
  2571 			paramLex.Assign( keyTypeString );
       
  2572 			paramLex.Val( keyType );
       
  2573 			//LOG_MSG2( "  found EIniKeyType =%d\n", keyType );
       
  2574 			}
       
  2575 
       
  2576 		// Get parameter value
       
  2577 			{
       
  2578 
       
  2579 			//LOG_MSG2("  ->GenerateKeyStringLC( index=%d, EIniKeyValue )\n", index );
       
  2580 			iniStringKey = GenerateKeyStringLC( index, EIniKeyValue );
       
  2581 
       
  2582 			//LOG_MSG( "  aPersistConfigData->GetKeyValue( EIniKeyValue )\n" );
       
  2583 			ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyStringValue );
       
  2584 			
       
  2585 			//LOG_MSG2( "  aPersistConfigData->GetKeyValue( EIniKeyValue ) returned string with length=%d\n", keyStringValue.Length() );
       
  2586 			CleanupStack::PopAndDestroy( iniStringKey );
       
  2587 			if( KErrNone != ret )
       
  2588 				{
       
  2589 				LOG_MSG3("  aPersistConfigData->GetKeyValue( EIniKeyValue ) returned %d for index %d\n", ret, index );
       
  2590 				break;
       
  2591 				}
       
  2592 
       
  2593 			switch( (COptionConfig::TOptionType) keyType )
       
  2594 				{
       
  2595 				case COptionConfig::ETInt:
       
  2596 				case COptionConfig::ETUInt:
       
  2597 				case COptionConfig::ETBool:
       
  2598 					paramLex.Assign( keyStringValue );
       
  2599 					paramLex.Val( keyIntValue );
       
  2600 					keyStringValue.Set( KNullDesC );
       
  2601 					break;
       
  2602 				}
       
  2603 			}
       
  2604 
       
  2605 
       
  2606 			/*
       
  2607 			{
       
  2608 			if( -1 != keyIntValue )
       
  2609 				{
       
  2610 				LOG_MSG2( "  found EIniKeyValue as Int =%d\n", keyIntValue );
       
  2611 				}
       
  2612 
       
  2613 			RBuf value;
       
  2614 			value.Create( keyStringValue );
       
  2615 			char* cl = (char*) value.Collapse().PtrZ();
       
  2616 			RDebug::Printf("  found EIniKeyValue as String =%s\n", cl );
       
  2617 			}
       
  2618 			*/
       
  2619 
       
  2620 		LOG_MSG3( "  SetConfigParameterL( value=%d, string length=%d\n", keyIntValue, keyStringValue.Length() );
       
  2621 
       
  2622 		switch(  aSource )
       
  2623 			{
       
  2624 
       
  2625 			case COptionConfig::ECoreDumpServer:
       
  2626 				SetConfigParameterL( keyIndex, keyIntValue, keyStringValue );
       
  2627 				break;
       
  2628 
       
  2629 			case COptionConfig::EFormatterPlugin:
       
  2630 
       
  2631 				if( (iFormatterPlugins.Count() > 0 ) && (iFormatterPlugins.Count() < aInstance) )
       
  2632 					{
       
  2633 					iFormatterPlugins[aInstance]->SetConfigParameterL( keyIndex, keyIntValue, keyStringValue );
       
  2634 					}
       
  2635 				else
       
  2636 					{
       
  2637 					LOG_MSG2("CCoreDumpSession::ChangeConfigParamsL() : formatter:%d not loaded\n", aInstance);
       
  2638 					User::Leave( KErrArgument );
       
  2639 					}
       
  2640 				break;
       
  2641 
       
  2642 			case COptionConfig::EWriterPlugin:
       
  2643 
       
  2644 				if( (iWriterPlugins.Count() > 0 ) && (iWriterPlugins.Count() < aInstance) )
       
  2645 					{
       
  2646 					iWriterPlugins[aInstance]->SetConfigParameterL( keyIndex, keyIntValue, keyStringValue );
       
  2647 					}
       
  2648 				else
       
  2649 					{
       
  2650 					LOG_MSG2("CCoreDumpSession::ChangeConfigParamsL() : writer:%d not loaded\n", aInstance);
       
  2651 					User::Leave( KErrArgument );
       
  2652 					}
       
  2653 				break;
       
  2654 
       
  2655 			default:
       
  2656 				User::Leave( KErrArgument );
       
  2657 			}
       
  2658 		
       
  2659 		index ++;
       
  2660 		}//while
       
  2661 	}
       
  2662 
       
  2663 
       
  2664 _LIT(KKey,"Key");
       
  2665 _LIT(KType,"Type");
       
  2666 _LIT(KIndex,"Index");
       
  2667 _LIT(KValue,"Value");
       
  2668 
       
  2669 /**
       
  2670 This method allocates a string of two concatenated components. The first component is based on 
       
  2671 the parameter aKey. The second component is the string representation of aIndex.
       
  2672 Thus it maps an enum to a string and then it appends the index. The string is left on the 
       
  2673 cleanup stack and it is the responsibility of the caller to remove it from the cleanup stack.
       
  2674 */
       
  2675 HBufC * CCoreDumpSession::GenerateKeyStringLC( TUint aIndex, 
       
  2676 										 CCoreDumpSession::TCoreDumpIniKey aKey )
       
  2677 	{
       
  2678 
       
  2679 	HBufC * keyString = HBufC::NewL( 20 );
       
  2680 	CleanupStack::PushL( keyString );
       
  2681 
       
  2682 	TPtr ptr = keyString->Des();
       
  2683 	ptr.Append( KKey );
       
  2684 
       
  2685 	switch( aKey )
       
  2686 		{
       
  2687 		case EIniKeyType:
       
  2688 			ptr.Append( KType );
       
  2689 			break;
       
  2690 
       
  2691 		case EIniKeyIndex:
       
  2692 			ptr.Append( KIndex );
       
  2693 			break;
       
  2694 
       
  2695 		case EIniKeyValue:
       
  2696 			ptr.Append( KValue );
       
  2697 			break;
       
  2698 		}
       
  2699 
       
  2700 	ptr.AppendNum( aIndex );
       
  2701 	return keyString;
       
  2702 	}
       
  2703 
       
  2704 void CCoreDumpSession::SuspendProcessL(TUint64 aPid)
       
  2705     {
       
  2706     LOG_MSG("->CCoreDumpSession::SuspendProcessL()\n");
       
  2707     iDataSource->GetThreadListL( aPid, iThreadPointerList, iTotalThreadListDescSize );
       
  2708     TInt err = KErrNone;
       
  2709     for(TInt i = 0; i < iThreadPointerList.Count(); i++)
       
  2710         {
       
  2711         LOG_MSG2("CCoreDumpSession::SuspenProcessL - suspending thread:%Ld\n", iThreadPointerList[i]->Id());
       
  2712         err = iSecSess.SuspendThread(iThreadPointerList[i]->Id());
       
  2713             if( (err != KErrNone) && (err != KErrAlreadyExists) )
       
  2714             {
       
  2715             LOG_MSG2("CCoreDumpSession::SuspendProcessL - unable to suspend thread! err:%d\n", err); 
       
  2716             User::LeaveIfError(err);
       
  2717             }
       
  2718         } 
       
  2719     }
       
  2720 
       
  2721 void CCoreDumpSession::ResumeThreadL(TUint64 aTid)
       
  2722 {
       
  2723     LOG_MSG2("->CCoreDumpSession::ResumeThreadL(aTid=%Ld)\n", aTid);
       
  2724 
       
  2725     TInt err = iSecSess.ResumeThread(TThreadId(aTid));
       
  2726     if(err != KErrNone)
       
  2727         {
       
  2728         LOG_MSG2("CCoreDumpSession::ResumeThreadL - unable to resume thread! err:%d\n", err); 
       
  2729         User::LeaveIfError(err);
       
  2730         }
       
  2731 }
       
  2732 
       
  2733 /**
       
  2734 Called to resume all the threads of the specified process. CCoreCrashHandler executes it as a post-processing action.
       
  2735 @param aPid ID of process to be resumed
       
  2736 @leave err one of the system wide error codes
       
  2737 @see SuspendProcessL
       
  2738 */
       
  2739 void CCoreDumpSession::ResumeProcessL(TUint64 aPid)
       
  2740 	{
       
  2741     LOG_MSG2("->CCoreDumpSession::ResumeProcessL(aPid=%Ld)\n", aPid);
       
  2742 
       
  2743     iDataSource->GetThreadListL( aPid, iThreadPointerList, iTotalThreadListDescSize );
       
  2744 
       
  2745     TInt err = KErrNone;
       
  2746     //first resume child threads
       
  2747     TInt looperr = KErrNone;
       
  2748     for(TInt j = 1; j < iThreadPointerList.Count(); j++)
       
  2749         {
       
  2750         LOG_MSG2("CCoreDumpSession::ResumeProcessL - resuming thread:%Ld\n", iThreadPointerList[j]->Id());
       
  2751         looperr = iSecSess.ResumeThread( iThreadPointerList[j]->Id() );
       
  2752         if( (looperr != KErrNone) && (looperr != KErrNotFound) )
       
  2753             {
       
  2754             err = looperr;
       
  2755             LOG_MSG2("CCoreDumpSession::ResumeProcessL - unable to resume thread! err:%d\n", err);
       
  2756             }
       
  2757         }
       
  2758 
       
  2759     looperr = KErrNone;
       
  2760     //then resume the main thread
       
  2761     if(iThreadPointerList.Count())
       
  2762         {
       
  2763         LOG_MSG2("CCoreDumpSession::ResumeProcessL - resuming main thread:%Ld\n", iThreadPointerList[0]->Id());
       
  2764         looperr = iSecSess.ResumeThread(iThreadPointerList[0]->Id());
       
  2765         }
       
  2766 
       
  2767     if( (looperr != KErrNone) && (looperr != KErrNotFound) )
       
  2768         {
       
  2769         err = looperr;
       
  2770         LOG_MSG2("CCoreDumpSession::ResumeProcessL - unable to resume main thread! err:%d\n", err); 
       
  2771         }
       
  2772 
       
  2773     User::LeaveIfError(err);
       
  2774 	}
       
  2775 
       
  2776 
       
  2777 void CCoreDumpSession::KillProcessL(TUint64 aPid)
       
  2778     {
       
  2779     LOG_MSG2("->CCoreDumpSession::KillProcessL(aPid=%Ld)\n", aPid);
       
  2780     RProcess target;
       
  2781     //LOG_MSG("CCoreDumpSession::KillProcessL - opening crashed process handle\n"); 
       
  2782     TInt err = target.Open(aPid);
       
  2783     if(err != KErrNone)
       
  2784     {
       
  2785         LOG_MSG2("CCoreDumpSession::KillProcessL - unable to open process handle! err:%d\n", err); 
       
  2786         User::Leave(err);
       
  2787     }
       
  2788 
       
  2789     CleanupClosePushL(target);
       
  2790 
       
  2791     TInt i;
       
  2792     for(i = 0; i < iObservationList.Count(); i++)
       
  2793         {
       
  2794         if(iObservationList[i]->TargetName().CompareF(target.FileName()) == 0) break;
       
  2795         }
       
  2796 
       
  2797     ResumeProcessL(aPid);
       
  2798 
       
  2799     if(i == iObservationList.Count())
       
  2800         {
       
  2801         LOG_MSG("CCoreDumpSession::KillProcessL - unable to find process observer!\n");
       
  2802         User::Leave(KErrNotFound);
       
  2803         }
       
  2804 
       
  2805 	LOG_MSG("  -> SetCrashEventsL(*iObservationList[i], EActionIgnore)\n" ); 
       
  2806     SetCrashEventsL(*iObservationList[i], EActionIgnore);
       
  2807 
       
  2808 	LOG_MSG("  -> target.Terminate(KErrAbort)\n" ); 
       
  2809     target.Terminate(KErrAbort);
       
  2810 	
       
  2811 	TRequestStatus logonStatus;
       
  2812 	LOG_MSG("  -> target.Logon( logonStatus );\n" ); 
       
  2813 	target.Logon( logonStatus );
       
  2814 	LOG_MSG("  <- target.Logon( logonStatus );\n" ); 
       
  2815 
       
  2816 	CleanupStack::PopAndDestroy(&target); //target
       
  2817 
       
  2818 	User::WaitForRequest( logonStatus );
       
  2819 	LOG_MSG("  <- User::WaitForRequest( logonStatus );\n" ); 
       
  2820 	
       
  2821 
       
  2822     if( (iPreCrashEventAction & ESuspendThread) || 
       
  2823 		(iPreCrashEventAction & ESuspendProcess) )
       
  2824         SetCrashEventsL(*iObservationList[i], EActionSuspend);
       
  2825     else
       
  2826         SetCrashEventsL(*iObservationList[i], EActionContinue);
       
  2827     }
       
  2828 
       
  2829 /**
       
  2830  * Cleanup item implementation for SCMConfiguration
       
  2831 */
       
  2832 void CCoreDumpSession::CleanupSCMConfiguration(TAny* aScmConfig)
       
  2833 	{
       
  2834 	SCMConfiguration* config = static_cast<SCMConfiguration*> (aScmConfig);
       
  2835 	delete config;
       
  2836 	config = NULL;
       
  2837 	}
       
  2838 
       
  2839 
       
  2840 //void CCoreDumpSession::ReadSCMConfigListL()
       
  2841 //	{	
       
  2842 //	// read the config data from the flash data source	
       
  2843 //	}
       
  2844 //
       
  2845 //void CCoreDumpSession::WriteSCMConfigListL()
       
  2846 //	{	
       
  2847 //	// read the config data from the flash data source	
       
  2848 //	iFlashDataSource->WriteSCMConfigL();	
       
  2849 //	}
       
  2850 //
       
  2851