--- /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);
+ }
+