installationservices/swi/source/swis/server/installationprocessor.cpp
changeset 0 ba25891c3a9e
child 25 7333d7932ef7
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * Application Processor.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**
       
    21  @file 
       
    22  @released
       
    23  @internalTechnology 
       
    24 */
       
    25 
       
    26 #include <hash.h>
       
    27 #include "installationprocessor.h"
       
    28 
       
    29 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
    30 #include <usif/sts/sts.h>
       
    31 #include "swtypereginfo.h"
       
    32 #include "installswtypehelper.h"
       
    33 #else
       
    34 #include "integrityservices.h"
       
    35 #endif
       
    36 
       
    37 #include "sisregistryentry.h"
       
    38 #include "sishelperclient.h"
       
    39 #include "sisregistryfiledescription.h"
       
    40 #include "sisregistrypackage.h"
       
    41 #include "sisstring.h"
       
    42 #include "hashcontainer.h"
       
    43 #include "siscontroller.h"
       
    44 #include "application.h"
       
    45 #include "userselections.h"
       
    46 #include "log.h"
       
    47 #include "secutils.h"
       
    48 #include "sisuihandler.h"
       
    49 #include "filesisdataprovider.h"
       
    50 #include "securitymanager.h"
       
    51 #include "securitypolicy.h"
       
    52 #include "sislauncherclient.h"
       
    53 #include "sisinfo.h"
       
    54 #include "sisuid.h"
       
    55 #include "plan.h"
       
    56 #include "sidcache.h"
       
    57 #include "sistruststatus.h"
       
    58 #include "securitycheckutil.h"
       
    59 #include "sisfieldtypes.h"
       
    60 #include "progressbar.h"
       
    61 #include "fileextractor.h"
       
    62 #include "securitycheckutil.h"
       
    63 
       
    64 using namespace Swi;
       
    65 
       
    66 
       
    67 _LIT(KApparcRegDir, "\\private\\10003a3f\\import\\apps\\");
       
    68 _LIT(KSisExt, ".sis");
       
    69 
       
    70 
       
    71 const TInt KSwiDaemonUid = 0x10202DCE;
       
    72 
       
    73 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
    74 CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager, 
       
    75 	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
       
    76 	Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
       
    77 	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
    78 	{
       
    79 	CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan, 
       
    80 		aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper, 
       
    81 		aControllerData, aObserver);
       
    82 	CleanupStack::Pop(self);
       
    83 	return self;
       
    84 	}
       
    85 #else
       
    86 CInstallationProcessor* CInstallationProcessor::NewL(const CPlan& aPlan, CSecurityManager &aSecurityManager, 
       
    87 	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
       
    88 	CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
    89 	{
       
    90 	CInstallationProcessor* self = CInstallationProcessor::NewLC(aPlan, 
       
    91 		aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
       
    92 	CleanupStack::Pop(self);
       
    93 	return self;
       
    94 	}
       
    95 #endif
       
    96 
       
    97 CInstallationProcessor* CInstallationProcessor::NewL(CInstallationProcessor& aProcessor)
       
    98 	{
       
    99 	CInstallationProcessor* self = CInstallationProcessor::NewLC(aProcessor.Plan(), 
       
   100 		aProcessor.iSecurityManager, aProcessor.iSisHelper, aProcessor.UiHandler(), 
       
   101 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   102 		aProcessor.TransactionSession(), aProcessor.iRegistryWrapper,
       
   103 #else
       
   104 		aProcessor.IntegrityServices(),
       
   105 #endif
       
   106 		aProcessor.iControllerData, aProcessor.Observer());
       
   107 	CleanupStack::Pop(self);
       
   108 	return self;
       
   109 	}
       
   110 
       
   111 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   112 CInstallationProcessor* CInstallationProcessor::NewLC(
       
   113 	const CPlan& aPlan, CSecurityManager &aSecurityManager, 
       
   114 	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
       
   115 	Usif::RStsSession& aStsSession, CRegistryWrapper& aRegistryWrapper,
       
   116 	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
   117 	{
       
   118 	CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan, 
       
   119 		aSecurityManager, aSisHelper, aUiHandler, aStsSession, aRegistryWrapper, 
       
   120 		aControllerData, aObserver);
       
   121 	CleanupStack::PushL(self);
       
   122 	self->ConstructL();
       
   123 	return self;
       
   124 	}
       
   125 #else
       
   126 CInstallationProcessor* CInstallationProcessor::NewLC(
       
   127 	const CPlan& aPlan, CSecurityManager &aSecurityManager, 
       
   128 	RSisHelper& aSisHelper, RUiHandler& aUiHandler, 
       
   129 	CIntegrityServices& aIntegrityServices, const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
   130 	{
       
   131 	CInstallationProcessor* self = new(ELeave) CInstallationProcessor(aPlan, 
       
   132 		aSecurityManager, aSisHelper, aUiHandler, aIntegrityServices, aControllerData, aObserver);
       
   133 	CleanupStack::PushL(self);
       
   134 	self->ConstructL();
       
   135 	return self;
       
   136 	}
       
   137 #endif
       
   138 
       
   139 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   140 CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan, 
       
   141 	CSecurityManager &aSecurityManager, RSisHelper& aSisHelper, 
       
   142 	RUiHandler& aUiHandler, Usif::RStsSession& aStsSession, 
       
   143 	CRegistryWrapper& aRegistryWrapper,
       
   144 	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
   145 	: CProcessor(aPlan, aUiHandler, aStsSession, aRegistryWrapper, aObserver), 
       
   146 	iSecurityManager(aSecurityManager), 
       
   147 	iSisHelper(aSisHelper),
       
   148 	iControllerData(aControllerData)
       
   149 	{
       
   150 	}
       
   151 #else
       
   152 CInstallationProcessor::CInstallationProcessor(const CPlan& aPlan, 
       
   153 	CSecurityManager &aSecurityManager, RSisHelper& aSisHelper, 
       
   154 	RUiHandler& aUiHandler, CIntegrityServices& aIntegrityServices, 
       
   155 	const TDesC8& aControllerData, RSwiObserverSession& aObserver)
       
   156 	: CProcessor(aPlan, aUiHandler, aIntegrityServices, aObserver), 
       
   157 	iSecurityManager(aSecurityManager), 
       
   158 	iSisHelper(aSisHelper),
       
   159 	iControllerData(aControllerData)
       
   160 	{
       
   161 	}
       
   162 #endif
       
   163 
       
   164 CInstallationProcessor::~CInstallationProcessor()
       
   165 	{
       
   166 	Cancel();
       
   167 	
       
   168 	delete iEmbeddedProcessor;
       
   169 	delete iFileExtractor;
       
   170 		
       
   171 	iFilesToCopy.ResetAndDestroy();
       
   172 	iApparcRegFiles.ResetAndDestroy();
       
   173 	
       
   174 	iLoader.Close();
       
   175 	iSkipFile.Close();
       
   176 	
       
   177 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   178 	iSoftwareTypeRegInfoArray.Close();
       
   179 #endif
       
   180 	}
       
   181 
       
   182 void CInstallationProcessor::ConstructL()
       
   183 	{
       
   184 	User::LeaveIfError(iLoader.Connect());
       
   185 		
       
   186 	CProcessor::ConstructL();
       
   187 	
       
   188 	iFileExtractor=CFileExtractor::NewL(Fs(), iSisHelper, UiHandler(), Plan().AppInfoL());
       
   189 	}
       
   190 
       
   191 void CInstallationProcessor::DoCancel()
       
   192 	{
       
   193 	CProcessor::DoCancel();
       
   194 	if (iEmbeddedProcessor && iEmbeddedProcessor->IsActive())
       
   195 		{
       
   196 		iEmbeddedProcessor->Cancel();
       
   197 		}
       
   198 	
       
   199 	if (iFileExtractor->IsActive())
       
   200 		{
       
   201 		iFileExtractor->Cancel();
       
   202 		}
       
   203 	}
       
   204 
       
   205 void CInstallationProcessor::DisplayFileL(const CSisRegistryFileDescription& aFileDescription, Sis::TSISFileOperationOptions aFileOperationOption)
       
   206 	{
       
   207 	// Default to continue
       
   208 	TFileTextOption fileTextOption(EInstFileTextOptionContinue);
       
   209 	bool forceAbortFlag = EFalse;
       
   210 	if (aFileOperationOption & Sis::EInstFileTextOptionSkipIfNo)
       
   211 		{
       
   212 		fileTextOption=EInstFileTextOptionSkipOneIfNo;
       
   213 		}
       
   214 	else if (aFileOperationOption & Sis::EInstFileTextOptionAbortIfNo)
       
   215 		{
       
   216 		fileTextOption=EInstFileTextOptionAbortIfNo;
       
   217 		}
       
   218 	else if (aFileOperationOption & Sis::EInstFileTextOptionExitIfNo)
       
   219 		{
       
   220 		fileTextOption=EInstFileTextOptionExitIfNo;
       
   221 		}
       
   222 	else if (aFileOperationOption & Sis::EInstFileTextOptionForceAbort)
       
   223 		{
       
   224 		//converts FA option to TC option.
       
   225 		fileTextOption=EInstFileTextOptionContinue;
       
   226 		forceAbortFlag = ETrue;
       
   227 		}
       
   228 			
       
   229 	TFileName temporaryFileName;
       
   230 		
       
   231 	TemporaryFileNameLC(aFileDescription, temporaryFileName);
       
   232 
       
   233 	EnsureTemporaryInstallDirExistsL(temporaryFileName);
       
   234 
       
   235 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   236 	TransactionSession().RegisterTemporaryL(temporaryFileName);
       
   237 #else
       
   238 	IntegrityServices().TemporaryL(temporaryFileName);
       
   239 #endif
       
   240 		
       
   241 	//	Extract this file to its temporary location.
       
   242 	// However this file may have already been extracted, due to displaying it as
       
   243 	// text, so we don't need to extract it again under this circumstance
       
   244 	RFile temporaryFile;
       
   245 	TInt err = temporaryFile.Create(Fs(), temporaryFileName, EFileWrite);
       
   246 	if (err==KErrNone)
       
   247 		{
       
   248 		// We are passing the file handle to SISHelper but still need to close 
       
   249 		// it here.
       
   250 		CleanupClosePushL(temporaryFile);
       
   251 		User::LeaveIfError(iSisHelper.ExtractFileL(Fs(), temporaryFile,
       
   252 			aFileDescription.Index(), ApplicationL().AbsoluteDataIndex(), UiHandler()));
       
   253 		CleanupStack::PopAndDestroy(&temporaryFile);
       
   254 		}
       
   255 	else if (err != KErrAlreadyExists)
       
   256 		{
       
   257 		User::Leave(err);
       
   258 		}
       
   259 		
       
   260 	User::LeaveIfError(temporaryFile.Open(Fs(), temporaryFileName, EFileRead));
       
   261 	CleanupClosePushL(temporaryFile);
       
   262 	
       
   263 	TInt fileSize=0;
       
   264 	User::LeaveIfError(temporaryFile.Size( fileSize));
       
   265 	HBufC8* text=HBufC8::NewMaxLC(fileSize);
       
   266 	TPtr8 textPtr(text->Des());
       
   267 
       
   268 	User::LeaveIfError(temporaryFile.Read(textPtr));	
       
   269 
       
   270 	CDisplayText* displayText = NULL;
       
   271 
       
   272 	displayText = CDisplayText::NewLC(Plan().AppInfoL(), fileTextOption, textPtr);
       
   273 	UiHandler().ExecuteL(*displayText);
       
   274 
       
   275 	switch (fileTextOption)
       
   276 		{
       
   277 		case EInstFileTextOptionContinue:
       
   278 		//for FA option ,raise a TC dialog and abort the installation.
       
   279 		if(forceAbortFlag)
       
   280 			{
       
   281 			User::Leave(KErrCancel);
       
   282 			}
       
   283 		break;
       
   284 		
       
   285 		case EInstFileTextOptionSkipOneIfNo:
       
   286 			{
       
   287 			iSkipFile.AppendL(displayText->ReturnResult());
       
   288 			}
       
   289 		break;
       
   290 	
       
   291 		case EInstFileTextOptionAbortIfNo:
       
   292 		case EInstFileTextOptionExitIfNo:
       
   293 		if (!displayText->ReturnResult())	
       
   294 			{
       
   295 			User::Leave(KErrCancel);
       
   296 			}
       
   297 		break;			
       
   298 		}
       
   299 
       
   300 	CleanupStack::PopAndDestroy(3, &temporaryFile);
       
   301 	}
       
   302 
       
   303 TBool CInstallationProcessor::ExtractFileL(CSisRegistryFileDescription& aFileToExtract)
       
   304 	{
       
   305 	DEBUG_PRINTF2(_L("Install Server - Installation Processor Extracting File '%S'"),
       
   306 		&aFileToExtract.Target());
       
   307 	
       
   308 	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch()
       
   309 			|| aFileToExtract.Operation() == Sis::EOpNull)
       
   310 		{
       
   311 		// This file will not really be copied, but still need to update the progress bar.
       
   312 		// Increment for extract stage (scaled by file size)
       
   313 		TInt ammount = ProgressBarFileIncrement(aFileToExtract.UncompressedLength());
       
   314 		// Increment for install/copy stage
       
   315 		ammount += KProgressBarEndIncrement;
       
   316 		UiHandler().UpdateProgressBarL(Plan().AppInfoL(), ammount);
       
   317 		// move onto next file
       
   318 		return EFalse;	
       
   319 		}
       
   320 
       
   321 	TFileName temporaryFileName;
       
   322 		
       
   323 	TemporaryFileNameLC(aFileToExtract, temporaryFileName);
       
   324 
       
   325 	// Add to the list of files to copy
       
   326 	CFileCopyDescription* fileCopyDescription=CFileCopyDescription::NewLC(
       
   327 		temporaryFileName, aFileToExtract);
       
   328 	User::LeaveIfError(iFilesToCopy.Append(fileCopyDescription));
       
   329 	CleanupStack::Pop(fileCopyDescription);	// Ownership is transferred
       
   330 
       
   331 	EnsureTemporaryInstallDirExistsL(temporaryFileName);
       
   332 
       
   333 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   334 	TransactionSession().RegisterTemporaryL(temporaryFileName);
       
   335 #else
       
   336 	IntegrityServices().TemporaryL(temporaryFileName);
       
   337 #endif
       
   338 
       
   339 	iFileExtractor->ExtractFileL(ApplicationL().AbsoluteDataIndex(), aFileToExtract, temporaryFileName, iStatus);
       
   340 	return ETrue;
       
   341 	}
       
   342 
       
   343 
       
   344 void CInstallationProcessor::DoExtractHashL(const CSisRegistryFileDescription& aFileToProcess)
       
   345 	{
       
   346 	TParsePtrC targetPath(aFileToProcess.Target());
       
   347 	// If the target is in sys\bin, write its hash into \sys\hash and name
       
   348 	// it after the file.  The check in the process file state will ensure
       
   349 	// that it must be a valid exe or dll to get this far.
       
   350 	if (targetPath.Path().CompareF(KBinPath) == 0)
       
   351 		{
       
   352 		ExtractHashL(aFileToProcess.Target(), aFileToProcess.Hash());
       
   353 		}	
       
   354 	}
       
   355 
       
   356 void CInstallationProcessor::CheckHashL(const CSisRegistryFileDescription& aFileToProcess, const TDesC& aCurrentFileName)
       
   357 	{
       
   358 	const CHashContainer& hash = aFileToProcess.Hash();
       
   359 	
       
   360 	// Calculate and check correct hash value
       
   361 	CFileSisDataProvider* fileDataProvider=CFileSisDataProvider::NewLC(Fs(), aCurrentFileName);
       
   362 	TBool hashIsValid=iSecurityManager.VerifyFileHashL(*fileDataProvider,hash);
       
   363 	CleanupStack::PopAndDestroy(fileDataProvider);
       
   364 	if (!hashIsValid)
       
   365 		{
       
   366 		User::Leave(KErrCorrupt);
       
   367 		}
       
   368 	}
       
   369 
       
   370 	
       
   371 
       
   372 void CInstallationProcessor::EnsureTemporaryInstallDirExistsL(const TDesC& aFileTarget)
       
   373 	{
       
   374 	TInt err = Fs().MkDirAll(aFileTarget);
       
   375 	if (err!= KErrNone && err != KErrAlreadyExists)
       
   376 		{
       
   377 		User::LeaveIfError(err);
       
   378 		}
       
   379 	}
       
   380 
       
   381 void CInstallationProcessor::TemporaryFileNameLC(const CSisRegistryFileDescription& aFileToExtract, TDes& aTemporaryFileName)
       
   382 	{
       
   383 	static TInt localTempCnt = 0;
       
   384 	TChar drive;
       
   385 	if(aFileToExtract.Target().Length())
       
   386 		{
       
   387 		// set temporary drive to be same as final target
       
   388 		drive = aFileToExtract.Target()[0];
       
   389 		}
       
   390 	else
       
   391 		{
       
   392 		// set temporary drive to the user selected drive
       
   393 		drive = ApplicationL().UserSelections().Drive();
       
   394 		}
       
   395 	 		
       
   396  	// If no drive has been selected then use the C drive for
       
   397  	// temporary files. This should only happen if the SIS file
       
   398  	// just contains text files to display but not install.
       
   399  	if (drive == TChar(KNoDriveSelected))
       
   400  		{
       
   401  		drive = iSystemDriveChar;
       
   402 		}
       
   403 	
       
   404 	// construct the temporary filename
       
   405 	// Format is  {Drive}:\sys\install\temp\file-{Data Unit}-{File Index}-{LocalCounter}
       
   406 	_LIT(KTemporaryFileFormat, "%c:%Sfile-%d-%d-%d");
       
   407 	TUint driveCh(drive); // Can't pass TChar to Format.
       
   408 	
       
   409 	aTemporaryFileName.Format(KTemporaryFileFormat, driveCh, &KSysInstallTempPath, 
       
   410 							 ApplicationL().AbsoluteDataIndex(), aFileToExtract.Index(),
       
   411 							 localTempCnt++);
       
   412 	}
       
   413 
       
   414 ///\short Extracts executable hash from controller to file for the loader
       
   415 void CInstallationProcessor::ExtractHashL(const TFileName& aFileName, 
       
   416 	const CHashContainer& aHash)
       
   417 	{	
       
   418 	const TDesC8& hashData = aHash.Data();
       
   419 		
       
   420 	TBuf<32> hashPath;	
       
   421 	TUint driveCh(iSystemDriveChar); // can't pass TChar to Format
       
   422 	hashPath.Format(KHashPathFormat, driveCh, &KHashPath);	
       
   423 	
       
   424 	TParse hashFileName;
       
   425 	hashFileName.Set(hashPath, &aFileName, NULL);
       
   426 	TInt err = Fs().MkDirAll(hashFileName.DriveAndPath());
       
   427 	if (err!=KErrNone && err!=KErrAlreadyExists)
       
   428 		{
       
   429 		User::LeaveIfError(err);
       
   430 		}
       
   431 	
       
   432 	// If the hash already exists, leave with KErrAlreadyExists
       
   433 	TEntry hashEntry;
       
   434 	if ( KErrNone == Fs().Entry(hashFileName.FullName(), hashEntry))
       
   435 		{
       
   436 		User::Leave( KErrAlreadyExists );
       
   437 		}
       
   438 
       
   439 	DEBUG_PRINTF2(_L("Install Server - Installation Processor, extracting hash file '%S'"), 
       
   440 		&(hashFileName.FullName()));
       
   441 
       
   442 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   443 	TransactionSession().RegisterNewL(hashFileName.FullName());
       
   444 #else
       
   445 	IntegrityServices().AddL(hashFileName.FullName());
       
   446 #endif
       
   447 
       
   448 	RFile file;
       
   449 	User::LeaveIfError(file.Create(Fs(), hashFileName.FullName(), 
       
   450 		EFileWrite|EFileShareExclusive|EFileStream));
       
   451 	CleanupClosePushL(file);
       
   452 	User::LeaveIfError(file.Write(hashData));
       
   453 	CleanupStack::PopAndDestroy(&file);
       
   454 	//Write a SWI event log for this hash file
       
   455 	TUint8 fileFlag(EFileAdded);
       
   456 	CObservationData *event = CObservationData::NewLC(hashFileName.FullName(),TUid::Null(),fileFlag);
       
   457 	Observer().AddEventL(*event);
       
   458 	CleanupStack::PopAndDestroy(event);
       
   459 	}
       
   460 
       
   461 void CInstallationProcessor::VerifyInstallPathL(const CSisRegistryFileDescription& aFileDescription)
       
   462 	{
       
   463 	// Check the target path of every file is legal
       
   464 	SecurityCheckUtil::TProtectedDirectoryCheckError targetError;
       
   465 	// sis file signed by Su Cert are allowed to install files in private dir 
       
   466 	// without corresponding executable in the package.
       
   467 	if (ApplicationL().IsInstallSuCertBased())
       
   468 		{
       
   469 		return;
       
   470 		}
       
   471 
       
   472 	TBool pathOk = SecurityCheckUtil::CheckProtectedDirectoriesL(
       
   473 		aFileDescription.Target(), aFileDescription.Operation(), iSidsAdded, targetError);
       
   474 	if (!pathOk)
       
   475 		{
       
   476 		/// Initialized to  EUiSIDMismatch to make RVCT Compiler happy / supress the warnings during ARM build.
       
   477 		TErrorDialog uiError = EUiSIDMismatch;
       
   478 		switch(targetError)
       
   479 			{
       
   480 			case SecurityCheckUtil::ESIDMismatch:
       
   481 			uiError = EUiSIDMismatch;
       
   482 			break;
       
   483 			
       
   484 			case SecurityCheckUtil::EInvalidFileName:
       
   485 			uiError = EUiInvalidFileName;
       
   486 			break;
       
   487 			
       
   488 			default:
       
   489 			User::Leave(KErrNotSupported);
       
   490 			}
       
   491 		CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),uiError,KNullDesC);
       
   492 		UiHandler().ExecuteL(*cmd);
       
   493 		CleanupStack::PopAndDestroy(cmd);
       
   494 		User::Leave(KErrAccessDenied);			
       
   495 		}		
       
   496 	}
       
   497 
       
   498 void CInstallationProcessor::InstallFileL(const CFileCopyDescription& aFileCopyDescription)
       
   499 	{
       
   500 	DEBUG_PRINTF2(_L("Install Server - Installation Processor, installing file to '%S'"),
       
   501 		&aFileCopyDescription.FileDescription().Target());
       
   502 	
       
   503 	// move file to it's final location
       
   504 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   505 	TransactionSession().RegisterNewL(aFileCopyDescription.FileDescription().Target());
       
   506 #else
       
   507 	IntegrityServices().AddL(aFileCopyDescription.FileDescription().Target());
       
   508 #endif
       
   509 	
       
   510 	// Move try 1 of 3
       
   511 	TInt err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
       
   512 	if(err != KErrNone)
       
   513 		{
       
   514 		// Move failed - maybe dir did not exist
       
   515 		(void) Fs().MkDirAll(aFileCopyDescription.FileDescription().Target());
       
   516 		// Move try 2 of 3
       
   517 		err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
       
   518 		if(err != KErrNone)
       
   519 			{
       
   520 			// Maybe destination already exists?
       
   521 			// Is this possible? Or would install have deleted file earlier!?!?
       
   522 
       
   523 			// Clear Read only attributes and delete the file
       
   524 			Fs().SetAtt(aFileCopyDescription.FileDescription().Target(), 0, KEntryAttReadOnly);
       
   525 			
       
   526 			iLoader.Delete(aFileCopyDescription.FileDescription().Target()); // ignore failure here since the rename will fail instead
       
   527 			
       
   528 			// Move try 3 of 3
       
   529 			err =Fs().Rename(aFileCopyDescription.TemporaryFileName(), aFileCopyDescription.FileDescription().Target());
       
   530 			}
       
   531 		}
       
   532 
       
   533 	User::LeaveIfError(err); // Did we manage to do the move?
       
   534 
       
   535 	// Update progress bar for the copy/install of this file
       
   536 	UiHandler().UpdateProgressBarL(Plan().AppInfoL(), KProgressBarEndIncrement);
       
   537 	
       
   538 	AddApparcFilesInListL(aFileCopyDescription.FileDescription().Target());
       
   539 
       
   540 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   541 	// Parse the file if it carries software type registration info
       
   542 	if (InstallSoftwareTypeHelper::IsValidSwRegFileL(aFileCopyDescription.FileDescription().Target(),
       
   543 													 ApplicationL().ControllerL().Info().Uid().Uid().iUid))
       
   544 		{
       
   545 		InstallSoftwareTypeHelper::ParseRegFileL(Fs(),
       
   546 												 aFileCopyDescription.FileDescription().Target(),
       
   547 												 iSoftwareTypeRegInfoArray);
       
   548 		}
       
   549 #endif
       
   550 
       
   551 	// Launch the file if RI flag is set.
       
   552 	if(ShouldLaunchL(aFileCopyDescription.FileDescription()))
       
   553 		{
       
   554 		LaunchFileL(aFileCopyDescription.FileDescription());
       
   555 		}
       
   556 	
       
   557 	}
       
   558 
       
   559 // State processing functions
       
   560 
       
   561 TBool CInstallationProcessor::DoStateInitializeL()
       
   562 	{
       
   563 	iUiState = EInitialize;
       
   564 	iCurrent = 0;
       
   565 	iFilesToCopyCurrent = 0;
       
   566 	iFilesToCopy.ResetAndDestroy();
       
   567 	iApparcRegFiles.ResetAndDestroy();
       
   568 	return ETrue;
       
   569 	}
       
   570 	
       
   571 TBool CInstallationProcessor::DoStateProcessEmbeddedL()
       
   572 	{
       
   573 	if (iCurrent < ApplicationL().EmbeddedApplications().Count())
       
   574 		{
       
   575 		EmbeddedProcessorL().ProcessApplicationL(*ApplicationL().EmbeddedApplications()[iCurrent++], iStatus);
       
   576 		WaitState(ECurrentState);
       
   577 		return EFalse;
       
   578 		}
       
   579 	else
       
   580 		{
       
   581 		iCurrent = 0;
       
   582 		return ETrue;
       
   583 		}
       
   584 	}
       
   585 	
       
   586 TBool CInstallationProcessor::DoStateProcessSkipFilesL()
       
   587 	{
       
   588 	TInt count = ApplicationL().FilesToSkipOnInstall().Count();
       
   589 	// create a modifyable reference
       
   590 	CApplication& app = const_cast <CApplication&>(ApplicationL());
       
   591 	CPlan& plan = const_cast <CPlan&>(Plan());
       
   592 
       
   593 	for (TInt i = 0; i < count; ++i)		
       
   594 		{
       
   595 		if (iSkipFile[i])
       
   596 			{
       
   597 			CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToSkipOnInstall()[i];
       
   598 			app.AddFileL(fileDescription);
       
   599 			plan.AddInstallFileForProgress(fileDescription.UncompressedLength());
       
   600 			}
       
   601 		}
       
   602 	iCurrent = 0;
       
   603 	return ETrue;	
       
   604 	}
       
   605 	
       
   606 TBool CInstallationProcessor::DoStateExtractFilesL()
       
   607 	{
       
   608 	if (iCurrent < ApplicationL().FilesToAdd().Count())
       
   609 		{
       
   610 		if (iUiState != EExtractFiles)
       
   611 			{
       
   612 			iUiState = EExtractFiles;
       
   613 			// Signal to UI we are extracting files
       
   614 			CHandleCancellableInstallEvent* cmd = CHandleCancellableInstallEvent::NewLC(Plan().AppInfoL(), EEventCopyingFiles, 0, KNullDesC);
       
   615 			UiHandler().ExecuteL(*cmd);
       
   616 			CleanupStack::PopAndDestroy(cmd);
       
   617 			}
       
   618 			
       
   619 		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
       
   620 		
       
   621 		if(ExtractFileL(fileDescription))
       
   622 			{
       
   623 			WaitState(ECurrentState);
       
   624 			}
       
   625 		else
       
   626 			{
       
   627 			SwitchState(ECurrentState);
       
   628 			}
       
   629 		return EFalse;
       
   630 		}
       
   631 	else
       
   632 		{
       
   633 		iCurrent = 0;
       
   634 		return ETrue;
       
   635 		}
       
   636 	}
       
   637 
       
   638 bool CInstallationProcessor::FileIsApparcReg(const TDesC& aFilename) const
       
   639 	{
       
   640 	TParsePtrC filename(aFilename);
       
   641 
       
   642 	return filename.Path().CompareF(KApparcRegDir) == 0;
       
   643 	}
       
   644 
       
   645 TBool CInstallationProcessor::DoStateProcessFilesL()
       
   646 	{
       
   647 	DEBUG_PRINTF(_L8("Install Server - Processing Files"));
       
   648 	if (iCurrent < ApplicationL().FilesToAdd().Count() )
       
   649 		{
       
   650 		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent];
       
   651 		
       
   652 		if(fileDescription.Operation() != Sis::EOpNull)
       
   653 			{
       
   654 			if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
       
   655 				{
       
   656 				// For pre-installed SISes, filenames could be "e:\foo.txt", but we
       
   657 				// want them to install successfully on "f:". So re-write stub file
       
   658 				// references to be the same drive as where the SIS file is located
       
   659 				TChar drive = ApplicationL().UserSelections().Drive();
       
   660 				TFileName target = fileDescription.Target();
       
   661 				target[0] = drive;
       
   662 				
       
   663 				// use filenames from the file descriptions
       
   664 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   665 				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
       
   666 					TransactionSession(), fileDescription, target);
       
   667 #else
       
   668 				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(), iSidsAdded,
       
   669 					IntegrityServices(), fileDescription, target);
       
   670 #endif
       
   671 				if (error != KErrNone)
       
   672 					{
       
   673 					ReportErrorL(TErrorDialog(error));
       
   674 					}
       
   675 				
       
   676 				// This is either preinstalled or is a propagation and as of Pdef115573 only files under /sys, /resource or 
       
   677 				// which have the VERIFY tag set need to have their hashes checked.
       
   678 				if ((fileDescription.OperationOptions() & Swi::Sis::EInstVerifyOnRestore) || SecurityCheckUtil::IsTargetTcbWriteProtected(fileDescription.Target()))
       
   679 					{
       
   680 					CheckHashL(fileDescription, target);
       
   681 					}
       
   682 				}
       
   683 			else
       
   684 				{
       
   685 				// use temporary file names
       
   686 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   687 				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
       
   688 					iSidsAdded, TransactionSession(), fileDescription,
       
   689 					iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
       
   690 #else
       
   691 				TInt error = SecurityCheckUtil::ProcessFileL(ApplicationL(), Fs(),
       
   692 					iSidsAdded, IntegrityServices(), fileDescription,
       
   693 					iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
       
   694 #endif
       
   695 				if (error != KErrNone)
       
   696 					{
       
   697 					ReportErrorL(TErrorDialog(error));
       
   698 					}	
       
   699 				CheckHashL(fileDescription, iFilesToCopy[iFilesToCopyCurrent]->TemporaryFileName());
       
   700 				iFilesToCopyCurrent++;
       
   701 				}
       
   702 			}
       
   703 
       
   704 		++iCurrent;
       
   705 		SwitchState(ECurrentState);
       
   706 		return EFalse;
       
   707 		}
       
   708 	else
       
   709 		{
       
   710 		
       
   711 		// Finally, if this is an addition to an existing package, add SIDs from that
       
   712 		// package to the list of SIDs attached to this package
       
   713 		
       
   714 		if (ApplicationL().IsPartialUpgrade() ||
       
   715 			ApplicationL().IsAugmentation()	||
       
   716 			ApplicationL().IsPreInstalledPatch())
       
   717 			{
       
   718 #ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   719 			RSisRegistrySession session;
       
   720 			User::LeaveIfError(session.Connect());
       
   721 			CleanupClosePushL(session);
       
   722 #endif
       
   723 			
       
   724 			RSisRegistryEntry entry;
       
   725 			// Planning stage already established the entry exists
       
   726 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   727 			TInt err = entry.Open(iRegistryWrapper.RegistrySession(), ApplicationL().ControllerL().Info().Uid().Uid());
       
   728 #else
       
   729 			TInt err = entry.Open(session, ApplicationL().ControllerL().Info().Uid().Uid());
       
   730 #endif
       
   731 			if (err == KErrNotFound)
       
   732 			{
       
   733 			  User::Leave(KErrMissingBasePackage);	
       
   734 			}
       
   735 			
       
   736 			User::LeaveIfError(err);	
       
   737 		  
       
   738 			CleanupClosePushL(entry);
       
   739 			
       
   740 			RArray<TUid> preinstalledSids;
       
   741 			CleanupClosePushL(preinstalledSids);
       
   742 			entry.SidsL(preinstalledSids);
       
   743 			
       
   744 			TInt sids(preinstalledSids.Count());
       
   745 			for (TInt i = 0; i < sids; ++i)
       
   746 				{
       
   747 				DEBUG_PRINTF2(_L("Install Server - Processing Files - Appending SID %08x"), preinstalledSids[i]);
       
   748 				iSidsAdded.Append(preinstalledSids[i]);
       
   749 				}
       
   750 			
       
   751 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   752 			CleanupStack::PopAndDestroy(2, &entry); // presintalledSids
       
   753 #else
       
   754 			CleanupStack::PopAndDestroy(3, &session); // entry, presintalledSids
       
   755 #endif
       
   756 			
       
   757 			}
       
   758 		
       
   759 		iCurrent = 0;
       
   760 		return ETrue;
       
   761 		}
       
   762 	}
       
   763 
       
   764 TBool CInstallationProcessor::DoStateVerifyPathsL()
       
   765 	{
       
   766 	if (iCurrent < ApplicationL().FilesToAdd().Count())
       
   767 		{
       
   768 		CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
       
   769 		VerifyInstallPathL(fileDescription);	
       
   770 		SwitchState(ECurrentState);
       
   771 		return EFalse;
       
   772 		}
       
   773 	else
       
   774 		{
       
   775 		iCurrent = 0;
       
   776 		return ETrue;
       
   777 		}
       
   778 	}
       
   779 	
       
   780 TBool CInstallationProcessor::DoStateInstallFilesL()
       
   781 	{
       
   782 	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
       
   783 		{
       
   784 		// Only need to install hash for files in pre-installed application.
       
   785 		if (iCurrent < ApplicationL().FilesToAdd().Count())
       
   786 			{
       
   787 			const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToAdd()[iCurrent++];
       
   788 			
       
   789 			if(fileDescription.Operation() != Sis::EOpNull)
       
   790 				{
       
   791 				DoExtractHashL(fileDescription);
       
   792 				
       
   793 				// Add apparc registerd files in list.
       
   794 				AddApparcFilesInListL(fileDescription.Target());
       
   795 				
       
   796 				// Launch the file if RI flag is set.
       
   797 				if(ShouldLaunchL(fileDescription))
       
   798 					{
       
   799 					LaunchFileL(fileDescription);
       
   800 					}
       
   801 					
       
   802 				AddEventToLogL(fileDescription);
       
   803 				}
       
   804 				
       
   805 			SwitchState(ECurrentState);
       
   806 			return EFalse;
       
   807 			}
       
   808 		}
       
   809 	else if (iCurrent < iFilesToCopy.Count())
       
   810 		{
       
   811 		const CFileCopyDescription& fileCopyDescription = *iFilesToCopy[iCurrent++];
       
   812 		DoExtractHashL(fileCopyDescription.FileDescription());
       
   813 		InstallFileL(fileCopyDescription);
       
   814 		AddEventToLogL(fileCopyDescription.FileDescription());
       
   815 		SwitchState(ECurrentState);
       
   816 		return EFalse;
       
   817 		}
       
   818 	iCurrent = 0;
       
   819 	return ETrue;
       
   820 	}
       
   821 
       
   822 
       
   823 
       
   824 TBool CInstallationProcessor::DoStateDisplayFilesL()
       
   825 	{
       
   826 	if (ApplicationL().IsPreInstalledApp() || ApplicationL().IsPreInstalledPatch())
       
   827 		{
       
   828 		return ETrue;
       
   829 		}
       
   830 	if (iCurrent < ApplicationL().FilesToDisplayOnInstall().Count())
       
   831 		{		
       
   832 		const CSisRegistryFileDescription& fileDescription = *ApplicationL().FilesToDisplayOnInstall()[iCurrent++];		
       
   833 		DisplayFileL(fileDescription, fileDescription.OperationOptions());
       
   834 		SwitchState(ECurrentState);
       
   835 		return EFalse;
       
   836 		}
       
   837 	else
       
   838 		{
       
   839 		iCurrent = 0;
       
   840 		return ETrue;
       
   841 		}		
       
   842 	}
       
   843 
       
   844 TBool CInstallationProcessor::DoStateUpdateRegistryL()
       
   845 	{
       
   846 	// destroy the memory heavy file copy descriptions
       
   847 	iFilesToCopy.ResetAndDestroy();
       
   848 
       
   849 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   850 	// Now that we are ready to make changes to the registry we start a transaction
       
   851 	// Note that the commit/rollback action is subsequently taken by the later steps of the state machine
       
   852 	iRegistryWrapper.StartMutableOperationsL();
       
   853 #else
       
   854 	RSisRegistryWritableSession session;
       
   855 	User::LeaveIfError(session.Connect());
       
   856 	CleanupClosePushL(session);
       
   857 #endif
       
   858 	
       
   859 	TInt64 offset = 0;
       
   860 	if (!ApplicationL().IsUninstall())
       
   861 		{
       
   862 		
       
   863 		const Swi::Sis::CController& controller = ApplicationL().ControllerL();
       
   864 	
       
   865 		// If this is the top level controller, strip the type field from it
       
   866 		// all controllers must be registered as if they were contained in a SIS
       
   867 		// array
       
   868 	
       
   869 		offset = controller.DataOffset();
       
   870 		if (offset == 0)
       
   871 			{
       
   872 			// top level controller
       
   873 			offset = 4;
       
   874 			TFileName fileName;
       
   875 			// Check whether we should create a SIS stub
       
   876 			if(IsApplicationPermittedInStub(ApplicationL())
       
   877 				&& !iSisHelper.IsStubL()
       
   878 				&& iSecurityManager.SecurityPolicy().AllowPackagePropagate() &&  IsStubSisFileRequiredL())  
       
   879 				{
       
   880 				TChar drive = ApplicationL().StubDrive();
       
   881 				if(CheckEmbeddedAppsInstalledOnSameDrive(ApplicationL().EmbeddedApplications(), drive))
       
   882 					{
       
   883 					// Create a stub SIS file for the auto-propagation feature.
       
   884 					CreateStubSisFileL(fileName);
       
   885 					// Register the stub SIS file at SWI registry, so that it will be removed on unistallation.
       
   886 					RegisterStubSisFileL(fileName);
       
   887 					}
       
   888 				}			
       
   889 			
       
   890 			// Check whether we are installing from an existing SIS stub
       
   891 			if(iSisHelper.IsStubL())
       
   892 				{
       
   893 				// Check whether the controller was a preinstalled type
       
   894 				// if so then it's a preinstalled stub, not a propagated app stub
       
   895 				Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();
       
   896 				if(installType != Sis::EInstPreInstalledPatch && installType != Sis::EInstPreInstalledApp)
       
   897 					{
       
   898 					// If we are installing from a removable media stub
       
   899 					// we need to add the stub to the list of files to
       
   900 					// remove during uninstall
       
   901 					// we don't need to create it because we are 
       
   902 					// already installing from a SIS stub
       
   903 					iSisHelper.GetSisFileNameL(fileName);
       
   904 					RegisterStubSisFileL(fileName);
       
   905 					}
       
   906 				else
       
   907 					{
       
   908 					// If this preinstalled package is deletable and the policy
       
   909 					// allows deletion of pre-installed files, add the stub sis
       
   910 					// file to the files to remove on uninstall.
       
   911 					CSecurityPolicy* securityPolicy=CSecurityPolicy::GetSecurityPolicyL();
       
   912 					if (securityPolicy->DeletePreinstalledFilesOnUninstall()
       
   913 						&& ApplicationL().IsDeletablePreinstalled())
       
   914 						{
       
   915 						// Get filename of stub sis file
       
   916 						TFileName stubFile;
       
   917 						iSisHelper.GetSisFileNameL(stubFile);
       
   918 						RegisterStubSisFileL(stubFile);
       
   919 						}
       
   920 					}
       
   921 				}
       
   922 			}
       
   923 		}
       
   924 	
       
   925 	TPtrC8 thisController(iControllerData.Mid(offset));
       
   926 	
       
   927 	if (ApplicationL().IsUpgrade() 
       
   928 		 || ApplicationL().IsPartialUpgrade())
       
   929 		{
       
   930 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   931 		if (iSoftwareTypeRegInfoArray.Count() > 0)
       
   932 			{
       
   933 			iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
       
   934 			}
       
   935 		else
       
   936 			{
       
   937 			iRegistryWrapper.RegistrySession().UpdateEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
       
   938 			}
       
   939 #else
       
   940 		session.UpdateEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
       
   941 #endif
       
   942 		}
       
   943 	else if (ApplicationL().IsInstall()
       
   944 				|| ApplicationL().IsAugmentation() 
       
   945 				|| ApplicationL().IsPreInstalledApp()
       
   946 				|| ApplicationL().IsPreInstalledPatch())
       
   947 		{
       
   948 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   949 		if (iSoftwareTypeRegInfoArray.Count() > 0)
       
   950 			{
       
   951 			iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, iSoftwareTypeRegInfoArray, TransactionSession().TransactionIdL());
       
   952 			}
       
   953 		else
       
   954 			{
       
   955 			iRegistryWrapper.RegistrySession().AddEntryL(ApplicationL(), thisController, TransactionSession().TransactionIdL());
       
   956 			}
       
   957 #else
       
   958 		session.AddEntryL(ApplicationL(), thisController, IntegrityServices().TransactionId());
       
   959 #endif
       
   960 		}
       
   961 	else if (ApplicationL().IsUninstall())
       
   962 		{
       
   963 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   964 		iRegistryWrapper.RegistrySession().DeleteEntryL(ApplicationL().PackageL() , TransactionSession().TransactionIdL()); 
       
   965 #else
       
   966 		session.DeleteEntryL(ApplicationL().PackageL() , IntegrityServices().TransactionId());
       
   967 #endif
       
   968 		}
       
   969 
       
   970 #ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
   971 	CleanupStack::PopAndDestroy(&session);
       
   972 #else
       
   973 	// Registration of MIME types of the software types being installed to AppArc.
       
   974 	// This operation is not transactional so it must be done after the software types
       
   975 	// have been successfully registered to the SCR by the following calls:
       
   976 	// RSisRegistryWritableSession::AddEntryL()
       
   977 	// RSisRegistryWritableSession::UpdateEntryL()
       
   978 	InstallSoftwareTypeHelper::RegisterMimeTypesL(iSoftwareTypeRegInfoArray);
       
   979 #endif
       
   980 	return ETrue;
       
   981 	}
       
   982 
       
   983 // CFileCopyDescription 
       
   984 
       
   985 /*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewL(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
       
   986 	{
       
   987 	CFileCopyDescription* self=CFileCopyDescription::NewLC(aTemporaryFileName, aFileDescription);
       
   988 	CleanupStack::Pop(self);
       
   989 	return self;
       
   990 	}
       
   991 
       
   992 /*static*/ CInstallationProcessor::CFileCopyDescription* CInstallationProcessor::CFileCopyDescription::NewLC(const TDesC& aTemporaryFileName, const CSisRegistryFileDescription& aFileDescription)
       
   993 	{
       
   994 	CFileCopyDescription* self=new (ELeave) CFileCopyDescription(aFileDescription);
       
   995 	CleanupStack::PushL(self);
       
   996 	self->ConstructL(aTemporaryFileName);
       
   997 	return self;
       
   998 	}
       
   999 
       
  1000 CInstallationProcessor::CFileCopyDescription::CFileCopyDescription(const CSisRegistryFileDescription& aFileDescription)
       
  1001 	:iFileDescription(aFileDescription)
       
  1002 	{
       
  1003 	}
       
  1004 
       
  1005 void CInstallationProcessor::CFileCopyDescription::ConstructL(const TDesC& aTemporaryFileName)
       
  1006 	{
       
  1007 	iTemporaryFileName=aTemporaryFileName.AllocL();
       
  1008 	}
       
  1009 
       
  1010 CInstallationProcessor::CFileCopyDescription::~CFileCopyDescription()
       
  1011 	{
       
  1012 	delete iTemporaryFileName;	
       
  1013 	}
       
  1014 
       
  1015 CInstallationProcessor& CInstallationProcessor::EmbeddedProcessorL()
       
  1016 	{
       
  1017 	if (!iEmbeddedProcessor)
       
  1018 		{
       
  1019 		iEmbeddedProcessor=CInstallationProcessor::NewL(*this);
       
  1020 		}
       
  1021 	return *iEmbeddedProcessor;
       
  1022 	}
       
  1023 	
       
  1024 void CInstallationProcessor::ReportErrorL(TErrorDialog aError)
       
  1025 	{
       
  1026 	CDisplayError* cmd=CDisplayError::NewLC(Plan().AppInfoL(),aError,KNullDesC);
       
  1027 	UiHandler().ExecuteL(*cmd);
       
  1028 	CleanupStack::PopAndDestroy(cmd);
       
  1029 	User::Leave(KErrSecurityError);	
       
  1030 	}
       
  1031 
       
  1032 TBool CInstallationProcessor::CheckEmbeddedAppsInstalledOnSameDrive(RPointerArray<CApplication> aArray, TChar aDrive)
       
  1033 	{
       
  1034 	for(TInt i = 0; i < aArray.Count(); i++)
       
  1035 		{
       
  1036 		CApplication& application = *aArray[i];
       
  1037 		
       
  1038 		if(!IsApplicationPermittedInStub(application))
       
  1039 			{
       
  1040 			return EFalse;
       
  1041 			}	
       
  1042 		else if(application.StubDrive() != aDrive)
       
  1043 			{
       
  1044 			// Embedded Application must be installed on the same drive
       
  1045 			// as the parent application otherwise the removable media
       
  1046 			// stub will reference files outside the media card
       
  1047 			return EFalse;
       
  1048 			}
       
  1049 		else if(!CheckEmbeddedAppsInstalledOnSameDrive(application.EmbeddedApplications(), aDrive))
       
  1050 			{
       
  1051 			return EFalse;
       
  1052 			}
       
  1053 		}
       
  1054 	return ETrue;
       
  1055 	}
       
  1056 
       
  1057 TBool CInstallationProcessor::IsApplicationPermittedInStub(const CApplication& aApplication)
       
  1058 	{
       
  1059 	if(	aApplication.IsPreInstalledApp() || 
       
  1060 		aApplication.IsPreInstalledPatch() ||
       
  1061 		aApplication.IsUninstall() ||
       
  1062 		aApplication.IsPartialUpgrade() ||
       
  1063 		!aApplication.CanPropagate())
       
  1064 		{
       
  1065 		// These installation types are not permitted in
       
  1066 		// a removable media stub
       
  1067 		// We cannot be certain that all required files will be present
       
  1068 		// on the media card when it is inserted into another device
       
  1069 		return EFalse;
       
  1070 		}
       
  1071 	else
       
  1072 		{
       
  1073 		return ETrue;
       
  1074 		}
       
  1075 	}
       
  1076 
       
  1077 
       
  1078 void CInstallationProcessor::CreateStubSisFileL(TFileName &aFileName)
       
  1079 	{
       
  1080 	// Do all this file stuff in SWI so we have necessary capabilities
       
  1081 	_LIT(KStubDelimiter,      "_");
       
  1082 	
       
  1083 	TUid appUid = ApplicationL().ControllerL().Info().Uid().Uid();
       
  1084 	TChar drive = ApplicationL().StubDrive();
       
  1085 	// build SwiDaemon Pathname
       
  1086 	aFileName.Append(drive);
       
  1087 	aFileName.Append(KDriveDelimiter);
       
  1088 	aFileName.Append(KPrivatePath);
       
  1089 	aFileName.AppendNumFixedWidth(KSwiDaemonUid, EHex, 8);
       
  1090 	aFileName.Append(KPathDelimiter);
       
  1091 	aFileName.AppendNumFixedWidth(appUid.iUid, EHex, 8);	
       
  1092 		
       
  1093 		
       
  1094 	Swi::Sis::TInstallType installType = ApplicationL().ControllerL().Info().InstallType();	
       
  1095 		
       
  1096 	switch(installType)
       
  1097 		{
       
  1098 		/* 
       
  1099 		If a device has more than one slot, we may install a PA/PP to a different media card. 
       
  1100 		In this case,we'll still create a stub SIS file even though we're installing from a media card.
       
  1101 		*/
       
  1102 
       
  1103 		// If an Installation type is SA/PA then append _0 after the stub UID.
       
  1104 		case Swi::Sis::EInstInstallation:
       
  1105 		case Swi::Sis::EInstPreInstalledApp:
       
  1106 			{
       
  1107 			aFileName.Append(KStubDelimiter);
       
  1108 			aFileName.Append('0');	
       
  1109 			break;
       
  1110 			}
       
  1111 				
       
  1112 		// If an Installation type is SP/PP then append _augNumber+1 after the stub UID.
       
  1113 		case Swi::Sis::EInstPreInstalledPatch:
       
  1114 		case Swi::Sis::EInstAugmentation:
       
  1115 			{
       
  1116 #ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1117 			RSisRegistrySession session;
       
  1118 			User::LeaveIfError(session.Connect());
       
  1119 			CleanupClosePushL(session);
       
  1120 #endif
       
  1121 
       
  1122 			RSisRegistryEntry entry;
       
  1123 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1124 			User::LeaveIfError(entry.Open(iRegistryWrapper.RegistrySession(), appUid));
       
  1125 #else
       
  1126 			User::LeaveIfError(entry.Open(session, appUid));
       
  1127 #endif
       
  1128 			CleanupClosePushL(entry);	
       
  1129 
       
  1130 			/*
       
  1131 			Get the Augmentations number and append the number in stub file name(DEF107470).
       
  1132 			This way we impose order on the installation sequence when the card is inserted on another device.
       
  1133 			Since SWI daemon processes stub files in alphabetic order, it will install augmentations only after the original package
       
  1134 			*/
       
  1135 			TInt augNumber = entry.AugmentationsNumberL();	
       
  1136 			User::LeaveIfError(augNumber);
       
  1137 			aFileName.Append(KStubDelimiter);
       
  1138 			aFileName.AppendFormat(_L("%d"),augNumber+1);
       
  1139 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1140 			CleanupStack::PopAndDestroy(&entry);
       
  1141 #else
       
  1142 			CleanupStack::PopAndDestroy(2, &session);
       
  1143 #endif
       
  1144 			break;
       
  1145 			}
       
  1146 
       
  1147 		default: 
       
  1148 			/* 
       
  1149 			If it is not SA/PA/SP/PP, then this function shouldn't have been invoked, 
       
  1150 			as these are the only package types which can appear according to Functional Specification 
       
  1151 			on a media card.
       
  1152 			*/
       
  1153 			ASSERT(EFalse);
       
  1154 		}
       
  1155 
       
  1156 	aFileName.Append(KSisExt);
       
  1157 
       
  1158 	TEntry entry;
       
  1159 	if (KErrNone == Fs().Entry(aFileName, entry))
       
  1160 		{
       
  1161 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1162 		TransactionSession().RemoveL(aFileName);
       
  1163 #else
       
  1164 		IntegrityServices().RemoveL(aFileName);	
       
  1165 #endif
       
  1166 		}
       
  1167 
       
  1168 	// Notify integrity support that we've created a stub
       
  1169 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1170 	TransactionSession().RegisterNewL(aFileName);
       
  1171 #else
       
  1172 	IntegrityServices().AddL(aFileName);
       
  1173 #endif
       
  1174 			
       
  1175 	// create SwiDaemon Private directory on the target drive
       
  1176 	TInt ret = Fs().MkDirAll(aFileName);
       
  1177 	if (ret!= KErrNone && ret != KErrAlreadyExists)
       
  1178 		{
       
  1179 		User::Leave(ret);
       
  1180 		}
       
  1181 
       
  1182 			
       
  1183 	// Create the stub file if required
       
  1184 	RFile file;
       
  1185 	User::LeaveIfError(file.Create(Fs(), aFileName, EFileStream | EFileWrite | EFileShareExclusive));
       
  1186 	CleanupClosePushL(file);
       
  1187 			
       
  1188 	TInt err = iSisHelper.CreateSisStub(file);
       
  1189 	CleanupStack::PopAndDestroy(&file);
       
  1190 		
       
  1191 	if(err != KErrNone)
       
  1192 		{
       
  1193 		// something went wrong while creating the stub
       
  1194 		// delete the incorrectly created file
       
  1195 #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
       
  1196 		TransactionSession().RemoveL(aFileName);
       
  1197 #else
       
  1198 		IntegrityServices().RemoveL(aFileName);
       
  1199 #endif
       
  1200 		User::Leave(err);
       
  1201 		}
       
  1202 	}
       
  1203 
       
  1204 void CInstallationProcessor::RegisterStubSisFileL(const TFileName &aFileName)
       
  1205 	{
       
  1206 	// Add the stub file to the list of files to be removed during uninstall
       
  1207 	CSisRegistryFileDescription* fileDescription 
       
  1208 			= CreateSisStubRegistryFileDescriptionLC(Fs(),aFileName);
       
  1209 		
       
  1210 	// cast away constness because we need to add a file to remove into the application
       
  1211 	CApplication& application  = const_cast<CApplication&>(ApplicationL());
       
  1212 	application.AddSisStubFileL(*fileDescription);
       
  1213 		
       
  1214 	CleanupStack::PopAndDestroy(fileDescription);
       
  1215 	}
       
  1216 
       
  1217 
       
  1218 TBool CInstallationProcessor::IsStubSisFileRequiredL()
       
  1219 	{
       
  1220 	// Check that drive is removable
       
  1221 	// we only write Stubs to removable media so they
       
  1222 	// will install when the same media card is inserted
       
  1223 	// in a different Symbian OS device
       
  1224 	TChar drive = ApplicationL().StubDrive();
       
  1225 	
       
  1226 	TDriveInfo driveInfo;
       
  1227 	TInt driveNum;
       
  1228 	RFs::CharToDrive(drive, driveNum);
       
  1229 	Fs().Drive(driveInfo, driveNum);
       
  1230 	
       
  1231 	if(driveInfo.iDriveAtt & KDriveAttRemovable)
       
  1232 		return ETrue;
       
  1233 	else
       
  1234 		return EFalse;
       
  1235 	}
       
  1236 
       
  1237 CSisRegistryFileDescription* CInstallationProcessor::CreateSisStubRegistryFileDescriptionLC(RFs& aFs, const TDesC& aFileName)
       
  1238 	{
       
  1239 	_LIT(KDataTypeSisx, "x-epoc/x-sisx-app");
       
  1240 	
       
  1241 	// This will leave if the file does not exist
       
  1242 	CFileSisDataProvider* dataProvider = CFileSisDataProvider::NewLC(aFs, aFileName);
       
  1243 	
       
  1244 	// create a SHA1 hash of the Sis Stub file 
       
  1245 	HBufC8* hash = iSecurityManager.CalculateHashLC(*dataProvider, CMessageDigest::ESHA1);
       
  1246 	CHashContainer* hashContainer = CHashContainer::NewLC(CMessageDigest::ESHA1, *hash);
       
  1247 
       
  1248 	TInt64 fileLength = 0;
       
  1249 	dataProvider->Seek(ESeekCurrent, fileLength);
       
  1250 	Sis::TSISFileOperationOptions options = static_cast<Sis::TSISFileOperationOptions>(0);
       
  1251 	
       
  1252 	CSisRegistryFileDescription *fileDescription = 
       
  1253 				CSisRegistryFileDescription::NewL(*hashContainer,
       
  1254 													aFileName,
       
  1255 													KDataTypeSisx(),
       
  1256 													Sis::EOpInstall,
       
  1257 													options,
       
  1258 													fileLength,
       
  1259 													0,
       
  1260 													KNullUid);
       
  1261 													
       
  1262 
       
  1263 	CleanupStack::PopAndDestroy(3, dataProvider); // hashContainer, hash, dataProvider
       
  1264 	CleanupStack::PushL(fileDescription);
       
  1265 	return fileDescription; 
       
  1266 	}
       
  1267 
       
  1268 
       
  1269 void CInstallationProcessor::AddEventToLogL(const CSisRegistryFileDescription& aFileDescription)
       
  1270 /**
       
  1271 	Write an install file event into the swi observation log file.
       
  1272 	
       
  1273 	@param aFileDescription The file whose name will be written into the log file.
       
  1274  */
       
  1275 	{
       
  1276 	TUint8 fileFlag(EFileAdded);
       
  1277 	TParsePtrC targetPath(aFileDescription.Target());
       
  1278 				
       
  1279 	if (0 == targetPath.Path().CompareF(KBinPath))
       
  1280 		{
       
  1281 		TEntry entry;
       
  1282 		TInt err = Fs().Entry(aFileDescription.Target(), entry);
       
  1283 		
       
  1284 		if(KErrNone == err && entry.IsTypeValid())
       
  1285 			{
       
  1286 			if(SecUtils::IsExe(entry))
       
  1287 				{//Set file exe flag.
       
  1288 				fileFlag |= Swi::EFileExe;
       
  1289 				}
       
  1290 			else if(SecUtils::IsDll(entry))
       
  1291 				{//Set file dll flag.
       
  1292 				fileFlag |= Swi::EFileDll;
       
  1293 				}
       
  1294 			}
       
  1295 		}
       
  1296 		
       
  1297 	CObservationData *event = CObservationData::NewLC(aFileDescription.Target(),aFileDescription.Sid(),fileFlag);
       
  1298 	Observer().AddEventL(*event);
       
  1299 	CleanupStack::PopAndDestroy(event);
       
  1300 	}
       
  1301 
       
  1302 void CInstallationProcessor::LaunchFileL(const CSisRegistryFileDescription& aFileDescription)
       
  1303 	{
       
  1304 	if (iApparcRegFiles.Count() > 0)
       
  1305 		{
       
  1306 		// Ask the launcher to notify Apparc of any new reg files
       
  1307 		RSisLauncherSession launcher;
       
  1308 		CleanupClosePushL(launcher);
       
  1309 		User::LeaveIfError(launcher.Connect());
       
  1310 	
       
  1311 		launcher.NotifyNewAppsL(iApparcRegFiles);
       
  1312 		// clean up our list so we don't notify of the files twice
       
  1313 		iApparcRegFiles.ResetAndDestroy();
       
  1314 		
       
  1315 		CleanupStack::PopAndDestroy(&launcher);
       
  1316 		}
       
  1317 
       
  1318 	// run the file
       
  1319 	RunFileL(aFileDescription.Target(), aFileDescription.MimeType(),
       
  1320 			aFileDescription.OperationOptions());
       
  1321 	}
       
  1322 	
       
  1323 TBool CInstallationProcessor::ShouldLaunchL(const CSisRegistryFileDescription& aFileDescription)
       
  1324 	{
       
  1325 	if (aFileDescription.Operation() == Sis::EOpRun && 
       
  1326 		aFileDescription.OperationOptions() & Sis::EInstFileRunOptionInstall)
       
  1327 		{
       
  1328 #ifdef SYMBIAN_SWI_RUN_ON_INSTALL_COMPLETE 
       
  1329 		return !(aFileDescription.OperationOptions() & Sis::EInstFileRunOptionAfterInstall);
       
  1330 #else
       
  1331 		return ETrue;
       
  1332 #endif	
       
  1333 		}
       
  1334 	return EFalse;
       
  1335 	}
       
  1336 	
       
  1337 void CInstallationProcessor::AddApparcFilesInListL(const TDesC& aTargetFileName)
       
  1338 	{
       
  1339 	if (FileIsApparcReg(aTargetFileName))
       
  1340 		{
       
  1341 		// we're installing a reg file so add it to our list. 
       
  1342 		HBufC* tmp = aTargetFileName.AllocLC();
       
  1343 		iApparcRegFiles.AppendL(tmp);
       
  1344 		CleanupStack::Pop(tmp);
       
  1345 		}		
       
  1346 	}