installationservices/swi/source/swis/server/installmachine.cpp
changeset 0 ba25891c3a9e
child 13 0817e13c927e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/swis/server/installmachine.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1984 @@
+/*
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*
+*/
+
+
+#define __INCLUDE_CAPABILITY_NAMES__ 
+#include <s32mem.h>
+#include "installmachine.h"
+#include "plan.h"
+#include "dessisdataprovider.h"
+#include "siscontroller.h"
+#include "siscertificatechain.h"
+#include "sisinstallerrors.h"
+#include "siscontentprovider.h"
+#include "sisinstallblock.h"
+#include "prerequisiteschecker.h"
+#include "postrequisiteschecker.h"
+#include "installationplanner.h"
+#include "log.h"
+#include "cleanuputils.h"
+#include "sisfiledescription.h"
+#include "sisinfo.h"
+#include "sisuid.h"
+#include "siscapabilities.h"
+#include "securitypolicy.h"
+#include "swispubsubdefs.h"
+#include "installationprocessor.h"
+#include "swi/launcher.h"
+#include "certchainconstraints.h"
+#include "swi/sistruststatus.h"
+#include <pkixcertchain.h>
+#include <swicertstore.h>
+#include <sacls.h>
+#include <f32file.h>
+#include "securitycheckutil.h"
+#include "sisptrprovider.h"
+#include <e32capability.h>
+#include <ocsp.h>
+#include "secutils.h"
+#include "sislauncherclient.h"
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include "swi/sisversion.h"
+#include "swi/nativecomponentinfo.h"
+#include <usif/usifcommon.h>
+#include "scrdbconstants.h"
+#endif
+
+using namespace Swi;
+using namespace Swi::Sis;
+
+
+//
+// TInstallState
+//
+
+CInstallMachine::TInstallState::TInstallState(CInstallMachine& aInstallMachine)
+:	iInstallMachine(aInstallMachine)
+	{
+	}
+
+//
+// TRegistrationState
+//
+
+CInstallMachine::TRegistrationState::TRegistrationState(
+	CInstallMachine& aInstallMachine)
+/**
+	Constructor.
+ */
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TRegistrationState::EnterL()
+/**
+	Send registration request to the SWI Observer and then activate the
+	installation machine.
+ */
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Registration State"));
+	//connect to the SWI Observer
+	User::LeaveIfError(iInstallMachine.Observer().Connect());
+	
+	//Register to the SWI Observer; which completes this request 
+	//when the SWI Observer Processor is idle.
+	iInstallMachine.Observer().Register(iInstallMachine.iStatus);
+	iInstallMachine.SetActive();
+	}
+
+CInstallMachine::TState* CInstallMachine::TRegistrationState::CompleteL()
+/**
+	Obtains the log file handle and its name from the SWI Observer.
+	Adds the log file to the transaction.
+ */
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Registration State complete"));
+	RBuf logFileName;
+	logFileName.CreateL(KMaxFileName);
+	logFileName.CleanupClosePushL();
+	
+	//Get created a log file and obtains its full name.
+	iInstallMachine.Observer().GetFileHandleL(logFileName);
+
+	//Add the log file the transaction
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	iInstallMachine.TransactionSession().RegisterNewL(logFileName);
+#else
+	iInstallMachine.IntegrityServicesL().AddL(logFileName);
+#endif
+
+	CleanupStack::PopAndDestroy(&logFileName);
+	// Get Controllers.
+	return static_cast<TState*>(&iInstallMachine.iGetControllerState);		
+	}
+	
+CInstallMachine::TState* CInstallMachine::TRegistrationState::ErrorL(TInt aCode)
+/**
+	If there is any error, closes the SWI Observer connection.
+ */
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Registration State failed with code '%d'"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TRegistrationState::Cancel()
+/**
+	Cancels the registration request.
+ */
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Registration State cancelled!"));
+	iInstallMachine.Observer().CancelRegistration();	
+	}
+
+
+//
+// TGetControllerState
+//
+
+CInstallMachine::TGetControllerState::TGetControllerState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TGetControllerState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Get Controller state"));
+
+	if (iInstallMachine.iSecurityManager->SecurityPolicy().DrmEnabled())
+		{
+		iInstallMachine.iSisHelper.OpenDrmContentL(static_cast<ContentAccess::TIntent>(iInstallMachine.iSecurityManager->SecurityPolicy().DrmIntent()));
+		}
+
+	iInstallMachine.iControllerData=
+		iInstallMachine.iSisHelper.SisControllerLC();
+	CleanupStack::Pop();
+	DEBUG_PRINTF2(_L8("Retrieved controller size %d"), iInstallMachine.iControllerData->Size());
+	
+	TPtrProvider provider(iInstallMachine.iControllerData->Des());
+
+	// Create controller
+	iInstallMachine.iController=Sis::CController::NewL(provider);
+
+	if(!iInstallMachine.iSecurityManager->SecurityPolicy().AllowPackagePropagate() 
+		 && iInstallMachine.iSisHelper.IsStubL())
+		{
+		// If it's a stub and our SWIPolicy AllowPackagePropagate
+		// flag is false we can only install if it's a 
+		// preinstalled stub not a removable media stub
+		if(iInstallMachine.iController->Info().InstallType() != EInstPreInstalledApp
+		 && iInstallMachine.iController->Info().InstallType() != EInstPreInstalledPatch)
+			{
+			// It is a removable media stub but our SWI policy forbids
+			// installation
+			User::Leave(KErrSecurityError);
+			}
+		
+		}
+	
+	// Create content provider which will be used everywhere for things like 
+	// TAppInfo etc.
+	iInstallMachine.iContentProvider=
+		CContentProvider::NewL(*iInstallMachine.iController);
+	
+	iInstallMachine.iCurrentContentProvider = iInstallMachine.iContentProvider;
+
+	// Create stuff for the installation planner to use later
+	iInstallMachine.iResult=CInstallationResult::NewL();
+	iInstallMachine.iPlanner=CInstallationPlanner::NewL(iInstallMachine.iSisHelper,iInstallMachine.UiHandler(), 
+		*iInstallMachine.iCurrentContentProvider, *iInstallMachine.iResult);
+	
+	iInstallMachine.iPlanner->SetDeviceSupportedLanguages(iInstallMachine.iDeviceSupportedLanguages);
+
+	
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Check if the machine runs in info collection mode. If so, set the planner too in the same mode.
+	if (iInstallMachine.IsInInfoMode())
+		{
+		iInstallMachine.iPlanner->SetInInfoCollectionMode(ETrue);
+		}
+	#endif
+	
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	}
+
+CInstallMachine::TState* CInstallMachine::TGetControllerState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Get Controller State complete"));
+	// Confirm installation with the user.
+	return static_cast<TState*>(&iInstallMachine.iConfirmationState);
+	}
+	
+CInstallMachine::TState* CInstallMachine::TGetControllerState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Get Controller State failed with code '%d'"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TGetControllerState::Cancel()
+	{
+	}
+
+//
+// TConfirmationState
+//
+
+CInstallMachine::TConfirmationState::TConfirmationState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TConfirmationState::EnterL()
+	{	
+	DEBUG_PRINTF(_L8("Install Machine - Entering Confirmation State"));
+	
+	TBool retval;
+	
+	TAppInfo appInfo(
+		iInstallMachine.iCurrentContentProvider->DefaultLanguageAppInfoL());
+	
+	RPointerArray<CX509Certificate> x509certs;
+	CleanupResetAndDestroyPushL(x509certs);
+	iInstallMachine.iSecurityManager->GetCertificatesFromControllerL(
+		*iInstallMachine.iController,x509certs);
+	
+	RPointerArray<CCertificateInfo> certs;
+	CleanupResetAndDestroyPushL(certs);
+	CSecurityManager::FillCertInfoArrayL(x509certs,certs);
+	
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	if (iInstallMachine.IsInInfoMode())
+		{
+		// If we operate in info mode, we just need the certs, no UI confirmation or logo will be displayed
+		CleanupStack::PopAndDestroy(2, &x509certs); // certs, x509certs
+		
+		iInstallMachine.CompleteSelf();
+		iInstallMachine.SetActive();
+
+		iInstallMachine.iOperationConfirmed = ETrue;				
+		return;
+		}
+	#endif
+	
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+	User::LeaveIfError(fs.ShareProtected());
+		
+	// Retrieve logo data which may not be present.
+	const CLogo* logo=iInstallMachine.iController->Logo();
+	if (logo)
+		{
+		const CFileDescription& fdesc(logo->FileDescription());
+		
+		// Create a temporary file for the logo.
+		
+		// Construct temporary file name for the logo.
+		TUint driveCh(RFs::GetSystemDriveChar());
+
+		TFileName logoFileName;
+		_LIT(KLogoFileNameFmt, "%c:\\sys\\install\\temp\\%08X-logo");
+		logoFileName.Format(KLogoFileNameFmt, driveCh,
+			iInstallMachine.iController->Info().Uid().Uid().iUid);
+		
+		TInt err = fs.MkDirAll(logoFileName);
+		if (err!= KErrNone && err != KErrAlreadyExists)
+			User::LeaveIfError(err);
+		
+		RFile logoFile;
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		iInstallMachine.TransactionSession().RegisterTemporaryL(logoFileName);
+#else
+		iInstallMachine.IntegrityServicesL().TemporaryL(logoFileName);
+#endif
+
+		User::LeaveIfError(logoFile.Replace(fs, logoFileName, 
+			EFileStream|EFileWrite|EFileRead|EFileShareExclusive));
+		CleanupClosePushL(logoFile);
+		
+		// Extract logo to a temporary file.
+		err=iInstallMachine.iSisHelper.ExtractFileL(fs, logoFile, 
+			fdesc.Index(), iInstallMachine.iController->DataIndex(), 
+			iInstallMachine.UiHandler());
+		User::LeaveIfError(err);
+		CleanupStack::PopAndDestroy(&logoFile);
+		
+		// Reopen file for reading (the handle will have been closed 
+		// by SISHelper).
+		User::LeaveIfError(logoFile.Open(fs, logoFileName, 
+			EFileStream|EFileRead|EFileShareExclusive));
+		CleanupClosePushL(logoFile);
+		CDisplayInstall* cmd=CDisplayInstall::NewLC(appInfo, fs, &logoFile, 
+			certs);
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		retval=cmd->ReturnResult();
+		CleanupStack::PopAndDestroy(2, &logoFile); // logoFile, cmd
+
+		RLoader loader;
+		User::LeaveIfError(loader.Connect());
+		CleanupClosePushL(loader);
+		
+		// Delete temporary logo file.
+		User::LeaveIfError(loader.Delete(logoFileName));
+		
+		CleanupStack::PopAndDestroy(&loader);
+		}
+	else
+		{
+		CDisplayInstall* cmd=CDisplayInstall::NewLC(appInfo, fs, NULL, certs);
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		retval=cmd->ReturnResult();
+		CleanupStack::PopAndDestroy(cmd);
+		}
+	
+	CleanupStack::PopAndDestroy(3, &x509certs); // fs, certs, x509certs
+	
+	// Check if the user cancelled installation.
+	if (!retval)
+		{
+		DEBUG_PRINTF(_L8("User canceled install at install dialog"));
+		User::Leave(KErrCancel);
+		}
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	
+	// user hasn't cancelled so mark the installation as confirmed. This
+	// will allow the registry cache to be regenerated further on during the
+	// installation process.
+	iInstallMachine.iOperationConfirmed = ETrue;	
+	}
+
+CInstallMachine::TState* CInstallMachine::TConfirmationState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Confirmation State complete"));
+	// Verify signature(s) if any.
+	return static_cast<TState*>(&iInstallMachine.iVerifyControllerState);
+	}
+	
+CInstallMachine::TState* CInstallMachine::TConfirmationState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Confirmation State failed with code '%d'"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TConfirmationState::Cancel()
+	{
+	}
+
+//
+// TVerifyControllerState
+//
+
+CInstallMachine::TVerifyControllerState::TVerifyControllerState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+// Verify signatures and cert chains using security manager
+void CInstallMachine::TVerifyControllerState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Verify Controller State"));
+
+	// Clear any results from previous controllers
+ 	iInstallMachine.iSigValidationResult=EValidationSucceeded;
+ 	iInstallMachine.iPkixResults.ResetAndDestroy();
+ 	iInstallMachine.iCertificates.ResetAndDestroy();
+ 	iInstallMachine.iGrantableCapabilitySet.SetEmpty();
+	iInstallMachine.iSecurityManager->ResetValidCertChains();
+	iInstallMachine.iOcspOutcomes.ResetAndDestroy();
+	iInstallMachine.iCertInfos.ResetAndDestroy();
+	
+	TInt64 dataOffset = iInstallMachine.CurrentController().DataOffset()-iInstallMachine.iController->DataOffset();
+	
+	// Get current controller data.
+	TPtrC8 data(iInstallMachine.iControllerData->Mid(dataOffset));
+						
+	// Verify certificate chains and prepare for OCSP.
+	iInstallMachine.iSecurityManager->VerifyControllerL(
+		data,
+		iInstallMachine.CurrentController(), 
+		&iInstallMachine.iSigValidationResult, 
+		iInstallMachine.iPkixResults,
+		iInstallMachine.iCertificates,
+		&iInstallMachine.iGrantableCapabilitySet,
+		iInstallMachine.iAllowUnsigned,
+		iInstallMachine.iEmbedded,
+		iInstallMachine.iStatus);
+
+	iInstallMachine.SetActive();
+	}
+
+// Handle signature and certificate validation errors
+CInstallMachine::TState* CInstallMachine::TVerifyControllerState::CompleteL()
+	{	
+	DEBUG_PRINTF(_L8("Install Machine - Verify Controller State Complete"));
+		
+	// Populate the cert info array in preparation for any
+	// dialogs we have to launch
+	
+	CSecurityManager::FillCertInfoArrayL(iInstallMachine.iCertificates,
+			iInstallMachine.iCertInfos);
+	
+	DEBUG_PRINTF2(_L8("Signature Validation Result is set to code %d"), iInstallMachine.iSigValidationResult);
+	
+	// check what was the result of validation
+	switch (iInstallMachine.iSigValidationResult)
+		{
+		default:
+			// BC break, unknown validation code, abort
+			User::Leave(KErrNotSupported);
+			break;
+		
+		case EValidationSucceeded:
+			// Chain was validated
+			// Increase the trust status of this install process
+			iInstallMachine.SetTrust(ESisPackageCertificateChainValidatedToTrustAnchor);
+			iInstallMachine.SetValidationStatus(EValidatedToAnchor);
+			
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			// Alert only when machine not runs in info collection mode
+			if(iInstallMachine.IsInInfoMode())
+				break;
+			#endif
+			// Continue normally, display security warning dialog so that the 
+			// UI gets certificate information.
+			// If the package is embedded, then skip notification to hide the embedding details from the user
+			if (!iInstallMachine.iEmbedded && !SecurityAlertL(ETrue))
+				User::Leave(KErrCancel); // User or UI cancelled installation.
+			break;
+				
+		case ESignatureNotPresent:
+			// This is a special case because we need to look at the policy 
+			// setting to determine if unsigned SIS files are allowed at all.
+			// Display security warning dialog.
+			{
+			
+			iInstallMachine.SetTrust(ESisPackageUnsignedOrSelfSigned);
+			iInstallMachine.SetValidationStatus(EUnsigned);   
+			
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			// Alert only when machine not runs in info collection mode
+			if(iInstallMachine.IsInInfoMode())
+				break;
+			#endif
+			
+			TBool cont = SecurityAlertL(iInstallMachine.iAllowUnsigned);
+			if (!cont || !iInstallMachine.iAllowUnsigned)
+				User::Leave(KErrSecurityError);
+
+			break;	
+			}
+		
+		case ESignatureSelfSigned:	
+			iInstallMachine.SetTrust(ESisPackageCertificateChainNoTrustAnchor);
+		    iInstallMachine.SetValidationStatus(EValidated);
+		    
+		    #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		    // Alert only when machine not runs in info collection mode
+			if(iInstallMachine.IsInInfoMode())
+				break;
+			#endif
+			if (!SecurityAlertL(ETrue))
+		    	User::Leave(KErrCancel);			
+		    break;
+		    
+		   
+        case ECertificateValidationError:
+		case ENoCertificate:
+		case ENoCodeSigningExtension:
+		case ENoSupportedPolicyExtension:
+			{
+			// Unable to validate the chain
+			// We apply the same policy as per unsigned SIS files
+			iInstallMachine.SetTrust(ESisPackageValidationFailed);	
+			iInstallMachine.SetValidationStatus(EInvalid);
+			
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			// Alert only when machine not runs in info collection mode
+			if(iInstallMachine.IsInInfoMode())
+				break;
+			#endif
+
+			// uh-oh, not good, ask the user because these are not fatal
+			TBool cont = SecurityAlertL(iInstallMachine.iAllowUnsigned);
+			if (!cont || !iInstallMachine.iAllowUnsigned)
+				User::Leave(KErrSecurityError);
+
+			break;
+			}
+			
+		case ESignatureCouldNotBeValidated:
+		case EMandatorySignatureMissing:
+            iInstallMachine.SetValidationStatus(EInvalid);
+            // we're in trouble, because these are fatal errors
+			
+			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			// Alert only when machine not runs in info collection mode
+			if(iInstallMachine.IsInInfoMode())
+				break;
+			#endif	
+
+			// coverity[unchecked_value]
+			SecurityAlertL(EFalse); // user cannot override the error
+			User::Leave(KErrSecurityError);
+
+			break;
+		}
+		
+	// All subsequent controllers will be embedded controllers	
+	iInstallMachine.iEmbedded = ETrue;		
+	
+				
+	// Devcert warning	
+	if (iInstallMachine.iSecurityManager->GetDevCertWarningState()==EFoundDevCerts
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK		
+		&& !iInstallMachine.IsInInfoMode()
+	#endif
+		)
+		{
+		// Warn only when machine runs in normal mode.
+		TAppInfo appInfo(
+			iInstallMachine.iContentProvider->DefaultLanguageAppInfoL());
+			
+		CHandleInstallEvent* cmd = CHandleInstallEvent::NewLC(appInfo, EEventDevCert, 0, KNullDesC);
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		if (!cmd->ReturnResult())
+			{
+			User::Leave(KErrSecurityError);	
+			}
+		CleanupStack::PopAndDestroy(cmd);	
+
+		//Only warn once
+		iInstallMachine.iSecurityManager->SetDevCertWarningState(EDevCertsWarned);	
+		}		
+		
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Forcibly skip the OCSP check and directly go to the prerequisites checking state when the 
+	// machine runs in component information collection mode. OCSP would introduce latency which is not expected when retrieving component info
+	if(iInstallMachine.IsInInfoMode())
+		{	
+		return static_cast<TState*>(&iInstallMachine.iCheckPrerequisitesState);
+		}
+	#endif
+
+	return static_cast<TState*>(&iInstallMachine.iOcspState);
+	}
+												
+CInstallMachine::TState* CInstallMachine::TVerifyControllerState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Verify Controller State failed with code '%d'"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TVerifyControllerState::Cancel()
+	{
+	}
+
+TBool CInstallMachine::TVerifyControllerState::SecurityAlertL(
+	TBool aCanOverride)
+	{
+	TAppInfo appInfo(
+		iInstallMachine.iCurrentContentProvider->DefaultLanguageAppInfoL());
+		
+	CDisplaySecurityWarning* cmd=CDisplaySecurityWarning::NewLC(appInfo,
+		iInstallMachine.iSigValidationResult, iInstallMachine.iPkixResults, 
+		iInstallMachine.iCertInfos, aCanOverride);
+		
+	iInstallMachine.UiHandler().ExecuteL(*cmd);
+	TBool retval=cmd->ReturnResult();
+	CleanupStack::PopAndDestroy(cmd);
+	return retval;
+	}
+
+//
+// TOcspState
+//
+
+CInstallMachine::TOcspState::TOcspState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+,	iNeedOcsp(ETrue)
+	{
+	}
+
+// Verify signatures and cert chains using security manager
+void CInstallMachine::TOcspState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering OCSP State"));
+	
+	// Determine is the check is necessary.
+	iNeedOcsp = iInstallMachine.iInstallPrefs->PerformRevocationCheck() && iInstallMachine.iSecurityManager->SecurityPolicy().OcspEnabled();
+	
+	if ((iInstallMachine.iCertificates.Count()) && iNeedOcsp)
+		{
+		// We haven't done the planning phase so we need to use the default
+		TAppInfo appInfo(iInstallMachine.iCurrentContentProvider->DefaultLanguageAppInfoL());
+
+		// Signal OCSP check starting
+		CHandleCancellableInstallEvent* cmd = CHandleCancellableInstallEvent::NewLC(appInfo, EEventOcspCheckStart, 0, KNullDesC);
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		CleanupStack::PopAndDestroy(cmd);
+		
+		// Start OCSP check.
+		TBuf8<256> ocspUri(iInstallMachine.iInstallPrefs->RevocationServerUri());
+		iInstallMachine.iSecurityManager->PerformOcspL(ocspUri, iInstallMachine.iIap,
+			&iInstallMachine.iOcspMsg,iInstallMachine.iOcspOutcomes,
+			iInstallMachine.iCertificates,iInstallMachine.iStatus);
+
+        TTime time;
+        time.UniversalTime();
+        TSisTrustStatus& trustStatus =  iInstallMachine.iController->TrustStatus();
+        trustStatus.SetLastCheckDate(time);
+		}
+	else
+		{
+		iNeedOcsp = EFalse;
+		iInstallMachine.CompleteSelf();
+		}
+	
+	iInstallMachine.SetActive();
+	}
+
+// Handle signature and certificate validation errors
+CInstallMachine::TState* CInstallMachine::TOcspState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Completed OCSP State"));
+	DEBUG_PRINTF2(_L8("OCSP Overall Message: %d"), iInstallMachine.iOcspMsg); 
+
+	TBool ocspError = EFalse;
+	for (TInt i = iInstallMachine.iOcspOutcomes.Count() - 1; i >= 0; i--)
+		{
+		DEBUG_PRINTF3(_L8("OCSP Result for chain %d - %d"), i, iInstallMachine.iOcspOutcomes[i]->iResult);
+		
+		if (iInstallMachine.iOcspOutcomes[i]->iResult != OCSP::EGood)
+			{
+			ocspError = ETrue;
+			break;
+			}
+		}
+    
+    TSisTrustStatus& trustStatus =  iInstallMachine.iController->TrustStatus();
+	
+	if (iNeedOcsp && !ocspError)
+	    {
+	    if (iInstallMachine.Trust() == ESisPackageCertificateChainValidatedToTrustAnchor)
+	    	{
+	    	iInstallMachine.SetTrust(ESisPackageChainValidatedToTrustAnchorAndOCSPValid);
+			}
+		iInstallMachine.SetRevocationStatus(EOcspGood);
+		trustStatus.SetResultDate(trustStatus.LastCheckDate());        
+		}
+	else if (iNeedOcsp && ocspError)
+		{
+
+ 		// Regenerate cert info array since cert list may have been pruned before
+ 		// OCSP check.
+ 		iInstallMachine.iCertInfos.ResetAndDestroy();
+ 		CSecurityManager::FillCertInfoArrayL(iInstallMachine.iCertificates,
+ 											iInstallMachine.iCertInfos);
+ 
+
+ 		// If OcspMandatory() is ETrue, then all OCSP errors are fatal.
+ 		TBool fatalError=iInstallMachine.iSecurityManager->SecurityPolicy().OcspMandatory() ? ETrue : EFalse;
+		switch (iInstallMachine.iOcspMsg)
+			{
+			default:
+				// Unknown value, must be a BC break!
+				User::Leave(KErrNotSupported);
+				break;
+				
+			case EResponseSignatureValidationFailure:
+			case EInvalidRevocationServerResponse:
+			case EInvalidCertificateStatusInformation:
+                iInstallMachine.SetRevocationStatus(EOcspTransient);
+				break;
+				
+			case EInvalidRevocationServerUrl:
+			case EUnableToObtainCertificateStatus:
+				// Possibly transient error, may retry.
+				if (iInstallMachine.Trust() == ESisPackageCertificateChainValidatedToTrustAnchor)
+	    			{
+					iInstallMachine.SetTrust(ESisPackageChainValidatedToTrustAnchorOCSPTransientError);
+					}
+				iInstallMachine.SetRevocationStatus(EOcspTransient);
+				break;
+			
+			case ECertificateStatusIsUnknown:
+				// Non-fatal permanent error, ask the user.
+				if (iInstallMachine.iSigValidationResult == ESignatureSelfSigned)
+					{
+					iInstallMachine.iOcspMsg = ECertificateStatusIsUnknownSelfSigned;
+					}
+				iInstallMachine.SetRevocationStatus(EOcspUnknown);
+				trustStatus.SetResultDate(trustStatus.LastCheckDate());        
+				break;
+				
+			case ECertificateStatusIsRevoked:
+				// Fatal security error, don't allow installation to proceed.
+				fatalError=ETrue;
+
+				// Install attempted with revoked certificate, reset trust
+				iInstallMachine.SetTrust(ESisPackageValidationFailed);
+				iInstallMachine.SetRevocationStatus(EOcspRevoked);
+				trustStatus.SetResultDate(trustStatus.LastCheckDate());        
+				break;
+			}
+
+		// We haven't done the planning phase so we need to use the default
+		TAppInfo appInfo(iInstallMachine.iCurrentContentProvider->DefaultLanguageAppInfoL());
+		
+	
+		// Signal OCSP check complete
+		CHandleInstallEvent* cmd = CHandleInstallEvent::NewLC(appInfo, EEventOcspCheckEnd, 0, KNullDesC);
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		
+
+		if (!cmd->ReturnResult())
+			{
+			User::Leave(KErrCancel);
+			}
+		CleanupStack::PopAndDestroy(cmd);
+		
+		// Display OCSP result dialog.
+		CDisplayOcspResult* dialogCmd=CDisplayOcspResult::NewLC(appInfo,
+			iInstallMachine.iOcspMsg,iInstallMachine.iOcspOutcomes,
+			iInstallMachine.iCertInfos,fatalError ? EFalse : ETrue);
+		iInstallMachine.UiHandler().ExecuteL(*dialogCmd);
+		
+		if (fatalError || dialogCmd->ReturnResult()==EFalse)
+			{
+			User::Leave(KErrCancel);
+			}
+		
+		CleanupStack::PopAndDestroy(dialogCmd);
+		} // else if (iNeedOcsp && ocspError)
+	else 
+	    {
+	    iInstallMachine.SetRevocationStatus(EOcspNotPerformed);
+	    }	
+	// finished verifying the controller
+	return static_cast<TState*>(&iInstallMachine.iCheckPrerequisitesState);
+	}
+												
+CInstallMachine::TState* CInstallMachine::TOcspState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - OCSP State failed with code %d"), aCode);
+	
+	
+	//If the error code is -7603 (KErrNoCertificates), handle it by popping up a warning and asking the user whether 
+	//he or she wants to continue. For any other error code leave the function.	
+	if ((OCSP::KErrNoCertificates == aCode) && !iInstallMachine.iSecurityManager->SecurityPolicy().OcspMandatory())
+		{			
+		TAppInfo appInfo(iInstallMachine.iCurrentContentProvider->DefaultLanguageAppInfoL());
+		CDisplayOcspResult* cmd=CDisplayOcspResult::NewLC(appInfo,
+				iInstallMachine.iOcspMsg, iInstallMachine.iOcspOutcomes, 
+				iInstallMachine.iCertInfos, ETrue);
+			
+		iInstallMachine.UiHandler().ExecuteL(*cmd);
+		TBool retval=cmd->ReturnResult();
+		CleanupStack::PopAndDestroy(cmd);
+		if (retval)
+			{
+			iInstallMachine.SetRevocationStatus(EOcspNotPerformed);	
+			return static_cast<TState*>(&iInstallMachine.iCheckPrerequisitesState);
+			}
+		else
+			{
+			User::Leave(aCode);
+			return NULL;		
+			}
+		}
+	else
+		{
+		User::Leave(aCode);
+		return NULL;
+		}
+	}
+
+void CInstallMachine::TOcspState::Cancel()
+	{
+	DEBUG_PRINTF(_L8("Cancelling OCSP check"));
+	iInstallMachine.iSecurityManager->Cancel();
+	}
+
+//
+// TCheckPrerequisitesState
+//
+
+CInstallMachine::TCheckPrerequisitesState::TCheckPrerequisitesState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TCheckPrerequisitesState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Prerequisites Check State"));
+
+	CPrerequisitesChecker* checker = CPrerequisitesChecker::NewLC(
+		iInstallMachine.UiHandler(), iInstallMachine.CurrentController(),
+		*iInstallMachine.iResult, *iInstallMachine.iCurrentContentProvider,
+		iInstallMachine.MainController());
+
+	checker->CheckPrerequisitesL();
+
+	CleanupStack::PopAndDestroy(checker);
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	}
+
+CInstallMachine::TState* CInstallMachine::TCheckPrerequisitesState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Completed Prerequisites Check State"));
+	return static_cast<TState*>(&iInstallMachine.iPlanInstallationState);
+	}
+	
+CInstallMachine::TState* CInstallMachine::TCheckPrerequisitesState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Prerequisites Check State failed with code %d"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TCheckPrerequisitesState::Cancel()
+	{
+	}
+	
+//
+// TPlanInstallationState
+//
+
+CInstallMachine::TPlanInstallationState::TPlanInstallationState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TPlanInstallationState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Installation Planning State"));
+	
+	// The following function may leave either because of an error or because 
+	// the user cancelled installation (a dialog), in which case it notifies 
+	// the UI so that we don't need to display anything (cancellation is not an
+	// error). See RunError() for more details.
+	
+	// used to store an array of file descriptions of the files that
+	// require capability checking
+	// This array does not OWN any of the pointers
+	RPointerArray<CFileDescription> filesToCapabilityCheck;
+	CleanupClosePushL(filesToCapabilityCheck);
+	
+	// Do the planning for the controller we just validated
+	iInstallMachine.iPlanner->PlanCurrentControllerL(filesToCapabilityCheck);	
+	
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Get the Capabilities required by the executables in the given component and set it in current controller.
+	//Setting the HasExecutable flag in the current contoller if it 
+	//contains any executable(.exe or .dll).
+	if (iInstallMachine.IsInInfoMode())
+		{
+		TCapabilitySet userGrantableCaps;
+		userGrantableCaps.SetEmpty();
+		iInstallMachine.GetRequestedCapabilities(userGrantableCaps, filesToCapabilityCheck);
+		iInstallMachine.SetUserGrantableCapabilities(userGrantableCaps);
+		
+		Sis::CController& controller = const_cast <Sis::CController&>(iInstallMachine.iPlanner->CurrentController());
+		controller.SetHasExecutable(EFalse);
+		TInt noOfFiles = filesToCapabilityCheck.Count();		
+		for(TInt i = 0 ; i < noOfFiles ; i++)
+		   {
+		   Swi::Sis::CFileDescription* fileDesc = filesToCapabilityCheck[i];
+		   const Swi::Sis::CString& filePath = fileDesc->Target();	
+		   const TDesC& path = filePath.Data();
+		   TInt pathLength = path.Length();
+		   if(pathLength < 4)
+			  continue;
+		   const TPtrC& extension = path.Mid(pathLength-4,4);					
+		   TBuf16<5> extnInLowerCase = extension;
+		   extnInLowerCase.LowerCase();
+		   if(extnInLowerCase == _L(".exe") || extnInLowerCase == _L(".dll"))
+			   {
+			   controller.SetHasExecutable(ETrue);
+			   break;
+			   }
+		    }
+		}
+	
+	#endif
+
+	// Check capabilities and ask the user to grant them if some of the user 
+	// capabilities are not signed for.
+	iInstallMachine.CheckAndGrantCapabilitiesL(filesToCapabilityCheck);
+
+ 	// Check if the Device ID is in the constraints.
+ 	iInstallMachine.CheckDeviceIdConstraintsL();
+	
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	CleanupStack::PopAndDestroy(&filesToCapabilityCheck);
+	}
+
+// The next state will be interfacing with STS
+CInstallMachine::TState* CInstallMachine::TPlanInstallationState::CompleteL()
+	{		
+	DEBUG_PRINTF(_L8("Install Machine - Completed Installation Planning State"));
+	// find the next controller to validate, otherwise go on to next stage
+	if(!iInstallMachine.iPlanner->GetNextController())
+		{
+		DEBUG_PRINTF(_L8("Finished planning final controller"));
+		
+		#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK		
+		// If the machine runs in component information extraction mode,
+		// All the needed info would have been available by this point.
+		// So, directly go to the final state and write the collected information back to the client.
+		if(iInstallMachine.IsInInfoMode())
+			{		
+			return static_cast<TState*>(&iInstallMachine.iFinalState);
+			}
+		#endif
+		
+		iInstallMachine.iPlanner->FinalisePlanL();
+		
+		iInstallMachine.iPlan=iInstallMachine.iPlanner->TransferPlanOwnership(); // pass on ownership!
+		delete iInstallMachine.iPlanner;
+		iInstallMachine.iPlanner = NULL;
+		iInstallMachine.iSecurityManager->SetDevCertWarningState(ENoDevCerts);
+		
+		if (iInstallMachine.iContentProvider != iInstallMachine.iCurrentContentProvider)
+			{
+			delete iInstallMachine.iCurrentContentProvider;
+			iInstallMachine.iCurrentContentProvider = iInstallMachine.iContentProvider;
+			}		
+        return static_cast<TState*>(&iInstallMachine.iCheckPostrequisitesState);        
+        }
+	else
+		{
+		if (iInstallMachine.iContentProvider != iInstallMachine.iCurrentContentProvider)
+			{
+			delete iInstallMachine.iCurrentContentProvider;
+
+			// In case NewL() in the following line leaves.
+			iInstallMachine.iCurrentContentProvider = NULL;
+			}
+			
+		iInstallMachine.iCurrentContentProvider = CContentProvider::NewL(iInstallMachine.CurrentController());
+		
+		return static_cast<TState*>(&iInstallMachine.iVerifyControllerState);
+		}
+	}
+
+CInstallMachine::TState* CInstallMachine::TPlanInstallationState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Planning Installation State failed with code %d"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TPlanInstallationState::Cancel()
+	{
+	}
+
+//
+// TCheckPostrequisitesState
+//
+
+CInstallMachine::TCheckPostrequisitesState::TCheckPostrequisitesState(CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TCheckPostrequisitesState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Postrequisites Check State"));
+	
+	CPostrequisitesChecker* checker =
+		CPostrequisitesChecker::NewLC(iInstallMachine.UiHandler(),
+									  *iInstallMachine.iPlan,
+									  *iInstallMachine.iResult,
+									  *iInstallMachine.iCurrentContentProvider);
+
+	checker->CheckPostrequisitesL();
+
+	CleanupStack::PopAndDestroy(checker);
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	}
+
+CInstallMachine::TState* CInstallMachine::TCheckPostrequisitesState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Completed Postrequisites Check State"));
+	// Inform UI of final progress bar value.
+	iInstallMachine.SetProgressBarFinalValueL();
+	return static_cast<TState*>(&iInstallMachine.iIntegritySupportState);
+	}
+	
+CInstallMachine::TState* CInstallMachine::TCheckPostrequisitesState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Postrequisites Check State failed with code %d"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TCheckPostrequisitesState::Cancel()
+	{
+	}
+	
+//
+// TIntegritySupportState
+//
+
+CInstallMachine::TIntegritySupportState::TIntegritySupportState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::TIntegritySupportState::EnterL()
+	{
+ 	DEBUG_PRINTF(_L8("Install Machine - Entering Integrity Support State"));
+	
+	// delete some data that we don't need while doing this memory
+	// intensive operation.
+	delete iInstallMachine.iPlanner;
+	iInstallMachine.iPlanner = NULL;
+	
+	// create an application processor
+	iInstallMachine.iProcessor = CInstallationProcessor::NewL(
+		*iInstallMachine.iPlan, *iInstallMachine.iSecurityManager, 
+		iInstallMachine.iSisHelper, iInstallMachine.UiHandler(),
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		iInstallMachine.TransactionSession(), iInstallMachine.RegistryWrapper(),
+#else
+		iInstallMachine.IntegrityServicesL(), 
+#endif
+		*iInstallMachine.iControllerData, iInstallMachine.Observer());
+	
+	// execute the plan, install files, update registry, all in one step
+	iInstallMachine.iProcessor->ProcessPlanL(iInstallMachine.iStatus);
+	iInstallMachine.SetActive();
+	}
+
+CInstallMachine::TState* CInstallMachine::TIntegritySupportState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Completed Integrity Support State"));
+	return static_cast<TState*>(&iInstallMachine.iFinalState);
+	}
+	
+CInstallMachine::TState* CInstallMachine::TIntegritySupportState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Integrity Support State failed with code %d"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TIntegritySupportState::Cancel()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Cancelling Integrity Support State"));
+	if (iInstallMachine.iProcessor)
+		{
+		iInstallMachine.iProcessor->Cancel();
+		}
+	}
+
+//
+// TFinalState
+//
+
+CInstallMachine::TFinalState::TFinalState(
+	CInstallMachine& aInstallMachine)
+:   CInstallMachine::TInstallState(aInstallMachine)
+	{
+	}
+
+void CInstallMachine::RunFileL(RSisLauncherSession& aLauncher, const TDesC& aFileName, const TDesC& aMimeType, Sis::TSISFileOperationOptions aFileOperationOption)
+	{
+	TBool wait = EFalse;
+	if (aFileOperationOption & Sis::EInstFileRunOptionWaitEnd)
+		{
+		// always wait for completion or timeout when uninstalling since 
+		// cannot remove the file when it is in use!
+		wait = ETrue;
+		}
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+	User::LeaveIfError(fs.ShareProtected());
+	
+	// Is the file an executable ?
+	TEntry entry;
+	User::LeaveIfError(fs.Entry(aFileName, entry));
+	if (entry.IsTypeValid() && SecUtils::IsExe(entry))
+		{
+		DEBUG_PRINTF2(_L("Install Machine - Running %S"),&aFileName);
+		aLauncher.RunExecutableL(aFileName, wait);
+		}
+	else 
+		{
+		RFile file;
+		CleanupClosePushL(file);				
+		if (aFileOperationOption & Sis::EInstFileRunOptionByMimeType)
+			{
+			DEBUG_PRINTF2(_L("Install Machine - Running via Mime %S"),&aFileName);
+			HBufC8* mimeType = HBufC8::NewLC(aMimeType.Length());
+			TPtr8 ptr = mimeType->Des();
+			ptr.Copy(aMimeType);
+			TRAPD(err, aLauncher.StartByMimeL(aFileName, *mimeType, wait));
+			if (err!=KErrNone) 
+				{
+				User::LeaveIfError(file.Open(fs, aFileName, EFileShareExclusive|EFileWrite));
+				TRAP_IGNORE(aLauncher.StartByMimeL(file, *mimeType, wait));
+				}
+			CleanupStack::PopAndDestroy(mimeType);		
+			}
+		else
+			{
+			DEBUG_PRINTF2(_L("Install Machine - Launching doc %S"),&aFileName);
+			TRAPD(err, aLauncher.StartDocumentL(aFileName, wait));		
+			if (err!=KErrNone)
+				{
+				User::LeaveIfError(file.Open(fs, aFileName, EFileShareExclusive|EFileWrite));
+				TRAP_IGNORE(aLauncher.StartDocumentL(file, wait));	
+				}
+			}
+		CleanupStack::PopAndDestroy(&file);		
+		}
+	CleanupStack::PopAndDestroy(&fs);
+	}
+
+void CInstallMachine::PublishPropertiesL()
+	{
+	User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidSoftwareInstallKey, ESwisStatusSuccess | ESwisInstall));
+		
+	// Store the top level controller's UID as the most recent successful installation
+	User::LeaveIfError(RProperty::Set(KUidSystemCategory, KUidSwiLatestInstallation, iController->Info().Uid().Uid().iUid));
+	}
+    
+void CInstallMachine::PostJournalFinalizationL(TInt aError)
+	{
+	DEBUG_PRINTF(_L8("Install Machine - PostJournalFinalization"));
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Do nothing in info mode
+	if(IsInInfoMode())
+		{
+		return;
+		}
+#endif
+	if (!iPlan)
+		{
+		return;
+		}
+	const RPointerArray<CSisRegistryFileDescription>& filesToRun = iPlan->FilesToRunAfterInstall();
+
+	TInt numFiles = filesToRun.Count();
+	
+	if (aError != KErrNone || numFiles <= 0)
+		{
+		return;
+		}
+	
+	// Check the top level application, if it's not trusted and the policy says no
+	// then don't run anything.
+	CSecurityPolicy* secPolicy = CSecurityPolicy::GetSecurityPolicyL();
+	if (!secPolicy->AllowRunOnInstallUninstall() && 
+			iPlan->ApplicationL().ControllerL().TrustStatus().ValidationStatus() < EValidatedToAnchor)
+		{
+		DEBUG_PRINTF(_L8("Install Machine - Toplevel controller is untrusted, not running files after install"));
+		return;
+		}
+	
+	DEBUG_PRINTF(_L8("Install Machine - Processing files to run after install"));
+	RSisLauncherSession launcher;
+	
+	if (launcher.Connect() != KErrNone)
+		{
+		DEBUG_PRINTF(_L8("Install Machine - Failed to connect to SisLauncher, continuing..."));
+		return;
+		}
+	CleanupClosePushL(launcher);
+	launcher.NotifyNewAppsL(iPlan->AppArcRegFiles());
+
+	if (iPlan->ContainsPlugins())
+
+		{
+		// set the "I'm done" propererty AFTER running ECOM reliant files.
+		launcher.RunAfterEcomNotificationL(filesToRun);
+		RProperty::Set(KUidSystemCategory, KUidSoftwareInstallKey, ESwisNone);
+		}
+	else
+		{
+		// set the "I'm done" propererty before running non-ECOM reliant files.
+		RProperty::Set(KUidSystemCategory, KUidSoftwareInstallKey, ESwisNone);
+		for (int i = 0; i < numFiles; ++i)
+			{
+			CSisRegistryFileDescription* file = filesToRun[i];
+			RunFileL(launcher,file->Target(),file->MimeType(),file->OperationOptions());
+			} 
+		}
+	CleanupStack::PopAndDestroy(&launcher);
+	}
+
+ void CInstallMachine::TFinalState::EnterL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Entering Final State"));
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// If the machine runs in component information extraction mode,
+	// All the needed info would have been available by this point.
+	// So, call the method to populate the details back to the given structure
+	// and go to the final state of the machine.
+	if(iInstallMachine.IsInInfoMode())
+		{
+		DEBUG_PRINTF(_L8("Install Machine - Returning component info"));
+		// Call in to populate the native component info in to the given structure.
+		PopulateNativeComponentInfoL(iInstallMachine.MainController(), iInstallMachine.iNativeComponentInfo);
+		
+		// Write the component information collected back in to the buffer passed in.
+		SendBackComponentInfoL();
+		}
+	else
+	#endif
+		{
+        iInstallMachine.PublishPropertiesL();
+		
+		if (iInstallMachine.iSecurityManager->SecurityPolicy().DrmEnabled())
+			{
+			DEBUG_PRINTF(_L8("Attempting to access (possibly) DRM'd SIS file via CAF"));
+			iInstallMachine.iSisHelper.ExecuteDrmIntentL(static_cast<ContentAccess::TIntent>(iInstallMachine.iSecurityManager->SecurityPolicy().DrmIntent()));
+			}
+		}
+	
+	iInstallMachine.CompleteSelf();
+	iInstallMachine.SetActive();
+	}
+    
+CInstallMachine::TState* CInstallMachine::TFinalState::CompleteL()
+	{
+	DEBUG_PRINTF(_L8("Install Machine - Completed Final State"));
+	return NULL;
+	}
+	
+CInstallMachine::TState* CInstallMachine::TFinalState::ErrorL(
+	TInt aCode)
+	{
+	DEBUG_PRINTF2(_L8("Install Machine - Final State failed with code %d"), aCode);
+	User::Leave(aCode);
+	return NULL;
+	}
+
+void CInstallMachine::TFinalState::Cancel()
+	{
+	}
+
+//
+// TControllerInfo
+//
+
+CInstallMachine::TControllerInfo::TControllerInfo(
+	const CController& aController, TInt64 aDataOffset)
+	: iController(aController), iDataOffset(aDataOffset)
+	{
+	}
+			
+const CController& CInstallMachine::TControllerInfo::Controller() const
+	{
+	return iController;
+	}
+			
+TInt64 CInstallMachine::TControllerInfo::DataOffset() const
+	{
+	return iDataOffset;
+	}
+
+//
+// CInstallMachine
+//
+
+CInstallMachine* CInstallMachine::NewLC(const RMessage2& aMessage)
+	{
+	CInstallMachine* self=new(ELeave) CInstallMachine(aMessage);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallMachine* CInstallMachine::NewLC(const RMessage2& aMessage, const TBool aInInfoMode)
+	{
+	CInstallMachine* self=new(ELeave) CInstallMachine(aMessage, aInInfoMode);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+#endif
+
+CInstallMachine* CInstallMachine::NewL(const RMessage2& aMessage)
+	{
+	CInstallMachine* self=NewLC(aMessage);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallMachine* CInstallMachine::NewL(const RMessage2& aMessage,const TBool aInInfoMode)
+	{
+	CInstallMachine* self=NewLC(aMessage, aInInfoMode);
+	CleanupStack::Pop(self);
+	return self;
+	}
+#endif
+
+void CInstallMachine::ConstructL()
+	{
+	DEBUG_PRINTF(_L8("Constructing new Install Machine"));
+
+	// connect to SIS helper before we start a transaction with transaction server
+	// so that long running rollbacks don't cause install to fail
+	User::LeaveIfError(iSisHelper.Connect());
+	
+	// Construct base class ( transaction)
+	CSwisStateMachine::ConstructL();
+		
+	// Read install preferences from the stream (they are passed in the 
+	// message's parameter 0)
+	TInt len=Message().GetDesLengthL(0);
+	HBufC8* buf=HBufC8::NewMaxLC(len);
+	TPtr8 p=buf->Des();
+	Message().ReadL(0,p);
+	RMemReadStream is;
+	is.Open(p.Ptr(),len);
+	CleanupClosePushL(is);
+	iInstallPrefs=CInstallPrefs::NewL(is);
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK   
+	if(!IsInInfoMode()) 
+         { 
+	#endif 
+         TInt deviceLanguageCount = is.ReadInt32L(); 
+         for(TInt i=0;i<deviceLanguageCount;i++) 
+        	 { 
+        	 iDeviceSupportedLanguages.AppendL(is.ReadInt32L()); 
+        	 DEBUG_PRINTF2(_L8("Language id that device supports =  %d"), iDeviceSupportedLanguages[i]); 
+        	 } 
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK   
+         } 
+	iNativeComponentInfo = CNativeComponentInfo::NewL();   
+	#endif 
+	
+	CleanupStack::PopAndDestroy(2,buf); // is, buf
+
+	// Create security manager here because we'll need its functionality very 
+	// early to display certificates to the user in the Install dialog (see 
+	// TConfirmationState::EnterL()).
+	iSecurityManager=CSecurityManager::NewL();
+	}
+	
+// Constructor, sets this pointer into the state objects
+CInstallMachine::CInstallMachine(const RMessage2& aMessage)
+:   CSwisStateMachine(aMessage),
+	iRegistrationState(*this),
+	iGetControllerState(*this),
+	iConfirmationState(*this),
+	iVerifyControllerState(*this),
+	iOcspState(*this),
+	iCheckPrerequisitesState(*this),
+    iPlanInstallationState(*this),
+    iCheckPostrequisitesState(*this),
+    iIntegritySupportState(*this),
+    iFinalState(*this),
+	iSigValidationResult(EValidationSucceeded),
+	iEmbedded(EFalse)
+	{
+	}
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallMachine::CInstallMachine(const RMessage2& aMessage,const TBool aInInfoMode)
+:   CSwisStateMachine(aMessage, aInInfoMode),
+	iRegistrationState(*this),
+	iGetControllerState(*this),
+	iConfirmationState(*this),
+	iVerifyControllerState(*this),
+	iOcspState(*this),
+	iCheckPrerequisitesState(*this),
+    iPlanInstallationState(*this),
+    iCheckPostrequisitesState(*this),
+    iIntegritySupportState(*this),
+    iFinalState(*this),
+	iSigValidationResult(EValidationSucceeded),
+	iEmbedded(EFalse)
+	{
+	
+	}
+#endif
+// Connects to UISS and SISHelper server
+TInt CInstallMachine::Start()
+	{
+	DEBUG_PRINTF(_L8("Starting Install"));
+	return CSwisStateMachine::Start();
+	}
+
+// Delete objects, close connection to the servers
+CInstallMachine::~CInstallMachine()
+	{
+	DEBUG_PRINTF(_L8("Destroying Install Machine"));
+	
+	if (iCurrentContentProvider != iContentProvider)
+		{
+		delete iCurrentContentProvider;
+		}
+		
+	delete iInstallPrefs;
+	delete iControllerData;
+	delete iController;
+	delete iContentProvider;
+	delete iPlan;
+	delete iResult;
+	delete iProcessor;
+	delete iSecurityManager;
+	iPkixResults.ResetAndDestroy();
+	iCertificates.ResetAndDestroy();
+	iCertInfos.ResetAndDestroy();
+	iOcspOutcomes.ResetAndDestroy();
+	iSisHelper.Close();
+	iDeviceSupportedLanguages.Close();
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	delete iNativeComponentInfo;
+	#endif
+	delete iPlanner;
+	}
+
+CInstallMachine::TState* CInstallMachine::FirstState()
+	{
+	return &iRegistrationState;
+	}
+
+// This is called from RunL() whenever a state leaves
+CInstallMachine::TState* CInstallMachine::ErrorOnStateEntryL(TInt aError)
+	{
+	return CurrentState()->ErrorL(aError);
+	}
+
+void CInstallMachine::GetRequestedCapabilities(TCapabilitySet& aRequestedCaps, RPointerArray<CFileDescription>& aFilesToCapabilityCheck)
+	{
+	// UserPromptService private directory
+	_LIT(KUpsPrivateDir, ":\\private\\10283558\\");	
+	
+	TInt numFiles = aFilesToCapabilityCheck.Count();
+	for (TInt i=0; i<numFiles; i++)
+		{
+		const CFileDescription* fd = aFilesToCapabilityCheck[i];
+		const CCapabilities* caps = fd->Capabilities();
+		
+		// Prevent un-authorised modification to User Prompt Service Policy Files
+		if (fd->Target().Data().FindF(KUpsPrivateDir) != KErrNotFound)
+			{
+			DEBUG_PRINTF2(_L("Install Machine - Found %S: Appending AllFiles capability"), &fd->Target().Data());
+			aRequestedCaps.AddCapability(ECapabilityAllFiles);
+			}		
+		
+		if (!caps)
+			continue;
+
+		const TInt KCapSetSize=sizeof(TUint32); // size of a capability bit set
+		const TInt KCapSetSizeBits=8*KCapSetSize;
+		const TDesC8& rawCaps=caps->Data();
+		const TInt KNumCapSets=rawCaps.Size()/KCapSetSize;
+		for (TInt set=0; set<KNumCapSets; set++)
+			{
+			TUint32 capsValue=*(reinterpret_cast<const TUint32*>(rawCaps.Ptr())+set);
+			for (TInt capIndex=0; capIndex<KCapSetSizeBits; capIndex++)
+				{
+				if (capsValue & (0x1<<capIndex))
+					{
+					TCapability cap=static_cast<TCapability>(capIndex+set*KCapSetSizeBits);
+					aRequestedCaps.AddCapability(cap);
+					}
+				}
+			}
+		}	
+	}
+
+// This is called from TVerifyControllerState::CompleteL()
+void CInstallMachine::CheckAndGrantCapabilitiesL(RPointerArray<CFileDescription>& aFilesToCapabilityCheck)
+	{
+	// The controller contains capabilities requested by all 
+	// executables in it. Let's make a union of them all.
+	TCapabilitySet requestedCaps;
+	requestedCaps.SetEmpty();
+	
+	// Get the set of capabilities required by the package.
+	GetRequestedCapabilities(requestedCaps, aFilesToCapabilityCheck);
+		
+	//Get the CertChainConstraint instance built by the SecurityManager.
+	const CCertChainConstraints* certChainConstraints = CurrentController().CertChainConstraints();
+				
+	//Get the capbibilies contrained from the CertChainConstraints
+	TCapabilitySet initCapConstraints=certChainConstraints->ValidCapabilities();
+	TCapabilitySet supportedCapabilitiesByBoth=initCapConstraints;
+
+	//build the capability constraints from the constrained capabilities and root capbilities
+	supportedCapabilitiesByBoth.Intersection(iGrantableCapabilitySet);
+
+  	// We have a set of granted capabilities, which is the intersection of iCapabilitySet  and 
+  	// Capbilities constraints(filled in the security manager).
+  	// Let's see if that's enough for the files to be installed.
+  	requestedCaps.Remove(supportedCapabilitiesByBoth);
+  	
+  	// Remove capabilities granted by the loader i.e disabled capabilities
+  	TCapabilitySet loaderGrantedCaps;
+  	loaderGrantedCaps.SetDisabled();
+  	requestedCaps.Remove(loaderGrantedCaps);
+	
+  	// Any capabilities left in requestedCaps after this are not signed for and not in the certs constraints. 
+	// Check if any of them are system capabilities. If so, bail out.
+  	TCapabilitySet requiredExtraSysCaps(requestedCaps);
+  	SecurityCheckUtil::RemoveUserCaps(requiredExtraSysCaps, *iSecurityManager);
+	TAppInfo appInfo(iCurrentContentProvider->DefaultLanguageAppInfoL()); 
+	
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Report the error to the user only when machine not runs in info collection mode
+	if(IsInInfoMode())
+		{
+		SetUserGrantableCapabilities(requestedCaps);
+		return;
+		}
+	#endif
+
+	if (SecurityCheckUtil::NotEmpty(requiredExtraSysCaps)||(SecurityCheckUtil::NotEmpty(requestedCaps) && EFalse==iSecurityManager->SecurityPolicy().AllowGrantUserCaps()))
+		{
+		// Report error to the user. Include the list of capabilities that are left in requestedCaps.
+		// Among these will be at least one cap that is not allowed. This is because 
+		// - it is a system cap which hasn't been granted or 
+		// - a user cap where granting of user caps during install is not allowed. 
+
+		// Build requested capabilities string.
+		const TInt KMaxCapNameLength=32; // should be enough for one capability name and
+										 // a space before the next capability name
+							  
+		HBufC* capsDisplayBuf=HBufC::NewLC(ECapability_Limit*KMaxCapNameLength);
+		TPtr p=capsDisplayBuf->Des();
+		_LIT(KSpace," "); 
+  
+		// Loop through the set of all possible capabilities. Check if each
+		// is in the requestedCaps set. If it is add the name of the 
+		// capability to the string in the capsDisplayBuf
+		for (TInt cap=ECapabilityTCB; cap<ECapability_Limit; cap++)
+			{ 
+			if (requestedCaps.HasCapability(static_cast<TCapability>(cap)))
+				{
+				// Get the string name for the capability
+				const char* capName = CapabilityNames[cap];
+				while (*capName)
+					{
+					p.Append(*capName++);
+					}			
+		
+				// Add a space following each capability name in string
+				p.Append(KSpace);
+				}
+			}
+			
+		// Report error to the user.
+		// Include the list of capability names 
+		CDisplayError* cmd=
+			CDisplayError::NewLC(appInfo,EUiCapabilitiesCannotBeGranted,
+			*capsDisplayBuf);		
+				
+		UiHandler().ExecuteL(*cmd);
+		CleanupStack::PopAndDestroy(cmd);
+		CleanupStack::PopAndDestroy(capsDisplayBuf);
+		User::Leave(KErrSecurityError);			
+		}
+	else if (SecurityCheckUtil::NotEmpty(requestedCaps)) //Required more user capabilities then
+		{
+		// User capabilities are supported by the CertChainConstraints, but not by root certificates.
+		if (initCapConstraints.HasCapabilities(requestedCaps))
+		{
+		// User capabilities only, ask the user to grant them
+		CDisplayGrantCapabilities* cmd=
+			CDisplayGrantCapabilities::NewLC(appInfo,requestedCaps);
+		UiHandler().ExecuteL(*cmd);
+		TBool result=cmd->ReturnResult();
+		CleanupStack::PopAndDestroy(cmd);
+		if (!result)
+			User::Leave(KErrSecurityError);
+		}
+		else
+			{
+			// User capabilities are not all supported by the CertChainConstraints.
+			CDisplayError* cmd=
+				CDisplayError::NewLC(appInfo,EUiConstraintsExceeded,
+				KNullDesC);
+			UiHandler().ExecuteL(*cmd);
+			CleanupStack::PopAndDestroy(cmd);			
+			User::Leave(KErrSecurityError);		
+			}
+		}
+    }
+
+void CInstallMachine::SignalCompletedL()
+	{
+	HandleInstallationEventL(iPlan, EEventCompletedInstall);
+	}
+	
+void CInstallMachine::SetTrust(TSisPackageTrust aTrust)
+	{
+	DEBUG_PRINTF2(_L8("Package Trust Status set to %d"), aTrust);
+	
+	// create a modifyable reference to the current controller
+	CController& controller = const_cast <CController&>
+						      (CurrentController());
+	
+	// set the trust
+	controller.SetTrust(aTrust);
+	}
+
+TSisPackageTrust CInstallMachine::Trust()
+	{
+	
+	CController& controller = const_cast <CController&>
+						      (CurrentController());
+	return controller.Trust();						      
+
+	}
+
+void CInstallMachine::SetValidationStatus(TValidationStatus status)
+    {
+	// set the validation status
+	CurrentController().TrustStatus().SetValidationStatus(status);
+    }
+    
+void CInstallMachine::SetRevocationStatus(TRevocationStatus status)
+    {
+	// set the revocation status
+	CurrentController().TrustStatus().SetRevocationStatus(status);
+    }
+    
+void CInstallMachine::CheckDeviceIdConstraintsL()
+	{
+ 	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ 	// Report the error to the user only when machine not runs in info collection mode
+	if(IsInInfoMode())
+		return;
+	#endif			
+	
+	const CCertChainConstraints* certChainConstraints = CurrentController().CertChainConstraints();
+			
+	const RPointerArray<HBufC>& deviceIDs=iSecurityManager->DeviceIDsInfo();	
+ 	TRAPD(err, SecurityCheckUtil::CheckDeviceIdConstraintsL(certChainConstraints, deviceIDs));
+ 	
+	if (err)
+		{
+		TAppInfo appInfo(iCurrentContentProvider->DefaultLanguageAppInfoL());
+		CDisplayError* cmd=
+			CDisplayError::NewLC(appInfo,EUiConstraintsExceeded,
+			KNullDesC);
+		UiHandler().ExecuteL(*cmd);
+		CleanupStack::PopAndDestroy(cmd);
+		User::Leave(KErrSecurityError);					
+		}	
+	}
+
+const Sis::CController& CInstallMachine::CurrentController()
+	{
+	return iPlanner->CurrentController();
+	}
+
+const Sis::CController& CInstallMachine::MainController()
+	{
+	return iPlanner->MainController();
+	}
+
+void CInstallMachine::SetProgressBarFinalValueL()
+	{
+	HandleInstallationEventL(iPlan, EEventSetProgressBarFinalValue, iPlan->FinalProgressBarValue());
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK	
+	SetFinalProgressBarValue(iPlan->FinalProgressBarValue());
+	#endif
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+// Populate the native component information.
+void CInstallMachine::TFinalState::PopulateNativeComponentInfoL(const CController& aController, CNativeComponentInfo* aNativeComponentInfo)
+	{	
+	const Sis::CController& controller(aController);
+	const Sis::CInfo& controllerInfo(controller.Info());
+	const TDesC& componentName((controllerInfo.Names()[0])->Data());
+	// Set the Component Name attribute.	
+	aNativeComponentInfo->iComponentName = HBufC::NewL(componentName.Length());
+	TPtr bufPtr(aNativeComponentInfo->iComponentName->Des());	
+	bufPtr.Copy(componentName);
+		
+	// Set the Component Version details.
+	TVersion version(controllerInfo.Version().Major(),
+					 controllerInfo.Version().Minor(),
+					 controllerInfo.Version().Build());	
+	TBuf<KSmlBufferSize> versionBuf;	
+	versionBuf.AppendFormat(KVersionFormat, version.iMajor, version.iMinor, version.iBuild);
+	aNativeComponentInfo->iVersion = HBufC::NewL(versionBuf.Length());
+	bufPtr.Set(aNativeComponentInfo->iVersion->Des());
+	bufPtr.Copy(versionBuf);
+	
+	// Set the Vendor Name attribute	
+	const TDesC& vendorName(controllerInfo.VendorNames()[0]->Data());
+	aNativeComponentInfo->iVendor = HBufC::NewL(vendorName.Length());
+	bufPtr.Set(aNativeComponentInfo->iVendor->Des());
+	bufPtr.Copy(vendorName);
+	
+	// Set the gloabl component Id
+	aNativeComponentInfo->iGlobalComponentId = FormatGlobalIdLC(controllerInfo.Uid().Uid(), componentName, controllerInfo.InstallType());
+	// It's already a member of the class. So, don't keep it in the cleanup stack, pop it out.
+	CleanupStack::Pop(aNativeComponentInfo->iGlobalComponentId);
+		
+	// Initially assume component is not installed (so, id is 0) and the scomo state to be deactivated
+	aNativeComponentInfo->iComponentId = 0;
+	aNativeComponentInfo->iScomoState = Usif::EDeactivated;
+	
+	// Connect to the SCR.
+	Usif::RSoftwareComponentRegistry scrSession;
+	User::LeaveIfError(scrSession.Connect());
+	CleanupClosePushL(scrSession);
+	
+	// Find and set the install status.	
+	PopulateInstallStatusL(aController, scrSession, aNativeComponentInfo);
+		
+	// Get the actual component ID and the SCOMO state if the component entry is found in the SCR
+	if ((aNativeComponentInfo->iInstallStatus == Usif::EUpgrade) || 
+		(aNativeComponentInfo->iInstallStatus == Usif::EAlreadyInstalled) ||
+		(aNativeComponentInfo->iInstallStatus == Usif::ENewerVersionAlreadyInstalled))
+		{
+		Usif::CComponentEntry* componentEntry = NULL;
+		// Get the component entry using the global Id and the software type.
+		TRAPD(err, componentEntry = scrSession.GetComponentL(*(aNativeComponentInfo->iGlobalComponentId), Usif::KSoftwareTypeNative));
+		if (err == KErrNone)
+			{			
+			aNativeComponentInfo->iComponentId = componentEntry->ComponentId();
+			aNativeComponentInfo->iScomoState = static_cast<Usif::TScomoState>(componentEntry->ScomoState());
+			delete componentEntry;
+			}
+		}
+
+	CleanupStack::PopAndDestroy(&scrSession);
+	
+	// Set the authenticity info based on the validation status.
+	if (controller.TrustStatus().ValidationStatus() >= EValidatedToAnchor)
+		{
+		aNativeComponentInfo->iAuthenticity = Usif::EAuthenticated;
+		}
+	else
+		{
+		aNativeComponentInfo->iAuthenticity = Usif::ENotAuthenticated;
+		}
+		
+	// Set the user grantable capabilities
+	aNativeComponentInfo->iUserGrantableCaps = const_cast<CController&>(aController).UserGrantableCapabilities();
+	
+	// Calculate the component size from the sontroller's file descriptions.
+	const RPointerArray<CFileDescription>& fileDescriptions = controller.InstallBlock().FileDescriptions();
+	for(TInt i = 0; i < fileDescriptions.Count(); i++)
+		{
+		aNativeComponentInfo->iMaxInstalledSize += fileDescriptions[i]->UncompressedLength();
+		}
+	
+	//Setting the HasExecutable flag
+	aNativeComponentInfo->iHasExe = controller.HasExecutable();
+	
+	const RPointerArray<CController>& embeddedControllers = aController.InstallBlock().EmbeddedControllers();
+	TInt totalEmbeddedControllers = embeddedControllers.Count();
+	for (TInt controller = 0; controller < totalEmbeddedControllers; controller++)
+		{
+		CNativeComponentInfo* infoNode = CNativeComponentInfo::NewLC();
+		PopulateNativeComponentInfoL(*embeddedControllers[controller], infoNode);
+		aNativeComponentInfo->iChildren.AppendL(infoNode);
+		CleanupStack::Pop(infoNode);
+		}	
+	}
+	
+// Populate the install state based on its earlier installation on the device.
+void CInstallMachine::TFinalState::PopulateInstallStatusL(const CController& aController, Usif::RSoftwareComponentRegistry& aScrSession, CNativeComponentInfo* aNativeComponentInfo)
+	{
+	const Sis::CInfo& controllerInfo(aController.Info());		
+	const TDesC& componentName((controllerInfo.Names()[0])->Data());
+	const TDesC& uniqueVendorName(controllerInfo.UniqueVendorName().Data());
+	TInstallType installType = controllerInfo.InstallType();
+
+	// As PA and PP packages are not support for getting component info, we check for them here
+	__ASSERT_ALWAYS(installType != EInstPreInstalledApp && installType != EInstPreInstalledPatch, User::Leave(KErrNotSupported));
+	
+	// Check to see if there is a package installed with this UID.
+	RSisRegistryWritableSession registrySession;
+	User::LeaveIfError(registrySession.Connect());
+	CleanupClosePushL(registrySession);	
+	
+	RSisRegistryWritableEntry registryEntry;
+	// Open the registry entry using the package name and vendor name.
+	TInt error = registryEntry.Open(registrySession, componentName, uniqueVendorName);		
+	if (error != KErrNone && error != KErrNotFound)
+		User::Leave(error);
+	CleanupClosePushL(registryEntry);
+	
+	TInt versionComparision = 0;
+	
+	// Registry entry found
+	if (error == KErrNone)
+		{
+		// Take the versions of the installed package and the new package
+		TVersion regVer = registryEntry.VersionL();		
+		TVersion newVer(controllerInfo.Version().Major(),
+				 controllerInfo.Version().Minor(),
+				 controllerInfo.Version().Build());
+				 
+		TBuf<KSmlBufferSize> regVersion;
+		TBuf<KSmlBufferSize> newVersion;		
+		regVersion.AppendFormat(KVersionFormat, regVer.iMajor, regVer.iMinor, regVer.iBuild);
+		newVersion.AppendFormat(KVersionFormat, newVer.iMajor, newVer.iMinor, newVer.iBuild);
+		
+		// Compare versions of the already installed package and the current package.
+		versionComparision = aScrSession.CompareVersionsL(regVersion, newVersion);
+		
+		// If both the versions are equal, say that, the same package is installed already
+		if (versionComparision == 0)
+			{
+			aNativeComponentInfo->iInstallStatus = Usif::EAlreadyInstalled;
+			}
+		// If the version installed is higher than the current version, say that, higher version is already installed.
+		else if (versionComparision > 0)
+			{
+			aNativeComponentInfo->iInstallStatus = Usif::ENewerVersionAlreadyInstalled;
+			}
+		// If the version installed is lower than the current version, say that, this is an upgrade.
+		else  // versionComparision < 0
+			{
+			aNativeComponentInfo->iInstallStatus = Usif::EUpgrade;
+			}
+		}
+	// If the registry entry is not found and the current package is a type 
+	// of base (SA or PA) package, say that, it's a new installation.
+	else if (installType == EInstInstallation)
+		{
+		aNativeComponentInfo->iInstallStatus = Usif::ENewComponent;
+		}
+	// If the registry entry is not found and the current package is a type 
+	// of partial upgrade (PU) package, say that, it's invalid because of the missing base.
+	else if (installType == EInstPartialUpgrade)
+		{
+		aNativeComponentInfo->iInstallStatus = Usif::EInvalid;
+		}
+	else if (installType == EInstAugmentation)
+		{		
+		// Get the component entry from SCR using the base package's globalId (UID). If the entry exists, the base package is installed.
+		// So, say the current component will become a new component. If the entry is not found in SCR, the base package is not installed.
+		// So, say the current component will become invalid (as the base is missing).
+		Usif::CComponentEntry* componentEntry = NULL;
+		HBufC* globalId = FormatGlobalIdLC(controllerInfo.Uid().Uid(), componentName, EInstInstallation);
+		componentEntry = aScrSession.GetComponentL(*globalId, Usif::KSoftwareTypeNative);
+		if (componentEntry != NULL)		
+			{
+			aNativeComponentInfo->iInstallStatus = Usif::ENewComponent;
+			}
+		else
+			{	
+			aNativeComponentInfo->iInstallStatus = Usif::EInvalid;
+			}
+		CleanupStack::PopAndDestroy(globalId);
+		delete componentEntry;
+		}	
+	CleanupStack::PopAndDestroy(2, &registrySession);
+	}
+
+void CInstallMachine::TFinalState::SendBackComponentInfoL()
+	{		
+	const static TInt KDefaultBufferSize = 2048;
+	
+	TInt err = KErrNone;
+	TInt streamBufSize = KDefaultBufferSize;
+	CBufFlat* tempBuffer = NULL;
+	RBufWriteStream stream;
+	do
+		{
+		tempBuffer = CBufFlat::NewL(streamBufSize);
+		CleanupStack::PushL(tempBuffer);
+		
+		stream.Open(*tempBuffer);
+		CleanupClosePushL(stream);		
+	
+		// Externalise the component info in to the stream		
+		TRAP(err, iInstallMachine.iNativeComponentInfo->ExternalizeL(stream));
+		if (err == KErrOverflow)
+			{
+			// Release the last allocation and re allocate with one more fold
+			CleanupStack::PopAndDestroy(2, tempBuffer); // tempBuffer, stream
+			streamBufSize += KDefaultBufferSize;
+			}			
+		} while(err == KErrOverflow);
+		
+	stream.CommitL();
+
+	// Create an HBufC8 from the stream buf's length, and copy 
+	// the stream buffer into this descriptor
+	HBufC8* buffer = HBufC8::NewLC(tempBuffer->Size());
+	TPtr8 ptr(buffer->Des());
+	tempBuffer->Read(0, ptr, tempBuffer->Size());
+		    	    
+    // Comp info buffer in the IPC args is in 2nd position. So, the index will be 1 (starts at 0).
+    TInt compInfoBufIndex = 1;
+    TInt argBufMaxLength = iInstallMachine.Message().GetDesMaxLengthL(compInfoBufIndex);
+    TInt localBufSize = buffer->Size();
+    
+    // If the allocation is insufficient for sending back the data, send the Over-Flow message to the client.
+    // client will re-allocate the required amount of memory and will issue the request again.
+	if ( argBufMaxLength < localBufSize)
+		{			
+		DEBUG_PRINTF3(_L8("Discovered overflow in component info buffer - needed %d but only %d was available"),
+			localBufSize, argBufMaxLength);
+		TPckgC<TInt> bufferSizePackage(localBufSize);
+		iInstallMachine.Message().WriteL(compInfoBufIndex, bufferSizePackage);
+		User::Leave(KErrOverflow);
+		}
+	// If the memory is sufficient, write the details back in to the client allocated memory.
+	else
+		{
+		iInstallMachine.Message().WriteL(compInfoBufIndex, *buffer);
+		}
+	CleanupStack::PopAndDestroy(3, tempBuffer); // tempBuffer, stream, buffer		
+	}
+	
+void CInstallMachine::SetUserGrantableCapabilities(TCapabilitySet aCapabilitySet)
+	{
+	DEBUG_PRINTF(_L8("Setting Package's User Granted Capabilities"));
+	
+	// create a modifyable reference to the current controller
+	CController& controller = const_cast<CController&>(CurrentController());
+	
+	// set the capabilities
+	controller.SetUserGrantableCapabilities(aCapabilitySet);
+	}
+#endif