installationservices/refswinstallationplugin/source/sifrefinstallertask.cpp
changeset 24 84a16765cd86
child 25 98b66e4fb0be
equal deleted inserted replaced
6:aba6b8104af3 24:84a16765cd86
       
     1 /*
       
     2 * Copyright (c) 2008-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 * This  file implements Reference Install tasks for getting ComponentInfo, installation, uninstallation and activation/deactivation.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "sifrefinstallertask.h"
       
    21 #include "sifrefbinpkgextractor.h"
       
    22 #include "usiflog.h"
       
    23 #include <usif/usiferror.h>
       
    24 
       
    25 using namespace Usif;
       
    26 
       
    27 _LIT(KRefInstPrivateDir, "c:\\private\\1028634e\\");
       
    28 
       
    29 /**
       
    30 A set of helper functions for Reference Installer tasks.
       
    31 */
       
    32 namespace InstallHelper
       
    33 	{
       
    34 	_LIT(KSifReferenceSoftwareType, "reference");
       
    35 	_LIT(KUiConfirmationQuestion, "Are you sure you want to %S component: %S, vendor: %S");
       
    36 	_LIT(KParamNameErrDesc, "Error Description");
       
    37 	_LIT(KErrFileAlreadyExists, "File already exists: ");
       
    38 	_LIT(KUiConfirmationTypeInstall, "install");
       
    39 	_LIT(KUiConfirmationTypeUpgrade, "upgrade");
       
    40 	_LIT(KUiConfirmationTypeUninstall, "uninstall");
       
    41 	_LIT(KUiParserErrorDesc, "Installer encountered a problem when parsing a package file.");
       
    42 	const TInt KMaxConfirmationTypeLengh = KUiConfirmationTypeUninstall.iTypeLength;
       
    43 
       
    44 	// This Reference Installer uses Component Name and Vendor Name in order to
       
    45 	// identify a component in the SCR database. This identification scheme doesn't provide
       
    46 	// unique ids and its results depend on the current language. Hence, a real installer
       
    47 	// must use the Unique Id mechanism provided by the SCR.
       
    48 	void FindComponentL(RSoftwareComponentRegistry& aScr, TComponentSearchData& aCompSearchData, const CSifRefPkgParser& aParser)
       
    49 		{
       
    50 		DEBUG_PRINTF(_L8("InstallHelper::FindComponentL()"));
       
    51 		
       
    52 		// Get the index of the current language
       
    53 		const TLanguage curLang = User::Language();
       
    54 		TInt langIndex = aParser.GetLanguageIndex(curLang);
       
    55 		if (langIndex == KErrNotFound)
       
    56 			{
       
    57 			ASSERT(aParser.Languages().Count() > 0); // The parser should have already rejected packages without languages
       
    58 			langIndex = 0;
       
    59 			}
       
    60 
       
    61 		// Data for CComponentInfo
       
    62 		aCompSearchData.iName = aParser.ComponentNames()[langIndex];
       
    63 		aCompSearchData.iVersion = aParser.Version().Name();
       
    64 		aCompSearchData.iVendor = aParser.VendorNames()[langIndex];
       
    65 		aCompSearchData.iScomoState = EDeactivated;
       
    66 		aCompSearchData.iInstallStatus = ENewComponent;
       
    67 		aCompSearchData.iComponentId = 0;
       
    68 
       
    69 		RSoftwareComponentRegistryView scrView;
       
    70 		CComponentFilter* filter = CComponentFilter::NewLC();
       
    71 		filter->SetNameL(*aCompSearchData.iName);
       
    72 		filter->SetVendorL(*aCompSearchData.iVendor);
       
    73 		filter->SetSoftwareTypeL(KSifReferenceSoftwareType);
       
    74 
       
    75 		scrView.OpenViewL(aScr, filter);
       
    76 		CleanupClosePushL(scrView);
       
    77 
       
    78 		// Iterate over matching components in order to determine the status of the package being processed.
       
    79 		CComponentEntry* component = NULL;
       
    80 		while ((component = scrView.NextComponentL()) != NULL)
       
    81 			{
       
    82 			const TDesC& installedVersion = component->Version();
       
    83 			const TInt cmp = RSoftwareComponentRegistry::CompareVersionsL(installedVersion, aCompSearchData.iVersion);
       
    84 			if (cmp > 0)
       
    85 				{
       
    86 				aCompSearchData.iInstallStatus = ENewerVersionAlreadyInstalled;
       
    87 				aCompSearchData.iScomoState = component->ScomoState();
       
    88 				aCompSearchData.iComponentId = component->ComponentId();
       
    89 				delete component;
       
    90 				break;
       
    91 				}
       
    92 			else if (cmp == 0 && aCompSearchData.iInstallStatus < EAlreadyInstalled)
       
    93 				{
       
    94 				aCompSearchData.iInstallStatus = EAlreadyInstalled;
       
    95 				aCompSearchData.iScomoState = component->ScomoState();
       
    96 				aCompSearchData.iComponentId = component->ComponentId();
       
    97 				}
       
    98 			else if (cmp < 0 && aCompSearchData.iInstallStatus < EUpgrade)
       
    99 				{
       
   100 				aCompSearchData.iInstallStatus = EUpgrade;
       
   101 				aCompSearchData.iScomoState = component->ScomoState();
       
   102 				aCompSearchData.iComponentId = component->ComponentId();
       
   103 				}
       
   104 			delete component;
       
   105 			}
       
   106 		CleanupStack::PopAndDestroy(2, filter);
       
   107 		}
       
   108 
       
   109 	TBool UnregisterAndDeleteFileL(RSoftwareComponentRegistry& aScr, RSoftwareComponentRegistryFilesList& aFileList, RStsSession& aSts, TComponentId aComponentId)
       
   110 		{
       
   111 		DEBUG_PRINTF(_L8("InstallHelper::UnregisterAndDeleteFileL()"));
       
   112 		
       
   113 		// Get next file
       
   114 		HBufC* file = aFileList.NextFileL();
       
   115 		if (file != NULL)
       
   116 			{
       
   117 			// and remove it from the file system
       
   118 			CleanupStack::PushL(file);
       
   119 			aSts.RemoveL(*file);
       
   120 			CleanupStack::PopAndDestroy(file);
       
   121 			}
       
   122 		else
       
   123 			{
       
   124 			// Remove the component from the SCR if there are no files left
       
   125 			aFileList.Close();
       
   126 			aScr.DeleteComponentL(aComponentId);
       
   127 			
       
   128 			// Copying complete
       
   129 			return ETrue;
       
   130 			}
       
   131 
       
   132 		// Copying in progress
       
   133 		return EFalse;
       
   134 		}
       
   135 
       
   136 	MInstallerUIHandler* CreateUiHandlerL(const COpaqueNamedParams* aCustomArguments, TInstallerUIHandlerFactory aUiHandlerFactory)
       
   137 		{
       
   138 		DEBUG_PRINTF(_L8("InstallHelper::CreateUiHandlerL()"));
       
   139 		
       
   140 		// Instantiate a UI handler for non-silent requests
       
   141 		if (aCustomArguments != NULL)
       
   142 			{
       
   143 			TInt silent = EFalse;
       
   144 			aCustomArguments->GetIntByNameL(_L("Silent"), silent);
       
   145 			if (silent)
       
   146 				{
       
   147 				return NULL;
       
   148 				}
       
   149 			}
       
   150 
       
   151 		return aUiHandlerFactory();
       
   152 		}
       
   153 
       
   154 	enum TConfirmationType
       
   155 		{
       
   156 		EConfirmationInstall,
       
   157 		EConfirmationUpgrade,
       
   158 		EConfirmationUninstall
       
   159 		};
       
   160 
       
   161 	void userConfirmationL(TConfirmationType aType, MInstallerUIHandler& uiHandler, const TDesC& aComponent, const TDesC& aVendor)
       
   162 		{
       
   163 		DEBUG_PRINTF(_L8("InstallHelper::userConfirmationL()"));
       
   164 		
       
   165 		const TInt maxLen = KUiConfirmationQuestion.iTypeLength + KMaxConfirmationTypeLengh + aComponent.Length() + aVendor.Length();
       
   166 		HBufC* info = HBufC::NewLC(maxLen);
       
   167 		TPtr bufInfo(info->Des());
       
   168 		
       
   169 		switch (aType)
       
   170 			{
       
   171 			case EConfirmationInstall:
       
   172 				bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeInstall, &aComponent, &aVendor);
       
   173 				break;
       
   174 
       
   175 			case EConfirmationUpgrade:
       
   176 				bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeUpgrade, &aComponent, &aVendor);
       
   177 				break;
       
   178 
       
   179 			case EConfirmationUninstall:
       
   180 				bufInfo.Format(KUiConfirmationQuestion, &KUiConfirmationTypeUninstall, &aComponent, &aVendor);
       
   181 				break;
       
   182 
       
   183 			default:
       
   184 				User::Leave(KErrArgument);
       
   185 			}
       
   186 
       
   187 		if (!uiHandler.ConfirmationUIHandler(*info))
       
   188 			{
       
   189 			User::Leave(KErrCancel);
       
   190 			}
       
   191 
       
   192 		CleanupStack::PopAndDestroy(info);
       
   193 		}
       
   194 	}
       
   195 
       
   196 // =============================================================================================================
       
   197 
       
   198 CSifRefGetComponentInfoTask* CSifRefGetComponentInfoTask::NewL(TTransportTaskParams& aParams)
       
   199 	{
       
   200 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::NewL()"));
       
   201 	
       
   202 	// Validate the arguments first.
       
   203 	if ((aParams.iFileName == NULL && aParams.iFileHandle == NULL) || aParams.iComponentInfo == NULL)
       
   204 		{
       
   205 		User::Leave(KErrArgument);
       
   206 		}
       
   207 		
       
   208 	CSifRefGetComponentInfoTask* self = new (ELeave) CSifRefGetComponentInfoTask(aParams);
       
   209 	return self;
       
   210 	}
       
   211 
       
   212 CSifRefGetComponentInfoTask::CSifRefGetComponentInfoTask(TTransportTaskParams& aParams)
       
   213 : CSifTransportTask(aParams, EFalse), iStep(EExtractEmbeddedPkgs)
       
   214 	{
       
   215 	}
       
   216 
       
   217 CSifRefGetComponentInfoTask::~CSifRefGetComponentInfoTask()
       
   218 	{
       
   219 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::~CSifRefGetComponentInfoTask()"));
       
   220 	
       
   221 	iFile.Close();
       
   222 	iFs.Close();
       
   223 	iScr.Close();
       
   224 	iSts.Close();
       
   225 	iEmbeddedComponents.Close();
       
   226 	if (iSifRequestInProgress)
       
   227 		{
       
   228 		iSif.CancelOperation();
       
   229 		}
       
   230 	iSif.Close();
       
   231 	delete iParser;
       
   232 	delete iComponentInfo;
       
   233 	}
       
   234 
       
   235 TBool CSifRefGetComponentInfoTask::ExecuteImplL()
       
   236 	{
       
   237 	DEBUG_PRINTF2(_L8("Exiting from CSifRefGetComponentInfoTask::ExecuteImplL(), iStep = %d"), iStep);
       
   238 	
       
   239 	TBool done = EFalse;
       
   240 	
       
   241 	switch (iStep)
       
   242 		{
       
   243 		case EExtractEmbeddedPkgs:
       
   244 			ExtractEmbeddedPkgsL();
       
   245 			++iStep;
       
   246 			break;
       
   247 
       
   248 		case EParsePkgFile:
       
   249 			iStep = ParsePkgFileL();
       
   250 			break;
       
   251 
       
   252 		case EFindComponent:
       
   253 			InstallHelper::FindComponentL(iScr, iCompSearchData, *iParser);
       
   254 			++iStep;
       
   255 			break;
       
   256 
       
   257 		case ECreateComponentInfoNode:
       
   258 			iStep = CreateComponentInfoNodeL();
       
   259 			break;
       
   260 
       
   261 		case ESetComponentInfo:
       
   262 			SetComponentInfoL();
       
   263 			done = ETrue;
       
   264 			break;
       
   265 
       
   266 		default:
       
   267 			User::Leave(KErrGeneral);
       
   268 		}
       
   269 
       
   270 	if (!iSifRequestInProgress)
       
   271 		{
       
   272 		TRequestStatus* status(RequestStatus());
       
   273 		User::RequestComplete(status, KErrNone);
       
   274 		}
       
   275 	
       
   276 	DEBUG_PRINTF3(_L8("Exiting from CSifRefGetComponentInfoTask::ExecuteImplL(), done = %d, iStep = %d"), done, iStep);
       
   277 	
       
   278 	return done;
       
   279 	}
       
   280 
       
   281 void CSifRefGetComponentInfoTask::ExtractEmbeddedPkgsL()
       
   282 	{
       
   283 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::ExtractEmbeddedPkgsL()"));
       
   284 	
       
   285 	// Start an STS transaction. The extraction of a package requires creation of temporary
       
   286 	// files that must be deleted when the GetComponentInfo requiest is complete. This is why
       
   287 	// we need this STS transaction here.
       
   288 	iSts.CreateTransactionL();
       
   289 
       
   290 	if (FileName())
       
   291 		{
       
   292 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileName(), KRefInstPrivateDir, iEmbeddedComponents);
       
   293 		}
       
   294 	else if (FileHandle())
       
   295 		{
       
   296 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileHandle(), KRefInstPrivateDir, iEmbeddedComponents);
       
   297 		}
       
   298 	else
       
   299 		{
       
   300 		ASSERT(0);
       
   301 		}
       
   302 	
       
   303 	// Connect to the SCR. The installer needs this session to check if a component being queried
       
   304 	// is already installed and, if yes, obtain its detials.
       
   305 	User::LeaveIfError(iScr.Connect());
       
   306 	}
       
   307 
       
   308 TInt CSifRefGetComponentInfoTask::ParsePkgFileL()
       
   309 	{
       
   310 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::ParsePkgFileL()"));
       
   311 	
       
   312 	delete iParser;
       
   313 	iParser = NULL;
       
   314 
       
   315 	// Check if the next component is of the type our installer supports. If yes, add it to the list of
       
   316 	// the components to be processed. If not, use the SIF API to obtain its details.
       
   317 	const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent];
       
   318 	if (node.Foreign())
       
   319 		{
       
   320 		// Connect to the SIF server
       
   321 		iComponentInfo = CComponentInfo::NewL();
       
   322 		User::LeaveIfError(iSif.Connect());
       
   323 
       
   324 		// Our installer keeps temporary files under its private folder and therefore we have to
       
   325 		// pass a file handle to the SIF API.
       
   326 		User::LeaveIfError(iFs.Connect());
       
   327 		iFs.ShareProtected();
       
   328 		User::LeaveIfError(iFile.Open(iFs, node.FileNameL(), EFileShareReadersOnly));
       
   329 
       
   330 		// Submit a SIF request 
       
   331 		iSif.GetComponentInfo(iFile, *iComponentInfo, *RequestStatus());
       
   332 		
       
   333 		iSifRequestInProgress = ETrue;
       
   334 
       
   335 		return ECreateComponentInfoNode;
       
   336 		}
       
   337 	else
       
   338 		{
       
   339 		iParser = CSifRefPkgParser::NewL(node.FileNameL());
       
   340 		return EFindComponent;
       
   341 		}
       
   342 	}
       
   343 
       
   344 TInt CSifRefGetComponentInfoTask::CreateComponentInfoNodeL()
       
   345 	{
       
   346 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::CreateComponentInfoNodeL()"));
       
   347 	
       
   348 	SifRefBinPkgExtractor::CAuxNode& auxNode = *iEmbeddedComponents[iCurrentComponent];
       
   349 
       
   350 	if (iSifRequestInProgress)
       
   351 		{
       
   352 		iSif.Close();
       
   353 		iFile.Close();
       
   354 		iFs.Close();
       
   355 		
       
   356 		iSifRequestInProgress = EFalse;
       
   357 		
       
   358 		// Add the root node of iComponentInfo to the tree
       
   359 		User::LeaveIfError(RequestStatus()->Int());
       
   360 		auxNode.SetCompInfoL(iComponentInfo);
       
   361 		iComponentInfo = NULL;
       
   362 		}
       
   363 	else
       
   364 		{
       
   365 		// This reference installer uses the KExampleFileSize const value to calculate the maximum size of the installed
       
   366 		// component on a phone. This is because the reference package file carries only the list of the files to be installed
       
   367 		// without the files themselves. A real installer should use the size of the files to be installed.
       
   368 		const TInt KExampleFileSize = 1024;
       
   369 		const TInt maxInstalledSize = iParser->Files().Count() * KExampleFileSize;
       
   370 		const TBool hasExe = EFalse;
       
   371 		// The example capabilities below are hardcoded due to the same reason. The reference package file doesn't contain
       
   372 		// user grantable capabilities but a real package file should provide them.
       
   373 		TCapabilitySet userGrantableCaps(ECapabilityReadUserData, ECapabilityWriteUserData);
       
   374 	
       
   375 		// Create a ComponentInfo node and set it as a root node.
       
   376 		CComponentInfo::CNode* compInfoNode = CComponentInfo::CNode::NewLC(InstallHelper::KSifReferenceSoftwareType,
       
   377 							*iCompSearchData.iName, iCompSearchData.iVersion, *iCompSearchData.iVendor,
       
   378 							iCompSearchData.iScomoState, iCompSearchData.iInstallStatus, iCompSearchData.iComponentId,
       
   379 							*iCompSearchData.iName, ENotAuthenticated, userGrantableCaps, maxInstalledSize, hasExe);
       
   380 		
       
   381 		auxNode.SetNodeL(compInfoNode);
       
   382 		CleanupStack::Pop(compInfoNode);
       
   383 		}
       
   384 	
       
   385 	return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ESetComponentInfo;
       
   386 	}
       
   387 
       
   388 void CSifRefGetComponentInfoTask::SetComponentInfoL()
       
   389 	{
       
   390 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::SetComponentInfoL()"));
       
   391 	
       
   392 	// At least one node must exist, otherwise we can't reach this point.
       
   393 	ASSERT (iEmbeddedComponents.Count() > 0);
       
   394 	
       
   395 	// Build a real tree of the nodes from iEmbeddedComponents which is a flat list
       
   396 	for (TInt i=iEmbeddedComponents.Count()-1; i>=1; --i)
       
   397 		{
       
   398 		iEmbeddedComponents[i]->RegisterChildToParentL();
       
   399 		}
       
   400 	
       
   401 	// Set the tree built above as the root node of ComponentInfo().
       
   402 	iEmbeddedComponents[0]->SetAsRootNodeL(*ComponentInfo());
       
   403 	}
       
   404 
       
   405 // =============================================================================================================
       
   406 
       
   407 CSifRefInstallTask* CSifRefInstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory)
       
   408 	{
       
   409 	DEBUG_PRINTF(_L8("CSifRefInstallTask::NewL()"));
       
   410 	
       
   411 	CSifRefInstallTask* self = new (ELeave) CSifRefInstallTask(aParams);
       
   412 	CleanupStack::PushL(self);
       
   413 	self->ConstructL(aUiHandlerFactory);
       
   414 	CleanupStack::Pop(self);
       
   415 	return self;
       
   416 	}
       
   417 
       
   418 CSifRefInstallTask::CSifRefInstallTask(TTransportTaskParams& aParams)
       
   419 : CSifTransportTask(aParams, EFalse), iStep(EExtractEmbeddedPkgs)
       
   420 	{
       
   421 	}
       
   422 
       
   423 CSifRefInstallTask::~CSifRefInstallTask()
       
   424 	{
       
   425 	DEBUG_PRINTF(_L8("CSifRefInstallTask::~CSifRefInstallTask()"));
       
   426 	
       
   427 	iFileList.Close();
       
   428 	iFile.Close();
       
   429 	iFs.Close();
       
   430 	iScr.Close();
       
   431 	iSts.Close();
       
   432 	iEmbeddedComponents.Close();
       
   433 	if (iSifRequestInProgress)
       
   434 		{
       
   435 		iSif.CancelOperation();
       
   436 		}
       
   437 	iSif.Close();
       
   438 	delete iParser;
       
   439 	delete iUiHandler;
       
   440 	delete iOpaqueArguments;
       
   441 	delete iOpaqueResults;
       
   442 	}
       
   443 
       
   444 void CSifRefInstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory)
       
   445 	{
       
   446 	if ((FileName() == NULL && FileHandle() == NULL) ||
       
   447 		CustomArguments() == NULL ||
       
   448 		CustomResults() == NULL)
       
   449 		{
       
   450 		User::Leave(KErrArgument);
       
   451 		}
       
   452 
       
   453 	iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory);
       
   454 	}
       
   455 
       
   456 TBool CSifRefInstallTask::ExecuteImplL()
       
   457 	{
       
   458 	DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   459 	
       
   460 	TBool done = EFalse;
       
   461 	
       
   462 	switch (iStep)
       
   463 		{
       
   464 		case EExtractEmbeddedPkgs:
       
   465 			ExtractEmbeddedPkgsL();
       
   466 			++iStep;
       
   467 			break;
       
   468 
       
   469 		case EParsePkgFile:
       
   470 			iStep = ParsePkgFileL();
       
   471 			break;
       
   472 
       
   473 		case ELaunchForeignInstall:
       
   474 			LaunchForeignInstallL();
       
   475 			++iStep;
       
   476 			break;
       
   477 
       
   478 		case EFinishForeignInstall:
       
   479 			FinishForeignInstallL();
       
   480 			iStep = EParsePkgFile;
       
   481 			break;
       
   482 
       
   483 		case EFindAndCheckComponent:
       
   484 			// Next step differs for ENewComponent and EUpgrade
       
   485 			iStep = FindAndCheckComponentL();
       
   486 			break;
       
   487 
       
   488 		case EGetInstalledFileList:
       
   489 			GetInstalledFileListL();
       
   490 			++iStep;
       
   491 			break;
       
   492 
       
   493 		case EUnregisterAndDeleteFile:
       
   494 			if (UnregisterAndDeleteFileL())
       
   495 				{
       
   496 				++iStep;
       
   497 				}
       
   498 			break;
       
   499 
       
   500 		case ERegisterComponent:
       
   501 			RegisterComponentL();
       
   502 			++iStep;
       
   503 			break;
       
   504 
       
   505 		case ECopyFile:
       
   506 			if (CopyFileL())
       
   507 				{
       
   508 				++iStep;
       
   509 				}
       
   510 			break;
       
   511 
       
   512 		case ESetScomoState:
       
   513 			iStep = SetScomoStateL();
       
   514 			break;
       
   515 
       
   516 		case ECommit:
       
   517 			CommitL();
       
   518 			done = ETrue;
       
   519 			break;
       
   520 
       
   521 		default:
       
   522 			User::Leave(KErrGeneral);
       
   523 		}
       
   524 
       
   525 	if (!iSifRequestInProgress)
       
   526 		{
       
   527 		TRequestStatus* status(RequestStatus());
       
   528 		User::RequestComplete(status, KErrNone);
       
   529 		}
       
   530 	
       
   531 	DEBUG_PRINTF3(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), done = %d, iStep = %d"), done, iStep);
       
   532 	
       
   533 	return done;
       
   534 	}
       
   535 
       
   536 namespace
       
   537 	{
       
   538 	TInt AuxNodeSorter(const SifRefBinPkgExtractor::CAuxNode& aLeft, const SifRefBinPkgExtractor::CAuxNode& aRight)
       
   539 		{
       
   540 		const TBool l = aLeft.Foreign();
       
   541 		const TBool r = aRight.Foreign();
       
   542 		if (l == r)
       
   543 			{
       
   544 			return 0;
       
   545 			}
       
   546 		else if (!l && r)
       
   547 			{
       
   548 			return 1;
       
   549 			}
       
   550 		else
       
   551 			{
       
   552 			return -1;
       
   553 			}
       
   554 		}
       
   555 	}
       
   556 
       
   557 void CSifRefInstallTask::ExtractEmbeddedPkgsL()
       
   558 	{
       
   559 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ExtractEmbeddedPkgsL()"));
       
   560 	
       
   561 	// Start an STS transaction
       
   562 	iSts.CreateTransactionL();
       
   563 
       
   564 	if (FileName())
       
   565 		{
       
   566 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileName(), KRefInstPrivateDir, iEmbeddedComponents);
       
   567 		}
       
   568 	else if (FileHandle())
       
   569 		{
       
   570 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileHandle(), KRefInstPrivateDir, iEmbeddedComponents);
       
   571 		}
       
   572 	else
       
   573 		{
       
   574 		ASSERT(0);
       
   575 		}
       
   576 	
       
   577 	// Sort the list of the embedded components in order to install foreign packages first
       
   578 	 const TLinearOrder<SifRefBinPkgExtractor::CAuxNode> sortOrder(AuxNodeSorter);
       
   579 	iEmbeddedComponents.Sort(sortOrder);
       
   580 	}
       
   581 
       
   582 TInt CSifRefInstallTask::ParsePkgFileL()
       
   583 	{
       
   584 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileL()"));
       
   585 	
       
   586 	TInt nextStep = -1;
       
   587 	TRAPD(err, nextStep = ParsePkgFileImplL());
       
   588 	if (err != KErrNone)
       
   589 		{
       
   590 		if (iUiHandler)
       
   591 			{
       
   592 			iUiHandler->ErrorDescriptionUIHandler(InstallHelper::KUiParserErrorDesc);
       
   593 			}
       
   594 		User::Leave(err);
       
   595 		}
       
   596 	
       
   597 	return nextStep;
       
   598 	}
       
   599 
       
   600 TInt CSifRefInstallTask::ParsePkgFileImplL()
       
   601 	{
       
   602 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileImplL()"));
       
   603 	
       
   604 	delete iParser;
       
   605 	iParser = NULL;
       
   606 
       
   607 	// Check if the next component is of the type our installer supports. If yes, add it to the list of
       
   608 	// the components to be processed. If not, use the SIF API to install it.
       
   609 	const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent];
       
   610 	if (node.Foreign())
       
   611 		{
       
   612 		return ELaunchForeignInstall;
       
   613 		}
       
   614 	else
       
   615 		{
       
   616 		iParser = CSifRefPkgParser::NewL(node.FileNameL());
       
   617 		return EFindAndCheckComponent;
       
   618 		}
       
   619 	}
       
   620 
       
   621 void CSifRefInstallTask::LaunchForeignInstallL()
       
   622 	{
       
   623 	DEBUG_PRINTF(_L8("CSifRefInstallTask::LaunchForeignInstallL()"));
       
   624 	
       
   625 	const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent];
       
   626 	
       
   627 	// Connect to the SIF server
       
   628 	User::LeaveIfError(iSif.Connect());
       
   629 
       
   630 	// Our installer keeps temporary files under its private folder and therefore we have to
       
   631 	// pass a file handle to the SIF API.
       
   632 	User::LeaveIfError(iFs.Connect());
       
   633 	iFs.ShareProtected();
       
   634 	User::LeaveIfError(iFile.Open(iFs, node.FileNameL(), EFileShareReadersOnly));
       
   635 
       
   636 	// Submit a SIF request 
       
   637 	iOpaqueArguments = COpaqueNamedParams::NewL();
       
   638 	iOpaqueResults = COpaqueNamedParams::NewL();
       
   639 	iSif.Install(iFile, *iOpaqueArguments, *iOpaqueResults, *RequestStatus(), EFalse);
       
   640 
       
   641 	iSifRequestInProgress = ETrue;
       
   642 	}
       
   643 
       
   644 void CSifRefInstallTask::FinishForeignInstallL()
       
   645 	{
       
   646 	DEBUG_PRINTF(_L8("CSifRefInstallTask::FinishForeignInstallL()"));
       
   647 	
       
   648 	iSif.Close();
       
   649 	iFile.Close();
       
   650 	iFs.Close();
       
   651 	delete iOpaqueArguments;
       
   652 	iOpaqueArguments = NULL;
       
   653 	delete iOpaqueResults;
       
   654 	iOpaqueResults = NULL;
       
   655 	
       
   656 	// Check the result of the concurrent installation
       
   657 	iSifRequestInProgress = EFalse;
       
   658 	User::LeaveIfError(RequestStatus()->Int());
       
   659 	
       
   660 	// There must be at least one component left because we install foreign components first
       
   661 	++iCurrentComponent;
       
   662 	}
       
   663 
       
   664 TInt CSifRefInstallTask::FindAndCheckComponentL()
       
   665 	{
       
   666 	DEBUG_PRINTF(_L8("CSifRefInstallTask::FindAndCheckComponentL()"));
       
   667 	
       
   668 	// Connect to the SCR and create a new transaction to continue the installation of our own type
       
   669 	if (!iScrTransaction)
       
   670 		{
       
   671 		User::LeaveIfError(iScr.Connect());
       
   672 		iScr.CreateTransactionL();
       
   673 		iScrTransaction = ETrue;
       
   674 		}
       
   675 	
       
   676 	// Exit code
       
   677 	TInt nextStep = ERegisterComponent;
       
   678 	
       
   679 	// Check if already installed
       
   680 	InstallHelper::FindComponentL(iScr, iCompSearchData, *iParser);
       
   681 	switch (iCompSearchData.iInstallStatus)
       
   682 		{
       
   683 		case ENewComponent:
       
   684 			// nextStep already set to ERegisterComponent
       
   685 			break;
       
   686 
       
   687 		case EUpgrade:
       
   688 			// Uninstall the previous version
       
   689 			nextStep = EGetInstalledFileList;
       
   690 			break;
       
   691 
       
   692 		case EAlreadyInstalled:
       
   693 			User::Leave(KErrSifSameVersionAlreadyInstalled);
       
   694 			break;
       
   695 
       
   696 		case ENewerVersionAlreadyInstalled:
       
   697 			User::Leave(KErrSifNewerVersionAlreadyInstalled);
       
   698 			break;
       
   699 
       
   700 		default:
       
   701 			ASSERT(0);
       
   702 		}
       
   703 
       
   704 	// Ask the user for the confirmation
       
   705 	if (iUiHandler != NULL)
       
   706 		{
       
   707 		userConfirmationL(iCompSearchData.iInstallStatus == ENewComponent ? InstallHelper::EConfirmationInstall : InstallHelper::EConfirmationUpgrade, *iUiHandler, *iCompSearchData.iName, *iCompSearchData.iVendor);
       
   708 		}
       
   709 
       
   710 	return nextStep;
       
   711 	}
       
   712 
       
   713 void CSifRefInstallTask::GetInstalledFileListL()
       
   714 	{
       
   715 	DEBUG_PRINTF(_L8("CSifRefInstallTask::GetInstalledFileListL()"));
       
   716 	
       
   717 	// Get a list of files to be deleted
       
   718 	iFileList.OpenListL(iScr, iCompSearchData.iComponentId);
       
   719 	}
       
   720 
       
   721 TBool CSifRefInstallTask::UnregisterAndDeleteFileL()
       
   722 	{
       
   723 	DEBUG_PRINTF(_L8("CSifRefInstallTask::UnregisterAndDeleteFileL()"));
       
   724 	
       
   725 	return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, iCompSearchData.iComponentId);
       
   726 	}
       
   727 
       
   728 void CSifRefInstallTask::RegisterComponentL()
       
   729 	{
       
   730 	DEBUG_PRINTF(_L8("CSifRefInstallTask::RegisterComponentL()"));
       
   731 	
       
   732 	// Register a new component in the SCR
       
   733 	RCPointerArray<CLocalizableComponentInfo> componentInfoArray;
       
   734 	CleanupClosePushL(componentInfoArray);
       
   735 
       
   736 	// ...for each language
       
   737 	const RLanguageArray& languages = iParser->Languages();
       
   738 	const TInt langCount = languages.Count();
       
   739 	for (TInt i=0; i<langCount; ++i)
       
   740 		{
       
   741 		const TDesC& locName = *iParser->ComponentNames()[i];
       
   742 		const TDesC& locVendor = *iParser->VendorNames()[i];
       
   743 		CLocalizableComponentInfo* componentInfo = CLocalizableComponentInfo::NewLC(locName, locVendor, languages[i]);
       
   744 		componentInfoArray.AppendL(componentInfo);
       
   745 		CleanupStack::Pop(componentInfo);
       
   746 		}
       
   747 	iCompSearchData.iComponentId = iScr.AddComponentL(componentInfoArray, InstallHelper::KSifReferenceSoftwareType);
       
   748 
       
   749 	// Set the version of a new component
       
   750 	iScr.SetComponentVersionL(iCompSearchData.iComponentId, iCompSearchData.iVersion);
       
   751 
       
   752 	CleanupStack::PopAndDestroy(&componentInfoArray);
       
   753 
       
   754 	iCopyFileIndex = 0;
       
   755 	iComponentSize = 0;
       
   756 	
       
   757 	// Send the id if the installed component to the client. If this is a compound package we send the id of the root component only.
       
   758 	if (iEmbeddedComponents[iCurrentComponent]->Root())
       
   759 		{
       
   760 		CustomResults()->AddIntL(KSifOutParam_ComponentId, iCompSearchData.iComponentId);
       
   761 		}
       
   762 	}
       
   763 
       
   764 namespace
       
   765 	{
       
   766 	TBool CheckPathExistenceL(const TDesC& filePath)
       
   767 		{
       
   768 		TBool exists = EFalse;
       
   769 
       
   770 		RFs fs;
       
   771 		User::LeaveIfError(fs.Connect());
       
   772 		CleanupClosePushL(fs);
       
   773 		TEntry entry;
       
   774 		TInt error = fs.Entry(filePath, entry);
       
   775 		if (error == KErrNone)
       
   776 			{
       
   777 			exists = ETrue;
       
   778 			}
       
   779 		else if (error != KErrPathNotFound && error != KErrNotFound)
       
   780 			{
       
   781 			User::Leave(error);
       
   782 			}
       
   783 		
       
   784 		CleanupStack::PopAndDestroy(&fs);
       
   785 		
       
   786 		return exists;
       
   787 		}
       
   788 	}
       
   789 
       
   790 TBool CSifRefInstallTask::CopyFileL()
       
   791 	{
       
   792 	DEBUG_PRINTF(_L8("CSifRefInstallTask::CopyFileL()"));
       
   793 	
       
   794 	// List of files to be copied from a package file 
       
   795 	const RCHBufCArray& files = iParser->Files();
       
   796 
       
   797 	// Register and copy a file if any left
       
   798 	if (iCopyFileIndex < files.Count())
       
   799 		{
       
   800 		// The name of the current file
       
   801 		const TDesC& filePath = *files[iCopyFileIndex];
       
   802 
       
   803 		// Check if filePath already exists
       
   804 		if (CheckPathExistenceL(filePath))
       
   805 			{
       
   806 			// Add a custom result describing the error
       
   807 			HBufC* desc = HBufC::NewLC(InstallHelper::KErrFileAlreadyExists.iTypeLength + filePath.Length());
       
   808 			TPtr bufDesc = desc->Des();
       
   809 			bufDesc.Copy(InstallHelper::KErrFileAlreadyExists);
       
   810 			bufDesc.Copy(filePath);
       
   811 			CustomResults()->AddStringL(InstallHelper::KParamNameErrDesc, *desc);
       
   812 			CleanupStack::PopAndDestroy(desc);
       
   813 			}
       
   814 
       
   815 		// Register the file in the SCR
       
   816 		iScr.RegisterComponentFileL(iCompSearchData.iComponentId, filePath);
       
   817 
       
   818 		// Copy the current file
       
   819 		RFile file;
       
   820 		iSts.CreateNewL(filePath, file, TFileMode(EFileShareExclusive |EFileWrite));
       
   821 		_LIT8(KReferenceFootprint, "This file belongs to the SIF reference component.\n");
       
   822 		const TInt numLines = 100; // The operation must take a while to simulate real copying
       
   823 		for (TInt i=0; i<numLines; ++i)
       
   824 			{
       
   825 			User::LeaveIfError(file.Write(KReferenceFootprint));
       
   826 			}
       
   827 		iComponentSize += KReferenceFootprint.iTypeLength*numLines;
       
   828 		file.Close();
       
   829 
       
   830 		++iCopyFileIndex;
       
   831 		}
       
   832 	else
       
   833 		{
       
   834 		// Set the size of the component in the SCR
       
   835 		iScr.SetComponentSizeL(iCompSearchData.iComponentId, iComponentSize);
       
   836 
       
   837 		// Step complete, all the files have been copied
       
   838 		return ETrue;
       
   839 		}
       
   840 
       
   841 	// Step not complete, there are still files left
       
   842 	
       
   843 	DEBUG_PRINTF(_L8("Exiting from CSifRefInstallTask::CopyFileL()"));
       
   844 	
       
   845 	return EFalse;
       
   846 	}
       
   847 
       
   848 TInt CSifRefInstallTask::SetScomoStateL()
       
   849 	{
       
   850 	DEBUG_PRINTF(_L8("CSifRefInstallTask::SetScomoStateL()"));
       
   851 	
       
   852 	// Activate the newly added component
       
   853 	TInt inactive = EFalse;
       
   854 	if (!CustomArguments()->GetIntByNameL(_L("InstallInactive"), inactive) || !inactive)
       
   855 		{
       
   856 		iScr.SetScomoStateL(iCompSearchData.iComponentId, EActivated);
       
   857 		}
       
   858 	
       
   859 	// Check if there are any components to be installed left
       
   860 	return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ECommit;
       
   861 	}
       
   862 
       
   863 void CSifRefInstallTask::CommitL()
       
   864 	{
       
   865 	DEBUG_PRINTF(_L8("CSifRefInstallTask::CommitL()"));
       
   866 	
       
   867 	// Commit the STS & SCR transactions
       
   868 	iSts.CommitL();
       
   869 	iScr.CommitTransactionL();
       
   870 	}
       
   871 
       
   872 // =============================================================================================================
       
   873 
       
   874 CSifRefUninstallTask* CSifRefUninstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory)
       
   875 	{
       
   876 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::NewL()"));
       
   877 	
       
   878 	CSifRefUninstallTask* self = new (ELeave) CSifRefUninstallTask(aParams);
       
   879 	CleanupStack::PushL(self);
       
   880 	self->ConstructL(aUiHandlerFactory);
       
   881 	CleanupStack::Pop(self);
       
   882 	return self;
       
   883 	}
       
   884 
       
   885 CSifRefUninstallTask::CSifRefUninstallTask(TTransportTaskParams& aParams)
       
   886 : CSifTransportTask(aParams), iStep(EGetFileList)
       
   887 	{
       
   888 	}
       
   889 
       
   890 void CSifRefUninstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory)
       
   891 	{
       
   892 	if (ComponentId() == NULL || CustomArguments() == NULL || CustomResults() == NULL)
       
   893 		{
       
   894 		User::Leave(KErrArgument);
       
   895 		}
       
   896 
       
   897 	iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory);
       
   898 	}
       
   899 
       
   900 CSifRefUninstallTask::~CSifRefUninstallTask()
       
   901 	{
       
   902 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::~CSifRefUninstallTask()"));
       
   903 	
       
   904 	// Make sure to close sub-session before the session
       
   905 	iFileList.Close();	
       
   906 	iScr.Close();
       
   907 	iSts.Close();
       
   908 	delete iUiHandler;
       
   909 	}
       
   910 
       
   911 TBool CSifRefUninstallTask::ExecuteImplL()
       
   912 	{
       
   913 	DEBUG_PRINTF2(_L8("CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   914 	
       
   915 	switch (iStep)
       
   916 		{
       
   917 		case EGetFileList:
       
   918 			GetFileListL();
       
   919 			break;
       
   920 
       
   921 		case EUnregisterAndDeleteFile:
       
   922 			if (!UnregisterAndDeleteFileL())
       
   923 				{
       
   924 				return EFalse;
       
   925 				}
       
   926 			break;
       
   927 
       
   928 		case ECommit:
       
   929 			CommitL();
       
   930 			return ETrue;
       
   931 
       
   932 		default:
       
   933 			User::Leave(KErrGeneral);
       
   934 		}
       
   935 
       
   936 	++iStep;
       
   937 
       
   938 	DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   939 	
       
   940 	return EFalse;
       
   941 	}
       
   942 
       
   943 void CSifRefUninstallTask::GetFileListL()
       
   944 	{
       
   945 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::GetFileListL()"));
       
   946 	
       
   947 	// Connect to the SCR and start a transaction
       
   948 	User::LeaveIfError(iScr.Connect());
       
   949 	iScr.CreateTransactionL();
       
   950 
       
   951 	// Ask the user for confirmation
       
   952 	if (iUiHandler != NULL)
       
   953 		{
       
   954 		CComponentEntry* entry = CComponentEntry::NewLC();
       
   955 		if (!iScr.GetComponentL(ComponentId(), *entry))
       
   956 			{
       
   957 			User::Leave(KErrNotFound);
       
   958 			}
       
   959 		userConfirmationL(InstallHelper::EConfirmationUninstall, *iUiHandler, entry->Name(), entry->Vendor());
       
   960 		CleanupStack::PopAndDestroy(entry);
       
   961 		}
       
   962 
       
   963 	// Get a list of files to be deleted
       
   964 	iFileList.OpenListL(iScr, ComponentId());
       
   965 
       
   966 	// Start an STS transaction
       
   967 	iSts.CreateTransactionL();
       
   968 	}
       
   969 
       
   970 TBool CSifRefUninstallTask::UnregisterAndDeleteFileL()
       
   971 	{
       
   972 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::UnregisterAndDeleteFileL()"));
       
   973 	
       
   974 	return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, ComponentId());
       
   975 	}
       
   976 
       
   977 void CSifRefUninstallTask::CommitL()
       
   978 	{
       
   979 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::CommitL()"));
       
   980 	
       
   981 	// Commit the STS & SCR transactions
       
   982 	iSts.CommitL();
       
   983 	iScr.CommitTransactionL();
       
   984 	}
       
   985 
       
   986 // =============================================================================================================
       
   987 
       
   988 CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask(TTransportTaskParams& aParams, TScomoState aScomoState)
       
   989 : CSifTransportTask(aParams), iScomoState(aScomoState)
       
   990 	{
       
   991 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask()"));
       
   992 	}
       
   993 
       
   994 CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask()
       
   995 	{
       
   996 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask()"));
       
   997 	
       
   998 	iScr.Close();
       
   999 	}
       
  1000 
       
  1001 TBool CSifRefActivateDeactivateTask::ExecuteImplL()
       
  1002 	{
       
  1003 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::ExecuteImplL()"));
       
  1004 	
       
  1005 	if (ComponentId() == NULL)
       
  1006 		{
       
  1007 		User::Leave(KErrArgument);
       
  1008 		}
       
  1009 
       
  1010 	// Connect to SCR and activate/deactivate component
       
  1011 	User::LeaveIfError(iScr.Connect());
       
  1012 	iScr.SetScomoStateL(ComponentId(), iScomoState);
       
  1013 
       
  1014 	return ETrue;
       
  1015 	}