boottimeintegritycheck/src/IntegrityCheck.cpp
changeset 0 164170e6151a
child 8 ece4bbb094df
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/boottimeintegritycheck/src/IntegrityCheck.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,2858 @@
+/*
+* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implementation of boot time integrity check program.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32cons.h>
+#include <f32file.h>
+#include <cctcertinfo.h>        // TCapabilitySet
+#include <s32file.h> 
+#include <signed.h>             // VerifySignatureL
+#include <x500dn.h>             // ExactMatchL
+#include <x509cert.h>           // x509
+#include <swi/hashcontainer.h>
+#include <swi/sisregistrysession.h>
+#include <swi/sisregistryentry.h>
+#include <swi/sisregistrypackage.h>
+#include <hash.h>
+#include <etelmm.h>             // For serial number size
+
+#include "IntegrityCheck.h"
+#include "InfoServerClient.h"
+#include "IntegrityCheckDefs.h"
+#include "IntegrityCheckClient.h"
+#include "IntegrityCheckDebug.h"
+
+
+// CONSTANTS
+
+_LIT(KBTICThreadName,"BootIntegrityCheck"); 
+_LIT(KBTICCertStoreZ,"z:\\resource\\swicertstore.dat");
+_LIT(KBTICCertStoreCName,"updatedswicertstore.dat");
+_LIT(KBTICCertStoreCPath,"c:\\resource\\swicertstore\\dat\\");
+_LIT(KBTICDriveC,"c:\\");
+_LIT(KBTICDriveCWildcard,"c:\\*");
+_LIT(KBTICExtensionExe,"*.exe");
+_LIT(KBTICSerialNumberFile,"*imei.txt");
+_LIT(KBTICStarWildcard,"*\\");
+/*
+#ifdef __BTIC_BINARIES_CHECK_ENABLED
+_LIT(KBTICSysPathC,"c:\\sys\\bin\\");
+_LIT(KBTICCertStoreC,
+    "c:\\resource\\swicertstore\\dat\\updatedswicertstore.dat"); 
+_LIT(KBTICSysPathCWildcard,"c:\\sys\\bin\\*");
+_LIT(KBTICExtensionDll,"*.dll");
+_LIT(KBTICExtensionDat,"*.dat");
+#endif //__BTIC_BINARIES_CHECK_ENABLED 
+*/    
+const TInt KBTICCapaCount = 2;  //Number of capabilities.
+const TUint64 KBTIC_DRM = 64;   //0000 0000 0000 0000 0000 0000 0100 0000
+const TUint64 KBTIC_TCB = 1;    //0000 0000 0000 0000 0000 0000 0000 0001
+const TInt KBTICCabaWordOffset = 17; //File heder offset for capa. word @ 64bit.  
+const TInt KBTICHashSize = 20; 
+const TInt KBTICTryToOpen = 240;  //Try to open file. (240 x 0.5sec = 120sec)   
+const TInt KBTICTryToCreate = 5; // Try to create process.
+const TUint KBTICObserverTime = 1000000; // 1sec.
+const TUint KBTICRunCount = 10; 
+        
+// MACROS
+
+using namespace Swi;
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+LOCAL_C TInt ThreadStartL();
+
+LOCAL_C TInt ReadCertificatesL( 
+    RFs& aFs, 
+    const TDesC& aPath,     
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCapabilityArray  );
+ 
+LOCAL_C TBool ValidateCertStoreL(
+    RFs& aFs,     
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCapaArray,
+    const TDesC& aCertStoreFileName,
+    const TDesC& aCertStoreFilePath ); 
+    
+LOCAL_C TBool ValidateProvisonerCertStoreL(
+    RFs& aFs,                                           
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCapaArray,     
+    const TDesC& aCertStoreFileName,
+    const TDesC& aCertStoreFilePath,
+    RSisRegistryEntry& aEntry );
+    
+LOCAL_C TBool ValidateSymbianCertStoreL(
+    RFs& aFs,                                           
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCapaArray,              
+    RSisRegistryEntry& aEntry,
+    RPointerArray<HBufC>& aUpdaterExePaths ); 
+    
+LOCAL_C TBool RunUpdaterL( RFs& aFs, RPointerArray<HBufC>& aUpdaterExePaths );    
+    
+LOCAL_C TBool DeleteAllFilesL( RFs& aFs, const TDesC& aFolderPath );                
+
+LOCAL_C TBool SearchFilesFromArrayL( 
+    RPointerArray<HBufC>& aSourceArray,
+    const TDesC& aDriveAndPath,
+    RPointerArray<HBufC>& aStringArray, 
+    RPointerArray<HBufC>& aFilesArray );
+                  
+LOCAL_C TBool SearchValidCertificateL( 
+    RSisRegistryEntry& aEntry, 
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCertCapaArray,
+    TUint64 aCapability );
+
+LOCAL_C TCapability GetCapability( TUint64 aCapability );
+    
+LOCAL_C TBool VerifyHashL(    
+    RSisRegistryEntry& aEntry, 
+    RPointerArray<HBufC>& aPathArray,
+    RPointerArray<HBufC8>& aHashArray );
+
+LOCAL_C TBool CompareToRegisteryHashL( 
+    RSisRegistryEntry& aEntry, 
+    TDesC& aEntryFile, 
+    TDesC8& aHashBuffer ); 
+      
+LOCAL_C TBool CheckSerialNumberL( RFs& aFs, const TDesC& aFileName ); 
+
+LOCAL_C void CorruptFileL( RFs& aFs, const TDesC& aFileName );                              
+
+LOCAL_C TBool CheckCapabilityWordAndCalcHashL( 
+    RFs& aFs, 
+    TBool aCheckCapa,
+    TUint64* aCapaVector,    
+    RPointerArray<HBufC>& aSourceArray,
+    RPointerArray<HBufC>& aFilesArray,
+    RPointerArray<HBufC8>& aHashArray,
+    RArray<TUint64>& aCapaArray );
+/*
+#ifdef __BTIC_BINARIES_CHECK_ENABLED
+
+LOCAL_C void RenameFileL( RFs& aFs, const TDesC& aFileName );
+
+LOCAL_C void UniteCertArraysL(     
+    RPointerArray<CX509Certificate>& aTargetCertArray,
+    RPointerArray<CX509Certificate>& aSourceCertArray );
+
+LOCAL_C void UniteCapaArraysL( 
+    RPointerArray<TCapabilitySet>& aTargetCapaArray,
+    RPointerArray<TCapabilitySet>& aSourceCapaArray );     
+        
+LOCAL_C void CheckBinariesL( 
+    RFs& aFs, 
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCertCapaArray );  
+ 
+LOCAL_C void FindFilesL( 
+    RFs& aFs, 
+    const TDesC& aPath,
+    const TDesC& aSearchString,    
+    RPointerArray<HBufC>& aFoundFilesArray );
+                 
+LOCAL_C TBool FindMatchFromSisPackageL( 
+    RFs& aFs,    
+    RPointerArray<HBufC>& aFilesArray, 
+    RPointerArray<HBufC8>& aHashArray, 
+    RArray<TUint64>& aCapaArray,
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCertCapaArray ); 
+
+#endif //__BTIC_BINARIES_CHECK_ENABLED
+*/     
+
+// FORWARD DECLARATIONS
+
+// LOCAL FUNCTION PROTOTYPES
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// E32Main()
+// Main for ARM environment.
+// Returns: KErrNone if successful  
+//          Othervice some system error code.
+// -----------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+    {
+    BTIC_TRACE_PRINT_ALLOC_CELLS("[BOOT INTECRITY CHECK] Main cell count = %d");  
+    TInt err = KErrNone;
+
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+
+    if ( !cleanup )
+        {
+        return KErrNoMemory;
+        }
+
+    TRAP( err, ThreadStartL() );
+
+    BTIC_TRACE_PRINT_NUM("[BOOT INTECRITY CHECK] Main TRAP error = %d", err);
+    
+    delete cleanup;
+
+    BTIC_TRACE_PRINT_ALLOC_CELLS("[BOOT INTECRITY CHECK] Main cell count = %d"); 
+    return err;
+    }
+
+
+// -----------------------------------------------------------------------------
+// ThreadStart()
+// 
+// This is programs main.
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TInt ThreadStartL()
+    {                                                       
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] START PROGRAM");    
+    __UHEAP_MARK;
+    BTIC_TRACE_PRINT_ALLOC_CELLS("Start Cell count = %d");  
+   
+    BTIC_TRACE_PRINT("Rename thread to BootIntegrityCheck");
+    // Rename thread as SecEnvInit.
+    User::RenameThread( KBTICThreadName );  
+      
+    // This should be read with feature manager etc. but since we 
+    // only support certificate database checking this is ok.
+    TBool binariesCheckEnbled = EFalse;   
+    
+    TBool certFileFound = EFalse; 
+    TInt err = KErrNone; 
+    TInt pushToStack = 0; 
+        
+    // GET BOOT REASON   
+    
+    BTIC_TRACE_PRINT("Get boot reason");     
+    TBool bootReasonFormat = EFalse;   
+    RIntegrityCheckClient bticServer;
+        
+    err = bticServer.Connect();    
+    BTIC_TRACE_PRINT_NUM("BTIC Server connect error = %d", err );
+    
+    if ( err == KErrNone )
+        {            
+        CleanupClosePushL( bticServer );                                
+        TInt bootReason = KErrNone;     
+                                               
+        // Get boot reason from btic server.
+        err = bticServer.GetSWBootReason( bootReason );                          
+        BTIC_TRACE_PRINT_NUM("GetSWBootReason error = %d", err );
+                            
+        if ( err == KErrNone )
+            {                                  
+            BTIC_TRACE_PRINT_NUM("Boot Reason number = %d", bootReason );
+            
+            if ( bootReason == EBTICRestoreFactorySetDeep )
+                {                                                                
+                BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] Boot reason: FORMAT");  
+                bootReasonFormat = ETrue;
+                }                                   
+            }             
+        CleanupStack::PopAndDestroy(); //bticServer                                  
+        }
+               
+    // OPEN FILE SERVER    
+    BTIC_TRACE_PRINT("Open FS session");
+
+    RFs fs;
+    // Connect to file server.
+    User::LeaveIfError( fs.Connect() );
+    CleanupClosePushL( fs );
+    pushToStack++;
+
+    // Find SWICertStore.dat in C drive.
+    TFindFile find( fs ); 
+    TBool certStoreOk = EFalse;  
+    CDir* entryList = NULL;   
+    HBufC* certStoreFilePath = NULL; 
+    HBufC* certStoreFileName = NULL; 
+           
+    BTIC_TRACE_PRINT("Find C SWI certificate store");    
+    
+    // Get all files from folder. 
+    if ( KErrNone == fs.GetDir ( 
+        KBTICCertStoreCPath, 
+        KEntryAttNormal,
+        ESortByName|EDirsFirst, 
+        entryList ) )
+        {     
+        if ( entryList )
+            {
+            CleanupStack::PushL( entryList );
+
+            TInt count = entryList->Count(); 
+
+            // If file is found.            
+            if ( count )
+                {                                              
+                BTIC_TRACE_PRINT("Store file found");
+                
+                // Get the highest version certstore file
+                const TEntry& entry = (*entryList)[count - 1];                                
+                
+                // Make temp buffer for file path. 
+                TBuf<KMaxFileName> path( KBTICCertStoreCPath );
+                path.Append( entry.iName );
+                
+                certStoreFilePath = path.AllocLC(); 
+                pushToStack++;                              
+                                                   
+                certStoreFileName = entry.iName.AllocLC(); 
+                pushToStack++;                                                              
+                                                
+                certFileFound = ETrue; 
+                
+                CleanupStack::Pop(); //certStoreFilePath
+                CleanupStack::Pop(); //certStoreFileName
+                CleanupStack::PopAndDestroy( 1, entryList ); 
+                CleanupStack::PushL( certStoreFilePath );                         
+                CleanupStack::PushL( certStoreFileName );                           
+                }
+            else
+                {
+                BTIC_TRACE_PRINT("No store file present");
+                CleanupStack::PopAndDestroy( 1, entryList ); 
+                }                                                
+            }
+        }
+    
+    BTIC_TRACE_PRINT("Check boot reason");  
+    // Check boot reason. If certificate store file is found start active file
+    // observer which checks that file is deleted. If not continue checking.        
+    if ( bootReasonFormat )
+        {
+        BTIC_TRACE_PRINT("Boot reason format");    
+        if( certFileFound )
+            {
+            BTIC_TRACE_PRINT("Start active file observer"); 
+            TInt status = KErrUnknown;
+                        
+            // Create active scheduler.
+            CActiveScheduler* threadScheduler = new CActiveScheduler;
+            CleanupStack::PushL( threadScheduler );
+            pushToStack++;
+
+            CActiveScheduler::Install( threadScheduler );
+
+            // Create file observer object.
+            CActiveFileObserver* observer =
+                CActiveFileObserver::NewL( fs, *certStoreFilePath, status );
+            CleanupStack::PushL( observer );
+            pushToStack++;
+             
+            BTIC_TRACE_PRINT("Start active scheduler");            
+            CActiveScheduler::Start();            
+            
+            BTIC_TRACE_PRINT_NUM("File observer status = %d", status );
+            
+            if ( status == KErrNone )
+                {
+                // Boot reason is fromat and certificate file is deleted.
+                // Stop checking and exit.                    
+                BTIC_TRACE_PRINT("Stop checking and exit");
+                certFileFound = EFalse;   
+                binariesCheckEnbled = EFalse;                 
+                }
+            }
+        else
+            {  
+            // Boot reason is fromat and no certificate file is found.
+            // Stop checking and exit.      
+            BTIC_TRACE_PRINT("Stop checking and exit");
+            certFileFound = EFalse;   
+            binariesCheckEnbled = EFalse;        
+            }    
+        }
+               
+ 
+    BTIC_TRACE_PRINT_NUM("Updated store read enabled(1) = %d",certFileFound);
+    BTIC_TRACE_PRINT_NUM("Binaries check enabled(0) = %d",binariesCheckEnbled);           
+   
+    // Create pointer array for root certificates.  
+    RPointerArray<CX509Certificate> x509CertArray;     
+    RPointerArray<TCapabilitySet> certCapaArray;
+    TInt fileError = 0;
+     
+    // Read root certificates if needed.      
+    if ( certFileFound || binariesCheckEnbled )
+        {                                    
+        // Get root certificates to x509 format.  
+        fileError = 
+          ReadCertificatesL( 
+              fs, 
+              KBTICCertStoreZ, 
+              x509CertArray, 
+              certCapaArray );
+
+        // Can't read root certificates or array is empty. 
+        // Let's return and try this in next boot.    
+        if ( fileError || x509CertArray.Count() == 0 )
+            {
+            BTIC_TRACE_PRINT("ERROR Can't read root certificates ! ! !");
+            CleanupStack::PopAndDestroy( pushToStack );
+            x509CertArray.ResetAndDestroy();                   
+            certCapaArray.ResetAndDestroy();
+            User::Leave( fileError );
+            }               
+        }
+              
+    // Create temporary pointer array for C-drive updated certificates. 
+    RPointerArray<CX509Certificate> tempCertArray;  
+    RPointerArray<TCapabilitySet> tempCapaArray;    
+             
+    // If candidate for certstore file is found read it and validate file.
+    if ( certFileFound )
+        {        
+        BTIC_TRACE_PRINT("Read certificates from C");       
+                                        
+        // Read certificates from C drive and set them to x509 format         
+        TRAP( err ,
+            fileError = ReadCertificatesL( 
+                fs, 
+                *certStoreFilePath, 
+                tempCertArray,                                          
+                tempCapaArray ) );
+                
+        BTIC_TRACE_PRINT_NUM("C read file error (0) = %d", fileError );
+        BTIC_TRACE_PRINT_NUM("C read Trap err (0) = %d", err );                
+               
+        // If ReadCertificatesL function leaves, we assume that something is
+        // tampered and the file is corrupted. However if function returns
+        // an error code, file is not corrupted.           
+        if ( err )
+            {
+            fileError = err;
+            TRAP_IGNORE( CorruptFileL( fs, *certStoreFilePath ) );
+            }                     
+                
+        // If there is no error when constructing a permanent file store object
+        // let's continue.                      
+        if ( fileError == KErrNone )
+            {
+            BTIC_TRACE_PRINT("Validate cert store");
+             
+            // Validate the certstore in C if certs are found. 
+            TRAP( err, 
+                  certStoreOk = ValidateCertStoreL( 
+                        fs, 
+                        x509CertArray, 
+                        certCapaArray, 
+                        *certStoreFileName,
+                        *certStoreFilePath ) );
+          
+            BTIC_TRACE_PRINT_NUM("Trap err (0) = %d", err );
+            BTIC_TRACE_PRINT_NUM("Cert storage valid (1) = %d", certStoreOk ); 
+         
+            // If validation fails or function leaves we will assume
+            // that database is tempered and it will be corrupted. 
+            // In practice this mean that all binaries signed with 
+            // certificates in C database will be corrupted.                                                                            
+            if ( ! certStoreOk || err != KErrNone )
+                {                                                    
+                TRAP_IGNORE( CorruptFileL( fs, *certStoreFilePath ) );
+                } 
+                
+            BTIC_TRACE_PRINT("\nStore validation complete"); 
+            }                                                
+        }  
+/*                               
+#ifdef __BTIC_BINARIES_CHECK_ENABLED
+          
+    // If found cert store is valid unite arrays.
+    if ( certStoreOk )
+        {
+        UniteCertArraysL( x509CertArray, tempCertArray ); 
+        // Reset tempCertArray because x509CertArray owns entrys now.
+        tempCertArray.Reset();
+         
+        UniteCapaArraysL( certCapaArray, tempCapaArray );
+        // Reset tempCapaArray because certCapaArray owns entrys now.               
+        tempCapaArray.Reset();
+        }
+
+    // Check that certificates are found before checking binaries.
+    if ( x509CertArray.Count() )
+        {
+        // Check that cert array and capa array has same amount of entrys.
+        // If amount is diffrent do not check binaries. Something is wrong.
+        if ( x509CertArray.Count() == certCapaArray.Count() )
+            {
+            // Check that binaries found in C: are istalled from a valid SIS 
+            // pagaces and binary's hash is valid.        
+            CheckBinariesL( fs, x509CertArray, certCapaArray );              
+            
+            BTIC_TRACE_PRINT("\nBinaries check complete\n");
+            }                     
+        }
+                                  
+#endif //__BTIC_BINARIES_CHECK_ENABLED
+*/      
+                            
+    BTIC_TRACE_PRINT("\nProgram complete\n");
+    // DELETE ALL ARRAYS AND ARRAY CONTENT    
+    x509CertArray.ResetAndDestroy();                
+    tempCertArray.ResetAndDestroy();
+    certCapaArray.ResetAndDestroy();
+    tempCapaArray.ResetAndDestroy();  
+  
+    CleanupStack::PopAndDestroy( pushToStack ); //fs, buffers
+      
+    BTIC_TRACE_PRINT("UHEAP MARK END");
+    __UHEAP_MARKEND;
+    BTIC_TRACE_PRINT_ALLOC_CELLS("End Cell count = %d");
+     
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] PROGRAM END");   
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// ReadCertificatesL
+// 
+// This function reads certificates from certificate storage and adds them in to 
+// given cert array if certificate can grant TCB or/and DRM. Also certificates 
+// capability set is added to given capability array. 
+// Given path must be valid one, othervice function returns error code.
+//
+// Returns: KErrNone if successful 
+//          Othervice some system-wide error code.
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TInt ReadCertificatesL( 
+    RFs& aFs,                                        // File server handle 
+    const TDesC& aPath,                              // Path to storage file. 
+    RPointerArray<CX509Certificate>& aX509CertArray, // Cert array.
+    RPointerArray<TCapabilitySet>& aCapabilityArray )// Capability array.
+    {            
+    TInt err = KErrNone;      
+    RFile file;
+    
+    err = file.Open( aFs, aPath, EFileRead );
+    
+    if ( err == KErrNone )
+        {                             
+        CleanupClosePushL( file );
+      
+        CPermanentFileStore* certStore = NULL;
+      
+        // Trap FromL if file is not in correct form it may leave.
+        TRAP( err, certStore = CPermanentFileStore::FromL( file ) );    
+          
+        if ( certStore && err == KErrNone )
+            {
+            CleanupStack::Pop( &file ); // Now owned by store.
+            CleanupStack::PushL( certStore );
+
+            // Read id of cert list stream
+            TStreamId streamId;
+            RStoreReadStream stream;  
+            stream.OpenLC( *certStore, certStore->Root() );     
+            stream >> streamId; 
+            CleanupStack::PopAndDestroy( &stream ); 
+
+            // Read the certificate list
+            RStoreReadStream certEntryStream;
+            certEntryStream.OpenLC( *certStore, streamId );
+
+            // Count entrys from stream.
+            TInt count = certEntryStream.ReadInt32L();    
+            BTIC_TRACE_PRINT_NUM("CertEntryStream count = %d", count );
+                       
+            HBufC8* certDataBuf = NULL;
+                               
+            for ( TInt index = 0 ; index < count ; index++ )
+                {
+                // Read data from stream.
+                CRootCertificateEntry* entry = 
+                    CRootCertificateEntry::NewLC( certEntryStream );
+                        
+                // Get certificate's capabilties from entry.
+                TCapabilitySet* capaSet = 
+                new( ELeave ) TCapabilitySet( entry->Capabilities() );        
+                CleanupStack::PushL( capaSet );
+              
+                // Check that certificate can grant TCB or DRM capabiltiy.                                 
+                if ( capaSet->HasCapability( GetCapability( KBTIC_TCB ) ) || 
+                    capaSet->HasCapability( GetCapability( KBTIC_DRM ) ) )
+                    {         
+                    // Append certificates capability set to array.         
+                    User::LeaveIfError( aCapabilityArray.Append( capaSet ) );
+
+                    CleanupStack::Pop( capaSet );                 
+                        
+                    // Open certificate data stream. This is actual x509 certificate.    
+                    RStoreReadStream stream;                  
+                    stream.OpenLC( *certStore, entry->DataStreamId() );
+                                                      
+                    // Get x509 size.
+                    TInt size = entry->Size();                                  
+
+                    // Since we do not have so meny certs in device let's make alloc
+                    // inside of the loop.                 
+                    certDataBuf = HBufC8::NewMaxLC( size );
+
+                    TPtr8 dataBufPtr = certDataBuf->Des();                       
+                                
+                    // Read x509 binary data to buffer.
+                    stream.ReadL( dataBufPtr, size );                   
+
+                    // Create x509 certificate object from binary data.   
+                    CX509Certificate* x509Cert = 
+                        CX509Certificate::NewLC( *certDataBuf ); 
+
+                    // Append x509 certificate object to pointer array. 
+                    User::LeaveIfError( aX509CertArray.Append( x509Cert ) );
+                                                  
+                    CleanupStack::Pop( x509Cert );
+                    x509Cert = NULL;
+                    CleanupStack::PopAndDestroy( certDataBuf );
+                    certDataBuf = NULL; 
+                    CleanupStack::PopAndDestroy( &stream );                     
+                    }
+                else
+                    {
+                    // Delete capaSet if certificate has not TCB or DRM.
+                    CleanupStack::PopAndDestroy( capaSet );
+                    capaSet = NULL;
+                    }    
+                        
+                CleanupStack::PopAndDestroy( entry );
+                entry = NULL;       
+                }   
+              
+            CleanupStack::PopAndDestroy( 2 );//certStore, certEntryStream               
+            }
+        else
+            {
+            // Clean up file is FromL leaves.
+            CleanupStack::PopAndDestroy( &file );
+            BTIC_TRACE_PRINT("ERROR CPermanentFileStore - Can not read certs.");
+            }           
+        }
+      
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ReadCertificatesL <---"); 
+  
+    return err;      
+    }                
+
+
+// -----------------------------------------------------------------------------
+// ValidateCertStoreL()
+//
+// This function checks that updated SWI certstore in C drive has been installed 
+// from valid SIS pacage. 
+// SIS pacage must have valid certificate and exe with a TCB capabilities. 
+//
+// NOTE this function assumes that Certprovisioner tool has imei.txt file. 
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TBool ValidateCertStoreL( 
+    RFs& aFs,                                       // File server handle
+    RPointerArray<CX509Certificate>& aX509CertArray,// Certificate array
+    RPointerArray<TCapabilitySet>& aCapaArray,      // Capability array
+    const TDesC& aCertStoreFileName,
+    const TDesC& aCertStoreFilePath  )     
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateCertStoreL v2->");
+    __UHEAP_MARK;
+                          
+    TBool storeOK = EFalse;                  
+    
+    RPointerArray<HBufC> updaterExePaths;
+         
+    Swi::RSisRegistrySession sisRegSession;  
+
+    // Leave if we can not connect to sis register. Othervice we have a risk 
+    // that valid files will be renamed if updated certstore is left out.             
+    User::LeaveIfError( sisRegSession.Connect() );
+        
+    CleanupClosePushL( sisRegSession );
+    
+    RPointerArray<CSisRegistryPackage> sisPackages;
+                
+    // Find installed packages.
+    sisRegSession.InstalledPackagesL( sisPackages );            
+            
+    Swi::RSisRegistryEntry entry;        
+        
+    TInt packageUID;   
+        
+    BTIC_TRACE_PRINT("Find matching UID");
+    
+    // If CertProvisioner tool has install updatedswicertstore file.
+    if ( aCertStoreFileName.Compare( KBTICCertStoreCName ) == KErrNone )
+        {
+        BTIC_TRACE_PRINT("UID -> KBTICCertProvUID");
+        packageUID = KBTICCertProvUID;
+        }
+    else
+        {
+        BTIC_TRACE_PRINT("UID -> KBTICSymbianSWIUpdaterUID");
+        packageUID = KBTICSymbianSWIUpdaterUID;
+        }
+                
+    TBool entryOpen = EFalse;       
+    
+    // Search correct sis pagace and open entry to it.
+    for( TInt index = 0; index < sisPackages.Count(); index++)
+        {  
+        BTIC_TRACE_PRINT_NUM("Search entry from sis reg. index = %d", index );
+             
+        if ( sisPackages[index]->Uid() == TUid::Uid( packageUID ) )
+            { 
+            BTIC_TRACE_PRINT("Open entry");
+                                                                    
+            User::LeaveIfError( entry.Open( 
+                sisRegSession, TUid::Uid( packageUID ) ) );
+ 
+            CleanupClosePushL( entry );
+
+            entryOpen = ETrue;                                                          
+            break;                                       
+            }             
+        } 
+                        
+    // Validate cert storage.     
+    if ( entryOpen )
+        {        
+        TBool controllerOk = EFalse;   
+
+#ifdef __BTIC_VERIFY_CONTROLLER        
+        // Check that sis controller is valid.       
+        controllerOk = entry.VerifyControllerSignatureL( aX509CertArray );
+                                     
+        BTIC_TRACE_PRINT("Controller verify ENABLED"); 
+        BTIC_TRACE_PRINT_NUM("Controller verify result (1) = %d", controllerOk );                                             
+#else   
+        // If controller verify is disabled set boolen to true.     
+        controllerOk = ETrue;          
+        BTIC_TRACE_PRINT("Controller verify DISABLED" );      
+#endif
+    
+        if ( controllerOk )
+            {            
+            if ( packageUID == KBTICCertProvUID )
+                {                   
+                storeOK = ValidateProvisonerCertStoreL(
+                    aFs,                                       
+                    aX509CertArray,
+                    aCapaArray,      
+                    aCertStoreFileName,
+                    aCertStoreFilePath,
+                    entry );
+                }
+            else
+                {
+                storeOK = ValidateSymbianCertStoreL(
+                    aFs,                                       
+                    aX509CertArray,
+                    aCapaArray,                                      
+                    entry,
+                    updaterExePaths );
+                }                
+            }                                                        
+        }                       
+                                                   
+    // Cleanup array.           
+    sisPackages.ResetAndDestroy();                                           
+
+    if ( entryOpen )
+        {        
+        CleanupStack::PopAndDestroy(); //RSisRegistryEntry               
+        }
+                       
+    CleanupStack::PopAndDestroy(); //RSisRegistrySession    
+    
+    // Ok Symbian store is valid, let's run Symbian updater exe.
+    // NOTE SisRegistry server etc. has file handle open, so we should
+    // close SisRegistryEntry before running updater. 
+    if ( storeOK && packageUID == KBTICSymbianSWIUpdaterUID )
+        {              
+        storeOK = RunUpdaterL( aFs, updaterExePaths );                        
+        }
+        
+    updaterExePaths.ResetAndDestroy();    
+                  
+    BTIC_TRACE_PRINT("UHEAP MARK END");     
+    __UHEAP_MARKEND;   
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateCertStoreL v2 <-");        
+    
+    return storeOK;        
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// ValidateProvisonerCertStoreL()
+//
+// 
+//
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TBool ValidateProvisonerCertStoreL(
+    RFs& aFs,                                       // File server handle
+    RPointerArray<CX509Certificate>& aX509CertArray,// Certificate array
+    RPointerArray<TCapabilitySet>& aCapaArray,      // Capability array
+    const TDesC& aCertStoreFileName,
+    const TDesC& aCertStoreFilePath,
+    RSisRegistryEntry& aEntry )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateProvisonerStoreL --->");
+    __UHEAP_MARK;
+        
+    TBool retOK = EFalse;                      
+    // installedFiles array owns entry's files.
+    RPointerArray<HBufC> installedFilesArray;
+    RPointerArray<HBufC> foundFilesArray;  
+    RPointerArray<HBufC> fileArray;  // Files that need to be cheked.
+    RPointerArray<HBufC8> hashArray; // Hash for each fileArray's file.
+    RArray<TUint64> capaArray;              
+    RPointerArray<HBufC> stringArray;
+    HBufC* string = NULL;
+    
+    TUint64* capaVector = new( ELeave ) TUint64[KBTICCapaCount];
+    CleanupArrayDeletePushL( capaVector );
+    capaVector[0] = KBTIC_TCB;
+                                                                                    
+    // Get all installed files from this sis register entry 
+    // to installedFilesArray.                                                            
+    aEntry.FilesL( installedFilesArray );  
+                                                                  
+    // Search all exes from array.   
+    if ( installedFilesArray.Count() > 0 )
+        { 
+        string = KBTICExtensionExe().AllocLC();
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop();
+        
+        retOK = SearchFilesFromArrayL( 
+            installedFilesArray,
+            KBTICDriveCWildcard, 
+            stringArray, 
+            foundFilesArray );                                  
+        } 
+                                                                                                               
+    // Find a exe that has TCB capapility and calculate hash over the file. 
+    if ( retOK )                       
+        {                                     
+        retOK = CheckCapabilityWordAndCalcHashL( 
+            aFs, 
+            ETrue, 
+            capaVector, 
+            foundFilesArray,
+            fileArray,
+            hashArray,
+            capaArray );                        
+        }                           
+                                                  
+    // Validate certificate from this entry and check that 
+    // certificate can grant the capability which is neede for the exe (TCB).     
+    if ( retOK )
+        {                                   
+        retOK = SearchValidCertificateL( 
+            aEntry, 
+            aX509CertArray, 
+            aCapaArray, 
+            KBTIC_TCB );     
+        }         
+                 
+    // Calculate hash over each exe file found in this entry.     
+    // Let's be confident that server is not tempered.    
+    if ( retOK )
+        {
+        retOK = EFalse;
+        
+        // Ok so now we should have one TCB file in fileArray and 2 other 
+        // files in foundFilesArray. We do not need to calculate hash over 
+        // TCB files again, so let's remove TCB files from array.              
+        TInt countExe = foundFilesArray.Count();        
+        TInt countTCB =  fileArray.Count();        
+        TBool removeFile = EFalse;                
+        
+        for ( TInt i = countExe-1; i >= 0 ; i-- )
+            {
+            removeFile = EFalse;            
+            
+            for ( TInt k = countTCB-1; k >= 0; k-- )
+                {  
+                // If fileArray has this path remove it.                               
+                if ( (fileArray[k]->Compare( *foundFilesArray[i] )) 
+                    == KErrNone )
+                    {
+                    removeFile = ETrue;                 
+                    }
+                }
+            
+            if ( removeFile )
+                {                
+                foundFilesArray.Remove( i );                      
+                }                          
+            }
+            
+        // Compress array so we don not have null pointers on it.        
+        foundFilesArray.Compress(); 
+        
+        // If all files are removed something is wrong. Return False.
+        if ( foundFilesArray.Count() )
+            {
+            // Ok let's calculate hashes for the other exes.
+            retOK = CheckCapabilityWordAndCalcHashL( 
+                aFs, 
+                EFalse, 
+                0, 
+                foundFilesArray,
+                fileArray,
+                hashArray,
+                capaArray );                             
+            }                   
+        }          
+           
+    // Remove previous strings from array.
+    stringArray.ResetAndDestroy();
+    // Remove pointers from array. Let's not calc. hash again.
+    foundFilesArray.Reset();                                    
+     
+    // Search imei.txt file from array and check that device's serial number
+    // is found in the file. NOTE file name must be imei.txt. 
+    if ( retOK )
+        {          
+        retOK = EFalse;
+                                 
+        string = KBTICSerialNumberFile().AllocLC();
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop();
+               
+        TBool foundFile = SearchFilesFromArrayL( 
+            installedFilesArray,
+            KBTICDriveCWildcard, 
+            stringArray, 
+            foundFilesArray );               
+                                   
+        if ( foundFile && foundFilesArray.Count() )
+            {
+            retOK = CheckSerialNumberL( aFs, *foundFilesArray[0] ); 
+            }                            
+        }        
+    
+    // Calculate hash over each file (*.dat and imei.txt) and check that 
+    // sisregistery has same hash (*.exe,*.dat,imei.txt).             
+    if ( retOK )
+        {        
+        retOK = EFalse;
+                        
+        // Note that certstore path from sis reg. points to private 
+        // directory not file's current logation. So we have to switch 
+        // file paths to get correct hash.
+
+        // Remove previous strings from array.
+        stringArray.ResetAndDestroy();
+                        
+        string = HBufC::NewLC( 
+            aCertStoreFileName.Length() + 
+            sizeof( KBTICStarWildcard ) );            
+        TPtr stringPtr = string->Des();  
+        
+        // Append certstorage name and wildcard (*\\) to string for search. 
+        // String should be = "*\\filename.dat"  Let's add "\\" to string
+        // so search do not accept eg. Öfilename.dat etc.
+        stringPtr.Copy( KBTICStarWildcard );     
+        stringPtr.Append( aCertStoreFileName );
+         
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop(); //String                
+                                        
+        // Search correct certstorage file from installedFilesArray.(sis reg.)                           
+        TBool foundFile = SearchFilesFromArrayL( 
+            installedFilesArray,
+            KBTICDriveCWildcard, 
+            stringArray, 
+            foundFilesArray );                   
+                
+        if ( foundFile )
+            { 
+            BTIC_TRACE_PRINT("Correct CertStore file found");
+                                   
+            // Get original certstorage path from array. 
+            HBufC* sisRegPath = foundFilesArray[foundFilesArray.Count() - 1];
+                
+            // Remove original path from array.     
+            foundFilesArray.Remove( foundFilesArray.Count() - 1 );
+            CleanupStack::PushL( sisRegPath ); //sisRegPath
+            
+            // Get current certstorage path.
+            HBufC* currentPath = aCertStoreFilePath.AllocLC();
+
+            // Set current path to array. So now we get correct hash. 
+            foundFilesArray.Append( currentPath );
+            CleanupStack::Pop(); //currentPath
+
+            BTIC_TRACE_PRINT("Calculate HASH for files");
+
+            // Calculate hash over files in foundFilesArray and add result to
+            // filesArray and hashArray                                 
+            CheckCapabilityWordAndCalcHashL( 
+                aFs, 
+                EFalse, 
+                0, 
+                foundFilesArray,
+                fileArray,
+                hashArray,
+                capaArray );   
+                
+             // Ok now we have correct hash but certstore path is not 
+             // correct for sis register. So we have to copy original 
+             // certstorage file path from sis reg. to filesArray.
+             
+             // Remove currentPath entry from array.             
+             fileArray.Remove( fileArray.Count() - 1 );
+             
+             // Delete currentPath buffer. We need to delete buffer because 
+             // we call only reset for foundFilesArray. Reset do not delete 
+             // buffer.  
+             delete currentPath;
+             
+             // Append orginal path from sis reg. for hash checking. 
+             fileArray.Append( sisRegPath ); 
+             CleanupStack::Pop(); //sisRegPath                                                                
+                                         
+            // Check that sis registery entry has same hash as we have.                                                                                                                                              
+            retOK = VerifyHashL( aEntry, fileArray, hashArray );   
+                         
+            }                                                                       
+        }
+    
+    CleanupStack::PopAndDestroy(); //capaVector   
+                                              
+    // Reset only. InstalledFiles array owns buffers.
+    foundFilesArray.Reset();
+    fileArray.Reset(); 
+    hashArray.ResetAndDestroy();                                    
+    installedFilesArray.ResetAndDestroy();         
+    stringArray.ResetAndDestroy(); 
+    capaArray.Close();                 
+    
+    BTIC_TRACE_PRINT("UHEAP MARK END");     
+    __UHEAP_MARKEND;
+    
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateProvisonerStoreL <---");
+    
+    return retOK;    
+    }
+  
+            
+// -----------------------------------------------------------------------------
+// ValidateSymbianCertStoreL()
+//
+// 
+//
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TBool ValidateSymbianCertStoreL(
+    RFs& aFs,                                       // File server handle
+    RPointerArray<CX509Certificate>& aX509CertArray,// Certificate array
+    RPointerArray<TCapabilitySet>& aCapaArray,      // Capability array        
+    RSisRegistryEntry& aEntry,
+    RPointerArray<HBufC>& aUpdaterExePaths )
+    {  
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateSymbianStoreL v2 --->");   
+      
+    TBool retOK  = EFalse;                       
+    // installedFiles array owns entry's files.
+    RPointerArray<HBufC> installedFilesArray;
+    RPointerArray<HBufC> foundFilesArray;  
+    RPointerArray<HBufC> fileArray;  // Files that need to be cheked.
+    RPointerArray<HBufC8> hashArray; // Hash for each fileArray's file.
+    RArray<TUint64> capaArray;              
+    RPointerArray<HBufC> stringArray;
+    HBufC* string = NULL;
+    
+    TUint64* capaVector = new( ELeave ) TUint64[KBTICCapaCount];
+    CleanupArrayDeletePushL( capaVector );
+    capaVector[0] = KBTIC_TCB;
+                                                                                   
+    // Get all installed files from this sis register entry 
+    // to installedFilesArray.                                                            
+    aEntry.FilesL( installedFilesArray );                                          
+                     
+    // Search all exes from array.   
+    if ( installedFilesArray.Count() > 0 )
+        { 
+        string = KBTICExtensionExe().AllocLC();
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop();
+        
+        retOK = SearchFilesFromArrayL( 
+            installedFilesArray,
+            KBTICDriveCWildcard, 
+            stringArray, 
+            foundFilesArray );                                  
+        } 
+                                                                                             
+    // Find a exe that has TCB capapility and calculate hash over the file. 
+    if ( retOK )                       
+        {                                     
+        retOK = CheckCapabilityWordAndCalcHashL( 
+            aFs, 
+            ETrue, 
+            capaVector, 
+            foundFilesArray,
+            fileArray,
+            hashArray,
+            capaArray );                        
+        }    
+                                                          
+    // Validate certificate from this entry and check that 
+    // certificate can grant the capability which is neede for the exe (TCB).     
+    if ( retOK )
+        {                                   
+        retOK = SearchValidCertificateL( 
+            aEntry, 
+            aX509CertArray, 
+            aCapaArray, 
+            KBTIC_TCB );     
+        } 
+    
+    // Check that sis registery has same hash as we have.              
+    if ( retOK )
+        {                                                  
+        retOK = VerifyHashL( aEntry, fileArray, hashArray );             
+        } 
+    
+    // Return exe's path to caller. NOTE Updater exe can not be executed
+    // before SisRegistryEntry is closed.    
+    if ( retOK )
+        {
+        // We will assume that updater has only one exe with TCB.
+        HBufC* path = fileArray[0]->AllocLC();          
+        // Append path to pointer array. 
+        User::LeaveIfError( aUpdaterExePaths.Append( path ) );         
+        CleanupStack::Pop(); //path          
+        }
+   
+    CleanupStack::PopAndDestroy(); //capaVector   
+                                              
+    // Reset only. InstalledFiles array owns buffers.
+    foundFilesArray.Reset();
+    fileArray.Reset(); 
+    hashArray.ResetAndDestroy();                                    
+    installedFilesArray.ResetAndDestroy();         
+    stringArray.ResetAndDestroy();  
+    capaArray.Close();              
+        
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ValidateSymbianStoreL v2 <---"); 
+                                     
+    return retOK;
+    }
+
+
+// -----------------------------------------------------------------------------
+// RunUpdaterL()
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+// 
+LOCAL_C TBool RunUpdaterL( RFs& aFs, RPointerArray<HBufC>& aUpdaterExePaths )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] RunUpdaterL ->");
+    // SIS register do not have hash values for storage file if it is provided 
+    // by Symbian SWI updater exe. We have to remove current storage file 
+    // and run exe again to get a verified swicertstorage in folder.
+            
+    TBool retOK = EFalse; 
+    
+    BTIC_TRACE_PRINT("Delete old store file(s)");          
+    // Delete all files from dat folder. If delete fails storage file is 
+    // corrupted.
+    // NOTE that SisRegistry Server has some closing time so we must try this 
+    // in loop.                
+    for ( TInt loop = 0; loop < KBTICTryToOpen; loop++ )
+        {                
+        if ( DeleteAllFilesL( aFs, KBTICCertStoreCPath ) )
+            {            
+            // We will assume that updater has only on exe with TCB.
+            HBufC* updaterExePath = aUpdaterExePaths[0];
+                                                           
+            RProcess process;
+            
+            BTIC_TRACE_PRINT("Run updater exe to get new store file"); 
+            
+            for ( TInt i = 0; i < KBTICTryToCreate; i++ )
+                {  
+                BTIC_TRACE_PRINT("Try to create Updater process");
+                              
+                if ( process.Create( *updaterExePath, KNullDesC ) == KErrNone )
+                    {
+                    // Run updater exe again.
+                    process.Resume(); 
+                    // Get rid of our handle. 
+                    process.Close();
+                                        
+                    retOK = ETrue;  
+
+                    BTIC_TRACE_PRINT("Updater process started OK"); 
+                    break;                                                 
+                    }                
+                }
+                                        
+            // Break the loop if delete is succesful.    
+            break;    			                                      
+            }
+        else
+            {
+            BTIC_TRACE_PRINT_NUM("Wait 0.5 sec. Attempt nr.%d", loop );
+            User::After( 500000 );
+            }                                                                   
+        }
+        
+    return retOK;                                                     
+    }
+
+// -----------------------------------------------------------------------------
+// DeleteAllFiles()
+//
+// Delete all files from given folder.
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+// 
+LOCAL_C TBool DeleteAllFilesL( RFs& aFs, const TDesC& aFolderPath )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] DeleteAllFilesL ");
+    
+    TBool folderEmpty = EFalse;                      
+    CDir* entryList = NULL; 
+    TBuf<KMaxFileName> path;        
+    
+    // Get all files from folder.    
+    if ( KErrNone == 
+            aFs.GetDir ( 
+                aFolderPath, 
+                KEntryAttNormal, 
+                ESortByName|EDirsFirst, 
+                entryList ) )
+        {
+        if ( entryList )
+            {
+            CleanupStack::PushL( entryList );
+            
+            TInt delCount = KErrNone;
+            TInt count = entryList->Count();            
+            
+            for ( TInt index = 0; index < count; index++ )
+                {
+                // Get file name.
+                const TEntry& entry = (*entryList)[index];
+                
+                // Set path to file. 
+                path.Copy( aFolderPath );
+                path.Append( entry.iName ); 
+                
+                // Remove Read Only attribute.
+                TInt err = aFs.SetAtt( path, 0, KEntryAttReadOnly );
+                BTIC_TRACE_PRINT_NUM("Remove Read Only attrib. = %d", err );                                 
+                       
+                if ( KErrNone == aFs.Delete( path ) )
+                    {                    
+                    delCount++;
+                    BTIC_TRACE_PRINT_NUM("Delete file with index = %d", index);
+                    }
+                }
+            
+            // If all files are removed.           
+            if ( delCount == count )
+                {
+                folderEmpty = ETrue; 
+                BTIC_TRACE_PRINT("All files removed");
+                }
+
+            CleanupStack::PopAndDestroy( 1, entryList );                             
+            }                                     
+        }
+                                    
+    return folderEmpty;
+    }
+
+
+// -----------------------------------------------------------------------------
+// SearchFilesFromArrayL
+// 
+// This function search file names containing given string from aSourceArray and 
+// add found file (path) to an aFilesArray. Search is limited to specified drive 
+// and path.
+// Note this function only adds source arrays pointers to files array. It dos not
+// create new heap descriptor.    
+// 
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+// 
+LOCAL_C TBool SearchFilesFromArrayL( 
+    RPointerArray<HBufC>& aSourceArray, // Array for searching.
+    const TDesC& aDriveAndPath,         // Accepted drive or/and path. 
+    RPointerArray<HBufC>& aStringArray, // String to be searched from path.
+    RPointerArray<HBufC>& aFilesArray ) // Result array.
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] SearchFilesFromArrayL --->");
+
+    TBool retVal = EFalse; 
+                
+    TInt count = aSourceArray.Count();
+    TInt stringCount = aStringArray.Count();
+    
+    // This loop gos through all paths from aSourceArray.                                 
+    for ( TInt index = 0; index < count; index++ )
+        {                
+        HBufC* filePath = aSourceArray[index];
+        
+        // Convert descriptor to lower case so we don't get problems with 
+        // Match or Compare functions. 
+        TPtr filePathPtr = filePath->Des();
+        filePathPtr.LowerCase(); 
+        
+        // Check that file is in correct directory.
+        TInt offsetA = filePath->Match( aDriveAndPath );
+        
+        if ( offsetA >= 0 )
+            {                                                       
+            // This loop gos through all strings what we are looking for.
+            for ( TInt indexB = 0; indexB < stringCount; indexB++ )
+                {                                
+                // Search string from file path.            
+                TInt offset = filePath->Match( *aStringArray[indexB] );
+                                                    
+                if ( offset >= 0 )
+                    {            
+                    User::LeaveIfError( aFilesArray.Append( filePath ) );  
+                                        
+                    retVal = ETrue;                                    
+                    }
+                }  
+            }
+        }                              
+     
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] SearchFilesFromArrayL <---");         
+        
+    return retVal;                    
+    }
+
+
+// -----------------------------------------------------------------------------
+// SearchValidCertificateL
+// 
+// This function validates entry's certificate against to certificate found in 
+// given array. It check also that certificate has rigth to grant given 
+// capability. 
+//
+// Note This function only validates first chain.    
+// 
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//              
+LOCAL_C TBool SearchValidCertificateL( 
+    RSisRegistryEntry& aEntry,                      // SIS Registery entry
+    RPointerArray<CX509Certificate>& aX509CertArray,// Array for certificates
+    RPointerArray<TCapabilitySet>& aCertCapaArray,  // Array for certs capability
+    TUint64 aCapability )                           // Needed capabiltiy
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] SearchValidCertificate v2.1 --->");      
+
+    RPointerArray<HBufC8> binaryCertChainArray;
+    // Get certificates in binary format.
+    aEntry.CertificateChainsL( binaryCertChainArray );
+                            
+    TInt chainCount = binaryCertChainArray.Count();
+    BTIC_TRACE_PRINT_NUM("Entry chain count (1) = %d", chainCount );
+        
+    TBool retVal = EFalse;                                                                  
+
+    RPointerArray<CX509Certificate> chainCertArray;
+
+    // Check all entry's chains    
+    for ( TInt chain = 0; chain < chainCount; chain++ )
+        {  
+        BTIC_TRACE_PRINT_NUM("Check chain nr = %d", chain);
+                                   
+        TPtr8 chainData = binaryCertChainArray[chain]->Des();
+
+        TInt pos = 0;
+        TInt end = chainData.Length();                                                    
+
+        // Get all certificates from chain.
+        while ( pos < end )
+            {                                   
+            CX509Certificate* decoded = 
+                CX509Certificate::NewLC( chainData, pos ); 
+                                    
+            // Add x509 certificate to pointter array. 
+            User::LeaveIfError( chainCertArray.Append( decoded ) );  
+                                                                     
+            CleanupStack::Pop( decoded );
+            }
+                       
+        TInt chainCertCount = chainCertArray.Count();    
+        BTIC_TRACE_PRINT_NUM("Chain's certificate count = %d", chainCertCount);
+
+        // Search certificate issued to root and verify signature against the root.
+        if ( chainCertCount > 0 )
+            {        
+            BTIC_TRACE_PRINT("Validate last cert against root");                  
+            // Last cert in chain should be issued to root.
+            const CX509Certificate* x509LastChainCert = chainCertArray[chainCertCount-1];    
+                
+            TInt rootCertCount = aX509CertArray.Count();                   
+            BTIC_TRACE_PRINT_NUM("Root cert array count = %d", rootCertCount);
+            TBool rootFound = EFalse;
+            TInt rootIndex = 0;         
+                
+            // Find matching root certificate and validate certificates.
+            for ( rootIndex = 0; rootIndex < rootCertCount; rootIndex++ )
+                {
+                BTIC_TRACE_PRINT_NUM("Root cert index = %d", rootIndex );
+                            
+                const CX509Certificate* x509RootCert = aX509CertArray[rootIndex];
+
+                // Compare entry cert's issuer to root cert's subject. 
+                if ( x509LastChainCert->IssuerName().ExactMatchL(
+                     x509RootCert->SubjectName() ) )
+                    {
+                    BTIC_TRACE_PRINT("Root found for this chain"); 
+                    BTIC_TRACE_PRINT("Verify signature");                                
+                    
+                    // Verify signature 
+                    if ( x509LastChainCert->VerifySignatureL( 
+                        x509RootCert->PublicKey().KeyData() ) )
+                        {                                                    
+                        BTIC_TRACE_PRINT("Signature OK");                    
+                        rootFound = ETrue;
+                        break; // Break loop.
+                        }
+                    }
+                }            
+              
+              // If root is found we have correct chain.
+              if ( rootFound )
+                  {              
+                  // If Chain has more then one certificate, verify chain.
+                  if ( chainCertCount > 1 )
+                    {
+                    BTIC_TRACE_PRINT("Verify certificate chain"); 
+                    TBool chainOK = ETrue;
+                    TInt certindex;
+                    
+                    for ( certindex = 0; certindex < chainCertCount-1; certindex++ )
+                        {    
+                        BTIC_TRACE_PRINT_NUM("Cert index = %d", certindex);
+                        BTIC_TRACE_PRINT_NUM("Signature Cert index = %d", certindex+1);                    
+                                        
+                        const CX509Certificate* cert = chainCertArray[certindex];
+                        const CX509Certificate* signatureCert = 
+                            chainCertArray[certindex+1];                    
+                                            
+                        // Compare issuer name to subject name.
+                        if ( cert->IssuerName().ExactMatchL(
+                             signatureCert->SubjectName() ) )
+                            {  
+                            BTIC_TRACE_PRINT("Issuer match found."); 
+                            BTIC_TRACE_PRINT("Verify signature against next cert");                                               
+                            // Validate certificate 
+                            if ( ! cert->VerifySignatureL( 
+                                signatureCert->PublicKey().KeyData() ) )
+                                {                                                    
+                                // Chain is broken. Validation failed. 
+                                BTIC_TRACE_PRINT("ERROR Chain broken, validation failed"); 
+                                chainOK = EFalse;
+                                break;                       
+                                } 
+                            }
+                         else
+                            {
+                            // Issuer do not match. Validation failed.
+                            BTIC_TRACE_PRINT("ERROR Chain broken, issuer error"); 
+                            chainOK = EFalse;
+                            break;
+                            }   
+                        }
+                    
+                    if ( chainOK )
+                        {
+                        BTIC_TRACE_PRINT("Entry's chain valid"); 
+                        retVal = ETrue;
+                        }
+                                   
+                    }
+                  // Chain has only one certificate, root.  
+                  else
+                    {
+                    BTIC_TRACE_PRINT("Entry's chain has only one certificate"); 
+                    retVal = ETrue;
+                    }  
+                    
+                  }
+              else
+                {
+                BTIC_TRACE_PRINT("No root found for this chain");
+                retVal = EFalse; 
+                }
+
+            // Check that matching root certificate has same capablitiy 
+            // as aCapability parameter.
+            if ( aCapability && retVal )
+                {            
+                TCapabilitySet* rootCapaSet = aCertCapaArray[rootIndex];  
+                
+                retVal = rootCapaSet->HasCapability( GetCapability( aCapability ) );
+                }
+            
+            // Reset array for next chain.                                                             
+            chainCertArray.ResetAndDestroy();  
+            }
+        
+        // If this is a valid certificate chain, break to loop.   
+        if ( retVal )
+            {                
+            break;
+            }
+            
+        } // FOR LOOP
+                    
+    binaryCertChainArray.ResetAndDestroy();
+    
+                                        
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] SearchValidCertificate v2.1 <---");         
+    
+    return retVal;
+    }
+
+
+// -----------------------------------------------------------------------------
+// GetCapability
+// 
+// This function converts 64 bit capability integer to Symbian capability 
+// enumeration. 
+//
+// Returns: ECapabilityTCB if capabilty is TCB 
+//          ECapabilityDRM if capabilty is DRM
+//          ECapability_Denied if capability not found 
+// -----------------------------------------------------------------------------
+//  
+LOCAL_C TCapability GetCapability( TUint64 aCapability )
+    {            
+    if ( aCapability == KBTIC_TCB )
+        {        
+        return ECapabilityTCB;
+        }
+        
+    else if ( aCapability == KBTIC_DRM )    
+        {        
+        return ECapabilityDRM;
+        }
+        
+    else
+        {
+        BTIC_TRACE_PRINT("! ! ERROR GetCapability -> ECapability_Denied ! !");
+        return ECapability_Denied;
+        }            
+    }
+
+
+// -----------------------------------------------------------------------------
+// VerifyHashL
+// 
+// This function compare file's hash to hash found in SIS Register. 
+//
+// Returns: ETure if all compare operations was successful.  
+//          EFalse other vice
+// -----------------------------------------------------------------------------
+//  
+LOCAL_C TBool VerifyHashL(    
+    RSisRegistryEntry& aEntry, 
+    RPointerArray<HBufC>& aPathArray,
+    RPointerArray<HBufC8>& aHashArray )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] VerifyHashL --->");
+    __UHEAP_MARK;
+           
+    TBool retVal = EFalse; 
+    TInt hashOk = 0;                        
+    TInt count = aPathArray.Count();                    
+    
+    for ( TInt index = 0; index < count; index++ )
+        {        
+        // Take first file        
+        HBufC* path = aPathArray[index];
+        HBufC8* hash = aHashArray[index];
+                                            
+        if ( CompareToRegisteryHashL( 
+            aEntry, 
+            *path, 
+            *hash ) )
+            {
+            hashOk++;                    
+            }                                                               
+        }
+        
+    // If all hashes are ok return ETrue.
+    if ( hashOk == count )
+        {
+        BTIC_TRACE_PRINT("\nAll hashes are ok\n");
+        retVal = ETrue;
+        }
+         
+     __UHEAP_MARKEND;     
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] VerifyHashL <---");
+    
+    return retVal;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CompareToRegisteryHashL
+// 
+// Note this function returns EFalse is HashL function leaves.   
+//
+// Returns: ETure if hash is valid.
+//          EFalse if hash was not valid.
+// -----------------------------------------------------------------------------
+// 
+LOCAL_C TBool CompareToRegisteryHashL( 
+    RSisRegistryEntry& aEntry, 
+    TDesC& aEntryFile, 
+    TDesC8& aHashBuffer )
+    {    
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CompareToRegisteryHashL --->");    
+       
+    TInt err = 0; 
+    TBool hashOk = EFalse;    
+    CHashContainer* hashContainer = NULL; 
+
+    BTIC_TRACE_PRINT("Get hash for file: ");        
+    BTIC_TRACE_PRINT_RAW( aEntryFile );     
+    
+    BTIC_TRACE_PRINT("RSisRegistryEntry.HashL()");                       
+    // Get hashConteiner for given file. 
+    TRAP( err, hashContainer = aEntry.HashL( aEntryFile ) ); 
+                
+    if ( err == KErrNone && hashContainer )    
+        {                            
+        CleanupStack::PushL( hashContainer );
+        
+        // Get hash data from hashConteiner.                                                                                                                                       
+        TBufC8<KBTICHashSize> hashFromReg( hashContainer->Data() );
+                                                
+        if ( hashFromReg.Compare( aHashBuffer ) == 0 )
+            {
+            hashOk = ETrue;
+            
+            BTIC_TRACE_PRINT("Hash ok"); 
+            }
+                                               
+        CleanupStack::PopAndDestroy(); //hashContainer       
+        }
+    else
+        {
+        // If HashL function leaves, return false.          
+        hashOk = EFalse;
+        BTIC_TRACE_PRINT_NUM("ERROR RSisRegistryEntry HashL = %d", err ); 
+        }    
+              
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CompareToRegisteryHashL <---");         
+           
+    return hashOk;
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CheckSerialNumberL
+//
+// This function opens IMEI file and checks that device's serial number is found 
+// in the file.
+//
+// Returns: ETure if serial number is found or some error with server. 
+//          EFalse if serial number not found
+// -----------------------------------------------------------------------------
+//     
+LOCAL_C TBool CheckSerialNumberL( RFs& aFs, const TDesC& aFileName )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckSerialNumberL --->");
+    __UHEAP_MARK;      
+    
+    TBool matchFound = EFalse;        
+           
+    RInfoServerClient server;
+              
+    // Connect to server.    
+    TInt err = server.Connect();
+    
+    BTIC_TRACE_PRINT_NUM("Server connect error = %d", err );
+    
+    if ( err == KErrNone )
+        {            
+        CleanupClosePushL( server );
+        
+        TBuf<RMobilePhone::KPhoneSerialNumberSize> deviceSerialNumber;
+                            
+        // Get device serial number from server.
+        err = server.GetSerialNumber( deviceSerialNumber );          
+        
+        RFile file;  
+            
+        if ( err == KErrNone )
+            {                        
+            // Open text file.
+            User::LeaveIfError( file.Open( aFs, aFileName, EFileRead ) );         
+            CleanupClosePushL( file );
+          
+            TInt size; 
+            file.Size( size );
+          
+            HBufC8* content = HBufC8::NewLC( size );      
+            TPtr8 ptr(content->Des());
+
+            // Read content
+            User::LeaveIfError( file.Read( ptr, size ) );                                
+            
+            TLex8 input( ptr );
+            TBool lineEnd( EFalse );
+            TChar ch;
+
+            TBuf<RMobilePhone::KPhoneSerialNumberSize> serialNumber;                
+            
+            while ( ! input.Eos() )
+                {                         
+                ch = input.Get();
+                                                          
+                if ( ( ch != '\n' ) && ( ch != '\r' ) )
+                    {
+                    // Check that we have space for next number. 
+                    if ( serialNumber.Size() < serialNumber.MaxSize() )
+                        {
+                        serialNumber.Append( ch ); 
+                        } 
+                    else
+                        {
+                        // Buffer size is 50 and it should be enoug, if not 
+                        // then something is wrong. Let's break to loop and
+                        // return false.      
+                        break;
+                        }                                        
+                   }                                  
+                else
+                   {
+                   lineEnd = ETrue;
+                   }
+
+                if ( ( lineEnd ) || ( input.Eos() ) )
+                   {                   
+                   if ( deviceSerialNumber == serialNumber )
+                        {
+                        BTIC_TRACE_PRINT("Correct serial number found");
+                        matchFound = ETrue;
+                        break;
+                        }                              
+                   
+                   serialNumber.FillZ(0);
+                   serialNumber.SetLength(0);
+                   lineEnd = EFalse;
+                   }               
+                }                
+            CleanupStack::PopAndDestroy( 2 ); //file, content                   
+            }                       
+        CleanupStack::PopAndDestroy(); //client                                                           
+        }  
+                
+    __UHEAP_MARKEND;                                  
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckSerialNumberL <---");
+                         
+    return matchFound;     
+    }
+ 
+           
+// -----------------------------------------------------------------------------
+// CorruptFileL
+//
+// This function corrupts certificate file so that certs can not be read.
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void CorruptFileL( RFs& aFs, const TDesC& aFileName )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ! ! CORRUPT STORE FILE ! !");           
+              
+    TFindFile find( aFs );
+    
+    TUint8 byteVector[8] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };    
+    
+    // Find given file in C drive.
+    if ( find.FindByDir( aFileName, KBTICDriveC ) == KErrNone )
+        {             
+        RFile file;
+        TInt err;
+                     
+        for ( TInt loop = 0; loop < KBTICTryToOpen; loop++ )
+            {
+            err = file.Open( aFs, aFileName, EFileRead | EFileWrite );
+            BTIC_TRACE_PRINT_NUM("File Open error = %d", err );            
+            
+            // If file is open or it has ReadOnly attribute wait and try again. 
+            if ( err )
+                {
+                BTIC_TRACE_PRINT_NUM("Wait 0.5 sec. Attempt nr.%d", loop );
+                User::After( 500000 );
+                
+                TInt seterr = aFs.SetAtt( aFileName, 0, KEntryAttReadOnly );
+                BTIC_TRACE_PRINT_NUM("Remove Read Only attrib. = %d", seterr );                    
+                }
+            else
+                {
+                break;
+                }    
+            }
+            
+        // Leave if error.
+        User::LeaveIfError( err );          
+        
+        CleanupClosePushL( file );
+           
+        TInt size = 0;
+        file.Size( size );
+
+        HBufC8* fileData = HBufC8::NewLC( size );
+        TPtr8 dataPtr = fileData->Des();                        
+
+        HBufC8* newFileData = HBufC8::NewLC( size + sizeof( byteVector ) );
+        TPtr8 newDataPtr = newFileData->Des();
+
+        file.Read( dataPtr ); 
+        // Copy corrupted bytes to buffer.
+        newDataPtr.Copy( &byteVector[0], sizeof( byteVector ) ); 
+        // Copy original file data to buffer.
+        newDataPtr.Append( dataPtr );            
+        // Write data at start of file.  
+        file.Write( 0, *newFileData ); 
+
+        file.Flush();  
+
+        CleanupStack::PopAndDestroy( 3 ); 
+        
+        BTIC_TRACE_PRINT("File corrupted" );        
+        }                        
+    }
+
+
+// -----------------------------------------------------------------------------
+// CheckCapabilityWordAndCalcHashL
+//
+// This function reads capability word from file heder and compares that to given
+// capability (aCapaVector). If there is more then one whanted capability the 
+// first match is selected. If match is found file path is added to aFilesArray
+// and hash is calculated over the binary and found capa is added to array. 
+// If aCheckCapa is set as EFalse, capability word is not checked and all files 
+// from aSourceArray is added to aFilesArray.
+// Note aCapaArray conteins only matched capability. Not all file's capabilities.
+//
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//        
+LOCAL_C TBool CheckCapabilityWordAndCalcHashL( 
+    RFs& aFs,                           // File server handle
+    TBool aCheckCapa,                   // Enables capability check.
+    TUint64* aCapaVector,               // Vector con. capa. that are checked.
+    RPointerArray<HBufC>& aSourceArray, // Files to be checked.
+    RPointerArray<HBufC>& aFilesArray,  // Passed files
+    RPointerArray<HBufC8>& aHashArray,  // File's hash
+    RArray<TUint64>& aCapaArray )       // File's capability.
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckCapaWordAndCalcHashL v3.1 ->");
+       
+    TFindFile find( aFs );    
+    
+    TInt pathCount = aSourceArray.Count();    
+    
+    TBool retVal = EFalse;     
+    TInt index;
+    TInt err;    
+    
+    CSHA1* sha = CSHA1::NewL();
+    CleanupStack::PushL( sha );
+    
+    RFile file; 
+    
+    for ( index = 0; index < pathCount; index++ )
+        {
+        BTIC_TRACE_PRINT_NUM("File array index = %d", index );
+        
+        HBufC* path = aSourceArray[index]; 
+        
+        BTIC_TRACE_PRINT("File path: ");
+        BTIC_TRACE_PRINT_RAW( *path );        
+                                                            
+        err = file.Open( aFs, *path, EFileShareReadersOnly );              
+      
+        if ( err == KErrNone )
+            {                               
+            CleanupClosePushL( file );                
+
+            TInt size = 0; 
+            file.Size( size );                                                               
+
+            // Alloc buffer for file.
+            HBufC8* buffer = HBufC8::NewLC( size );
+
+            if ( buffer )
+                {
+                TPtr8 bufferPtr = buffer->Des();                            
+
+                // Read file binary to buffer.          
+                err = file.Read( bufferPtr );               
+                                 
+                if ( err == KErrNone || buffer->Length() != 0 )
+                    { 
+                    TUint64 capa = 0;
+                    TBool capabilityOk = EFalse;   
+                     
+                    // Check capability if needed.                    
+                    if ( aCheckCapa )
+                        {
+                        // Get pointer to heap buffer.
+                        const TUint8* ptr = buffer->Ptr();   
+                                                     
+                        // Capapility word (64bit) is found in 0x88 bytes after 
+                        // file heder offset. 0x88 = 136 bytes/8=17 words@64.                                                     
+                        TUint64 word = ((TUint64*)ptr)[KBTICCabaWordOffset]; 
+                                                                            
+                        for ( TInt iCapa = 0; iCapa < KBTICCapaCount; iCapa++ ) 
+                            {
+                            BTIC_TRACE_PRINT_NUM("Capa index = %d", iCapa );
+                            
+                            capa = aCapaVector[iCapa];
+                            
+                            if ( (word & capa) == capa )
+                                {  
+                                BTIC_TRACE_PRINT("Capability match found");                      
+                                capabilityOk = ETrue;
+                                break;
+                                }                                     
+                            }                                                              
+                        }
+                        
+                    // If capa check is not needed calculate hash over the file. 
+                    // Capability is set as zero.   
+                    else
+                        {
+                        BTIC_TRACE_PRINT("Capability NOT REGUIRED");
+                        capabilityOk = ETrue;    
+                        }
+                                           
+                    if ( capabilityOk )
+                        {              
+                        BTIC_TRACE_PRINT("Append file information to array"); 
+                        
+                        // Add found capability to array
+                        User::LeaveIfError( aCapaArray.Append( capa ) );                    
+                                                                         
+                        // Append pointer to files path.
+                        User::LeaveIfError( aFilesArray.Append( path ) ); 
+                                               
+                        HBufC8* hash = HBufC8::NewLC( KBTICHashSize );                        
+                        TPtr8 hashPtr = hash->Des();
+                                                                                
+                        sha->Reset();                        
+                                                
+                        // Calucalte hash over file's binary.
+                        hashPtr.Copy( sha->Hash( bufferPtr ) );
+                        
+                        // Check that digest has correct length.
+                        if ( hash->Length() != KBTICHashSize )
+                            {
+                            BTIC_TRACE_PRINT("\nERROR HASH SIZE"); 
+                            User::Leave( KErrGeneral );
+                            }                                                        
+                        
+                        // Add file's hash to array
+                        User::LeaveIfError( aHashArray.Append( hash ) );                                                  
+                        
+                        CleanupStack::Pop(); // hash; 
+                        
+                        retVal = ETrue;                          
+                        }
+                    }
+                else
+                    {
+                    BTIC_TRACE_PRINT_NUM("\nERROR File read = %d", err );            
+                    User::Leave( KErrGeneral );  
+                    }                                                   
+                }
+            else
+                {
+                BTIC_TRACE_PRINT("\nERROR HBufC8 buffer alloc failed");              
+                User::Leave( KErrGeneral );  
+                }      
+                                                                                
+            CleanupStack::PopAndDestroy( 2 ); // file,  fileBuffer         
+            }
+        else
+            {
+            BTIC_TRACE_PRINT_NUM("\nERROR File open = %d", err );              
+            User::Leave( KErrGeneral );  
+            }                                    
+        } 
+            
+    CleanupStack::PopAndDestroy(); // sha                 
+                    
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckCapaWordAndCalcHashL v3 <---");     
+    
+    return retVal;            
+    }    
+
+/*
+#ifdef __BTIC_BINARIES_CHECK_ENABLED
+
+
+// -----------------------------------------------------------------------------
+// RenameFileL
+//
+// This function renames given file by replacing existing file extension to .bak
+// -----------------------------------------------------------------------------
+//    
+LOCAL_C void RenameFileL( RFs& aFs, const TDesC& aFileName )
+    { 
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ! ! ! RenameFileL --->");
+       
+    _LIT( KBTICFileExtensionBak,".bak" );
+              
+    TFindFile find( aFs );
+      
+    // Find given file in C drive.
+    if ( find.FindByDir( aFileName, KBTICSysPathC ) == KErrNone )
+        {          
+        TInt length = aFileName.Length();
+        HBufC* newName = HBufC::NewLC( length + sizeof( KBTICFileExtensionBak ) );
+        TPtr newNamePtr = newName->Des();                        
+        
+        newNamePtr.Copy( aFileName ); 
+        // Add ".bak" extension to file name.
+        newNamePtr.Append( KBTICFileExtensionBak );                              
+        
+        // Rename file.
+        TInt err = aFs.Rename( aFileName, *newName );
+        
+        // If error try ones more. 
+        if ( err != KErrNone )
+            {
+            aFs.Rename( aFileName, *newName );
+            }
+        }
+
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ! ! ! RenameFileL <---");        
+    }
+    
+
+// -----------------------------------------------------------------------------
+// UniteCertArraysL
+//
+// Function append source array's pointers to target array. 
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void UniteCertArraysL(     
+    RPointerArray<CX509Certificate>& aTargetCertArray,
+    RPointerArray<CX509Certificate>& aSourceCertArray )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] UniteCertArraysL --->");    
+        
+    TInt count = aSourceCertArray.Count();
+        
+    if ( count > 0 )
+        {
+        for ( TInt index = 0; index < count; index++ )
+            {
+            CX509Certificate* x509Cert = aSourceCertArray[index];
+            // Note if append fails -> some binaries will be corrupted.          
+            aTargetCertArray.Append( x509Cert );                        
+            }                
+        }
+            
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] UniteCertArraysL <---");            
+    }
+
+
+// -----------------------------------------------------------------------------
+// UniteCapaArraysL
+//
+// Function append source array's pointers to target array. 
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void UniteCapaArraysL( 
+    RPointerArray<TCapabilitySet>& aTargetCapaArray,
+    RPointerArray<TCapabilitySet>& aSourceCapaArray )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] UniteCapaArraysL --->");    
+   
+    TInt count = aSourceCapaArray.Count();            
+        
+    if ( count > 0 )
+        {
+        for ( TInt index = 0; index < count; index++ )
+            {
+            TCapabilitySet* capaSet = aSourceCapaArray[index];
+            // Note if append fails -> some binaries will be corrupted.           
+            aTargetCapaArray.Append( capaSet );                        
+            }                
+        }       
+        
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] UniteCapaArraysL <---");    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CheckBinariesL
+//
+// This function checks all exe or dll binarys conteining TCB and DRM capability 
+// in C:\sys\bin directory. It calculates hash over the binary and compares that 
+// to one found in SIS Registery. It check also that SIS pacage's certificate 
+// has rigth to grant TCB or DRM capabiltity.
+// If some file in C:\sys\bin directory is not found in SIS Registery it is 
+// renamed.
+// 
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void CheckBinariesL( 
+    RFs& aFs, 
+    RPointerArray<CX509Certificate>& aX509CertArray,
+    RPointerArray<TCapabilitySet>& aCertCapaArray )    
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckBinariesL --->");
+    __UHEAP_MARK;          
+    
+    TInt pushToStack = 0;
+    TInt err = 0;            
+    
+    RPointerArray<HBufC> allFilesArray;
+    
+    // Find all exe files from c:\sys\bin.
+    FindFilesL( aFs, KBTICSysPathC, KBTICExtensionExe, allFilesArray );    
+    // Find all dll files from c:\sys\bin.
+    FindFilesL( aFs, KBTICSysPathC, KBTICExtensionDll, allFilesArray );
+     
+    TInt count = allFilesArray.Count();
+    
+    if ( count > 0 )
+        {            
+        RPointerArray<HBufC> filesArray;
+        RPointerArray<HBufC8> hashArray; 
+        RArray<TUint64> capaArray;  
+                
+        TBool foundFiles = EFalse;
+
+        // Copy whanted capabilities to array.                   
+        TUint64* capaVector = new( ELeave ) TUint64[KBTICCapaCount];
+        CleanupArrayDeletePushL( capaVector );
+        capaVector[0] = KBTIC_TCB;
+        capaVector[1] = KBTIC_DRM;
+        
+        // Find files conteining whanted capability and calculate hash over file.  
+        
+        // NOTE NOTE currently this function addends only one capability to 
+        // capaArray. This must be changed if all capabilities should be 
+        // checked from certificate.        
+                         
+        foundFiles = CheckCapabilityWordAndCalcHashL( 
+            aFs,
+            ETrue, 
+            capaVector,                        
+            allFilesArray, 
+            filesArray, 
+            hashArray,
+            capaArray );                             
+                                                 
+        CleanupStack::PopAndDestroy();  //capaVector 
+                    
+        if ( foundFiles && err == KErrNone )
+            {
+            // Find match for fileArray's files from SIS registery
+            // Check that file's (binary) hash matches to SIS registery's hash 
+            // Check that SIS registery cert. is valid and has file's capability.              
+            FindMatchFromSisPackageL( 
+                aFs,                 
+                filesArray, 
+                hashArray,
+                capaArray, 
+                aX509CertArray,
+                aCertCapaArray );                           
+                            
+            count = filesArray.Count();
+            
+            BTIC_TRACE_PRINT_NUM("Files array count = %d (should be 0 )", count );
+            
+            // Rename all files which was not found in sis registery.
+            if ( count )  
+                {                               
+                for ( TInt index = 0; index < count; index++ )
+                    {
+                    HBufC* filePath = filesArray[index];
+                                        
+                    RenameFileL( aFs, *filePath );                                                                 
+                    }
+                }                
+            }    
+                                           
+        filesArray.Reset(); // Reset only. allFilesArray owns heap memory.                               
+        hashArray.ResetAndDestroy();                                       
+        }
+    
+    allFilesArray.ResetAndDestroy(); 
+               
+    CleanupStack::PopAndDestroy( pushToStack );  //searchPath    
+       
+    BTIC_TRACE_PRINT("UHEAP MARK END");  
+    __UHEAP_MARKEND;    
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CheckBinariesL <---");  
+    }
+
+
+// -----------------------------------------------------------------------------
+// FindFilesL
+//
+// This function searches one or more files that conteins given string in file 
+// name. File names are added to array with complete path.  
+// -----------------------------------------------------------------------------
+//       
+LOCAL_C void FindFilesL( 
+    RFs& aFs,                               // File server handle.
+    const TDesC& aPath,                     // Search directory and drive.
+    const TDesC& aSearchString,             // String to be found in file name.
+    RPointerArray<HBufC>& aFoundFilesArray )// Result files.
+    {  
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] FindFilesL --->"); 
+     
+    TInt err = 0;
+    TFindFile find( aFs ); 
+    CDir* dirList = NULL;
+    HBufC* path;
+          
+    TFileName searchExtension;
+    searchExtension.Copy( aSearchString );
+    
+    // Find files from searchPath directory. Note that dirlist
+    // contains only file name not path to it.                  
+    err = find.FindWildByPath( searchExtension, &aPath, dirList );
+                    
+    TInt pathLength = aPath.Length(); 
+    
+    if ( err == KErrNone && dirList )
+        {
+        CleanupStack::PushL( dirList );
+        
+        // Get the count of find files.
+        TInt count = dirList->Count();
+        
+        BTIC_TRACE_PRINT_NUM("Dir list count = %d", count ); 
+                                   
+        for ( TInt index = 0; index < count; index++ )
+            {                                    
+            path = HBufC::NewLC( pathLength + (*dirList)[index].iName.Length() );              
+            TPtr ptrPath = path->Des();
+            
+            // Copy system path to buffer.
+            ptrPath.Copy( KBTICSysPathC );
+            // Append files name to path buffer.
+            ptrPath.Append( (*dirList)[index].iName ); 
+            
+            ptrPath.LowerCase();                                   
+            
+            aFoundFilesArray.Append( path );
+            
+            CleanupStack::Pop(); //path
+            }
+            
+        CleanupStack::Pop(); //dirList 
+        delete dirList;  
+        }
+                       
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] FindFilesL <---");                 
+    }
+
+
+
+// -----------------------------------------------------------------------------  
+// FindMatchFromSisPackageL
+//
+// This function search given files from SIS Registery. Function removes file 
+// from aFilesArray alway when it is found in Registery. If aFilesArray contains 
+// files after function return those files are not found in SIS Registery.
+// 
+// Returns: ETure if successful  
+//          EFalse othervice
+// -----------------------------------------------------------------------------
+//  
+LOCAL_C TBool FindMatchFromSisPackageL( 
+    RFs& aFs,                           // File server handle
+    RPointerArray<HBufC>& aFilesArray,  // Files to be checked
+    RPointerArray<HBufC8>& aHashArray,  // File's hash
+    RArray<TUint64>& aCapaArray,        // File's capability
+    RPointerArray<CX509Certificate>& aX509CertArray, // Cert array
+    RPointerArray<TCapabilitySet>& aCertCapaArray )  // Cert's capability
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] FindMatchFromSisPackageL --->");
+    __UHEAP_MARK; 
+    
+    TInt err = KErrNone;        
+    TBool allOK = EFalse; 
+               
+    Swi::RSisRegistrySession sisRegSession;  
+            
+    err = sisRegSession.Connect();
+    
+    if ( err == KErrNone )
+        {
+        CleanupClosePushL( sisRegSession );
+        
+        RPointerArray<CSisRegistryPackage> sisPackages;
+                       
+        // Find installed packages.
+        sisRegSession.InstalledPackagesL( sisPackages );                
+                      
+        TBool entryOpen = EFalse;    
+        TInt entryFilesCount = 0;
+        TInt fileCount = 0;        
+        Swi::RSisRegistryEntry entry; 
+        // Array for entrys files. This owns heap memory.                       
+        RPointerArray<HBufC> installedFiles; 
+        // Array for dll and exe files found in sis registery.
+        RPointerArray<HBufC> entryFiles;
+        // Array for wild card string to be search from file list.
+        RPointerArray<HBufC> stringArray;
+        HBufC* string;
+        
+        // Add wild card strings to array.                    
+        string = KBTICExtensionExe().AllocLC();
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop();
+        
+        string = KBTICExtensionDll().AllocLC();
+        User::LeaveIfError( stringArray.Append( string ) );
+        CleanupStack::Pop();                     
+                
+        // Open sis registery entry and search paths to installed exes and dlls.
+        for( TInt index = 0; index < sisPackages.Count(); index++)
+            {  
+            BTIC_TRACE_PRINT_NUM("entry loop Index = %d", index );
+
+            // If error happens make leave. If some pacage is left out we can 
+            // not continue, because all files found in C must be found also 
+            // in sis registery.                                           
+            User::LeaveIfError( 
+                entry.OpenL( sisRegSession, *sisPackages[index] ) );                         
+                                                 
+            CleanupClosePushL( entry );
+            entryOpen = ETrue; 
+            
+            // Get this entrys installed files.                                                                          
+            entry.FilesL( installedFiles );                                          
+                        
+            if ( installedFiles.Count() > 0 )
+                {                     
+                // Search match for string array conten from entrys files.
+                // Note that heap memory is owned by installeFiles array.
+                SearchFilesFromArrayL( 
+                    installedFiles, 
+                    KBTICSysPathCWildcard,
+                    stringArray, 
+                    entryFiles );                                                                                             
+                }                                                                                                                                                                              
+                                                                            
+            entryFilesCount = entryFiles.Count();
+            
+            BTIC_TRACE_PRINT_NUM("Entry files count = %d", entryFilesCount );
+                    
+            if ( entryFilesCount > 0 )
+                {
+                TBool pagaceCertValid = EFalse;                                
+                
+                // Go torug all file paths from entryFiles aray.
+                for ( TInt indexB = 0; indexB < entryFilesCount; indexB++ )
+                    {
+                    BTIC_TRACE_PRINT_NUM("file path loop IndexB = %d", indexB );
+                    
+                    // Get file's path from sis pagace entry.
+                    HBufC* entryFile = entryFiles[indexB];                                         
+                    
+                    fileCount = aFilesArray.Count();
+                                                                     
+                    // Compare registery file path to files found in C:\sys\bin.            
+                    for ( TInt indexC = fileCount - 1; indexC >= 0; indexC-- )
+                        {                                                
+                        // Get file's path from array conteining dlls and exes.
+                        HBufC* file = aFilesArray[indexC];                                                                                                
+                        
+                        TInt result = entryFile->CompareC( *file );
+                                               
+                        BTIC_TRACE_PRINT_NUM("\nCompare result = %d", result );                        
+                        
+                        // If result is zero match is found.
+                        if ( result == 0 )                        
+                            {
+                            BTIC_TRACE_PRINT("File path Match found" ); 
+                            
+                            // Get file's hash
+                            HBufC8* hash = aHashArray[indexC];                                                                                                                                                                       
+                                                    
+                            BTIC_TRACE_PRINT("CompareToRegisteryHashL -->" );                            
+                           
+                            TBool hashOk = CompareToRegisteryHashL( 
+                                entry, 
+                                *entryFile, 
+                                *hash );
+                                
+                            BTIC_TRACE_PRINT("CompareToRegisteryHashL <--" );     
+                            
+                                                      
+                            if ( hashOk )
+                                {
+                                BTIC_TRACE_PRINT("HASH OK");
+                                
+                                // Check if entry cert is already valid.
+                                if ( ! pagaceCertValid )
+                                    {                                          
+                                    BTIC_TRACE_PRINT("Validate pagace cert");
+                                     
+                                    // Validate entry's certificate and 
+                                    // check that certificate has correct 
+                                    // capablities.                                                                                                                  
+                                    TBool certOk = SearchValidCertificateL( 
+                                        entry, 
+                                        aX509CertArray,                                             
+                                        aCertCapaArray,
+                                        aCapaArray[indexC] );
+                                    
+                                    if ( certOk )
+                                        {
+                                        BTIC_TRACE_PRINT("Pagace CERT VALID - OK");
+                                        
+                                        // Validate pagace cert. only once.
+                                        pagaceCertValid = ETrue;
+                                        }
+                                    else
+                                        {
+                                        // Rename file if cert is not ok.
+                                        
+                                        RenameFileL( aFs, *entryFile );                                            
+                                        // Should we rename all files in this
+                                        // entry or only this one.
+                                        }                                            
+                                    }                                                                   
+                                } 
+                            else
+                                {
+                                BTIC_TRACE_PRINT("HASH Error -> Rename file");
+                                // If hash is false rename file.
+                                RenameFileL( aFs, *entryFile );
+                                }      
+                                                                                                                                                                                                                     
+                            // Set arrays entry to zero so we will not 
+                            // compear it twice. We do not have to delete 
+                            // entry because aFilesArray do not own heap 
+                            // memory.                                
+                            aFilesArray.Remove( indexC );
+                            
+                            //Remove also hash and capa entry from array.
+                            HBufC8* hashBuffer = aHashArray[indexC];
+                            delete hashBuffer;
+                            aHashArray.Remove( indexC);
+                            
+                            aCapaArray.Remove( indexC );                                                        
+                                                                                                                                                         
+                            break;                  
+                            }                                                                                                         
+                        }
+                    }
+                } 
+                
+            if ( entryOpen )
+                {    
+                BTIC_TRACE_PRINT("Clear ENTRY and installedFiles array");
+                    
+                CleanupStack::PopAndDestroy(); //entry                   
+                entryFiles.Reset(); //Reset only.
+                installedFiles.ResetAndDestroy();               
+                }
+                
+           // Break entry loop if all files are removed.     
+           if ( aFilesArray.Count() == 0 )
+                {
+                BTIC_TRACE_PRINT("NO MORE EXE/DLL FILES -> BREAK LOOP");
+                break;
+                }                                                                                                                   
+            }                       
+        
+        stringArray.ResetAndDestroy();
+        CleanupStack::PopAndDestroy(); // sisRegSession 
+        
+        allOK = ETrue;    
+        }
+     
+     
+    BTIC_TRACE_PRINT("UHEAP MARK END");  
+    __UHEAP_MARKEND;          
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] FindMatchFromSisPackageL <---"); 
+    
+    return allOK;
+    }
+
+
+#endif //__BTIC_BINARIES_CHECK_ENABLED
+*/
+      
+// =========================== CRootCertificateEntry ===========================
+
+// -----------------------------------------------------------------------------
+// NewLC()
+// 
+// -----------------------------------------------------------------------------
+//
+CRootCertificateEntry* CRootCertificateEntry::NewLC( RReadStream& aStream )
+    {
+    CRootCertificateEntry* self = new(ELeave) CRootCertificateEntry();
+    CleanupStack::PushL(self);
+
+    self->InternalizeL( aStream );
+
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CRootCertificateEntry()
+// 
+// -----------------------------------------------------------------------------
+//
+CRootCertificateEntry::CRootCertificateEntry()
+    { 
+    }
+
+
+// -----------------------------------------------------------------------------
+// ~CRootCertificateEntry()
+// 
+// -----------------------------------------------------------------------------
+//
+CRootCertificateEntry::~CRootCertificateEntry()
+    {
+    iApplications.Close();    
+    }
+
+
+// -----------------------------------------------------------------------------
+// InternalizeL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CRootCertificateEntry::InternalizeL( RReadStream& aStream )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] InternalizeL");
+
+    iX509CertificateType = aStream.ReadUint8L();
+
+    iSize = aStream.ReadInt32L();
+
+    aStream >> iLabel;
+
+    iCertId = aStream.ReadInt32L();
+
+    iCACertificateType = aStream.ReadUint8L();
+
+    aStream >> iSubjectKeyId;
+
+    aStream >> iIssuerKeyId; 
+
+    TInt count = aStream.ReadInt32L();
+
+    for ( TInt i = 0 ; i < count ; ++i )
+        {
+        TUid id;
+        aStream >> id;
+        User::LeaveIfError( iApplications.Append( id ) );
+        }
+
+    iTrusted = !!aStream.ReadUint8L();  // converts TUint8 to TBool
+
+    aStream >> iDataStreamId;
+
+    TPckg<TCapabilitySet> capsPckg( iCapabilities );  
+    aStream >> capsPckg;  
+
+    iMandatory = !!aStream.ReadUint8L();    
+    }
+
+     
+// -----------------------------------------------------------------------------
+// DataStreamId()
+// 
+// -----------------------------------------------------------------------------
+//
+TStreamId CRootCertificateEntry::DataStreamId() const
+    {
+    return iDataStreamId;
+    }
+
+
+// -----------------------------------------------------------------------------
+// Capabilities()
+// 
+// -----------------------------------------------------------------------------
+//
+const TCapabilitySet& CRootCertificateEntry::Capabilities() const
+    {
+    return iCapabilities;
+    }
+
+// -----------------------------------------------------------------------------
+// Size()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CRootCertificateEntry::Size() const
+    {
+    return iSize;
+    }
+
+  
+// -----------------------------------------------------------------------------
+// CertID()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CRootCertificateEntry::CertID() const
+    {
+    return iCertId;
+    }
+
+
+
+// =========================== CActiveFileObserver ============================
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::CActiveFileObserver()
+// -----------------------------------------------------------------------------
+//
+CActiveFileObserver::CActiveFileObserver( RFs&  aFs, TInt& aResult) 
+    : CActive( EPriorityNormal ),
+    iFs( aFs ), 
+    iResult( aResult )    
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::~CActiveFileObserver()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CActiveFileObserver::~CActiveFileObserver()
+    {  
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] ~CActiveFileObserver");   
+    // Cancel the outstanding request. This calls DoCancel().
+    Cancel();  
+    // Close timer.    
+    iRTimer.Close();
+    
+    if ( iPath )
+        {
+        delete iPath;
+        iPath = NULL;
+        }        
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver* CActiveFileObserver::NewL()
+// Factory method.
+// -----------------------------------------------------------------------------
+//
+CActiveFileObserver* CActiveFileObserver::NewL( 
+    RFs&  aFs,
+    const TDesC& aPath,      
+    TInt& aResult )
+    {
+    CActiveFileObserver* observer = 
+        new(ELeave) CActiveFileObserver( aFs, aResult );
+        
+    CleanupStack::PushL( observer );
+
+    observer->ConstructL( aPath );
+
+    CleanupStack::Pop();
+
+    return observer;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::ConstructL()
+// Second-phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CActiveFileObserver::ConstructL( const TDesC& aPath )
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CActiveFileObserver::ConstructL"); 
+    
+    iRunCount = 0;
+       
+    iPath = HBufC::NewL( aPath.Length() );
+    TPtr iPathPtr = iPath->Des();
+    iPathPtr.Copy( aPath );
+    
+    iRTimer.CreateLocal();
+    
+    // Add to scheduler.    
+    CActiveScheduler::Add( this );
+    
+    // Issue first timer request.
+    IssueRequest();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::DoCancel()
+// Cancel function for active object.
+// -----------------------------------------------------------------------------
+//
+void CActiveFileObserver::DoCancel()
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CActiveFileObserver::DoCancel"); 
+    // Cancel outstanding request.    
+    iRTimer.Cancel();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::RunError()
+// Handles a leave occurring in the request completion event handler RunL.
+// -----------------------------------------------------------------------------
+//
+TInt CActiveFileObserver::RunError( TInt aError )
+    { 
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CActiveFileObserver::RunError"); 
+    iResult = aError;             
+    BTIC_TRACE_PRINT_NUM("[BOOT INTE.] RunError: err = %d", aError );
+    return aError;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::IssueRequest()
+// This function issues new 
+// -----------------------------------------------------------------------------
+void CActiveFileObserver::IssueRequest()
+    {     
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CActiveFileObserver::IssueRequest");            
+    //iFs.NotifyChange( ENotifyEntry, iStatus, *iPath );
+    iRunCount++;
+
+    iRTimer.After( iStatus, KBTICObserverTime );
+       
+    // Wait request to complete.
+    SetActive();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CActiveFileObserver::RunL()
+// This function handles active object’s request completion event
+// -----------------------------------------------------------------------------
+//
+void CActiveFileObserver::RunL()
+    {
+    BTIC_TRACE_PRINT("[BOOT INTECRITY CHECK] CActiveFileObserver::RunL"); 
+                                      
+    TInt err = KErrNone; 
+    RFile file;
+    // Try to open the file.
+    err = file.Open( iFs, *iPath, EFileShareReadersOrWriters | EFileRead );               
+    
+    BTIC_TRACE_PRINT_NUM("[BOOT INTE.] RunL: file open err = %d", err );
+    
+    if ( err == KErrNone )
+        {
+        // Close the file.
+        file.Close();
+        
+        if ( iRunCount < KBTICRunCount )        
+            {
+            // Make new request.
+            IssueRequest();      
+            }
+        else
+            {
+            BTIC_TRACE_PRINT("[BOOT INTE.] RunL: File not deleted -> CANCEL"); 
+            // File is not deleted. Stop active observer 
+            // and continue data base checking.
+            iResult = KErrCancel;
+            Deque();
+            CActiveScheduler::Stop();             
+            }    
+        }        
+    else if ( err == KErrNotFound || err == KErrPathNotFound )
+        {
+        // Ok file is deleted. Stop active observer and return.
+        BTIC_TRACE_PRINT("[BOOT INTE.] RunL: File deleted -> OK");         
+        iResult = KErrNone;   
+        Deque();
+        CActiveScheduler::Stop();       
+        } 
+    else
+        {
+        // Some other file open error etc. KErrInUse. Let's continue.
+                         
+        if ( iRunCount < KBTICRunCount )        
+            {
+            // Make new request.
+            IssueRequest();      
+            }
+        else
+            {
+            BTIC_TRACE_PRINT("[BOOT INTE.] RunL: File not deleted -> CANCEL"); 
+            // File is not deleted. Stop active observer 
+            // and continue data base checking.
+            iResult = KErrCancel;
+            Deque();
+            CActiveScheduler::Stop();             
+            }            
+        }                                               
+    }
+
+//EOF