installationservices/refswinstallationplugin/source/sifrefinstallertask.cpp
branchRCL_3
changeset 26 8b7f4e561641
parent 25 7333d7932ef7
child 27 e8965914fac7
equal deleted inserted replaced
25:7333d7932ef7 26:8b7f4e561641
     1 /*
       
     2 * Copyright (c) 2008-2010 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 		const TBool driveSelectionRequired = EFalse;
       
   372 		RPointerArray<Usif::CComponentInfo::CApplicationInfo>* applications = NULL;
       
   373 		// The example capabilities below are hardcoded due to the same reason. The reference package file doesn't contain
       
   374 		// user grantable capabilities but a real package file should provide them.
       
   375 		TCapabilitySet userGrantableCaps(ECapabilityReadUserData, ECapabilityWriteUserData);
       
   376 	
       
   377 		// Create a ComponentInfo node and set it as a root node.
       
   378 		CComponentInfo::CNode* compInfoNode = CComponentInfo::CNode::NewLC(InstallHelper::KSifReferenceSoftwareType,
       
   379 							*iCompSearchData.iName, iCompSearchData.iVersion, *iCompSearchData.iVendor,
       
   380 							iCompSearchData.iScomoState, iCompSearchData.iInstallStatus, iCompSearchData.iComponentId,
       
   381 							*iCompSearchData.iName, ENotAuthenticated, userGrantableCaps, maxInstalledSize, hasExe, driveSelectionRequired, applications);
       
   382 		
       
   383 		auxNode.SetNodeL(compInfoNode);
       
   384 		CleanupStack::Pop(compInfoNode);
       
   385 		}
       
   386 	
       
   387 	return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ESetComponentInfo;
       
   388 	}
       
   389 
       
   390 void CSifRefGetComponentInfoTask::SetComponentInfoL()
       
   391 	{
       
   392 	DEBUG_PRINTF(_L8("CSifRefGetComponentInfoTask::SetComponentInfoL()"));
       
   393 	
       
   394 	// At least one node must exist, otherwise we can't reach this point.
       
   395 	ASSERT (iEmbeddedComponents.Count() > 0);
       
   396 	
       
   397 	// Build a real tree of the nodes from iEmbeddedComponents which is a flat list
       
   398 	for (TInt i=iEmbeddedComponents.Count()-1; i>=1; --i)
       
   399 		{
       
   400 		iEmbeddedComponents[i]->RegisterChildToParentL();
       
   401 		}
       
   402 	
       
   403 	// Set the tree built above as the root node of ComponentInfo().
       
   404 	iEmbeddedComponents[0]->SetAsRootNodeL(*ComponentInfo());
       
   405 	}
       
   406 
       
   407 // =============================================================================================================
       
   408 
       
   409 CSifRefInstallTask* CSifRefInstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory)
       
   410 	{
       
   411 	DEBUG_PRINTF(_L8("CSifRefInstallTask::NewL()"));
       
   412 	
       
   413 	CSifRefInstallTask* self = new (ELeave) CSifRefInstallTask(aParams);
       
   414 	CleanupStack::PushL(self);
       
   415 	self->ConstructL(aUiHandlerFactory);
       
   416 	CleanupStack::Pop(self);
       
   417 	return self;
       
   418 	}
       
   419 
       
   420 CSifRefInstallTask::CSifRefInstallTask(TTransportTaskParams& aParams)
       
   421 : CSifTransportTask(aParams, EFalse), iStep(EExtractEmbeddedPkgs)
       
   422 	{
       
   423 	}
       
   424 
       
   425 CSifRefInstallTask::~CSifRefInstallTask()
       
   426 	{
       
   427 	DEBUG_PRINTF(_L8("CSifRefInstallTask::~CSifRefInstallTask()"));
       
   428 	
       
   429 	iFileList.Close();
       
   430 	iFile.Close();
       
   431 	iFs.Close();
       
   432 	iScr.Close();
       
   433 	iSts.Close();
       
   434 	iEmbeddedComponents.Close();
       
   435 	if (iSifRequestInProgress)
       
   436 		{
       
   437 		iSif.CancelOperation();
       
   438 		}
       
   439 	iSif.Close();
       
   440 	delete iParser;
       
   441 	delete iUiHandler;
       
   442 	delete iOpaqueArguments;
       
   443 	delete iOpaqueResults;
       
   444 	}
       
   445 
       
   446 void CSifRefInstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory)
       
   447 	{
       
   448 	if ((FileName() == NULL && FileHandle() == NULL) ||
       
   449 		CustomArguments() == NULL ||
       
   450 		CustomResults() == NULL)
       
   451 		{
       
   452 		User::Leave(KErrArgument);
       
   453 		}
       
   454 
       
   455 	iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory);
       
   456 	}
       
   457 
       
   458 TBool CSifRefInstallTask::ExecuteImplL()
       
   459 	{
       
   460 	DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   461 	
       
   462 	TBool done = EFalse;
       
   463 	
       
   464 	switch (iStep)
       
   465 		{
       
   466 		case EExtractEmbeddedPkgs:
       
   467 			ExtractEmbeddedPkgsL();
       
   468 			++iStep;
       
   469 			break;
       
   470 
       
   471 		case EParsePkgFile:
       
   472 			iStep = ParsePkgFileL();
       
   473 			break;
       
   474 
       
   475 		case ELaunchForeignInstall:
       
   476 			LaunchForeignInstallL();
       
   477 			++iStep;
       
   478 			break;
       
   479 
       
   480 		case EFinishForeignInstall:
       
   481 			FinishForeignInstallL();
       
   482 			iStep = EParsePkgFile;
       
   483 			break;
       
   484 
       
   485 		case EFindAndCheckComponent:
       
   486 			// Next step differs for ENewComponent and EUpgrade
       
   487 			iStep = FindAndCheckComponentL();
       
   488 			break;
       
   489 
       
   490 		case EGetInstalledFileList:
       
   491 			GetInstalledFileListL();
       
   492 			++iStep;
       
   493 			break;
       
   494 
       
   495 		case EUnregisterAndDeleteFile:
       
   496 			if (UnregisterAndDeleteFileL())
       
   497 				{
       
   498 				++iStep;
       
   499 				}
       
   500 			break;
       
   501 
       
   502 		case ERegisterComponent:
       
   503 			RegisterComponentL();
       
   504 			++iStep;
       
   505 			break;
       
   506 
       
   507 		case ECopyFile:
       
   508 			if (CopyFileL())
       
   509 				{
       
   510 				++iStep;
       
   511 				}
       
   512 			break;
       
   513 
       
   514 		case ESetScomoState:
       
   515 			iStep = SetScomoStateL();
       
   516 			break;
       
   517 
       
   518 		case ECommit:
       
   519 			CommitL();
       
   520 			done = ETrue;
       
   521 			break;
       
   522 
       
   523 		default:
       
   524 			User::Leave(KErrGeneral);
       
   525 		}
       
   526 
       
   527 	if (!iSifRequestInProgress)
       
   528 		{
       
   529 		TRequestStatus* status(RequestStatus());
       
   530 		User::RequestComplete(status, KErrNone);
       
   531 		}
       
   532 	
       
   533 	DEBUG_PRINTF3(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), done = %d, iStep = %d"), done, iStep);
       
   534 	
       
   535 	return done;
       
   536 	}
       
   537 
       
   538 namespace
       
   539 	{
       
   540 	TInt AuxNodeSorter(const SifRefBinPkgExtractor::CAuxNode& aLeft, const SifRefBinPkgExtractor::CAuxNode& aRight)
       
   541 		{
       
   542 		const TBool l = aLeft.Foreign();
       
   543 		const TBool r = aRight.Foreign();
       
   544 		if (l == r)
       
   545 			{
       
   546 			return 0;
       
   547 			}
       
   548 		else if (!l && r)
       
   549 			{
       
   550 			return 1;
       
   551 			}
       
   552 		else
       
   553 			{
       
   554 			return -1;
       
   555 			}
       
   556 		}
       
   557 	}
       
   558 
       
   559 void CSifRefInstallTask::ExtractEmbeddedPkgsL()
       
   560 	{
       
   561 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ExtractEmbeddedPkgsL()"));
       
   562 	
       
   563 	// Start an STS transaction
       
   564 	iSts.CreateTransactionL();
       
   565 
       
   566 	if (FileName())
       
   567 		{
       
   568 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileName(), KRefInstPrivateDir, iEmbeddedComponents);
       
   569 		}
       
   570 	else if (FileHandle())
       
   571 		{
       
   572 		SifRefBinPkgExtractor::BuildPkgTreeL(iSts, *FileHandle(), KRefInstPrivateDir, iEmbeddedComponents);
       
   573 		}
       
   574 	else
       
   575 		{
       
   576 		ASSERT(0);
       
   577 		}
       
   578 	
       
   579 	// Sort the list of the embedded components in order to install foreign packages first
       
   580 	 const TLinearOrder<SifRefBinPkgExtractor::CAuxNode> sortOrder(AuxNodeSorter);
       
   581 	iEmbeddedComponents.Sort(sortOrder);
       
   582 	}
       
   583 
       
   584 TInt CSifRefInstallTask::ParsePkgFileL()
       
   585 	{
       
   586 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileL()"));
       
   587 	
       
   588 	TInt nextStep = -1;
       
   589 	TRAPD(err, nextStep = ParsePkgFileImplL());
       
   590 	if (err != KErrNone)
       
   591 		{
       
   592 		if (iUiHandler)
       
   593 			{
       
   594 			iUiHandler->ErrorDescriptionUIHandler(InstallHelper::KUiParserErrorDesc);
       
   595 			}
       
   596 		User::Leave(err);
       
   597 		}
       
   598 	
       
   599 	return nextStep;
       
   600 	}
       
   601 
       
   602 TInt CSifRefInstallTask::ParsePkgFileImplL()
       
   603 	{
       
   604 	DEBUG_PRINTF(_L8("CSifRefInstallTask::ParsePkgFileImplL()"));
       
   605 	
       
   606 	delete iParser;
       
   607 	iParser = NULL;
       
   608 
       
   609 	// Check if the next component is of the type our installer supports. If yes, add it to the list of
       
   610 	// the components to be processed. If not, use the SIF API to install it.
       
   611 	const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent];
       
   612 	if (node.Foreign())
       
   613 		{
       
   614 		return ELaunchForeignInstall;
       
   615 		}
       
   616 	else
       
   617 		{
       
   618 		iParser = CSifRefPkgParser::NewL(node.FileNameL());
       
   619 		return EFindAndCheckComponent;
       
   620 		}
       
   621 	}
       
   622 
       
   623 void CSifRefInstallTask::LaunchForeignInstallL()
       
   624 	{
       
   625 	DEBUG_PRINTF(_L8("CSifRefInstallTask::LaunchForeignInstallL()"));
       
   626 	
       
   627 	const SifRefBinPkgExtractor::CAuxNode& node = *iEmbeddedComponents[iCurrentComponent];
       
   628 	
       
   629 	// Connect to the SIF server
       
   630 	User::LeaveIfError(iSif.Connect());
       
   631 
       
   632 	// Our installer keeps temporary files under its private folder and therefore we have to
       
   633 	// pass a file handle to the SIF API.
       
   634 	User::LeaveIfError(iFs.Connect());
       
   635 	iFs.ShareProtected();
       
   636 	User::LeaveIfError(iFile.Open(iFs, node.FileNameL(), EFileShareReadersOnly));
       
   637 
       
   638 	// Submit a SIF request 
       
   639 	iOpaqueArguments = COpaqueNamedParams::NewL();
       
   640 	iOpaqueResults = COpaqueNamedParams::NewL();
       
   641 	iSif.Install(iFile, *iOpaqueArguments, *iOpaqueResults, *RequestStatus(), EFalse);
       
   642 
       
   643 	iSifRequestInProgress = ETrue;
       
   644 	}
       
   645 
       
   646 void CSifRefInstallTask::FinishForeignInstallL()
       
   647 	{
       
   648 	DEBUG_PRINTF(_L8("CSifRefInstallTask::FinishForeignInstallL()"));
       
   649 	
       
   650 	iSif.Close();
       
   651 	iFile.Close();
       
   652 	iFs.Close();
       
   653 	delete iOpaqueArguments;
       
   654 	iOpaqueArguments = NULL;
       
   655 	delete iOpaqueResults;
       
   656 	iOpaqueResults = NULL;
       
   657 	
       
   658 	// Check the result of the concurrent installation
       
   659 	iSifRequestInProgress = EFalse;
       
   660 	User::LeaveIfError(RequestStatus()->Int());
       
   661 	
       
   662 	// There must be at least one component left because we install foreign components first
       
   663 	++iCurrentComponent;
       
   664 	}
       
   665 
       
   666 TInt CSifRefInstallTask::FindAndCheckComponentL()
       
   667 	{
       
   668 	DEBUG_PRINTF(_L8("CSifRefInstallTask::FindAndCheckComponentL()"));
       
   669 	
       
   670 	// Connect to the SCR and create a new transaction to continue the installation of our own type
       
   671 	if (!iScrTransaction)
       
   672 		{
       
   673 		User::LeaveIfError(iScr.Connect());
       
   674 		iScr.CreateTransactionL();
       
   675 		iScrTransaction = ETrue;
       
   676 		}
       
   677 	
       
   678 	// Exit code
       
   679 	TInt nextStep = ERegisterComponent;
       
   680 	
       
   681 	// Check if already installed
       
   682 	InstallHelper::FindComponentL(iScr, iCompSearchData, *iParser);
       
   683 	switch (iCompSearchData.iInstallStatus)
       
   684 		{
       
   685 		case ENewComponent:
       
   686 			// nextStep already set to ERegisterComponent
       
   687 			break;
       
   688 
       
   689 		case EUpgrade:
       
   690 			// Uninstall the previous version
       
   691 			nextStep = EGetInstalledFileList;
       
   692 			break;
       
   693 
       
   694 		case EAlreadyInstalled:
       
   695 			User::Leave(KErrSifSameVersionAlreadyInstalled);
       
   696 			break;
       
   697 
       
   698 		case ENewerVersionAlreadyInstalled:
       
   699 			User::Leave(KErrSifNewerVersionAlreadyInstalled);
       
   700 			break;
       
   701 
       
   702 		default:
       
   703 			ASSERT(0);
       
   704 		}
       
   705 
       
   706 	// Ask the user for the confirmation
       
   707 	if (iUiHandler != NULL)
       
   708 		{
       
   709 		userConfirmationL(iCompSearchData.iInstallStatus == ENewComponent ? InstallHelper::EConfirmationInstall : InstallHelper::EConfirmationUpgrade, *iUiHandler, *iCompSearchData.iName, *iCompSearchData.iVendor);
       
   710 		}
       
   711 
       
   712 	return nextStep;
       
   713 	}
       
   714 
       
   715 void CSifRefInstallTask::GetInstalledFileListL()
       
   716 	{
       
   717 	DEBUG_PRINTF(_L8("CSifRefInstallTask::GetInstalledFileListL()"));
       
   718 	
       
   719 	// Get a list of files to be deleted
       
   720 	iFileList.OpenListL(iScr, iCompSearchData.iComponentId);
       
   721 	}
       
   722 
       
   723 TBool CSifRefInstallTask::UnregisterAndDeleteFileL()
       
   724 	{
       
   725 	DEBUG_PRINTF(_L8("CSifRefInstallTask::UnregisterAndDeleteFileL()"));
       
   726 	
       
   727 	return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, iCompSearchData.iComponentId);
       
   728 	}
       
   729 
       
   730 void CSifRefInstallTask::RegisterComponentL()
       
   731 	{
       
   732 	DEBUG_PRINTF(_L8("CSifRefInstallTask::RegisterComponentL()"));
       
   733 	
       
   734 	// Register a new component in the SCR
       
   735 	RCPointerArray<CLocalizableComponentInfo> componentInfoArray;
       
   736 	CleanupClosePushL(componentInfoArray);
       
   737 
       
   738 	// ...for each language
       
   739 	const RLanguageArray& languages = iParser->Languages();
       
   740 	const TInt langCount = languages.Count();
       
   741 	for (TInt i=0; i<langCount; ++i)
       
   742 		{
       
   743 		const TDesC& locName = *iParser->ComponentNames()[i];
       
   744 		const TDesC& locVendor = *iParser->VendorNames()[i];
       
   745 		CLocalizableComponentInfo* componentInfo = CLocalizableComponentInfo::NewLC(locName, locVendor, languages[i]);
       
   746 		componentInfoArray.AppendL(componentInfo);
       
   747 		CleanupStack::Pop(componentInfo);
       
   748 		}
       
   749 	iCompSearchData.iComponentId = iScr.AddComponentL(componentInfoArray, InstallHelper::KSifReferenceSoftwareType);
       
   750 
       
   751 	// Set the version of a new component
       
   752 	iScr.SetComponentVersionL(iCompSearchData.iComponentId, iCompSearchData.iVersion);
       
   753 
       
   754 	CleanupStack::PopAndDestroy(&componentInfoArray);
       
   755 
       
   756 	iCopyFileIndex = 0;
       
   757 	iComponentSize = 0;
       
   758 	
       
   759 	// 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.
       
   760 	if (iEmbeddedComponents[iCurrentComponent]->Root())
       
   761 		{
       
   762 		CustomResults()->AddIntL(KSifOutParam_ComponentId, iCompSearchData.iComponentId);
       
   763 		}
       
   764 	}
       
   765 
       
   766 namespace
       
   767 	{
       
   768 	TBool CheckPathExistenceL(const TDesC& filePath)
       
   769 		{
       
   770 		TBool exists = EFalse;
       
   771 
       
   772 		RFs fs;
       
   773 		User::LeaveIfError(fs.Connect());
       
   774 		CleanupClosePushL(fs);
       
   775 		TEntry entry;
       
   776 		TInt error = fs.Entry(filePath, entry);
       
   777 		if (error == KErrNone)
       
   778 			{
       
   779 			exists = ETrue;
       
   780 			}
       
   781 		else if (error != KErrPathNotFound && error != KErrNotFound)
       
   782 			{
       
   783 			User::Leave(error);
       
   784 			}
       
   785 		
       
   786 		CleanupStack::PopAndDestroy(&fs);
       
   787 		
       
   788 		return exists;
       
   789 		}
       
   790 	}
       
   791 
       
   792 TBool CSifRefInstallTask::CopyFileL()
       
   793 	{
       
   794 	DEBUG_PRINTF(_L8("CSifRefInstallTask::CopyFileL()"));
       
   795 	
       
   796 	// List of files to be copied from a package file 
       
   797 	const RCHBufCArray& files = iParser->Files();
       
   798 
       
   799 	// Register and copy a file if any left
       
   800 	if (iCopyFileIndex < files.Count())
       
   801 		{
       
   802 		// The name of the current file
       
   803 		const TDesC& filePath = *files[iCopyFileIndex];
       
   804 
       
   805 		// Check if filePath already exists
       
   806 		if (CheckPathExistenceL(filePath))
       
   807 			{
       
   808 			// Add a custom result describing the error
       
   809 			HBufC* desc = HBufC::NewLC(InstallHelper::KErrFileAlreadyExists.iTypeLength + filePath.Length());
       
   810 			TPtr bufDesc = desc->Des();
       
   811 			bufDesc.Copy(InstallHelper::KErrFileAlreadyExists);
       
   812 			bufDesc.Copy(filePath);
       
   813 			CustomResults()->AddStringL(InstallHelper::KParamNameErrDesc, *desc);
       
   814 			CleanupStack::PopAndDestroy(desc);
       
   815 			}
       
   816 
       
   817 		// Register the file in the SCR
       
   818 		iScr.RegisterComponentFileL(iCompSearchData.iComponentId, filePath);
       
   819 
       
   820 		// Copy the current file
       
   821 		RFile file;
       
   822 		iSts.CreateNewL(filePath, file, TFileMode(EFileShareExclusive |EFileWrite));
       
   823 		_LIT8(KReferenceFootprint, "This file belongs to the SIF reference component.\n");
       
   824 		const TInt numLines = 100; // The operation must take a while to simulate real copying
       
   825 		for (TInt i=0; i<numLines; ++i)
       
   826 			{
       
   827 			User::LeaveIfError(file.Write(KReferenceFootprint));
       
   828 			}
       
   829 		iComponentSize += KReferenceFootprint.iTypeLength*numLines;
       
   830 		file.Close();
       
   831 
       
   832 		++iCopyFileIndex;
       
   833 		}
       
   834 	else
       
   835 		{
       
   836 		// Set the size of the component in the SCR
       
   837 		iScr.SetComponentSizeL(iCompSearchData.iComponentId, iComponentSize);
       
   838 
       
   839 		// Step complete, all the files have been copied
       
   840 		return ETrue;
       
   841 		}
       
   842 
       
   843 	// Step not complete, there are still files left
       
   844 	
       
   845 	DEBUG_PRINTF(_L8("Exiting from CSifRefInstallTask::CopyFileL()"));
       
   846 	
       
   847 	return EFalse;
       
   848 	}
       
   849 
       
   850 TInt CSifRefInstallTask::SetScomoStateL()
       
   851 	{
       
   852 	DEBUG_PRINTF(_L8("CSifRefInstallTask::SetScomoStateL()"));
       
   853 	
       
   854 	// Activate the newly added component
       
   855 	TInt inactive = EFalse;
       
   856 	if (!CustomArguments()->GetIntByNameL(_L("InstallInactive"), inactive) || !inactive)
       
   857 		{
       
   858 		iScr.SetScomoStateL(iCompSearchData.iComponentId, EActivated);
       
   859 		}
       
   860 	
       
   861 	// Check if there are any components to be installed left
       
   862 	return (++iCurrentComponent < iEmbeddedComponents.Count()) ? EParsePkgFile : ECommit;
       
   863 	}
       
   864 
       
   865 void CSifRefInstallTask::CommitL()
       
   866 	{
       
   867 	DEBUG_PRINTF(_L8("CSifRefInstallTask::CommitL()"));
       
   868 	
       
   869 	// Commit the STS & SCR transactions
       
   870 	iSts.CommitL();
       
   871 	iScr.CommitTransactionL();
       
   872 	}
       
   873 
       
   874 // =============================================================================================================
       
   875 
       
   876 CSifRefUninstallTask* CSifRefUninstallTask::NewL(TTransportTaskParams& aParams, TInstallerUIHandlerFactory aUiHandlerFactory)
       
   877 	{
       
   878 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::NewL()"));
       
   879 	
       
   880 	CSifRefUninstallTask* self = new (ELeave) CSifRefUninstallTask(aParams);
       
   881 	CleanupStack::PushL(self);
       
   882 	self->ConstructL(aUiHandlerFactory);
       
   883 	CleanupStack::Pop(self);
       
   884 	return self;
       
   885 	}
       
   886 
       
   887 CSifRefUninstallTask::CSifRefUninstallTask(TTransportTaskParams& aParams)
       
   888 : CSifTransportTask(aParams), iStep(EGetFileList)
       
   889 	{
       
   890 	}
       
   891 
       
   892 void CSifRefUninstallTask::ConstructL(TInstallerUIHandlerFactory aUiHandlerFactory)
       
   893 	{
       
   894 	if (ComponentId() == NULL || CustomArguments() == NULL || CustomResults() == NULL)
       
   895 		{
       
   896 		User::Leave(KErrArgument);
       
   897 		}
       
   898 
       
   899 	iUiHandler = InstallHelper::CreateUiHandlerL(CustomArguments(), aUiHandlerFactory);
       
   900 	}
       
   901 
       
   902 CSifRefUninstallTask::~CSifRefUninstallTask()
       
   903 	{
       
   904 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::~CSifRefUninstallTask()"));
       
   905 	
       
   906 	// Make sure to close sub-session before the session
       
   907 	iFileList.Close();	
       
   908 	iScr.Close();
       
   909 	iSts.Close();
       
   910 	delete iUiHandler;
       
   911 	}
       
   912 
       
   913 TBool CSifRefUninstallTask::ExecuteImplL()
       
   914 	{
       
   915 	DEBUG_PRINTF2(_L8("CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   916 	
       
   917 	switch (iStep)
       
   918 		{
       
   919 		case EGetFileList:
       
   920 			GetFileListL();
       
   921 			break;
       
   922 
       
   923 		case EUnregisterAndDeleteFile:
       
   924 			if (!UnregisterAndDeleteFileL())
       
   925 				{
       
   926 				return EFalse;
       
   927 				}
       
   928 			break;
       
   929 
       
   930 		case ECommit:
       
   931 			CommitL();
       
   932 			return ETrue;
       
   933 
       
   934 		default:
       
   935 			User::Leave(KErrGeneral);
       
   936 		}
       
   937 
       
   938 	++iStep;
       
   939 
       
   940 	DEBUG_PRINTF2(_L8("Exiting from CSifRefInstallTask::ExecuteImplL(), iStep = %d"), iStep);
       
   941 	
       
   942 	return EFalse;
       
   943 	}
       
   944 
       
   945 void CSifRefUninstallTask::GetFileListL()
       
   946 	{
       
   947 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::GetFileListL()"));
       
   948 	
       
   949 	// Connect to the SCR and start a transaction
       
   950 	User::LeaveIfError(iScr.Connect());
       
   951 	iScr.CreateTransactionL();
       
   952 
       
   953 	// Ask the user for confirmation
       
   954 	if (iUiHandler != NULL)
       
   955 		{
       
   956 		CComponentEntry* entry = CComponentEntry::NewLC();
       
   957 		if (!iScr.GetComponentL(ComponentId(), *entry))
       
   958 			{
       
   959 			User::Leave(KErrNotFound);
       
   960 			}
       
   961 		userConfirmationL(InstallHelper::EConfirmationUninstall, *iUiHandler, entry->Name(), entry->Vendor());
       
   962 		CleanupStack::PopAndDestroy(entry);
       
   963 		}
       
   964 
       
   965 	// Get a list of files to be deleted
       
   966 	iFileList.OpenListL(iScr, ComponentId());
       
   967 
       
   968 	// Start an STS transaction
       
   969 	iSts.CreateTransactionL();
       
   970 	}
       
   971 
       
   972 TBool CSifRefUninstallTask::UnregisterAndDeleteFileL()
       
   973 	{
       
   974 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::UnregisterAndDeleteFileL()"));
       
   975 	
       
   976 	return InstallHelper::UnregisterAndDeleteFileL(iScr, iFileList, iSts, ComponentId());
       
   977 	}
       
   978 
       
   979 void CSifRefUninstallTask::CommitL()
       
   980 	{
       
   981 	DEBUG_PRINTF(_L8("CSifRefUninstallTask::CommitL()"));
       
   982 	
       
   983 	// Commit the STS & SCR transactions
       
   984 	iSts.CommitL();
       
   985 	iScr.CommitTransactionL();
       
   986 	}
       
   987 
       
   988 // =============================================================================================================
       
   989 
       
   990 CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask(TTransportTaskParams& aParams, TScomoState aScomoState)
       
   991 : CSifTransportTask(aParams), iScomoState(aScomoState)
       
   992 	{
       
   993 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::CSifRefActivateDeactivateTask()"));
       
   994 	}
       
   995 
       
   996 CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask()
       
   997 	{
       
   998 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::~CSifRefActivateDeactivateTask()"));
       
   999 	
       
  1000 	iScr.Close();
       
  1001 	}
       
  1002 
       
  1003 TBool CSifRefActivateDeactivateTask::ExecuteImplL()
       
  1004 	{
       
  1005 	DEBUG_PRINTF(_L8("CSifRefActivateDeactivateTask::ExecuteImplL()"));
       
  1006 	
       
  1007 	if (ComponentId() == NULL)
       
  1008 		{
       
  1009 		User::Leave(KErrArgument);
       
  1010 		}
       
  1011 
       
  1012 	// Connect to SCR and activate/deactivate component
       
  1013 	User::LeaveIfError(iScr.Connect());
       
  1014 	iScr.SetScomoStateL(ComponentId(), iScomoState);
       
  1015 
       
  1016 	return ETrue;
       
  1017 	}