secureswitools/swisistools/source/interpretsislib/sisfile.cpp
changeset 0 ba25891c3a9e
child 12 7ca52d38f8c3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/interpretsislib/sisfile.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,477 @@
+/*
+* 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: 
+*
+*/
+
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4786)
+#endif 
+
+// System Includes
+#include <openssl/sha.h>
+#include <iostream>
+
+// User Includes
+#include "is_utils.h"
+#include "errors.h"
+#include "sisfile.h"
+#include "controllerinfo.h"
+#include "hashcontainer.h"
+#include "expressionevaluator.h"
+
+// SisX Library Includes
+#include "sisfiledescription.h"
+#include "sisfiledata.h"
+#include "siscontents.h"
+#include "siscontroller.h"
+#include "sisinfo.h"
+#include "sisinstallblock.h"
+#include "sisarray.h"
+#include "sissupportedlanguages.h"
+#include "sissupportedoptions.h"
+#include "sissupportedoption.h"
+#include "sislanguage.h"
+#include "sisdataunit.h"
+#include "sisdata.h"
+#include "sisstring.h"
+
+const std::string Type2String(CSISInfo::TSISInstallationType aType)
+{
+	switch (aType)
+	{
+	case CSISInfo::EInstInstallation :
+		return "SA";
+	case CSISInfo::EInstAugmentation :
+		return "SP";
+	case CSISInfo::EInstPartialUpgrade :
+		return "PU";
+	case CSISInfo::EInstPreInstalledApp :
+		return "PA";
+		break;
+	case CSISInfo::EInstPreInstalledPatch :
+		return "PP";
+	default:
+		return "Invalid/Unknown Type";
+	}
+}
+
+
+SisFile::~SisFile()
+	{
+	}
+
+SisFile::SisFile(const std::wstring& aFilename)
+	{
+	iContents.Load(aFilename);
+	}
+
+
+TUint32 SisFile::GetPackageUid() const
+	{
+	return iContents.UID1();
+	}
+
+
+const CSISPrerequisites* SisFile::GetDependencies() const
+	{
+	return &iContents.Controller().Prerequisites();
+	}
+
+
+const CSISProperties* SisFile::GetProperties() const
+	{
+	return &iContents.Controller().Properties();
+	}
+
+std::wstring SisFile::GetVendorLocalName() const
+	{
+	return iContents.Controller().SISInfo().VendorName();
+	}
+
+
+void SisFile::GetControllerData(const char*& aData, int& aLen) const
+	{
+	aData = (char*)iContents.Controller().RawBuffer();
+	aLen = iContents.Controller().RawBufferSize();
+	}
+
+const CSISController& SisFile::GetController()
+	{
+		return iContents.Controller();
+	}
+
+bool SisFile::GetInstallableFiles(InstallableFiles& aFiles, 
+								  ExpressionEvaluator& aEvaluator,
+								  const std::wstring& aDrivePath,
+								  int aInstallingDrive) const
+{
+	bool success = true;
+	
+	CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType();
+	int count = iContents.SisData().DataUnitCount();
+	const CSISDataUnit* dataUnit = NULL;
+	
+	if (installType ==  CSISInfo::EInstInstallation || installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade)
+		{
+		dataUnit = &(iContents.DataUnit(0));
+		}
+
+	// Logo
+	if (!iContents.Controller().SISLogo().WasteOfSpace())
+		{
+		const CSISFileDescription& fileDes = iContents.Controller().SISLogo().FileDesc();
+
+		// FT or empty target file names are not installed
+		if(fileDes.Operation() != CSISFileDescription::EOpText && fileDes.Target().size() > 0)
+			{
+			// for PA stub sis files no file data present,
+			// aFiles will be filled with only file descriptions of files, empty file data
+			if (NULL != dataUnit && fileDes.Operation() != CSISFileDescription::EOpNull)
+				{
+				aFiles.push_back(new InstallableFile(fileDes, new CSISFileData(dataUnit->FileData(fileDes.FileIndex())), aDrivePath, aInstallingDrive));		
+				}
+			else 
+				{
+				// SIS files will not be present in PA stubs
+				aFiles.push_back( new InstallableFile(fileDes,aDrivePath,aInstallingDrive));		
+				}
+			}
+		}
+
+	// process main controller - data unit 0
+	const CSISInstallBlock& installBlock = iContents.Controller().InstallBlock();
+
+	ProcessInstallBlock(installBlock, aFiles, aEvaluator, aDrivePath, aInstallingDrive);
+
+	return success;
+}
+
+bool SisFile::HasEmbedded() const
+{
+	const CSISInstallBlock& blk = iContents.Controller().InstallBlock();	
+	TControllerMap embeddedCtls;
+	iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false);
+	
+	return (embeddedCtls.size() != 0);	
+}
+
+void SisFile::CheckValid() const
+	{
+	std::string error;
+
+	CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType();
+	// Allow SA, SP, PU and PA(stub) installations only
+	bool success = 	(installType == CSISInfo::EInstInstallation) 	|| 
+					(installType == CSISInfo::EInstPreInstalledApp)	||
+					(installType == CSISInfo::EInstAugmentation) 	|| 
+					(installType == CSISInfo::EInstPartialUpgrade);
+
+	if (installType == CSISInfo::EInstPreInstalledApp)
+		{
+		LWARN(L"Installation of PA type SIS files may cause problems on upgrade and/or restoration. Please see the documentation for details." );
+		}
+
+	if (!success)
+		{
+		std::string type = Type2String(installType);
+		error = "Invalid package type (" + type + ")";
+		}
+	bool failed = !success;
+
+    
+	success = iContents.Controller().SupportedOptionCount() == 0;
+	if (!success)
+		error += "SIS File contains user options";
+	failed = failed || !success;
+
+	const CSISInstallBlock& blk = iContents.Controller().InstallBlock();
+
+	int fileCount = blk.FileCount();
+	for(int i = 0; i < fileCount; ++i)
+		{
+		const CSISFileDescription& fD = blk.FileDescription(i);
+        const CSISFileDescription::TSISFileOperation operation = fD.Operation();
+		std::wstring target(fD.Target().GetString());
+        //
+        switch( operation )
+            {
+        case CSISFileDescription::EOpInstall:
+            success = true;
+            break;
+        case CSISFileDescription::EOpRun:
+        	{
+				const CSISFileDescription::TSISInstOption operationOptions = fD.OperationOptions();
+				if(operationOptions & CSISFileDescription::EInstFileRunOptionByMimeType)
+				{
+					LWARN(L"File " << target << L" contains \"Run-Using-MIME\" option that will be ignored.");
+				}
+				if((operationOptions & CSISFileDescription::EInstFileRunOptionInstall) \
+						&& (operationOptions & CSISFileDescription::EInstFileRunOptionUninstall))
+				{
+					LWARN(L"File " << target << L" contains \"RUN-BOTH\" option that will be ignored.");			
+				}
+				else if(operationOptions & CSISFileDescription::EInstFileRunOptionInstall)
+				{
+					LWARN(L"File " << target << L" contains \"Run-On-Install\" option that will be ignored.");			
+				}
+				else if(operationOptions & CSISFileDescription::EInstFileRunOptionUninstall)
+				{
+					LWARN(L"File " << target << L" contains \"Run-On-Uninstall\" option that will be ignored.");			
+				}
+				if(operationOptions & CSISFileDescription::EInstFileRunOptionBeforeShutdown)
+				{
+					LWARN(L"File " << target << L" contains \"Run-Before-Shutdown\" option that will be ignored.");			
+				}
+                if(operationOptions & CSISFileDescription::EInstFileRunOptionAfterInstall)
+				{
+					LWARN(L"File " << target << L" contains \"Run-After-Install\" option that will be ignored.");			
+				}
+				LWARN(L"File " << target << L" contains \"File-Run\" option that will be ignored.");			
+			}
+            success = true;
+            break;
+        case CSISFileDescription::EOpText:
+        	LWARN(L"File " << target << L" contains \"Display Text\" option that will be ignored." );
+            success = true;
+            break;
+        case CSISFileDescription::EOpNull:
+            success = true;
+            break;
+        default:
+            success = false;
+            break;
+            }
+		//
+        if (!success)
+    		{
+			error += "SIS File contains install options : "+operation;
+			break;
+	    	}
+		}
+	failed = failed || !success;
+
+	if (failed)
+		{
+		std::string x;
+		throw InvalidSis(Ucs2ToUtf8(this->GetPackageName(),x),
+			error, SIS_NOT_SUPPORTED);
+		}
+	}
+
+std::wstring SisFile::GetVendorName() const
+	{
+	return iContents.Controller().SISInfo().UniqueVendorName();
+	}
+
+std::wstring SisFile::GetPackageName() const
+	{
+	return iContents.Controller().SISInfo().PackageName(0);
+	}
+
+TUint32 SisFile::GetIndex() const
+	{
+	return iContents.Controller().DataIndex();
+	}
+
+TUint32 SisFile::GetSigned() const
+{
+	return true;
+}
+
+TUint32 SisFile::GetInstallType() const
+	{
+	return iContents.Controller().SISInfo().InstallationType();
+	}
+
+TUint32 SisFile::GetInstallFlags() const
+	{
+	return iContents.Controller().SISInfo().InstallationFlag();
+	}
+
+TUint32 SisFile::GetLanguage() const
+	{
+	return iContents.Controller().Language(0);
+	}
+
+Version SisFile::GetVersion() const
+	{
+	const CSISVersion& v =	iContents.Controller().SISInfo().SISVersion();
+	return Version(v.Major(), v.Minor(), v.Build());
+	}
+
+const Controllers SisFile::GetControllerInfo(const TUint16 aRegistryFileMajorVersion, 
+											 const TUint16 aRegistryFileMinorVersion) const
+	{
+	ControllerInfo* ci = new ControllerInfo();
+	ci->SetVersion(GetVersion());
+	ci->CalculateAndSetHash(iContents.Controller(),aRegistryFileMajorVersion,aRegistryFileMinorVersion);
+	ci->SetOffset(0);
+	Controllers c;
+
+	c.push_back(ci);
+
+	// Embedded controllers
+	
+	TControllerMap embeddedCtls;
+	iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false);
+	for (TControllerMapConstIter iter = embeddedCtls.begin(); iter != embeddedCtls.end(); ++iter)	
+		{
+		const CSISController& ctrl = *iter->second;
+		ControllerInfo* ci = new ControllerInfo();
+
+		ci->SetVersion(GetVersion());
+		ci->CalculateAndSetHash(ctrl,aRegistryFileMajorVersion,aRegistryFileMinorVersion);
+		ci->SetOffset(0);
+		c.push_back(ci);
+		}
+
+	return c;
+	}
+
+
+std::vector<TInt> SisFile::GetAllInstallChainIndices() const
+	{
+	int signatureCount = iContents.Controller().SignatureCount();
+
+	std::vector<TInt> result;
+	for(int index = 0; index < signatureCount; ++index)
+		{
+		result.push_back(index);
+		}
+	return result;
+	}
+
+void SisFile::GetInstallableFiles(	InstallableFiles& aFiles, 
+									const CSISInstallBlock& aInstallBlock, 
+									const std::wstring& aDrivePath,
+									int aInstallingDrive) const
+	{
+	CSISInfo::TSISInstallationType installType = iContents.Controller().SISInfo().InstallationType();
+	const CSISDataUnit* dataUnit = NULL;
+	
+	if (installType ==  CSISInfo::EInstInstallation || installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade)
+		{
+		dataUnit = &(iContents.DataUnit(0));
+		}
+
+	int fileCount = aInstallBlock.FileCount();
+
+	for (int i = 0; i < fileCount; ++i)
+		{
+		const CSISFileDescription& fileDes = aInstallBlock.FileDescription(i);
+		
+		// FT or empty target file names are not installed
+		if(fileDes.Operation() == CSISFileDescription::EOpText && fileDes.Target().size() == 0)
+			{
+			continue;
+			}
+
+		// for PA stub sis files no file data present,
+		// aFiles will be filled with only file descriptions of files, empty file data
+		if (NULL != dataUnit && fileDes.Operation() != CSISFileDescription::EOpNull)
+			{
+			const CSISFileData& filedataref = dataUnit->FileData(fileDes.FileIndex());
+			aFiles.push_back(new InstallableFile(fileDes, new CSISFileData(dataUnit->FileData(fileDes.FileIndex())), aDrivePath, aInstallingDrive));
+			}
+		else // for stubs, no file data
+			{
+			aFiles.push_back(new InstallableFile(fileDes, aDrivePath, aInstallingDrive));
+			}
+		}
+	}
+
+void SisFile::ProcessInstallBlock(const CSISInstallBlock& aInstallBlock, 
+								  InstallableFiles& aFiles, 
+								  ExpressionEvaluator& aEvaluator, 
+								  const std::wstring& aDrivePath,
+								  int aInstallingDrive) const
+	{
+	GetInstallableFiles(aFiles, aInstallBlock, aDrivePath, aInstallingDrive);
+
+	const CSISArray<CSISIf, CSISFieldRoot::ESISIf>& ifs = aInstallBlock.Ifs();
+	for (int i = 0; i < ifs.size(); ++i)
+		{
+		const CSISIf& ifBlock = ifs[i];
+
+		if (ifBlock.WasteOfSpace())
+			{
+			std::string x;
+			std::string error = "corrupt SIS file";
+			throw InvalidSis(Ucs2ToUtf8(this->GetPackageName(),x), error, INVALID_SIS);
+			}
+
+		// Main expression
+		const ExpressionResult expressionResult = aEvaluator.Evaluate( ifBlock.Expression() );
+		const bool processBlock = expressionResult.BoolValue();
+		if ( processBlock )
+			{
+			ProcessInstallBlock(ifBlock.InstallBlock(), aFiles, aEvaluator, aDrivePath, aInstallingDrive);
+			continue;
+			}
+		
+		int elseCount = ifBlock.ElseIfCount();
+		for (int i = 0; i < elseCount; ++i)
+			{
+			const CSISElseIf& ifElseBlock = ifBlock.ElseIf(i) ;
+			if ( aEvaluator.Evaluate(ifElseBlock.Expression()).BoolValue())
+				{
+				ProcessInstallBlock(ifElseBlock.InstallBlock(), aFiles, aEvaluator, aDrivePath, aInstallingDrive);
+				break;	// Stop processing else if blocks
+				}
+			// Process the rest of the files
+			GetInstallableFiles(aFiles, ifElseBlock.InstallBlock(), aDrivePath, aInstallingDrive);
+			}
+		} 
+	}
+
+PackageUids SisFile::GetEmbeddedPackageUids() const
+{
+	// Embedded controllers
+	PackageUids pkgs;
+	TControllerMap embeddedCtls;
+	iContents.Controller().InstallBlock().GetEmbeddedControllers(embeddedCtls, false);
+	for (TControllerMapConstIter iter = embeddedCtls.begin(); iter != embeddedCtls.end(); ++iter)
+		{
+			const CSISController* ctrl = iter->second;
+			const CSISInfo& info = ctrl->SISInfo();
+			TUint32 uid = info.UID1();
+			pkgs.push_back(uid);
+		 }
+	return pkgs;
+}
+
+bool SisFile::IsSupportedLanguage(TUint32 aLanguage) const
+{
+	bool result = false;
+	int langCount = iContents.Controller().LanguageCount();
+	for (int i = 0; i < langCount; ++i)
+		{
+		if (iContents.Controller().Language(i) == aLanguage)
+			{
+			result = true;
+			break;
+			}
+		}	
+	return result;
+}
+
+void SisFile::MakeSISStub(std::wstring& aFileName)
+	{
+	CSISContents contents = iContents;
+	contents.SetStub(CSISContents::EStubPreInstalled);
+	contents.WriteSIS(aFileName);
+	}
+