secureswitools/swisistools/source/interpretsislib/installer.cpp
changeset 0 ba25891c3a9e
child 12 7ca52d38f8c3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/interpretsislib/installer.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1559 @@
+/*
+* Copyright (c) 2006-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: 
+*
+*/
+
+
+#pragma warning (disable: 4786)
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+
+#include "dbhelper.h" 
+
+#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <exception>
+#include <sstream>
+#include <algorithm>
+#include <functional>
+#include <fstream>
+#include <stdio.h>
+#include <sys/stat.h>
+
+// SisX Library
+#include "sisdependency.h"
+#include "sisversionrange.h"
+#include "sisversion.h"
+#include "sisprerequisites.h"
+#include "sisfiledescription.h"
+#include "sisstring.h"
+#include "sishash.h"
+
+// User includes
+#include "stringutils.h"
+#include "parameterlist.h"
+#include "rommanager.h"
+#include "configmanager.h"
+#include "errors.h"
+#include "is_utils.h"
+#include "installer.h"
+#include "sisregistryobject.h"
+#include "adornedutilities.h"
+
+// Constants
+const char KRomDriveLetter = 'z';
+const TUint32 KSwiDaemonUid = 0x10202DCE;
+const std::wstring KSysBinPath = L"\\sys\\bin\\";
+
+TInt CheckWildCard(TInt aVal, TInt aReplace)
+{
+	return
+		aVal == -1
+		? aReplace
+		: aVal;
+}
+
+bool InRange(const Version& aVersion, const CSISVersionRange& aRange)
+{
+	Version from(
+		CheckWildCard(aRange.FromVersion().Major(), aVersion.GetMajor()),
+		CheckWildCard(aRange.FromVersion().Minor(), aVersion.GetMinor()),
+		CheckWildCard(aRange.FromVersion().Build(), aVersion.GetBuild()));
+
+	if(!aRange.ToVersion().WasteOfSpace())
+	{
+		Version to(
+			CheckWildCard(aRange.ToVersion().Major(), aVersion.GetMajor()),
+			CheckWildCard(aRange.ToVersion().Minor(), aVersion.GetMinor()),
+			CheckWildCard(aRange.ToVersion().Build(), aVersion.GetBuild()));
+
+		if (aVersion == from ||
+			aVersion == to)
+		{
+			return true;
+		}
+
+		return (aVersion > from && aVersion < to);
+	}
+	else
+	{
+		return (aVersion >= from);
+	}
+}
+
+
+Installer::Installer( SisRegistry& aReg, const CParameterList& aParamList, RomManager& aRomManager, ConfigManager& aConfigManager )
+:   iParamList(aParamList), iRegistry(aReg), iRomManager( aRomManager ), iConfigManager( aConfigManager ),
+    iExpressionEnvironment( NULL ), iExpressionEvaluator( NULL )
+{
+}
+
+TInt Installer::Install(const CParameterList::SISFileList& aList)
+{
+	TInt result = 0;
+	CParameterList::SISFileList sisFiles;
+
+	// Get the SIS files
+	for (CParameterList::SISFileList::const_iterator curr = aList.begin(); curr != aList.end(); ++curr)
+	{
+		std::wstring shortName(curr->iFileName);
+
+		// Ensure formatting is correct
+		if ( StringUtils::IsLastCharacter( shortName, KDirectorySeparator[ 0 ] ) ||
+             StringUtils::IsLastCharacter( shortName, L'/' ) )
+		{
+			shortName.erase(shortName.length()-1,1);
+		}
+
+		if ( IsDirectory(shortName) )
+		{
+			std::list<std::wstring> contents;
+			GetDirContents(shortName, contents);
+
+			for (std::list<std::wstring>::iterator currStr = contents.begin(); currStr != contents.end(); ++currStr)
+			{
+				if ((currStr->find(L".SIS",0) != std::wstring::npos)
+					|| (currStr->find(L".sis",0) != std::wstring::npos))
+				{
+					InstallSISFile sisFileName(shortName + KDirectorySeparator + *currStr, 
+												curr->iTargetDrive, curr->iGenerateStub, 
+												curr->iNonRemovable, curr->iNotRegister, curr->iSUFlag);
+
+					sisFiles.push_back(sisFileName);
+				}
+			}
+
+			if (sisFiles.empty())
+			{
+				LWARN(L"No .SIS files found in directory" << shortName);
+			}
+		}
+		else if ((shortName.find(L".SIS",0) != std::wstring::npos)
+				|| (shortName.find(L".sis",0) != std::wstring::npos))
+		{
+			InstallSISFile sisFileName(shortName, curr->iTargetDrive, curr->iGenerateStub, 
+										curr->iNonRemovable, curr->iNotRegister, curr->iSUFlag);
+
+			sisFiles.push_back(sisFileName);
+		}
+		else
+		{
+			LWARN(L"Invalid SIS file: " << shortName);
+		}
+	}
+
+	bool installed = false;
+
+	do
+		{
+		installed = false;
+		iMissing.clear();
+		CParameterList::SISFileList::iterator curr = sisFiles.begin();
+
+		while (curr != sisFiles.end())
+			{
+			// install it
+			try 
+				{
+				LINFO(L"*** Installing " << (curr->iFileName) << L" ***");
+
+				SanitiseSISFileAttributes(*curr);
+
+				result = Install(*curr);
+
+				if ( result == SUCCESS)
+					{
+                    LINFO(L"");
+					LINFO(L"*** Installed " << (curr->iFileName) << L" ***");
+
+					installed =  true;
+					curr = sisFiles.erase(curr);
+					}
+				else
+					{
+					LERROR(L"Failed to install " << (curr->iFileName));
+					++curr;
+					}
+				}
+			catch(CSISException e)
+				{
+				// catch problems with individual sis files
+				LERROR(L"Unable to install " << (curr->iFileName));
+				LINFO(e.widewhat());
+				curr = sisFiles.erase(curr);
+				if (result == 0)
+					result =  FILE_ERROR;
+				}
+			catch  (InterpretSisError& e)
+				{
+				LERROR(L"Failed installing " << (curr->iFileName));
+				LERROR(L"\t" << Utf8ToUcs2(e.what()));
+				curr = sisFiles.erase(curr);
+				
+				if (result == 0)
+					result =  e.GetErrorCode();
+				}
+			}
+		}
+	while (installed);
+
+	if (result == 0 && !iMissing.empty())
+		result = MISSING_DEPENDENCY;
+
+	if(iParamList.RegistryVersionExists())
+		{
+	// Backup.lst regenerated at SisRegistry startup
+	iRegistry.RemoveBackupLst();
+		}
+	return result;
+
+}
+
+
+void Installer::SanitiseSISFileAttributes(const InstallSISFile& aInstallSISFile)
+{
+	SisFile file(aInstallSISFile.iFileName);
+
+	int targetDrive = aInstallSISFile.iTargetDrive;
+
+	if (!iConfigManager.IsTargetDrivePresent(targetDrive))
+	{
+		std::wstring shortName(aInstallSISFile.iFileName);
+
+		throw InterpretSisError(L"The installing target drive for " + shortName +
+				L" is not defined", CMDLINE_ERROR);
+	}
+
+	if (aInstallSISFile.iGenerateStub && !iConfigManager.IsTargetDriveExt(targetDrive))
+	{
+		std::wstring shortName(aInstallSISFile.iFileName);
+
+		throw InterpretSisError(L"The stub SIS file for " + shortName +
+				L" cannot be created to an internal drive", CMDLINE_ERROR);
+	}
+
+	if (aInstallSISFile.iGenerateStub && file.GetInstallType() == CSISInfo::EInstPartialUpgrade)
+	{
+	std::wstring shortName(aInstallSISFile.iFileName);
+
+	throw InterpretSisError(L"Generating stub SIS file for " + shortName +
+				L" (PU type) is not supported", SIS_NOT_SUPPORTED);
+	}
+}
+
+
+TInt Installer::Install(const InstallSISFile& aInstallSISFile)
+{
+	SisFile file(aInstallSISFile.iFileName);
+
+	// Setup the expression evaluator
+	SetupExpressionEnvironment( file, GetSisRegistry(), iRomManager );
+
+	// check presence of embedded sis files and 
+	// display a warning if they are not installed before
+	if (file.HasEmbedded())
+		{
+		CheckEmbedded(file);
+		}
+
+	// check file is acceptable
+	file.CheckValid();
+
+	if (!DependenciesOk(file))
+	{
+		return MISSING_DEPENDENCY;
+	}
+
+	if (!IsValidUpgrade(file, aInstallSISFile.iSUFlag))
+	{
+		return INVALID_UPGRADE;
+	}
+
+	InstallableFiles installable;
+	GetInstallableFiles(file, installable, *iExpressionEvaluator, aInstallSISFile.iTargetDrive);
+
+	// Uninstall the same package (if found) prior to any installation
+	UninstallPkg(file);
+
+	CheckDestinations(file, installable, aInstallSISFile);
+
+	InstallFiles(installable, iParamList.SystemDriveLetter());
+
+	UpdateRegistry(file, installable, aInstallSISFile, aInstallSISFile.iSUFlag);
+	
+	if (aInstallSISFile.iGenerateStub)
+	{
+		CreateStubSisFile(aInstallSISFile, file);
+	}
+
+	FreeInstallableFiles(installable);
+
+	return SUCCESS;
+}
+
+/** 
+ Prepares a list of ROM files which are allowed to be eclipsed from the right 
+ source according to the SIS file upgrade type.
+
+ If a SIS file wants to eclipse a file in ROM, it will fail unless there is an 
+ associated stub SIS file present in the ROM that can be used by the Installer to 
+ identify the replacement file as a valid upgrade of the original.  
+ */
+void Installer::PrepareEclipsableFilesList(const SisFile& aSis)
+{
+	iEclipsableRomFiles.clear();
+	iEclipsableOverwriteFiles.clear();
+
+	TUint32 pkgUid = aSis.GetPackageUid();
+
+	// upgrade SIS file attributes
+	bool puInstallation = aSis.GetInstallType() == CSISInfo::EInstPartialUpgrade;
+	bool spInstallation = aSis.GetInstallType() == CSISInfo::EInstAugmentation;
+	
+	// base package
+	const SisRegistryObject& registryEntry = iRegistry.GetRegistryObject(pkgUid);
+	bool currentPkgIsInRom = registryEntry.GetInRom();
+	bool stubExistsInRom = iRegistry.IsRomStubPackage(pkgUid); 
+
+	// SA+RU, PU and SP are all allowed to eclipse ROM files. There must
+	// exist a valid ROM stub in order to populate the eclipsable files list.
+	if (IsValidEclipsingUpgrade(aSis, registryEntry))
+	{
+		// when an upgrade happens over an upgrade which has already upgraded the 
+		// ROM based pacakge (i.e. ROM Stub -> SA+RU -> PU), don't populate the
+		// eclipsable files from the SIS registry entry which may be in-complete.
+		// Directly populate the eclipsable files list from the corresponding stub
+		// SIS file.
+		if (!currentPkgIsInRom && stubExistsInRom && (puInstallation || spInstallation))
+		{
+			iRegistry.GetStubFileEntries(pkgUid, iEclipsableRomFiles);
+		}
+		else
+		{
+			const FileDescriptions& files = registryEntry.GetFileDescriptions();
+			FileDescriptions::const_iterator curr = files.begin();
+			FileDescriptions::const_iterator end  = files.end();
+
+			for ( ; curr != end ; ++curr)
+			{
+				std::wstring target((*curr)->GetTarget());
+				iEclipsableRomFiles.push_back(target);
+			}
+		}
+	}
+}
+
+/**
+ Non-SU packages can Eclipse iff:
+ a) The package uids match and 
+ b) The package to be installed is immediate Upgrade to ROM (SP or PU over ROM)
+      (SA is allowed based on next condition)
+ c) (or) The package to be installed is (SA+RU type or PU or SP type) and it has a matching ROM stub SIS file
+ are allowed to eclipse files.    
+ */
+bool Installer::IsValidEclipsingUpgrade(const SisFile& aSis, const SisRegistryObject& registryEntry)
+{
+	TUint32 pkgUid = aSis.GetPackageUid();
+
+	// case a)
+	if (pkgUid != registryEntry.GetUid())
+		return false;
+
+	bool stubExistsInRom = iRegistry.IsRomStubPackage(pkgUid);
+	bool isBaseInRom = registryEntry.GetInRom();
+	bool saInstall = aSis.GetInstallType() == CSISInfo::EInstInstallation;
+	bool reg51 = true;
+	if(iParamList.RegistryVersionExists())
+		{
+	int regMajor = iParamList.RegistryMajorVersion();
+	int regMinor = iParamList.RegistryMinorVersion();
+	bool reg51 = (regMajor >= SisRegistry::KSisRegistryMajorVersion) &&  
+					(regMinor >= SisRegistry::KSisRegistryMinorVersion);
+		}
+	// RU flag was introduce when the SISRegistry was 5.1, otherwise, treat it as normal SA file
+	bool romUpgradeFlag = (aSis.GetInstallFlags() & CSISInfo::EInstFlagROMUpgrade) && reg51;
+	bool romUpgradableSA = saInstall && romUpgradeFlag;
+	bool puInstall = aSis.GetInstallType() == CSISInfo::EInstPartialUpgrade;
+	bool spInstall = aSis.GetInstallType() == CSISInfo::EInstAugmentation;
+	
+	// case b)
+	if (isBaseInRom && !saInstall)
+		return true;
+
+	// case c)
+	return (stubExistsInRom && (romUpgradableSA || puInstall || spInstall));    	
+}
+
+void Installer::UninstallPkg(const SisFile& aSis)
+{
+	TUint32 uid = aSis.GetPackageUid();
+	TUint32 installType = aSis.GetInstallType();
+
+	// Check to see the SA is installed, otherwise, RemovePkg() will throw an exception
+	if (iRegistry.IsInstalled(uid) && (installType == CSISInfo::EInstInstallation))
+	{
+		LINFO(L"Removing package \"" << aSis.GetPackageName() << L"\" prior to re-installation");
+
+		// Remove all installed files for this Uid's packages and all the SisRegistry Entries
+		iRegistry.RemovePkg(uid, true);
+	}
+
+	if (installType == CSISInfo::EInstAugmentation)
+	{
+		// Clean up the installed files from the specified SP package and the SisRegistry Entry
+		iRegistry.RemoveEntry(uid, aSis.GetPackageName(), aSis.GetVendorName());
+	}
+
+	// Regenerate the ROM stub registry entries for eclipsing check later.
+	iRegistry.GenerateStubRegistry();
+}
+
+
+struct CheckDependencyMet
+{
+	CheckDependencyMet(
+		Installer& aInstaller,
+		std::vector<SisRegistryDependency>& aMissing)
+		: iInstaller(aInstaller),
+		iMissingDependencies(aMissing)
+	{}
+
+	void operator()(const CSISDependency* dep)
+	{
+		if (!iInstaller.CheckDependency(dep))
+		{
+			iMissingDependencies.push_back(SisRegistryDependency(*dep));
+		}
+	}
+	Installer& iInstaller;
+	std::vector<SisRegistryDependency>& iMissingDependencies;
+};
+
+bool Installer::CheckDependency(const CSISDependency* aDep)
+{
+	bool result = false;
+
+	try
+	{
+		const SisRegistryObject& pkg =
+			iRegistry.GetRegistryObject(aDep->SisUID().UID1());
+
+		const CSISVersionRange& range = aDep->VersionRange();
+		if (!range.WasteOfSpace() && InRange(pkg.GetVersion(), range))
+			{
+			result = true;
+			}
+		else
+			{
+			result = false;
+			}
+	}
+
+	catch(...)
+	{
+		result = false;
+	}
+	return result ;
+}
+
+bool Installer::DependenciesOk(const SisFile& aFile)
+	{
+	const CSISPrerequisites* reqs = aFile.GetDependencies();
+	const CSISPrerequisites::TDependencyList& deps = reqs->DependencyList();
+
+	CheckDependencyMet checkDependencyMet(*this, iMissing[aFile.GetPackageName()]);
+	for(int i = 0; i < deps.size(); ++i)
+		{
+		checkDependencyMet(&deps[i]);
+		}
+
+	return iMissing[aFile.GetPackageName()].size() == 0;
+	}
+
+
+bool Installer::IsValidUpgrade(const SisFile& aFile, bool aSUFlag)
+{
+	TUint32 pkg = aFile.GetPackageUid();
+	TUint32 installFlags = aFile.GetInstallFlags();
+	bool RUFlag = ((installFlags & CSISInfo::EInstFlagROMUpgrade) &&  CSISInfo::EInstFlagROMUpgrade);
+
+	if(iParamList.RegistryVersionExists())
+		{
+	int regMajor = iParamList.RegistryMajorVersion();
+	int regMinor = iParamList.RegistryMinorVersion();
+	bool reg51 = (regMajor >= SisRegistry::KSisRegistryMajorVersion) &&  
+					(regMinor >= SisRegistry::KSisRegistryMinorVersion);
+	// RU flag was introduce when the SISRegistry was 5.1, otherwise, treat it as normal SA file
+		RUFlag = RUFlag && reg51;
+		}
+	if ( aSUFlag && !RUFlag)
+	{
+		std::stringstream err;
+		err << "Illegal system upgrade (SU) of ROM package 0x" << std::hex << pkg << " without setting the RU flag";
+		throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG);
+	}
+
+	// Check is this package has been installed before
+
+	TUint32 installType = aFile.GetInstallType();
+
+	if (iRegistry.IsInstalled(pkg))
+		{
+		ValidateRegistry(aFile,pkg,installFlags,RUFlag);	
+		}
+	else if (installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade)
+		{
+		// Installing SP and PU without the base package
+		std::stringstream err;
+		err << "Could not perform upgrade - the base package 0x" << std::hex 
+			<< pkg << " is missing";
+
+		throw InterpretSisError(err.str(), MISSING_BASE_PACKAGE);
+		}
+
+	return true;
+	}
+
+void Installer::ValidateRegistry(const SisFile& aFile, TUint32 aPckgUid, TUint32 aInstallFlags, bool aRUFlag)
+	{
+	bool isSisNonRemovable = aInstallFlags & CSISInfo::EInstFlagNonRemovable;
+	bool isBaseRemovable = false;
+	bool inRom = false;
+	bool isPreInstalled = false;
+	TUint32 uid = 0;
+	std::wstring packageName;
+	
+	InitializeRegistryDetails(aPckgUid, isBaseRemovable, inRom, isPreInstalled, uid, packageName );
+	
+	// Check is this package has been installed before
+	TUint32 installType = aFile.GetInstallType();
+
+	if (installType == CSISInfo::EInstInstallation)
+		{
+		if (inRom && !aRUFlag)
+			{
+			std::stringstream err;
+			err << "Illegal SA upgrade to ROM package 0x" << std::hex << aPckgUid;
+			throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG);
+			}
+		// This is not a ROM base package, check is there a SIS stub base package present
+		else if (iRegistry.IsRomStubPackage(aPckgUid) && !aRUFlag)
+			{			
+			std::stringstream err;
+			err << "Indirect SA upgrade to ROM package 0x" << std::hex << aPckgUid
+				<< " missing RU flag";
+			throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG);
+			}
+		}
+	else if (installType == CSISInfo::EInstAugmentation)
+		{
+		if (isBaseRemovable && isSisNonRemovable)
+			{
+			std::stringstream err;
+			err << "Not allowed to install SP + NR to the removable base package 0x" << std::hex << aPckgUid;
+
+			throw InterpretSisError(err.str(), INVALID_UPGRADE);
+			}
+
+		if (packageName == aFile.GetPackageName() && uid == aFile.GetPackageUid())
+			{
+			std::stringstream err;
+			err << "Cannot augment package 0x" << std::hex << aFile.GetPackageUid() << " - package names match";
+
+			throw InterpretSisError(err.str(), MISSING_BASE_PACKAGE);
+			}
+		}
+	else if (installType == CSISInfo::EInstPartialUpgrade)
+		{
+		// Do not allow partial upgrades to preinstalled applications
+		if (isPreInstalled)
+			{
+			std::stringstream err;
+			err << "Cannot install PU (0x" << std::hex << aPckgUid << ") to a PA";
+
+			throw InterpretSisError(err.str(), INVALID_UPGRADE);
+			}
+
+		// Partial Upgrade can only be installed to a base package of the same install flag type.
+		// The only exception is a ROM stub which is upgradable and non-removable by definition.
+		if ((isBaseRemovable == isSisNonRemovable) && !inRom )
+			{
+			std::stringstream err;
+			err << "Cannot install PU (0x" << std::hex << aPckgUid << ") to a base package with a different removable flag type";
+
+			throw InterpretSisError(err.str(), INVALID_UPGRADE);
+			}
+		}
+	else if (installType == CSISInfo::EInstPreInstalledApp)
+		{
+		std::stringstream err;
+		err << "Cannot install PA (0x" << std::hex << aPckgUid << ") over top of another package";
+
+		throw InterpretSisError(err.str(), INVALID_UPGRADE);
+		}
+	}
+
+void Installer::InitializeRegistryDetails(  const TUint32 aPckgUid, bool& aIsBaseRemovable, 
+											bool& aInRom, bool& aIsPreInstalled, 
+											TUint32& aUid, std::wstring& aPackageName 
+										)
+	{
+	if(iParamList.RegistryVersionExists() )
+		{
+		const SisRegistryObject& obj = iRegistry.GetRegistryObject(aPckgUid);
+		aIsBaseRemovable = obj.GetIsRemovable();
+		aInRom = obj.GetInRom();
+		aIsPreInstalled = obj.IsPreInstalled();
+		aUid = obj.GetUid();
+		aPackageName = obj.GetPackageName();
+		}
+	#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+	else
+		{
+		const DbHelper* dbHelper( iRegistry.GetDbHelper());
+		TInt32 componentId = dbHelper->GetComponentId(aPckgUid);
+		aIsBaseRemovable = dbHelper->GetIsRemovable(componentId);
+		aInRom = dbHelper->GetInRom(componentId);
+		if(dbHelper->GetInstallType(componentId) == CSISInfo::EInstPreInstalledApp )
+			{
+			aIsPreInstalled = true;
+			}
+		aUid = dbHelper->GetUid(componentId);
+		aPackageName = dbHelper->GetPackageName(componentId);
+		}
+	#endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK	
+	}
+
+bool Installer::GetInstallableFiles(const SisFile& aFile, InstallableFiles& aList, ExpressionEvaluator& aEvaluator, 
+									int aInstallingDrive)
+{
+	return aFile.GetInstallableFiles(aList, aEvaluator, 
+		iConfigManager.GetLocalDrivePath(aInstallingDrive), aInstallingDrive);
+}
+
+
+struct InstallFile
+{
+	InstallFile(const std::wstring& aCDrive, const int aSystemDrive)
+		: iSystemDrivePath(aCDrive), iSystemDrive(aSystemDrive) {}
+
+	const std::wstring& iSystemDrivePath;
+	const int iSystemDrive;
+
+	void operator()(const InstallableFile* aFile)
+	{
+		std::fstream output;
+		std::wstring target(aFile->GetTarget());
+		std::wstring localTarget(aFile->GetLocalTarget());
+
+		bool fileNullOption = (aFile->FileDescription()->Operation() == CSISFileDescription::EOpNull);
+				
+        if (!target.length())
+            {
+			LINFO(L"Skipping file with empty destination filename");
+            }
+        else
+            {
+			// Unicode characters can not be displayed on DOS prompt
+ 			std::string temporary = Ucs2ToUtf8(target);
+			std::wstring targetDisplay = Utf8ToUcs2( temporary );
+		    LINFO(L"Installing file: " << targetDisplay);
+
+            std::wstring targetDirectory = localTarget.substr( 0, localTarget.rfind( KDirectorySeparator ) );    		
+			const unsigned char* buffer = NULL;
+			TUint32 len;
+
+			if (aFile->IsStub()) // PA
+			{
+				// check the presence of file at target location 
+				if (!FileExists(localTarget))
+				{
+					throw InterpretSisError(L"PA Install error - No target file- "+target, PA_NO_TARGET_FILE);
+				}
+			}
+			else // SA 
+			{
+				// if the FN option specified, leave the file creation
+				if (fileNullOption)
+				{
+					LINFO(L"File " << target << L" contains \"Delete-File-On-Uninstall\" option." );
+				}
+				else 
+				{
+					if ( !MakeDir( targetDirectory ) )
+					{
+						throw InterpretSisError(L"Directory Creation Error - "+targetDirectory,
+													DIRECTORY_CREATION_ERROR);
+					}
+
+					HANDLE hFile = MakeSISOpenFile(localTarget.c_str(), GENERIC_WRITE, CREATE_ALWAYS);
+					if( INVALID_HANDLE_VALUE == hFile )
+					{
+						throw InterpretSisError(L"FileOpenError - "+target, FILE_ERROR);
+					}
+					buffer = aFile->FileData()->Data();
+					len = aFile->FileData()->UncompressedSize();
+					DWORD bytesWritten;
+					BOOL error = WriteFile(hFile, buffer, len, &bytesWritten, NULL);
+					if( error != TRUE )
+					{
+						throw InterpretSisError(L"FileWriteError - "+target, FILE_ERROR);
+					}
+					CloseHandle(hFile);
+				}
+			}
+
+			if (aFile->IsExecutable() && !fileNullOption)
+			{
+				// register the hash
+				std::wstring basename = localTarget.substr( localTarget.rfind( KDirectorySeparator ) + 1 );
+				std::wstring hashdir = iSystemDrivePath + L"\\sys\\hash\\";
+				std::wstring reghashdir = L"$:\\sys\\hash\\";
+
+				if ( !MakeDir( hashdir ) )
+				{
+					throw InterpretSisError(L"Directory Creation Error - "+hashdir,
+													DIRECTORY_CREATION_ERROR);
+				}
+
+				// hash file is always created on the system drive
+				reghashdir[0] = iSystemDrive;
+
+				LINFO(L"\tCreating hash: " << reghashdir << basename);
+
+				std::wstring hash = hashdir + basename;
+				HANDLE hFile = MakeSISOpenFile(hash.c_str(), GENERIC_WRITE, CREATE_ALWAYS);		
+				if( INVALID_HANDLE_VALUE == hFile )
+				{
+					throw InterpretSisError(L"FileOpenError - " + hashdir + basename, FILE_ERROR);
+				}
+
+				buffer = aFile->FileDescription()->Hash().Blob().Data();
+				len = aFile->FileDescription()->Hash().Blob().Size();
+				DWORD bytesWritten;
+				BOOL error = WriteFile(hFile, buffer, len, &bytesWritten, NULL);
+				if( error != TRUE )
+				{
+					throw InterpretSisError(L"FileWriteError - " + hashdir + basename, FILE_ERROR);
+				}
+				CloseHandle(hFile);
+			}
+        }
+	}
+};
+
+
+void Installer::InstallFiles(const InstallableFiles& aList, const int aInstallDrive)
+{
+	std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(aInstallDrive);
+
+	std::for_each(aList.begin(), aList.end(), InstallFile(localTargetPath, aInstallDrive));
+}
+
+
+void Installer::UpdateRegistry(const SisFile& aFile, const InstallableFiles& aList, 
+												   const InstallSISFile& aInstallSISFile, const bool aSUFlag)
+{
+	if (aFile.GetInstallType() == CSISInfo::EInstPartialUpgrade)
+	{
+		iRegistry.UpdateRegistryEntry(aFile, aList, aInstallSISFile);
+	}
+	else if (!aInstallSISFile.iNotRegister)
+	{
+		iRegistry.AddRegistryEntry(aFile, aList, aInstallSISFile);
+	}
+}
+
+/** This function takes a fully qualified name and searches the filesystem through for all possible adorned filename matches.
+ Besides that it calculates the unadorned version of the input filename as well and return it through the corresponding given 
+ input reference variable.
+ @param aTarget the fully qualified filename (full path and name)
+ @param aUnadornedName the calulated unadorned name is returned through this variable(full path and unadorned name calculated from aTarget)
+ @param aAdornedFileNamesFound all the found adorned name matches are returned through this list
+*/
+void Installer::AdornedProcessingOfFile(const std::wstring& aTarget, std::wstring& aUnadornedName, 
+										std::list<std::wstring>& aAdornedFileNamesFound)
+{
+	std::wstring targetNameAndExt(StringUtils::NameAndExt(aTarget));
+	std::wstring targetDriveAndPath(StringUtils::DriveAndPath(aTarget));
+
+	std::wstring unadornedName;
+	std::wstring searchNameWild;
+
+	// create the unadorned version of the target file e.g. c:\sys\bin\a.dll
+	GetUnadornedFileName(targetNameAndExt, unadornedName);
+	aUnadornedName = targetDriveAndPath;
+	aUnadornedName.append(unadornedName);
+
+	// create a wildcard version of the target file e.g. c:\sys\bin\a{????????}.dll
+	GenerateSearchNameWild(targetNameAndExt, searchNameWild);
+
+	const DrivesMap& driveMap = iConfigManager.GetDrivesMap();
+	FindAllAdornedVariants(searchNameWild, KSysBinPath, aAdornedFileNamesFound, driveMap);
+
+	// find all adorned variants in the ROM/ROFS logs
+	if (iParamList.IsFlagSet(CParameterList::EFlagsRomRofsLogFilesSet))
+	{
+		std::wstring romSearchNameWild = L"z:\\sys\\bin\\";
+		romSearchNameWild.append(searchNameWild);
+		iRomManager.FindAllAdornedVariants(romSearchNameWild, aAdornedFileNamesFound);
+	}
+}
+
+/**
+ This function ensures the SIS file to be installed does not illegally
+ eclipse a file already installed in the ROM.
+ @param aFile the SIS file to be installed
+ @param aTarget the fully qualified filename (full path and name)
+ @param aInstallableFile the current installing files properties
+ @param aSUFlag specifies if the installing SIS file has been signed by a SU certificate
+*/
+bool Installer::ValidEclipse(const SisFile& aFile, const std::wstring& aTarget, const InstallableFile& aInstallableFile, bool aSUFlag)
+{
+	bool result = true;
+	std::wstring searchNameUnadorned = L"";
+	std::wstring localDir = L"";
+	std::list<std::wstring> adornedFileNamesFound;
+
+	int targetDisk = tolower(aTarget[0]);
+	const DrivesMap& driveMap = iConfigManager.GetDrivesMap();
+
+	int count = driveMap.size();
+
+	// check for adorned (versioned) files e.g. dummy{12345678}.dll
+	if (aTarget.find(KSysBinPath) != std::wstring::npos)
+	{
+		AdornedProcessingOfFile(aTarget, searchNameUnadorned, adornedFileNamesFound);
+	}
+	else
+	{
+		searchNameUnadorned = aTarget;
+	}
+
+	DrivesMap::const_iterator it = driveMap.begin();
+	DrivesMap::const_iterator end = driveMap.end();
+
+	// search on all of defined drives (including the ROM and system drive) for
+	// the target file
+	for ( ; it != end ; ++it)
+	{
+		// drive letter
+		int disk = tolower(it->first);
+		searchNameUnadorned[0] = disk;
+		std::wstring unadornedLocalPath(searchNameUnadorned);
+
+		// check if adorned file version is found on this disk
+		bool adornedFound = false;
+
+		std::list<std::wstring>::iterator index = adornedFileNamesFound.begin();
+		std::list<std::wstring>::iterator adornedEnd = adornedFileNamesFound.end();
+		int nrOfAdornedFilenamesFound = adornedFileNamesFound.size();
+
+		for ( ; index != adornedEnd ; ++index)
+		{
+			std::wstring adornedFile = *index;
+			int drive = tolower(adornedFile[0]);
+			if (drive == disk)
+			{
+				adornedFound = true;
+				break;
+			}
+		}
+		
+		// the actual directory
+		localDir = it->second->iDir;
+		bool unadornedFound;
+
+		// check to see if we are using ROM/ROFS files to represent the z drive.
+		// If so, check to see if the ROM file exists in the logs.
+		if (disk == 'z' && localDir.empty())
+		{
+			unadornedFound = iRomManager.RomFileExists(searchNameUnadorned);
+		}
+		else
+		{
+			// convert to the local path and see if the file exists on the current drive
+			ConvertToLocalPath( unadornedLocalPath, localDir );
+			unadornedFound = FileExists(unadornedLocalPath);
+		}
+
+		bool matchFound = unadornedFound || adornedFound;
+		if (!matchFound)
+			continue;
+
+		bool processEclipsingSuspectsFoundOnThisDrive = false;
+		
+		// The logic varies whether we find an eclipsable/overwritable file on: (1) The same disk as the one we are installing to
+		// (2) The Z drive (ROM), (3) Any other drive
+		if (disk == targetDisk)  // case (1)
+		{
+			bool isOverwrite = FileExists(aInstallableFile.GetLocalTarget());
+			
+			// there are 3 possible cases: (1.1) We are correctly overwriting the already present file (a PU), 
+			// (1.2) We are incorrectly overwriting the file present, (1.3) We are eclipsing the file (if one of the file names is adorned)
+			if (isOverwrite)
+			{
+				// case 1.1 and 1.2 are handled here - overwrite the file if we have the right to do so.
+				HandleFileOverwriting(aFile, aTarget, aSUFlag);
+			}
+			else
+			{
+				// case 1.3 is handled here: 
+				// we have found a matching filename (either unadorned or adorned); add it to the eclipsing suspects
+				processEclipsingSuspectsFoundOnThisDrive = true;
+			}
+		}
+		else if (disk == 'z') // case (2)
+		{
+			// we are eclipsing a ROM file, check if this is authorised:
+			// see implementation of IsEclipsable()
+			if (!IsEclipsable(searchNameUnadorned, aSUFlag))
+			{
+				result = false;
+				break;
+			}
+		}
+		else // case (3)
+		{
+			processEclipsingSuspectsFoundOnThisDrive = true;
+		}
+
+		// now check to see whether the unadorned or the adorned filename found on 
+		// this drive should be added to iEclipsableOverwriteFiles.
+		if (processEclipsingSuspectsFoundOnThisDrive && unadornedFound)
+		{
+			iEclipsableOverwriteFiles.push_back(searchNameUnadorned);
+		}
+
+		if (processEclipsingSuspectsFoundOnThisDrive && adornedFound)
+		{
+			nrOfAdornedFilenamesFound = adornedFileNamesFound.size();
+			std::list<std::wstring>::iterator index = adornedFileNamesFound.begin();
+			std::list<std::wstring>::iterator adornedEnd = adornedFileNamesFound.end();
+
+			// add the adorned filenames found to the list of eclipsable/overwrite candidates
+			for ( ; index != adornedEnd ; ++index)
+			{
+				std::wstring adornedFile = *index;
+				int drive = tolower(adornedFile[0]);
+				if (drive == disk)
+				{
+					iEclipsableOverwriteFiles.push_back(adornedFile);
+				}
+			}
+		}
+	}
+	// end of loop
+
+	// the final step is to try and remove all the files from iEclipsableOverwriteFiles that
+	// will prevent this SIS file from installing.
+	if (result && (iEclipsableOverwriteFiles.size() > 0))
+	{
+		FilterNonBlockingFilesOfFilename(aFile, aTarget);
+	}
+
+	return result;
+}
+
+/** Checks the list of eclipsable candidate files against those that are owned by the 
+ installing package (if any). Blocking files are removed if a match is found.
+ @param aFile the SIS file to be installed
+ @param aTarget the fully qualified filename (full path and name)
+*/
+void Installer::FilterNonBlockingFilesOfFilename(const SisFile& aFile, const std::wstring& aTarget)
+{
+	// if the package aleady exists
+	TUint32 pkgUid = aFile.GetPackageUid();
+	if (iRegistry.IsInstalled(pkgUid))
+	{
+		const SisRegistryObject& registryEntry = iRegistry.GetRegistryObject(pkgUid);
+		const FileDescriptions& installedFiles = registryEntry.GetFileDescriptions();			
+	
+		FileDescriptions::const_iterator inCurr = installedFiles.begin();
+		FileDescriptions::const_iterator inEnd  = installedFiles.end();
+
+		for ( ; inCurr != inEnd ; ++inCurr)
+		{
+			std::wstring baseFile((*inCurr)->GetTarget());
+
+			std::list<std::wstring>::iterator eCurr = iEclipsableOverwriteFiles.begin();
+			std::list<std::wstring>::iterator eEnd = iEclipsableOverwriteFiles.end();
+
+			for ( ; eCurr != eEnd; ++eCurr)
+			{
+				std::wstring eclipseFile(*eCurr);
+				
+				// the installed base package owns the eclipse/overwrite candidate
+				if (FoldedCompare(baseFile, eclipseFile) == 0)
+				{
+					// we are installing a new adorned variant of a file, so remove the blocking
+					// file from the list
+					if (StringUtils::NameAndExt(baseFile) != StringUtils::NameAndExt(aTarget))
+					{
+						eCurr = iEclipsableOverwriteFiles.erase(eCurr);
+					}
+				}
+			}
+		}
+	}
+}
+
+/** This function examines the list of ROM files we may eclipse to see if the supplied name is among them.
+ Here we have 2 options:
+ 1)   file is not to be installed to \sys\bin\
+      in this case we don't invoke special handling of adorned filenames so we are only
+      interested in if that particular file is allowed to be eclipsed
+ 2)   file is to be installed to \sys\bin therefore we have to handle adorned filenames.
+      Eclipsing is allowed if the filename that we are trying to install is a variant of any ROM filename 
+      marked as eclipsable i.e: if we are trying to install c:\sys\bin\A{000A0001}.dll
+      and we have z:\sys\bin\A.dll as an eclipsable file or any z:\sys\bin\A{????????}.dll
+      then we are allowed to eclipse.
+ @param aRomFile fully qualified filename in ROM that is to be checked for eclipising (i.e: z:\sys\bin\some.dll)
+ @param aSUFlag specifies if the installing SIS file has been signed by a SU certificate
+*/
+bool Installer::IsEclipsable(std::wstring& aRomFile, bool aSUFlag)
+{
+	// SA/SP/PU sis + RU flag + signed by SU root cert is allowed
+	if (aSUFlag)
+		return true;
+
+	bool isEclipsable = false;
+	bool goesToSysBin = (aRomFile.compare(KSysBinPath) != std::wstring::npos);
+
+	// go through the list of ROM files which are allowed to be eclipsed
+	std::list<std::wstring>::const_iterator end = iEclipsableRomFiles.end();
+	for (std::list<std::wstring>::const_iterator curr = iEclipsableRomFiles.begin() ;
+		 curr != end; ++curr)
+	{
+		std::wstring eclipsableRomFile = *curr;
+		
+		// support wildcard characters in ROM stub files
+		if (StringUtils::WildcardCompare(eclipsableRomFile,aRomFile)) // case 1
+		{
+			isEclipsable = true;
+			break;
+		}
+		else if (goesToSysBin) // case 2
+		{
+			if (IsAdornedVariationOf(eclipsableRomFile,aRomFile))
+			{
+				isEclipsable = true;
+				break;
+			}
+		}
+	}
+
+	return isEclipsable;
+}
+
+/** This function handles overwriting scenarios (i.e: we are trying to install c:\somedir\somename.ext however it already exists)
+ In this case we have 2 possibilities:
+ 1) We are correctly overwriting the already present file (a PU)
+ 2) We are incorrectly overwriting the file present
+ @param aFile the SIS file to be installed
+ @param aTarget The fully qualified filename (full path and name)
+ @param aSUFlag specifies if the installing SIS file has been signed by a SU certificate
+*/
+void Installer::HandleFileOverwriting(const SisFile& aFile, const std::wstring& aTarget, bool aSUFlag)
+{
+	// find out which package this file belongs to
+	TUint32 owningUid = 0;
+	const SisRegistryObject* owningObj = iRegistry.OwningPackage(aTarget,owningUid);
+	bool isSp = aFile.GetInstallType() == CSISInfo::EInstAugmentation;
+	bool isPu = aFile.GetInstallType() == CSISInfo::EInstPartialUpgrade;
+	bool isSa = aFile.GetInstallType() == CSISInfo::EInstInstallation;
+
+	// no package owns this file. Always allow orphaned file overwriting!
+	if (owningUid == 0)
+	{
+		// do not display a warning if the installing file is a PA. The user
+		// needs to copy the installing files to the installing directory
+		// prior to installing the SIS file.
+		std::string tempTarget = Ucs2ToUtf8(aTarget);
+  	  	std::wstring targetDisplay = Utf8ToUcs2( tempTarget );
+		if (aFile.GetInstallType() == CSISInfo::EInstPreInstalledApp)
+		{
+			LINFO(targetDisplay << L" found for PA installation");
+		}
+		else
+		{
+			LWARN(targetDisplay << L" overwrites orphaned file");
+		}
+	}
+	else if (aFile.GetPackageUid() == owningUid)
+	{
+		// SP can not overwrite a file in the base pkg
+		if (isSp)
+		{
+			std::wostringstream os;
+			os << aTarget << L" overwrites file from base package 0x" << std::hex << owningUid << L" \"" << owningObj->GetPackageName() << L"\"" << std::endl;
+			iProblemFiles.append(os.str());
+			iError = ECLIPSING_VIOLATION;
+		}
+	}
+	else
+	{
+		// SP can not overwrite a file belonging to a different base pkg
+		// PU/SA can not overwrite a file belonging to a different base pkg unless it has been signed by
+		// a SU cert
+		if (isSp || (!aSUFlag && (isPu || isSa)))
+		{
+			std::wostringstream os;
+			os << aTarget << L" overwrites file from base package 0x" << std::hex << owningUid << L" \"" << owningObj->GetPackageName() << L"\"" << std::endl;
+			iProblemFiles.append(os.str());
+			iError = ECLIPSING_VIOLATION;
+		}
+		else
+		{
+			LWARN(aTarget << L" overwrites file from base package 0x" << std::hex << owningUid << L" \"" << owningObj->GetPackageName() << L"\"");
+		}
+	}
+}
+
+void Installer::WarnEclipseOverWrite(const SisFile& aFile)
+{
+	// we still have some blocking files left after we have checked the destination
+	// of the installing file.
+	if (iEclipsableOverwriteFiles.size()>0)
+	{
+		// InterpretSIS allows orphan file eclipsing/overwriting
+		std::list<std::wstring>::const_iterator curr = iEclipsableOverwriteFiles.begin();
+		std::list<std::wstring>::const_iterator end = iEclipsableOverwriteFiles.end();
+		
+		for ( ; curr != end; ++curr)
+		{
+			std::wstring eclipseFile(*curr);
+
+			TUint32 owningUid = 0;
+			const SisRegistryObject* owningObj = iRegistry.OwningPackage(eclipseFile, owningUid);
+			
+			// always allow orphaned file overwriting
+			if (owningUid == 0)
+			{
+				LWARN(eclipseFile << L" eclipses orphaned file.");
+			}
+			else
+			{
+				// SP/PU can not overwrite a file belonging to a different base pkg or
+				// SP/PU can not eclipse a base package which is not in the ROM.
+				std::wostringstream os;
+				os << eclipseFile << L" eclipses file from package 0x" << std::hex << owningUid << L" \"" << owningObj->GetPackageName() << L"\"" << std::endl;
+				iProblemFiles.append(os.str());
+				iError = ECLIPSING_VIOLATION;
+				continue;
+			}
+		}		
+	}
+}
+
+void Installer::CheckDestinations(const SisFile& aFile, InstallableFiles& aFiles, 
+								  const InstallSISFile& aInstallSISFile)
+{
+	bool suFlag = aInstallSISFile.iSUFlag;
+	
+	// if the -e option or InstallSISFile::iNotRegister is set, disable the eclipsing checks
+	bool isEclipseAllowed = (iParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet)) || aInstallSISFile.iNotRegister;
+
+	iError = SUCCESS;
+
+	Sids sids;
+	GetSidsFromInstallable(aFiles, sids);
+
+	const std::wstring privatePath = L":\\private\\";
+	const std::wstring sysPath = L":\\sys\\";
+	const std::wstring sysBinPath = L":\\sys\\bin\\";
+	const std::wstring resourcePath = L":\\resource\\";
+	const std::wstring exeType = L".exe";
+
+    int num_of_files = aFiles.size();
+	TUint32 pkgUid = aFile.GetPackageUid();
+	TUint32 installType = aFile.GetInstallType();
+	std::list<std::wstring> stubFileEntries;
+
+	iRegistry.GetStubFileEntries(pkgUid, stubFileEntries);
+
+	// if a base package exists, check to see if it chains back to a ROM stub. If so, populate
+	// iEclipsableRomFiles with the files owned by the ROM stub. Only ROM files can be eclipsed.
+	//
+	// if the package has been signed by a SU cert, then there is no need to generate the eclipsable
+	// file list - it is allowed to eclipse any file in the ROM.
+	if (iRegistry.IsInstalled(pkgUid) && !suFlag)
+		{
+		PrepareEclipsableFilesList(aFile);
+		}
+
+	// loop through the files to be installed
+	for( int ii=num_of_files-1; ii>=0; ii-- )
+	{   
+		const InstallableFile* file = aFiles[ ii ];
+        const CSISFileDescription* sisDescription = file->FileDescription();
+
+		// file to be installed
+		std::wstring target( file->GetTarget() );
+
+		if (sisDescription->Operation() == CSISFileDescription::EOpText)
+			break;
+		if (sisDescription->Operation() == CSISFileDescription::EOpNull)
+			{
+			// a FN file can not remove a file from \sys or \resource
+			if ((target.find(sysPath,0) != std::wstring::npos) || (target.find(resourcePath,0) != std::wstring::npos))
+				{
+				// eclipsing problem
+				std::wostringstream os;
+				os << L"FN file \"" << target << L"\" can not remove a file from \\sys or \\resource" << std::endl;
+				iProblemFiles.append(os.str());
+				iError = DATA_CAGE_VIOLATION;
+				continue;
+				}
+			}
+        else 
+            {
+			std::wstring realTarget(file->GetLocalTarget());
+
+		    std::wstring romTarget(target);
+			romTarget[0] = KRomDriveLetter;
+
+			// check to see if we are legally allowed to eclipse a ROM file 
+			if (!isEclipseAllowed)
+			{
+				if (!ValidEclipse(aFile, target, *file, suFlag))
+				{
+					// eclipsing problem
+					std::wostringstream os;
+					os << target << L" eclipses file from ROM" << std::endl;
+					iProblemFiles.append(os.str());
+					iError = ECLIPSING_VIOLATION;
+					continue;
+				}
+			}
+			
+			// additional platsec checks
+			if (target.find(privatePath) != std::wstring::npos)
+		    {
+				// add an extra one for the drive letter
+			    TInt start = privatePath.size()+1;
+			    TInt end   = target.find( KDirectorySeparator[ 0 ], start);
+
+			    std::wistringstream uidStr(target.substr(start,end-start));
+
+			    TUint32 sid = 0;
+			    uidStr >> std::hex >> sid;
+				
+				if (sid == 0)
+					break;
+
+				// if a file in a private directory is registered, check to see if
+				// it belongs to this package
+			    if (std::find(sids.begin(), sids.end(), sid) == sids.end())
+			    {
+					TUint32 sidOwnerPkgUId = KNullUid;
+
+					if (iRegistry.SidExists(sid))
+					{
+						if(iParamList.RegistryVersionExists())
+							{
+						// SID belongs to some package, lets find out its UID
+						const SisRegistryPackage& sisRegistryPkg = iRegistry.SidToPackage(sid);
+
+						sidOwnerPkgUId = sisRegistryPkg.GetUid();
+							}
+						else
+							{
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+							sidOwnerPkgUId = iRegistry.GetUid(sid);
+#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+							}
+					}
+
+					if (sidOwnerPkgUId != pkgUid)
+					{
+						// this package is trying to write to a SID's private directory 
+						// which does not belong to this package
+
+						const int KUidStringLength = 8;
+						std::wstring importPath = privatePath;
+
+						importPath.append( uidStr.str() + L"\\import" );
+
+						if ((target.find(importPath,0) == std::wstring::npos) && !suFlag)
+						{
+							// only SA with RU + SU and PU with RU + SU flag can override other private directory
+							std::wostringstream os;
+							os << target << L" cannot be written to a private directory which "
+								<< L"does not belong to any exe in this package" << std::endl;
+							iProblemFiles.append(os.str());
+							iError = DATA_CAGE_VIOLATION;
+							continue;
+						}
+					}
+			    }
+		    }
+		    else if (file->IsExecutable())
+		    {
+				TUint32 sid = file->Sid();
+
+				std::wstring romFileWithDuplicateSid(L"");
+				bool sidExistsInRom = iRomManager.SidExistsInRom(romFileWithDuplicateSid, sid);
+				bool sidExistsInRegistry = iRegistry.SidExists(sid);
+
+				if (sidExistsInRegistry && file->IsExe())
+				{
+					// the .EXE which owns the SID
+					std::wstring owningSidFile;
+					iRegistry.SidToFileName(sid,owningSidFile);
+
+					bool owningPkgInRom = false;
+					bool samePkgUid = false;
+					TUint32 owningPkg = 0;
+					if(iParamList.RegistryVersionExists())
+						{
+						// the SisRegistryObject which owns the .EXE
+						
+						const SisRegistryObject* owningObj = iRegistry.OwningPackage(owningSidFile,owningPkg);
+
+						owningPkgInRom = owningObj->GetInRom();
+						samePkgUid = (owningPkg == pkgUid);
+						}
+					else
+						{
+						#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+							owningPkg = iRegistry.GetUid(owningSidFile);
+							owningPkgInRom = iRegistry.GetInRom(owningPkg);
+							samePkgUid = (owningPkg == pkgUid);
+						#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+						}
+					std::wstring targetName = StringUtils::NameAndExt(file->GetTarget());
+					std::wstring owningSidFileName = StringUtils::NameAndExt(owningSidFile);
+
+					bool sameTargetName = (FoldedCompare(targetName,owningSidFileName) == 0);
+					bool romStubExists = iRegistry.IsRomStubPackage(pkgUid);
+					bool validInstallType = (installType == CSISInfo::EInstInstallation || installType == CSISInfo::EInstPartialUpgrade || installType == CSISInfo::EInstAugmentation);
+
+					// allow SID eclipsing in the following scenarios:
+					// 1) SIS file has been signed by a SU cert
+					// 2) eclipsing checks have been disabled by the user (using -e)
+					// 3) SP/PU/SA+RU eclipsing of a ROM stub
+					bool allowSidEclipse = false;
+
+					// case 1 and 2
+					if (suFlag || isEclipseAllowed)
+						allowSidEclipse = true;
+
+					// case 3
+					if (validInstallType && sameTargetName && samePkgUid && (owningPkgInRom || romStubExists))
+					{
+						allowSidEclipse = true;
+					}
+					
+					if (!allowSidEclipse)
+					{
+						std::wostringstream os;
+										
+						os << L"The existing file " << owningSidFile << L" already has the SID 0x" << std::hex << sid
+						   << std::dec << L", cannot install " << target << std::endl;
+						iProblemFiles.append(os.str());
+						iError = DUPLICATE_SID;
+						continue;
+					}
+				}
+				// .EXE exists in the ROM, but no ROM stub has ownership of it
+				else if (sidExistsInRom)
+				{
+					// A ROM stub could have referenced this .EXE using wildcards - in this case the SID will not
+					// be registered in the SIS registry.
+					bool isInstalled = iRegistry.IsInstalled(pkgUid);
+					bool ownedByRomStub = false;
+					if (isInstalled)
+					{
+						if (iRegistry.IsRomStubPackage(pkgUid))
+						{
+							CSISController* sisController = iRegistry.GetStubController(pkgUid);
+							TFileDescList fileDesList;
+							sisController->InstallBlock().GetFileList(fileDesList);
+							for(TFileDescListConstIter iter = fileDesList.begin(); iter != fileDesList.end(); ++iter)
+							{
+								const CSISFileDescription* fD = *iter;
+
+								std::wstring romStubTarget(fD->Target().GetString());
+
+								if (StringUtils::WildcardCompare(romStubTarget,romFileWithDuplicateSid))
+								{
+									ownedByRomStub = true;
+									break;
+								}
+							}
+						}
+					}
+
+					bool allowSidEclipse = false;
+
+					if (suFlag || isEclipseAllowed)
+						allowSidEclipse = true;
+
+					if (!allowSidEclipse && !ownedByRomStub)
+					{
+						std::wostringstream os;
+											
+						os << L"A ROM file already has the SID 0x" << std::hex << file->Sid()
+						   << std::dec << L", cannot install " << target << std::endl;
+						iProblemFiles.append(os.str());
+						iError = DUPLICATE_SID;
+						continue;
+					}
+				}
+		    }
+		    else if (realTarget.find(sysBinPath) != std::wstring::npos)
+		    {
+				std::wostringstream os;
+				os << target << L" cannot be installed to a data caged area" << std::endl;
+				iProblemFiles.append(os.str());
+				iError = DATA_CAGE_VIOLATION;
+				continue;
+		    }
+        }
+	}
+
+	// we still may have blocking files left. Handle them here.
+	WarnEclipseOverWrite(aFile);
+
+	iEclipsableOverwriteFiles.clear();
+	iEclipsableRomFiles.clear();
+
+	if (!iProblemFiles.empty())
+	{
+		std::string x;
+		throw InvalidSis("", Ucs2ToUtf8(iProblemFiles,x), iError);
+	}
+}
+
+void Installer::SetupExpressionEnvironment(const SisFile& aFile, const SisRegistry& aSisRegistry, RomManager& aRomManager )
+{
+	delete iExpressionEnvironment;
+	iExpressionEnvironment = new ExpressionEnvironment( aFile,
+                                                        aSisRegistry,
+                                                        iRomManager,
+                                                        iConfigManager,
+                                                        iParamList.SystemDrivePath() );
+    
+    delete iExpressionEvaluator;
+    iExpressionEvaluator = new ExpressionEvaluator( *iExpressionEnvironment );
+}
+
+void Installer::CheckEmbedded(const SisFile& aFile)
+{
+	PackageUids pkgs = aFile.GetEmbeddedPackageUids();
+
+	for (PackageUids::const_iterator curr = pkgs.begin() ;
+		 curr != pkgs.end() ;
+		 ++curr)
+	{
+		 if (!iRegistry.IsInstalled(*curr))
+		 {
+			 
+			 LWARN(L" Embedded Package not installed: UID " << std::hex << *curr );
+		 }
+	}
+}
+
+
+void Installer::CreateStubSisFile(const InstallSISFile& aInstallSISFile, SisFile& aSis)
+{
+	int targetDrive = aInstallSISFile.iTargetDrive;
+	std::wstring drivePath = iConfigManager.GetLocalDrivePath(targetDrive);
+	
+	drivePath.append(L"\\private\\");
+
+	// build SwiDaemon Pathname
+	std::wstring ctrl = StringUtils::MakePathFromSID(drivePath, KSwiDaemonUid);
+
+	if ( !MakeDir( ctrl ) )
+	{
+		throw InterpretSisError(L"Directory Creation Error - "+ctrl, DIRECTORY_CREATION_ERROR);
+	}
+
+	std::wstringstream s;
+	s << std::hex << aSis.GetPackageUid();
+
+	ctrl.append(s.str());
+
+
+	switch(aSis.GetInstallType())
+    {
+	case CSISInfo::EInstInstallation:
+	case CSISInfo::EInstPreInstalledApp:
+		{
+			// If an Installation type is SA/PA then append _0 after the stub UID.
+			ctrl.append(L"_0");
+			break;
+		}
+
+	case CSISInfo::EInstAugmentation:
+		{
+			// If an Installation type is SP then append an index after the stub UID.
+
+			int num = 0;
+
+			ctrl.append( L"_");
+			
+			if (aInstallSISFile.iNotRegister)
+			{
+				// In this case, we can only assume all the previous SP installations 
+				// (of a particular package) are consistently installed to the same target 
+				// drive and all of the SP installation's attribute are set to either 
+				// +mcardalone OR +mcardalonenr. Otherwise, the generated index will be wrong.
+
+				// Get the index from the daemon folder
+				num = GetAugmentationsNumber(ctrl);
+			}
+			else
+			{
+				// In this case, we can only assume all the previous SP installations 
+				// (of a particular package) is consistent with attributes set to either 
+				// +mcard OR +mcardnr. Otherwise, the generated index will be wrong.
+
+				// Get the index from the sisregistry entries
+				num = iRegistry.GetAugmentationsNumber(aSis.GetPackageUid());
+			}
+
+			std::wstringstream s2;
+			s2 << std::hex << num;
+			ctrl.append( s2.str() );
+			break;
+		}
+
+	default:
+		{
+			std::wstring err(L"SIS file cannot be propagated: ");
+			err.append(aInstallSISFile.iFileName);
+			throw InterpretSisError(err, SIS_NOT_SUPPORTED);
+		}
+	}
+
+	ctrl.append(L".sis");
+
+	// Display the target SIS file. Format the stub SIS file string so it displays correctly.
+	std::wstring ctrlDrive(L"$:");
+	ctrlDrive[0] = targetDrive;
+	std::wstring ctrlTarget = ctrl.substr(iConfigManager.GetLocalDrivePath(targetDrive).length(),ctrl.length());
+	ctrlDrive.append(ctrlTarget);
+
+	LINFO(L"\tCreating stub: " << ctrlDrive);
+
+	aSis.MakeSISStub(ctrl);
+	// If the NR flag is set, change the file attribute to RO
+	if (aInstallSISFile.iNonRemovable)
+	{
+		_wchmod(ctrl.c_str(),_S_IREAD);
+	}
+}