--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sisregistry/server/sisregistryserversession.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,2660 @@
+/*
+* Copyright (c) 2004-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:
+* CSisRegistrySession class implementation
+*
+*/
+
+
+/**
+ @file
+ @released
+ @internalComponent
+*/
+#include <s32mem.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <e32property.h>
+#include <connect/sbdefs.h>
+#include <miscutil.h>
+#include <swi/sistruststatus.h>
+#include <swi/sisregistrylog.h>
+#include <scs/ipcstream.h>
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include "sislauncherclient.h"
+#include "swtypereginfo.h"
+#endif
+
+#include "scrhelperutil.h"
+#include "scrdbconstants.h"
+#include "log.h"
+#include "swi/siscontroller.h"
+#include "sisregistryserversession.h"
+#include "sisregistryserver.h"
+#include "sisregistryserverconst.h"
+#include "sisregistryobject.h"
+#include "sisregistryfiledescription.h"
+#include "sisregistrydependency.h"
+#include "controllerinfo.h"
+#include "arrayutils.h"
+#include "hashcontainer.h"
+#include "filesisdataprovider.h"
+#include "dessisdataprovider.h"
+#include "sisrevocationmanager.h"
+#include "siscontroller.h"
+#include "siscertificatechain.h"
+#include "sisregistryproperty.h"
+
+#include "cleanuputils.h"
+#include "sisregistryutil.h"
+#include "sisinfo.h"
+#include "sisuid.h"
+#include "securitymanager.h"
+#include "siscontrollerverifier.h"
+#include "sisinstallblock.h"
+#include "sisregistryfiledescription.h"
+#include "sisregistrywritablesession.h"
+
+using namespace Swi;
+using namespace Usif;
+
+const TInt KUidHexLength = 8;
+_LIT(KSWIRegFirstInitFile, "\\sys\\install\\sisregistry\\swiregfirstinit.log");
+
+// Function to panic an offending client
+void CSisRegistrySession::PanicClient(const RMessagePtr2& aMessage, Swi::TSisRegistryPanic aPanic)
+ {
+ aMessage.Panic(KSisRegistryShortName, aPanic);
+ }
+
+//
+// 2nd phase construct for sessions - called by the CServer framework
+//
+void CSisRegistrySession::CreateL()
+ {
+ Server().AddSession();
+
+ User::LeaveIfError(iFs.Connect());
+ iSystemDrive = iFs.GetSystemDrive();
+
+ // Create a session with the Software Component Registry
+ User::LeaveIfError(iScrSession.Connect());
+
+ TInt res = KErrNone;
+ TRAP(res , res = IsFirmwareUpdatedL());
+
+ if (IsFirstInvocationL() || res )
+ {
+ isFwUpdated = ETrue;
+ FirstInvocationInitL();
+ }
+
+ TRAP(res, UpdateRecentFWVersionL(););
+ if (res != KErrNone)
+ {
+ // log that
+ DEBUG_PRINTF2(_L8("Updating recent Firmware Version failed with error code = %d."), res);
+ }
+ }
+
+CSisRegistrySession::~CSisRegistrySession()
+ {
+ Server().DropSession();
+ iOpenedPackages.ResetAndDestroy();
+ iScrSession.Close();
+ iFs.Close();
+ }
+
+// Returns ETrue if this is the first run of SWIRegistry server ever (or after firmware upgrade)
+TBool CSisRegistrySession::IsFirstInvocationL()
+ {
+ TBool firstInvocation = ETrue;
+
+ // Check if the flagging file KSWIRegFirstInitFile exists in on the <systemdrive>
+ RBuf fileName;
+ CleanupClosePushL(fileName);
+ fileName.CreateL(KMaxPath);
+ TDriveUnit drive(iSystemDrive);
+ fileName = drive.Name();
+ fileName.Append(KSWIRegFirstInitFile);
+ TEntry entry;
+ if (iFs.Entry(fileName, entry) == KErrNone)
+ {
+ firstInvocation = EFalse;
+ }
+ CleanupStack::PopAndDestroy(&fileName);
+ return firstInvocation;
+ }
+
+// Does initialization required when run after very first boot of phone (or after firmware upgrade)
+// Method is only invoked when such a state is detected
+// Leaves behind a file in <systemdrive>:\sys to mark a successful initialization
+void CSisRegistrySession::FirstInvocationInitL()
+ {
+ // Add the ROM installed stub details to SCR
+ // Create an SCR transaction, so that entries won't be added to the SCR if the function leaves
+ iScrSession.CreateTransactionL();
+ ProcessRomDriveL();
+ iScrSession.CommitTransactionL();
+ // Create a file in <systemdrive>:\sys to mark a successful initialization
+ // so that we don't come here again (unless firmware is upgraded in which case <systemdrive>:\sys
+ // should be cleaned
+ RBuf fileName;
+ CleanupClosePushL(fileName);
+ fileName.CreateL(KMaxPath);
+ TDriveUnit drive(iSystemDrive);
+ fileName = drive.Name();
+ fileName.Append(KSWIRegFirstInitFile);
+ RFile file;
+ CleanupClosePushL(file);
+ file.Replace(iFs, fileName, EFileWrite | EFileShareAny);
+ CleanupStack::PopAndDestroy(2, &fileName); // file
+ }
+
+//
+// Handle a client request.
+// Leaving is handled by CSisRegistry::ServiceError() which reports
+// the error code to the client
+//
+void CSisRegistrySession::ServiceL(const RMessage2& aMessage)
+ {
+ DEBUG_PRINTF2(_L8("SIS Registry Server - ServiceL (function %d)"), aMessage.Function());
+
+ switch (aMessage.Function())
+ {
+ // general registry
+ case EInstalledUids:
+ RequestInstalledUidsL(aMessage);
+ break;
+ case EInstalledPackages:
+ RequestInstalledPackagesL(aMessage);
+ break;
+ case EUidInstalled:
+ UidInstalledL(aMessage);
+ break;
+ case EControllerInstalled:
+ ControllerInstalledL(aMessage);
+ break;
+ case ESidToPackage:
+ RequestSidToPackageL(aMessage);
+ break;
+ case ESidToFileName:
+ RequestSidToFileNameL(aMessage);
+ break;
+ case EModifiable:
+ RequestModifiableL(aMessage);
+ break;
+ case EHash:
+ RequestHashL(aMessage);
+ break;
+ // general entry
+ case EOpenRegistryUid:
+ OpenRegistryUidEntryL(aMessage);
+ break;
+ case EOpenRegistryPackage:
+ OpenRegistryPackageEntryL(aMessage);
+ break;
+ case EOpenRegistryNames:
+ OpenRegistryNamesEntryL(aMessage);
+ break;
+ case ECloseRegistryEntry:
+ CloseRegistryEntryL(aMessage);
+ break;
+ case EVersion:
+ SubsessionL(aMessage.Int3()).RequestVersionRegistryEntryL(aMessage);
+ break;
+ case EPackageName:
+ SubsessionL(aMessage.Int3()).RequestPackageNameRegistryEntryL(aMessage);
+ break;
+ case EUniqueVendorName:
+ SubsessionL(aMessage.Int3()).RequestUniqueVendorNameRegistryEntryL(aMessage);
+ break;
+ case ELocalizedVendorName:
+ SubsessionL(aMessage.Int3()).RequestLocalizedVendorNameRegistryEntryL(aMessage);
+ break;
+ case EUid:
+ SubsessionL(aMessage.Int3()).RequestUidRegistryEntryL(aMessage);
+ break;
+ case ESids:
+ SubsessionL(aMessage.Int3()).RequestSidsRegistryEntryL(aMessage);
+ break;
+ case ELanguage:
+ SubsessionL(aMessage.Int3()).RequestLanguageRegistryEntryL(aMessage);
+ break;
+ case EUidPresent:
+ SubsessionL(aMessage.Int3()).UidPresentRegistryEntryL(aMessage);
+ break;
+ case ESigned:
+ SubsessionL(aMessage.Int3()).SignedRegistryEntryL(aMessage);
+ break;
+ case EGetTrust:
+ SubsessionL(aMessage.Int3()).RegistryEntryTrustL(aMessage);
+ break;
+ case ETrustTimeStamp:
+ SubsessionL(aMessage.Int3()).TrustTimeStampL(aMessage);
+ break;
+ case ETrustStatus:
+ SubsessionL(aMessage.Int3()).TrustStatusEntryL(aMessage);
+ break;
+ case EIsSidPresent:
+ IsSidPresentL(aMessage);
+ break;
+ case EShutdownAllApps:
+ SubsessionL(aMessage.Int3()).ShutdownAllAppsL(aMessage);
+ break;
+ case ERevocationStatus:
+ SubsessionL(aMessage.Int3()).RevocationCheckEntryL(aMessage);
+ break;
+ case ECancelRevocationStatus:
+ SubsessionL(aMessage.Int3()).CancelRevocationCheckEntryL(aMessage);
+ break;
+ case EInRom:
+ SubsessionL(aMessage.Int3()).InRomRegistryEntryL(aMessage);
+ break;
+ case EAugmentation:
+ SubsessionL(aMessage.Int3()).AugmentationRegistryEntryL(aMessage);
+ break;
+ case EControllers:
+ SubsessionL(aMessage.Int3()).RequestControllersL(aMessage);
+ break;
+ case EProperty:
+ SubsessionL(aMessage.Int3()).RequestPropertyRegistryEntryL(aMessage);
+ break;
+ case EFiles:
+ SubsessionL(aMessage.Int3()).RequestFileNamesRegistryEntryL(aMessage);
+ break;
+ case EHashEntry:
+ SubsessionL(aMessage.Int3()).RequestHashRegistryEntryL(aMessage);
+ break;
+ case EFileDescriptions:
+ SubsessionL(aMessage.Int3()).RequestFileDescriptionsRegistryEntryL(aMessage);
+ break;
+ case ESelectedDrive:
+ SubsessionL(aMessage.Int3()).RequestSelectedDriveRegistryEntryL(aMessage);
+ break;
+ case EInstalledDrives:
+ SubsessionL(aMessage.Int3()).RequestInstalledDrivesRegistryEntryL(aMessage);
+ break;
+ case EPreInstalled:
+ SubsessionL(aMessage.Int3()).PreInstalledRegistryEntryL(aMessage);
+ break;
+ case EInstallType:
+ SubsessionL(aMessage.Int3()).RequestInstallTypeRegistryEntryL(aMessage);
+ break;
+ case ECertificateChains:
+ SubsessionL(aMessage.Int3()).RequestCertificateChainsRegistryEntryL(aMessage);
+ break;
+ case EEmbeddedPackages:
+ SubsessionL(aMessage.Int3()).RequestEmbeddedPackageRegistryEntryL(aMessage);
+ break;
+ case EEmbeddingPackages:
+ SubsessionL(aMessage.Int3()).RequestEmbeddingPackagesRegistryEntryL(aMessage);
+ break;
+ case EPackageAugmentations:
+ SubsessionL(aMessage.Int3()).RequestPackageAugmentationsRegistryEntryL(aMessage);
+ break;
+ case EPackageAugmentationsNumber:
+ SubsessionL(aMessage.Int3()).RequestPackageAugmentationsNumberL(aMessage);
+ break;
+ case ESize:
+ SubsessionL(aMessage.Int3()).RequestSizeRegistryEntryL(aMessage);
+ break;
+ case EPackage:
+ SubsessionL(aMessage.Int3()).RequestPackageRegistryEntryL(aMessage);
+ break;
+ case EGetMatchingSupportedLanguages:
+ SubsessionL(aMessage.Int3()).RequestMatchingSupportedLanguagesL(aMessage);
+ break;
+ case ECreateTransaction:
+ CreateTransactionL(aMessage);
+ break;
+ case ECommitTransaction:
+ CommitTransactionL(aMessage);
+ break;
+ case ERollbackTransaction:
+ RollbackTransactionL(aMessage);
+ break;
+ case EAddEntry:
+ RegisterEntryL(aMessage, ETrue, EFalse);
+ break;
+ case EAddSoftwareTypeEntry:
+ RegisterEntryL(aMessage, ETrue, ETrue);
+ break;
+ case EUpdateEntry:
+ RegisterEntryL(aMessage, EFalse, EFalse);
+ break;
+ case EUpdateSoftwareTypeEntry:
+ RegisterEntryL(aMessage, EFalse, ETrue);
+ break;
+ case EDeleteEntry:
+ DeleteEntryL(aMessage);
+ break;
+ case EDependencies:
+ SubsessionL(aMessage.Int3()).RequestDependenciesRegistryEntryL(aMessage);
+ break;
+ case EDependentPackages:
+ SubsessionL(aMessage.Int3()).RequestDependentPackagesRegistryEntryL(aMessage);
+ break;
+ case EGetEntry:
+ RequestRegistryEntryL(aMessage);
+ break;
+ case EAddDrive:
+ AddDriveL(aMessage);
+ break;
+ case EDeletablePreInstalled:
+ SubsessionL(aMessage.Int3()).DeletablePreInstalledRegistryEntryL(aMessage);
+ break;
+ case EVerifyController:
+ {
+ SubsessionL(aMessage.Int3()).VerifyControllerL(aMessage);
+ break;
+ }
+ case ERemoveWithLastDependent:
+ {
+ SubsessionL(aMessage.Int3()).RemoveWithLastDependentL(aMessage);
+ break;
+ }
+ case ESetRemoveWithLastDependent:
+ {
+ SubsessionL(aMessage.Int3()).SetRemoveWithLastDependentL(aMessage);
+ break;
+ }
+ case EloggingFile:
+ LoggingFileInfoL(aMessage);
+ break;
+ case ENonRemovable:
+ SubsessionL(aMessage.Int3()).IsRemovableL(aMessage);
+ break;
+ case ERemovablePackages:
+ RequestRemovablePackagesL(aMessage);
+ break;
+ case EPackageExistsInRom:
+ PackageExistsInRomL(aMessage);
+ break;
+ case EInitRecovery:
+ RecoverL(aMessage);
+ break;
+ case EStubFileEntries:
+ RequestStubFileEntriesL(aMessage);
+ break;
+ case ESignedBySuCert:
+ SubsessionL(aMessage.Int3()).SignedBySuCertRegistryEntryL(aMessage);
+ break;
+ case ESetComponentState:
+ SetComponentStateL(aMessage);
+ break;
+ case EIsFileRegistered:
+ IsFileRegisteredL(aMessage);
+ break;
+ case EComponentIdForUid:
+ GetComponentIdForUidL(aMessage);
+ break;
+ default:
+ PanicClient(aMessage,EPanicIllegalFunction);
+ break;
+ }
+ }
+
+void CSisRegistrySession::RequestInstalledUidsL(const RMessage2& aMessage)
+ {
+ RArray<TUid> uids;
+ CleanupClosePushL(uids);
+
+ // Retrieve all the components from SCR
+ RArray<TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+
+ ScrHelperUtil::GetComponentIdListL(iScrSession, componentIdList);
+
+ // Retrieve the UIDs for all the components
+ TInt compCount = componentIdList.Count();
+ for (TInt index = 0; index < compCount; ++index)
+ {
+ TComponentId compId = componentIdList[index];
+ TUid uid = TUid::Uid(GetIntPropertyValueL(iScrSession, compId, KCompUid, ETrue));
+ TInt err = uids.InsertInUnsignedKeyOrder(uid);
+ if ((err != KErrNone) && (err != KErrAlreadyExists))
+ {
+ CleanupStack::PopAndDestroy(&componentIdList);
+ User::Leave(err);
+ }
+ }
+ CleanupStack::PopAndDestroy(&componentIdList);
+ SisRegistryUtil::SendDataArrayL(aMessage, uids, EIpcArgument0);
+ CleanupStack::PopAndDestroy(&uids);
+ }
+
+void CSisRegistrySession::RequestInstalledPackagesL(const RMessage2& aMessage)
+ {
+ RPointerArray<CSisRegistryPackage> packages;
+ CleanupResetAndDestroyPushL(packages);
+
+ // Retrieve all the installed components from SCR
+
+ RArray<TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+ ScrHelperUtil::GetComponentIdListL(iScrSession, componentIdList);
+
+ // Get the components count and iterate through all of them.
+ TInt compCount = componentIdList.Count();
+ for (TInt index = 0; index < compCount; ++index)
+ {
+ // Take the component Id.
+ TComponentId compId = componentIdList[index];
+ // Get the relevant package from SCR.
+ CSisRegistryPackage *package = NULL;
+ ScrHelperUtil::ReadFromScrL(iScrSession, compId, package);
+ CleanupStack::PushL(package);
+ packages.AppendL(package);
+ CleanupStack::Pop(package);
+ }
+ CleanupStack::PopAndDestroy(&componentIdList);
+ SisRegistryUtil::SendDataPointerArrayL(aMessage, packages, EIpcArgument0);
+ CleanupStack::PopAndDestroy(&packages);
+ }
+
+void CSisRegistrySession::UidInstalledL(const RMessage2& aMessage)
+ {
+ TUid uid;
+ TPckg<TUid> packageUid(uid);
+ aMessage.ReadL(EIpcArgument0, packageUid);
+
+ // check whether is registered
+ TBool isRegistered = IsRegisteredL(uid);
+ DEBUG_CODE_SECTION(
+ if (isRegistered)
+ {
+ DEBUG_PRINTF2(_L8("SIS Registry Server - UID 0x%08x is registered."), uid);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L8("SIS Registry Server - UID 0x%08x is not registered."), uid);
+ }
+ );
+
+ // return the data back
+ TPckgC<TBool> packageBool(isRegistered);
+ aMessage.WriteL(EIpcArgument1, packageBool);
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::ControllerInstalledL(const RMessage2& aMessage)
+ {
+ TBool installed;
+
+ TInt srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC8* buffer = HBufC8::NewLC(srcLen);
+ TPtr8 dest = buffer->Des();
+
+ // read data in the buffer
+ aMessage.ReadL(EIpcArgument0, dest, 0);
+
+ // lets store all in a stream
+ RDesReadStream stream(dest);
+ CleanupClosePushL(stream);
+
+ // now create the hash object to look for
+ CHashContainer* hash = CHashContainer::NewLC(stream);
+
+ // is the entry present already?
+ installed = IsRegisteredL(*hash);
+ DEBUG_CODE_SECTION(
+ if (installed)
+ {
+ DEBUG_PRINTF(_L8("SIS Registry Server - Controller is installed."));
+ }
+ else
+ {
+ DEBUG_PRINTF(_L8("SIS Registry Server - Controller is not installed."));
+ }
+ );
+
+ // return the data back
+ TPckgC<TBool> isInstalled(installed);
+ aMessage.WriteL(EIpcArgument1, isInstalled);
+ aMessage.Complete(KErrNone);
+ // reclaim memory back
+ CleanupStack::PopAndDestroy(3, buffer); // buffer, stream, hash
+ }
+
+void CSisRegistrySession::CreateTransactionL(const RMessage2& aMessage)
+ {
+ TRAPD(err, iScrSession.CreateTransactionL());
+ aMessage.Complete(err);
+ }
+
+void CSisRegistrySession::CommitTransactionL(const RMessage2& aMessage)
+ {
+ TRAPD(err, iScrSession.CommitTransactionL());
+ aMessage.Complete(err);
+ }
+
+void CSisRegistrySession::RollbackTransactionL(const RMessage2& aMessage)
+ {
+ TRAPD(err, iScrSession.RollbackTransactionL());
+ aMessage.Complete(err);
+ }
+
+void CSisRegistrySession::RegisterSoftwareTypesL(TComponentId aComponentId, const RMessage2& aMessage)
+ {
+ RIpcReadStream readStream;
+ readStream.Open(aMessage, 3);
+ CleanupClosePushL(readStream);
+
+ RCPointerArray<CSoftwareTypeRegInfo> swTypeRegInfoArray;
+ CleanupClosePushL(swTypeRegInfoArray);
+ SoftwareTypeRegInfoUtils::UnserializeArrayL(readStream, swTypeRegInfoArray);
+
+ for (TInt i=0; i<swTypeRegInfoArray.Count(); ++i)
+ {
+ const CSoftwareTypeRegInfo& info = *swTypeRegInfoArray[i];
+ const RPointerArray<CLocalizedSoftwareTypeName>& locSwTypeNames = info.LocalizedSoftwareTypeNames();
+ RCPointerArray<Usif::CLocalizedSoftwareTypeName> scrSwTypeNames;
+ CleanupClosePushL(scrSwTypeNames);
+ for (TInt i=0; i<locSwTypeNames.Count(); ++i)
+ {
+ scrSwTypeNames.AppendL(Usif::CLocalizedSoftwareTypeName::NewLC(locSwTypeNames[i]->Name(), locSwTypeNames[i]->Locale()));
+ CleanupStack::Pop();
+ }
+
+ DEBUG_PRINTF2(_L("Sis Registry Server - Adding software type: %S"), &info.UniqueSoftwareTypeName());
+
+ iScrSession.AddSoftwareTypeL(info.UniqueSoftwareTypeName(),
+ info.SifPluginUid(),
+ info.InstallerSecureId(),
+ info.ExecutionLayerSecureId(),
+ info.MimeTypes(),
+ &scrSwTypeNames);
+ CleanupStack::PopAndDestroy(&scrSwTypeNames);
+ }
+
+ RBuf uniqueNames;
+ uniqueNames.CleanupClosePushL();
+ SoftwareTypeRegInfoUtils::SerializeUniqueSwTypeNamesL(swTypeRegInfoArray, uniqueNames);
+ iScrSession.SetComponentPropertyL(aComponentId, KTxtSoftwareTypeComponentProperty, uniqueNames);
+
+ CleanupStack::PopAndDestroy(3, &readStream); // swTypeRegInfoArray, uniqueNames
+ }
+
+void CSisRegistrySession::RegisterEntryL(const RMessage2& aMessage, TBool aNewEntry, TBool aRegisterSoftwareTypes)
+ {
+ // register/update new/existing registry entry
+ // get the registry object from client space
+ // get the size of the descriptor in client space
+ // and allocate sufficient buffer
+ TInt srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC8* buffer = HBufC8::NewLC(srcLen);
+ TPtr8 dest = buffer->Des();
+ // read data in the buffer
+ aMessage.ReadL(EIpcArgument0, dest, 0);
+
+ // lets store all in a stream
+ RDesReadStream stream(dest);
+ CleanupClosePushL(stream);
+
+ // now create a registry entry from the stream
+ CSisRegistryObject* object = CSisRegistryObject::NewL(stream);
+ CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
+ CleanupStack::PushL(object);
+ buffer = NULL;
+
+ DEBUG_CODE_SECTION(
+ if (aNewEntry)
+ {
+ DEBUG_PRINTF4(_L("Sis Registry Server - registering entry for object with UID: 0x%08x, Name: %S, Vendor: %S."),
+ object->Uid().iUid, &(object->Name()), &(object->Vendor()));
+ }
+ else
+ {
+ DEBUG_PRINTF4(_L("Sis Registry Server - updating entry for object with UID: 0x%08x, Name: %S, Vendor: %S."),
+ object->Uid().iUid, &(object->Name()), &(object->Vendor()));
+ }
+ );
+
+
+ TBool isRegistered(EFalse);
+ if(aNewEntry)
+ {
+ isRegistered = IsRegisteredL(object->Uid(), object->Name());
+ }
+ else
+ {
+ // We're upgrading an existing entry, if it's not an augmentation upgrade,
+ // check for the existance of the base package. Otherwise, check by augmentation index
+ if (object->InstallType() != Sis::EInstAugmentation)
+ {
+ isRegistered = IsRegisteredL(object->Uid());
+ }
+ else
+ {
+ isRegistered = IsRegisteredL(object->Uid(), object->Name());
+ }
+ }
+
+ // the entry should not be existing - new or
+ // the entry should be existing - upgrade
+ if (isRegistered != aNewEntry)
+ {
+ // get this transaction ID from client space, using packaging
+ TInt64 transactionID;
+ TPckg<TInt64> pkgTransactionID(transactionID);
+ aMessage.ReadL(EIpcArgument1, pkgTransactionID);
+
+ RStsSession stsSession;
+ stsSession.OpenTransactionL(transactionID);
+ CleanupClosePushL(stsSession);
+
+ if (!aNewEntry)
+ {
+ // Retrieve all the component details from SCR
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, object->Uid(), object->Index());
+
+ CSisRegistryObject* existingObject = CSisRegistryObject::NewLC();
+ ScrHelperUtil::GetComponentL(iScrSession, compId, *existingObject);
+
+ // DEF085506 fix. remove control files (Previous SA and any of PUs) also while SA upgrading.
+ if (object->InstallType() == Sis::EInstInstallation)
+ {
+ RemoveEntryL(*existingObject);
+ RemoveCleanupInfrastructureL(*existingObject, stsSession);
+ }
+ else // PartialUpgarde case remove only registry file.
+ {
+ // Essentially, this is an uninstall except we leave the controller file intact.
+ RemoveEntryL(*existingObject);
+ }
+ CleanupStack::PopAndDestroy(existingObject);
+ }
+ // get the current controller from client space
+ // check the size of the descriptor in client space
+ // and allocate accordingly
+ TInt srcLenCtrl = aMessage.GetDesLengthL(EIpcArgument2);
+ HBufC8* bufferCtrl = HBufC8::NewLC(srcLenCtrl);
+ TPtr8 destCtrl = bufferCtrl->Des();
+
+ // read controller content as a binary data
+ aMessage.ReadL(EIpcArgument2, destCtrl, 0);
+ Usif::TScrComponentOperationType opType = aNewEntry ? Usif::EScrCompInstall : Usif::EScrCompUpgrade;
+ const TComponentId compId = AddRegistryEntryL(*object, stsSession, *bufferCtrl, opType);
+
+ // Register software types
+ if (aRegisterSoftwareTypes)
+ {
+ RegisterSoftwareTypesL(compId, aMessage);
+ }
+
+ CleanupStack::PopAndDestroy(2, &stsSession); // bufferCtrl
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ DEBUG_CODE_SECTION(
+ if (aNewEntry)
+ {
+ DEBUG_PRINTF(_L8("Sis Registry Server - Error, package already exists!"));
+ }
+ else
+ {
+ DEBUG_PRINTF(_L8("Sis Registry Server - Error, package was not found!"));
+ }
+ );
+
+ TInt reason = (aNewEntry)? KErrAlreadyExists:KErrNotFound;
+ aMessage.Complete(reason);
+ }
+
+ // need to free up the used memory
+ CleanupStack::PopAndDestroy(object);
+ }
+
+void CSisRegistrySession::UnregisterSoftwareTypesL(TComponentId aComponentId)
+ {
+ CLocalizablePropertyEntry* property = static_cast<CLocalizablePropertyEntry*>(iScrSession.GetComponentPropertyL(aComponentId, KTxtSoftwareTypeComponentProperty));
+ if (property == NULL)
+ {
+ return;
+ }
+ CleanupStack::PushL(property);
+
+ RArray<TPtrC> swTypeNames;
+ CleanupClosePushL(swTypeNames);
+ SoftwareTypeRegInfoUtils::UnserializeUniqueSwTypeNamesL(property->StrValue(), swTypeNames);
+
+ RCPointerArray<HBufC8> deletedMimeTypes;
+ CleanupClosePushL(deletedMimeTypes);
+
+ for (TInt i=0; i<swTypeNames.Count(); ++i)
+ {
+ RCPointerArray<HBufC> deletedMimeTypes16;
+ CleanupClosePushL(deletedMimeTypes16);
+ iScrSession.DeleteSoftwareTypeL(swTypeNames[i], deletedMimeTypes16);
+
+ for (TInt m=0; m<deletedMimeTypes16.Count(); ++m)
+ {
+ const TDesC& mimeType16 = *deletedMimeTypes16[m];
+ HBufC8* mimeType = HBufC8::NewLC(mimeType16.Length());
+ mimeType->Des().Copy(mimeType16);
+ deletedMimeTypes.AppendL(mimeType);
+ CleanupStack::Pop(mimeType);
+ }
+
+ CleanupStack::PopAndDestroy(&deletedMimeTypes16);
+ }
+
+ // Use SISLauncher to unregister MIME types for SIFLauncher
+ RSisLauncherSession launcher;
+ CleanupClosePushL(launcher);
+ TInt err = launcher.Connect();
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF2(_L8("Failed to connect to the SISLauncher, err = %d\n"), err);
+ User::Leave(err);
+ }
+ launcher.UnregisterSifLauncherMimeTypesL(deletedMimeTypes);
+
+ CleanupStack::PopAndDestroy(4, property); // swTypeNames, deletedMimeTypes, launcher
+ }
+
+// Delete a registry entry keyed by package and vendor names
+// uses integrity services and the associated transactionId
+void CSisRegistrySession::DeleteEntryL(const RMessage2& aMessage)
+ {
+
+ TUid uid;
+ TPckg<TUid> packageUid(uid);
+ aMessage.ReadL(EIpcArgument0, packageUid, 0);
+
+ TInt pkgIndex;
+ TPckg<TInt> packageIndex(pkgIndex);
+ aMessage.ReadL(EIpcArgument1, packageIndex);
+
+ Usif::TComponentId componentId = ScrHelperUtil::GetComponentIdL(iScrSession, uid, pkgIndex);
+
+ // If the component being removed has registered software types, unregister them now.
+ // This operation deletes MIME types mapping from AppArc and therefore is not transactional.
+ UnregisterSoftwareTypesL(componentId);
+
+ CSisRegistryObject* object = CSisRegistryObject::NewLC();
+ ScrHelperUtil::GetComponentL(iScrSession, componentId, *object);
+
+ DEBUG_PRINTF4(_L("Sis Registry Server - Removing package registry entry for UID: %08x, Name: %S, Vendor %S."),
+ object->Uid().iUid, &(object->Name()), &(object->Vendor()));
+
+ // transaction ID - ipc(2)
+ TInt64 transactionID;
+ TPckg<TInt64> pkgTransactionID(transactionID);
+ aMessage.ReadL(EIpcArgument2, pkgTransactionID);
+
+ // create a integrity service object
+ Usif::RStsSession stssession;
+ stssession.OpenTransactionL(transactionID);
+ CleanupClosePushL(stssession);
+
+ RemoveEntryL(*object);
+ RemoveCleanupInfrastructureL(*object, stssession);
+
+ // If removal is for ROM upgrade type, after removing the existing registry entry set,
+ // regenerate the Registry Entry Cache.
+ // If any of the ROM based stub doesn't have its registry set
+ // in appropriate path, it will create them (SCR entry & . ctl)
+ // from the ROM based stub sis file.
+ if ((object->InstallType() == Sis::EInstInstallation ||
+ object->InstallType() == Sis::EInstPartialUpgrade) &&
+ SisRegistryUtil::RomBasedPackageL(object->Uid()))
+ {
+ // Re-add the ROM installed stub details to SCR (only those missing will be added)
+ ProcessRomDriveL();
+ }
+ CleanupStack::PopAndDestroy(2, object);// STS
+
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::OpenRegistryUidEntryL(const RMessage2& aMessage)
+ {
+ // expects a UID as an arg 0
+ TUid uid;
+ TPckg<TUid> packageUid(uid);
+ aMessage.ReadL(EIpcArgument0, packageUid, 0);
+
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Opening entry subsession for UID: %08x"),
+ uid.iUid);
+
+ TUint subsessionId = 0;
+ TRAPD(err, subsessionId = CreateSubsessionHandleL(uid));
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF3(_L8("Sis Registry Server - Error (%d) creating subsession handle for package uid: %08x"), err, uid.iUid);
+ aMessage.Complete(err);
+ return;
+ }
+
+ TPckgC<TInt> refId(subsessionId);
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Sucessfully opened, subsession ID %d."), subsessionId);
+ aMessage.WriteL(EIpcArgument3, refId);
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::OpenRegistryPackageEntryL(const RMessage2& aMessage)
+ {
+ // Package Name - ipc(0)
+ TInt srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC8* buffer = HBufC8::NewLC(srcLen);
+ TPtr8 dest = buffer->Des();
+ // read data in the buffer
+ aMessage.ReadL(EIpcArgument0, dest, 0);
+
+ // lets store all in a stream
+ RDesReadStream stream(dest);
+ CleanupClosePushL(stream);
+
+ // now create a registry entry
+ CSisRegistryPackage* package = CSisRegistryPackage::NewLC(stream);
+
+ DEBUG_PRINTF5(_L("Sis Registry Server - Opening entry subsession for UID: %08x, Name: %S, Vendor: %S, Index:%d"),
+ package->Uid().iUid, &(package->Name()), &(package->Vendor()), package->Index());
+
+ TUint subsessionId = 0;
+ TRAPD(err, subsessionId = CreateSubsessionHandleL(*package));
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF3(_L8("Sis Registry Server - Error (%d) creating subsession handle for package uid: %08x"), err, package->Uid().iUid);
+ aMessage.Complete(err);
+ CleanupStack::PopAndDestroy(3, buffer); // buffer, stream, package
+ return;
+ }
+
+ TPckgC<TInt> refId(subsessionId);
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Sucessfully opened, subsession ID %d."), subsessionId);
+ aMessage.WriteL(EIpcArgument3, refId);
+ aMessage.Complete(KErrNone);
+ CleanupStack::PopAndDestroy(3, buffer); // buffer, stream, package
+ }
+
+void CSisRegistrySession::OpenRegistryNamesEntryL(const RMessage2& aMessage)
+ {
+ // expects a package name and a vendor name as an arg 0 and 1
+ // Package Name - ipc(0)
+ TInt srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC* packageName = HBufC::NewLC(srcLen);
+ TPtr namePtr1 = packageName->Des();
+ aMessage.ReadL(EIpcArgument0, namePtr1, 0);
+
+ // Vendor's Name - ipc(1)
+ srcLen = aMessage.GetDesLengthL(EIpcArgument1);
+ HBufC* vendorName = HBufC::NewLC(srcLen);
+ TPtr namePtr2 = vendorName->Des();
+ // read
+ aMessage.ReadL(EIpcArgument1, namePtr2, 0);
+
+ DEBUG_PRINTF3(_L("Sis Registry Server - Opening entry subsession by name/vendor. Name: %S, Vendor: %S."),
+ packageName, vendorName);
+
+ TUint subsessionId = 0;
+ TRAPD(err, subsessionId = CreateSubsessionHandleL(*packageName, *vendorName));
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Error (%d) creating subsession handle for package"), err);
+ aMessage.Complete(err);
+ CleanupStack::PopAndDestroy(2, packageName);// packageName, vendorName
+ return;
+ }
+
+ TPckgC<TInt> refId(subsessionId);
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Sucessfully opened, subsession ID %d."), subsessionId);
+ aMessage.WriteL(EIpcArgument3, refId);
+ aMessage.Complete(KErrNone);
+ CleanupStack::PopAndDestroy(2, packageName);// packageName, vendorName
+ }
+
+void CSisRegistrySession::CloseRegistryEntryL(const RMessage2& aMessage)
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Closing open subsession, ID %d."),
+ aMessage.Int3());
+
+ CloseSubsessionHandleL(aMessage.Int3());
+ aMessage.Complete(KErrNone);
+ }
+
+// Gets the total number of files in a stub file and all the entries as well.
+// The output will be based on the request parameters (operational mode) sent as input.
+void CSisRegistrySession::RequestStubFileEntriesL(const RMessage2& aMessage)
+ {
+ TBool stubNotFound(ETrue);
+
+ TUid tUid;
+ TPckg<TUid> packageUid(tUid);
+ aMessage.ReadL(EIpcArgument0, packageUid, 0);
+
+ TStubExtractionMode tMode;
+ TPckg<TStubExtractionMode> packageMode(tMode);
+ aMessage.ReadL(EIpcArgument1, packageMode, 0);
+
+ // Prepare the stub file path.
+ TDriveUnit romDrive(EDriveZ);
+ RBuf romRegistryPath;
+ romRegistryPath.CreateL(romDrive.Name(), KMaxPath);
+ CleanupClosePushL(romRegistryPath);
+ romRegistryPath.Append(KPreInstalledPath);
+
+ RFs tFs;
+ CDir* dir;
+
+ // Get stub files under the ROM stub directory (Z:\system\install\).
+ User::LeaveIfError(tFs.Connect());
+ CleanupClosePushL(tFs);
+
+ TInt err = tFs.GetDir(romRegistryPath, KEntryAttMatchExclude | KEntryAttDir, ESortNone, dir);
+
+ if (err == KErrNone)
+ {
+ CleanupStack::PushL(dir);
+ TInt count(dir->Count());
+ RBuf controllerFileName;
+ controllerFileName.CreateL(KMaxFileName);
+ CleanupClosePushL(controllerFileName);
+ for (TInt index = 0; index < count; ++index)
+ {
+ controllerFileName = romRegistryPath;
+ controllerFileName.Append((*dir)[index].iName);
+
+ // Read the ROM stub controller
+ CFileSisDataProvider* fileProvider = CFileSisDataProvider::NewLC(tFs, controllerFileName);
+ Swi::Sis::CController* stubController = NULL;
+ TRAPD(errCode, stubController = Swi::Sis::CController::NewL(*fileProvider));
+ if (errCode != KErrNone)
+ {
+ // Ignore the broken stub file under the ROM stub directory.
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Failed to read the stub controller. Error code %d."), errCode);
+ CleanupStack::PopAndDestroy(fileProvider);
+ continue;
+ }
+ CleanupStack::PushL(stubController);
+
+ // If the UID in a stub file matches the current package's UID,
+ // populate the list of eclipsable files from the same stub file.
+ if ( stubController->Info().Uid().Uid() == tUid )
+ {
+ stubNotFound = EFalse;
+ const RPointerArray<Sis::CFileDescription>& depArray = stubController->InstallBlock().FileDescriptions();
+ // Get as many number of files as possible that can be accomodate in client allocated buffer.
+ if (tMode == EGetFiles)
+ {
+ TInt sizeRed = 0;
+ TInt startingFileNo;
+ TPckg<TInt> start(startingFileNo);
+ aMessage.ReadL(EIpcArgument2, start, 0);
+
+ RPointerArray<TPtrC> fileNames;
+ CleanupResetAndDestroy<RPointerArray<TPtrC> >::PushL(fileNames);
+
+ TInt totalDepArrayCount = depArray.Count();
+ // Populate the files in to a temporary array.
+ for(TInt fileCount = startingFileNo; fileCount < totalDepArrayCount; ++fileCount )
+ {
+ sizeRed += depArray[fileCount]->Target().Data().Size();
+ // If amount of data red exceeds the client buffer size, break reading.
+ if (sizeRed > KDefaultBufferSize)
+ {
+ break;
+ }
+
+ // Only create a TPtrC when we know we have space available
+ TPtrC* fileName = new(ELeave) TPtrC(depArray[fileCount]->Target().Data());
+ CleanupStack::PushL(fileName);
+ fileNames.AppendL(fileName);
+ CleanupStack::Pop(fileName);
+ }
+ // Stream via multiple IPC writes instead of
+ // copying to a buffer and streaming from there.
+ RIpcWriteStream ipcstream;
+ ipcstream.Open(aMessage, EIpcArgument3);
+ CleanupClosePushL(ipcstream);
+ ExternalizePointerArrayL(fileNames,ipcstream);
+ ipcstream.CommitL();
+ aMessage.Complete(KErrNone);
+ CleanupStack::PopAndDestroy(&ipcstream);
+ CleanupStack::PopAndDestroy(&fileNames);
+ }
+ // If only the count needed, send the stub file's total entrie's count.
+ else if (tMode == EGetCount)
+ {
+ TPckgBuf<TInt> fileCount(depArray.Count());
+ aMessage.WriteL(EIpcArgument2, fileCount);
+ aMessage.Complete(KErrNone);
+ }
+ CleanupStack::PopAndDestroy(2, fileProvider);
+ break;
+ }
+ CleanupStack::PopAndDestroy(2, fileProvider);
+ }
+ CleanupStack::PopAndDestroy(2, dir); // controllerFileName
+ // If the stub file itself not found, leave with the same error info'
+ if (stubNotFound)
+ {
+ aMessage.Complete(KErrNotFound);
+ }
+ }
+ else if(err != KErrPathNotFound)
+ {
+ aMessage.Complete(err);
+ }
+ CleanupStack::PopAndDestroy(2, &romRegistryPath); // tFs
+ }
+
+void CSisRegistrySession::RequestRegistryEntryL(const RMessage2& aMessage)
+ {
+ TUid uid;
+ TPckg<TUid> packageUid(uid);
+ aMessage.ReadL(EIpcArgument0, packageUid);
+
+ // Get the base component Id matching with the given Uid.
+ TComponentId componentId = ScrHelperUtil::GetComponentIdL(iScrSession, uid, 0);
+
+ // Create an empty registry object and pass on to helper util to populate it from SCR.
+ CSisRegistryObject* object = CSisRegistryObject::NewLC();
+ ScrHelperUtil::GetComponentL(iScrSession, componentId, *object);
+
+ // Serialize the object and send it to client.
+ SisRegistryUtil::SendDataL(aMessage, *object, EIpcArgument1);
+ CleanupStack::PopAndDestroy(object);
+ }
+
+void CSisRegistrySession::AddDriveL(const RMessage2& aMessage)
+ {
+ TInt drive;
+ TPckg<TInt> pkgDrive(drive);
+ aMessage.ReadL(EIpcArgument0, pkgDrive);
+
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Removable drive %d added."), drive);
+
+ // Find flagging controllers for non-preinstalled packages on
+ // this drive and do cleanup if necessary
+ ProcessRemovableDriveL(drive);
+
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::RequestSidToPackageL(const RMessage2& aMessage)
+ {
+ TUid sid;
+ TPckg<TUid> executableSid(sid);
+
+ aMessage.ReadL(EIpcArgument0, executableSid);
+
+ // componentId and index of the first matching Sid in CompSID<index> array gets populated
+ // by call to GetCompIdAndCompSidIndexL().The value of index is redundant here.
+ TComponentId componentId = 0;
+ TInt index = 0;
+ GetCompIdAndCompSidIndexL(sid, componentId, index);
+
+ if(componentId == KErrNotFound)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ CSisRegistryPackage *package = NULL;
+ ScrHelperUtil::ReadFromScrL(iScrSession, componentId, package);
+ CleanupStack::PushL(package);
+
+ DEBUG_PRINTF5(_L("Sis Registry Server - SID 0x%08x is owned by package UID: 0x%08x, Name: %S, Vendor: %S."),
+ sid.iUid, package->Uid().iUid, &(package->Name()), &(package->Vendor()));
+
+ SisRegistryUtil::SendDataL(aMessage, *package, EIpcArgument1);
+ CleanupStack::PopAndDestroy(package);
+
+ }
+
+void CSisRegistrySession::RequestSidToFileNameL(const RMessage2& aMessage)
+ {
+ TInt thirdParameter;
+ TDriveUnit expectedDrive;
+ TUid sid;
+ TPckg<TUid> fileSid(sid);
+
+ // Obtain the sid from argument slot 0 from the client
+ aMessage.ReadL(EIpcArgument0, fileSid);
+
+ // Obtain drive from argument slot 2 from the client.
+ // This parameter will be set to -1 if user did not specified a drive with this request.
+ thirdParameter = aMessage.Int2();
+
+ // Obtain the componentId and array index of CompSID<index> custom property matching a given aSid.
+ TComponentId componentId = 0;
+ TInt index = 0;
+ GetCompIdAndCompSidIndexL(sid, componentId, index, thirdParameter);
+
+ if(componentId == KErrNotFound)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // retrieve the CompSidFileName property value , based on the index obtained.
+ TBuf<KSmlBufferSize> compSidFileName(KEmptyString);
+ compSidFileName.Format(KCompSidFileNameFormat, index);
+
+ HBufC* fileName = GetStrPropertyValueL(iScrSession, componentId, compSidFileName);
+ CleanupStack::PushL(fileName);
+ DEBUG_PRINTF3(_L("Sis Registry Server - SID 0x%08x maps to file '%S'."),
+ sid.iUid, fileName);
+
+ // Send the filename back to the client in argument slot 1
+ aMessage.WriteL(EIpcArgument1, *fileName);
+
+ CleanupStack::PopAndDestroy(fileName);
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::RequestModifiableL(const RMessage2& aMessage)
+ {
+ // get file name
+ TUint srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC* fileName = HBufC::NewLC(srcLen);
+ TPtr namePtr1 = fileName->Des();
+ aMessage.ReadL(EIpcArgument0, namePtr1, 0);
+
+ TBool modifiableFile = ModifiableL(*fileName);
+
+ DEBUG_CODE_SECTION(
+ if (modifiableFile)
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - File '%S' is modifiable."),
+ fileName);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - File '%S' is not modifiable."),
+ fileName);
+ }
+ );
+
+ TPckgC<TBool> isModifiable(modifiableFile);
+ aMessage.WriteL(EIpcArgument1, isModifiable);
+ aMessage.Complete(KErrNone);
+ CleanupStack::PopAndDestroy(fileName);
+ }
+
+void CSisRegistrySession::IsFileRegisteredL(const RMessage2& aMessage)
+ {
+ TUint srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC* fileName = HBufC::NewLC(srcLen);
+ TPtr namePtr1 = fileName->Des();
+ aMessage.ReadL(EIpcArgument0, namePtr1, 0);
+
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+ componentFilter->SetFileL(*fileName);
+
+ RArray<TComponentId> componentsIdList;
+ CleanupClosePushL(componentsIdList);
+ iScrSession.GetComponentIdsL(componentsIdList, componentFilter);
+
+ TBool result = (componentsIdList.Count() > 0);
+
+ TPckgC<TBool> isRegistered(result);
+ aMessage.WriteL(EIpcArgument1, isRegistered);
+ aMessage.Complete(KErrNone);
+ CleanupStack::PopAndDestroy(3, fileName); // componentsIdList, componentFilter
+ }
+
+void CSisRegistrySession::GetComponentIdForUidL(const RMessage2& aMessage)
+ {
+ TInt uid = aMessage.Int0();
+ TComponentId componentId(0);
+ if (!ScrHelperUtil::GetComponentIdL(iScrSession, TUid::Uid(uid), CSisRegistryPackage::PrimaryIndex, componentId))
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Component id for UID %d was not found '%S'."), uid);
+ User::Leave(KErrNotFound);
+ }
+
+ TPckgC<Usif::TComponentId> componentIdPckg(componentId);
+ aMessage.WriteL(EIpcArgument1, componentIdPckg);
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::RequestHashL(const RMessage2& aMessage)
+ {
+ // get file name
+ TUint srcLen = aMessage.GetDesLengthL(EIpcArgument0);
+ HBufC* fileName = HBufC::NewLC(srcLen);
+ TPtr namePtr1 = fileName->Des();
+ aMessage.ReadL(EIpcArgument0, namePtr1, 0);
+
+ DEBUG_PRINTF2(_L("Sis Registry Server - Client requested the hash of file '%S'."), fileName);
+
+ CHashContainer* hashContainer = HashL(*fileName);
+ CleanupStack::PushL(hashContainer);
+
+ SisRegistryUtil::SendDataL(aMessage, *hashContainer, EIpcArgument1);
+
+ CleanupStack::PopAndDestroy(hashContainer);
+ CleanupStack::PopAndDestroy(fileName);
+ }
+
+// Handle an error from CSisRegistrySession::ServiceL()
+// A bad descriptor error implies a badly programmed client, so panic it;
+// otherwise use the default handling (report the error to the client)
+void CSisRegistrySession::ServiceError(const RMessage2& aMessage, TInt aError)
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - ServiceL left with code %d."), aError);
+
+ if (aError == KErrBadDescriptor)
+ {
+ PanicClient(aMessage, EPanicBadDescriptor);
+ }
+ CSession2::ServiceError(aMessage, aError);
+ }
+
+void CSisRegistrySession::UpdateTrustStatusL(const TUid& aUid, const TSisTrustStatus& aTrustStatus)
+ {
+
+ // Get the component (base) for the specified uid
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, aUid, CSisRegistryPackage::PrimaryIndex);
+
+ // Update the trust status
+ ScrHelperUtil::WriteToScrL(iScrSession, compId, aTrustStatus);
+ }
+
+/**
+ Handle the EIsSidPresent message by extracting a SID from the
+ message and checking whether is in any registered package.
+
+ @param aMessage Message refers to client-side descriptors
+ which contains SID and boolean.
+ */
+void CSisRegistrySession::IsSidPresentL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TUid> uid;
+ aMessage.ReadL(EIpcArgument0, uid);
+
+ TBool isPresent = EFalse;
+ TComponentId componentId = 0;
+ TInt index = 0;
+
+ // If the supplied SID is present in SCR, then a call to GetCompIdAndCompSidIndexL succeeds.
+ // Else the componenetId will result in KErrNotFound.
+ GetCompIdAndCompSidIndexL(uid(), componentId, index);
+ if(componentId != KErrNotFound)
+ {
+ isPresent = ETrue;
+ }
+
+ DEBUG_CODE_SECTION(
+ if (isPresent)
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - SID 0x%08x is present in registry."),
+ uid().iUid);
+ }
+ else
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - SID 0x%08x is not present in registry."),
+ uid().iUid);
+ }
+ );
+
+ TPckgBuf<TBool> present(isPresent);
+ aMessage.WriteL(EIpcArgument1, present);
+ aMessage.Complete(KErrNone);
+ }
+
+/**
+ Handle the EPackageExistsInRom message by extracting a pkg uid in the message
+
+ @param aMessage Message refers to client-side descriptors
+ which contains a pkg uid to be searched on ROM stub files
+ and a boolean which holds the return value (string found or not).
+ */
+void CSisRegistrySession::PackageExistsInRomL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TUid> tuid;
+ aMessage.ReadL(EIpcArgument0, tuid);
+ TBool isInRom = SisRegistryUtil::RomBasedPackageL(tuid());
+
+ TPckgBuf<TBool> present(isInRom);
+ aMessage.WriteL(EIpcArgument1, present);
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::RequestRemovablePackagesL(const RMessage2& aMessage)
+ {
+ RPointerArray<CSisRegistryPackage> packages;
+ CleanupResetAndDestroyPushL(packages);
+ RemovablePackageListL(packages);
+ SisRegistryUtil::SendDataPointerArrayL(aMessage, packages, EIpcArgument0);
+ CleanupStack::PopAndDestroy(&packages);
+ }
+
+void CSisRegistrySession::RecoverL(const RMessage2& aMessage)
+ {
+ // Check to see if a backup is in progress...
+ TInt backup = 0;
+ User::LeaveIfError(RProperty::Get(KUidSystemCategory,conn::KUidBackupRestoreKey,backup));
+
+ if(backup == conn::EBURUnset || (backup == (conn::EBURNormal | conn::ENoBackup))) //no backup or restore is in progress
+ {
+ //no recovery attempt is made during backup/restore as recovery may seriously affect the file system, which might impact backup/restore
+ RStsRecoverySession stsRecoverySession;
+ CleanupClosePushL(stsRecoverySession);
+ TRAP_IGNORE(stsRecoverySession.RollbackAllPendingL());
+ CleanupStack::PopAndDestroy(&stsRecoverySession);
+
+ //Start SWI Observer so that it can process the log files left from the previous session.
+ RSwiObserverSession swiObserver;
+ swiObserver.ProcessLogsL(iFs);
+ swiObserver.Close();
+ }
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::LoggingFileInfoL(const RMessage2& aMessage)
+ {
+ CSecurityPolicy* securityPolicy = CSecurityPolicy::GetSecurityPolicyL();
+ TInt maxNumOfEntries = securityPolicy->MaxNumOfLogEntries();
+ HBufC8* buf = ScrHelperUtil::GetLogInfoLC(iScrSession, maxNumOfEntries);
+ if(buf)
+ {
+ aMessage.WriteL(EIpcArgument0, *buf);
+ CleanupStack::PopAndDestroy(buf);
+ }
+ aMessage.Complete(KErrNone);
+ }
+
+void CSisRegistrySession::SetComponentStateL(const RMessage2& aMessage)
+ {
+ TPckgBuf<Usif::TComponentId> pkgComponentId;
+ TPckgBuf<Usif::TScomoState> pkgState;
+ aMessage.ReadL(EIpcArgument0, pkgComponentId, 0);
+ aMessage.ReadL(EIpcArgument1, pkgState, 0);
+ iScrSession.SetScomoStateL(pkgComponentId(), pkgState());
+ aMessage.Complete(KErrNone);
+ }
+
+// Helper methods
+
+TBool CSisRegistrySession::IsRegisteredL(const TUid& aUid)
+ {
+ return ScrHelperUtil::IsUidPresentL(iScrSession, aUid);
+ }
+
+TBool CSisRegistrySession::IsRegisteredL(const CHashContainer& aHashContainer)
+ {
+ // Iterates through all the components registered in SCR and tries to find any component's
+ // controller hash matches with the given hash vlue.
+ CHashContainer* hashContainer = NULL;
+ RPointerArray<CControllerInfo> controllerInfoArray;
+
+ // Create an empty filter.
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+
+ // Get the list of all native components installed on the device.
+ RArray<TComponentId> componentsIdList;
+ CleanupClosePushL(componentsIdList);
+ iScrSession.GetComponentIdsL(componentsIdList, componentFilter);
+
+ // Iterate through all the components in the view.
+ for (TInt idIndex = 0; idIndex < componentsIdList.Count(); idIndex++)
+ {
+ // Get the Controller Info array from SCR.
+ CleanupResetAndDestroyPushL(controllerInfoArray);
+ ScrHelperUtil::InternalizeControllerArrayL(iScrSession, componentsIdList[idIndex], controllerInfoArray);
+ // Iterate through all the controllers, get the hash of each of them and compare with the given value.
+ // If any hash value matches, say the package registered - TRUE.
+ for (TInt index = 0; index < controllerInfoArray.Count(); index++)
+ {
+ ScrHelperUtil::ReadFromScrL(iScrSession, componentsIdList[idIndex], hashContainer, index);
+ CleanupStack::PushL(hashContainer);
+ if (aHashContainer == *hashContainer)
+ {
+ CleanupStack::PopAndDestroy(4, componentFilter); // componentFilter, componentsIdList, controllerInfoArray & hashContainer
+ // There found a matching component. So, return TRUE.
+ return ETrue;
+ }
+ CleanupStack::PopAndDestroy(hashContainer);
+ }
+
+ CleanupStack::PopAndDestroy(&controllerInfoArray);
+ }
+
+ CleanupStack::PopAndDestroy(2, componentFilter); //componentFilter & componentsIdList
+
+ // None of the registered component's controller hash matches with the given hash.
+ // So, return FALSE. Mean to say, the component on invocation is not registered yet.
+ return EFalse;
+ }
+
+TBool CSisRegistrySession::IsRegisteredL(const TUid& aUid, const TDesC& aPackageName)
+ {
+ return ScrHelperUtil::IsUidAndNamePresentL(iScrSession, aUid, aPackageName);
+ }
+
+void CSisRegistrySession::RemoveEntryL(const CSisRegistryPackage& aPackage)
+ {
+ DEBUG_PRINTF4(_L("Sis Registry Server - Removing the entry from Software Component Registry of package : UID: 0x%08x, Name: %S, Vendor: %S ."),
+ aPackage.Uid().iUid, &aPackage.Name(), &aPackage.Vendor());
+
+ // Get the corresponding component from SCR
+ TComponentId compId = 0;
+ if (!ScrHelperUtil::GetComponentIdL(iScrSession, aPackage.Uid(), aPackage.Index(), compId))
+ {
+ //if aPackage is not present in the database , then display the message and leave
+ DEBUG_PRINTF4(_L("Component Entry : UID: 0x%08x, Name: %S, Vendor: %S , not found in Software Component Registry"),
+ aPackage.Uid().iUid, &aPackage.Name(), &aPackage.Vendor());
+ User::Leave(KErrNotFound);
+ }
+
+ iScrSession.DeleteComponentL(compId);
+ }
+
+void CSisRegistrySession::RemoveCleanupInfrastructureL(const CSisRegistryObject& aObject, RStsSession& aStsSession)
+ {
+ DEBUG_PRINTF(_L8("Sis Registry Server - Removing cleanup infrastructure."));
+
+ RArray<TInt> driveArray;
+ CleanupClosePushL(driveArray);
+ ControllerDriveListL(aObject, driveArray);
+ TInt count(driveArray.Count());
+ for (TInt i = 0; i < count; ++i)
+ {
+ TInt driveNum = driveArray[i];
+ TChar driveChar;
+ User::LeaveIfError(RFs::DriveToChar(driveNum, driveChar));
+
+ // Check if the drive exists before trying to do anything with it,
+ // otherwise ignore it and continue to the next drive.
+ // Also skip write-protected media for pre-installed packages.
+ // An entry registered as a preinstalled package should only have a
+ // drive in this array when it is a package installed from a removable
+ // media stub (also known as a propagation) and the swipolicy indicates
+ // that such packages are deletable.
+ TVolumeInfo volInfo;
+ if (KErrNone == iFs.Volume(volInfo, driveNum) &&
+ (!aObject.PreInstalled() ||
+ !(volInfo.iDrive.iMediaAtt & KMediaAttWriteProtected)))
+ {
+ // remove the controller(s) for this registry entry and drive
+ if (RemoveControllerL(aObject, aStsSession, driveNum))
+ {
+ // If the controller was sucessfully removed then remove the uninstall logs
+ // Uninstall logs aren't created for files installed on the system drive
+ if (driveNum == iSystemDrive || aObject.InRom())
+ {
+ continue;
+ }
+
+ HBufC* name = SisRegistryUtil::BuildUninstallLogFileNameLC(aObject.Uid(), aObject.Index(), driveChar);
+ DEBUG_PRINTF2(_L("Sis Registry Server - Attempting to remove cleanup log '%S'"), name);
+ TRAPD(err, aStsSession.RemoveL(*name));
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - Failed to remove cleanup log (unexpected error: %d.)"), err);
+ User::Leave(err);
+ }
+ CleanupStack::PopAndDestroy(name);
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&driveArray);
+ }
+
+TBool CSisRegistrySession::RemoveControllerL(const CSisRegistryObject& aObject, RStsSession& aStsSession, TInt aDrive)
+ {
+ TInt count(aObject.ControllerInfo().Count());
+ TBool removed = ETrue;
+ for (TInt i = 0; i < count; i++)
+ {
+ HBufC* name = SisRegistryUtil::BuildControllerFileNameLC(aObject.Uid(), aObject.Index(), aObject.ControllerInfo()[i]->Offset(), aDrive);
+ DEBUG_PRINTF2(_L("Sis Registry Server - Removing flagging controller '%S'."), name);
+
+ TRAPD(err, aStsSession.RemoveL(*name));
+ if (err != KErrNone)
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Removal of flagging controller failed (Unexpected error %d.)"), err);
+ removed = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(name);
+ }
+ return removed;
+ }
+
+// creates a compacted array using a token
+void CSisRegistrySession::ControllerDriveListL(const CSisRegistryObject& aObject, RArray<TInt>& aDriveList)
+ {
+ aDriveList.Reset();
+ // a copy of the controller is always kept on drive C
+ aDriveList.Append(iSystemDrive);
+
+ // only controllers will be written to removable media and
+ // we have now to check for those
+ TUint installationDrives = aObject.Drives();
+ TUint fixedDrives = FixedDrivesL();
+ TUint remainingDrives = installationDrives & ~fixedDrives;
+
+ if (remainingDrives)
+ {
+ TInt index = 0;
+ // reuse the path but change drive letter
+ while (remainingDrives)
+ {
+ // compare a single drive digit
+ if (remainingDrives & 0x00000001)
+ {
+ User::LeaveIfError(aDriveList.Append(index));
+ }
+ remainingDrives>>=1;
+ index++;
+ }
+ }
+ }
+
+// Returns a bitmap of internal drives present on the system
+TUint CSisRegistrySession::FixedDrivesL() const
+ {
+ TUint intDrives = 0;
+ TDriveList driveList;
+
+ // Get all the internal drives and convert the list to a bit array
+ User::LeaveIfError(iFs.DriveList(driveList, KDriveAttInternal));
+ for (TInt drive = 0; drive < KMaxDrives; ++drive)
+ {
+ if (driveList[drive] != 0)
+ {
+ intDrives |= (1 << drive);
+ }
+ }
+ return intDrives;
+ }
+
+TComponentId CSisRegistrySession::AddRegistryEntryL(CSisRegistryObject& aObject, RStsSession& aStsSession, const TDesC8& aController, Usif::TScrComponentOperationType aOpType)
+ {
+ const TComponentId compId = AddEntryL(aObject, aOpType);
+
+ // If swipolicy.ini sets false to DeletePreinstalledFilesOnUninstall
+ // we don't need to create an uninstall log because we don't want cleanup activity to happen.
+ // Just add the controller for preinstalled app in system drive.
+ if(aObject.PreInstalled() && !aObject.DeletablePreInstalled())
+ {
+ // Create a controller on system drive for preinstalled application
+ AddControllerL(aObject, aStsSession, aController, iSystemDrive);
+ }
+ else
+ {
+ // Add cleanup infrastructure if required
+ AddCleanupInfrastructureL(aObject, aStsSession, aController);
+ }
+
+ return compId;
+ }
+
+TComponentId CSisRegistrySession::AddEntryL(CSisRegistryObject& aObject, Usif::TScrComponentOperationType aOpType)
+ {
+ // set the index
+ if (aObject.InstallType() == Sis::EInstAugmentation ||
+ aObject.InstallType() == Sis::EInstPreInstalledPatch)
+ {
+ // Just get the number of installed augmentations - this is nothing but the index of the last augmentation
+ aObject.SetIndex(GetAugmentationCountL(aObject.Uid()) + 1);
+ }
+
+ // Resolve the embedded packages index values
+ TInt embeddedIndex = 0;
+ CSisRegistryPackage* embeddedPackage = NULL;
+ while ((embeddedPackage = aObject.EmbeddedPackage(embeddedIndex++)) != NULL)
+ {
+ // Retrieve the component Id from SCR for a given Package UID, name and vendor.
+ // If the package is not present in the registry, do not consider it as an error - embedded packages may upgrade each other causing a single registry entry
+ TComponentId componentId(0);
+ if (!ScrHelperUtil::GetComponentIdL(iScrSession, embeddedPackage->Name(), embeddedPackage->Vendor(), componentId))
+ continue;
+
+ TInt packageIndex = GetIntPropertyValueL(iScrSession, componentId, KCompIndex, EFalse, KDefaultComponentIndex);
+ embeddedPackage->SetIndex(packageIndex);
+ }
+
+ // Store the SIS Registry Object in to the Software Component Registry.
+ TComponentId compId = 0;
+ ScrHelperUtil::AddComponentL(iScrSession, compId, aObject, aOpType);
+ // Set SCOMO state to activated - when SWI Registry supports de-activation, should be changed accordingly
+ iScrSession.SetScomoStateL(compId, EActivated);
+
+ return compId;
+ }
+
+void CSisRegistrySession::AddControllerL(const CSisRegistryObject& aObject,
+ RStsSession& aStsSession, const TDesC8& aBuffer, const TInt aDrive)
+ {
+ HBufC* name = SisRegistryUtil::BuildControllerFileNameLC(aObject.Uid(), aObject.Index(), aObject.ControllerInfo().Count()-1, aDrive);
+ DEBUG_PRINTF2(_L("Sis Registry Server - Installing controller file to '%S'."), name);
+
+ TEntry entry;
+ if (KErrNone == iFs.Entry(*name, entry))
+ {
+ // Remove any existing file with the same name
+ aStsSession.RemoveL(*name);
+ }
+
+ // add controller to integrity services log
+ aStsSession.RegisterNewL(*name);
+
+ // store
+ SisRegistryUtil::EnsureDirExistsL(iFs, *name);
+
+ RFileWriteStream fileStream;
+ User::LeaveIfError(fileStream.Create(iFs, *name, EFileWrite|EFileShareExclusive));
+ CleanupStack::PopAndDestroy(name);
+ CleanupClosePushL(fileStream);
+ fileStream.WriteL(aBuffer);
+
+ // commit and close file
+ CleanupStack::PopAndDestroy(&fileStream);
+ }
+
+void CSisRegistrySession::AddCleanupInfrastructureL(CSisRegistryObject& aObject, RStsSession& aStsSession, const TDesC8& aControllerBuffer)
+ {
+ DEBUG_PRINTF(_L8("Sis Registry Server - Adding Cleanup Infrastructure."));
+
+ RArray<TInt> driveArray;
+ CleanupClosePushL(driveArray);
+ ControllerDriveListL(aObject, driveArray);
+ TInt driveCount(driveArray.Count());
+ // Loop through all the removable drives (and the system drive)
+ for (TInt i = 0; i < driveCount; ++i)
+ {
+ TInt driveNum = driveArray[i];
+ // Skip drives which are not present. Note that this will only be
+ // valid for filenull operations, but we will otherwise have failed
+ // earlier in installation planning so we don't need to check
+ // the operation again.
+ TVolumeInfo volInfo;
+ if (KErrNone != iFs.Volume(volInfo, driveNum))
+ {
+ continue;
+ }
+
+ // Create a flagging controller on the drive in question
+ AddControllerL(aObject, aStsSession, aControllerBuffer, driveNum);
+
+ // There is no need to create uninstall logs for the files put on the
+ // system drive; all other drives in the list should be removable.
+ // We can also skip writing uninstall logs if the object is in ROM,
+ // since uninstallation should never be possible.
+ if (driveNum == iSystemDrive || aObject.InRom())
+ {
+ continue;
+ }
+
+ // Create uninstall log on the system drive and add all installed files to it
+ // Note that there is a separate uninstall log created for each removable drive (these
+ // go in separate contained directories named the same as the drive letter)
+ TChar driveLetter;
+ User::LeaveIfError(iFs.DriveToChar(driveNum, driveLetter));
+ driveLetter.Fold();
+ HBufC* ulogName = SisRegistryUtil::BuildUninstallLogFileNameLC(aObject.Uid(), aObject.Index(), driveLetter);
+
+ // If dir exists register it for removal since this is a data-caged area and we
+ // don't want presence of any other files here.
+ // NOTE: Here we are relying on the ordering of operations executed by STS
+ // We are expecting the removal first and then addition of a new file!
+ TParsePtrC parseName(*ulogName);
+ TPtrC parsePath = parseName.DriveAndPath();
+ TEntry entry;
+ if (iFs.Entry(parsePath, entry) == KErrNone)
+ {
+ // Remove any uninstall logs with this path
+ aStsSession.RemoveL(parsePath);
+ }
+
+ SisRegistryUtil::EnsureDirExistsL(iFs, *ulogName);
+ DEBUG_PRINTF2(_L("Sis Registry Server - Creating uninstall log '%S'"), ulogName);
+
+ RFile ulogFile;
+ CleanupClosePushL(ulogFile);
+ aStsSession.CreateNewL(*ulogName, ulogFile, TFileMode(EFileShareExclusive |EFileStream));
+ RFileWriteStream ulogStream(ulogFile);
+ CleanupClosePushL(ulogStream);
+
+ TInt filesCount = aObject.FileDescriptions().Count();
+ for (TInt index = 0; index < filesCount; ++index)
+ {
+ const TDesC& target = aObject.FileDescriptions()[index]->Target();
+ TChar targetDrive = target[0];
+ targetDrive.Fold();
+ // Only add files that are installed to this removable drive
+ if (driveLetter == targetDrive)
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - Adding file '%S' cleanup uninstall log"), &target);
+ ulogStream << target;
+ }
+ }
+
+ // Add any potential private paths as targets for cleanup operations
+ RBuf privatePath;
+ privatePath.CreateL(KMaxFileName);
+ CleanupClosePushL(privatePath);
+ TInt sidCount = aObject.Sids().Count();
+ for (TInt index = 0; index < sidCount; ++index)
+ {
+ privatePath = KPrivatePathFormat;
+ privatePath[0] = driveLetter;
+ privatePath.AppendNumFixedWidthUC(aObject.Sids()[index].iUid, EHex, KUidHexLength);
+ privatePath.Append(KPathDelimiter);
+
+ DEBUG_PRINTF2(_L("Sis Registry Server - Adding (potential) private path '%S' to cleanup uninstall log"), &privatePath);
+ ulogStream << privatePath;
+ }
+
+ // Add the flagging controller
+ HBufC* controllerName = SisRegistryUtil::BuildControllerFileNameLC(aObject.Uid(),
+ aObject.Index(), aObject.ControllerInfo().Count() - 1, driveNum);
+ ulogStream << *controllerName;
+
+ // We need to ensure that an automatic cleanup does not happen if the media card is inserted
+ // in to a different phone since this would leave behind a broken installation on the original
+ // phone even when the card is put back into it.
+ CleanupStack::PopAndDestroy(5, ulogName); // ulogFile, ulogStream, privatePath, controllerName
+ }
+
+ CleanupStack::PopAndDestroy(&driveArray);
+ }
+
+/*
+ * Subsession creation helper method. For the supplied package UID opens the corresponding
+ * component (base), stores it in an array and returns the entry's index as the subsession ID
+ */
+TUint CSisRegistrySession::CreateSubsessionHandleL(const TUid& aPackageUid)
+ {
+ // Get the component matching the Uid (get the base component)
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, aPackageUid, CSisRegistryPackage::PrimaryIndex);
+
+ // Store the component ID and return the array index as subsession ID
+ // NOTE: This code assumes the items are appended sequentially thereby the indexing increases monotonically!
+ CSisRegistrySubSession *subsession = new (ELeave) CSisRegistrySubSession(*this, compId, aPackageUid);
+ CleanupStack::PushL(subsession);
+ iOpenedPackages.AppendL(subsession);
+ CleanupStack::Pop(subsession);
+ return iOpenedPackages.Count(); // Will be index + 1
+ }
+
+/*
+ * Subsession creation helper method. For the supplied package opens the corresponding
+ * component, stores it in an array and returns the entry's index as the subsession ID
+ */
+TUint CSisRegistrySession::CreateSubsessionHandleL(const CSisRegistryPackage& aPackage)
+ {
+ // Get the component matching the Uid (get the base component)
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, aPackage.Uid(), aPackage.Index());
+
+ // Store the component ID and return the array index as subsession ID
+ // NOTE: This code assumes the items are appended sequentially thereby the indexing increases monotonically!
+ CSisRegistrySubSession *subsession = new (ELeave) CSisRegistrySubSession(*this, compId, aPackage.Uid());
+ CleanupStack::PushL(subsession);
+ iOpenedPackages.AppendL(subsession);
+ CleanupStack::Pop(subsession);
+ return iOpenedPackages.Count(); // Will be index + 1
+ }
+
+/*
+ * Subsession creation helper method. For the supplied package name and vendor name opens the
+ * corresponding component, stores it in an array and returns the entry's index as the subsession ID
+ * NOTE: There can be multiple such components and this API opnes the first one found!
+ */
+TUint CSisRegistrySession::CreateSubsessionHandleL(const TDesC& aPackageName, const TDesC& aVendorName)
+ {
+ // Get the component matching the Uid (get the base component)
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, aPackageName, aVendorName);
+ // Get the uid
+ TUid uid = TUid::Uid(GetIntPropertyValueL(iScrSession, compId, KCompUid, ETrue));
+
+ // Store the component ID and return the array index as subsession ID
+ // NOTE: This code assumes the items are appended sequentially thereby the indexing increases monotonically!
+ CSisRegistrySubSession *subsession = new (ELeave) CSisRegistrySubSession(*this, compId, uid);
+ CleanupStack::PushL(subsession);
+ iOpenedPackages.AppendL(subsession);
+ CleanupStack::Pop(subsession);
+ return iOpenedPackages.Count(); // Will be index + 1
+ }
+
+void CSisRegistrySession::CloseSubsessionHandleL(TUint aId)
+ {
+ TInt index = OpenedPackageIndexL(aId);
+ CSisRegistrySubSession* subsession = iOpenedPackages[index];
+ iOpenedPackages.Remove(index);
+ delete subsession;
+ }
+
+CSisRegistrySubSession& CSisRegistrySession::SubsessionL(TUint aSubsessionId)
+ {
+ // Lookup the component ID for this subsession ID
+ TInt index = OpenedPackageIndexL(aSubsessionId);
+ return *iOpenedPackages[index];
+ }
+
+TUint CSisRegistrySession::OpenedPackageIndexL(TUint aSubsessionId)
+ {
+ TInt index = aSubsessionId - 1; // Subtract 1 since we return subsession ID as index + 1
+ if (index < 0 || index >= iOpenedPackages.Count())
+ {
+ User::Leave(KErrNotFound);
+ }
+ return index;
+ }
+
+TBool CSisRegistrySession::IdentifyControllerL(TComponentId aComponentId, const TDesC& aFileName)
+ {
+ TBool found = EFalse;
+
+ // Get the controller's hashes to verify if the controller file belongs to this component
+ RPointerArray<CControllerInfo> controllerInfo;
+ CleanupResetAndDestroyPushL(controllerInfo);
+ ScrHelperUtil::InternalizeControllerArrayL(iScrSession, aComponentId, controllerInfo);
+
+ // Calculate the hash of the controller passed in as a filename
+ RFile file;
+ User::LeaveIfError(file.Open(iFs, aFileName, EFileRead | EFileShareReadersOnly));
+ CleanupClosePushL(file);
+ TInt fileSize;
+ User::LeaveIfError(file.Size(fileSize));
+ HBufC8* buffer = HBufC8::NewLC(fileSize);
+ TPtr8 ptr(buffer->Des());
+ User::LeaveIfError(file.Read(0, ptr, fileSize));
+
+ // Read the controller
+ CDesDataProvider* desProvider = CDesDataProvider::NewLC(*buffer);
+ Sis::CController* controller = Sis::CController::NewLC(*desProvider, Sis::EAssumeType);
+ CMessageDigest* msgDigest = controller->GenerateControllerHashLC(*buffer);
+ TPtrC8 hash = msgDigest->Final();
+
+ TInt controllerCount = controllerInfo.Count();
+ for (TInt index = 0; index < controllerCount; index++)
+ {
+ if (controllerInfo[index]->HashContainer().Data() == hash)
+ {
+ found = ETrue;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(6, &controllerInfo); // file, buffer, desProvider, controller, msgDigest
+ return found;
+ }
+
+// Processes the removable looking for any installations for cleanup
+void CSisRegistrySession::ProcessRemovableDriveL(TInt aDrive)
+ {
+ TDriveUnit drive(aDrive);
+ // create directory path
+ RBuf regPath;
+ regPath.CreateL(drive.Name(), KMaxFileName);
+ CleanupClosePushL(regPath);
+ regPath.Append(KRegistryPath);
+
+ CDir* dir;
+ TInt err = iFs.GetDir(regPath, KEntryAttDir, ESortNone, dir);
+ CleanupStack::PushL(dir);
+ if(err == KErrNone)
+ {
+ TInt count(dir->Count());
+ for (TInt i = 0; i < count; ++i)
+ {
+ // want to be able to trap the failure, log it and process the next controller
+ // in this way a corrupt controler would not hog the processing
+ TRAPD(res, DiscoverControllersL(regPath, (*dir)[i].iName));
+ if (res != KErrNone)
+ {
+ // log that
+ DEBUG_PRINTF2(_L8("Sis Registry Server - DiscoverController failed with error %d."), res);
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2, ®Path); // dir
+ }
+
+void CSisRegistrySession::DiscoverControllersL(const TDesC& aRegistryPath, const TDesC& aDirectoryName)
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - Attempting to discover controllers we can clean up (Directory '%S')"),
+ &aDirectoryName);
+
+ // we expect uid directories to be 8 characters long, ignore others
+ if (aDirectoryName.Length() != KUidHexLength)
+ return;
+
+ // Determine the uid from the directory name
+ TLex lex(aDirectoryName);
+ TUint uidValue;
+ User::LeaveIfError(lex.Val(uidValue, EHex));
+
+ TUid uid = TUid::Uid(uidValue);
+ RBuf controllerPath;
+ controllerPath.CreateL(aRegistryPath, KMaxFileName);
+ CleanupClosePushL(controllerPath);
+ controllerPath.Append(aDirectoryName);
+ controllerPath.Append(KPathDelimiter);
+ controllerPath.Append(KControllerFileFilter);
+
+ CDir* dir;
+ // List the directory contents, excluding directories, system and hidden files.
+ // i.e. just normal files
+ TInt err = iFs.GetDir(controllerPath, KEntryAttMatchExclude | KEntryAttDir, ESortNone, dir);
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Flagging controller directory, read returned code %d."), err);
+
+ if (err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(&controllerPath);
+ return;
+ }
+
+ CleanupStack::PushL(dir);
+ TParsePtrC parse(controllerPath);
+ RBuf controllerName;
+ controllerName.CreateL(KMaxFileName);
+ CleanupClosePushL(controllerName);
+
+ TInt count(dir->Count());
+ for (TInt i = 0; i < count; ++i)
+ {
+ const TEntry& entry = (*dir)[i];
+
+ // Determine the augmentation index
+ TLex parser(entry.iName);
+ TUint augmentationIndex = 0;
+ if (parser.Val(augmentationIndex, EHex) != KErrNone)
+ {
+ continue;
+ }
+
+ controllerName = parse.DriveAndPath();
+ controllerName.Append(entry.iName);
+
+ // Controller present, see if is still installed on this device
+ TComponentId componentId = 0;
+ if (ScrHelperUtil::GetComponentIdL(iScrSession, uid, augmentationIndex, componentId) &&
+ IdentifyControllerL(componentId, controllerName))
+ {
+ // It's installed so skip over it
+ continue;
+ }
+ // Also make sure that it *was* installed on this phone.
+ // The presence of the uninstall log ensures this.
+ // It's not installed so use the uninstall log created during install to cleanup the installation
+ HBufC* ulogName = SisRegistryUtil::BuildUninstallLogFileNameLC(uid, augmentationIndex, aRegistryPath[0]);
+ TEntry entryUninstallLogFile;
+ TInt err = iFs.Entry(*ulogName, entryUninstallLogFile);
+ if (err == KErrNone)
+ {
+ DEBUG_PRINTF3(_L("Sis Registry Server - App no longer on device, cleaning up files for '%S' using log '%S'."),
+ &controllerName, ulogName);
+ ExecuteUninstallLogL(*ulogName, controllerName);
+ }
+ else
+ {
+ // Uninstall log is not present so don't cleanup
+ DEBUG_PRINTF(_L("Sis Registry Server - Skipping cleanup since app wasn't installed on this phone."));
+ }
+ CleanupStack::PopAndDestroy(ulogName);
+ }
+ CleanupStack::PopAndDestroy(3, &controllerPath); // dir, controllerName
+ }
+
+void CSisRegistrySession::ExecuteUninstallLogL(const TDesC& aUninstallLogFile, const TDesC& aControllerFile)
+ {
+ // Process uninstall log file for cleanup
+ TParsePtrC ctlFile(aControllerFile);
+ TChar driveChar = ctlFile.Drive()[0];
+ driveChar.Fold();
+
+ RPointerArray<HBufC> entryList;
+ CleanupResetAndDestroy<RPointerArray<HBufC> >::PushL(entryList);
+
+ RFileReadStream ulogStream;
+ CleanupClosePushL(ulogStream);
+
+ TEntry entry;
+ if ((iFs.Entry(aUninstallLogFile, entry) == KErrNone) &&
+ (ulogStream.Open(iFs, aUninstallLogFile, EFileShareAny | EFileStream) == KErrNone))
+ {
+ // Process the log and collect the files and private path entries
+ for (;;)
+ {
+ HBufC* logEntry = NULL;
+ TRAPD(err, logEntry = HBufC::NewL(ulogStream, KMaxFileName));
+ if (err == KErrEof)
+ {
+ break;
+ }
+ User::LeaveIfError(err);
+ CleanupStack::PushL(logEntry);
+ if (logEntry->Length() == 0)
+ {
+ CleanupStack::PopAndDestroy(logEntry);
+ break;
+ }
+ // Make sure the entry's location is on the same drive as the removable media
+ // Also ignore any wildcard specification (this should never be legally present in the log)
+ TParsePtrC parseEntry(*logEntry);
+ TChar logEntryDrive = parseEntry.Drive()[0];
+ logEntryDrive.Fold();
+ if ((logEntryDrive != driveChar) || (parseEntry.IsWild()))
+ {
+ // Ignore this entry
+ CleanupStack::PopAndDestroy(logEntry);
+ continue;
+ }
+ entryList.AppendL(logEntry); // Ownership transferred to array
+ CleanupStack::Pop(logEntry);
+ }
+ }
+
+ // Close the log file early since we need to delete it now
+ CleanupStack::PopAndDestroy(&ulogStream);
+
+ // Add the log file to the entry list for cleanup.
+ // Controller file would already be part of cleanup log
+ // Removing log file and ctl file at the end of cleanup is better since if the
+ // removable drive is ejected while we are cleaning up, we can try the cleanup next
+ // time the card is inserted again
+ HBufC* tempEntry = aUninstallLogFile.AllocLC();
+ entryList.AppendL(tempEntry); // takes ownership
+ CleanupStack::Pop(tempEntry);
+
+ // Delete all collected entries
+ TInt entryCount = entryList.Count();
+ for (TInt index = 0; index < entryCount; ++index)
+ {
+ HBufC* entry = entryList[index];
+ TParsePtrC parseEntry(*entry);
+ DEBUG_PRINTF2(_L("Sis Registry Server - Deleting file and path '%S'"), entry);
+ // Check if it's a file
+ if (!parseEntry.NamePresent())
+ {
+ MiscUtil::DeletePathIfEmpty(iFs, *entry);
+ continue;
+ }
+ TInt err = iFs.Delete(*entry);
+ if (err == KErrAccessDenied)
+ {
+ // File may be read-only. Clear the attribute and try again
+ iFs.SetAtt(*entry, 0, KEntryAttReadOnly);
+ iFs.Delete(*entry);
+ }
+ MiscUtil::DeletePathIfEmpty(iFs, *entry);
+ }
+
+ CleanupStack::PopAndDestroy(&entryList);
+ }
+
+void CSisRegistrySession::GetCompIdAndCompSidIndexL(const TUid& aSid, TComponentId& aComponentId, TInt& aIndex, TInt aExpectedDrive)
+ {
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+ componentFilter->AddPropertyL(KCompSidsPresent, 1);
+
+ // Retrieve the componentId of all the components with SIDs from the SCR.
+ RArray<TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+ iScrSession.GetComponentIdsL(componentIdList, componentFilter);
+
+ TInt componentCount = componentIdList.Count();
+ RArray<TUid> sidArray;
+ CleanupClosePushL(sidArray);
+ TBool sidMatchFound = EFalse;
+
+ for(TInt i = 0; i < componentCount && !sidMatchFound; ++i)
+ {
+ TComponentId componentId = componentIdList[i];
+ sidArray.Reset();
+ ScrHelperUtil::InternalizeSidArrayL(iScrSession, componentId, sidArray);
+
+ // index of the first matching SID in the array.
+ aIndex = sidArray.Find(aSid);
+ if(aIndex == KErrNotFound)
+ continue;
+
+ // If the search is narrowed to a particular drive, get the file name and check whether it matches the drive
+ if (aExpectedDrive != -1)
+ {
+ TBuf<KSmlBufferSize> compSidFileName(KEmptyString);
+ compSidFileName.Format(KCompSidFileNameFormat, aIndex);
+
+ HBufC* fileName = GetStrPropertyValueL(iScrSession, componentId, compSidFileName);
+ CleanupStack::PushL(fileName);
+ if (fileName->Length() == 0)
+ {
+ CleanupStack::PopAndDestroy(fileName);
+ continue;
+ }
+ TInt drive;
+ User::LeaveIfError(RFs::CharToDrive((*fileName)[0], drive));
+ if(drive != aExpectedDrive)
+ {
+ CleanupStack::PopAndDestroy(fileName);
+ continue;
+ }
+ CleanupStack::PopAndDestroy(fileName);
+ }
+
+ aComponentId = componentId;
+ sidMatchFound = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy(3, componentFilter); // componentIdList and sidArray.
+ if(!sidMatchFound)
+ {
+ // No component contains aSid.
+ aComponentId = KErrNotFound;
+ }
+ }
+
+TBool CSisRegistrySession::ModifiableL(const TDesC& aFileName)
+ {
+ // Retrieve the list of components which contain aFileName.
+ RArray<TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+ iScrSession.GetComponentsL(aFileName, componentIdList);
+
+ // No component in Software Component Registry contain aFileName.
+ if(componentIdList.Count() == 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // having obtained the list of components containing aFilename in componentIdList , use any
+ // one of the component from the list to find out whether aFileName is modifiable or not.
+
+ const TComponentId componentId = componentIdList[0];
+ CleanupStack::PopAndDestroy(&componentIdList);
+
+
+ Sis::TSISFileOperationOptions operationOptions = static_cast<Sis::TSISFileOperationOptions>(0);
+ Usif::CPropertyEntry* propertyEntry = NULL;
+ propertyEntry = iScrSession.GetFilePropertyL(componentId, aFileName, KFileFileOperationOptions);
+
+ if (propertyEntry)
+ {
+ operationOptions = static_cast<Sis::TSISFileOperationOptions>(static_cast<Usif::CIntPropertyEntry*>(propertyEntry)->IntValue());
+ }
+
+ // find out if the file is modifiable, and return an appropriate
+ // Boolean value. If the expression below is True, then the file is modifiable.
+ TBool isModifiable = (operationOptions & Sis::EInstVerifyOnRestore) ? EFalse : ETrue;
+
+ // Files under \sys or \resource are never modifiable
+ _LIT(KSys, "\\sys\\");
+ _LIT(KResource, "\\resource\\");
+ if (aFileName.FindF(KSys) == 2 || aFileName.FindF(KResource) == 2)
+ {
+ isModifiable = EFalse;
+ }
+
+ return isModifiable;
+ }
+
+CHashContainer* CSisRegistrySession::HashL(const TDesC& aFileName)
+ {
+ // Retrieve the list of components which contain aFileName.
+ RArray<TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+ iScrSession.GetComponentsL(aFileName, componentIdList);
+
+ // No component in Software Component Registry contain aFileName.
+ if(componentIdList.Count() == 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // having obtained the list of components containing aFilename in componentIdList , use any
+ // one of the component from the list to retrieve the hash of aFileName.
+ TInt index = 0;
+ const TComponentId componentId = componentIdList[index];
+ CleanupStack::PopAndDestroy(&componentIdList);
+
+ CHashContainer* hashContainer = NULL;
+ ScrHelperUtil::ReadFromScrL(iScrSession, componentId, hashContainer, aFileName);
+ return hashContainer; // ownership is transferred to the caller(ie, Swi::CSisRegistrySession::RequestHashL())
+ }
+
+void CSisRegistrySession::RemovablePackageListL(RPointerArray<CSisRegistryPackage>& aPackages)
+ {
+ aPackages.ResetAndDestroy();
+
+ // Filter the components from SCR whose Removable flag is set.
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+ componentFilter->SetRemovable(ETrue);
+
+ RSoftwareComponentRegistryView subSession;
+ CleanupClosePushL(subSession);
+ subSession.OpenViewL(iScrSession, componentFilter);
+
+ // Create CSisRegistryPackage object for all the removable components and append them in aPackages array..
+ CComponentEntry* componentEntry = NULL;
+ while((componentEntry = subSession.NextComponentL()) != NULL)
+ {
+ CleanupStack::PushL(componentEntry);
+ TComponentId componentId = componentEntry->ComponentId();
+
+ CSisRegistryPackage *package = NULL;
+ ScrHelperUtil::ReadFromScrL(iScrSession, componentId, package);
+ CleanupStack::PushL(package);
+ aPackages.AppendL(package);
+ CleanupStack::Pop(package);
+ CleanupStack::PopAndDestroy(componentEntry);
+
+ }
+
+ CleanupStack::PopAndDestroy(2, componentFilter); //componentFilter and subSession.
+ }
+
+void CSisRegistrySession::ProcessRomDriveL()
+ {
+ DEBUG_PRINTF(_L8("Sis Registry Server - Registering In-Rom controllers."));
+
+ TDriveUnit romDrive(SisRegistryUtil::SystemRomDrive());
+ RBuf romRegistryPath;
+ romRegistryPath.CreateL(romDrive.Name(), KMaxPath);
+ CleanupClosePushL(romRegistryPath);
+ romRegistryPath.Append(KPreInstalledPath);
+ // open the directory
+ CDir* dir;
+ TInt err = iFs.GetDir(romRegistryPath, KEntryAttMatchExclude | KEntryAttDir, ESortNone, dir);
+ // check that all is correct but make sure to handle missing directory
+
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Reading ROM stub directory returned %d."), err);
+
+ if (err == KErrNone)
+ {
+ CleanupStack::PushL(dir);
+
+ TInt count(dir->Count());
+ RBuf controllerFileName;
+ controllerFileName.CreateL(KMaxFileName);
+ CleanupClosePushL(controllerFileName);
+ for (TInt index = 0; index < count; ++index)
+ {
+ controllerFileName = romRegistryPath;
+ controllerFileName.Append((*dir)[index].iName);
+ TRAPD(res, RegisterInRomControllerL(controllerFileName));
+ if (res != KErrNone)
+ {
+ // log it only, we cannot stop as the next might be ok
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Failed to register in ROM controller. Error code %d."), res);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2, dir); // controllerFileName
+ }
+ else if(err != KErrPathNotFound)
+ {
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(&romRegistryPath);
+ }
+
+void CSisRegistrySession::RegisterInRomControllerL(const TDesC& aFileName)
+ {
+ DEBUG_PRINTF2(_L("Sis Registry Server - Registering In-ROM controller file '%S'."), &aFileName);
+
+ RFile romController;
+ CleanupClosePushL(romController);
+ // open file and read the data
+ User::LeaveIfError(romController.Open(iFs, aFileName, EFileRead | EFileShareReadersOnly));
+ // read the data from the file
+ TInt fileSize;
+ romController.Size(fileSize);
+ HBufC8* controllerData = HBufC8::NewLC(fileSize);
+ TPtr8 ptr(controllerData->Des());
+ romController.Read(0, ptr, fileSize);
+
+ CDesDataProvider* desProvider = CDesDataProvider::NewLC(*controllerData);
+ // read the controller
+ Swi::Sis::CController* controller = Swi::Sis::CController::NewLC(*desProvider);
+
+ // create an object from the controller
+ CSisRegistryObject* object = CSisRegistryObject::NewLC();
+
+ // Discard the 4 byte type field for consistency with
+ // all other registry entries
+ TPtrC8 assumedTypeController(controllerData->Mid(4));
+ // we cannot guess whether it is registered without opening it
+ object->ProcessInRomControllerL(*controller, assumedTypeController);
+
+
+ TBool overwriteRegEntry = EFalse;
+
+ TBool isStubRegistered = IsRegisteredL(object->Uid(), object->Name());
+ if ( isFwUpdated && isStubRegistered )
+ {
+ TComponentId compId = ScrHelperUtil::GetComponentIdL(iScrSession, object->Uid(), object->Index());
+ TSisPackageTrust trustStatus;
+ trustStatus = static_cast<TSisPackageTrust>(GetIntPropertyValueL(iScrSession, compId, KCompTrust, EFalse, KDefaultTrustValue));
+ //ScrHelperUtil::ReadFromScrL(iSession.ScrSession(), iComponentId, trustStatus);
+ if ( ESisPackageBuiltIntoRom == trustStatus )
+ {
+ DEBUG_PRINTF2(_L8("Sis Registry Server - Attempting to delete registry entry 0x%08x as a firmware update detected"), object->Uid().iUid);
+
+ // If the component being removed has registered software types, unregister them now.
+ // This operation deletes MIME types mapping from AppArc and therefore is not transactional.
+ UnregisterSoftwareTypesL(compId);
+
+ CSisRegistryObject* object = CSisRegistryObject::NewLC();
+ ScrHelperUtil::GetComponentL(iScrSession, compId, *object);
+
+ DEBUG_PRINTF4(_L("Sis Registry Server - Removing package registry entry for UID: %08x, Name: %S, Vendor %S."),
+ object->Uid().iUid, &(object->Name()), &(object->Vendor()));
+
+ RemoveEntryL(*object);
+
+ CleanupStack::PopAndDestroy();
+ overwriteRegEntry = ETrue;
+ }
+ }
+
+
+ if ( !isStubRegistered || overwriteRegEntry )
+ {
+ // update cache or just call refresh
+ AddEntryL(*object, Usif::EScrCompHidden); // EScrCompHidden is supplied not to create any log for the ROM controller on the SCR side.
+
+ // store a copy of the controller
+ HBufC* name = SisRegistryUtil::BuildControllerFileNameLC(object->Uid(), object->Index(),
+ 0);
+
+ SisRegistryUtil::EnsureDirExistsL(iFs, *name);
+ RFile newController;
+
+ // If stray .ctl files exist (for example, after phone was rebooted in the middle of registration), calling RFile::Create() will result a Leave.
+ // Therefore, RFile::Replace() is rather ideal.
+ User::LeaveIfError(newController.Replace(iFs, *name, EFileWrite | EFileShareExclusive));
+ CleanupStack::PopAndDestroy(name);
+ CleanupClosePushL(newController);
+
+ // Write the controller, minus the 4 byte type field for consistency with
+ // all other registry entries
+ newController.Write(assumedTypeController);
+ CleanupStack::PopAndDestroy(&newController);
+ }
+
+ CleanupStack::PopAndDestroy(5, &romController); //controller, object, desProvider, controllerData
+ }
+
+TInt CSisRegistrySession::GetAugmentationCountL(const TUid& aUid)
+ {
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->AddPropertyL(KCompUid, aUid.iUid);
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+
+ RArray<Usif::TComponentId> componentIdList;
+ CleanupClosePushL(componentIdList);
+ iScrSession.GetComponentIdsL(componentIdList, componentFilter);
+
+ TInt componentsCount = componentIdList.Count();
+ TInt result = componentsCount ? componentsCount - 1 : 0;
+ CleanupStack::PopAndDestroy(2, componentFilter); // componentIdList
+ return result;
+ }
+
+void CSisRegistrySession::GetAugmentationDetailsL(const TUid& aUid, RPointerArray<CSisRegistryPackage>& aPackagesArray, TComponentId aBaseComponentId)
+ {
+ TInt componentId = 0;
+ TInt componentIndex = 0;
+ CSisRegistryPackage* augmentedPackage = NULL;
+ // Create the component filter with Component Uid.
+ CComponentFilter* componentFilter = CComponentFilter::NewLC();
+ componentFilter->AddPropertyL(KCompUid, aUid.iUid);
+ componentFilter->SetSoftwareTypeL(KSoftwareTypeNative);
+ RSoftwareComponentRegistryView subSession;
+ CleanupClosePushL(subSession);
+ // Populate the view with components matching the filter specification ( Comp' Uid ).
+ subSession.OpenViewL(iScrSession, componentFilter);
+
+ // Iterate through all the components with this Uid
+ CComponentEntry* componentEntry = NULL;
+ while((componentEntry = subSession.NextComponentL()) != NULL)
+ {
+ CleanupStack::PushL(componentEntry);
+ componentId = componentEntry->ComponentId();
+ if (aBaseComponentId == componentId)
+ {
+ CleanupStack::PopAndDestroy(componentEntry);
+ continue; // An optimisation - skip the base component
+ }
+ componentIndex = GetIntPropertyValueL(iScrSession, componentId, KCompIndex, EFalse, KDefaultComponentIndex);
+ // Check if the package is not base package (SA). If so, add it to the list of augmentated packages.
+ if (componentIndex != CSisRegistryPackage::PrimaryIndex)
+ {
+ // Get the unique vendor name that is stored as a property
+ HBufC* uniqueVendor = GetStrPropertyValueL(iScrSession, componentId, KCompUniqueVendorName);
+ CleanupStack::PushL(uniqueVendor);
+ augmentedPackage = CSisRegistryPackage::NewLC(aUid, componentEntry->Name(), *uniqueVendor);
+ augmentedPackage->SetIndex(componentIndex);
+ aPackagesArray.AppendL(augmentedPackage);
+ CleanupStack::Pop(augmentedPackage);
+ CleanupStack::PopAndDestroy(uniqueVendor);
+ }
+
+ CleanupStack::PopAndDestroy(componentEntry);
+ }
+
+ CleanupStack::PopAndDestroy(2, componentFilter); // componentFilter, subSession
+ }
+
+
+_LIT( KSWVersionFileName, "Z:\\resource\\versions\\sw.txt" );
+const TInt KSysUtilVersionTextLength = 64;
+_LIT( KNewLinePattern, "\\n" );
+_LIT( KNewline, "\n" );
+/**
+Fetch text from specified files.
+Copied from /common/generic/syslibs/bafl/sysutil/src/sysutil.cpp
+*/
+static TInt GetTextFromFile(
+ const TDesC& aFilename,
+ TDes& aValue,
+ TBool aRemoveNewLines )
+ {
+ RFs fs;
+ TInt err;
+ err = fs.Connect();
+ if (err != KErrNone)
+ return err;
+
+ RFile file;
+ err = file.Open( fs, aFilename,
+ EFileRead | EFileStreamText | EFileShareReadersOnly );
+ if (err != KErrNone)
+ {
+ fs.Close();
+ return err;
+ }
+
+ TBuf8<2> characters;
+ err = file.Read(characters);
+
+ if (err == KErrNone || err == KErrTooBig)
+ {
+ // This means that we have an ANSI file (without the header bytes)
+ if( characters.Length() == 0 || characters.Length() == 1 )
+ {
+ file.Close();
+ fs.Close();
+ return KErrCorrupt;
+ }
+ else
+ {
+ TUint8 firstByte = characters[0];
+ TUint8 secondByte = characters[1];
+
+ // Heading byte values for unicode files
+ const TInt KFFByte = 255;
+ const TInt KFEByte = 254;
+
+ // If file isn't unicode KErrCorrupt is returned
+ if( (firstByte!=KFFByte && secondByte!=KFEByte) && (secondByte!=KFFByte && firstByte!=KFEByte) )
+ {
+ file.Close();
+ fs.Close();
+ return KErrCorrupt;
+ }
+ }
+ }
+
+ TFileText tf;
+ tf.Set(file);
+ err = tf.Read(aValue);
+ // If the maximum length of the descriptor is insufficient to hold the record,
+ // the Read() function returns KErrTooBig and the descriptor is filled to its maximum length.
+ //
+ // If Read() is called when the current position is the end of the file (that is, after
+ // the last line delimiter in the file), KErrEof is returned, and the length of the buffer
+ // is set to zero. In this case, this would mean an empty file, as this code always reads
+ // from the beginning of the file.
+
+ if (err == KErrNone || err == KErrTooBig)
+ {
+ if (aValue.Length() > KSysUtilVersionTextLength)
+ {
+ // File content is larger than 64 characters. Truncate to 64 characters.
+ aValue.Delete(KSysUtilVersionTextLength,aValue.Length() - KSysUtilVersionTextLength);
+ err = KErrTooBig;
+ }
+
+ if (aRemoveNewLines)
+ {
+ // Replace new-line patterns with real ones
+ TInt error = aValue.Find(KNewLinePattern);
+ while (error != KErrNotFound)
+ {
+ // error is a position
+ aValue.Replace(error, KNewLinePattern().Length(), KNewline );
+ error = aValue.Find(KNewLinePattern);
+ }
+ }
+ }
+
+ file.Close();
+ fs.Close();
+
+ return err;
+ }
+// GetSWVersion. Read sw.txt and return concatenated to single line
+// Copied from /common/generic/syslibs/bafl/sysutil/src/sysutil.cpp but without caching functionality
+static TInt GetSWVersion(TDes& aValue)
+ {
+ TInt err = GetTextFromFile( KSWVersionFileName, aValue, ETrue );
+
+
+ if ( err != KErrNone )
+ {
+ DEBUG_PRINTF3(_L8("Error: %d, while processing: %S"),err, &KSWVersionFileName);
+ }
+
+ return err;
+ }
+
+const TInt KInfoBufLength=KSysUtilVersionTextLength;
+_LIT(KROMVersionStringCacheDir, ":\\sys\\install\\sisregistry\\");
+_LIT(KROMVersionStringCacheFileName, "ROMVersionStringCache_localSysUtil.bin");
+
+
+TBool CSisRegistrySession::IsFirmwareUpdatedL()
+ {
+ TChar sysDrive = RFs::GetSystemDriveChar();
+ TInt maxSizeofFileName = KROMVersionStringCacheDir().Length() + KROMVersionStringCacheFileName().Length() + 1;
+ RBuf romVersionCacheFileName;
+ romVersionCacheFileName.CreateL(maxSizeofFileName);
+ romVersionCacheFileName.CleanupClosePushL();
+ romVersionCacheFileName.Append(sysDrive);
+ romVersionCacheFileName.Append(KROMVersionStringCacheDir());
+ romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
+
+ //Read the length & value from it, if any.
+ RFileReadStream romVerStream;
+ TInt err = romVerStream.Open(iFs,romVersionCacheFileName,EFileRead);
+ if ( err != KErrNone )
+ {
+ CleanupStack::PopAndDestroy(1);
+ return ETrue;
+ }
+ CleanupClosePushL(romVerStream);
+ TBuf<KInfoBufLength> version;
+ TUint32 length = romVerStream.ReadUint32L();
+ if (length>KInfoBufLength)
+ {
+ //File must be corrupt, an attempt to read will panic
+ //User::Leave(KErrCorrupt);
+ CleanupStack::PopAndDestroy(2);
+ return ETrue;
+ }
+ romVerStream.ReadL(version, length);
+
+ //the persisted version has been successfully read
+ //read the actual current version string
+ TBuf<KInfoBufLength> actualVersion;
+
+ err = GetSWVersion(actualVersion); //use the local implementation of the SysUtil::GetSWVersion function
+
+ if(err == KErrNone)
+ {
+ if (version.Compare(actualVersion) != 0)
+ {
+ //Leave if the current version is different from the previous stored version and recreate applist.
+ DEBUG_PRINTF(_L8("!!Firmware update detected!! Rebuilding AppList"));
+ CleanupStack::PopAndDestroy(2);
+ return ETrue;
+ }
+ }
+ else
+ {
+ //Leave if any error reading the version information, except if file is not present
+ if (err != KErrPathNotFound && err != KErrNotFound)
+ {
+ DEBUG_PRINTF2(_L8("!!Error %d reading Firmware version. Rebuilding AppList"),err);
+ CleanupStack::PopAndDestroy(2);
+ return ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
+ return EFalse;
+ }
+
+void CSisRegistrySession::UpdateRecentFWVersionL()
+ {
+ //Write a cache of the ROM version to a separate stream
+ //Build the filename for the cache file
+ TChar sysDrive = RFs::GetSystemDriveChar();
+ TInt maxSizeofFileName = KROMVersionStringCacheDir().Length() + KROMVersionStringCacheFileName().Length() + 1;
+ RBuf romVersionCacheFileName;
+ romVersionCacheFileName.CreateL(maxSizeofFileName);
+ romVersionCacheFileName.CleanupClosePushL();
+ romVersionCacheFileName.Append(sysDrive);
+ romVersionCacheFileName.Append(KROMVersionStringCacheDir());
+ romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
+
+ //Read the length & value from it, if any.
+ RFileWriteStream romVerStream;
+ User::LeaveIfError(romVerStream.Replace(iFs,romVersionCacheFileName,EFileWrite));
+ CleanupClosePushL(romVerStream);
+ TBuf<KInfoBufLength> version;
+ GetSWVersion(version);
+
+ // Write even if SysUtil returns err since all conditions are taken care during restore.
+ romVerStream.WriteUint32L(version.Length());
+ romVerStream.WriteL(version);
+ CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
+ }
+