/*
* Copyright (c) 2008-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:
* ScrHelperUtil class provides the list of functionalities needed to store and retrieve the
* SIS Registry Object in to and from the Software Component Registry respectively.
*
*/
/**
@file
@released
@internalComponent
*/
#include <e32uid.h>
#include "scrhelperutil.h"
#include "log.h"
#include "scrdbconstants.h"
#include "sisregistryobject.h"
#include "sisregistrytoken.h"
#include "sisregistrypackage.h"
#include "hashcontainer.h"
#include "sisproperties.h"
#include "controllerinfo.h"
#include "sisregistrydependency.h"
#include "sisregistryfiledescription.h"
#include "sisregistryproperty.h"
#include "cleanuputils.h"
#include <usif/usifcommon.h>
#include <swi/sisregistrylog.h>
#include <scs/streamingarray.h>
#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include "screntries_internal.h"
#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
using namespace Swi;
// Store the SIS Registry Object details in to the Software Component Registry - SCR.
// The component object should have been fully constructed before calling this method.
void ScrHelperUtil::AddComponentL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::TComponentId& aCompId, CSisRegistryObject& aObject, Usif::TScrComponentOperationType aOpType)
{
WriteToScrL(aScrSession, aCompId, aObject, aOpType);
////StopTimerAndWriteResultL(timer, _L8(" WriteToScrL "));
// The default value of isRemovable is true in SCR - we change it only if needed
if(aObject.iIsRemovable == EFalse)
{
aScrSession.SetIsComponentRemovableL(aCompId, aObject.IsRemovable());
}
aScrSession.SetVendorNameL(aCompId, *(aObject.iVendorLocalizedName), aObject.Language());
if(KDefaultInstallType != aObject.InstallType())
{
aScrSession.SetComponentPropertyL(aCompId, KCompInstallType, aObject.InstallType());
}
if(KDefaultIsInRom != aObject.InRom())
{
aScrSession.SetComponentPropertyL(aCompId, KCompInRom, aObject.InRom());
}
if(KDefaultIsDeletablePreInstalled != aObject.DeletablePreInstalled())
{
aScrSession.SetComponentPropertyL(aCompId, KCompDeletablePreinstalled, aObject.DeletablePreInstalled());
}
if(KDefaultIsSigned != aObject.IsSigned())
{
aScrSession.SetComponentPropertyL(aCompId, KCompIsSigned, aObject.IsSigned());
}
if(KDefaultTrustValue != aObject.Trust())
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrust, aObject.Trust());
}
if(KDefaultRemoveWithLastDependent != aObject.RemoveWithLastDependent())
{
aScrSession.SetComponentPropertyL(aCompId, KCompIsRemoveWithLastDependent, aObject.RemoveWithLastDependent());
}
aScrSession.SetComponentPropertyL(aCompId, KCompTrustTimeStamp, aObject.TrustTimeStamp().Int64());
if(KDefaultIsSignedBySuCert != aObject.IsSignedBySuCert())
{
aScrSession.SetComponentPropertyL(aCompId, KCompSignedBySuCert, aObject.IsSignedBySuCert());
}
if(KDefaultIsDrmProtected != aObject.IsDrmProtected())
{
aScrSession.SetIsComponentDrmProtectedL(aCompId, aObject.IsDrmProtected());
}
if(KDefaultIsComponentHidden != aObject.IsHidden())
{
aScrSession.SetIsComponentHiddenL(aCompId, aObject.IsHidden());
}
ExternalizeSupplierPackageArrayL(aScrSession, aObject.Uid(), aObject.Name(), aObject.InstallType(), aObject.iDependencies);
ExternalizeEmbeddedPackageArrayL(aScrSession, aCompId, aObject.iEmbeddedPackages);
ExternalizePropertiesArrayL(aScrSession, aCompId, aObject.iProperties);
ExternalizeFileDescriptionsArrayL(aScrSession, aCompId, aObject.FileDescriptions());
WriteToScrL(aScrSession, aCompId, aObject.TrustStatus());
ExternalizeChainIndexArrayL(aScrSession, aCompId, aObject.InstallChainIndicies());
}
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::TComponentId& aCompId, CSisRegistryObject& aObject, Usif::TScrComponentOperationType aOpType)
{
// Add the component name, it's vendor name and the supporting language in to the SCR.
RPointerArray<Usif::CLocalizableComponentInfo> componentInfo;
CleanupResetAndDestroyPushL(componentInfo);
TInt matchingLanguageCount = aObject.GetLocalizedPackageNamesArray().Count();
Usif::CLocalizableComponentInfo* component;
if( matchingLanguageCount > 0 )
{
for(TInt i=0;i<matchingLanguageCount;i++)
{
component = Usif::CLocalizableComponentInfo::NewLC((*(aObject.GetLocalizedPackageNamesArray()[i])), (*(aObject.GetLocalizedVendorNamesArray()[i])), (TLanguage)aObject.GetSupportedLanguageIdsArray()[i]);
componentInfo.AppendL(component);
CleanupStack::Pop(component);
}
}
else
{
component = Usif::CLocalizableComponentInfo::NewLC(aObject.Name(), aObject.Vendor(), aObject.Language());
componentInfo.AppendL(component);
CleanupStack::Pop(component);
}
HBufC* compGlobalId = NULL;
// For all SP and PP type packages, global Id is composed with package Uid and name.
if (aObject.Index() > 0)
{
const TDesC& packageName = aObject.Name();
compGlobalId = HBufC::NewLC(KCompUidSize + packageName.Size());
TPtr ptr(compGlobalId->Des());
ptr.AppendFormat(KPatchGlobalIdFormat, aObject.Uid().iUid, &(aObject.Name()));
}
// For all other non-SP and non-PP packages the global Id is simply the package Uid.
else
{
compGlobalId = HBufC::NewLC(KCompUidSize);
TPtr ptr(compGlobalId->Des());
ptr.AppendFormat(KGlobalIdFormat, aObject.Uid().iUid);
}
aCompId = aScrSession.AddComponentL(componentInfo, KNativeSoftwareType, compGlobalId, aOpType);
CleanupStack::PopAndDestroy(2, &componentInfo);
// Write the SIS Registry Token details
WriteToScrL(aScrSession, aCompId, static_cast<CSisRegistryToken&>(aObject));
}
// Store the SIS Registry Token details in to the SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::TComponentId& aCompId, CSisRegistryToken& aToken)
{
// First write the SIS Registry Package details
WriteToScrL(aScrSession, aCompId, static_cast<CSisRegistryPackage&>(aToken));
// Format the version to text and store in the SCR.
TBuf<KSmlBufferSize> versionString(KEmptyString);
VersionToString(aToken.Version(), versionString);
aScrSession.SetComponentVersionL(aCompId, versionString);
// iDrives will be automatically populated by SCR
ExternalizeSidArrayL(aScrSession, aCompId, aToken.Sids());
ExternalizeControllerArrayL(aScrSession, aCompId, aToken.ControllerInfo());
if (aToken.Language() != ELangEnglish)
{
// ROM stubs are typically set to English so save a few bytes in the database and a DB operation
// for files installed as English
aScrSession.SetComponentPropertyL(aCompId, KCompLanguage, static_cast<TInt32>(aToken.Language()));
}
if (aToken.SelectedDrive() != 0)
{
// ROM stubs are set to drive 0 - this optimisation avoids adding a custom property for these
aScrSession.SetComponentPropertyL(aCompId, KCompSelectedDrive, static_cast<TInt32>(aToken.SelectedDrive()));
}
}
// Store the SIS Registry Package details in to the SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::TComponentId& aCompId, CSisRegistryPackage& aPackage)
{
// Store the Unique Vendor Name as a custom property
aScrSession.SetComponentPropertyL(aCompId, KCompUniqueVendorName, *(aPackage.iVendorName));
aScrSession.SetComponentPropertyL(aCompId, KCompUid, static_cast<TInt32>(aPackage.iUid.iUid));
// The index is the Index of the component being installed. Always it will be 0 for SA type packages and
// the index will start incrementing for each SP we install on top the base (SA) package.
if (aPackage.Index() != KDefaultComponentIndex)
aScrSession.SetComponentPropertyL(aCompId, KCompIndex, aPackage.Index());
}
// Store the array of package's SID details in to the SCR.
void ScrHelperUtil::ExternalizeSidArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const RArray<TUid>& aSids)
{
TBuf<KSmlBufferSize> compSid(KEmptyString);
TInt sidCount = aSids.Count();
if(KDefaultSidCount != sidCount)
aScrSession.SetComponentPropertyL(aCompId, KCompSidCount, sidCount);
if(sidCount > 0)
aScrSession.SetComponentPropertyL(aCompId, KCompSidsPresent, 1);
for (TInt index = 0; index < sidCount; ++index)
{
compSid.Format(KCompSidFormat, index);
aScrSession.SetComponentPropertyL(aCompId, compSid, static_cast<TUint>(aSids[index].iUid));
}
}
// Store the array of controllers in to the SCR.
void ScrHelperUtil::ExternalizeControllerArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const RPointerArray<CControllerInfo>& aControllerInfoArray)
{
TInt controllerCount = aControllerInfoArray.Count();
if(KDefaultControllerCount != controllerCount)
aScrSession.SetComponentPropertyL(aCompId, KCompControllerCount, controllerCount);
for (TInt index = 0; index < controllerCount; ++index)
{
WriteToScrL(aScrSession, aCompId, *(aControllerInfoArray[index]), index);
}
}
// Store the controller's details in to the SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CControllerInfo& aControllerInfo, TInt aIndex)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
TBuf<KSmlBufferSize> propertyValue(KEmptyString);
propertyName.Format(KVersionNameFormat, aIndex);
TVersion controllerVersion = aControllerInfo.Version();
if (controllerVersion.iMajor != KDefaultVersionMajor || controllerVersion.iMinor != KDefaultVersionMinor ||
controllerVersion.iBuild != KDefaultVersionBuild)
{
VersionToString(controllerVersion, propertyValue);
aScrSession.SetComponentPropertyL(aCompId, propertyName, propertyValue);
}
// Multiple PU controllers on top of an SA will lead the offset values to be incremented by one for each PU.
if (aControllerInfo.iOffset != 0)
{
// Most applications are SA's that have not been upgraded so use a default value of 0
propertyName.Format(KOffsetNameFormat, aIndex);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aControllerInfo.iOffset);
}
WriteToScrL(aScrSession, aCompId, *(aControllerInfo.iHashContainer), aIndex);
}
// Store the controller's hash details in to the SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CHashContainer& aHashContainer, TInt aIndex)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KHashAlgorithmNameFormat, aIndex);
if (aHashContainer.Algorithm() != CMessageDigest::ESHA1)
aScrSession.SetComponentPropertyL(aCompId, propertyName, static_cast<TInt32>(aHashContainer.Algorithm()));
propertyName.Format(KHashDataNameFormat, aIndex);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aHashContainer.Data());
}
// Store the array of supplier package dependency details in to the SCR.
// Supplier packages are the packages on which the current package is depending on.
void ScrHelperUtil::ExternalizeSupplierPackageArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aCompUid, const TDesC& aCompName, Sis::TInstallType aInstallType, RPointerArray<CSisRegistryDependency>& aDependentPackageArray)
{
for (TInt index = 0; index < aDependentPackageArray.Count(); ++index)
{
WriteToScrL(aScrSession, aCompUid, aCompName, aInstallType, *(aDependentPackageArray[index]));
}
}
// Store the details of one of the dependency package of given component in to SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aCompUid, const TDesC& aCompName, Sis::TInstallType aInstallType, CSisRegistryDependency& aRegistryDependency)
{
TBuf <KCompUidSize> supplierGlobalIdString;
TBuf<KSmlBufferSize> fromVersionString(KEmptyString);
TBuf<KSmlBufferSize> toVersionString(KEmptyString);
// Get the dependent details.
HBufC* dependentGlobalIdString = FormatGlobalIdLC(aCompUid, aCompName, aInstallType);
// Get the supplier details.
supplierGlobalIdString.AppendFormat(KGlobalIdFormat, aRegistryDependency.iUid.iUid);
VersionToString(aRegistryDependency.iFromVersion, fromVersionString);
VersionToString(aRegistryDependency.iToVersion, toVersionString);
// Create the component global id for both dependent and supplier.
Usif::CGlobalComponentId* supplierGlobalId = Usif::CGlobalComponentId::NewLC(supplierGlobalIdString, Usif::KSoftwareTypeNative);
Usif::CGlobalComponentId* dependentGlobalId = Usif::CGlobalComponentId::NewLC(*dependentGlobalIdString, Usif::KSoftwareTypeNative);
// Create the versioned component Id for supplier.
Usif::CVersionedComponentId* supplierVersionedCompId = Usif::CVersionedComponentId::NewLC(*supplierGlobalId, &fromVersionString, &toVersionString);
// Add the dependency details in to SCR.
TRAPD(err, aScrSession.AddComponentDependencyL(*supplierVersionedCompId, *dependentGlobalId));
// Since SWI allows multiple equal dependencies, we ignore KErrAlreadyExists
if (err != KErrNone && err != KErrAlreadyExists)
{
User::Leave(err);
}
CleanupStack::PopAndDestroy(4, dependentGlobalIdString);
}
// Store details of the array of embedded packages of the given component in to SCR.
void ScrHelperUtil::ExternalizeEmbeddedPackageArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryPackage>& aEmbeddedPackageArray)
{
TInt embeddedPackageCount = aEmbeddedPackageArray.Count();
if(KDefaultEmbeddedPackageCount != embeddedPackageCount)
aScrSession.SetComponentPropertyL(aCompId, KCompEmbeddedPackageCount, embeddedPackageCount);
if(embeddedPackageCount > 0)
aScrSession.SetComponentPropertyL(aCompId, KCompEmbeddedPackagePresent, 1);
TBuf<KBigBufferSize> propertyName(KEmptyString);
for (TInt index = 0; index < embeddedPackageCount; ++index)
{
CSisRegistryPackage* package = aEmbeddedPackageArray[index];
// Store the package details
propertyName.Format(KCompEmbeddedPackageUid, index);
aScrSession.SetComponentPropertyL(aCompId, propertyName, package->Uid().iUid);
propertyName.Format(KCompEmbeddedPackageName, index);
aScrSession.SetComponentPropertyL(aCompId, propertyName, package->Name());
propertyName.Format(KCompEmbeddedPackageVendor, index);
aScrSession.SetComponentPropertyL(aCompId, propertyName, package->Vendor());
propertyName.Format(KCompEmbeddedPackageIndex, index);
aScrSession.SetComponentPropertyL(aCompId, propertyName, package->Index());
}
}
// Store the details of one of the embedded package of the given component in to SCR.
void ScrHelperUtil::ExternalizePropertiesArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryProperty>& aRegistryPropertyArray)
{
TInt compPropertyCount = aRegistryPropertyArray.Count();
if(KDefaultCompPropertyCount != compPropertyCount)
aScrSession.SetComponentPropertyL(aCompId, KCompPropertyCount, compPropertyCount);
for (TInt index = 0; index < compPropertyCount; ++index)
{
WriteToScrL(aScrSession, aCompId, *(aRegistryPropertyArray[index]), index);
}
}
// Store the SIS Registry property in to SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryProperty& aRegistryProperty, TInt aIndex)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KCompPropertyKey, aIndex);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aRegistryProperty.iKey);
propertyName.Format(KCompPropertyValue, aIndex);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aRegistryProperty.iValue);
}
TInt CompareDescriptors(const TPtrC &aLhs, const TPtrC& aRhs)
{
return aLhs.CompareF(aRhs);
}
// Store the array of owned file's details in to the SCR.
// Wild carded files are stored as part of component custom property group. Where as the normal files are stored
// as part of files property group. The wild carded files are used only in stub files and they are used only during
// checking for eclipse validation during ROM upgrade. The wild carded files won't give file ownership information.
void ScrHelperUtil::ExternalizeFileDescriptionsArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryFileDescription>& aFileDescriptionArray)
{
// As SCR won't support the wildcard characters on file names, if the file name has wildcard characters,
// dont' store them as part file properties. Rather, store them as component custom properties only.
TInt wildCardFileCount = 0;
TInt executableFileIndex = 0;
TInt64 componentSize = 0;
// Since SCR does not check for duplicate entries, and they may occur in SWI, we filter them here
// The file names are stored in a temporary array and compared with while iterating over file descriptions. Duplicates are skipped
// Cannot use CDesC16ArrayFlat as it is in BAFL which the TCB sisregistryserver cannot link to
RArray<TPtrC> filenamesArray;
CleanupClosePushL(filenamesArray);
TInt fileDescriptionsCount = aFileDescriptionArray.Count();
TLinearOrder<TPtrC> descriptorsComparator(&CompareDescriptors);
for (TInt index = 0; index < fileDescriptionsCount; ++index)
{
const TDesC& fileTarget = aFileDescriptionArray[index]->Target();
TPtrC fileTargetPtr(fileTarget);
if (filenamesArray.SpecificFindInOrder(fileTargetPtr, descriptorsComparator, EArrayFindMode_First) != KErrNotFound)
continue; // Skip duplicates
filenamesArray.InsertInOrder(fileTargetPtr, descriptorsComparator);
if (IsWildcardFile(fileTarget))
{
// Calls the method with ETrue if it's wild carded file.
WriteToScrL(aScrSession, aCompId, *(aFileDescriptionArray[index]), ETrue, wildCardFileCount, -1);
++wildCardFileCount;
}
else
{
// If the file's SID value is not zero (only for EXEs)
if (aFileDescriptionArray[index]->Sid().iUid != 0)
{
WriteToScrL(aScrSession, aCompId, *(aFileDescriptionArray[index]), EFalse, -1, executableFileIndex);
++executableFileIndex;
}
else
{
WriteToScrL(aScrSession, aCompId, *(aFileDescriptionArray[index]), EFalse, -1, -1);
}
// Get the each file size and accumulate it to get the whole component size.
componentSize += aFileDescriptionArray[index]->UncompressedLength();
}
}
if (KDefaultWildCardFileCount != wildCardFileCount)
aScrSession.SetComponentPropertyL(aCompId, KCompWildCardFileCount, wildCardFileCount);
if (0 != componentSize) // For ROM components, the typical size is 0 which is also the default value at the SCR
aScrSession.SetComponentSizeL(aCompId, componentSize);
CleanupStack::PopAndDestroy(&filenamesArray);
}
// Store the owned files details in to the SCR.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryFileDescription& aFileDescription,
TBool aIsWildcardedFile, TInt aIndex, TInt aExecutableFileIndex)
{
if (aIsWildcardedFile)
{
// SCR doesn't support the wildcard cahracters in file names.
// So, store the object as a component custom property.
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KCompWildCardFile, aIndex);
// For wild-carded files, all properties apart from the target are meaningless
aScrSession.SetComponentPropertyL(aCompId, propertyName, aFileDescription.Target());
return;
}
// For normal file, store it using regular SCR file management APIs
// Store the file name as component property to get the FileName related to a specific SID easily.
// CSisRegistryPackage::iSids & CSisRegistryObject::iFileDescriptions are to be in sync. Otherwise, this mapping will fail.
if (aExecutableFileIndex != -1) // Value will be -1 for non executables.
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KCompSidFileNameFormat, aExecutableFileIndex);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aFileDescription.Target());
}
TBool considerFileInDriveList = (aFileDescription.Operation() != Swi::Sis::EOpNull);
// For OpNull, we shouldn't update the drive list, as the file does not actually exist, it is only registered for uninstall
aScrSession.RegisterComponentFileL(aCompId, aFileDescription.Target(), considerFileInDriveList);
if (aFileDescription.MimeType().Size() > 0)
{
RBuf8 mimeType8;
mimeType8.CreateL(aFileDescription.MimeType().Size());
CleanupClosePushL(mimeType8);
mimeType8.Copy(aFileDescription.MimeType());
aScrSession.SetFilePropertyL(aCompId, aFileDescription.Target(), KFileMimeType, mimeType8);
CleanupStack::PopAndDestroy(&mimeType8);
}
if (aFileDescription.Operation() != Swi::Sis::EOpInstall)
{
aScrSession.SetFilePropertyL(aCompId, aFileDescription.Target(), KFileSisFileOperation, aFileDescription.Operation());
}
if (aFileDescription.OperationOptions())
{
aScrSession.SetFilePropertyL(aCompId, aFileDescription.Target(), KFileFileOperationOptions, aFileDescription.OperationOptions());
}
if (aFileDescription.Sid().iUid)
{
aScrSession.SetFilePropertyL(aCompId, aFileDescription.Target(), KFileSid, aFileDescription.Sid().iUid);
}
WriteToScrL(aScrSession, aCompId, aFileDescription.Hash(), aFileDescription.Target());
}
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const CHashContainer& aHashContainer, const TDesC& aFileName)
{
if (aHashContainer.Algorithm() != CMessageDigest::ESHA1)
{
aScrSession.SetFilePropertyL(aCompId, aFileName, KFileHashAlgorithm, static_cast<TInt32>(aHashContainer.Algorithm()));
}
if (aHashContainer.Data().Length() > 0)
{
aScrSession.SetFilePropertyL(aCompId, aFileName, KFileHashData, aHashContainer.Data());
}
}
// Store the SIS Trust Status to the Software Component Registry.
void ScrHelperUtil::WriteToScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const TSisTrustStatus& aTrustStatus)
{
if(KDefaultValidationStatus != aTrustStatus.iValidationStatus)
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustValidationStatus, aTrustStatus.iValidationStatus);
}
if(KDefaultRevocationStatus != aTrustStatus.iRevocationStatus)
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustRevocationStatus, aTrustStatus.iRevocationStatus);
}
if(KDefaultGeneralDate != aTrustStatus.iResultDate.Int64())
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustResultDate, aTrustStatus.iResultDate.Int64());
}
if(KDefaultGeneralDate != aTrustStatus.iLastCheckDate.Int64())
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustLastCheckDate, aTrustStatus.iLastCheckDate.Int64());
}
if(KDefaultIsQuarantined != aTrustStatus.iQuarantined)
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustIsQuarantined, aTrustStatus.iQuarantined);
}
if(KDefaultGeneralDate != aTrustStatus.iQuarantinedDate.Int64())
{
aScrSession.SetComponentPropertyL(aCompId, KCompTrustQuarantinedDate, aTrustStatus.iQuarantinedDate.Int64());
}
// Update the 'Origin Verified' & 'Known Revoked' fields of the component
// based on this object's validation status and revocation status respectively.
if (aTrustStatus.iValidationStatus >= Swi::EValidatedToAnchor)
{
aScrSession.SetIsComponentOriginVerifiedL(aCompId, ETrue);
}
if (aTrustStatus.iRevocationStatus == Swi::EOcspRevoked)
{
aScrSession.SetIsComponentKnownRevokedL(aCompId, ETrue);
}
}
// Store the Chain Index array elements to the Software Component Registry.
void ScrHelperUtil::ExternalizeChainIndexArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const RArray<TInt>& aChainIndexArray)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
TInt chainIndexCount = aChainIndexArray.Count();
if(KDefaultChainIndex != chainIndexCount)
aScrSession.SetComponentPropertyL(aCompId, KCompInstallChainIndexCount, chainIndexCount);
for (TInt index = 0; index < chainIndexCount; ++index)
{
propertyName.Format(KCompInstallChainIndex, index);
aScrSession.SetComponentPropertyL(aCompId, propertyName, aChainIndexArray[index]);
}
}
// Retrieve the SIS Registry Object details of the given component from Software Component Registry - SCR.
void ScrHelperUtil::GetComponentL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryObject& aObject)
{
// First retrieve the user selected language to use it as the locale to retrive localized strings
TLanguage userSelectedLanguage = static_cast<TLanguage>(GetIntPropertyValueL(aScrSession, aCompId, KCompLanguage, EFalse, ELangEnglish));
//Retrieve the locale information from ComponentLocalizable
GetComponentLocalizedInfoL(aScrSession, aCompId, aObject);
// Then get all properties of the component
RPointerArray<Usif::CPropertyEntry> propertyArray;
aScrSession.GetComponentPropertiesL(aCompId, propertyArray);
CleanupResetAndDestroyPushL(propertyArray);
// Get the component entry of the given Component Id and construct the registry object hierarchy.
Usif::CComponentEntry* componentEntry = Usif::CComponentEntry::NewLC();
aScrSession.GetComponentL(aCompId, *componentEntry, userSelectedLanguage);
// First read the SIS Registry Token
ReadFromScrL(aScrSession, componentEntry, static_cast<CSisRegistryToken&>(aObject), &propertyArray);
aObject.iIsRemovable = componentEntry->IsRemovable();
// Internalize other simple member variables of the object.
// The values retrieved from the data base are casted according to the variable types.
aObject.iVendorLocalizedName = componentEntry->Vendor().AllocL();
// Internalize the DRM protection status on the component
aObject.iIsDrmProtected = componentEntry->IsDrmProtected();
// Internalize the 'hidden' nature of the component
aObject.iIsHidden = componentEntry->IsHidden();
CleanupStack::PopAndDestroy(componentEntry);
aObject.iTrustTimeStamp = TTime(GetInt64PropertyValueL(aScrSession, aCompId, KCompTrustTimeStamp, ETrue));
// Assign default values
aObject.iInstallType = KDefaultInstallType;
aObject.iInRom = KDefaultIsInRom;
aObject.iDeletablePreInstalled = KDefaultIsDeletablePreInstalled;
aObject.iSigned = KDefaultIsSigned;
aObject.iTrust = KDefaultTrustValue;
aObject.iRemoveWithLastDependent = KDefaultRemoveWithLastDependent;
aObject.iSignedBySuCert = KDefaultIsSignedBySuCert;
// Check the retrieved properties to see if the properties assigned with default values exist.
// Update the existing properties with the retrieved property values.
TInt propertyCount = propertyArray.Count();
for(TInt i=0; i<propertyCount; ++i)
{
const TDesC& propertyName = propertyArray[i]->PropertyName();
if(Usif::CPropertyEntry::EIntProperty != propertyArray[i]->PropertyType())
continue; // In this loop, only integer properties are checked. Ignore binary and localizable properties.
Usif::CIntPropertyEntry* property = static_cast<Usif::CIntPropertyEntry*>(propertyArray[i]);
TInt value = property->IntValue();
if(KCompInstallType() == propertyName)
{
aObject.iInstallType = static_cast<Sis::TInstallType>(value);
}
else if(KCompInRom() == propertyName)
{
aObject.iInRom = static_cast<TBool>(value);
}
else if(KCompDeletablePreinstalled() == propertyName)
{
aObject.iDeletablePreInstalled = static_cast<TBool>(value);
}
else if(KCompIsSigned() == propertyName)
{
aObject.iSigned = static_cast<TBool>(value);
}
else if(KCompTrust() == propertyName)
{
aObject.iTrust = static_cast<TSisPackageTrust>(value);
}
else if(KCompIsRemoveWithLastDependent() == propertyName)
{
aObject.iRemoveWithLastDependent = value;
}
else if(KCompSignedBySuCert() == propertyName)
{
aObject.iSignedBySuCert = static_cast<TBool>(value);
}
}
// Internalize the other array members of the object.
InternalizeSupplierPackageArrayL(aScrSession, aObject.Uid(), aObject.Name(), aObject.iInstallType, aObject.iDependencies);
InternalizeEmbeddedPackageArrayL(aScrSession, aCompId, aObject.iEmbeddedPackages, &propertyArray);
InternalizePropertiesArrayL(aScrSession, aCompId, aObject.iProperties, &propertyArray);
InternalizeFileDescriptionsArrayL(aScrSession, aCompId, aObject.iFileDescriptions);
aObject.iOwnedFileDescriptions = aObject.iFileDescriptions.Count();
ReadFromScrL(aScrSession, aCompId, aObject.iTrustStatus, &propertyArray);
InternalizeChainIndexArrayL(aScrSession, aCompId, aObject.iInstallChainIndices, &propertyArray);
CleanupStack::PopAndDestroy(&propertyArray);
}
// Retrieve the localizable details of a given component from Software Component Registry - SCR.
void ScrHelperUtil::GetComponentLocalizedInfoL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryObject& aObject)
{
DEBUG_PRINTF2(_L8("Retrieve the localized information related to component with CompId:%d"),aCompId);
RPointerArray<Usif::CLocalizableComponentInfo> compLocalizedInfoArray;
CleanupResetAndDestroyPushL(compLocalizedInfoArray);
aScrSession.GetComponentLocalizedInfoL(aCompId, compLocalizedInfoArray);
for(TInt i=0;i<compLocalizedInfoArray.Count();i++)
{
aObject.iLocalizedPackageNames.AppendL((compLocalizedInfoArray[i]->NameL()).AllocL());
aObject.iLocalizedVendorNames.AppendL((compLocalizedInfoArray[i]->VendorL()).AllocL());
aObject.iSupportedLanguageIds.AppendL(compLocalizedInfoArray[i]->Locale());
}
CleanupStack::Pop(&compLocalizedInfoArray);
compLocalizedInfoArray.ResetAndDestroy();
}
TBool ScrHelperUtil::IsUidPresentL(const Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aPackageUid)
{
Usif::TComponentId dummyComponentId(0);
return GetComponentIdL(aScrSession, aPackageUid, CSisRegistryPackage::PrimaryIndex, dummyComponentId); // If the base package for the UID does not exist, then it cannot be present on the system
}
TBool ScrHelperUtil::IsUidAndNamePresentL(const Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aUid, const TDesC& aPackageName)
{
// Get all components for the given UID and perform a comparison with package names
// Note that we cannot apply package names on the filter
// Get the right component id matching with the package UID, name and index.
Usif::CComponentFilter* componentFilter = Usif::CComponentFilter::NewLC();
componentFilter->SetSoftwareTypeL(Usif::KSoftwareTypeNative);
componentFilter->AddPropertyL(KCompUid, aUid.iUid);
Usif::RSoftwareComponentRegistryView subSession;
CleanupClosePushL(subSession);
subSession.OpenViewL(aScrSession, componentFilter);
Usif::CComponentEntry* compEntry = NULL;
TBool found = EFalse;
while (!found && (compEntry = subSession.NextComponentL()) != NULL)
{
CleanupStack::PushL(compEntry);
if (compEntry->Name() == aPackageName)
{
found = ETrue;
}
CleanupStack::PopAndDestroy(compEntry);
}
CleanupStack::PopAndDestroy(2, componentFilter); // subSession
if (!found)
{
DEBUG_PRINTF2(_L8("Sis Registry Server - Retrieving Component ID for the given UID (%d) failed."), aUid.iUid);
DEBUG_PRINTF2(_L8("Error : %d. Component not found in the SCR."), KErrNotFound);
return EFalse;
}
return ETrue;
}
// Queries the SCR for a component ID matching with the given values for Package UID and Package Index
// Returns EFalse, if not found. Returns ETrue if found, and returns the component id in the [out] parameter in such case
TBool ScrHelperUtil::GetComponentIdL(const Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aPackageUid, const TInt aPackageIndex, Usif::TComponentId& aComponentId)
{
// Setup a filter based on the input parameters
Usif::CComponentFilter* compFilter = Usif::CComponentFilter::NewLC();
compFilter->AddPropertyL(KCompUid, aPackageUid.iUid);
compFilter->SetSoftwareTypeL(Usif::KSoftwareTypeNative);
RArray<Usif::TComponentId> componentIdList;
CleanupClosePushL(componentIdList);
aScrSession.GetComponentIdsL(componentIdList, compFilter);
if(componentIdList.Count() == 0)
{
// No components are found in the SCR. So, return false
CleanupStack::PopAndDestroy(2, compFilter); // componentIdList
DEBUG_PRINTF2(_L8("Sis Registry Server - Unable to find component for UID: %x"), aPackageUid.iUid);
return EFalse;
}
// Filtering on KCompIndex is expensive in the SCR, as many values would be zero and the index is ineffective causing many comparisons in the DB. Usually the number of
// components matching the UID is low (as these are the base package + augmentations).
TBool matchingIndexFound = EFalse;
for (TInt i = 0; i < componentIdList.Count(); ++i)
{
TInt componentIndex = GetIntPropertyValueL(aScrSession, componentIdList[i], KCompIndex, EFalse, KDefaultComponentIndex);
if (componentIndex == aPackageIndex)
{
aComponentId = componentIdList[i];
matchingIndexFound = ETrue;
break;
}
}
CleanupStack::PopAndDestroy(2, compFilter); // componentIdList
if (!matchingIndexFound)
{
DEBUG_PRINTF3(_L8("Sis Registry Server - Unable to find matching package for UID %d and index %d"), aPackageUid.iUid, aPackageIndex);
return EFalse;
}
return ETrue;
}
// Queries the SCR for a component ID matching with the given values for Package UID and Package Index
// Leaves with KErrNone if the a corresponding component cannot be found
Usif::TComponentId ScrHelperUtil::GetComponentIdL(const Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aPackageUid, const TInt aPackageIndex)
{
Usif::TComponentId compId;
if (!GetComponentIdL(aScrSession, aPackageUid, aPackageIndex, compId))
User::Leave(KErrNotFound);
return compId;
}
// Queries the SCR for a component ID matching with the given values for Package Name and Package Vendor Name.
// Returns the matching component Id, if succeeds. Otherwise, it leaves with relevant error code.
// NOTE: There can be multiple such components and this API returns the first one found!
Usif::TComponentId ScrHelperUtil::GetComponentIdL(const Usif::RSoftwareComponentRegistry& aScrSession, const TDesC& aPackageName, const TDesC& aVendorName)
{
Usif::TComponentId compId;
if (!GetComponentIdL(aScrSession, aPackageName, aVendorName, compId))
User::Leave(KErrNotFound);
return compId;
}
// Queries the SCR for a component ID matching with the given values for Package Name and Package Vendor Name.
// Returns true iff the component exists. Uses the out parameter for setting the component's id in such case
// NOTE: There can be multiple such components and this API returns the first one found!
TBool ScrHelperUtil::GetComponentIdL(const Usif::RSoftwareComponentRegistry& aScrSession, const TDesC& aPackageName, const TDesC& aVendorName, Usif::TComponentId& aComponentId)
{
// Get the right component id matching with the package UID, name and vendor name.
Usif::CComponentFilter* componentFilter = Usif::CComponentFilter::NewLC();
componentFilter->SetSoftwareTypeL(Usif::KSoftwareTypeNative);
componentFilter->SetNameL(aPackageName);
componentFilter->AddPropertyL(KCompUniqueVendorName, aVendorName, Usif::KNonLocalized);
RArray<Usif::TComponentId> componentIdList;
CleanupClosePushL(componentIdList);
aScrSession.GetComponentIdsL(componentIdList, componentFilter);
if(componentIdList.Count() == 0)
{
// No components are found in the SCR. So, return FALSE
CleanupStack::PopAndDestroy(2, componentFilter); // componentIdList
DEBUG_PRINTF3(_L("Sis Registry Server - Component ID not found for the given name (%S) and vendor (%S)."),
&aPackageName, &aVendorName);
return EFalse;
}
// If found, get the corresponding Component Id and return it.
aComponentId = componentIdList[0];
CleanupStack::PopAndDestroy(2, componentFilter); // componentIdList
return ETrue;
}
// Retrieve the SIS Registry Token details.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::CComponentEntry* aComponentEntry, CSisRegistryToken& aToken, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
// First read the SIS Registry Package
ReadFromScrL(aScrSession, aComponentEntry, static_cast<CSisRegistryPackage&>(aToken));
InternalizeSidArrayL(aScrSession, aComponentEntry->ComponentId(), aToken.iSids, aPropertyArray);
InternalizeControllerArrayL(aScrSession, aComponentEntry->ComponentId(), aToken.iControllerInfo, aPropertyArray);
// Reset the Installed Drives
aToken.iDrives = 0;
// Convert the TDriveList format to the BitMask format.
TDriveList driveList = aComponentEntry->InstalledDrives();
MakeDrivesFromStringL(driveList, aToken.iDrives);
// Since the wild carded files are not stored as part of FilesProperties,
// SCR won't populate the installed drives itself.
// So, for wild carded ROM packages, we will manually populate the iDrives with Z.
TInt wildCardFileCount = GetIntPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompWildCardFileCount, EFalse, KDefaultWildCardFileCount);
if (wildCardFileCount > 0)
{
aToken.iDrives |= 1 << EDriveZ;
}
// Get the version.
StringToVersionL(aComponentEntry->Version(), aToken.iVersion);
aToken.iLanguage = static_cast<TLanguage>(GetIntPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompLanguage, EFalse, ELangEnglish));
aToken.iSelectedDrive = static_cast<TChar>(GetIntPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompSelectedDrive, EFalse));
}
// Retrieve the SIS Registry Package details.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, Usif::CComponentEntry* aComponentEntry, CSisRegistryPackage& aPackage)
{
aPackage.iUid.iUid = GetIntPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompUid, ETrue);
aPackage.iPackageName = aComponentEntry->Name().AllocL();
aPackage.iVendorName = GetStrPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompUniqueVendorName);
aPackage.iIndex = GetIntPropertyValueL(aScrSession, aComponentEntry->ComponentId(), KCompIndex, EFalse, KDefaultComponentIndex);
}
// Retrieve the component's array of SID details from SCR.
void ScrHelperUtil::InternalizeSidArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RArray<TUid>& aSidsArray, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
TBuf<KSmlBufferSize> compSid(KEmptyString);
TInt sidCount = 0;
if(aPropertyArray)
sidCount = GetIntegerPropertyValueFromArrayL(KCompSidCount, KDefaultSidCount, *aPropertyArray);
else
sidCount = GetIntPropertyValueL(aScrSession, aCompId, KCompSidCount, EFalse, KDefaultSidCount);
for (TInt index = 0; index < sidCount; ++index)
{
compSid.Format(KCompSidFormat, index);
TUid tUid = TUid::Uid(GetIntPropertyValueL(aScrSession, aCompId, compSid, ETrue));
aSidsArray.AppendL(tUid);
}
}
// Retrieve the array of controlller's details for the given component from SCR.
void ScrHelperUtil::InternalizeControllerArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CControllerInfo>& aControllerInfoArray, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
TInt controllerCount = 0;
if(aPropertyArray)
controllerCount = GetIntegerPropertyValueFromArrayL(KCompControllerCount, KDefaultControllerCount, *aPropertyArray);
else
controllerCount = GetIntPropertyValueL(aScrSession, aCompId, KCompControllerCount, EFalse, KDefaultControllerCount);
for (TInt index = 0; index < controllerCount; ++index)
{
CControllerInfo* controllerInfo = NULL;
ReadFromScrL(aScrSession, aCompId, controllerInfo, index);
CleanupStack::PushL(controllerInfo);
aControllerInfoArray.AppendL(controllerInfo);
CleanupStack::Pop(controllerInfo);
}
}
// Retrieve the given controller details from SCR.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CControllerInfo*& aControllerInfo, TInt aIndex)
{
TVersion version(KDefaultVersionMajor, KDefaultVersionMinor, KDefaultVersionBuild);
TInt offset;
CHashContainer* hashContainer = NULL;
TBuf<KBigBufferSize> controllerVersionName(KEmptyString);
TBuf<KBigBufferSize> controllerOffsetName(KEmptyString);
HBufC* controllerVersionPointer = NULL;
controllerVersionName.Format(KVersionNameFormat, aIndex);
controllerVersionPointer = GetStrPropertyValueL(aScrSession, aCompId, controllerVersionName, Usif::KUnspecifiedLocale, EFalse);
if (controllerVersionPointer) // The value is optional in the DB - assumed default if not present
{
StringToVersionL(controllerVersionPointer->Des(), version);
delete controllerVersionPointer;
}
controllerOffsetName.Format(KOffsetNameFormat, aIndex);
offset = GetIntPropertyValueL(aScrSession, aCompId, controllerOffsetName, EFalse, 0);
ReadFromScrL(aScrSession, aCompId, hashContainer, aIndex);
CleanupStack::PushL(hashContainer);
aControllerInfo = CControllerInfo::NewL(version, *hashContainer, offset);
CleanupStack::PopAndDestroy(hashContainer);
}
// Retrieve the hash details of the controller.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CHashContainer*& aHashContainer, TInt aIndex)
{
CMessageDigest::THashId algorithm;
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KHashAlgorithmNameFormat, aIndex);
algorithm = static_cast<CMessageDigest::THashId>(GetIntPropertyValueL(aScrSession, aCompId, propertyName, EFalse, CMessageDigest::ESHA1));
propertyName.Format(KHashDataNameFormat, aIndex);
HBufC8* data = GetBinaryPropertyValueL(aScrSession, aCompId, propertyName);
CleanupStack::PushL(data);
aHashContainer = CHashContainer::NewL(algorithm, *data);
CleanupStack::PopAndDestroy(data);
}
// Retrieve the array of supplier package details for the given component.
// Supplier packages are the packages on which the current package is depending on.
void ScrHelperUtil::InternalizeSupplierPackageArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const TUid& aCompUid, const TDesC& aCompName, Sis::TInstallType aInstallType, RPointerArray<CSisRegistryDependency>& aDependentPackageArray)
{
RPointerArray<Usif::CVersionedComponentId> supplierCompList;
CleanupResetAndDestroyPushL(supplierCompList);
HBufC* dependentGlobalIdString = FormatGlobalIdLC(aCompUid, aCompName, aInstallType);
Usif::CGlobalComponentId* dependentGlobalId = Usif::CGlobalComponentId::NewLC(*dependentGlobalIdString, Usif::KSoftwareTypeNative);
aScrSession.GetSupplierComponentsL(*dependentGlobalId, supplierCompList);
CleanupStack::PopAndDestroy(2, dependentGlobalIdString);
for (TInt index = 0; index < supplierCompList.Count(); ++index)
{
// Create the object from SCR and append it to the array.
CSisRegistryDependency* dependency = NULL;
ReadFromScrL(*(supplierCompList[index]), dependency);
CleanupStack::PushL(dependency);
aDependentPackageArray.AppendL(dependency);
CleanupStack::Pop(dependency);
}
CleanupStack::PopAndDestroy(&supplierCompList);
}
// Retrieve the package dependency details of the given component.
void ScrHelperUtil::ReadFromScrL(Usif::CVersionedComponentId& aVersionedSupplierCompId, CSisRegistryDependency*& aRegistryDependency)
{
TUid tUid;
TVersion fromVersion;
TVersion toVersion;
// Get the supplier package details. The supplier Uid if extracted from it's global Id.
const Usif::CGlobalComponentId &supplierGlobalId = aVersionedSupplierCompId.GlobalId();
ExtractCompUidL(supplierGlobalId.GlobalIdName(), tUid);
StringToVersionL(*(aVersionedSupplierCompId.VersionFrom()), fromVersion);
StringToVersionL(*(aVersionedSupplierCompId.VersionTo()), toVersion);
aRegistryDependency = CSisRegistryDependency::NewL(tUid, fromVersion, toVersion);
}
// Retrieve the array of embedded packages of the given component.
void ScrHelperUtil::InternalizeEmbeddedPackageArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryPackage>& aEmbeddedPackageArray, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
TInt embedCount = 0;
if(aPropertyArray)
embedCount = GetIntegerPropertyValueFromArrayL(KCompEmbeddedPackageCount, KDefaultEmbeddedPackageCount, *aPropertyArray);
else
embedCount = GetIntPropertyValueL(aScrSession, aCompId, KCompEmbeddedPackageCount, EFalse, KDefaultEmbeddedPackageCount);
for (TInt index = 0; index < embedCount; ++index)
{
// Get the package details
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KCompEmbeddedPackageUid, index);
TUid packageUid = TUid::Uid(GetIntPropertyValueL(aScrSession, aCompId, propertyName, ETrue));
propertyName.Format(KCompEmbeddedPackageName, index);
HBufC16* packageName = GetStrPropertyValueL(aScrSession, aCompId, propertyName);
CleanupStack::PushL(packageName);
propertyName.Format(KCompEmbeddedPackageVendor, index);
HBufC* packageVendor = GetStrPropertyValueL(aScrSession, aCompId, propertyName);
CleanupStack::PushL(packageVendor);
propertyName.Format(KCompEmbeddedPackageIndex, index);
TInt packageIndex = GetIntPropertyValueL(aScrSession, aCompId, propertyName, ETrue);
CSisRegistryPackage *package = CSisRegistryPackage::NewLC(packageUid, *packageName, *packageVendor);
package->SetIndex(packageIndex);
aEmbeddedPackageArray.AppendL(package);
CleanupStack::Pop(package);
CleanupStack::PopAndDestroy(2, packageName);
}
}
// Retrieve the package details of the given component from the SCR.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryPackage*& aPackage)
{
TUid compUid = TUid::Uid(GetIntPropertyValueL(aScrSession, aCompId, KCompUid, ETrue));
TInt componentIndex = GetIntPropertyValueL(aScrSession, aCompId, KCompIndex, EFalse, KDefaultComponentIndex);
// Unique vendor name is stored as a custom property
HBufC* uniqueVendor = GetStrPropertyValueL(aScrSession, aCompId, KCompUniqueVendorName);
CleanupStack::PushL(uniqueVendor);
Usif::CComponentEntry* componentEntry = Usif::CComponentEntry::NewLC();
aScrSession.GetComponentL(aCompId, *componentEntry);
aPackage = CSisRegistryPackage::NewL(compUid, componentEntry->Name(), *uniqueVendor);
aPackage->iIndex = componentIndex;
CleanupStack::PopAndDestroy(2, uniqueVendor); // componentEntry
}
// Retrieve the array of SIS regiatry properties related to the given component from SCR.
void ScrHelperUtil::InternalizePropertiesArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryProperty>& aPropertyArray, RPointerArray<Usif::CPropertyEntry>* aCompPropertyArray)
{
TInt propertyCount = 0;
if(aCompPropertyArray)
propertyCount = GetIntegerPropertyValueFromArrayL(KCompPropertyCount, KDefaultCompPropertyCount, *aCompPropertyArray);
else
propertyCount = GetIntPropertyValueL(aScrSession, aCompId, KCompPropertyCount, EFalse, KDefaultCompPropertyCount);
for (TInt index = 0; index < propertyCount; ++index)
{
// Create the object from SCR and append it to the array.
CSisRegistryProperty* property = NULL;
ReadFromScrL(aScrSession, aCompId, property, index);
aPropertyArray.AppendL(property);
CleanupStack::Pop(property);
}
}
// Retrieve the SIS registry property details from the SCR.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryProperty*& aRegistryProperty, TInt aIndex)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
aRegistryProperty = new(ELeave) CSisRegistryProperty();
CleanupStack::PushL(aRegistryProperty);
propertyName.Format(KCompPropertyKey, aIndex);
aRegistryProperty->iKey = GetIntPropertyValueL(aScrSession, aCompId, propertyName, ETrue);
propertyName.Format(KCompPropertyValue, aIndex);
aRegistryProperty->iValue = GetIntPropertyValueL(aScrSession, aCompId, propertyName, ETrue);
}
// Retrieve the files owned by the given component from the Software Component Registry.
void ScrHelperUtil::InternalizeFileDescriptionsArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RPointerArray<CSisRegistryFileDescription>& aFileDescriptionArray)
{
HBufC* fileName = NULL;
// First internalize all the wildcarded files (if any).
TInt wildCardFileCount = GetIntPropertyValueL(aScrSession, aCompId, KCompWildCardFileCount, EFalse, KDefaultWildCardFileCount);
for (TInt index = 0; index < wildCardFileCount; index++)
{
TBuf<KBigBufferSize> propertyName(KEmptyString);
propertyName.Format(KCompWildCardFile, index);
fileName = GetStrPropertyValueL(aScrSession, aCompId, propertyName);
CleanupStack::PushL(fileName);
CSisRegistryFileDescription* fileDescription;
ReadFromScrL(aScrSession, aCompId, fileDescription, *fileName, ETrue); // ETrue for wild carded files
CleanupStack::PushL(fileDescription);
aFileDescriptionArray.AppendL(fileDescription);
CleanupStack::Pop(fileDescription);
CleanupStack::PopAndDestroy(fileName);
}
// Internalize the normal files (non wildcarded).
Usif::RSoftwareComponentRegistryFilesList subSession;
CleanupClosePushL(subSession);
subSession.OpenListL(aScrSession, aCompId);
for (;;)
{
fileName = subSession.NextFileL();
if (!fileName)
{
break;
}
CleanupStack::PushL(fileName);
CSisRegistryFileDescription* fileDescription = NULL;
ReadFromScrL(aScrSession, aCompId, fileDescription, *fileName, EFalse); // EFalse for normal (non wild carded) files
CleanupStack::PushL(fileDescription);
aFileDescriptionArray.AppendL(fileDescription);
CleanupStack::Pop(fileDescription);
CleanupStack::PopAndDestroy(fileName);
}
CleanupStack::PopAndDestroy(&subSession);
}
// Retrieve information of the given file from Software Component Registry.
// Wild carded file's details are read from component custom properties group and
// Normal file's details are read from the file properties group.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CSisRegistryFileDescription*& aFileDescription, const TDesC& aFileName, TBool aIsWildcardedFile)
{
aFileDescription = CSisRegistryFileDescription::NewLC();
aFileDescription->iTarget = aFileName.AllocL();
// If the file name has any wild card charactors on it, the object should be read from component custom porperties.
if (aIsWildcardedFile)
{
// A wildcard applies to MULTIPLE files so discard all values that only apply to single files
aFileDescription->iMimeType = HBufC16::NewL(0);
aFileDescription->iHash = CHashContainer::NewL(CMessageDigest::ESHA1, KNullDesC8);
aFileDescription->iOperation = Swi::Sis::EOpInstall;
CleanupStack::Pop(aFileDescription);
return;
}
// Else, read the object from file properties
RPointerArray<Usif::CPropertyEntry> propertyArray;
CleanupResetAndDestroyPushL(propertyArray);
aScrSession.GetFilePropertiesL(aCompId, aFileDescription->Target(), propertyArray);
aFileDescription->iOperation = Swi::Sis::EOpInstall; // EOpInstall is the default value - we record the operation in the SCR only if it is different
// Not all file properties are present for every file. We use default values for the non-mandatory ones, such as SID
for (TInt i = 0; i < propertyArray.Count(); ++i)
{
const TDesC& propertyName = propertyArray[i]->PropertyName();
if (propertyName == KFileMimeType)
{
Usif::CBinaryPropertyEntry* binaryPropertyEntry = static_cast<Usif::CBinaryPropertyEntry *>(propertyArray[i]);
const TDesC8& mimeType8 = binaryPropertyEntry->BinaryValue();
aFileDescription->iMimeType = HBufC16::NewL(mimeType8.Length());
aFileDescription->iMimeType->Des().Copy(mimeType8);
}
Usif::CIntPropertyEntry* intPropertyEntry = static_cast<Usif::CIntPropertyEntry *>(propertyArray[i]);
if (propertyName == KFileSisFileOperation)
{
aFileDescription->iOperation = static_cast<Sis::TSISFileOperation>(intPropertyEntry->IntValue());
}
else if (propertyName == KFileFileOperationOptions)
{
aFileDescription->iOperationOptions = static_cast<Sis::TSISFileOperationOptions>(intPropertyEntry->IntValue());
}
else if (propertyName == KFileSid)
{
aFileDescription->iSid = TUid::Uid(intPropertyEntry->IntValue());
}
}
if (!aFileDescription->iMimeType)
{
aFileDescription->iMimeType = HBufC16::NewL(0);
}
CleanupStack::PopAndDestroy(&propertyArray);
ReadFromScrL(aScrSession, aCompId, aFileDescription->iHash, aFileName);
CleanupStack::Pop(aFileDescription);
}
// Retrieve the Hash values related to the given file from the Software Component Registry
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, CHashContainer*& aHashContainer, const TDesC& aFileName)
{
HBufC8* data = NULL;
CMessageDigest::THashId algorithm = CMessageDigest::ESHA1;
RPointerArray<Usif::CPropertyEntry> propertyArray;
CleanupResetAndDestroyPushL(propertyArray);
aScrSession.GetFilePropertiesL(aCompId, aFileName, propertyArray);
for (TInt i = 0; i < propertyArray.Count(); ++i)
{
const TDesC& propertyName = propertyArray[i]->PropertyName();
if (propertyName == KFileHashData)
{
Usif::CBinaryPropertyEntry* binaryPropertyEntry = static_cast<Usif::CBinaryPropertyEntry *>(propertyArray[i]);
data = HBufC8::NewLC(binaryPropertyEntry->BinaryValue().Length());
data->Des().Copy(binaryPropertyEntry->BinaryValue());
}
else if (propertyName == KFileHashAlgorithm)
{
Usif::CIntPropertyEntry* intPropertyEntry = static_cast<Usif::CIntPropertyEntry *>(propertyArray[i]);
algorithm = static_cast<CMessageDigest::THashId>(intPropertyEntry->IntValue());
}
}
if (data == NULL)
{
data = HBufC8::NewLC(0);
}
CleanupStack::Pop(data);
CleanupStack::PopAndDestroy(&propertyArray);
CleanupStack::PushL(data);
aHashContainer = CHashContainer::NewL(algorithm, *data);
CleanupStack::PopAndDestroy(data);
}
// Retrieve the SIS Trust Status from the Software Component Registry.
void ScrHelperUtil::ReadFromScrL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, TSisTrustStatus& aTrustStatus, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
RPointerArray<Usif::CPropertyEntry> *localCopyOfPropertyArray;
RPointerArray<Usif::CPropertyEntry> localPropertyArray;
if(aPropertyArray)
{
localCopyOfPropertyArray = aPropertyArray;
}
else
{ // if the properties array parameter is not passed, retrieve all properties of the component in question.
aScrSession.GetComponentPropertiesL(aCompId, localPropertyArray);
CleanupResetAndDestroyPushL(localPropertyArray);
localCopyOfPropertyArray = &localPropertyArray;
}
// Then find and assign values from the component properties array
aTrustStatus.iValidationStatus = KDefaultValidationStatus;
aTrustStatus.iRevocationStatus = KDefaultRevocationStatus;
aTrustStatus.iResultDate = TTime(KDefaultGeneralDate);
aTrustStatus.iLastCheckDate = TTime(KDefaultGeneralDate);
aTrustStatus.iQuarantined = KDefaultIsQuarantined;
aTrustStatus.iQuarantinedDate = TTime(KDefaultGeneralDate);
RPointerArray<Usif::CPropertyEntry>& propertyArray = *localCopyOfPropertyArray;
TInt propertyCount = propertyArray.Count();
for(TInt i=0; i<propertyCount; ++i)
{
if(Usif::CPropertyEntry::EIntProperty != propertyArray[i]->PropertyType())
continue; // In this loop, only integer properties are checked. Ignore binary and localizable properties.
const TDesC& propertyName = propertyArray[i]->PropertyName();
Usif::CIntPropertyEntry* property = static_cast<Usif::CIntPropertyEntry*>(propertyArray[i]);
if(KCompTrustValidationStatus() == propertyName)
{
aTrustStatus.iValidationStatus = static_cast<TValidationStatus>(property->IntValue());
}
else if(KCompTrustRevocationStatus() == propertyName)
{
aTrustStatus.iRevocationStatus = static_cast<TRevocationStatus>(property->IntValue());
}
else if(KCompTrustResultDate() == propertyName)
{
aTrustStatus.iResultDate = TTime(property->Int64Value());
}
else if(KCompTrustLastCheckDate() == propertyName)
{
aTrustStatus.iLastCheckDate = TTime(property->Int64Value());
}
else if(KCompTrustIsQuarantined() == propertyName)
{
aTrustStatus.iQuarantined = static_cast<TBool>(property->IntValue());
}
else if(KCompTrustQuarantinedDate() == propertyName)
{
aTrustStatus.iQuarantinedDate = TTime(property->Int64Value());
}
}
if(!aPropertyArray)
{ // Delete the local array if it has been populated
CleanupStack::PopAndDestroy(&localPropertyArray);
}
}
// Retrieve the Chain Index array elements from the Software Component Registry - SCR.
void ScrHelperUtil::InternalizeChainIndexArrayL(Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, RArray<TInt>& aChainIndexArray, RPointerArray<Usif::CPropertyEntry>* aPropertyArray)
{
TInt chainIndex = 0;
TBuf<KBigBufferSize> propertyName(KEmptyString);
TInt chainIndexCount = 0;
if(aPropertyArray)
chainIndexCount = GetIntegerPropertyValueFromArrayL(KCompInstallChainIndexCount, KDefaultChainIndex, *aPropertyArray);
else
chainIndexCount = GetIntPropertyValueL(aScrSession, aCompId, KCompInstallChainIndexCount, EFalse, KDefaultChainIndex);
for (TInt index = 0; index < chainIndexCount; ++index)
{
propertyName.Format(KCompInstallChainIndex, index);
chainIndex = GetIntPropertyValueL(aScrSession, aCompId, propertyName, ETrue);
aChainIndexArray.AppendL(chainIndex);
}
}
// Get the value for given integer (64 bit) type property related to the given component.
TInt64 Swi::GetInt64PropertyValueL(const Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const TDesC& aPropertyName, TBool aAlwaysExpectedInDb, TInt64 aDefaultValue)
{
TInt64 propertyValue = 0;
Usif::CIntPropertyEntry* propertyEntry = NULL;
propertyEntry = static_cast<Usif::CIntPropertyEntry *>(aScrSession.GetComponentPropertyL(aCompId, aPropertyName));
__ASSERT_ALWAYS(propertyEntry || !aAlwaysExpectedInDb, User::Leave(KErrAbort));
propertyValue = propertyEntry ? propertyEntry->Int64Value() : aDefaultValue;
delete propertyEntry;
return (propertyValue);
}
// Get the value for given integer type property related to the given component.
TInt Swi::GetIntPropertyValueL(const Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const TDesC& aPropertyName, TBool aAlwaysExpectedInDb, TInt aDefaultValue)
{
TInt propertyValue = 0;
Usif::CIntPropertyEntry* propertyEntry = NULL;
propertyEntry = static_cast<Usif::CIntPropertyEntry *>(aScrSession.GetComponentPropertyL(aCompId, aPropertyName));
__ASSERT_ALWAYS(propertyEntry || !aAlwaysExpectedInDb, User::Leave(KErrAbort));
propertyValue = propertyEntry ? propertyEntry->Int64Value() : aDefaultValue;
delete propertyEntry;
return (propertyValue);
}
// Get the value for given string type property related to the given component.
HBufC* Swi::GetStrPropertyValueL(const Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const TDesC& aPropertyName, const TLanguage aLocale/*= Usif::KUnspecifiedLocale*/, TBool aAlwaysExpectedInDb /*=ETrue*/)
{
HBufC *propertyValue = NULL;
Usif::CLocalizablePropertyEntry* propertyEntry = NULL;
propertyEntry = static_cast<Usif::CLocalizablePropertyEntry *>(aScrSession.GetComponentPropertyL(aCompId, aPropertyName, aLocale));
__ASSERT_ALWAYS(propertyEntry || !aAlwaysExpectedInDb, User::Leave(KErrAbort));
if (!propertyEntry)
return NULL;
CleanupStack::PushL(propertyEntry);
// Ownership of the descriptor is transfered to the caller.
propertyValue = propertyEntry->StrValue().AllocL();
CleanupStack::PopAndDestroy(propertyEntry);
return (propertyValue);
}
// Get the binary string value for given property related to the given component.
HBufC8* Swi::GetBinaryPropertyValueL(const Usif::RSoftwareComponentRegistry& aScrSession, const Usif::TComponentId aCompId, const TDesC& aPropertyName)
{
HBufC8 *propertyValue = NULL;
Usif::CBinaryPropertyEntry* propertyEntry = NULL;
propertyEntry = static_cast<Usif::CBinaryPropertyEntry *>(aScrSession.GetComponentPropertyL(aCompId, aPropertyName));
__ASSERT_ALWAYS((propertyEntry != NULL), User::Leave(KErrAbort));
CleanupStack::PushL(propertyEntry);
// Ownership of the descriptor is transfered to the caller.
propertyValue = propertyEntry->BinaryValue().AllocL();
CleanupStack::PopAndDestroy(propertyEntry);
return (propertyValue);
}
// Creates the bit mask formated drives from the TDriveList (string) formated drive.
void Swi::MakeDrivesFromStringL(TDriveList& aDriveList, TUint& aDrive)
{
if(aDriveList.Length() == 0 )
{
return;
}
for(TInt driveNum=EDriveA; driveNum<=EDriveZ; ++driveNum)
{
if(aDriveList[driveNum])
{
aDrive |= 1<<driveNum;
}
}
}
// Write the Version object in to string format.
void Swi::VersionToString(const TVersion& aVersion, TDes& aVersionString)
{
aVersionString.AppendFormat(KVersionFormat, aVersion.iMajor, aVersion.iMinor, aVersion.iBuild);
}
// Create the Version object from the string format.
void Swi::StringToVersionL(const TDesC& aVersionString, TVersion& aVersion)
{
_LIT(KDot, ".");
TInt dotPos1 = aVersionString.FindF(KDot);
TInt dotPos2 = 0;
if(dotPos1 > 0)
{
dotPos2 = aVersionString.Mid(dotPos1 + 1).FindF(KDot);
}
if (dotPos1 <= 0 || dotPos2 <= 0)
{
DEBUG_PRINTF2(_L8("Sis Registry Server - The version format is not recognized for a SIS file. Expected format: n.n.n But, Got : %S"), &aVersionString);
User::Leave(KErrNotSupported);
}
TLex lex(aVersionString);
User::LeaveIfError(lex.Val(aVersion.iMajor));
lex = aVersionString.Mid(dotPos1 + 1);
User::LeaveIfError(lex.Val(aVersion.iMinor));
lex = aVersionString.Mid(dotPos1 + dotPos2 + 2);
User::LeaveIfError(lex.Val(aVersion.iBuild));
}
void ScrHelperUtil::GetComponentIdListL(const Usif::RSoftwareComponentRegistry& aScrSession, RArray<Usif::TComponentId>& aComponentIdList)
{
// Create a filter.
Usif::CComponentFilter* componentFilter = Usif::CComponentFilter::NewLC();
componentFilter->SetSoftwareTypeL(Usif::KSoftwareTypeNative);
// Retrieve the componentId of all the components from the SCR.
aScrSession.GetComponentIdsL(aComponentIdList, componentFilter);
CleanupStack::PopAndDestroy(componentFilter);
}
TBool ScrHelperUtil::IsWildcardFile(const TDesC& aFileName)
{
return (aFileName.Locate('?') != KErrNotFound ||
aFileName.Locate('*') != KErrNotFound ||
aFileName[aFileName.Length() - 1] == '\\');
}
// Extracts the UID of the component from it's global Id data.
// Just an string to TUid conversion.
void ScrHelperUtil::ExtractCompUidL(const TDesC& aGlobalIdStr, TUid& aUid)
{
TInt64 uidNum;
// Make sure the length of the global id string is exactly 8 chahacters in length.
__ASSERT_ALWAYS((aGlobalIdStr.Length() == 8), User::Leave(KErrCorrupt));
TLex lex(aGlobalIdStr);
TInt error = lex.Val(uidNum, EHex);
__ASSERT_ALWAYS((error == KErrNone), User::Leave(error));
aUid = TUid::Uid(uidNum);
}
TBool ComparePropertyNames(const Usif::CPropertyEntry& aLhs, const Usif::CPropertyEntry& aRhs)
{
return (aLhs.PropertyName() == aRhs.PropertyName());
}
TInt ScrHelperUtil::FindPropertyL(const RPointerArray<Usif::CPropertyEntry>& aProperties, const TDesC& aPropertyName)
{
Usif::CPropertyEntry *dummyProperty = Usif::CIntPropertyEntry::NewLC(aPropertyName, 0);
TInt ret = aProperties.Find(dummyProperty, TIdentityRelation<Usif::CPropertyEntry>(ComparePropertyNames));
CleanupStack::PopAndDestroy(dummyProperty);
return ret;
}
TInt ScrHelperUtil::GetIntegerPropertyValueFromArrayL(const TDesC& aPropertyName, TInt aDefaultValue, const RPointerArray<Usif::CPropertyEntry>& aProperties)
{
TInt propertyValue = aDefaultValue;
TInt pos = FindPropertyL(aProperties, aPropertyName);
if(KErrNotFound != pos)
{
propertyValue = static_cast<Usif::CIntPropertyEntry*>(aProperties[pos])->IntValue();
}
return propertyValue;
}
HBufC8* ScrHelperUtil::GetLogInfoLC(const Usif::RSoftwareComponentRegistry& aScrSession, TInt aMaxLogEntries)
{
RPointerArray<Usif::CScrLogEntry> logEntries;
CleanupResetAndDestroyPushL(logEntries);
const TDesC& swType = Usif::KSoftwareTypeNative();
aScrSession.RetrieveLogEntriesL(logEntries, &swType);
RPointerArray<CLogEntry> swiLogEntries;
CleanupResetAndDestroyPushL(swiLogEntries);
TInt logCount = logEntries.Count();
TInt surplusCount = logCount - aMaxLogEntries;
TInt startIndex = surplusCount>0 ? surplusCount : 0;
for(TInt i=startIndex; i<logCount; ++i)
{
Usif::CScrLogEntry *scrLog = logEntries[i];
CLogEntry *swiLog = new(ELeave)CLogEntry();
CleanupStack::PushL(swiLog);
swiLog->iPackageName = scrLog->ComponentName().AllocL();
TVersion version;
StringToVersionL(scrLog->ComponentVersion(), version);
swiLog->iMajorVersion = version.iMajor;
swiLog->iMinorVersion = version.iMinor;
swiLog->iBuildVersion = version.iBuild;
swiLog->iEvent = scrLog->OperationTime();
switch (scrLog->OperationType())
{
case Usif::EScrCompUnInstall:
swiLog->iInstallType = ESwiLogUnInstall;
break;
case Usif::EScrCompUpgrade:
swiLog->iInstallType = ESwiLogUpgrade;
break;
case Usif::EScrCompInstall:
default:
swiLog->iInstallType = ESwiLogInstall;
}
TBuf<KSmlBufferSize> uidString(KEmptyString);
uidString.Copy(scrLog->GlobalId().Ptr(), 8);
ExtractCompUidL(uidString, swiLog->iUid);
swiLogEntries.AppendL(swiLog);
CleanupStack::Pop(swiLog); // Ownership has been transferred
}
HBufC8 *logsBuf = ExternalizePointersArrayLC(swiLogEntries, EFalse); // EFalse -> Don't externalize the array length
CleanupStack::Pop(logsBuf);
CleanupStack::PopAndDestroy(2, &logEntries); // logEntries, swiLogEntries,
CleanupStack::PushL(logsBuf);
return logsBuf;
}