installationservices/swi/source/swis/server/installationprocessor.cpp
changeset 0 ba25891c3a9e
child 25 98b66e4fb0be
child 65 7333d7932ef7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/swis/server/installationprocessor.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1346 @@
+/*
+* Copyright (c) 1997-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: 
+* Application Processor.
+*
+*/
+
+
+/**
+ @file 
+ @released
+ @internalTechnology 
+*/
+
+#include <hash.h>
+#include "installationprocessor.h"
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <usif/sts/sts.h>
+#include "swtypereginfo.h"
+#include "installswtypehelper.h"
+#else
+#include "integrityservices.h"
+#endif
+
+#include "sisregistryentry.h"
+#include "sishelperclient.h"
+#include "sisregistryfiledescription.h"
+#include "sisregistrypackage.h"
+#include "sisstring.h"
+#include "hashcontainer.h"
+#include "siscontroller.h"
+#include "application.h"
+#include "userselections.h"
+#include "log.h"
+#include "secutils.h"
+#include "sisuihandler.h"
+#include "filesisdataprovider.h"
+#include "securitymanager.h"
+#include "securitypolicy.h"
+#include "sislauncherclient.h"
+#include "sisinfo.h"
+#include "sisuid.h"
+#include "plan.h"
+#include "sidcache.h"
+#include "sistruststatus.h"
+#include "securitycheckutil.h"
+#include "sisfieldtypes.h"
+#include "progressbar.h"
+#include "fileextractor.h"
+#include "securitycheckutil.h"
+
+using namespace Swi;
+
+
+_LIT(KApparcRegDir, "\\private\\10003a3f\\import\\apps\\");
+_LIT(KSisExt, ".sis");
+
+
+const TInt KSwiDaemonUid = 0x10202DCE;
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager, 
+	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
+	Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
+	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	{
+	CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan, 
+		aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper, 
+		aControllerData, aObserver);
+	CleanupStack::Pop(self);
+	return self;
+	}
+#else
+CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager, 
+	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
+	CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	{
+	CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan, 
+		aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
+	CleanupStack::Pop(self);
+	return self;
+	}
+#endif
+
+CInstallationProcessor* CInstallationProcessor::NewL(CInstallationProcessor& aProcessor)
+	{
+	CInstallationProcessor* self = CInstallationProcessor::NewLC(aProcessor.Plan(), 
+		aProcessor.iSecurityManager, aProcessor.iSisHelper, aProcessor.UiHandler(), 
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		aProcessor.TransactionSession(), aProcessor.iRegistryWrapper,
+#else
+		aProcessor.IntegrityServices(),
+#endif
+		aProcessor.iControllerData, aProcessor.Observer());
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor* CInstallationProcessor::NewLC(
+	const CPlan& aPlan, CSecurityManager &aSecurityManager, 
+	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
+	Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
+	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	{
+	CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan, 
+		aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper, 
+		aControllerData, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+#else
+CInstallationProcessor* CInstallationProcessor::NewLC(
+	const CPlan& aPlan, CSecurityManager &aSecurityManager, 
+	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
+	CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	{
+	CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan, 
+		aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+#endif
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan, 
+	CSecurityManager &aSecurityManager, RSisHelper& aSisHelper, 
+	RUiHandler& aUiHandler, Usif::RStsSession& aStsSession, 
+	CRegistryWrapper& aRegistryWrapper,
+	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	: CProcessor(aPlan, aUiHandler, aStsSession, aRegistryWrapper, aObserver), 
+	iSecurityManager(aSecurityManager), 
+	iSisHelper(aSisHelper),
+	iControllerData(aControllerData)
+	{
+	}
+#else
+CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan, 
+	CSecurityManager &aSecurityManager, RSisHelper& aSisHelper, 
+	RUiHandler& aUiHandler, CIntegrityServices& aIntegrityServices, 
+	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+	: CProcessor(aPlan, aUiHandler, aIntegrityServices, aObserver), 
+	iSecurityManager(aSecurityManager), 
+	iSisHelper(aSisHelper),
+	iControllerData(aControllerData)
+	{
+	}
+#endif
+
+CInstallationProcessor::~CInstallationProcessor()
+	{
+	Cancel();
+	
+	delete iEmbeddedProcessor;
+	delete iFileExtractor;
+		
+	iFilesToCopy.ResetAndDestroy();
+	iApparcRegFiles.ResetAndDestroy();
+	
+	iLoader.Close();
+	iSkipFile.Close();
+	
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	iSoftwareTypeRegInfoArray.Close();
+#endif
+	}
+
+void CInstallationProcessor::ConstructL()
+	{
+	User::LeaveIfError(iLoader.Connect());
+		
+	CProcessor::ConstructL();
+	
+	iFileExtractor=CFileExtractor::NewL(Fs(), iSisHelper, UiHandler(), Plan().AppInfoL());
+	}
+
+void CInstallationProcessor::DoCancel()
+	{
+	CProcessor::DoCancel();
+	if (iEmbeddedProcessor && iEmbeddedProcessor->IsActive())
+		{
+		iEmbeddedProcessor->Cancel();
+		}
+	
+	if (iFileExtractor->IsActive())
+		{
+		iFileExtractor->Cancel();
+		}
+	}
+
+void CInstallationProcessor::DisplayFileL(const CSisRegistryFileDescription& aFileDescription, Sis::TSISFileOperationOptions aFileOperationOption)
+	{
+	// Default to continue
+	TFileTextOption fileTextOption(EInstFileTextOptionContinue);
+	bool forceAbortFlag = EFalse;
+	if (aFileOperationOption & Sis::EInstFileTextOptionSkipIfNo)
+		{
+		fileTextOption=EInstFileTextOptionSkipOneIfNo;
+		}
+	else if (aFileOperationOption & Sis::EInstFileTextOptionAbortIfNo)
+		{
+		fileTextOption=EInstFileTextOptionAbortIfNo;
+		}
+	else if (aFileOperationOption & Sis::EInstFileTextOptionExitIfNo)
+		{
+		fileTextOption=EInstFileTextOptionExitIfNo;
+		}
+	else if (aFileOperationOption & Sis::EInstFileTextOptionForceAbort)
+		{
+		//converts FA option to TC option.
+		fileTextOption=EInstFileTextOptionContinue;
+		forceAbortFlag = ETrue;
+		}
+			
+	TFileName temporaryFileName;
+		
+	TemporaryFileNameLC(aFileDescription, temporaryFileName);
+
+	EnsureTemporaryInstallDirExistsL(temporaryFileName);
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	TransactionSession().RegisterTemporaryL(temporaryFileName);
+#else
+	IntegrityServices().TemporaryL(temporaryFileName);
+#endif
+		
+	//	Extract this file to its temporary location.
+	// However this file may have already been extracted, due to displaying it as
+	// text, so we don't need to extract it again under this circumstance
+	RFile temporaryFile;
+	TInt err = temporaryFile.Create(Fs(), temporaryFileName, EFileWrite);
+	if (err==KErrNone)
+		{
+		// We are passing the file handle to SISHelper but still need to close 
+		// it here.
+		CleanupClosePushL(temporaryFile);
+		User::LeaveIfError(iSisHelper.ExtractFileL(Fs(), temporaryFile,
+			aFileDescription.Index(), ApplicationL().AbsoluteDataIndex(), UiHandler()));
+		CleanupStack::PopAndDestroy(&temporaryFile);
+		}
+	else if (err != KErrAlreadyExists)
+		{
+		User::Leave(err);
+		}
+		
+	User::LeaveIfError(temporaryFile.Open(Fs(), temporaryFileName, EFileRead));
+	CleanupClosePushL(temporaryFile);
+	
+	TInt fileSize=0;
+	User::LeaveIfError(temporaryFile.Size( fileSize));
+	HBufC8* text=HBufC8::NewMaxLC(fileSize);
+	TPtr8 textPtr(text->Des());
+
+	User::LeaveIfError(temporaryFile.Read(textPtr));	
+
+	CDisplayText* displayText = NULL;
+
+	displayText = CDisplayText::NewLC(Plan().AppInfoL(), fileTextOption, textPtr);
+	UiHandler().ExecuteL(*displayText);
+
+	switch (fileTextOption)
+		{
+		case EInstFileTextOptionContinue:
+		//for FA option ,raise a TC dialog and abort the installation.
+		if(forceAbortFlag)
+			{
+			User::Leave(KErrCancel);
+			}
+		break;
+		
+		case EInstFileTextOptionSkipOneIfNo:
+			{
+			iSkipFile.AppendL(displayText->ReturnResult());
+			}
+		break;
+	
+		case EInstFileTextOptionAbortIfNo:
+		case EInstFileTextOptionExitIfNo:
+		if (!displayText->ReturnResult())	
+			{
+			User::Leave(KErrCancel);
+			}
+		break;			
+		}
+
+	CleanupStack::PopAndDestroy(3, &temporaryFile);
+	}
+
+TBool CInstallationProcessor::ExtractFileL(CSisRegistryFileDescription& aFileToExtract)
+	{
+	DEBUG_PRINTF2(_L("Install Server - Installation Processor Extracting File '%S'"),
+		&aFileToExtract.Target());
+	
+	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch()
+			|| aFileToExtract.Operation() == Sis::EOpNull)
+		{
+		// This file will not really be copied, but still need to update the progress bar.
+		// Increment for extract stage (scaled by file size)
+		TInt ammount = ProgressBarFileIncrement(aFileToExtract.UncompressedLength());
+		// Increment for install/copy stage
+		ammount += KProgressBarEndIncrement;
+		UiHandler().UpdateProgressBarL(Plan().AppInfoL(), ammount);
+		// move onto next file
+		return EFalse;	
+		}
+
+	TFileName temporaryFileName;
+		
+	TemporaryFileNameLC(aFileToExtract, temporaryFileName);
+
+	// Add to the list of files to copy
+	CFileCopyDescription* fileCopyDescription=CFileCopyDescription::NewLC(
+		temporaryFileName, aFileToExtract);
+	User::LeaveIfError(iFilesToCopy.Append(fileCopyDescription));
+	CleanupStack::Pop(fileCopyDescription);	// Ownership is transferred
+
+	EnsureTemporaryInstallDirExistsL(temporaryFileName);
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	TransactionSession().RegisterTemporaryL(temporaryFileName);
+#else
+	IntegrityServices().TemporaryL(temporaryFileName);
+#endif
+
+	iFileExtractor->ExtractFileL(ApplicationL().AbsoluteDataIndex(), aFileToExtract, temporaryFileName, iStatus);
+	return ETrue;
+	}
+
+
+void CInstallationProcessor::DoExtractHashL(const CSisRegistryFileDescription& aFileToProcess)
+	{
+	TParsePtrC targetPath(aFileToProcess.Target());
+	// If the target is in sys\bin, write its hash into \sys\hash and name
+	// it after the file.  The check in the process file state will ensure
+	// that it must be a valid exe or dll to get this far.
+	if (targetPath.Path().CompareF(KBinPath) == 0)
+		{
+		ExtractHashL(aFileToProcess.Target(), aFileToProcess.Hash());
+		}	
+	}
+
+void CInstallationProcessor::CheckHashL(const CSisRegistryFileDescription& aFileToProcess, const TDesC& aCurrentFileName)
+	{
+	const CHashContainer& hash = aFileToProcess.Hash();
+	
+	// Calculate and check correct hash value
+	CFileSisDataProvider* fileDataProvider=CFileSisDataProvider::NewLC(Fs(), aCurrentFileName);
+	TBool hashIsValid=iSecurityManager.VerifyFileHashL(*fileDataProvider,hash);
+	CleanupStack::PopAndDestroy(fileDataProvider);
+	if (!hashIsValid)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	}
+
+	
+
+void CInstallationProcessor::EnsureTemporaryInstallDirExistsL(const TDesC& aFileTarget)
+	{
+	TInt err = Fs().MkDirAll(aFileTarget);
+	if (err!= KErrNone && err != KErrAlreadyExists)
+		{
+		User::LeaveIfError(err);
+		}
+	}
+
+void CInstallationProcessor::TemporaryFileNameLC(const CSisRegistryFileDescription& aFileToExtract, TDes& aTemporaryFileName)
+	{
+	static TInt localTempCnt = 0;
+	TChar drive;
+	if(aFileToExtract.Target().Length())
+		{
+		// set temporary drive to be same as final target
+		drive = aFileToExtract.Target()[0];
+		}
+	else
+		{
+		// set temporary drive to the user selected drive
+		drive = ApplicationL().UserSelections().Drive();
+		}
+	 		
+ 	// If no drive has been selected then use the C drive for
+ 	// temporary files. This should only happen if the SIS file
+ 	// just contains text files to display but not install.
+ 	if (drive == TChar(KNoDriveSelected))
+ 		{
+ 		drive = iSystemDriveChar;
+		}
+	
+	// construct the temporary filename
+	// Format is  {Drive}:\sys\install\temp\file-{Data Unit}-{File Index}-{LocalCounter}
+	_LIT(KTemporaryFileFormat, "%c:%Sfile-%d-%d-%d");
+	TUint driveCh(drive); // Can't pass TChar to Format.
+	
+	aTemporaryFileName.Format(KTemporaryFileFormat, driveCh, &KSysInstallTempPath, 
+							 ApplicationL().AbsoluteDataIndex(), aFileToExtract.Index(),
+							 localTempCnt++);
+	}
+
+///\short Extracts executable hash from controller to file for the loader
+void CInstallationProcessor::ExtractHashL(const TFileName& aFileName, 
+	const CHashContainer& aHash)
+	{	
+	const TDesC8& hashData = aHash.Data();
+		
+	TBuf<32> hashPath;	
+	TUint driveCh(iSystemDriveChar); // can't pass TChar to Format
+	hashPath.Format(KHashPathFormat, driveCh, &KHashPath);	
+	
+	TParse hashFileName;
+	hashFileName.Set(hashPath, &aFileName, NULL);
+	TInt err = Fs().MkDirAll(hashFileName.DriveAndPath());
+	if (err!=KErrNone && err!=KErrAlreadyExists)
+		{
+		User::LeaveIfError(err);
+		}
+	
+	// If the hash already exists, leave with KErrAlreadyExists
+	TEntry hashEntry;
+	if ( KErrNone == Fs().Entry(hashFileName.FullName(), hashEntry))
+		{
+		User::Leave( KErrAlreadyExists );
+		}
+
+	DEBUG_PRINTF2(_L("Install Server - Installation Processor, extracting hash file '%S'"), 
+		&(hashFileName.FullName()));
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	TransactionSession().RegisterNewL(hashFileName.FullName());
+#else
+	IntegrityServices().AddL(hashFileName.FullName());
+#endif
+
+	RFile file;
+	User::LeaveIfError(file.Create(Fs(), hashFileName.FullName(), 
+		EFileWrite|EFileShareExclusive|EFileStream));
+	CleanupClosePushL(file);
+	User::LeaveIfError(file.Write(hashData));
+	CleanupStack::PopAndDestroy(&file);
+	//Write a SWI event log for this hash file
+	TUint8 fileFlag(EFileAdded);
+	CObservationData *event = CObservationData::NewLC(hashFileName.FullName(),TUid::Null(),fileFlag);
+	Observer().AddEventL(*event);
+	CleanupStack::PopAndDestroy(event);
+	}
+
+void CInstallationProcessor::VerifyInstallPathL(const CSisRegistryFileDescription& aFileDescription)
+	{
+	// Check the target path of every file is legal
+	SecurityCheckUtil::TProtectedDirectoryCheckError targetError;
+	// sis file signed by Su Cert are allowed to install files in private dir 
+	// without corresponding executable in the package.
+	if (ApplicationL().IsInstallSuCertBased())
+		{
+		return;
+		}
+
+	TBool pathOk = SecurityCheckUtil::CheckProtectedDirectoriesL(
+		aFileDescription.Target(), aFileDescription.Operation(), iSidsAdded, targetError);
+	if (!pathOk)
+		{
+		/// Initialized to  EUiSIDMismatch to make RVCT Compiler happy / supress the warnings during ARM build.
+		TErrorDialog uiError = EUiSIDMismatch;
+		switch(targetError)
+			{
+			case SecurityCheckUtil::ESIDMismatch:
+			uiError = EUiSIDMismatch;
+			break;
+			
+			case SecurityCheckUtil::EInvalidFileName:
+			uiError = EUiInvalidFileName;
+			break;
+			
+			default:
+			User::Leave(KErrNotSupported);
+			}
+		CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),uiError,KNullDesC);
+		UiHandler().ExecuteL(*cmd);
+		CleanupStack::PopAndDestroy(cmd);
+		User::Leave(KErrAccessDenied);			
+		}		
+	}
+
+void CInstallationProcessor::InstallFileL(const CFileCopyDescription& aFileCopyDescription)
+	{
+	DEBUG_PRINTF2(_L("Install Server - Installation Processor, installing file to '%S'"),
+		&aFileCopyDescription.FileDescription().Target());
+	
+	// move file to it's final location
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	TransactionSession().RegisterNewL(aFileCopyDescription.FileDescription().Target());
+#else
+	IntegrityServices().AddL(aFileCopyDescription.FileDescription().Target());
+#endif
+	
+	// Move try 1 of 3
+	TInt err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+	if(err != KErrNone)
+		{
+		// Move failed - maybe dir did not exist
+		(void) Fs().MkDirAll(aFileCopyDescription.FileDescription().Target());
+		// Move try 2 of 3
+		err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+		if(err != KErrNone)
+			{
+			// Maybe destination already exists?
+			// Is this possible? Or would install have deleted file earlier!?!?
+
+			// Clear Read only attributes and delete the file
+			Fs().SetAtt(aFileCopyDescription.FileDescription().Target(), 0, KEntryAttReadOnly);
+			
+			iLoader.Delete(aFileCopyDescription.FileDescription().Target()); // ignore failure here since the rename will fail instead
+			
+			// Move try 3 of 3
+			err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+			}
+		}
+
+	User::LeaveIfError(err); // Did we manage to do the move?
+
+	// Update progress bar for the copy/install of this file
+	UiHandler().UpdateProgressBarL(Plan().AppInfoL(), KProgressBarEndIncrement);
+	
+	AddApparcFilesInListL(aFileCopyDescription.FileDescription().Target());
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Parse the file if it carries software type registration info
+	if (InstallSoftwareTypeHelper::IsValidSwRegFileL(aFileCopyDescription.FileDescription().Target(),
+													 ApplicationL().ControllerL().Info().Uid().Uid().iUid))
+		{
+		InstallSoftwareTypeHelper::ParseRegFileL(Fs(),
+												 aFileCopyDescription.FileDescription().Target(),
+												 iSoftwareTypeRegInfoArray);
+		}
+#endif
+
+	// Launch the file if RI flag is set.
+	if(ShouldLaunchL(aFileCopyDescription.FileDescription()))
+		{
+		LaunchFileL(aFileCopyDescription.FileDescription());
+		}
+	
+	}
+
+// State processing functions
+
+TBool CInstallationProcessor::DoStateInitializeL()
+	{
+	iUiState = EInitialize;
+	iCurrent = 0;
+	iFilesToCopyCurrent = 0;
+	iFilesToCopy.ResetAndDestroy();
+	iApparcRegFiles.ResetAndDestroy();
+	return ETrue;
+	}
+	
+TBool CInstallationProcessor::DoStateProcessEmbeddedL()
+	{
+	if (iCurrent < ApplicationL().EmbeddedApplications().Count())
+		{
+		EmbeddedProcessorL().ProcessApplicationL(*ApplicationL().EmbeddedApplications()[iCurrent++], iStatus);
+		WaitState(ECurrentState);
+		return EFalse;
+		}
+	else
+		{
+		iCurrent = 0;
+		return ETrue;
+		}
+	}
+	
+TBool CInstallationProcessor::DoStateProcessSkipFilesL()
+	{
+	TInt count = ApplicationL().FilesToSkipOnInstall().Count();
+	// create a modifyable reference
+	CApplication& app = const_cast <CApplication&>(ApplicationL());
+	CPlan& plan = const_cast <CPlan&>(Plan());
+
+	for (TInt i = 0; i < count; ++i)		
+		{
+		if (iSkipFile[i])
+			{
+			CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToSkipOnInstall()[i];
+			app.AddFileL(fileDescription);
+			plan.AddInstallFileForProgress(fileDescription.UncompressedLength());
+			}
+		}
+	iCurrent = 0;
+	return ETrue;	
+	}
+	
+TBool CInstallationProcessor::DoStateExtractFilesL()
+	{
+	if (iCurrent < ApplicationL().FilesToAdd().Count())
+		{
+		if (iUiState != EExtractFiles)
+			{
+			iUiState = EExtractFiles;
+			// Signal to UI we are extracting files
+			CHandleCancellableInstallEvent* cmd = CHandleCancellableInstallEvent::NewLC(Plan().AppInfoL(), EEventCopyingFiles, 0, KNullDesC);
+			UiHandler().ExecuteL(*cmd);
+			CleanupStack::PopAndDestroy(cmd);
+			}
+			
+		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+		
+		if(ExtractFileL(fileDescription))
+			{
+			WaitState(ECurrentState);
+			}
+		else
+			{
+			SwitchState(ECurrentState);
+			}
+		return EFalse;
+		}
+	else
+		{
+		iCurrent = 0;
+		return ETrue;
+		}
+	}
+
+bool CInstallationProcessor::FileIsApparcReg(const TDesC& aFilename) const
+	{
+	TParsePtrC filename(aFilename);
+
+	return filename.Path().CompareF(KApparcRegDir) == 0;
+	}
+
+TBool CInstallationProcessor::DoStateProcessFilesL()
+	{
+	DEBUG_PRINTF(_L8("Install Server - Processing Files"));
+	if (iCurrent < ApplicationL().FilesToAdd().Count() )
+		{
+		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent];
+		
+		if(fileDescription.Operation() != Sis::EOpNull)
+			{
+			if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+				{
+				// For pre-installed SISes, filenames could be "e:\foo.txt", but we
+				// want them to install successfully on "f:". So re-write stub file
+				// references to be the same drive as where the SIS file is located
+				TChar drive = ApplicationL().UserSelections().Drive();
+				TFileName target = fileDescription.Target();
+				target[0] = drive;
+				
+				// use filenames from the file descriptions
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
+					TransactionSession(), fileDescription, target);
+#else
+				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
+					IntegrityServices(), fileDescription, target);
+#endif
+				if (error != KErrNone)
+					{
+					ReportErrorL(TErrorDialog(error));
+					}
+				
+				// This is either preinstalled or is a propagation and as of Pdef115573 only files under /sys, /resource or 
+				// which have the VERIFY tag set need to have their hashes checked.
+				if ((fileDescription.OperationOptions() & Swi::Sis::EInstVerifyOnRestore) || SecurityCheckUtil::IsTargetTcbWriteProtected(fileDescription.Target()))
+					{
+					CheckHashL(fileDescription, target);
+					}
+				}
+			else
+				{
+				// use temporary file names
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
+					iSidsAdded, TransactionSession(), fileDescription,
+					iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+#else
+				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
+					iSidsAdded, IntegrityServices(), fileDescription,
+					iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+#endif
+				if (error != KErrNone)
+					{
+					ReportErrorL(TErrorDialog(error));
+					}	
+				CheckHashL(fileDescription, iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+				iFilesToCopyCurrent++;
+				}
+			}
+
+		++iCurrent;
+		SwitchState(ECurrentState);
+		return EFalse;
+		}
+	else
+		{
+		
+		// Finally, if this is an addition to an existing package, add SIDs from that
+		// package to the list of SIDs attached to this package
+		
+		if (ApplicationL().IsPartialUpgrade() ||
+			ApplicationL().IsAugmentation()	||
+			ApplicationL().IsPreInstalledPatch())
+			{
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			RSisRegistrySession session;
+			User::LeaveIfError(session.Connect());
+			CleanupClosePushL(session);
+#endif
+			
+			RSisRegistryEntry entry;
+			// Planning stage already established the entry exists
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			TInt err = entry.Open(iRegistryWrapper.RegistrySession(), ApplicationL().ControllerL().Info().Uid().Uid());
+#else
+			TInt err = entry.Open(session, ApplicationL().ControllerL().Info().Uid().Uid());
+#endif
+			if (err == KErrNotFound)
+			{
+			  User::Leave(KErrMissingBasePackage);	
+			}
+			
+			User::LeaveIfError(err);	
+		  
+			CleanupClosePushL(entry);
+			
+			RArray<TUid> preinstalledSids;
+			CleanupClosePushL(preinstalledSids);
+			entry.SidsL(preinstalledSids);
+			
+			TInt sids(preinstalledSids.Count());
+			for (TInt i = 0; i < sids; ++i)
+				{
+				DEBUG_PRINTF2(_L("Install Server - Processing Files - Appending SID %08x"), preinstalledSids[i]);
+				iSidsAdded.Append(preinstalledSids[i]);
+				}
+			
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			CleanupStack::PopAndDestroy(2, &entry); // presintalledSids
+#else
+			CleanupStack::PopAndDestroy(3, &session); // entry, presintalledSids
+#endif
+			
+			}
+		
+		iCurrent = 0;
+		return ETrue;
+		}
+	}
+
+TBool CInstallationProcessor::DoStateVerifyPathsL()
+	{
+	if (iCurrent < ApplicationL().FilesToAdd().Count())
+		{
+		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+		VerifyInstallPathL(fileDescription);	
+		SwitchState(ECurrentState);
+		return EFalse;
+		}
+	else
+		{
+		iCurrent = 0;
+		return ETrue;
+		}
+	}
+	
+TBool CInstallationProcessor::DoStateInstallFilesL()
+	{
+	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+		{
+		// Only need to install hash for files in pre-installed application.
+		if (iCurrent < ApplicationL().FilesToAdd().Count())
+			{
+			const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+			
+			if(fileDescription.Operation() != Sis::EOpNull)
+				{
+				DoExtractHashL(fileDescription);
+				
+				// Add apparc registerd files in list.
+				AddApparcFilesInListL(fileDescription.Target());
+				
+				// Launch the file if RI flag is set.
+				if(ShouldLaunchL(fileDescription))
+					{
+					LaunchFileL(fileDescription);
+					}
+					
+				AddEventToLogL(fileDescription);
+				}
+				
+			SwitchState(ECurrentState);
+			return EFalse;
+			}
+		}
+	else if (iCurrent < iFilesToCopy.Count())
+		{
+		const CFileCopyDescription& fileCopyDescription = *iFilesToCopy[iCurrent++];
+		DoExtractHashL(fileCopyDescription.FileDescription());
+		InstallFileL(fileCopyDescription);
+		AddEventToLogL(fileCopyDescription.FileDescription());
+		SwitchState(ECurrentState);
+		return EFalse;
+		}
+	iCurrent = 0;
+	return ETrue;
+	}
+
+
+
+TBool CInstallationProcessor::DoStateDisplayFilesL()
+	{
+	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+		{
+		return ETrue;
+		}
+	if (iCurrent < ApplicationL().FilesToDisplayOnInstall().Count())
+		{		
+		const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToDisplayOnInstall()[iCurrent++];		
+		DisplayFileL(fileDescription, fileDescription.OperationOptions());
+		SwitchState(ECurrentState);
+		return EFalse;
+		}
+	else
+		{
+		iCurrent = 0;
+		return ETrue;
+		}		
+	}
+
+TBool CInstallationProcessor::DoStateUpdateRegistryL()
+	{
+	// destroy the memory heavy file copy descriptions
+	iFilesToCopy.ResetAndDestroy();
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	// Now that we are ready to make changes to the registry we start a transaction
+	// Note that the commit/rollback action is subsequently taken by the later steps of the state machine
+	iRegistryWrapper.StartMutableOperationsL();
+#else
+	RSisRegistryWritableSession session;
+	User::LeaveIfError(session.Connect());
+	CleanupClosePushL(session);
+#endif
+	
+	TInt64 offset = 0;
+	if (!ApplicationL().IsUninstall())
+		{
+		
+		const Swi::Sis::CController& controller = ApplicationL().ControllerL();
+	
+		// If this is the top level controller, strip the type field from it
+		// all controllers must be registered as if they were contained in a SIS
+		// array
+	
+		offset = controller.DataOffset();
+		if (offset == 0)
+			{
+			// top level controller
+			offset = 4;
+			TFileName fileName;
+			// Check whether we should create a SIS stub
+			if(IsApplicationPermittedInStub(ApplicationL())
+				&& !iSisHelper.IsStubL()
+				&& iSecurityManager.SecurityPolicy().AllowPackagePropagate() &&  IsStubSisFileRequiredL())  
+				{
+				TChar drive = ApplicationL().StubDrive();
+				if(CheckEmbeddedAppsInstalledOnSameDrive(ApplicationL().EmbeddedApplications(), drive))
+					{
+					// Create a stub SIS file for the auto-propagation feature.
+					CreateStubSisFileL(fileName);
+					// Register the stub SIS file at SWI registry, so that it will be removed on unistallation.
+					RegisterStubSisFileL(fileName);
+					}
+				}			
+			
+			// Check whether we are installing from an existing SIS stub
+			if(iSisHelper.IsStubL())
+				{
+				// Check whether the controller was a preinstalled type
+				// if so then it's a preinstalled stub, not a propagated app stub
+				Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();
+				if(installType != Sis::EInstPreInstalledPatch && installType != Sis::EInstPreInstalledApp)
+					{
+					// If we are installing from a removable media stub
+					// we need to add the stub to the list of files to
+					// remove during uninstall
+					// we don't need to create it because we are 
+					// already installing from a SIS stub
+					iSisHelper.GetSisFileNameL(fileName);
+					RegisterStubSisFileL(fileName);
+					}
+				else
+					{
+					// If this preinstalled package is deletable and the policy
+					// allows deletion of pre-installed files, add the stub sis
+					// file to the files to remove on uninstall.
+					CSecurityPolicy* securityPolicy=CSecurityPolicy::GetSecurityPolicyL();
+					if (securityPolicy->DeletePreinstalledFilesOnUninstall()
+						&& ApplicationL().IsDeletablePreinstalled())
+						{
+						// Get filename of stub sis file
+						TFileName stubFile;
+						iSisHelper.GetSisFileNameL(stubFile);
+						RegisterStubSisFileL(stubFile);
+						}
+					}
+				}
+			}
+		}
+	
+	TPtrC8 thisController(iControllerData.Mid(offset));
+	
+	if (ApplicationL().IsUpgrade() 
+		 || ApplicationL().IsPartialUpgrade())
+		{
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		if (iSoftwareTypeRegInfoArray.Count() > 0)
+			{
+			iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
+			}
+		else
+			{
+			iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
+			}
+#else
+		session.UpdateEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
+#endif
+		}
+	else if (ApplicationL().IsInstall()
+				|| ApplicationL().IsAugmentation() 
+				|| ApplicationL().IsPreInstalledApp()
+				|| ApplicationL().IsPreInstalledPatch())
+		{
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		if (iSoftwareTypeRegInfoArray.Count() > 0)
+			{
+			iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
+			}
+		else
+			{
+			iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
+			}
+#else
+		session.AddEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
+#endif
+		}
+	else if (ApplicationL().IsUninstall())
+		{
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		iRegistryWrapper.RegistrySession().DeleteEntryL(ApplicationL().PackageL() , TransactionSession().TransactionIdL()); 
+#else
+		session.DeleteEntryL(ApplicationL().PackageL() , IntegrityServices().TransactionId());
+#endif
+		}
+
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	CleanupStack::PopAndDestroy(&session);
+#else
+	// Registration of MIME types of the software types being installed to AppArc.
+	// This operation is not transactional so it must be done after the software types
+	// have been successfully registered to the SCR by the following calls:
+	// RSisRegistryWritableSession::AddEntryL()
+	// RSisRegistryWritableSession::UpdateEntryL()
+	InstallSoftwareTypeHelper::RegisterMimeTypesL(iSoftwareTypeRegInfoArray);
+#endif
+	return ETrue;
+	}
+
+// CFileCopyDescription 
+
+/*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewL(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
+	{
+	CFileCopyDescription* self=CFileCopyDescription::NewLC(aTemporaryFileName, aFileDescription);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewLC(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
+	{
+	CFileCopyDescription* self=new (ELeave) CFileCopyDescription(aFileDescription);
+	CleanupStack::PushL(self);
+	self->ConstructL(aTemporaryFileName);
+	return self;
+	}
+
+CInstallationProcessor::CFileCopyDescription::CFileCopyDescription(const CSisRegistryFileDescription& aFileDescription)
+	:iFileDescription(aFileDescription)
+	{
+	}
+
+void CInstallationProcessor::CFileCopyDescription::ConstructL(const TDesC& aTemporaryFileName)
+	{
+	iTemporaryFileName=aTemporaryFileName.AllocL();
+	}
+
+CInstallationProcessor::CFileCopyDescription::~CFileCopyDescription()
+	{
+	delete iTemporaryFileName;	
+	}
+
+CInstallationProcessor& CInstallationProcessor::EmbeddedProcessorL()
+	{
+	if (!iEmbeddedProcessor)
+		{
+		iEmbeddedProcessor=CInstallationProcessor::NewL(*this);
+		}
+	return *iEmbeddedProcessor;
+	}
+	
+void CInstallationProcessor::ReportErrorL(TErrorDialog aError)
+	{
+	CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),aError,KNullDesC);
+	UiHandler().ExecuteL(*cmd);
+	CleanupStack::PopAndDestroy(cmd);
+	User::Leave(KErrSecurityError);	
+	}
+
+TBool CInstallationProcessor::CheckEmbeddedAppsInstalledOnSameDrive(RPointerArray<CApplication> aArray, TChar aDrive)
+	{
+	for(TInt i = 0; i < aArray.Count(); i++)
+		{
+		CApplication& application = *aArray[i];
+		
+		if(!IsApplicationPermittedInStub(application))
+			{
+			return EFalse;
+			}	
+		else if(application.StubDrive() != aDrive)
+			{
+			// Embedded Application must be installed on the same drive
+			// as the parent application otherwise the removable media
+			// stub will reference files outside the media card
+			return EFalse;
+			}
+		else if(!CheckEmbeddedAppsInstalledOnSameDrive(application.EmbeddedApplications(), aDrive))
+			{
+			return EFalse;
+			}
+		}
+	return ETrue;
+	}
+
+TBool CInstallationProcessor::IsApplicationPermittedInStub(const CApplication& aApplication)
+	{
+	if(	aApplication.IsPreInstalledApp() || 
+		aApplication.IsPreInstalledPatch() ||
+		aApplication.IsUninstall() ||
+		aApplication.IsPartialUpgrade() ||
+		!aApplication.CanPropagate())
+		{
+		// These installation types are not permitted in
+		// a removable media stub
+		// We cannot be certain that all required files will be present
+		// on the media card when it is inserted into another device
+		return EFalse;
+		}
+	else
+		{
+		return ETrue;
+		}
+	}
+
+
+void CInstallationProcessor::CreateStubSisFileL(TFileName &aFileName)
+	{
+	// Do all this file stuff in SWI so we have necessary capabilities
+	_LIT(KStubDelimiter,      "_");
+	
+	TUid appUid = ApplicationL().ControllerL().Info().Uid().Uid();
+	TChar drive = ApplicationL().StubDrive();
+	// build SwiDaemon Pathname
+	aFileName.Append(drive);
+	aFileName.Append(KDriveDelimiter);
+	aFileName.Append(KPrivatePath);
+	aFileName.AppendNumFixedWidth(KSwiDaemonUid, EHex, 8);
+	aFileName.Append(KPathDelimiter);
+	aFileName.AppendNumFixedWidth(appUid.iUid, EHex, 8);	
+		
+		
+	Swi::Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();	
+		
+	switch(installType)
+		{
+		/* 
+		If a device has more than one slot, we may install a PA/PP to a different media card. 
+		In this case,we'll still create a stub SIS file even though we're installing from a media card.
+		*/
+
+		// If an Installation type is SA/PA then append _0 after the stub UID.
+		case Swi::Sis::EInstInstallation:
+		case Swi::Sis::EInstPreInstalledApp:
+			{
+			aFileName.Append(KStubDelimiter);
+			aFileName.Append('0');	
+			break;
+			}
+				
+		// If an Installation type is SP/PP then append _augNumber+1 after the stub UID.
+		case Swi::Sis::EInstPreInstalledPatch:
+		case Swi::Sis::EInstAugmentation:
+			{
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			RSisRegistrySession session;
+			User::LeaveIfError(session.Connect());
+			CleanupClosePushL(session);
+#endif
+
+			RSisRegistryEntry entry;
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			User::LeaveIfError(entry.Open(iRegistryWrapper.RegistrySession(), appUid));
+#else
+			User::LeaveIfError(entry.Open(session, appUid));
+#endif
+			CleanupClosePushL(entry);	
+
+			/*
+			Get the Augmentations number and append the number in stub file name(DEF107470).
+			This way we impose order on the installation sequence when the card is inserted on another device.
+			Since SWI daemon processes stub files in alphabetic order, it will install augmentations only after the original package
+			*/
+			TInt augNumber = entry.AugmentationsNumberL();	
+			User::LeaveIfError(augNumber);
+			aFileName.Append(KStubDelimiter);
+			aFileName.AppendFormat(_L("%d"),augNumber+1);
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+			CleanupStack::PopAndDestroy(&entry);
+#else
+			CleanupStack::PopAndDestroy(2, &session);
+#endif
+			break;
+			}
+
+		default: 
+			/* 
+			If it is not SA/PA/SP/PP, then this function shouldn't have been invoked, 
+			as these are the only package types which can appear according to Functional Specification 
+			on a media card.
+			*/
+			ASSERT(EFalse);
+		}
+
+	aFileName.Append(KSisExt);
+
+	TEntry entry;
+	if (KErrNone == Fs().Entry(aFileName, entry))
+		{
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		TransactionSession().RemoveL(aFileName);
+#else
+		IntegrityServices().RemoveL(aFileName);	
+#endif
+		}
+
+	// Notify integrity support that we've created a stub
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	TransactionSession().RegisterNewL(aFileName);
+#else
+	IntegrityServices().AddL(aFileName);
+#endif
+			
+	// create SwiDaemon Private directory on the target drive
+	TInt ret = Fs().MkDirAll(aFileName);
+	if (ret!= KErrNone && ret != KErrAlreadyExists)
+		{
+		User::Leave(ret);
+		}
+
+			
+	// Create the stub file if required
+	RFile file;
+	User::LeaveIfError(file.Create(Fs(), aFileName, EFileStream | EFileWrite | EFileShareExclusive));
+	CleanupClosePushL(file);
+			
+	TInt err = iSisHelper.CreateSisStub(file);
+	CleanupStack::PopAndDestroy(&file);
+		
+	if(err != KErrNone)
+		{
+		// something went wrong while creating the stub
+		// delete the incorrectly created file
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+		TransactionSession().RemoveL(aFileName);
+#else
+		IntegrityServices().RemoveL(aFileName);
+#endif
+		User::Leave(err);
+		}
+	}
+
+void CInstallationProcessor::RegisterStubSisFileL(const TFileName &aFileName)
+	{
+	// Add the stub file to the list of files to be removed during uninstall
+	CSisRegistryFileDescription* fileDescription 
+			= CreateSisStubRegistryFileDescriptionLC(Fs(),aFileName);
+		
+	// cast away constness because we need to add a file to remove into the application
+	CApplication& application  = const_cast<CApplication&>(ApplicationL());
+	application.AddSisStubFileL(*fileDescription);
+		
+	CleanupStack::PopAndDestroy(fileDescription);
+	}
+
+
+TBool CInstallationProcessor::IsStubSisFileRequiredL()
+	{
+	// Check that drive is removable
+	// we only write Stubs to removable media so they
+	// will install when the same media card is inserted
+	// in a different Symbian OS device
+	TChar drive = ApplicationL().StubDrive();
+	
+	TDriveInfo driveInfo;
+	TInt driveNum;
+	RFs::CharToDrive(drive, driveNum);
+	Fs().Drive(driveInfo, driveNum);
+	
+	if(driveInfo.iDriveAtt & KDriveAttRemovable)
+		return ETrue;
+	else
+		return EFalse;
+	}
+
+CSisRegistryFileDescription* CInstallationProcessor::CreateSisStubRegistryFileDescriptionLC(RFs& aFs, const TDesC& aFileName)
+	{
+	_LIT(KDataTypeSisx, "x-epoc/x-sisx-app");
+	
+	// This will leave if the file does not exist
+	CFileSisDataProvider* dataProvider = CFileSisDataProvider::NewLC(aFs, aFileName);
+	
+	// create a SHA1 hash of the Sis Stub file 
+	HBufC8* hash = iSecurityManager.CalculateHashLC(*dataProvider, CMessageDigest::ESHA1);
+	CHashContainer* hashContainer = CHashContainer::NewLC(CMessageDigest::ESHA1, *hash);
+
+	TInt64 fileLength = 0;
+	dataProvider->Seek(ESeekCurrent, fileLength);
+	Sis::TSISFileOperationOptions options = static_cast<Sis::TSISFileOperationOptions>(0);
+	
+	CSisRegistryFileDescription *fileDescription = 
+				CSisRegistryFileDescription::NewL(*hashContainer,
+													aFileName,
+													KDataTypeSisx(),
+													Sis::EOpInstall,
+													options,
+													fileLength,
+													0,
+													KNullUid);
+													
+
+	CleanupStack::PopAndDestroy(3, dataProvider); // hashContainer, hash, dataProvider
+	CleanupStack::PushL(fileDescription);
+	return fileDescription; 
+	}
+
+
+void CInstallationProcessor::AddEventToLogL(const CSisRegistryFileDescription& aFileDescription)
+/**
+	Write an install file event into the swi observation log file.
+	
+	@param aFileDescription The file whose name will be written into the log file.
+ */
+	{
+	TUint8 fileFlag(EFileAdded);
+	TParsePtrC targetPath(aFileDescription.Target());
+				
+	if (0 == targetPath.Path().CompareF(KBinPath))
+		{
+		TEntry entry;
+		TInt err = Fs().Entry(aFileDescription.Target(), entry);
+		
+		if(KErrNone == err && entry.IsTypeValid())
+			{
+			if(SecUtils::IsExe(entry))
+				{//Set file exe flag.
+				fileFlag |= Swi::EFileExe;
+				}
+			else if(SecUtils::IsDll(entry))
+				{//Set file dll flag.
+				fileFlag |= Swi::EFileDll;
+				}
+			}
+		}
+		
+	CObservationData *event = CObservationData::NewLC(aFileDescription.Target(),aFileDescription.Sid(),fileFlag);
+	Observer().AddEventL(*event);
+	CleanupStack::PopAndDestroy(event);
+	}
+
+void CInstallationProcessor::LaunchFileL(const CSisRegistryFileDescription& aFileDescription)
+	{
+	if (iApparcRegFiles.Count() > 0)
+		{
+		// Ask the launcher to notify Apparc of any new reg files
+		RSisLauncherSession launcher;
+		CleanupClosePushL(launcher);
+		User::LeaveIfError(launcher.Connect());
+	
+		launcher.NotifyNewAppsL(iApparcRegFiles);
+		// clean up our list so we don't notify of the files twice
+		iApparcRegFiles.ResetAndDestroy();
+		
+		CleanupStack::PopAndDestroy(&launcher);
+		}
+
+	// run the file
+	RunFileL(aFileDescription.Target(), aFileDescription.MimeType(),
+			aFileDescription.OperationOptions());
+	}
+	
+TBool CInstallationProcessor::ShouldLaunchL(const CSisRegistryFileDescription& aFileDescription)
+	{
+	if (aFileDescription.Operation() == Sis::EOpRun && 
+		aFileDescription.OperationOptions() & Sis::EInstFileRunOptionInstall)
+		{
+#ifdef SYMBIAN_SWI_RUN_ON_INSTALL_COMPLETE 
+		return !(aFileDescription.OperationOptions() & Sis::EInstFileRunOptionAfterInstall);
+#else
+		return ETrue;
+#endif	
+		}
+	return EFalse;
+	}
+	
+void CInstallationProcessor::AddApparcFilesInListL(const TDesC& aTargetFileName)
+	{
+	if (FileIsApparcReg(aTargetFileName))
+		{
+		// we're installing a reg file so add it to our list. 
+		HBufC* tmp = aTargetFileName.AllocLC();
+		iApparcRegFiles.AppendL(tmp);
+		CleanupStack::Pop(tmp);
+		}		
+	}