devicediagnosticsfw/diagresultsdb/server/src/diagresultsdbtestrecordsubsession.cpp
branchRCL_3
changeset 25 b183ec05bd8c
parent 24 13d7c31c74e0
child 26 19bba8228ff0
equal deleted inserted replaced
24:13d7c31c74e0 25:b183ec05bd8c
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class definition of 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "diagresultsdatabasecommon.h"
       
    20 #include "diagresultsdbsession.h"
       
    21 #include "diagresultsdbtestrecordsubsession.h"
       
    22 #include "diagresultsdbtestrecord.h"
       
    23 #include "diagresultsdbtestrecordhandle.h"
       
    24 #include "diagresultsdbrecordengineparam.h"
       
    25 #include "diagresultsdatabase.h"
       
    26 
       
    27 #include <s32mem.h> 
       
    28 
       
    29 //this matches the size in the client side.
       
    30 const TInt KResultsDatabaseSubsessionBufferLength = 0x250;
       
    31 const TInt KResultsDatabaseSubsessionGranuality = 50;
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // NewL.
       
    35 // ---------------------------------------------------------------------------
       
    36 // 
       
    37 CDiagResultsDbTestRecordSubsession* CDiagResultsDbTestRecordSubsession::NewL(
       
    38                              CDiagResultsDbSession* aSession, 
       
    39                              CDiagResultsDbTestRecordHandle* aTestRecordHandle,
       
    40                              TBool aReadonly
       
    41                              )
       
    42     {
       
    43     CDiagResultsDbTestRecordSubsession* self = new( ELeave ) 
       
    44                 CDiagResultsDbTestRecordSubsession( aSession, 
       
    45                                                     aTestRecordHandle,
       
    46                                                     aReadonly
       
    47                                                     );
       
    48     CleanupStack::PushL( self );
       
    49     self->ConstructL();
       
    50     CleanupStack::Pop();
       
    51     return self;
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // Destructor. Checks has the test record been written into the DB.
       
    56 // If it hasn't been written, destructor writes the data. 
       
    57 // This situation happens when for example client dies suddenly.
       
    58 // ---------------------------------------------------------------------------
       
    59 // 
       
    60 CDiagResultsDbTestRecordSubsession::~CDiagResultsDbTestRecordSubsession()
       
    61     {
       
    62     delete iTestRecordHandle;
       
    63     iTestRecordHandle = NULL;
       
    64     
       
    65     if ( iBuffer )
       
    66         {
       
    67         iBuffer->Reset();
       
    68         delete iBuffer;
       
    69         iBuffer = NULL;
       
    70         }
       
    71     }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // ConstructL. Creates the server side buffer.
       
    75 // ---------------------------------------------------------------------------
       
    76 // 
       
    77 void CDiagResultsDbTestRecordSubsession::ConstructL()
       
    78     {
       
    79     // buffer for IPC. Objects are transmitted in this buffer.
       
    80 	// Size of the buffer has to be selected carefully.
       
    81 	// It should be 'large enough' but not too large.
       
    82 	// If you see too many overflows, increase the size.
       
    83 	// Subsession buffer can be smaller than the session buffer
       
    84 	iBuffer = CBufFlat::NewL( KResultsDatabaseSubsessionGranuality  );
       
    85 	iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
    86     }
       
    87 
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // Handles subsession requests. 
       
    91 // ---------------------------------------------------------------------------
       
    92 // 
       
    93 TBool CDiagResultsDbTestRecordSubsession::DispatchMessageL(
       
    94                                                     const RMessage2& aMessage)
       
    95     {
       
    96     TInt function = aMessage.Function();
       
    97     switch( function )
       
    98 		{
       
    99         case DiagResultsDbCommon::ESubsessionGetTestRecordId:
       
   100             {            
       
   101             TPckgBuf<TUid> uid( iTestRecordHandle->RecordInfo().iRecordId);
       
   102             aMessage.Write( 0, uid );
       
   103             return EFalse;
       
   104             }
       
   105         
       
   106         case DiagResultsDbCommon::ESubsessionTestCompleted: //SYNC
       
   107             {
       
   108             iMsg = aMessage;
       
   109            
       
   110             CompleteTestRecordL( aMessage );
       
   111             
       
   112             aMessage.Complete( KErrNone );
       
   113             
       
   114             //Do compacting after subsession is completed to
       
   115             //minimize disk space usage
       
   116             if ( iSession->SessionHasWritten() )
       
   117                 {
       
   118                 iSession->Store().CompactDatabase();
       
   119                 }
       
   120             
       
   121             //Not asynchronous, but this prevents calling Complete again.
       
   122             return ETrue;
       
   123             }
       
   124   
       
   125         case DiagResultsDbCommon::ESubsessionGetStatus:
       
   126             {
       
   127             GetStatusL ( aMessage );
       
   128             return EFalse;
       
   129             }
       
   130 		case DiagResultsDbCommon::ESubsessionSuspend: //SYNC
       
   131 		    {
       
   132 		    iMsg = aMessage;
       
   133            
       
   134             SuspendTestRecordL( aMessage );
       
   135             
       
   136             aMessage.Complete( KErrNone );
       
   137             
       
   138             //Do compacting after subsession is completed to
       
   139             //minimize disk space usage
       
   140             if ( iSession->SessionHasWritten() )
       
   141                 {
       
   142                 iSession->Store().CompactDatabase();
       
   143                 }
       
   144             
       
   145             //Not asynchronous, but this prevents calling Complete again.
       
   146             return ETrue;
       
   147 		    }
       
   148             
       
   149         case DiagResultsDbCommon::ESubsessionIsTestCompleted:
       
   150             {
       
   151             TPckgBuf<TBool> pckg ( Completed() );
       
   152             aMessage.Write( 0, pckg );
       
   153             return EFalse;
       
   154             }
       
   155         case DiagResultsDbCommon::ESubsessionGetRecordInfo:
       
   156             {
       
   157             TPckgBuf<TDiagResultsDatabaseTestRecordInfo> pckg(
       
   158                                                  iTestRecordHandle->RecordInfo());
       
   159             aMessage.Write( 0, pckg );
       
   160             return EFalse;
       
   161             }
       
   162         case DiagResultsDbCommon::ESubsessionGetTestUids:
       
   163             {
       
   164             GetTestUidsL( aMessage );
       
   165             return EFalse;
       
   166             }
       
   167             
       
   168 		case DiagResultsDbCommon::ESubsessionIsSuspended:
       
   169 		    {
       
   170 		    TBool suspended = EFalse;
       
   171             if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
       
   172                     TDiagResultsDatabaseTestRecordInfo::ESuspended )
       
   173                 {
       
   174                 suspended = ETrue;
       
   175                 }
       
   176                 
       
   177             TPckgBuf<TBool> pckg ( suspended );
       
   178             aMessage.Write( 0, pckg );
       
   179             return EFalse;
       
   180 		    }
       
   181 		
       
   182 		case DiagResultsDbCommon::ESubsessionGetEngineParam:
       
   183 		    {
       
   184 		    GetEngineParamL( aMessage );
       
   185             return EFalse;
       
   186 		    }    
       
   187 		    
       
   188         case DiagResultsDbCommon::ESubsessionLogTestResult: //ASYNC
       
   189             {
       
   190             iMsg = aMessage;
       
   191             iCompletedLogTest = EFalse;
       
   192             LogTestResultL( aMessage );
       
   193             return ETrue;
       
   194             }
       
   195         
       
   196         case DiagResultsDbCommon::ESubsessionCancelLogTestResult: 
       
   197             {
       
   198             CancelLogTestResult( aMessage );
       
   199             
       
   200             return EFalse;
       
   201             }
       
   202 
       
   203         case DiagResultsDbCommon::ESubsessionGetTestResult:
       
   204             {
       
   205             GetTestResultL( aMessage );
       
   206             return EFalse;
       
   207             }
       
   208             
       
   209         case DiagResultsDbCommon::ESubsessionGetTestResults:
       
   210             {
       
   211             GetTestResultsL( iTestRecordHandle, aMessage );
       
   212             return EFalse;
       
   213             }
       
   214         default:
       
   215             break;
       
   216 		}
       
   217 	aMessage.Panic( _L("DiagSrv panic: unknown command"), 
       
   218 	                    DiagResultsDbCommon::EBadRequest );
       
   219 	return EFalse;
       
   220 	}
       
   221 
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // Returns record complete status.
       
   225 // ---------------------------------------------------------------------------
       
   226 // 
       
   227 TBool CDiagResultsDbTestRecordSubsession::Completed() const
       
   228     {
       
   229     TBool completed = EFalse;
       
   230      
       
   231     if ( iTestRecordHandle->RecordInfo().iCompleted )
       
   232         {
       
   233         completed = ETrue;
       
   234         }
       
   235     return completed;         
       
   236     }
       
   237 
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // Maps server side status into user side status.
       
   241 // ---------------------------------------------------------------------------
       
   242 //  
       
   243 void CDiagResultsDbTestRecordSubsession::GetStatusL ( const RMessage2& aMessage )
       
   244     {
       
   245     
       
   246     RDiagResultsDatabaseRecord::TRecordStatus status;
       
   247     
       
   248     if ( iTestRecordHandle->RecordInfo().iCompleted )
       
   249         {
       
   250         
       
   251         if ( iTestRecordHandle->RecordInfo().iRecordStatus == 
       
   252                                     TDiagResultsDatabaseTestRecordInfo::EOpen )
       
   253             {
       
   254             
       
   255             status = RDiagResultsDatabaseRecord::EPartiallyCompleted;
       
   256             }
       
   257         else if ( iTestRecordHandle->RecordInfo().iRecordStatus == 
       
   258                                     TDiagResultsDatabaseTestRecordInfo::ESuspended )
       
   259             {
       
   260             status = RDiagResultsDatabaseRecord::EPartiallyCompleted;
       
   261             }
       
   262         else if (  iTestRecordHandle->RecordInfo().iRecordStatus == 
       
   263                                     TDiagResultsDatabaseTestRecordInfo::ECompleted )   
       
   264             {
       
   265             status = RDiagResultsDatabaseRecord::ECompleted;
       
   266             }     
       
   267         else 
       
   268         	{        		  
       
   269             User::Panic( _L("DiagDbServer error"), DiagResultsDbCommon::EGetStatusPanic);                  
       
   270 			status = RDiagResultsDatabaseRecord::ECrashed;	
       
   271         	}
       
   272         }
       
   273     else // iCompleted == EFalse
       
   274         {
       
   275          if ( iTestRecordHandle->RecordInfo().iRecordStatus == 
       
   276                                     TDiagResultsDatabaseTestRecordInfo::EOpen )
       
   277             {
       
   278             if ( iSession->SessionHasWritten() )
       
   279                 {
       
   280                 status = RDiagResultsDatabaseRecord::EOpen;
       
   281                 }
       
   282             else
       
   283                 {
       
   284                 status = RDiagResultsDatabaseRecord::ECrashed;
       
   285                 }
       
   286             }
       
   287         else if ( iTestRecordHandle->RecordInfo().iRecordStatus == 
       
   288                                     TDiagResultsDatabaseTestRecordInfo::ESuspended )
       
   289             {
       
   290             status = RDiagResultsDatabaseRecord::ESuspended;
       
   291             }
       
   292          // TDiagResultsDatabaseTestRecordInfo::ECompleted is not valid combination either
       
   293         else     
       
   294             {
       
   295             User::Panic( _L("DiagDbServer error"), DiagResultsDbCommon::EGetStatusPanic);
       
   296 			status = RDiagResultsDatabaseRecord::ECrashed;
       
   297             }        
       
   298         }
       
   299         
       
   300     TPckgBuf<RDiagResultsDatabaseRecord::TRecordStatus> pckg( status );
       
   301     aMessage.Write( 0, pckg );    
       
   302     }
       
   303 
       
   304 // ---------------------------------------------------------------------------
       
   305 // Constructor.
       
   306 // ---------------------------------------------------------------------------
       
   307 //     
       
   308 CDiagResultsDbTestRecordSubsession::CDiagResultsDbTestRecordSubsession(
       
   309                             CDiagResultsDbSession* aSession, 
       
   310                             CDiagResultsDbTestRecordHandle* aTestRecordHandle,
       
   311                             TBool aReadonly
       
   312                             ):
       
   313         iSession( aSession ), iTestRecordHandle( aTestRecordHandle ), 
       
   314         iReadonly (aReadonly), iCompletedLogTest( EFalse )
       
   315     {
       
   316 	
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // Read-only subsession or not
       
   321 // ---------------------------------------------------------------------------
       
   322 // 
       
   323 TBool CDiagResultsDbTestRecordSubsession::ReadonlySubsession() const
       
   324     {
       
   325     return iReadonly;
       
   326     }
       
   327 
       
   328 // ---------------------------------------------------------------------------
       
   329 // Retrieve session params.
       
   330 // ---------------------------------------------------------------------------
       
   331 // 
       
   332 void CDiagResultsDbTestRecordSubsession::GetEngineParamL( const RMessage2& aMessage )
       
   333     {    
       
   334     iSession->ReadBufferL( aMessage, 0, iBuffer );
       
   335 
       
   336 	RBufWriteStream stream ( *iBuffer );
       
   337 	CleanupClosePushL( stream );
       
   338 
       
   339     iTestRecordHandle->GetEngineParam().ExternalizeL( stream );    
       
   340     
       
   341     stream.CommitL();
       
   342     
       
   343 	CleanupStack::PopAndDestroy( &stream );
       
   344 	
       
   345 	 // if client buffer is not big enough	    
       
   346     if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
       
   347         {
       
   348         User::Leave( KErrOverflow );
       
   349         }
       
   350     
       
   351     aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space 
       
   352     }
       
   353 
       
   354 
       
   355 // ---------------------------------------------------------------------------
       
   356 // Log data into the store. This does not write data into the file.
       
   357 // ---------------------------------------------------------------------------
       
   358 // 
       
   359 void CDiagResultsDbTestRecordSubsession::LogTestResultL( 
       
   360                                                 const RMessage2& aMessage )
       
   361     {
       
   362     if ( Completed() )
       
   363         {
       
   364         User::Leave( KErrAlreadyExists );
       
   365         }
       
   366         
       
   367     if ( ReadonlySubsession() )
       
   368         {
       
   369         User::Leave( KErrAccessDenied  );
       
   370         }
       
   371         
       
   372     //Writing anymore results into suspended record is considered as resume   
       
   373     iTestRecordHandle->RecordInfo().iRecordStatus = 
       
   374                                     TDiagResultsDatabaseTestRecordInfo::EOpen;
       
   375         
       
   376     iSession->ReadBufferL( aMessage, 0, iBuffer );
       
   377     
       
   378     RBufReadStream stream( *iBuffer );
       
   379     CleanupClosePushL ( stream );
       
   380     
       
   381     CDiagResultsDatabaseItem * item = 
       
   382                             CDiagResultsDatabaseItem::NewL ( stream );
       
   383     CleanupStack::PushL( item );    
       
   384 
       
   385     //Update handle + write data into the file. Handle and DB must be in sync.
       
   386     TInt error = iSession->Store().CompleteTestResult( ETrue, 
       
   387                                                        *iTestRecordHandle, 
       
   388                                                        *item );
       
   389     
       
   390     //item has been written, so delete the object
       
   391     CleanupStack::PopAndDestroy( item ); 
       
   392     CleanupStack::PopAndDestroy( &stream );
       
   393     
       
   394     iCompletedLogTest = ETrue;
       
   395     
       
   396     // LogTestResult is asynchronous.
       
   397     if( error == KErrNone )
       
   398         {
       
   399         iSession->HasWritten();
       
   400         aMessage.Complete( KErrNone );   
       
   401         }
       
   402     else 
       
   403         {
       
   404         if ( error == KErrDiskFull )
       
   405             {
       
   406             iSession->DoNotCompact();
       
   407             }
       
   408             
       
   409         aMessage.Complete ( error );
       
   410         }
       
   411     }
       
   412 
       
   413 
       
   414 // ---------------------------------------------------------------------------
       
   415 // Cancel LogTestResultL.
       
   416 // ---------------------------------------------------------------------------
       
   417 // 
       
   418 void CDiagResultsDbTestRecordSubsession::CancelLogTestResult( 
       
   419                                                const RMessage2& /*aMessage*/ )
       
   420     {
       
   421     if (!iMsg.IsNull() && !iCompletedLogTest )
       
   422         {  
       
   423         iMsg.Complete( KErrCancel ); //Complete client's request. 
       
   424         }
       
   425     }
       
   426 
       
   427     
       
   428 // ---------------------------------------------------------------------------
       
   429 // Returns the test record.
       
   430 // ---------------------------------------------------------------------------
       
   431 // 
       
   432 CDiagResultsDbTestRecordHandle* CDiagResultsDbTestRecordSubsession::CurrentTestRecordHandle()
       
   433     {
       
   434     return iTestRecordHandle;
       
   435     }
       
   436 
       
   437 // ---------------------------------------------------------------------------
       
   438 // Finds one test result and serialize it. If it is not found, return KErrNone
       
   439 // ---------------------------------------------------------------------------
       
   440 // 
       
   441 void CDiagResultsDbTestRecordSubsession::GetTestResultL( 
       
   442                                                    const RMessage2& aMessage )
       
   443     {
       
   444     iSession->ReadBufferL( aMessage, 1, iBuffer );
       
   445     
       
   446     TPckgBuf<TUid> uidpckg;
       
   447 	aMessage.Read(0, uidpckg);
       
   448     TUid testUid = uidpckg(); 
       
   449 	
       
   450 	//Find right stream Id from the handle
       
   451 	TStreamId id;
       
   452 	TInt error = iTestRecordHandle->MatchingStreamId( testUid, id );
       
   453 	
       
   454 	User::LeaveIfError ( error );
       
   455 	
       
   456 	CDiagResultsDatabaseItem* item = 
       
   457 	     iSession->Store().OpenExistingTestResultL( id );
       
   458 	CleanupStack::PushL( item );
       
   459 	  
       
   460 	RBufWriteStream stream ( *iBuffer );
       
   461 	CleanupClosePushL( stream );
       
   462 	item->ExternalizeL( stream );
       
   463 	stream.CommitL();
       
   464 	CleanupStack::PopAndDestroy( &stream );
       
   465 	
       
   466 	CleanupStack::PopAndDestroy( item );
       
   467 	          
       
   468 	if ( iBuffer->Size() == 0 ) // Item was not found
       
   469 	    {
       
   470 	    User::Leave ( KErrNotFound );
       
   471 	    }
       
   472 	
       
   473 	 // if client buffer is not big enough	    
       
   474     if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(1) )
       
   475         {
       
   476         User::Leave( KErrOverflow );
       
   477         }
       
   478     
       
   479     aMessage.Write( 1, iBuffer->Ptr(0) ); //write to client's address space 
       
   480    
       
   481     }
       
   482 
       
   483 // ---------------------------------------------------------------------------
       
   484 // Complete test record i.e. write it to file in parts.
       
   485 // ---------------------------------------------------------------------------
       
   486 // 
       
   487 void CDiagResultsDbTestRecordSubsession::CompleteTestRecordL( 
       
   488                                                    const RMessage2& aMessage )
       
   489     {
       
   490     if ( Completed() )
       
   491         {
       
   492         User::Leave( KErrAlreadyExists );
       
   493         }
       
   494     if ( ReadonlySubsession() )
       
   495         {
       
   496         User::Leave( KErrAccessDenied  );
       
   497         }    
       
   498     
       
   499     TPckgBuf<TBool> completeFullyPckg;
       
   500 	aMessage.Read(0, completeFullyPckg);
       
   501     TBool completeFully = completeFullyPckg();
       
   502     
       
   503     if ( completeFully )
       
   504         {
       
   505         iTestRecordHandle->RecordInfo().iRecordStatus = 
       
   506                                 TDiagResultsDatabaseTestRecordInfo::ECompleted;
       
   507                                 
       
   508         iTestRecordHandle->RecordInfo().iCompleted = ETrue;
       
   509         }
       
   510     else // partial complete. iRecordStatus is not changed.
       
   511         {
       
   512         iTestRecordHandle->RecordInfo().iCompleted = ETrue;
       
   513         }
       
   514     
       
   515     //Cleanup is not necessary if logging failed.
       
   516     TInt error = iSession->Store().CompleteRecord( *iTestRecordHandle );
       
   517     
       
   518     if ( error == KErrDiskFull )
       
   519             {
       
   520             iSession->DoNotCompact();
       
   521             }
       
   522    
       
   523     User::LeaveIfError ( error );         
       
   524     
       
   525     iSession->HasWritten();
       
   526     
       
   527     iSession->Store().CleanUpDatabaseL( ETrue );
       
   528     }
       
   529 
       
   530 
       
   531 // ---------------------------------------------------------------------------
       
   532 // Suspend test record i.e. write it to file in parts.
       
   533 // ---------------------------------------------------------------------------
       
   534 // 
       
   535 void CDiagResultsDbTestRecordSubsession::SuspendTestRecordL( 
       
   536                                                    const RMessage2& /*aMessage*/ )
       
   537     {
       
   538     if ( Completed() )
       
   539         {
       
   540         User::Leave( KErrAlreadyExists );
       
   541         }
       
   542     if ( ReadonlySubsession() )
       
   543         {
       
   544         User::Leave( KErrAccessDenied  );
       
   545         }    
       
   546     
       
   547     iTestRecordHandle->RecordInfo().iRecordStatus = 
       
   548                                 TDiagResultsDatabaseTestRecordInfo::ESuspended;
       
   549 
       
   550     iTestRecordHandle->RecordInfo().iCompleted = EFalse;
       
   551                                 
       
   552     TInt error = iSession->Store().CompleteRecord( *iTestRecordHandle );
       
   553     
       
   554      if ( error == KErrDiskFull )
       
   555             {
       
   556             iSession->DoNotCompact();
       
   557             }
       
   558    
       
   559     User::LeaveIfError ( error );         
       
   560         
       
   561     iSession->Store().CleanUpDatabaseL( ETrue );
       
   562     
       
   563     iSession->HasWritten();
       
   564     }
       
   565 
       
   566 // ---------------------------------------------------------------------------
       
   567 // Observers function. Observers store after CompleteTestRecordL has been
       
   568 // called.
       
   569 // ---------------------------------------------------------------------------
       
   570 // 
       
   571 void CDiagResultsDbTestRecordSubsession::CompletedRecordL( TInt aError )
       
   572     {
       
   573     iMsg.Complete( aError ); // complete async function
       
   574     }
       
   575 
       
   576 
       
   577 // ---------------------------------------------------------------------------
       
   578 // Get test results of a test record.
       
   579 // ---------------------------------------------------------------------------
       
   580 // 
       
   581 void CDiagResultsDbTestRecordSubsession::GetTestResultsL( 
       
   582                                         CDiagResultsDbTestRecordHandle* aHandle, 
       
   583                                         const RMessage2& aMessage )
       
   584     {
       
   585     iSession->ReadBufferL( aMessage, 0, iBuffer );
       
   586     
       
   587     	
       
   588     RBufWriteStream stream ( *iBuffer );
       
   589     CleanupClosePushL ( stream );
       
   590     stream.WriteInt16L( aHandle->Count() );
       
   591 	
       
   592 	CDiagResultsDbTestRecord* testrecord = 
       
   593 	    iSession->Store().OpenExistingRecordL( TUid::Uid(aHandle->RecordId().Value()), ETrue );
       
   594 	CleanupStack::PushL (testrecord);
       
   595 	
       
   596 	for ( TInt i = 0; i < aHandle->Count(); ++i )
       
   597 	    {
       
   598 	    const CDiagResultsDatabaseItem& item = (*testrecord)[i];
       
   599 	    item.ExternalizeL( stream );
       
   600 	    }
       
   601 	    
       
   602     CleanupStack::PopAndDestroy( testrecord );
       
   603     
       
   604     // if client buffer is not big enough
       
   605     if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) ) 
       
   606         {
       
   607         User::Leave( KErrOverflow );
       
   608         }
       
   609 
       
   610     aMessage.Write( 0, iBuffer->Ptr(0) );  //write to client's address space
       
   611     
       
   612     CleanupStack::PopAndDestroy( &stream );
       
   613     } 
       
   614 
       
   615 // ---------------------------------------------------------------------------
       
   616 // Get UIDs of test results that are stored inside the test record.
       
   617 // ---------------------------------------------------------------------------
       
   618 //     
       
   619 void CDiagResultsDbTestRecordSubsession::GetTestUidsL( 
       
   620                                             const RMessage2& aMessage )
       
   621     {
       
   622     iSession->ReadBufferL( aMessage, 0, iBuffer );
       
   623     
       
   624    	RBufWriteStream stream ( *iBuffer );
       
   625    	CleanupClosePushL( stream );
       
   626 
       
   627    	//Write how many uids there are.
       
   628    	stream.WriteInt16L( iTestRecordHandle->Count() );
       
   629    	
       
   630 	for (TInt i = 0; i < iTestRecordHandle->Count(); ++i)
       
   631 	    {
       
   632 	    stream.WriteInt32L( iTestRecordHandle->Get(i).iTestUid.iUid ) ;        
       
   633 	    }
       
   634 	        
       
   635 	// if client buffer is not big enough        
       
   636     if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) ) 
       
   637         {
       
   638         User::Leave( KErrOverflow );
       
   639         }
       
   640     
       
   641     
       
   642     aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space 
       
   643    
       
   644     CleanupStack::PopAndDestroy( &stream );
       
   645     }