diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/interpretsislib/sisfile.cpp --- /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 +#include + +// 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 SisFile::GetAllInstallChainIndices() const + { + int signatureCount = iContents.Controller().SignatureCount(); + + std::vector 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& 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); + } +