--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/swis/server/installationprocessor.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1346 @@
+/*
+* Copyright (c) 1997-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:
+* Application Processor.
+*
+*/
+
+
+/**
+ @file
+ @released
+ @internalTechnology
+*/
+
+#include <hash.h>
+#include "installationprocessor.h"
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <usif/sts/sts.h>
+#include "swtypereginfo.h"
+#include "installswtypehelper.h"
+#else
+#include "integrityservices.h"
+#endif
+
+#include "sisregistryentry.h"
+#include "sishelperclient.h"
+#include "sisregistryfiledescription.h"
+#include "sisregistrypackage.h"
+#include "sisstring.h"
+#include "hashcontainer.h"
+#include "siscontroller.h"
+#include "application.h"
+#include "userselections.h"
+#include "log.h"
+#include "secutils.h"
+#include "sisuihandler.h"
+#include "filesisdataprovider.h"
+#include "securitymanager.h"
+#include "securitypolicy.h"
+#include "sislauncherclient.h"
+#include "sisinfo.h"
+#include "sisuid.h"
+#include "plan.h"
+#include "sidcache.h"
+#include "sistruststatus.h"
+#include "securitycheckutil.h"
+#include "sisfieldtypes.h"
+#include "progressbar.h"
+#include "fileextractor.h"
+#include "securitycheckutil.h"
+
+using namespace Swi;
+
+
+_LIT(KApparcRegDir, "\\private\\10003a3f\\import\\apps\\");
+_LIT(KSisExt, ".sis");
+
+
+const TInt KSwiDaemonUid = 0x10202DCE;
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager,
+ RSisHelper& aSisHelper, RUiHandler& aUiHandler,
+ Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
+ const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ {
+ CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan,
+ aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper,
+ aControllerData, aObserver);
+ CleanupStack::Pop(self);
+ return self;
+ }
+#else
+CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager,
+ RSisHelper& aSisHelper, RUiHandler& aUiHandler,
+ CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ {
+ CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan,
+ aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
+ CleanupStack::Pop(self);
+ return self;
+ }
+#endif
+
+CInstallationProcessor* CInstallationProcessor::NewL(CInstallationProcessor& aProcessor)
+ {
+ CInstallationProcessor* self = CInstallationProcessor::NewLC(aProcessor.Plan(),
+ aProcessor.iSecurityManager, aProcessor.iSisHelper, aProcessor.UiHandler(),
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ aProcessor.TransactionSession(), aProcessor.iRegistryWrapper,
+#else
+ aProcessor.IntegrityServices(),
+#endif
+ aProcessor.iControllerData, aProcessor.Observer());
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor* CInstallationProcessor::NewLC(
+ const CPlan& aPlan, CSecurityManager &aSecurityManager,
+ RSisHelper& aSisHelper, RUiHandler& aUiHandler,
+ Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
+ const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ {
+ CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan,
+ aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper,
+ aControllerData, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+#else
+CInstallationProcessor* CInstallationProcessor::NewLC(
+ const CPlan& aPlan, CSecurityManager &aSecurityManager,
+ RSisHelper& aSisHelper, RUiHandler& aUiHandler,
+ CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ {
+ CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan,
+ aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+#endif
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan,
+ CSecurityManager &aSecurityManager, RSisHelper& aSisHelper,
+ RUiHandler& aUiHandler, Usif::RStsSession& aStsSession,
+ CRegistryWrapper& aRegistryWrapper,
+ const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ : CProcessor(aPlan, aUiHandler, aStsSession, aRegistryWrapper, aObserver),
+ iSecurityManager(aSecurityManager),
+ iSisHelper(aSisHelper),
+ iControllerData(aControllerData)
+ {
+ }
+#else
+CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan,
+ CSecurityManager &aSecurityManager, RSisHelper& aSisHelper,
+ RUiHandler& aUiHandler, CIntegrityServices& aIntegrityServices,
+ const TDesC8& aControllerData, RSwiObserverSession& aObserver)
+ : CProcessor(aPlan, aUiHandler, aIntegrityServices, aObserver),
+ iSecurityManager(aSecurityManager),
+ iSisHelper(aSisHelper),
+ iControllerData(aControllerData)
+ {
+ }
+#endif
+
+CInstallationProcessor::~CInstallationProcessor()
+ {
+ Cancel();
+
+ delete iEmbeddedProcessor;
+ delete iFileExtractor;
+
+ iFilesToCopy.ResetAndDestroy();
+ iApparcRegFiles.ResetAndDestroy();
+
+ iLoader.Close();
+ iSkipFile.Close();
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ iSoftwareTypeRegInfoArray.Close();
+#endif
+ }
+
+void CInstallationProcessor::ConstructL()
+ {
+ User::LeaveIfError(iLoader.Connect());
+
+ CProcessor::ConstructL();
+
+ iFileExtractor=CFileExtractor::NewL(Fs(), iSisHelper, UiHandler(), Plan().AppInfoL());
+ }
+
+void CInstallationProcessor::DoCancel()
+ {
+ CProcessor::DoCancel();
+ if (iEmbeddedProcessor && iEmbeddedProcessor->IsActive())
+ {
+ iEmbeddedProcessor->Cancel();
+ }
+
+ if (iFileExtractor->IsActive())
+ {
+ iFileExtractor->Cancel();
+ }
+ }
+
+void CInstallationProcessor::DisplayFileL(const CSisRegistryFileDescription& aFileDescription, Sis::TSISFileOperationOptions aFileOperationOption)
+ {
+ // Default to continue
+ TFileTextOption fileTextOption(EInstFileTextOptionContinue);
+ bool forceAbortFlag = EFalse;
+ if (aFileOperationOption & Sis::EInstFileTextOptionSkipIfNo)
+ {
+ fileTextOption=EInstFileTextOptionSkipOneIfNo;
+ }
+ else if (aFileOperationOption & Sis::EInstFileTextOptionAbortIfNo)
+ {
+ fileTextOption=EInstFileTextOptionAbortIfNo;
+ }
+ else if (aFileOperationOption & Sis::EInstFileTextOptionExitIfNo)
+ {
+ fileTextOption=EInstFileTextOptionExitIfNo;
+ }
+ else if (aFileOperationOption & Sis::EInstFileTextOptionForceAbort)
+ {
+ //converts FA option to TC option.
+ fileTextOption=EInstFileTextOptionContinue;
+ forceAbortFlag = ETrue;
+ }
+
+ TFileName temporaryFileName;
+
+ TemporaryFileNameLC(aFileDescription, temporaryFileName);
+
+ EnsureTemporaryInstallDirExistsL(temporaryFileName);
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RegisterTemporaryL(temporaryFileName);
+#else
+ IntegrityServices().TemporaryL(temporaryFileName);
+#endif
+
+ // Extract this file to its temporary location.
+ // However this file may have already been extracted, due to displaying it as
+ // text, so we don't need to extract it again under this circumstance
+ RFile temporaryFile;
+ TInt err = temporaryFile.Create(Fs(), temporaryFileName, EFileWrite);
+ if (err==KErrNone)
+ {
+ // We are passing the file handle to SISHelper but still need to close
+ // it here.
+ CleanupClosePushL(temporaryFile);
+ User::LeaveIfError(iSisHelper.ExtractFileL(Fs(), temporaryFile,
+ aFileDescription.Index(), ApplicationL().AbsoluteDataIndex(), UiHandler()));
+ CleanupStack::PopAndDestroy(&temporaryFile);
+ }
+ else if (err != KErrAlreadyExists)
+ {
+ User::Leave(err);
+ }
+
+ User::LeaveIfError(temporaryFile.Open(Fs(), temporaryFileName, EFileRead));
+ CleanupClosePushL(temporaryFile);
+
+ TInt fileSize=0;
+ User::LeaveIfError(temporaryFile.Size( fileSize));
+ HBufC8* text=HBufC8::NewMaxLC(fileSize);
+ TPtr8 textPtr(text->Des());
+
+ User::LeaveIfError(temporaryFile.Read(textPtr));
+
+ CDisplayText* displayText = NULL;
+
+ displayText = CDisplayText::NewLC(Plan().AppInfoL(), fileTextOption, textPtr);
+ UiHandler().ExecuteL(*displayText);
+
+ switch (fileTextOption)
+ {
+ case EInstFileTextOptionContinue:
+ //for FA option ,raise a TC dialog and abort the installation.
+ if(forceAbortFlag)
+ {
+ User::Leave(KErrCancel);
+ }
+ break;
+
+ case EInstFileTextOptionSkipOneIfNo:
+ {
+ iSkipFile.AppendL(displayText->ReturnResult());
+ }
+ break;
+
+ case EInstFileTextOptionAbortIfNo:
+ case EInstFileTextOptionExitIfNo:
+ if (!displayText->ReturnResult())
+ {
+ User::Leave(KErrCancel);
+ }
+ break;
+ }
+
+ CleanupStack::PopAndDestroy(3, &temporaryFile);
+ }
+
+TBool CInstallationProcessor::ExtractFileL(CSisRegistryFileDescription& aFileToExtract)
+ {
+ DEBUG_PRINTF2(_L("Install Server - Installation Processor Extracting File '%S'"),
+ &aFileToExtract.Target());
+
+ if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch()
+ || aFileToExtract.Operation() == Sis::EOpNull)
+ {
+ // This file will not really be copied, but still need to update the progress bar.
+ // Increment for extract stage (scaled by file size)
+ TInt ammount = ProgressBarFileIncrement(aFileToExtract.UncompressedLength());
+ // Increment for install/copy stage
+ ammount += KProgressBarEndIncrement;
+ UiHandler().UpdateProgressBarL(Plan().AppInfoL(), ammount);
+ // move onto next file
+ return EFalse;
+ }
+
+ TFileName temporaryFileName;
+
+ TemporaryFileNameLC(aFileToExtract, temporaryFileName);
+
+ // Add to the list of files to copy
+ CFileCopyDescription* fileCopyDescription=CFileCopyDescription::NewLC(
+ temporaryFileName, aFileToExtract);
+ User::LeaveIfError(iFilesToCopy.Append(fileCopyDescription));
+ CleanupStack::Pop(fileCopyDescription); // Ownership is transferred
+
+ EnsureTemporaryInstallDirExistsL(temporaryFileName);
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RegisterTemporaryL(temporaryFileName);
+#else
+ IntegrityServices().TemporaryL(temporaryFileName);
+#endif
+
+ iFileExtractor->ExtractFileL(ApplicationL().AbsoluteDataIndex(), aFileToExtract, temporaryFileName, iStatus);
+ return ETrue;
+ }
+
+
+void CInstallationProcessor::DoExtractHashL(const CSisRegistryFileDescription& aFileToProcess)
+ {
+ TParsePtrC targetPath(aFileToProcess.Target());
+ // If the target is in sys\bin, write its hash into \sys\hash and name
+ // it after the file. The check in the process file state will ensure
+ // that it must be a valid exe or dll to get this far.
+ if (targetPath.Path().CompareF(KBinPath) == 0)
+ {
+ ExtractHashL(aFileToProcess.Target(), aFileToProcess.Hash());
+ }
+ }
+
+void CInstallationProcessor::CheckHashL(const CSisRegistryFileDescription& aFileToProcess, const TDesC& aCurrentFileName)
+ {
+ const CHashContainer& hash = aFileToProcess.Hash();
+
+ // Calculate and check correct hash value
+ CFileSisDataProvider* fileDataProvider=CFileSisDataProvider::NewLC(Fs(), aCurrentFileName);
+ TBool hashIsValid=iSecurityManager.VerifyFileHashL(*fileDataProvider,hash);
+ CleanupStack::PopAndDestroy(fileDataProvider);
+ if (!hashIsValid)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+
+
+
+void CInstallationProcessor::EnsureTemporaryInstallDirExistsL(const TDesC& aFileTarget)
+ {
+ TInt err = Fs().MkDirAll(aFileTarget);
+ if (err!= KErrNone && err != KErrAlreadyExists)
+ {
+ User::LeaveIfError(err);
+ }
+ }
+
+void CInstallationProcessor::TemporaryFileNameLC(const CSisRegistryFileDescription& aFileToExtract, TDes& aTemporaryFileName)
+ {
+ static TInt localTempCnt = 0;
+ TChar drive;
+ if(aFileToExtract.Target().Length())
+ {
+ // set temporary drive to be same as final target
+ drive = aFileToExtract.Target()[0];
+ }
+ else
+ {
+ // set temporary drive to the user selected drive
+ drive = ApplicationL().UserSelections().Drive();
+ }
+
+ // If no drive has been selected then use the C drive for
+ // temporary files. This should only happen if the SIS file
+ // just contains text files to display but not install.
+ if (drive == TChar(KNoDriveSelected))
+ {
+ drive = iSystemDriveChar;
+ }
+
+ // construct the temporary filename
+ // Format is {Drive}:\sys\install\temp\file-{Data Unit}-{File Index}-{LocalCounter}
+ _LIT(KTemporaryFileFormat, "%c:%Sfile-%d-%d-%d");
+ TUint driveCh(drive); // Can't pass TChar to Format.
+
+ aTemporaryFileName.Format(KTemporaryFileFormat, driveCh, &KSysInstallTempPath,
+ ApplicationL().AbsoluteDataIndex(), aFileToExtract.Index(),
+ localTempCnt++);
+ }
+
+///\short Extracts executable hash from controller to file for the loader
+void CInstallationProcessor::ExtractHashL(const TFileName& aFileName,
+ const CHashContainer& aHash)
+ {
+ const TDesC8& hashData = aHash.Data();
+
+ TBuf<32> hashPath;
+ TUint driveCh(iSystemDriveChar); // can't pass TChar to Format
+ hashPath.Format(KHashPathFormat, driveCh, &KHashPath);
+
+ TParse hashFileName;
+ hashFileName.Set(hashPath, &aFileName, NULL);
+ TInt err = Fs().MkDirAll(hashFileName.DriveAndPath());
+ if (err!=KErrNone && err!=KErrAlreadyExists)
+ {
+ User::LeaveIfError(err);
+ }
+
+ // If the hash already exists, leave with KErrAlreadyExists
+ TEntry hashEntry;
+ if ( KErrNone == Fs().Entry(hashFileName.FullName(), hashEntry))
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+
+ DEBUG_PRINTF2(_L("Install Server - Installation Processor, extracting hash file '%S'"),
+ &(hashFileName.FullName()));
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RegisterNewL(hashFileName.FullName());
+#else
+ IntegrityServices().AddL(hashFileName.FullName());
+#endif
+
+ RFile file;
+ User::LeaveIfError(file.Create(Fs(), hashFileName.FullName(),
+ EFileWrite|EFileShareExclusive|EFileStream));
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.Write(hashData));
+ CleanupStack::PopAndDestroy(&file);
+ //Write a SWI event log for this hash file
+ TUint8 fileFlag(EFileAdded);
+ CObservationData *event = CObservationData::NewLC(hashFileName.FullName(),TUid::Null(),fileFlag);
+ Observer().AddEventL(*event);
+ CleanupStack::PopAndDestroy(event);
+ }
+
+void CInstallationProcessor::VerifyInstallPathL(const CSisRegistryFileDescription& aFileDescription)
+ {
+ // Check the target path of every file is legal
+ SecurityCheckUtil::TProtectedDirectoryCheckError targetError;
+ // sis file signed by Su Cert are allowed to install files in private dir
+ // without corresponding executable in the package.
+ if (ApplicationL().IsInstallSuCertBased())
+ {
+ return;
+ }
+
+ TBool pathOk = SecurityCheckUtil::CheckProtectedDirectoriesL(
+ aFileDescription.Target(), aFileDescription.Operation(), iSidsAdded, targetError);
+ if (!pathOk)
+ {
+ /// Initialized to EUiSIDMismatch to make RVCT Compiler happy / supress the warnings during ARM build.
+ TErrorDialog uiError = EUiSIDMismatch;
+ switch(targetError)
+ {
+ case SecurityCheckUtil::ESIDMismatch:
+ uiError = EUiSIDMismatch;
+ break;
+
+ case SecurityCheckUtil::EInvalidFileName:
+ uiError = EUiInvalidFileName;
+ break;
+
+ default:
+ User::Leave(KErrNotSupported);
+ }
+ CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),uiError,KNullDesC);
+ UiHandler().ExecuteL(*cmd);
+ CleanupStack::PopAndDestroy(cmd);
+ User::Leave(KErrAccessDenied);
+ }
+ }
+
+void CInstallationProcessor::InstallFileL(const CFileCopyDescription& aFileCopyDescription)
+ {
+ DEBUG_PRINTF2(_L("Install Server - Installation Processor, installing file to '%S'"),
+ &aFileCopyDescription.FileDescription().Target());
+
+ // move file to it's final location
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RegisterNewL(aFileCopyDescription.FileDescription().Target());
+#else
+ IntegrityServices().AddL(aFileCopyDescription.FileDescription().Target());
+#endif
+
+ // Move try 1 of 3
+ TInt err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+ if(err != KErrNone)
+ {
+ // Move failed - maybe dir did not exist
+ (void) Fs().MkDirAll(aFileCopyDescription.FileDescription().Target());
+ // Move try 2 of 3
+ err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+ if(err != KErrNone)
+ {
+ // Maybe destination already exists?
+ // Is this possible? Or would install have deleted file earlier!?!?
+
+ // Clear Read only attributes and delete the file
+ Fs().SetAtt(aFileCopyDescription.FileDescription().Target(), 0, KEntryAttReadOnly);
+
+ iLoader.Delete(aFileCopyDescription.FileDescription().Target()); // ignore failure here since the rename will fail instead
+
+ // Move try 3 of 3
+ err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
+ }
+ }
+
+ User::LeaveIfError(err); // Did we manage to do the move?
+
+ // Update progress bar for the copy/install of this file
+ UiHandler().UpdateProgressBarL(Plan().AppInfoL(), KProgressBarEndIncrement);
+
+ AddApparcFilesInListL(aFileCopyDescription.FileDescription().Target());
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ // Parse the file if it carries software type registration info
+ if (InstallSoftwareTypeHelper::IsValidSwRegFileL(aFileCopyDescription.FileDescription().Target(),
+ ApplicationL().ControllerL().Info().Uid().Uid().iUid))
+ {
+ InstallSoftwareTypeHelper::ParseRegFileL(Fs(),
+ aFileCopyDescription.FileDescription().Target(),
+ iSoftwareTypeRegInfoArray);
+ }
+#endif
+
+ // Launch the file if RI flag is set.
+ if(ShouldLaunchL(aFileCopyDescription.FileDescription()))
+ {
+ LaunchFileL(aFileCopyDescription.FileDescription());
+ }
+
+ }
+
+// State processing functions
+
+TBool CInstallationProcessor::DoStateInitializeL()
+ {
+ iUiState = EInitialize;
+ iCurrent = 0;
+ iFilesToCopyCurrent = 0;
+ iFilesToCopy.ResetAndDestroy();
+ iApparcRegFiles.ResetAndDestroy();
+ return ETrue;
+ }
+
+TBool CInstallationProcessor::DoStateProcessEmbeddedL()
+ {
+ if (iCurrent < ApplicationL().EmbeddedApplications().Count())
+ {
+ EmbeddedProcessorL().ProcessApplicationL(*ApplicationL().EmbeddedApplications()[iCurrent++], iStatus);
+ WaitState(ECurrentState);
+ return EFalse;
+ }
+ else
+ {
+ iCurrent = 0;
+ return ETrue;
+ }
+ }
+
+TBool CInstallationProcessor::DoStateProcessSkipFilesL()
+ {
+ TInt count = ApplicationL().FilesToSkipOnInstall().Count();
+ // create a modifyable reference
+ CApplication& app = const_cast <CApplication&>(ApplicationL());
+ CPlan& plan = const_cast <CPlan&>(Plan());
+
+ for (TInt i = 0; i < count; ++i)
+ {
+ if (iSkipFile[i])
+ {
+ CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToSkipOnInstall()[i];
+ app.AddFileL(fileDescription);
+ plan.AddInstallFileForProgress(fileDescription.UncompressedLength());
+ }
+ }
+ iCurrent = 0;
+ return ETrue;
+ }
+
+TBool CInstallationProcessor::DoStateExtractFilesL()
+ {
+ if (iCurrent < ApplicationL().FilesToAdd().Count())
+ {
+ if (iUiState != EExtractFiles)
+ {
+ iUiState = EExtractFiles;
+ // Signal to UI we are extracting files
+ CHandleCancellableInstallEvent* cmd = CHandleCancellableInstallEvent::NewLC(Plan().AppInfoL(), EEventCopyingFiles, 0, KNullDesC);
+ UiHandler().ExecuteL(*cmd);
+ CleanupStack::PopAndDestroy(cmd);
+ }
+
+ CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+
+ if(ExtractFileL(fileDescription))
+ {
+ WaitState(ECurrentState);
+ }
+ else
+ {
+ SwitchState(ECurrentState);
+ }
+ return EFalse;
+ }
+ else
+ {
+ iCurrent = 0;
+ return ETrue;
+ }
+ }
+
+bool CInstallationProcessor::FileIsApparcReg(const TDesC& aFilename) const
+ {
+ TParsePtrC filename(aFilename);
+
+ return filename.Path().CompareF(KApparcRegDir) == 0;
+ }
+
+TBool CInstallationProcessor::DoStateProcessFilesL()
+ {
+ DEBUG_PRINTF(_L8("Install Server - Processing Files"));
+ if (iCurrent < ApplicationL().FilesToAdd().Count() )
+ {
+ CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent];
+
+ if(fileDescription.Operation() != Sis::EOpNull)
+ {
+ if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+ {
+ // For pre-installed SISes, filenames could be "e:\foo.txt", but we
+ // want them to install successfully on "f:". So re-write stub file
+ // references to be the same drive as where the SIS file is located
+ TChar drive = ApplicationL().UserSelections().Drive();
+ TFileName target = fileDescription.Target();
+ target[0] = drive;
+
+ // use filenames from the file descriptions
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
+ TransactionSession(), fileDescription, target);
+#else
+ TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
+ IntegrityServices(), fileDescription, target);
+#endif
+ if (error != KErrNone)
+ {
+ ReportErrorL(TErrorDialog(error));
+ }
+
+ // This is either preinstalled or is a propagation and as of Pdef115573 only files under /sys, /resource or
+ // which have the VERIFY tag set need to have their hashes checked.
+ if ((fileDescription.OperationOptions() & Swi::Sis::EInstVerifyOnRestore) || SecurityCheckUtil::IsTargetTcbWriteProtected(fileDescription.Target()))
+ {
+ CheckHashL(fileDescription, target);
+ }
+ }
+ else
+ {
+ // use temporary file names
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
+ iSidsAdded, TransactionSession(), fileDescription,
+ iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+#else
+ TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
+ iSidsAdded, IntegrityServices(), fileDescription,
+ iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+#endif
+ if (error != KErrNone)
+ {
+ ReportErrorL(TErrorDialog(error));
+ }
+ CheckHashL(fileDescription, iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
+ iFilesToCopyCurrent++;
+ }
+ }
+
+ ++iCurrent;
+ SwitchState(ECurrentState);
+ return EFalse;
+ }
+ else
+ {
+
+ // Finally, if this is an addition to an existing package, add SIDs from that
+ // package to the list of SIDs attached to this package
+
+ if (ApplicationL().IsPartialUpgrade() ||
+ ApplicationL().IsAugmentation() ||
+ ApplicationL().IsPreInstalledPatch())
+ {
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ RSisRegistrySession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
+#endif
+
+ RSisRegistryEntry entry;
+ // Planning stage already established the entry exists
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TInt err = entry.Open(iRegistryWrapper.RegistrySession(), ApplicationL().ControllerL().Info().Uid().Uid());
+#else
+ TInt err = entry.Open(session, ApplicationL().ControllerL().Info().Uid().Uid());
+#endif
+ if (err == KErrNotFound)
+ {
+ User::Leave(KErrMissingBasePackage);
+ }
+
+ User::LeaveIfError(err);
+
+ CleanupClosePushL(entry);
+
+ RArray<TUid> preinstalledSids;
+ CleanupClosePushL(preinstalledSids);
+ entry.SidsL(preinstalledSids);
+
+ TInt sids(preinstalledSids.Count());
+ for (TInt i = 0; i < sids; ++i)
+ {
+ DEBUG_PRINTF2(_L("Install Server - Processing Files - Appending SID %08x"), preinstalledSids[i]);
+ iSidsAdded.Append(preinstalledSids[i]);
+ }
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ CleanupStack::PopAndDestroy(2, &entry); // presintalledSids
+#else
+ CleanupStack::PopAndDestroy(3, &session); // entry, presintalledSids
+#endif
+
+ }
+
+ iCurrent = 0;
+ return ETrue;
+ }
+ }
+
+TBool CInstallationProcessor::DoStateVerifyPathsL()
+ {
+ if (iCurrent < ApplicationL().FilesToAdd().Count())
+ {
+ CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+ VerifyInstallPathL(fileDescription);
+ SwitchState(ECurrentState);
+ return EFalse;
+ }
+ else
+ {
+ iCurrent = 0;
+ return ETrue;
+ }
+ }
+
+TBool CInstallationProcessor::DoStateInstallFilesL()
+ {
+ if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+ {
+ // Only need to install hash for files in pre-installed application.
+ if (iCurrent < ApplicationL().FilesToAdd().Count())
+ {
+ const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
+
+ if(fileDescription.Operation() != Sis::EOpNull)
+ {
+ DoExtractHashL(fileDescription);
+
+ // Add apparc registerd files in list.
+ AddApparcFilesInListL(fileDescription.Target());
+
+ // Launch the file if RI flag is set.
+ if(ShouldLaunchL(fileDescription))
+ {
+ LaunchFileL(fileDescription);
+ }
+
+ AddEventToLogL(fileDescription);
+ }
+
+ SwitchState(ECurrentState);
+ return EFalse;
+ }
+ }
+ else if (iCurrent < iFilesToCopy.Count())
+ {
+ const CFileCopyDescription& fileCopyDescription = *iFilesToCopy[iCurrent++];
+ DoExtractHashL(fileCopyDescription.FileDescription());
+ InstallFileL(fileCopyDescription);
+ AddEventToLogL(fileCopyDescription.FileDescription());
+ SwitchState(ECurrentState);
+ return EFalse;
+ }
+ iCurrent = 0;
+ return ETrue;
+ }
+
+
+
+TBool CInstallationProcessor::DoStateDisplayFilesL()
+ {
+ if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
+ {
+ return ETrue;
+ }
+ if (iCurrent < ApplicationL().FilesToDisplayOnInstall().Count())
+ {
+ const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToDisplayOnInstall()[iCurrent++];
+ DisplayFileL(fileDescription, fileDescription.OperationOptions());
+ SwitchState(ECurrentState);
+ return EFalse;
+ }
+ else
+ {
+ iCurrent = 0;
+ return ETrue;
+ }
+ }
+
+TBool CInstallationProcessor::DoStateUpdateRegistryL()
+ {
+ // destroy the memory heavy file copy descriptions
+ iFilesToCopy.ResetAndDestroy();
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ // Now that we are ready to make changes to the registry we start a transaction
+ // Note that the commit/rollback action is subsequently taken by the later steps of the state machine
+ iRegistryWrapper.StartMutableOperationsL();
+#else
+ RSisRegistryWritableSession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
+#endif
+
+ TInt64 offset = 0;
+ if (!ApplicationL().IsUninstall())
+ {
+
+ const Swi::Sis::CController& controller = ApplicationL().ControllerL();
+
+ // If this is the top level controller, strip the type field from it
+ // all controllers must be registered as if they were contained in a SIS
+ // array
+
+ offset = controller.DataOffset();
+ if (offset == 0)
+ {
+ // top level controller
+ offset = 4;
+ TFileName fileName;
+ // Check whether we should create a SIS stub
+ if(IsApplicationPermittedInStub(ApplicationL())
+ && !iSisHelper.IsStubL()
+ && iSecurityManager.SecurityPolicy().AllowPackagePropagate() && IsStubSisFileRequiredL())
+ {
+ TChar drive = ApplicationL().StubDrive();
+ if(CheckEmbeddedAppsInstalledOnSameDrive(ApplicationL().EmbeddedApplications(), drive))
+ {
+ // Create a stub SIS file for the auto-propagation feature.
+ CreateStubSisFileL(fileName);
+ // Register the stub SIS file at SWI registry, so that it will be removed on unistallation.
+ RegisterStubSisFileL(fileName);
+ }
+ }
+
+ // Check whether we are installing from an existing SIS stub
+ if(iSisHelper.IsStubL())
+ {
+ // Check whether the controller was a preinstalled type
+ // if so then it's a preinstalled stub, not a propagated app stub
+ Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();
+ if(installType != Sis::EInstPreInstalledPatch && installType != Sis::EInstPreInstalledApp)
+ {
+ // If we are installing from a removable media stub
+ // we need to add the stub to the list of files to
+ // remove during uninstall
+ // we don't need to create it because we are
+ // already installing from a SIS stub
+ iSisHelper.GetSisFileNameL(fileName);
+ RegisterStubSisFileL(fileName);
+ }
+ else
+ {
+ // If this preinstalled package is deletable and the policy
+ // allows deletion of pre-installed files, add the stub sis
+ // file to the files to remove on uninstall.
+ CSecurityPolicy* securityPolicy=CSecurityPolicy::GetSecurityPolicyL();
+ if (securityPolicy->DeletePreinstalledFilesOnUninstall()
+ && ApplicationL().IsDeletablePreinstalled())
+ {
+ // Get filename of stub sis file
+ TFileName stubFile;
+ iSisHelper.GetSisFileNameL(stubFile);
+ RegisterStubSisFileL(stubFile);
+ }
+ }
+ }
+ }
+ }
+
+ TPtrC8 thisController(iControllerData.Mid(offset));
+
+ if (ApplicationL().IsUpgrade()
+ || ApplicationL().IsPartialUpgrade())
+ {
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ if (iSoftwareTypeRegInfoArray.Count() > 0)
+ {
+ iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
+ }
+ else
+ {
+ iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
+ }
+#else
+ session.UpdateEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
+#endif
+ }
+ else if (ApplicationL().IsInstall()
+ || ApplicationL().IsAugmentation()
+ || ApplicationL().IsPreInstalledApp()
+ || ApplicationL().IsPreInstalledPatch())
+ {
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ if (iSoftwareTypeRegInfoArray.Count() > 0)
+ {
+ iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
+ }
+ else
+ {
+ iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
+ }
+#else
+ session.AddEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
+#endif
+ }
+ else if (ApplicationL().IsUninstall())
+ {
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ iRegistryWrapper.RegistrySession().DeleteEntryL(ApplicationL().PackageL() , TransactionSession().TransactionIdL());
+#else
+ session.DeleteEntryL(ApplicationL().PackageL() , IntegrityServices().TransactionId());
+#endif
+ }
+
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ CleanupStack::PopAndDestroy(&session);
+#else
+ // Registration of MIME types of the software types being installed to AppArc.
+ // This operation is not transactional so it must be done after the software types
+ // have been successfully registered to the SCR by the following calls:
+ // RSisRegistryWritableSession::AddEntryL()
+ // RSisRegistryWritableSession::UpdateEntryL()
+ InstallSoftwareTypeHelper::RegisterMimeTypesL(iSoftwareTypeRegInfoArray);
+#endif
+ return ETrue;
+ }
+
+// CFileCopyDescription
+
+/*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewL(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
+ {
+ CFileCopyDescription* self=CFileCopyDescription::NewLC(aTemporaryFileName, aFileDescription);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewLC(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
+ {
+ CFileCopyDescription* self=new (ELeave) CFileCopyDescription(aFileDescription);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTemporaryFileName);
+ return self;
+ }
+
+CInstallationProcessor::CFileCopyDescription::CFileCopyDescription(const CSisRegistryFileDescription& aFileDescription)
+ :iFileDescription(aFileDescription)
+ {
+ }
+
+void CInstallationProcessor::CFileCopyDescription::ConstructL(const TDesC& aTemporaryFileName)
+ {
+ iTemporaryFileName=aTemporaryFileName.AllocL();
+ }
+
+CInstallationProcessor::CFileCopyDescription::~CFileCopyDescription()
+ {
+ delete iTemporaryFileName;
+ }
+
+CInstallationProcessor& CInstallationProcessor::EmbeddedProcessorL()
+ {
+ if (!iEmbeddedProcessor)
+ {
+ iEmbeddedProcessor=CInstallationProcessor::NewL(*this);
+ }
+ return *iEmbeddedProcessor;
+ }
+
+void CInstallationProcessor::ReportErrorL(TErrorDialog aError)
+ {
+ CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),aError,KNullDesC);
+ UiHandler().ExecuteL(*cmd);
+ CleanupStack::PopAndDestroy(cmd);
+ User::Leave(KErrSecurityError);
+ }
+
+TBool CInstallationProcessor::CheckEmbeddedAppsInstalledOnSameDrive(RPointerArray<CApplication> aArray, TChar aDrive)
+ {
+ for(TInt i = 0; i < aArray.Count(); i++)
+ {
+ CApplication& application = *aArray[i];
+
+ if(!IsApplicationPermittedInStub(application))
+ {
+ return EFalse;
+ }
+ else if(application.StubDrive() != aDrive)
+ {
+ // Embedded Application must be installed on the same drive
+ // as the parent application otherwise the removable media
+ // stub will reference files outside the media card
+ return EFalse;
+ }
+ else if(!CheckEmbeddedAppsInstalledOnSameDrive(application.EmbeddedApplications(), aDrive))
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+TBool CInstallationProcessor::IsApplicationPermittedInStub(const CApplication& aApplication)
+ {
+ if( aApplication.IsPreInstalledApp() ||
+ aApplication.IsPreInstalledPatch() ||
+ aApplication.IsUninstall() ||
+ aApplication.IsPartialUpgrade() ||
+ !aApplication.CanPropagate())
+ {
+ // These installation types are not permitted in
+ // a removable media stub
+ // We cannot be certain that all required files will be present
+ // on the media card when it is inserted into another device
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+
+void CInstallationProcessor::CreateStubSisFileL(TFileName &aFileName)
+ {
+ // Do all this file stuff in SWI so we have necessary capabilities
+ _LIT(KStubDelimiter, "_");
+
+ TUid appUid = ApplicationL().ControllerL().Info().Uid().Uid();
+ TChar drive = ApplicationL().StubDrive();
+ // build SwiDaemon Pathname
+ aFileName.Append(drive);
+ aFileName.Append(KDriveDelimiter);
+ aFileName.Append(KPrivatePath);
+ aFileName.AppendNumFixedWidth(KSwiDaemonUid, EHex, 8);
+ aFileName.Append(KPathDelimiter);
+ aFileName.AppendNumFixedWidth(appUid.iUid, EHex, 8);
+
+
+ Swi::Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();
+
+ switch(installType)
+ {
+ /*
+ If a device has more than one slot, we may install a PA/PP to a different media card.
+ In this case,we'll still create a stub SIS file even though we're installing from a media card.
+ */
+
+ // If an Installation type is SA/PA then append _0 after the stub UID.
+ case Swi::Sis::EInstInstallation:
+ case Swi::Sis::EInstPreInstalledApp:
+ {
+ aFileName.Append(KStubDelimiter);
+ aFileName.Append('0');
+ break;
+ }
+
+ // If an Installation type is SP/PP then append _augNumber+1 after the stub UID.
+ case Swi::Sis::EInstPreInstalledPatch:
+ case Swi::Sis::EInstAugmentation:
+ {
+#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ RSisRegistrySession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
+#endif
+
+ RSisRegistryEntry entry;
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ User::LeaveIfError(entry.Open(iRegistryWrapper.RegistrySession(), appUid));
+#else
+ User::LeaveIfError(entry.Open(session, appUid));
+#endif
+ CleanupClosePushL(entry);
+
+ /*
+ Get the Augmentations number and append the number in stub file name(DEF107470).
+ This way we impose order on the installation sequence when the card is inserted on another device.
+ Since SWI daemon processes stub files in alphabetic order, it will install augmentations only after the original package
+ */
+ TInt augNumber = entry.AugmentationsNumberL();
+ User::LeaveIfError(augNumber);
+ aFileName.Append(KStubDelimiter);
+ aFileName.AppendFormat(_L("%d"),augNumber+1);
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ CleanupStack::PopAndDestroy(&entry);
+#else
+ CleanupStack::PopAndDestroy(2, &session);
+#endif
+ break;
+ }
+
+ default:
+ /*
+ If it is not SA/PA/SP/PP, then this function shouldn't have been invoked,
+ as these are the only package types which can appear according to Functional Specification
+ on a media card.
+ */
+ ASSERT(EFalse);
+ }
+
+ aFileName.Append(KSisExt);
+
+ TEntry entry;
+ if (KErrNone == Fs().Entry(aFileName, entry))
+ {
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RemoveL(aFileName);
+#else
+ IntegrityServices().RemoveL(aFileName);
+#endif
+ }
+
+ // Notify integrity support that we've created a stub
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RegisterNewL(aFileName);
+#else
+ IntegrityServices().AddL(aFileName);
+#endif
+
+ // create SwiDaemon Private directory on the target drive
+ TInt ret = Fs().MkDirAll(aFileName);
+ if (ret!= KErrNone && ret != KErrAlreadyExists)
+ {
+ User::Leave(ret);
+ }
+
+
+ // Create the stub file if required
+ RFile file;
+ User::LeaveIfError(file.Create(Fs(), aFileName, EFileStream | EFileWrite | EFileShareExclusive));
+ CleanupClosePushL(file);
+
+ TInt err = iSisHelper.CreateSisStub(file);
+ CleanupStack::PopAndDestroy(&file);
+
+ if(err != KErrNone)
+ {
+ // something went wrong while creating the stub
+ // delete the incorrectly created file
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ TransactionSession().RemoveL(aFileName);
+#else
+ IntegrityServices().RemoveL(aFileName);
+#endif
+ User::Leave(err);
+ }
+ }
+
+void CInstallationProcessor::RegisterStubSisFileL(const TFileName &aFileName)
+ {
+ // Add the stub file to the list of files to be removed during uninstall
+ CSisRegistryFileDescription* fileDescription
+ = CreateSisStubRegistryFileDescriptionLC(Fs(),aFileName);
+
+ // cast away constness because we need to add a file to remove into the application
+ CApplication& application = const_cast<CApplication&>(ApplicationL());
+ application.AddSisStubFileL(*fileDescription);
+
+ CleanupStack::PopAndDestroy(fileDescription);
+ }
+
+
+TBool CInstallationProcessor::IsStubSisFileRequiredL()
+ {
+ // Check that drive is removable
+ // we only write Stubs to removable media so they
+ // will install when the same media card is inserted
+ // in a different Symbian OS device
+ TChar drive = ApplicationL().StubDrive();
+
+ TDriveInfo driveInfo;
+ TInt driveNum;
+ RFs::CharToDrive(drive, driveNum);
+ Fs().Drive(driveInfo, driveNum);
+
+ if(driveInfo.iDriveAtt & KDriveAttRemovable)
+ return ETrue;
+ else
+ return EFalse;
+ }
+
+CSisRegistryFileDescription* CInstallationProcessor::CreateSisStubRegistryFileDescriptionLC(RFs& aFs, const TDesC& aFileName)
+ {
+ _LIT(KDataTypeSisx, "x-epoc/x-sisx-app");
+
+ // This will leave if the file does not exist
+ CFileSisDataProvider* dataProvider = CFileSisDataProvider::NewLC(aFs, aFileName);
+
+ // create a SHA1 hash of the Sis Stub file
+ HBufC8* hash = iSecurityManager.CalculateHashLC(*dataProvider, CMessageDigest::ESHA1);
+ CHashContainer* hashContainer = CHashContainer::NewLC(CMessageDigest::ESHA1, *hash);
+
+ TInt64 fileLength = 0;
+ dataProvider->Seek(ESeekCurrent, fileLength);
+ Sis::TSISFileOperationOptions options = static_cast<Sis::TSISFileOperationOptions>(0);
+
+ CSisRegistryFileDescription *fileDescription =
+ CSisRegistryFileDescription::NewL(*hashContainer,
+ aFileName,
+ KDataTypeSisx(),
+ Sis::EOpInstall,
+ options,
+ fileLength,
+ 0,
+ KNullUid);
+
+
+ CleanupStack::PopAndDestroy(3, dataProvider); // hashContainer, hash, dataProvider
+ CleanupStack::PushL(fileDescription);
+ return fileDescription;
+ }
+
+
+void CInstallationProcessor::AddEventToLogL(const CSisRegistryFileDescription& aFileDescription)
+/**
+ Write an install file event into the swi observation log file.
+
+ @param aFileDescription The file whose name will be written into the log file.
+ */
+ {
+ TUint8 fileFlag(EFileAdded);
+ TParsePtrC targetPath(aFileDescription.Target());
+
+ if (0 == targetPath.Path().CompareF(KBinPath))
+ {
+ TEntry entry;
+ TInt err = Fs().Entry(aFileDescription.Target(), entry);
+
+ if(KErrNone == err && entry.IsTypeValid())
+ {
+ if(SecUtils::IsExe(entry))
+ {//Set file exe flag.
+ fileFlag |= Swi::EFileExe;
+ }
+ else if(SecUtils::IsDll(entry))
+ {//Set file dll flag.
+ fileFlag |= Swi::EFileDll;
+ }
+ }
+ }
+
+ CObservationData *event = CObservationData::NewLC(aFileDescription.Target(),aFileDescription.Sid(),fileFlag);
+ Observer().AddEventL(*event);
+ CleanupStack::PopAndDestroy(event);
+ }
+
+void CInstallationProcessor::LaunchFileL(const CSisRegistryFileDescription& aFileDescription)
+ {
+ if (iApparcRegFiles.Count() > 0)
+ {
+ // Ask the launcher to notify Apparc of any new reg files
+ RSisLauncherSession launcher;
+ CleanupClosePushL(launcher);
+ User::LeaveIfError(launcher.Connect());
+
+ launcher.NotifyNewAppsL(iApparcRegFiles);
+ // clean up our list so we don't notify of the files twice
+ iApparcRegFiles.ResetAndDestroy();
+
+ CleanupStack::PopAndDestroy(&launcher);
+ }
+
+ // run the file
+ RunFileL(aFileDescription.Target(), aFileDescription.MimeType(),
+ aFileDescription.OperationOptions());
+ }
+
+TBool CInstallationProcessor::ShouldLaunchL(const CSisRegistryFileDescription& aFileDescription)
+ {
+ if (aFileDescription.Operation() == Sis::EOpRun &&
+ aFileDescription.OperationOptions() & Sis::EInstFileRunOptionInstall)
+ {
+#ifdef SYMBIAN_SWI_RUN_ON_INSTALL_COMPLETE
+ return !(aFileDescription.OperationOptions() & Sis::EInstFileRunOptionAfterInstall);
+#else
+ return ETrue;
+#endif
+ }
+ return EFalse;
+ }
+
+void CInstallationProcessor::AddApparcFilesInListL(const TDesC& aTargetFileName)
+ {
+ if (FileIsApparcReg(aTargetFileName))
+ {
+ // we're installing a reg file so add it to our list.
+ HBufC* tmp = aTargetFileName.AllocLC();
+ iApparcRegFiles.AppendL(tmp);
+ CleanupStack::Pop(tmp);
+ }
+ }