installationservices/swcomponentregistry/source/server/scrrequestimpl.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 * Defines the class which implements SCR's service requests.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**
       
    21  @file
       
    22  @internalComponent
       
    23  @released
       
    24 */
       
    25 
       
    26 #include "scrrequestimpl.h"
       
    27 #include "scrdatabase.h"
       
    28 #include "screntries.h"
       
    29 #include "scrserver.h"
       
    30 #include "scrcommon.h"
       
    31 #include "scrsubsession.h"
       
    32 #include "usiflog.h"
       
    33 #include "usiferror.h"
       
    34 #include <s32mem.h>
       
    35 #include <bautils.h>
       
    36 #include <scs/streamingarray.h>
       
    37 #include <scs/ipcstream.h>
       
    38 #include <scs/ipcstream.inl>
       
    39 #include <scs/cleanuputils.h>
       
    40 #include <e32hashtab.h>
       
    41 #include <usif/sts/sts.h>
       
    42 
       
    43 using namespace Usif;
       
    44 
       
    45 _LIT(KComponentIdColumnName, "ComponentId"); 
       
    46 _LIT(KCompFileIdColumnName, "CmpFileId"); 
       
    47 _LIT(KComponentPropertiesTable, "ComponentProperties");
       
    48 _LIT(KFilePropertiesTable, "FileProperties");
       
    49 
       
    50 /** Maximum number of log records could be recorded by SCR. */
       
    51 // It is estimated that a thousand log entries create 40K-100K log file.
       
    52 const TInt KMaxScrLogEntries = 1000;
       
    53 /** The file path of SCR log file. */
       
    54 _LIT(KScrLogFileName, "!:\\private\\10285bc0\\scr.log");
       
    55 /** The file path of SCR temporary log file. */
       
    56 _LIT(KScrTempLogFileName, "!:\\private\\10285bc0\\scr_tmp.log");
       
    57 	
       
    58 const TUint KDbInterfaceMajorVersion = 1;
       
    59 const TUint KDbInterfaceMinorVersion = 1;
       
    60 #ifdef _DEBUG
       
    61 const TUint KDbInterfaceBuildNumber = 1;
       
    62 #endif
       
    63 
       
    64 enum TScrPanicId
       
    65 	{
       
    66 	KScrIllegalCallSequence = 1,
       
    67 	KScrIllegalParameter = 2
       
    68 	};
       
    69 
       
    70 static void PanicClient(const RMessagePtr2& aMessage, TScrPanicId aPanic)
       
    71 	{
       
    72 	_LIT(KPanicMessage, "ScrServer");
       
    73     aMessage.Panic(KPanicMessage, aPanic);
       
    74     }
       
    75 
       
    76 HBufC* UpdateFilePathDriveLC(const TDesC& aFilePath, TChar aDrive)
       
    77 	{
       
    78 	HBufC *fileName = HBufC::NewLC(aFilePath.Length());
       
    79 	TPtr ptrFileName(fileName->Des());
       
    80 	ptrFileName.Copy(aFilePath);
       
    81 	ptrFileName[0] = aDrive;
       
    82 	return fileName; 
       
    83 	}	
       
    84 	
       
    85 ////////////////////////
       
    86 // CScrRequestImpl
       
    87 ////////////////////////
       
    88 
       
    89 CScrRequestImpl::CScrRequestImpl(RFs& aFs)
       
    90 	: iFs(aFs)
       
    91 	{
       
    92 	}
       
    93 
       
    94 CScrRequestImpl::~CScrRequestImpl()
       
    95 	{
       
    96 	delete iDbHandle;
       
    97 	delete iComponentEntry;
       
    98 	iProperties.ResetAndDestroy();
       
    99 	delete iSingleProperty;
       
   100 	iFileComponents.Close();
       
   101 	iVerCompIdList.ResetAndDestroy();
       
   102 	iDeletedMimeTypes.ResetAndDestroy();
       
   103 	iLogEntries.ResetAndDestroy();
       
   104 	iMatchingSupportedLanguageList.Close();
       
   105 	}
       
   106 
       
   107 CScrRequestImpl* CScrRequestImpl::CScrRequestImpl::NewL(RFs& aFs, RFile& aDatabaseFile, RFile& aJournalFile)
       
   108 	{
       
   109 	CScrRequestImpl *self = new(ELeave) CScrRequestImpl(aFs);
       
   110 	CleanupStack::PushL(self);
       
   111 	self->ConstructL(aDatabaseFile, aJournalFile);
       
   112 	CleanupStack::Pop(self);
       
   113 	return self;
       
   114 	}
       
   115 
       
   116 void CScrRequestImpl::ConstructL(RFile& aDatabaseFile, RFile& aJournalFile)
       
   117 	{
       
   118 	iDbHandle = CDatabase::NewL(aDatabaseFile, aJournalFile);
       
   119 	InitializeDbVersionL();
       
   120 	VerifyDbVersionCompatibilityL();
       
   121 	// Make sure that private directory exists - required for temporary and log files
       
   122 	_LIT(KPrivateDirPath, "!:\\private\\10285bc0\\");
       
   123 	HBufC* privateDirPath = UpdateFilePathDriveLC(KPrivateDirPath, iFs.GetSystemDriveChar());
       
   124 	TInt res = iFs.MkDirAll(*privateDirPath);
       
   125 	__ASSERT_ALWAYS(res == KErrNone || res == KErrAlreadyExists, User::Leave(res));
       
   126 	CleanupStack::PopAndDestroy(privateDirPath);
       
   127 	}
       
   128 
       
   129 HBufC* CScrRequestImpl::ReadDescLC(const RMessage2& aMessage, TInt aSlot)
       
   130 	{
       
   131 	TInt len = aMessage.GetDesLengthL(aSlot);
       
   132 	HBufC* desc = HBufC::NewLC(len);
       
   133 	TPtr ptrDesc(desc->Des());
       
   134 	aMessage.ReadL(aSlot, ptrDesc);
       
   135 	return desc;
       
   136 	}
       
   137 
       
   138 HBufC8* CScrRequestImpl::ReadDesc8LC(const RMessage2& aMessage, TInt aSlot)
       
   139 	{
       
   140 	TInt len = aMessage.GetDesLengthL(aSlot);
       
   141 	HBufC8* desc = HBufC8::NewLC(len);
       
   142 	TPtr8 ptrDesc(desc->Des());
       
   143 	aMessage.ReadL(aSlot, ptrDesc);
       
   144 	return desc;
       
   145 	}
       
   146 
       
   147 HBufC* CScrRequestImpl::FormatStatementLC(const TDesC& aStatement, TInt aFormattedLength,...) const
       
   148 	{
       
   149 	VA_LIST list;
       
   150 	VA_START(list, aFormattedLength);
       
   151 	HBufC* statementStr = HBufC::NewLC(aStatement.Length() + aFormattedLength + 1);
       
   152 	TPtr statementStrPtr(statementStr->Des()); 
       
   153 	statementStrPtr.FormatList(aStatement, list);
       
   154 	VA_END(list);
       
   155 	
       
   156 	// SQLite requires the statement string to end with NULL char.
       
   157 	statementStrPtr.Append('\0');
       
   158 	return statementStr;
       
   159 	}
       
   160 
       
   161 void CScrRequestImpl::CreateTransactionL()
       
   162 	{
       
   163 	DEBUG_PRINTF(_L8("Create Transaction request received."));
       
   164 	_LIT(KBeginTransaction, "BEGIN IMMEDIATE;");
       
   165 	ExecuteStatementL(KBeginTransaction());	
       
   166 	DEBUG_PRINTF(_L8("Transaction has begun!"));
       
   167 	}
       
   168 
       
   169 void CScrRequestImpl::RollbackTransactionL()
       
   170 	{
       
   171 	DEBUG_PRINTF(_L8("Rollback Transaction request received."));
       
   172 	_LIT(KRollbackTransaction, "ROLLBACK;");
       
   173 	ExecuteStatementL(KRollbackTransaction());
       
   174 	DEBUG_PRINTF(_L8("Transaction has been rolled back successfuly!"));
       
   175 	}
       
   176 
       
   177 void CScrRequestImpl::CommitTransactionL()
       
   178 	{
       
   179 	DEBUG_PRINTF(_L8("Commit Transaction request received."));
       
   180 	_LIT(KCommitTransaction, "COMMIT;");
       
   181 	ExecuteStatementL(KCommitTransaction());
       
   182 	DEBUG_PRINTF(_L8("Transaction has been committed successfully!"));
       
   183 	}
       
   184 
       
   185 HBufC* CScrRequestImpl::GenerateGlobalIdL(const TDesC& aUniqueSwTypeName, const TDesC& aGlobalId) const
       
   186 	{ 
       
   187 	HBufC *globalIdBuf = HBufC::NewL(aUniqueSwTypeName.Length() + aGlobalId.Length() + 1); // 1 is extra memory to put NULL char
       
   188 	TPtr globalIdDes(globalIdBuf->Des());
       
   189 	
       
   190 	globalIdDes.Copy(aUniqueSwTypeName);
       
   191 	globalIdDes.Append('\0');
       
   192 	globalIdDes.Append(aGlobalId);
       
   193 	
       
   194 	return globalIdBuf;
       
   195 	}
       
   196 
       
   197 TComponentId CScrRequestImpl::CommonAddComponentL(const TDesC& aUniqueSwTypeName, const TDesC& aGlobalId)
       
   198 	{
       
   199 	DEBUG_PRINTF(_L8("Adding a base component."));
       
   200 	// Get the current time
       
   201 	TTime time;
       
   202 	time.HomeTime();
       
   203 	TDateTime datetime = time.DateTime();
       
   204 	TBuf<16> installTime;
       
   205 	// We cannot use TTime::FormatL, since it starts months and days with 01, which is not accepted by TTime::Set() which starts them from 0
       
   206 	installTime.Format(_L("%04d%02d%02d:%02d%02d%02d"), datetime.Year(), datetime.Month(), datetime.Day(), datetime.Hour(), datetime.Minute(), datetime.Second());
       
   207 	
       
   208 	// SoftwareTypeId is the hash of unique software type name. For more information, see CScrRequestImpl::AddSoftwareTypeL.
       
   209 	// In Components table, both SoftwareTypeId and unique SoftwareTypeName is stored so that the software type name of a component
       
   210 	// can be returned even if the corresponding installer (software type) has been uninstalled. The unique sofware type name
       
   211 	// might be used by the client to identify the installer required to uninstall the component.
       
   212 	TUint32 swTypeId = HashCaseSensitiveL(aUniqueSwTypeName);
       
   213 	
       
   214 	if(aGlobalId.CompareF(KNullDesC()))
       
   215 		{ // Global Id is supplied by client
       
   216 		HBufC *globalId = GenerateGlobalIdL(aUniqueSwTypeName, aGlobalId);
       
   217 		CleanupStack::PushL(globalId);
       
   218 		TUint32 globalIdHash = HashCaseSensitiveL(*globalId);
       
   219 		
       
   220 		_LIT(KInsertComponent,"INSERT INTO Components(SoftwareTypeId,SoftwareTypeName,GlobalIdHash,GlobalId,InstallTime) VALUES(?,?,?,?,?);");
       
   221 		TInt numberOfValues = 5;
       
   222 		ExecuteStatementL(KInsertComponent(), numberOfValues, EValueInteger, swTypeId, EValueString, &aUniqueSwTypeName, EValueInteger, globalIdHash, EValueString, globalId, EValueString, &installTime);
       
   223 		CleanupStack::PopAndDestroy(globalId);
       
   224 		}
       
   225 	else
       
   226 		{// Global Id is NOT supplied by client
       
   227 		_LIT(KInsertComponent,"INSERT INTO Components(SoftwareTypeId,SoftwareTypeName,InstallTime) VALUES(?,?,?);");
       
   228 		TInt numberOfValues = 3;
       
   229 		ExecuteStatementL(KInsertComponent(), numberOfValues, EValueInteger, swTypeId, EValueString, &aUniqueSwTypeName, EValueString, &installTime);
       
   230 		}
       
   231 	
       
   232 	DEBUG_PRINTF(_L8("The new component has been added to Components table successfully."));
       
   233 	return iDbHandle->LastInsertedIdL();
       
   234 	}
       
   235 
       
   236 void CScrRequestImpl::AddComponentLocalizablesL(TComponentId aCompId, TLanguage aLocale, const TDesC& aName, const TDesC& aVendor)
       
   237 	{
       
   238 	DEBUG_PRINTF4(_L("Adding the component(%d) localizables: name(%S) and vendor(%S)."), aCompId, &aName, &aVendor);
       
   239 	
       
   240 	if(!aName.CompareF(KNullDesC()))
       
   241 		{// Component name cannot be empty
       
   242 		DEBUG_PRINTF(_L8("Component name cannot be NULL string."));
       
   243 		User::Leave(KErrArgument);
       
   244 		}
       
   245 	
       
   246 	_LIT(KInsertComponentLocalizables, "INSERT INTO ComponentLocalizables(ComponentId,Locale,Name,Vendor) VALUES(?,?,?,?);");
       
   247 	TInt numberOfValues = 4;
       
   248 	ExecuteStatementL(KInsertComponentLocalizables(), numberOfValues, EValueInteger, aCompId, EValueInteger, aLocale, EValueString, &aName, EValueString, &aVendor);
       
   249 	
       
   250 	DEBUG_PRINTF(_L8("The component localizables have been added successfully."));
       
   251 	}
       
   252 
       
   253 void CScrRequestImpl::ComponentRollback(TAny* aParam)
       
   254 	{
       
   255 	TRollbackParams *param = static_cast<TRollbackParams*>(aParam);
       
   256 	_LIT(KDeleteComponents, "DELETE FROM Components WHERE ComponentId=?;");
       
   257 	TInt numberOfValues = 1;
       
   258 	TRAP_IGNORE(param->iReqImplHandle.ExecuteStatementL(KDeleteComponents, numberOfValues, EValueInteger, param->iIdColumnVal););
       
   259 	}
       
   260 	
       
   261 void CScrRequestImpl::ComponentLocalizablesRollback(TAny* aParam)
       
   262 	{
       
   263 	TRollbackParams *param = static_cast<TRollbackParams*>(aParam);
       
   264 	_LIT(KDeleteComponentLocalizables, "DELETE FROM ComponentLocalizables WHERE ComponentId=?;");
       
   265 	TInt numberOfValues = 1;
       
   266 	TRAP_IGNORE(param->iReqImplHandle.ExecuteStatementL(KDeleteComponentLocalizables, numberOfValues, EValueInteger, param->iIdColumnVal););
       
   267 	}
       
   268 
       
   269 void CScrRequestImpl::AddComponentL(const RMessage2& aMessage)
       
   270 	{
       
   271 	DEBUG_PRINTF(_L8("Adding a new component."));
       
   272 	// First check if the supplied operation type is valid
       
   273 	TScrComponentOperationType compOpType;
       
   274 	TPckg<TScrComponentOperationType> opTypePckg(compOpType);
       
   275 	aMessage.ReadL(3, opTypePckg, 0);
       
   276 		
       
   277 	if(compOpType != EScrCompInstall && compOpType != EScrCompUpgrade && compOpType != EScrCompHidden)
       
   278 		{
       
   279 		DEBUG_PRINTF2(_L("Unexpected component operation type (%d) was provided!"), static_cast<TInt>(compOpType));
       
   280 		User::Leave(KErrArgument);
       
   281 		}
       
   282 	
       
   283 	RIpcReadStream componentInfoReader;
       
   284 	CleanupClosePushL(componentInfoReader);
       
   285 	componentInfoReader.Open(aMessage, 1);
       
   286 	
       
   287 	RPointerArray<CLocalizableComponentInfo> componentInfoArray;
       
   288 	CleanupResetAndDestroyPushL(componentInfoArray);
       
   289 	InternalizePointersArrayL(componentInfoArray, componentInfoReader);
       
   290 	TInt arrayCount = componentInfoArray.Count();
       
   291 	// This check is done at the client side - if we get this condition here, this means that a rogue client-server call bypassed the R-class
       
   292 	__ASSERT_ALWAYS(arrayCount > 0, PanicClient(aMessage, KScrIllegalParameter));
       
   293 
       
   294 	HBufC *uniqueSwTypeName = GetSoftwareTypeNameFromMsgLC(aMessage);
       
   295 	HBufC *globalId = ReadDescLC(aMessage, 2);
       
   296 	TComponentId newComponentId = CommonAddComponentL(*uniqueSwTypeName, *globalId);
       
   297 	
       
   298 	// Add the newly added component into the cleanupstack so that it can be deleted in case of leaving.
       
   299 	TRollbackParams cleanupParam(newComponentId, *this);
       
   300 	CleanupStack::PushL(TCleanupItem(CScrRequestImpl::ComponentRollback, &cleanupParam));
       
   301 	// Add the component localizables cleanup into the cleanupstack so that they can be deleted in case of leaving.
       
   302 	CleanupStack::PushL(TCleanupItem(CScrRequestImpl::ComponentLocalizablesRollback, &cleanupParam));
       
   303 	
       
   304 	// For a log record, the component name is chosen for the current locale. If it doesn't exist, 
       
   305 	// then the non-localized component name is picked. If none of them exist, the first name in the names 
       
   306 	// array is used as default.
       
   307 	TInt componentNameIndexForLog (0);
       
   308 	TInt indexForCurrentLocale = KErrNotFound;
       
   309 	TInt indexForNonLocalized = KErrNotFound;
       
   310 	for(TInt i=0; i<arrayCount; ++i)
       
   311 		{
       
   312 		TLanguage locale(componentInfoArray[i]->Locale());
       
   313 		const TDesC& name = componentInfoArray[i]->NameL();
       
   314 		const TDesC& vendor = componentInfoArray[i]->VendorL();
       
   315 		AddComponentLocalizablesL(newComponentId, locale, name, vendor);
       
   316 		if(locale == User::Language())
       
   317 			indexForCurrentLocale = i;
       
   318 		else if(locale == KNonLocalized)
       
   319 			indexForNonLocalized = i;
       
   320 		}
       
   321 	CleanupStack::Pop(2, &cleanupParam); // cleanupitem for ComponentRollback, cleanupitem for ComponentLocalizablesRollback
       
   322 	
       
   323 	if(indexForCurrentLocale != KErrNotFound)
       
   324 		componentNameIndexForLog = indexForCurrentLocale;
       
   325 	else if(indexForNonLocalized != KErrNotFound)
       
   326 		componentNameIndexForLog = indexForNonLocalized;
       
   327 	
       
   328 	if(EScrCompHidden != compOpType)
       
   329 		{
       
   330 		CScrLogEntry *logRecord = CScrLogEntry::NewLC(componentInfoArray[componentNameIndexForLog]->NameL(), *uniqueSwTypeName, *globalId, KNullDesC, compOpType);
       
   331 		logRecord->iComponentId = newComponentId;
       
   332 		iLogEntries.Append(logRecord);
       
   333 		CleanupStack::Pop(logRecord); // Ownershipd is transferred
       
   334 		}
       
   335 	CleanupStack::PopAndDestroy(4, &componentInfoReader); // componentInfoReader, componentInfoArray, uniqueSwTypeName, globalId
       
   336 	
       
   337 	TPckg<TComponentId> componentIdDes(newComponentId);
       
   338 	aMessage.WriteL(3, componentIdDes);
       
   339 	}
       
   340 
       
   341 HBufC* CScrRequestImpl::ReadAndGetGlobalIdLC(const RMessage2& aMessage, TInt aSlot) const
       
   342 	{
       
   343 	// Read global id object from the message
       
   344 	CGlobalComponentId *globalId = ReadObjectFromMessageLC<CGlobalComponentId>(aMessage, aSlot);
       
   345 	HBufC *globalIdBuf = GenerateGlobalIdL(globalId->SoftwareTypeName(), globalId->GlobalIdName());
       
   346 	CleanupStack::PopAndDestroy(globalId);
       
   347 	CleanupStack::PushL(globalIdBuf);
       
   348 	return globalIdBuf;
       
   349 	}
       
   350 
       
   351 TUint32 CScrRequestImpl::HashGlobalIdsL(const TDesC& aDependantId, const TDesC& aSupplierId) const
       
   352 	{
       
   353 	RBuf concatGlobalIds;
       
   354 	concatGlobalIds.CreateL(aDependantId.Length() + aSupplierId.Length());
       
   355 	concatGlobalIds.CleanupClosePushL();
       
   356 	concatGlobalIds.Copy(aDependantId);
       
   357 	concatGlobalIds.Append(aSupplierId);
       
   358 	TUint32 globalIdsHash = HashCaseSensitiveL(concatGlobalIds);
       
   359 	CleanupStack::PopAndDestroy(&concatGlobalIds);
       
   360 	return globalIdsHash;
       
   361 	}
       
   362 
       
   363 void CScrRequestImpl::AddComponentDependencyL(const RMessage2& aMessage)
       
   364 	{
       
   365 	DEBUG_PRINTF(_L8("Adding a new component dependency."));
       
   366 	
       
   367 	CVersionedComponentId *verCompId = ReadObjectFromMessageLC<CVersionedComponentId>(aMessage, 1);
       
   368 	HBufC *suppGlobalId = GenerateGlobalIdL(verCompId->GlobalId().SoftwareTypeName(), verCompId->GlobalId().GlobalIdName());
       
   369 	CleanupStack::PushL(suppGlobalId);
       
   370 	TUint32 suppGlobalIdHash = HashCaseSensitiveL(*suppGlobalId);
       
   371 	
       
   372 	HBufC *depGlobalId = ReadAndGetGlobalIdLC(aMessage, 2);
       
   373 	TUint32 depGlobalIdHash = HashCaseSensitiveL(*depGlobalId);
       
   374 	
       
   375 	TUint32 globalIdsHash = HashGlobalIdsL(*depGlobalId, *suppGlobalId);
       
   376 	
       
   377 	const TDesC* versionFrom = verCompId->VersionFrom();
       
   378 	const TDesC* versionTo = verCompId->VersionTo();
       
   379 	
       
   380 	_LIT(KInsertDependencyFront, "INSERT INTO ComponentDependencies(GlobalIdHash,DependantGlobalIdHash,SupplierGlobalIdHash,DependantGlobalId,SupplierGlobalId");
       
   381 	_LIT(KInsertDependencyEnd, ") VALUES(?,?,?,?,?");
       
   382 
       
   383 	const TInt KMaxInsertDependencyLength = 180;     ///< Maximum length of a possible dependency insert statement (KInsertDependencyFront + KInsertDependencyEnd + some space for optional columns)
       
   384 	const TInt KMaxInsertDependencyValueLength = 30; ///< Maximum length of the end part of a possible dependency insert statement (KInsertDependencyEnd + some space for optional values).
       
   385 
       
   386 	TInt numberOfValues = 5; // 5->(GlobalIdHash, DependantGlobalIdHash, SupplierGlobalIdHash, DependantGlobalId, SupplierGlobalId)
       
   387 	RBuf insertStmtStr;
       
   388 	insertStmtStr.CreateL(KMaxInsertDependencyLength);
       
   389 	insertStmtStr.CleanupClosePushL();
       
   390 	insertStmtStr.Copy(KInsertDependencyFront());
       
   391 	
       
   392 	RBuf insertStmtEndStr;
       
   393 	insertStmtEndStr.CreateL(KMaxInsertDependencyValueLength);
       
   394 	insertStmtEndStr.CleanupClosePushL();
       
   395 	insertStmtEndStr.Copy(KInsertDependencyEnd());
       
   396 	
       
   397 	// VersionFrom and VersionTo values are optional. Hence, a dynamic insert statement will be created.
       
   398 	// insertStmtStr is initialized with the statement including mandatory columns. Then versionFrom/To
       
   399 	// values are checked. If any of them is provided, then the corresponding column name is added to the statement.
       
   400 	// insertStmtEndStr is constructed with a number of value characters(?) as new value chars will be added
       
   401 	// if new columns are added to the statement
       
   402 	// In the end, insertStmtEndStr is added to insertStmtStr in order to complete the dependency insert statement.
       
   403 	
       
   404 	const TDesC* firstVersionParam(0);
       
   405 	const TDesC* secondVersionParam(0);
       
   406 	
       
   407 	_LIT(KInsertValue, ",?");
       
   408 	if(versionFrom)
       
   409 		{
       
   410 		_LIT(KVersionFrom, ",VersionFrom");
       
   411 		insertStmtStr.Append(KVersionFrom());
       
   412 		insertStmtEndStr.Append(KInsertValue());
       
   413 		firstVersionParam = versionFrom;
       
   414 		++numberOfValues;
       
   415 		}
       
   416 	
       
   417 	if(versionTo)
       
   418 		{
       
   419 		_LIT(KVersionTo, ",VersionTo");
       
   420 		insertStmtStr.Append(KVersionTo());
       
   421 		insertStmtEndStr.Append(KInsertValue());
       
   422 		if(firstVersionParam)
       
   423 			{
       
   424 			secondVersionParam = versionTo;
       
   425 			}
       
   426 		else
       
   427 			{
       
   428 			firstVersionParam = versionTo;
       
   429 			}
       
   430 		++numberOfValues;
       
   431 		}
       
   432 	
       
   433 	// Append the end part of the statement to the front part.
       
   434 	insertStmtStr.Append(insertStmtEndStr);
       
   435 	// Close the statement
       
   436 	_LIT(KInsertClose,");");
       
   437 	insertStmtStr.Append(KInsertClose());
       
   438 	// SQLite requires the statement string to end with NULL char.
       
   439 	insertStmtStr.Append('\0');
       
   440 	// All parameters are supplied, but numberOfValues of them will be taken into account.
       
   441 	ExecuteStatementL(insertStmtStr, numberOfValues, EValueInteger, globalIdsHash, EValueInteger, depGlobalIdHash, EValueInteger, suppGlobalIdHash, EValueString, depGlobalId, EValueString, suppGlobalId, EValueString, firstVersionParam, EValueString, secondVersionParam);
       
   442 	
       
   443 	CleanupStack::PopAndDestroy(5, verCompId); // verCompId, suppGlobalId, depGlobalId, insertStmtStr, insertStmtEndStr
       
   444 	}
       
   445 
       
   446 CStatement* CScrRequestImpl::CreateGeneralPropertyStatementWithLocaleL(const TDesC& aStmtStr, TInt aIdColumnValue, TLanguage aLocale, const TDesC& aPropName, TBool aDoLocaleResolving) const
       
   447 	{
       
   448 	CStatement *stmt(0);
       
   449 	TInt numberOfValues = 3;
       
   450 	
       
   451 	if(KUnspecifiedLocale == aLocale)
       
   452 		{
       
   453 		// No locale is specified. Client wants SCR to find the property automatically.
       
   454 		// So, first look up the properties for the current locale and its downgraded languages.
       
   455 		ASSERT(aDoLocaleResolving); // We cannot get a situation where KUnspecifiedLocale is given with locale resolving disabled: it is an undefined state.
       
   456 		stmt = CreateStatementObjectWithLocaleL(aStmtStr, User::Language(), numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueLanguage);
       
   457 		
       
   458 		if(!stmt)
       
   459 			{
       
   460 			// No property is defined with the current locale. Look up the non-localized properties.
       
   461 			stmt = CreateStatementObjectWithLocaleL(aStmtStr, KNonLocalized, numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueLanguage);
       
   462 			}
       
   463 		}
       
   464 	else if(KNonLocalized == aLocale)
       
   465 		{
       
   466 		// Non-localized properties are requested. Look up the non-localized properties.
       
   467 		stmt = CreateStatementObjectWithLocaleL(aStmtStr, KNonLocalized, numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueLanguage);
       
   468 		}
       
   469 	else
       
   470 		{
       
   471 		// A particular language is specified. Look up the properties with for this particular language
       
   472 		// and its downgraded languages.
       
   473 		stmt = aDoLocaleResolving ? 
       
   474 			CreateStatementObjectWithLocaleL(aStmtStr, aLocale, numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueLanguage, aDoLocaleResolving) :
       
   475 			CreateStatementObjectWithLocaleNoDowngradeL(aStmtStr, aLocale, numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueLanguage, aDoLocaleResolving);
       
   476 		}
       
   477 	return stmt;
       
   478 	}
       
   479 
       
   480 TInt CScrRequestImpl::FindGeneralPropertyNoLocaleDowngradeL(const TDesC& aTableName, const TDesC& aIdColumnName, TInt aIdColumnValue, const TDesC& aPropertyName, TLanguage aLocale, TPropertyType& aPropertyType) const
       
   481 	{
       
   482 	_LIT(KFindProperty, "SELECT PropertyId,IntValue,StrValue,IsStr8Bit FROM %S WHERE Name=? AND %S=? AND Locale=?;");
       
   483 	TInt formattedLen = aTableName.Length() + aIdColumnName.Length();
       
   484 	HBufC *statementStr = FormatStatementLC(KFindProperty(), formattedLen, &aTableName, &aIdColumnName);
       
   485 
       
   486 	// As we do not require downgrading locales, the last parameter is EFalse
       
   487 	CStatement *stmtFind = CreateGeneralPropertyStatementWithLocaleL(*statementStr, aIdColumnValue, aLocale, aPropertyName, EFalse);
       
   488 	if(!stmtFind)
       
   489 		{ // the property does not exist, return
       
   490 		CleanupStack::PopAndDestroy(statementStr);
       
   491 		return KErrNotFound;
       
   492 		}
       
   493 	CleanupStack::PushL(stmtFind);
       
   494 	
       
   495 	// the property in question exists in the properties table 
       
   496 	TInt propertyId = stmtFind->IntColumnL(0);					// 0 -> PropertyId		
       
   497 	TBool isIntPropertyNull = stmtFind->IsFieldNullL(1); 	// 2 -> IntValue
       
   498 	TBool isStrPropertyNull = stmtFind->IsFieldNullL(2); 	// 3 -> StrValue
       
   499 			
       
   500 	if(!isIntPropertyNull)
       
   501 		{
       
   502 		aPropertyType = CScrRequestImpl::EPropertyInteger;
       
   503 		}
       
   504 	else if(!isStrPropertyNull)
       
   505 		{
       
   506 		TBool is8BitString = (stmtFind->IntColumnL(3) == 1);
       
   507 		aPropertyType = is8BitString ? CScrRequestImpl::EPropertyBinary : CScrRequestImpl::EPropertyLocalizable;
       
   508 		}
       
   509 	else // None of the columns is defined - corrupt DB 
       
   510 		{
       
   511 		DEBUG_PRINTF(_L8("Unexpected situation! Neither int value nor str value are defined for a property"));
       
   512 		User::Leave(KErrCorrupt);
       
   513 		}
       
   514 	CleanupStack::PopAndDestroy(2, statementStr); // stmtFind, statementStr
       
   515 	return propertyId;
       
   516 	}
       
   517 
       
   518 void CScrRequestImpl::BindStatementValuesL(CStatement& aStatement, TLanguage aLanguage, TInt aValuesNum, VA_LIST aList) const
       
   519 	{
       
   520 	TInt bindIdx(0);
       
   521 	while(aValuesNum--)
       
   522 		{
       
   523 		CScrRequestImpl::TValueType t = static_cast<CScrRequestImpl::TValueType>(VA_ARG(aList, TInt));
       
   524 		switch(t)
       
   525 			{
       
   526 			case EValueString:
       
   527 				{
       
   528 				const TDesC* strVal = VA_ARG(aList, const TDesC*);
       
   529 				aStatement.BindStrL(++bindIdx, *strVal);
       
   530 				break;
       
   531 				}
       
   532 			case EValueInteger:
       
   533 				{
       
   534 				TInt intVal = VA_ARG(aList, TInt);
       
   535 				aStatement.BindIntL(++bindIdx, intVal);
       
   536 				break;
       
   537 				}
       
   538 			case EValueInteger64:
       
   539 				{
       
   540 				TInt64 intVal64 = VA_ARG(aList, TInt64);
       
   541 				aStatement.BindInt64L(++bindIdx, intVal64);
       
   542 				break;
       
   543 				}
       
   544 			case EValueLanguage:
       
   545 				{
       
   546 				aStatement.BindIntL(++bindIdx, aLanguage);
       
   547 				break;
       
   548 				}
       
   549 			case EValueBinary:
       
   550 				{
       
   551 				const TDesC8* binaryVal = VA_ARG(aList, const TDesC8*);
       
   552 				aStatement.BindBinaryL(++bindIdx, *binaryVal);
       
   553 				break;
       
   554 				}				
       
   555 			default:
       
   556 				DEBUG_PRINTF2(_L8("Encountered unexpected value type (%d)!"), t);
       
   557 				ASSERT(0);
       
   558 			} // switch
       
   559 		} // while
       
   560 	} // End of the function
       
   561 
       
   562 void CScrRequestImpl::ExecuteStatementL(TRefByValue<const TDesC> aStatement, TInt aValuesNum,...)
       
   563 	{// TRefByValue is used to suppress rcvt compile warning
       
   564 	VA_LIST argList;
       
   565 	VA_START(argList, aValuesNum);
       
   566 	
       
   567 	CStatement *stmt = iDbHandle->PrepareStatementLC(aStatement);
       
   568 	BindStatementValuesL(*stmt, KLangNone, aValuesNum, argList);
       
   569 	stmt->ExecuteStatementL();
       
   570 	CleanupStack::PopAndDestroy(stmt);
       
   571 	
       
   572 	VA_END(argList);
       
   573 	}
       
   574 
       
   575 void CScrRequestImpl::SetGeneralLocalizablePropertyL(CScrRequestImpl::TPropertyType aPropType, TInt aPropertyId, const TDesC& aIdColumnName, TInt aIdColumnValue, const TDesC& aPropName, TLanguage aLocale, const TDesC& aPropValue)
       
   576 	{
       
   577 	switch(aPropType)
       
   578 		{
       
   579 		case CScrRequestImpl::EPropertyUndefined:
       
   580 			{// the property does NOT exist, insert a new one
       
   581 			_LIT(KInsertProperty, "INSERT INTO ComponentProperties(Name,Locale,%S,StrValue) VALUES(?,?,?,?);");
       
   582 			TInt formattedLen = aIdColumnName.Length();
       
   583 			HBufC *statementStr = FormatStatementLC(KInsertProperty(), formattedLen, &aIdColumnName );
       
   584 			TInt numberOfValues = 4;
       
   585 			ExecuteStatementL(*statementStr, numberOfValues, EValueString, &aPropName, EValueInteger, aLocale, EValueInteger, aIdColumnValue, EValueString, &aPropValue);
       
   586 			CleanupStack::PopAndDestroy(statementStr);
       
   587 			break;
       
   588 			}
       
   589 		case CScrRequestImpl::EPropertyLocalizable: 
       
   590 			{
       
   591 			// the property exists, update it
       
   592 			_LIT(KUpdateProperty, "UPDATE ComponentProperties SET StrValue=? WHERE PropertyId=?;");
       
   593 			TInt numberOfValues = 2;
       
   594 			ExecuteStatementL(KUpdateProperty(), numberOfValues, EValueString, &aPropValue, EValueInteger, aPropertyId);
       
   595 			break;
       
   596 			}
       
   597 		default:
       
   598 			DEBUG_PRINTF(_L8("The property type isn't localizable string and cannot be updated with this API."))
       
   599 			User::Leave(KErrAbort);
       
   600 		}
       
   601 	}
       
   602 
       
   603 void CScrRequestImpl::SetGeneralBinaryPropertyL(CScrRequestImpl::TPropertyType aPropType, TInt aPropertyId, const TDesC& aTableName, const TDesC& aIdColumnName, TInt aIdColumnValue, const TDesC& aPropName, const TDesC8& aPropValue)
       
   604 	{
       
   605 	switch(aPropType)
       
   606 		{
       
   607 		case CScrRequestImpl::EPropertyUndefined:
       
   608 			{// the property does NOT exist, insert a new one
       
   609 			_LIT(KInsertProperty, "INSERT INTO %S(Name,%S,StrValue,IsStr8Bit) VALUES(?,?,?,1);");
       
   610 			TInt formattedLen = aTableName.Length() + aIdColumnName.Length();
       
   611 			HBufC *statementStr = FormatStatementLC(KInsertProperty(), formattedLen, &aTableName, &aIdColumnName );
       
   612 			TInt numberOfValues = 3;
       
   613 			ExecuteStatementL(*statementStr, numberOfValues, EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueBinary, &aPropValue);
       
   614 			CleanupStack::PopAndDestroy(statementStr);
       
   615 			break;
       
   616 			}
       
   617 		case CScrRequestImpl::EPropertyBinary: 
       
   618 			{
       
   619 			// the property exists, update it
       
   620 			_LIT(KUpdateProperty, "UPDATE %S SET StrValue=? WHERE PropertyId=?;");
       
   621 			HBufC *statementStr = FormatStatementLC(KUpdateProperty(), aTableName.Length(), &aTableName);
       
   622 			TInt numberOfValues = 2;
       
   623 			ExecuteStatementL(*statementStr, numberOfValues, EValueBinary, &aPropValue, EValueInteger, aPropertyId);
       
   624 			CleanupStack::PopAndDestroy(statementStr);
       
   625 			break;
       
   626 			}
       
   627 		default:
       
   628 			DEBUG_PRINTF(_L8("The property type isn't an 8-bit string and cannot be updated with this API."))
       
   629 			User::Leave(KErrAbort);
       
   630 		}
       
   631 	}
       
   632 
       
   633 void CScrRequestImpl::SetGeneralIntPropertyL(TPropertyType aPropType, TInt aPropertyId, const TDesC& aTableName, const TDesC& aIdColumnName , TInt aIdColumnValue, const TDesC& aPropName, TInt64 aPropValue)
       
   634 	{
       
   635 	switch(aPropType)
       
   636 		{
       
   637 		case CScrRequestImpl::EPropertyUndefined:
       
   638 			{// the property does NOT exist, insert a new one
       
   639 			_LIT(KInsertProperty, "INSERT INTO %S(Name,%S,IntValue) VALUES(?,?,?)");
       
   640 			TInt formattedLen = aTableName.Length() + aIdColumnName.Length();
       
   641 			HBufC* statementStr = FormatStatementLC(KInsertProperty(), formattedLen, &aTableName, &aIdColumnName );
       
   642 			TInt numberOfValues = 3;
       
   643 			ExecuteStatementL(*statementStr, numberOfValues,EValueString, &aPropName, EValueInteger, aIdColumnValue, EValueInteger64, aPropValue);
       
   644 			CleanupStack::PopAndDestroy(statementStr);
       
   645 			break;
       
   646 			}
       
   647 		case CScrRequestImpl::EPropertyInteger:
       
   648 			{// the property exists, update it
       
   649 			_LIT(KUpdateProperty, "UPDATE %S SET IntValue=? WHERE PropertyId=?;");
       
   650 			HBufC *statementStr = FormatStatementLC(KUpdateProperty(), aTableName.Length(), &aTableName);
       
   651 			TInt numberOfValues = 2;
       
   652 			ExecuteStatementL(*statementStr, numberOfValues, EValueInteger64, aPropValue, EValueInteger, aPropertyId);
       
   653 			CleanupStack::PopAndDestroy(statementStr);
       
   654 			break;
       
   655 			}
       
   656 		default:
       
   657 			DEBUG_PRINTF(_L8("The property type isn't integer and cannot be updated with this API."));
       
   658 			User::Leave(KErrAbort);
       
   659 		}
       
   660 	}
       
   661 
       
   662 template <class A> void VerifySetPropertyParamsL(HBufC* aPropName, A* aPropValue)
       
   663 	{
       
   664 	if (!aPropName || !aPropValue)
       
   665 		User::Leave(KErrArgument);	
       
   666 	}
       
   667 	
       
   668 void CScrRequestImpl::SetComponentLocalizablePropertyL(const RMessage2& aMessage)
       
   669 	{
       
   670 	DEBUG_PRINTF(_L8("Setting component string property."));
       
   671 	// N.B. Don't change the order of IPC parameter reading, otherwise fails in UREL mode.
       
   672 	HBufC *propName = ReadDescLC(aMessage, 1);
       
   673 	HBufC *propValue = ReadDescLC(aMessage, 2);
       
   674 	VerifySetPropertyParamsL(propName, propValue);
       
   675 
       
   676 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   677 	TLanguage locale = TLanguage(aMessage.Int3());
       
   678 	
       
   679 	CScrRequestImpl::TPropertyType propType(CScrRequestImpl::EPropertyUndefined);
       
   680 	// The function name states that we don't want automatic locale resolving. If, e.g. we set a property for ELangAmerican, we don't want FindGeneralProperty to match existing value for ELangEnglish
       
   681 	TInt propertyId = FindGeneralPropertyNoLocaleDowngradeL(KComponentPropertiesTable(), KComponentIdColumnName(), componentId, *propName, locale, propType);
       
   682 	SetGeneralLocalizablePropertyL(propType, propertyId, KComponentIdColumnName(), componentId, *propName, locale, *propValue);
       
   683 	CleanupStack::PopAndDestroy(2, propName);
       
   684 	}
       
   685 
       
   686 void CScrRequestImpl::SetComponentBinaryPropertyL(const RMessage2& aMessage)
       
   687 	{
       
   688 	DEBUG_PRINTF(_L8("Setting component binary property."));
       
   689 	// N.B. Don't change the order of IPC parameter reading, otherwise fails in UREL mode.
       
   690 	HBufC *propName = ReadDescLC(aMessage, 1);
       
   691 	HBufC8 *propValue = ReadDesc8LC(aMessage, 2);
       
   692 	
       
   693 	VerifySetPropertyParamsL(propName, propValue);
       
   694 	
       
   695 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   696 	
       
   697 	CScrRequestImpl::TPropertyType propType(CScrRequestImpl::EPropertyUndefined);
       
   698 	TInt propertyId = FindGeneralPropertyNoLocaleDowngradeL(KComponentPropertiesTable(), KComponentIdColumnName(), componentId, *propName, KLangNone, propType);
       
   699 	SetGeneralBinaryPropertyL(propType, propertyId, KComponentPropertiesTable(), KComponentIdColumnName(), componentId, *propName, *propValue);
       
   700 	CleanupStack::PopAndDestroy(2, propName);
       
   701 	}
       
   702 
       
   703 void CScrRequestImpl::SetComponentIntPropertyL(const RMessage2& aMessage)
       
   704 	{
       
   705 	DEBUG_PRINTF(_L8("Setting component integer property."));
       
   706 	// N.B. Don't change the order of IPC parameter reading, otherwise fails in UREL mode.
       
   707 	HBufC* propName = ReadDescLC(aMessage, 1);
       
   708 	
       
   709 	if (!propName)
       
   710 		User::Leave(KErrArgument);
       
   711 	
       
   712 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   713 	TInt64 propValue = MAKE_TINT64(aMessage.Int2(), aMessage.Int3());	
       
   714 		
       
   715 	TPropertyType propType(CScrRequestImpl::EPropertyUndefined);
       
   716 	TInt propertyId = FindGeneralPropertyNoLocaleDowngradeL(KComponentPropertiesTable(), KComponentIdColumnName(), componentId, *propName, KLangNone, propType);
       
   717 	SetGeneralIntPropertyL(propType, propertyId, KComponentPropertiesTable(), KComponentIdColumnName(), componentId, *propName, propValue);
       
   718 	CleanupStack::PopAndDestroy(propName);
       
   719 	}
       
   720 
       
   721 TUint32 CScrRequestImpl::HashCaseInsensitiveL(const TDesC& aName)
       
   722 	{
       
   723 	RBuf temp;
       
   724 	temp.CreateMaxL(aName.Length());
       
   725 	temp.CleanupClosePushL();
       
   726 	temp.Copy(aName);
       
   727 	temp.LowerCase(); // The hashed column is case-insensitive. So, the hashed value must be
       
   728 					  // case-insensitive too. To achieve that we need to set to lower-case.	
       
   729 	TUint32 hashVal = HashCaseSensitiveL(temp);
       
   730 	CleanupStack::PopAndDestroy(&temp);
       
   731 	return hashVal;
       
   732 	}
       
   733 
       
   734 TUint32 CScrRequestImpl::HashCaseSensitiveL(const TDesC& aName)
       
   735 	{
       
   736 	TUint32 hashVal = 0;
       
   737 	Mem::Crc32(hashVal,aName.Ptr(),aName.Size());
       
   738 	return hashVal;
       
   739 	}
       
   740 
       
   741 TInt CScrRequestImpl::GetComponentFileIdL(const TDesC& aFileName, TComponentId aComponentId) const
       
   742 	{
       
   743 	DEBUG_PRINTF3(_L("Looking up a component(%d) file(%S)"), aComponentId, &aFileName);
       
   744 	
       
   745 	TUint32 hash = HashCaseInsensitiveL(aFileName);
       
   746 	_LIT(KFindComponentFile, "SELECT CmpFileId FROM ComponentsFiles WHERE ComponentId=? AND LocationHash=?;");
       
   747 	CStatement *stmtFind = iDbHandle->PrepareStatementLC(KFindComponentFile());
       
   748 	stmtFind->BindIntL(1, aComponentId);
       
   749 	stmtFind->BindIntL(2, hash);
       
   750 	
       
   751 	if(!stmtFind->ProcessNextRowL())
       
   752 		{
       
   753 		DEBUG_PRINTF3(_L("Component %d does not have File=%S!"), aComponentId, &aFileName);
       
   754 		CleanupStack::PopAndDestroy(stmtFind);
       
   755 		return KErrNotFound;
       
   756 		}
       
   757 	TInt componentFileId = stmtFind->IntColumnL(0);
       
   758 	CleanupStack::PopAndDestroy(stmtFind);
       
   759 	return componentFileId;
       
   760 	}
       
   761 
       
   762 TInt CScrRequestImpl::FindComponentFileL(const TDesC& aFileName, TComponentId aComponentId) const
       
   763 	{
       
   764 	TInt cmpFileId = GetComponentFileIdL(aFileName, aComponentId);
       
   765 	if(KErrNotFound == cmpFileId)
       
   766 		{
       
   767 		User::Leave(KErrNotFound);
       
   768 		}
       
   769 	return cmpFileId;
       
   770 	}
       
   771 
       
   772 TInt CScrRequestImpl::GetDriveFromFilePath(const TDesC& aFilePath, TDriveUnit& aDriveUnit) const
       
   773 	{
       
   774 	if(!iFs.IsValidName(aFilePath))
       
   775 		{// even if the file name validity is checked before registering the file, do double check
       
   776 		 // to be on the safe side. Because, if the file format is invalid, the rest of the code may panic.
       
   777 		DEBUG_PRINTF2(_L("The file (%S) doesn't have a valid name format!"), &aFilePath);
       
   778 		return KErrArgument;
       
   779 		}
       
   780 	
       
   781 	TParsePtrC fileParser(aFilePath);
       
   782 	TPtrC driveLetter(fileParser.Drive());
       
   783 	if(driveLetter == KNullDesC())
       
   784 		{
       
   785 		DEBUG_PRINTF2(_L("The file (%S) doesn't contain any drive letter!"), &aFilePath);
       
   786 		return KErrArgument;
       
   787 		}
       
   788 	aDriveUnit = driveLetter;
       
   789 	return KErrNone;
       
   790 	}
       
   791 
       
   792 TInt CScrRequestImpl::InstalledDrivesToBitmaskL(const TDriveList& aDriveList) const
       
   793 	{
       
   794 	TInt installedDrives(0);
       
   795 	for(TInt driveNum=EDriveA; driveNum<=EDriveZ; ++driveNum)
       
   796 		{
       
   797 		if(aDriveList[driveNum])
       
   798 			{
       
   799 			installedDrives |= 1<<driveNum;
       
   800 			}
       
   801 		}
       
   802 	return installedDrives;
       
   803 	}
       
   804 
       
   805 TInt CScrRequestImpl::GetInstalledDrivesBitmaskL(TComponentId aComponentId) const
       
   806 	{
       
   807 	// Get installed drives list from database
       
   808 	_LIT(KSelectInstalledDrivesBitmask, "SELECT InstalledDrives FROM Components WHERE ComponentId=?;");
       
   809 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectInstalledDrivesBitmask);
       
   810 	stmt->BindIntL(1, aComponentId);
       
   811 	if(!stmt->ProcessNextRowL())
       
   812 		{
       
   813 		DEBUG_PRINTF2(_L8("Component (%d) couldn't be found in the SCR database."), aComponentId);
       
   814 		User::Leave(KErrNotFound);
       
   815 		}
       
   816 	TInt res = stmt->IntColumnL(0);
       
   817 	CleanupStack::PopAndDestroy(stmt);
       
   818 	return res;
       
   819 	}
       
   820 
       
   821 TBool CScrRequestImpl::HasFilesOnDriveL(TDriveUnit aDrive, TComponentId aComponentId)
       
   822 	{
       
   823 	CStatement *stmt = OpenFileListStatementL(aComponentId);
       
   824 	CleanupStack::PushL(stmt);
       
   825 	HBufC *nextFilePath(NULL);
       
   826 	TBool returnValue(EFalse);
       
   827 	
       
   828 	while ( returnValue == EFalse && (nextFilePath = GetNextFilePathL(*stmt)) != NULL)
       
   829 		{
       
   830 		TDriveUnit fileDrive;
       
   831 		TInt res = GetDriveFromFilePath(*nextFilePath, fileDrive);
       
   832 		// Files with invalid paths are ignored
       
   833 		if (res == KErrNone && fileDrive == aDrive)
       
   834 			{
       
   835 			returnValue = ETrue;
       
   836 			}
       
   837 		delete nextFilePath;			
       
   838 		}
       
   839 		
       
   840 	CleanupStack::PopAndDestroy(stmt);
       
   841 	return returnValue;
       
   842 	}
       
   843 	
       
   844 void CScrRequestImpl::UpdateInstalledDrivesL(TComponentId aComponentId, const TDesC& aFilePath, TFileOperationType aType)
       
   845 	{
       
   846 	TDriveUnit drive;
       
   847 	User::LeaveIfError(GetDriveFromFilePath(aFilePath, drive));
       
   848 	
       
   849 	TInt driveNum = static_cast<TInt>(drive);	
       
   850 	TInt oldDrivesBitmask = GetInstalledDrivesBitmaskL(aComponentId);
       
   851 
       
   852 	TInt newDrivesBitmask = oldDrivesBitmask;
       
   853 	// Update the list of installed drives
       
   854 	if(aType == EFileRegistered)
       
   855 		{
       
   856 		newDrivesBitmask |= 0x1 << driveNum;
       
   857 		}
       
   858 	else // aType == EFileUnregistered
       
   859 		{
       
   860 		TBool hasOtherFilesOnTheDrive = HasFilesOnDriveL(drive, aComponentId);
       
   861 		if (!hasOtherFilesOnTheDrive)
       
   862 			{
       
   863 			// Do a logical AND with a bitmask which looks like 111110111111
       
   864 			TInt andBitmask = ~(0x1 << driveNum);
       
   865 			newDrivesBitmask &= andBitmask;
       
   866 			}
       
   867 		}
       
   868 
       
   869 	if (newDrivesBitmask != oldDrivesBitmask)
       
   870 		{
       
   871 		// Write back the updated installed drives and list 
       
   872 		_LIT(KUpdateInstalledDrives, "UPDATE Components SET InstalledDrives=? WHERE ComponentId=?;");
       
   873 		TInt numberOfValues = 2;
       
   874 		ExecuteStatementL(KUpdateInstalledDrives, numberOfValues, EValueInteger, newDrivesBitmask, EValueInteger, aComponentId);
       
   875 		}
       
   876 	}
       
   877 
       
   878 void CScrRequestImpl::RegisterComponentFileL(const RMessage2& aMessage)
       
   879    	{
       
   880 	DEBUG_PRINTF(_L8("Registering component file."));
       
   881    	
       
   882    	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   883    	HBufC* fileName = ReadFileNameFromMsgLC(aMessage);
       
   884  	TBool considerFileInDrivesList = aMessage.Int2();	
       
   885    	TUint32 hash = HashCaseInsensitiveL(*fileName);
       
   886 	TDriveUnit drive(*fileName);
       
   887    	TVolumeInfo volInfo;
       
   888    	
       
   889    	_LIT(KInsertFile, "INSERT INTO ComponentsFiles(ComponentId,LocationHash,Location) VALUES(?,?,?);");
       
   890    	TInt numberOfValues = 3;
       
   891    	ExecuteStatementL(KInsertFile(), numberOfValues, EValueInteger, componentId, EValueInteger, hash, EValueString, fileName);
       
   892    	// Reflect this file addition in the installed drives field of the components table
       
   893 	// Or the drive list is updated in case of a FILENULL operation on a removable drive
       
   894    	// If this step fails (for example, this file name is incorrect) then we cannot register the file
       
   895  	if (KErrNone == iFs.Volume(volInfo, drive) || considerFileInDrivesList)
       
   896  		UpdateInstalledDrivesL(componentId, *fileName, EFileRegistered);
       
   897  	
       
   898    	CleanupStack::PopAndDestroy(fileName);
       
   899    	}
       
   900 
       
   901 void CScrRequestImpl::SetFileStrPropertyL(const RMessage2& aMessage)
       
   902 	{
       
   903 	DEBUG_PRINTF(_L8("Setting file string property."));
       
   904 	
       
   905 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);	
       
   906 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
   907 	
       
   908 	TInt compFileId = FindComponentFileL(*fileName, componentId);
       
   909 		
       
   910 	HBufC* propName  = ReadDescLC(aMessage, 2);
       
   911 	TPropertyType propType(CScrRequestImpl::EPropertyUndefined);
       
   912 	TInt propertyId = FindGeneralPropertyNoLocaleDowngradeL(KFilePropertiesTable(), KCompFileIdColumnName(), compFileId, *propName, KLangNone, propType);
       
   913 	
       
   914 	HBufC8* propValue = ReadDesc8LC(aMessage, 3);
       
   915 	SetGeneralBinaryPropertyL(propType, propertyId, KFilePropertiesTable(), KCompFileIdColumnName(), compFileId, *propName, *propValue);
       
   916 	CleanupStack::PopAndDestroy(3, fileName);
       
   917 	}
       
   918 
       
   919 void CScrRequestImpl::SetFileIntPropertyL(const RMessage2& aMessage)
       
   920 	{
       
   921 	DEBUG_PRINTF(_L8("Setting integer file property."));
       
   922 		
       
   923 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   924 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
   925 	TInt compFileId = FindComponentFileL(*fileName, componentId);
       
   926 	
       
   927 	HBufC* propName  = ReadDescLC(aMessage, 2);
       
   928 	TPropertyType propType(CScrRequestImpl::EPropertyUndefined);
       
   929 	TInt propertyId = FindGeneralPropertyNoLocaleDowngradeL(KFilePropertiesTable(), KCompFileIdColumnName(), compFileId, *propName, KLangNone, propType);
       
   930 	
       
   931 	TInt propValue   = aMessage.Int3();
       
   932 	SetGeneralIntPropertyL(propType, propertyId, KFilePropertiesTable(), KCompFileIdColumnName(), compFileId, *propName, propValue);
       
   933 	CleanupStack::PopAndDestroy(2, fileName);
       
   934 	}
       
   935 
       
   936 void CScrRequestImpl::SetComponentLocalizableL(TComponentId aComponentId, TLanguage aLocale, const TDesC& aColumnName, const TDesC& aName, const TDesC& aVendor)
       
   937 	{
       
   938 	_LIT(KFindComponentLocalizable, "SELECT CompLocalId FROM ComponentLocalizables WHERE ComponentId=? AND Locale=?;");
       
   939 	TInt numberOfValues = 2;
       
   940 	CStatement *stmt = CreateStatementObjectWithLocaleL(KFindComponentLocalizable, aLocale, numberOfValues, EValueInteger, aComponentId, EValueLanguage);	
       
   941 	
       
   942 	if(!stmt)
       
   943 		{// Add a new name for this component
       
   944 		AddComponentLocalizablesL(aComponentId, aLocale, aName, aVendor);
       
   945 		}
       
   946 	else
       
   947 		{// Exists, update the localizable field of the component
       
   948 		CleanupStack::PushL(stmt);
       
   949 		TInt compLocId = stmt->IntColumnL(0);
       
   950 		_LIT(KUpdateComponentName, "UPDATE ComponentLocalizables SET %S=? WHERE CompLocalId=?;");
       
   951 		HBufC *statementStr = FormatStatementLC(KUpdateComponentName, aColumnName.Length(), &aColumnName);
       
   952 		const TDesC *value = aName.Length() ? &aName : &aVendor;
       
   953 		TInt numberOfValues = 2;
       
   954 		ExecuteStatementL(*statementStr, numberOfValues, EValueString, value, EValueInteger, compLocId);
       
   955 		CleanupStack::PopAndDestroy(2, stmt); // stmt, statementStr
       
   956 		}
       
   957 	}
       
   958 
       
   959 void CScrRequestImpl::SetComponentNameL(const RMessage2& aMessage)
       
   960 	{
       
   961 	DEBUG_PRINTF(_L8("Setting component name."));
       
   962 	
       
   963 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   964 	HBufC *componentName = ReadDescLC(aMessage, 1);
       
   965 	if (!componentName->CompareF(KNullDesC()))
       
   966 		{// Component name cannot be empty
       
   967 		DEBUG_PRINTF(_L8("Component name cannot be set or modified to a NULL string."));
       
   968 		User::Leave(KErrArgument);
       
   969 		}	
       
   970 		
       
   971 	TLanguage locale = TLanguage(aMessage.Int2());
       
   972 	_LIT(KComponentNameField,"Name");
       
   973 	SetComponentLocalizableL(componentId, locale, KComponentNameField, *componentName, KNullDesC());
       
   974 	CleanupStack::PopAndDestroy(componentName);
       
   975 	}
       
   976 
       
   977 void CScrRequestImpl::SetVendorNameL(const RMessage2& aMessage)
       
   978 	{
       
   979 	DEBUG_PRINTF(_L8("Setting vendor name."));
       
   980 	
       
   981 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   982 	HBufC *vendorName = ReadDescLC(aMessage, 1);
       
   983 	TLanguage locale = TLanguage(aMessage.Int2());
       
   984 	_LIT(KComponentVendorField,"Vendor");
       
   985 	SetComponentLocalizableL(componentId, locale, KComponentVendorField, KNullDesC(), *vendorName);
       
   986 	CleanupStack::PopAndDestroy(vendorName);
       
   987 	}
       
   988 
       
   989 void CScrRequestImpl::ReadAndSetCommonComponentPropertyL(const RMessage2& aMessage, const TDesC& aPropertyColumn)
       
   990 	{
       
   991 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
   992 	TInt propertyValue = aMessage.Int1();
       
   993 	
       
   994 	_LIT(KUpdateCommonProperty, "UPDATE Components SET %S=? WHERE ComponentId=?;");
       
   995 	TInt formattedLen = aPropertyColumn.Length();
       
   996 	HBufC *statementStr = FormatStatementLC(KUpdateCommonProperty(), formattedLen, &aPropertyColumn );
       
   997 	TInt numberOfValues = 2;
       
   998 	ExecuteStatementL(*statementStr, numberOfValues, EValueInteger, propertyValue, EValueInteger, componentId);
       
   999 	CleanupStack::PopAndDestroy(statementStr);
       
  1000 	}
       
  1001 
       
  1002 void CScrRequestImpl::SetIsComponentRemovableL(const RMessage2& aMessage)
       
  1003 	{
       
  1004 	DEBUG_PRINTF(_L8("Setting the component's removable attribute."));
       
  1005 	_LIT(KColumnNameRemovable, "Removable");
       
  1006 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameRemovable);
       
  1007 	}
       
  1008 
       
  1009 void CScrRequestImpl::SetIsComponentDrmProtectedL(const RMessage2& aMessage)
       
  1010 	{
       
  1011 	DEBUG_PRINTF(_L8("Setting the component's DRM protected attribute."));
       
  1012 	_LIT(KColumnNameDrmProtected, "DRMProtected");
       
  1013 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameDrmProtected);	
       
  1014 	}
       
  1015 
       
  1016 void CScrRequestImpl::SetIsComponentHiddenL(const RMessage2& aMessage)
       
  1017 	{
       
  1018 	DEBUG_PRINTF(_L8("Setting the component's hidden attribute."));
       
  1019 	_LIT(KColumnNameHidden, "Hidden");
       
  1020 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameHidden);		
       
  1021 	}
       
  1022 
       
  1023 void CScrRequestImpl::SetIsComponentKnownRevokedL(const RMessage2& aMessage)
       
  1024 	{
       
  1025 	DEBUG_PRINTF(_L8("Setting the component's known-revoked attribute."));
       
  1026 	_LIT(KColumnNameKnownRevoked, "KnownRevoked");
       
  1027 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameKnownRevoked);	
       
  1028 	}
       
  1029 
       
  1030 void CScrRequestImpl::SetIsComponentOriginVerifiedL(const RMessage2& aMessage)
       
  1031 	{
       
  1032 	DEBUG_PRINTF(_L8("Setting the component's removable attribute."));
       
  1033 	_LIT(KColumnNameOriginVerified, "OriginVerified");
       
  1034 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameOriginVerified);	
       
  1035 	}
       
  1036 		
       
  1037 void CScrRequestImpl::SetComponentSizeL(const RMessage2& aMessage)
       
  1038 	{
       
  1039 	DEBUG_PRINTF(_L8("Setting the component's install-time size."));
       
  1040 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1041 	TInt64 componentSize = MAKE_TINT64(aMessage.Int1(), aMessage.Int2());
       
  1042 	if (componentSize < 0)
       
  1043 		{
       
  1044 		DEBUG_PRINTF2(_L8("Received incorrect component size: %d."), componentSize);
       
  1045 		User::Leave(KErrArgument);
       
  1046 		}
       
  1047 	_LIT(KUpdateComponentSize, "UPDATE Components SET Size=? WHERE ComponentId=?;");
       
  1048 	TInt numberOfValues = 2;
       
  1049 	ExecuteStatementL(KUpdateComponentSize, numberOfValues, EValueInteger64, componentSize, EValueInteger, componentId);
       
  1050 	}
       
  1051 
       
  1052 TBool FindLogEntryWithComponentId(const TComponentId *aKey, const CScrLogEntry& aEntry)
       
  1053 	{
       
  1054 	return (*aKey == aEntry.ComponentId()); 
       
  1055 	}
       
  1056 
       
  1057 void CScrRequestImpl::SetComponentVersionL(const RMessage2& aMessage)
       
  1058 	{
       
  1059 	DEBUG_PRINTF(_L8("Setting component version."));
       
  1060 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1061 	HBufC *version = ReadDescLC(aMessage, 1);
       
  1062 	
       
  1063 	_LIT(KUpdateVersion, "UPDATE Components SET Version=? WHERE ComponentId=?;");
       
  1064 	TInt numberOfValues = 2;
       
  1065 	ExecuteStatementL(KUpdateVersion, numberOfValues, EValueString, version, EValueInteger, componentId);
       
  1066 	
       
  1067 	TInt logIdx = iLogEntries.Find(componentId, FindLogEntryWithComponentId);
       
  1068 	if(KErrNotFound == logIdx)
       
  1069 		{
       
  1070 		CleanupStack::PopAndDestroy(version);
       
  1071 		return;
       
  1072 		}
       
  1073 	DeleteObjectZ(iLogEntries[logIdx]->iVersion);
       
  1074 	iLogEntries[logIdx]->iVersion = version; // Ownership is transferred
       
  1075 	CleanupStack::Pop(version);
       
  1076 	}
       
  1077 
       
  1078 void CScrRequestImpl::DeleteComponentPropertyL(const RMessage2& aMessage)
       
  1079 	{
       
  1080 	DEBUG_PRINTF(_L8("Deleting component property."));
       
  1081 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1082 	HBufC *name = ReadDescLC(aMessage, 1);
       
  1083 	
       
  1084 	_LIT(KDeleteComponentProperty, "DELETE FROM ComponentProperties WHERE Name=? AND ComponentId=?;");
       
  1085 	TInt numberOfValues = 2;
       
  1086 	ExecuteStatementL(KDeleteComponentProperty, numberOfValues, EValueString, name, EValueInteger, componentId);
       
  1087 	CleanupStack::PopAndDestroy(name);
       
  1088 	}
       
  1089 
       
  1090 void CScrRequestImpl::DeleteFilePropertyL(const RMessage2& aMessage)
       
  1091 	{
       
  1092 	DEBUG_PRINTF(_L8("Deleting file property."));
       
  1093 	
       
  1094 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1095 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
  1096 	
       
  1097 	TInt compFileId = FindComponentFileL(*fileName, componentId);
       
  1098 	HBufC *propName = ReadDescLC(aMessage, 2);
       
  1099 	
       
  1100 	_LIT(KDeleteFileProperty, "DELETE FROM FileProperties WHERE CmpFileId=? AND Name=?;");
       
  1101 	TInt numberOfValues = 2;
       
  1102 	ExecuteStatementL(KDeleteFileProperty, numberOfValues, EValueInteger, compFileId, EValueString, propName);
       
  1103 	CleanupStack::PopAndDestroy(2, fileName);
       
  1104 	}
       
  1105 
       
  1106 void CScrRequestImpl::UnregisterComponentFileL(const RMessage2& aMessage)
       
  1107 	{
       
  1108 	DEBUG_PRINTF(_L8("Unregistering a component file."));
       
  1109 	
       
  1110 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1111 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
  1112 	
       
  1113 	TInt compFileId = GetComponentFileIdL(*fileName, componentId);
       
  1114 	if (compFileId == KErrNotFound)
       
  1115 		{
       
  1116 		CleanupStack::PopAndDestroy(fileName);
       
  1117 		return; // If the file is not registered, we do not return an error - this sort of condition is better enforced at upper layers 
       
  1118 		}
       
  1119 		
       
  1120 	_LIT(KDeleteComponentFileProperties, "DELETE from FileProperties WHERE CmpFileId=?;");
       
  1121 	TInt numberOfValues = 1;
       
  1122 	ExecuteStatementL(KDeleteComponentFileProperties, numberOfValues, EValueInteger, compFileId);
       
  1123 	DEBUG_PRINTF3(_L("Properties of the file(%S) of the component(%d) have been deleted."), fileName, componentId);
       
  1124 
       
  1125 	_LIT(KUnregisterComponentFile, "DELETE FROM ComponentsFiles WHERE CmpFileId=?;");
       
  1126 	ExecuteStatementL(KUnregisterComponentFile, numberOfValues, EValueInteger, compFileId);
       
  1127 
       
  1128 	// Reflect this file deletion in the installed drives field of the components table
       
  1129 	UpdateInstalledDrivesL(componentId, *fileName, EFileUnregistered);
       
  1130 	CleanupStack::PopAndDestroy(fileName);
       
  1131 	}
       
  1132 
       
  1133 void ReadNullableStringFromStatementL(CStatement& aStmt, TPtrC& aValue, TInt aFieldNum)
       
  1134 	{
       
  1135 	aValue.Set(KNullDesC());
       
  1136 	if(!aStmt.IsFieldNullL(aFieldNum))
       
  1137 		{ // If the value is not NULL, set it.
       
  1138 		aValue.Set(aStmt.StrColumnL(aFieldNum));
       
  1139 		}
       
  1140 	}
       
  1141 
       
  1142 void CScrRequestImpl::DeleteComponentL(const RMessage2& aMessage)
       
  1143 	{
       
  1144 	DEBUG_PRINTF(_L8("Deleting a component."));
       
  1145 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1146 	DEBUG_PRINTF2(_L8("Deleting component(%d)."), componentId);
       
  1147 	
       
  1148 	// Create the log record before deleting the component
       
  1149 	_LIT(KSelectComponentInfo, "SELECT SoftwareTypeName,GlobalId,Version FROM Components WHERE ComponentId=?;");
       
  1150 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectComponentInfo);
       
  1151 	stmt->BindIntL(1, componentId);
       
  1152 	
       
  1153 	// if the component doesn't exist, the code shouldn't come here. It should have left with KErrNotFound at security check level.
       
  1154 	__ASSERT_ALWAYS(stmt->ProcessNextRowL(), User::Leave(KErrAbort));
       
  1155 	
       
  1156 	CComponentEntry *entry2bDeleted = CComponentEntry::NewLC();
       
  1157 	entry2bDeleted->iSwType = stmt->StrColumnL(0).AllocL();
       
  1158 	
       
  1159 	TPtrC globalId;
       
  1160 	ReadNullableStringFromStatementL(*stmt, globalId, 1);
       
  1161 	if(globalId.Length() > 0)
       
  1162 		{
       
  1163 		CGlobalComponentId *globalIdObj = ParseGlobalComponendIdLC(globalId);
       
  1164 		entry2bDeleted->iGlobalId = globalIdObj->GlobalIdName().AllocL();
       
  1165 		CleanupStack::PopAndDestroy(globalIdObj);
       
  1166 		}
       
  1167 	else
       
  1168 		{
       
  1169 		entry2bDeleted->iGlobalId = globalId.AllocL();
       
  1170 		}
       
  1171 	TPtrC version;
       
  1172 	ReadNullableStringFromStatementL(*stmt, version, 2);
       
  1173 	entry2bDeleted->iVersion = version.AllocL();
       
  1174 	AddComponentEntryLocalizablesL(componentId, *entry2bDeleted, KUnspecifiedLocale);
       
  1175 
       
  1176 	CScrLogEntry *logRecord = CScrLogEntry::NewL(entry2bDeleted->Name(), entry2bDeleted->SoftwareType(), entry2bDeleted->GlobalId(), entry2bDeleted->Version(), EScrCompUnInstall);
       
  1177 	logRecord->iComponentId = componentId;
       
  1178 	CleanupStack::PopAndDestroy(2, stmt); // stmt, entry2bDeleted
       
  1179 	CleanupStack::PushL(logRecord);
       
  1180 	
       
  1181 	// Now begin the component deletion
       
  1182 	TInt numberOfValues = 1;
       
  1183 	_LIT(KDeleteComponentProperties,"DELETE FROM ComponentProperties WHERE ComponentId=?;");
       
  1184 	ExecuteStatementL(KDeleteComponentProperties, numberOfValues, EValueInteger, componentId);
       
  1185 	DEBUG_PRINTF2(_L8("Properties of component(%d) have been deleted."), componentId);
       
  1186 	
       
  1187 	_LIT(KDeleteComponentFileProperties, "DELETE from FileProperties WHERE CmpFileId IN \
       
  1188 				(SELECT CmpFileId FROM ComponentsFiles WHERE ComponentId=?);");
       
  1189 	ExecuteStatementL(KDeleteComponentFileProperties, numberOfValues, EValueInteger, componentId);
       
  1190 	DEBUG_PRINTF2(_L8("Properties of files of component(%d) have been deleted."), componentId);
       
  1191 
       
  1192 	_LIT(KDeleteComponentFiles, "DELETE FROM ComponentsFiles WHERE ComponentId=?;");
       
  1193 	ExecuteStatementL(KDeleteComponentFiles, numberOfValues, EValueInteger, componentId);
       
  1194 	DEBUG_PRINTF2(_L8("File registrations of component(%d) have been deleted."), componentId);
       
  1195 
       
  1196 	_LIT(KDeleteComponentLocalizables, "DELETE FROM ComponentLocalizables WHERE ComponentId=?;");
       
  1197 	ExecuteStatementL(KDeleteComponentLocalizables, numberOfValues, EValueInteger, componentId);
       
  1198 	DEBUG_PRINTF2(_L8("Localizables of component(%d) have been deleted."), componentId);
       
  1199 	
       
  1200 	// Delete all dependencies where this component is dependant
       
  1201 	_LIT(KDeleteComponentDependencies, "DELETE FROM ComponentDependencies WHERE DependantGlobalIdHash IN \
       
  1202 				(SELECT GlobalIdHash FROM Components WHERE ComponentId=?);");
       
  1203 	ExecuteStatementL(KDeleteComponentDependencies, numberOfValues, EValueInteger, componentId);
       
  1204 	DEBUG_PRINTF2(_L8("Dependencies of component(%d) have been deleted."), componentId);
       
  1205 	
       
  1206 	_LIT(KDeleteComponents, "DELETE FROM Components WHERE ComponentId=?;");
       
  1207 	ExecuteStatementL(KDeleteComponents, numberOfValues, EValueInteger, componentId);
       
  1208 	DEBUG_PRINTF2(_L8("Finally component(%d) has been deleted."), componentId);
       
  1209 	
       
  1210 	// Add log record
       
  1211 	iLogEntries.Append(logRecord);
       
  1212 	CleanupStack::Pop(logRecord); // Ownership is transferred
       
  1213 	}
       
  1214 
       
  1215 void CScrRequestImpl::DeleteComponentDependencyL(const RMessage2& aMessage)
       
  1216 	{
       
  1217 	DEBUG_PRINTF(_L8("Deleting a component dependency."));
       
  1218 	
       
  1219 	HBufC *suppGlobalId = ReadAndGetGlobalIdLC(aMessage, 1);
       
  1220 	HBufC *depGlobalId = ReadAndGetGlobalIdLC(aMessage, 2);
       
  1221 	TUint32 globalIdsHash = HashGlobalIdsL(*depGlobalId, *suppGlobalId);
       
  1222 	CleanupStack::PopAndDestroy(2, suppGlobalId); // suppGlobalId,depGlobalId
       
  1223 	
       
  1224 	_LIT(KDeleteDependency, "DELETE FROM ComponentDependencies WHERE GlobalIdHash=?;");
       
  1225 	TInt numberOfValues = 1;
       
  1226 	ExecuteStatementL(KDeleteDependency(), numberOfValues, EValueInteger, globalIdsHash);
       
  1227 	}
       
  1228 
       
  1229 TBool CScrRequestImpl::BindAndProcessStatementObjectL(CStatement& aStatementObj, TLanguage aLanguage, TInt aValuesNum, VA_LIST aList) const
       
  1230 	{
       
  1231 	aStatementObj.ResetL();
       
  1232 	BindStatementValuesL(aStatementObj, aLanguage, aValuesNum, aList);
       
  1233 	return aStatementObj.ProcessNextRowL();
       
  1234 	}
       
  1235 
       
  1236 CStatement* CScrRequestImpl::CreateStatementObjectWithoutLocaleL(const TDesC& aStatement, TInt aValuesNum,...) const	
       
  1237 	{
       
  1238 	VA_LIST argList;
       
  1239 	VA_START(argList, aValuesNum);
       
  1240 	
       
  1241 	CStatement *stmt = iDbHandle->PrepareStatementLC(aStatement);
       
  1242 	
       
  1243 	// The language parameter is irrelevant. The BindAndProcessStatementObjectL is reused here to avoid code duplication. 
       
  1244 	TBool success = BindAndProcessStatementObjectL(*stmt, ELangNone, aValuesNum, argList);
       
  1245 	
       
  1246 	VA_END(argList);
       
  1247 	
       
  1248 	if(!success)
       
  1249 		{ // if the code reaches here, it means there is no record for the given criteria
       
  1250 		CleanupStack::PopAndDestroy(stmt);
       
  1251 		return NULL;
       
  1252 		}
       
  1253 	CleanupStack::Pop(stmt);
       
  1254 	return stmt;	
       
  1255 	}
       
  1256 
       
  1257 CStatement* CScrRequestImpl::CreateStatementObjectWithLocaleNoDowngradeL(const TDesC& aStatement, TLanguage aLocale, TInt aValuesNum,...) const	
       
  1258 	{
       
  1259 	VA_LIST argList;
       
  1260 	VA_START(argList, aValuesNum);	
       
  1261 	
       
  1262 	CStatement *stmt = iDbHandle->PrepareStatementLC(aStatement);	
       
  1263 	TBool success = BindAndProcessStatementObjectL(*stmt, aLocale, aValuesNum, argList);
       
  1264 		
       
  1265 	if(!success)
       
  1266 		{ // if the code reaches here, it means there is no record for the given criteria		
       
  1267 		CleanupStack::PopAndDestroy(stmt);			
       
  1268 		return NULL;
       
  1269 		}
       
  1270 		
       
  1271 	CleanupStack::Pop(stmt);	
       
  1272 	return stmt;
       
  1273 	
       
  1274 	}
       
  1275 
       
  1276 // This function tries automatically downgrading languages to the nearest locale	
       
  1277 CStatement* CScrRequestImpl::CreateStatementObjectWithLocaleL(const TDesC& aStatement, TLanguage aLocale, TInt aValuesNum,...) const
       
  1278 	{
       
  1279 	VA_LIST argList;
       
  1280 	VA_START(argList, aValuesNum);
       
  1281 	
       
  1282 	CStatement *stmt = iDbHandle->PrepareStatementLC(aStatement);
       
  1283 	//Avoiding call to BAFL for the current locale. If succeeds, BAFL will not be invoked
       
  1284 	TBool success = BindAndProcessStatementObjectL(*stmt, aLocale, aValuesNum, argList);	
       
  1285     VA_START(argList, aValuesNum);
       
  1286 	
       
  1287 	if ( !success )
       
  1288 	   {
       
  1289        // Run the given statement for the passed or its equivalent languages
       
  1290        // First, get the Equivalent Language path for the given locale. The first element
       
  1291        // in the array is the given language.		
       
  1292        TLanguagePath equivalentLanguages;
       
  1293        BaflUtils::GetEquivalentLanguageList(aLocale, equivalentLanguages);
       
  1294     
       
  1295        TInt i = 1; //skipping the current locale
       
  1296        while ( equivalentLanguages[i] != ELangNone && !success)	
       
  1297            {
       
  1298            success = BindAndProcessStatementObjectL(*stmt, equivalentLanguages[i], aValuesNum, argList);
       
  1299            VA_START(argList, aValuesNum);
       
  1300            i++;
       
  1301            }
       
  1302        VA_END(argList);
       
  1303         
       
  1304        if(!success)
       
  1305            { // if the code reaches here, it means there is no record for the given criteria       
       
  1306            CleanupStack::PopAndDestroy(stmt);          
       
  1307            return NULL;
       
  1308            }
       
  1309 	    }
       
  1310 	else
       
  1311 		{
       
  1312 		VA_END(argList);
       
  1313 		}
       
  1314 
       
  1315 	CleanupStack::Pop(stmt);	
       
  1316 	return stmt;
       
  1317 	}
       
  1318 
       
  1319 CComponentEntry* CScrRequestImpl::CreateComponentEntryFromStatementHandleL(CStatement& aStmt) const
       
  1320 	{
       
  1321 	TComponentId componentId = aStmt.IntColumnL(0);
       
  1322 	TInt removable = aStmt.IntColumnL(3);
       
  1323 	TInt64 size = aStmt.Int64ColumnL(4);
       
  1324 	TScomoState scomoState = TScomoState(aStmt.IntColumnL(5));
       
  1325 	
       
  1326 	TInt drmProtected = aStmt.IntColumnL(6);
       
  1327 	TInt hidden = aStmt.IntColumnL(7);
       
  1328 	TInt knownRevoked = aStmt.IntColumnL(8);
       
  1329 	TInt originVerified = aStmt.IntColumnL(9);
       
  1330 	
       
  1331 	TPtrC globalIdDes;
       
  1332 	ReadNullableStringFromStatementL(aStmt, globalIdDes, 10);
       
  1333 	HBufC *globalId = NULL;
       
  1334 	if(globalIdDes.Length())
       
  1335 		{ // if global id is not NULL
       
  1336 		CGlobalComponentId *globalIdObj = ParseGlobalComponendIdLC(globalIdDes);
       
  1337 		globalId = globalIdObj->GlobalIdName().AllocL();
       
  1338 		CleanupStack::PopAndDestroy(globalIdObj);
       
  1339 		CleanupStack::PushL(globalId);
       
  1340 		}
       
  1341 	else
       
  1342 		{ // Global Id is NULL
       
  1343 		globalId = KNullDesC().AllocLC();
       
  1344 		}
       
  1345 	
       
  1346 	TInt installedDrivesBitmask = aStmt.IntColumnL(11);
       
  1347 	// Convert bitmask to TDriveList
       
  1348 	TDriveList installedDriveList;
       
  1349 	installedDriveList.FillZ(KMaxDrives);
       
  1350 	for (TInt i = 0; i < KMaxDrives && installedDrivesBitmask > 0; ++i, installedDrivesBitmask >>= 1)
       
  1351 		{
       
  1352 		installedDriveList[i] = installedDrivesBitmask & 0x1;
       
  1353 		}
       
  1354 	
       
  1355 	TPtrC version(KNullDesC());
       
  1356 	if(!aStmt.IsFieldNullL(12))
       
  1357 		version.Set(aStmt.StrColumnL(12));
       
  1358 	
       
  1359 	TPtrC installTime = aStmt.StrColumnL(13);
       
  1360 		
       
  1361 	CComponentEntry *entry = CComponentEntry::NewL(componentId, KNullDesC, KNullDesC, KNullDesC, *globalId, removable, size, scomoState, installedDriveList, version, installTime, drmProtected, hidden, knownRevoked, originVerified);
       
  1362 	CleanupStack::PopAndDestroy(globalId);
       
  1363 	return entry;
       
  1364 	}
       
  1365 
       
  1366 //
       
  1367 // aLocalizableStmtStr = A SELECT statement which queries a table for a specific locale. In other words, the statement has got a locale condition.
       
  1368 // aAnyValueStmtStr = A SELECT statement which doesn't contain a locale condition. The result row set will include records with any locale.
       
  1369 // aConditionIntValue = The value of the integer condition of the statements given.
       
  1370 // aConditionLocale = The value of the locale condition of the localizable statement (first parameter).
       
  1371 //
       
  1372 CStatement* CScrRequestImpl::ExecuteLocalizableStatementL(const TDesC& aLocalizableStmtStr, const TDesC& aAnyValueStmtStr, TInt aConditionIntValue, TLanguage aConditionLocale) const
       
  1373 	{
       
  1374 	TInt numberOfValues = 2;
       
  1375 	CStatement *stmtLoc(0);
       
  1376 	
       
  1377 	if(KUnspecifiedLocale == aConditionLocale)
       
  1378 		{
       
  1379 		// The locale is not specified. So, first try to run the statement for the current locale and its downgraded languages.
       
  1380 		stmtLoc = CreateStatementObjectWithLocaleL(aLocalizableStmtStr, User::Language(), numberOfValues, EValueInteger, aConditionIntValue, EValueLanguage);
       
  1381 		if (!stmtLoc)
       
  1382 			{
       
  1383 			// No result for the current locale at all. Try to find non-localized values.
       
  1384 			stmtLoc = CreateStatementObjectWithLocaleL(aLocalizableStmtStr, KNonLocalized, numberOfValues, EValueInteger, aConditionIntValue, EValueLanguage);			
       
  1385 			}
       
  1386 
       
  1387 		if (!stmtLoc)
       
  1388 			{
       
  1389 			// No result for the current locale or the non-localized, "neutral" locale. Try finding any locale
       
  1390 			stmtLoc = CreateStatementObjectWithoutLocaleL(aAnyValueStmtStr, 1, EValueInteger, aConditionIntValue);		
       
  1391 			}
       
  1392 		}
       
  1393 		else if(KNonLocalized == aConditionLocale)
       
  1394 			{
       
  1395 			// Only non-localized names are requested.
       
  1396 			stmtLoc = CreateStatementObjectWithLocaleL(aLocalizableStmtStr, KNonLocalized, numberOfValues, EValueInteger, aConditionIntValue, EValueLanguage);
       
  1397 			}
       
  1398 		else
       
  1399 			{
       
  1400 			// Names are requested for a particular locale.
       
  1401 			stmtLoc = CreateStatementObjectWithLocaleL(aLocalizableStmtStr, aConditionLocale, numberOfValues, EValueInteger, aConditionIntValue, EValueLanguage);
       
  1402 			}
       
  1403 	
       
  1404 	return stmtLoc;
       
  1405 	}
       
  1406 
       
  1407 void CScrRequestImpl::AddComponentEntryLocalizablesL(TComponentId aComponentId, CComponentEntry& aEntry, TLanguage aLocale) const
       
  1408 	{
       
  1409 	_LIT(KSelectLocalizableNames, "SELECT Name,Vendor FROM ComponentLocalizables WHERE ComponentId=? AND Locale=?;");
       
  1410 	_LIT(KSelectAnyNames, "SELECT Name,Vendor FROM ComponentLocalizables WHERE ComponentId=?;");
       
  1411 	
       
  1412 	CStatement *stmtLoc = ExecuteLocalizableStatementL(KSelectLocalizableNames, KSelectAnyNames, aComponentId, aLocale);	
       
  1413 	if(!stmtLoc)
       
  1414 		{
       
  1415 		DEBUG_PRINTF3(_L8("Name and Vendor couldn't be found for the component (%d) and locale(%d)."), aComponentId, aLocale);
       
  1416 		User::Leave(KErrScrUnsupportedLocale);
       
  1417 		}
       
  1418 
       
  1419 	CleanupStack::PushL(stmtLoc);	
       
  1420 		
       
  1421 	TPtrC name(stmtLoc->StrColumnL(0));
       
  1422 	TPtrC vendor(stmtLoc->StrColumnL(1));
       
  1423 	DeleteObjectZ(aEntry.iName);
       
  1424 	aEntry.iName = name.AllocL(); // Ownership is transferred to the entry object
       
  1425 	DeleteObjectZ(aEntry.iVendor);
       
  1426 	if ( 0 != vendor.Ptr())
       
  1427 		aEntry.iVendor = vendor.AllocL(); // Ownership is transferred to the entry object
       
  1428 	else
       
  1429 		aEntry.iVendor = HBufC::NewL(1);
       
  1430 	
       
  1431 	CleanupStack::PopAndDestroy(stmtLoc);
       
  1432 	}
       
  1433 
       
  1434 void CScrRequestImpl::AddSoftwareTypeNameToComponentEntryL(CStatement& aStmt, CComponentEntry& aEntry, TLanguage aLocale) const
       
  1435 	{
       
  1436 	TInt softwareTypeId = aStmt.IntColumnL(1);
       
  1437 	_LIT(KSelectLocalizableSwTypeName, "SELECT Name FROM SoftwareTypeNames WHERE SoftwareTypeId=? AND Locale=?;");
       
  1438 	CStatement *stmtLoc = ExecuteLocalizableStatementL(KSelectLocalizableSwTypeName, KSelectLocalizableSwTypeName, softwareTypeId, aLocale);
       
  1439 	if(stmtLoc)
       
  1440 		{
       
  1441 		CleanupStack::PushL(stmtLoc);
       
  1442 		TPtrC name(stmtLoc->StrColumnL(0));
       
  1443 		DeleteObjectZ(aEntry.iSwType);
       
  1444 		aEntry.iSwType = name.AllocL(); // Ownership is transferred to the entry object
       
  1445 		CleanupStack::PopAndDestroy(stmtLoc);
       
  1446 		return;
       
  1447 		}
       
  1448 	
       
  1449 	// The software type doesn't exist or there is no localized name of the software type, add the unique software type name
       
  1450 	TPtrC uniqueSwTypeName = aStmt.StrColumnL(2);
       
  1451 	DeleteObjectZ(aEntry.iSwType);
       
  1452 	aEntry.iSwType = uniqueSwTypeName.AllocL(); // Ownership is transferred to the entry object
       
  1453 	}
       
  1454 
       
  1455 void CScrRequestImpl::GetGeneralComponentEntrySizeL(const RMessage2& aMessage, const TDesC& aConditionColumn, TUint32 aConditionValue, TInt aReturnSizeSlot, TLanguage aLocale, CComponentEntry*& aComponentEntry) const
       
  1456 	{
       
  1457 	_LIT(KSelectComponents, "SELECT ComponentId,SoftwareTypeId,SoftwareTypeName,Removable,Size,ScomoState,DRMProtected,Hidden,KnownRevoked,OriginVerified,GlobalId,InstalledDrives,Version,InstallTime FROM Components WHERE %S=?;");
       
  1458 	
       
  1459 	TInt formattedLen = aConditionColumn.Length();
       
  1460 	HBufC *statementStr = FormatStatementLC(KSelectComponents(), formattedLen, &aConditionColumn);
       
  1461 	CStatement *stmt = iDbHandle->PrepareStatementLC(*statementStr);
       
  1462 	stmt->BindIntL(1, aConditionValue);
       
  1463 		
       
  1464 	if(!stmt->ProcessNextRowL())
       
  1465 		{
       
  1466 		DEBUG_PRINTF2(_L8("The component(%d) couldn't be found. The size returned is zero."), aConditionValue);
       
  1467 		WriteIntValueL(aMessage, aReturnSizeSlot, 0);
       
  1468 		CleanupStack::PopAndDestroy(2, statementStr); // statementStr, stmt
       
  1469 		return;
       
  1470 		}
       
  1471 		
       
  1472 	DeleteObjectZ(aComponentEntry);
       
  1473 	aComponentEntry = CreateComponentEntryFromStatementHandleL(*stmt);
       
  1474 	AddComponentEntryLocalizablesL(aComponentEntry->ComponentId(), *aComponentEntry, aLocale);
       
  1475 	AddSoftwareTypeNameToComponentEntryL(*stmt, *aComponentEntry, aLocale);
       
  1476 	
       
  1477 	WriteObjectSizeL(aMessage, aReturnSizeSlot, aComponentEntry);
       
  1478 	CleanupStack::PopAndDestroy(2, statementStr); // statementStr, stmt
       
  1479 	}
       
  1480 
       
  1481 void CScrRequestImpl::GetComponentEntrySizeL(const RMessage2& aMessage) const
       
  1482 	{
       
  1483 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1484 	DEBUG_PRINTF2(_L8("Returning the entry size of component(%d)."), componentId);
       
  1485 	TLanguage locale = TLanguage(aMessage.Int1());
       
  1486 	
       
  1487 	_LIT(KConditionColumn, "ComponentId");
       
  1488 	TInt returnSizeSlot=2;
       
  1489 	GetGeneralComponentEntrySizeL(aMessage, KConditionColumn(), componentId, returnSizeSlot, locale, iComponentEntry);
       
  1490 	}
       
  1491 	
       
  1492 void CScrRequestImpl::GetComponentEntryDataL(const RMessage2& aMessage) const
       
  1493 	{
       
  1494 	DEBUG_PRINTF(_L8("Returning the component entry data."));
       
  1495 	WriteObjectDataL(aMessage, 0, iComponentEntry);
       
  1496 	DeleteObjectZ(iComponentEntry); // Delete the object to prevent it to be resent.
       
  1497 	}
       
  1498 
       
  1499 void CScrRequestImpl::GetComponentLocalizedEntrySizeL(const RMessage2& aMessage) const
       
  1500     {
       
  1501     TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1502     DEBUG_PRINTF2(_L8("Returning the localized information entry size of component(%d)."), componentId);
       
  1503     _LIT(KSelectMatchingSupportedLocales, "SELECT Locale, Name, Vendor FROM ComponentLocalizables WHERE ComponentId=?;");
       
  1504     CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectMatchingSupportedLocales);
       
  1505     stmt->BindIntL(1, componentId);
       
  1506     while(stmt->ProcessNextRowL())
       
  1507        {
       
  1508         TPtrC name(stmt->StrColumnL(1));
       
  1509         TPtrC vendor(stmt->StrColumnL(2));
       
  1510         TInt locale(stmt->IntColumnL(0)); 
       
  1511         CLocalizableComponentInfo *compLocalizedInfo = Usif::CLocalizableComponentInfo::NewLC( name, vendor,(TLanguage)locale);
       
  1512         iCompLocalizedInfoArray.Insert(compLocalizedInfo,iCompLocalizedInfoArray.Count());
       
  1513         CleanupStack::Pop(compLocalizedInfo);
       
  1514         }
       
  1515     // Release allocated memories
       
  1516     CleanupStack::PopAndDestroy(1, stmt); // stmt
       
  1517     WriteArraySizeL(aMessage, 1, iCompLocalizedInfoArray);
       
  1518     }
       
  1519 
       
  1520 void CScrRequestImpl::GetComponentLocalizedEntryDataL(const RMessage2& aMessage) const
       
  1521     {
       
  1522     DEBUG_PRINTF(_L8("Returning the localized information entry data."));
       
  1523     WriteArrayDataL(aMessage, 0, iCompLocalizedInfoArray);
       
  1524     iCompLocalizedInfoArray.ResetAndDestroy(); 
       
  1525     }
       
  1526 
       
  1527 TBool CompareProperties(const CPropertyEntry& aRhs, const CPropertyEntry& aLhs)
       
  1528 	{
       
  1529 	return ((aRhs.PropertyType() == aLhs.PropertyType()) && 
       
  1530 		   (aRhs.PropertyName() == aLhs.PropertyName()));		   
       
  1531 	}
       
  1532 
       
  1533 void CScrRequestImpl::AddGeneralPropertiesArrayWithLocaleL(const TDesC& aStmtStr, TLanguage aLocale, TComponentId aIdColumnValue, RPointerArray<CPropertyEntry>& aProperties) const
       
  1534 	{
       
  1535 	TInt numberOfValues = 2;
       
  1536 	CStatement *stmt = CreateStatementObjectWithLocaleL(aStmtStr, aLocale, numberOfValues, EValueInteger, aIdColumnValue, EValueLanguage);
       
  1537 	if(!stmt)
       
  1538 		{
       
  1539 		return;
       
  1540 		}
       
  1541 	CleanupStack::PushL(stmt);	
       
  1542 	do
       
  1543 		{
       
  1544 		TPtrC name(stmt->StrColumnL(0));
       
  1545 		CPropertyEntry *entry = GetPropertyEntryL(*stmt, name, 1); // aStartingIndex=1
       
  1546 		CleanupStack::PushL(entry);
       
  1547 		if(KErrNotFound == aProperties.Find(entry, TIdentityRelation<CPropertyEntry>(CompareProperties)))
       
  1548 			{
       
  1549 			aProperties.AppendL(entry);
       
  1550 			CleanupStack::Pop(entry);	// because array is now owner
       
  1551 			}
       
  1552 		else
       
  1553 			{
       
  1554 			CleanupStack::PopAndDestroy(entry);
       
  1555 			}
       
  1556 		} while(stmt->ProcessNextRowL());
       
  1557 	CleanupStack::PopAndDestroy(stmt);
       
  1558 	}
       
  1559 
       
  1560 void CScrRequestImpl::GetGeneralPropertiesArrayL(const TDesC& aTableName, const TDesC& aIdColumnName , TComponentId aIdColumnValue, TLanguage aLocale, RPointerArray<CPropertyEntry>& aProperties) const
       
  1561 	{
       
  1562 	_LIT(KSelectGeneralLocalizableProperties, "SELECT Name,IntValue,StrValue,Locale,IsStr8Bit FROM %S WHERE %S=? AND Locale=?;");
       
  1563 	TInt formattedLen = aTableName.Length() + aIdColumnName.Length();
       
  1564 	HBufC *statementStr = FormatStatementLC(KSelectGeneralLocalizableProperties, formattedLen, &aTableName, &aIdColumnName );
       
  1565 	
       
  1566 	if(KUnspecifiedLocale == aLocale)
       
  1567 		{
       
  1568 		// Locale is not specified. First get non-localized properties
       
  1569 		AddGeneralPropertiesArrayWithLocaleL(*statementStr, KNonLocalized, aIdColumnValue, aProperties);		
       
  1570 		// Then get the localizable properties with the current locale
       
  1571 		AddGeneralPropertiesArrayWithLocaleL(*statementStr, User::Language(), aIdColumnValue, aProperties);
       
  1572 		}
       
  1573 	else if(KNonLocalized == aLocale)
       
  1574 		{
       
  1575 		// Only non-localized properties are requested.
       
  1576 		AddGeneralPropertiesArrayWithLocaleL(*statementStr, KNonLocalized, aIdColumnValue, aProperties);
       
  1577 		}
       
  1578 	else
       
  1579 		{
       
  1580 		// Locale is specified. It means that only properties with this locale are wanted
       
  1581 		AddGeneralPropertiesArrayWithLocaleL(*statementStr, aLocale, aIdColumnValue, aProperties);
       
  1582 		}
       
  1583 	
       
  1584 	CleanupStack::PopAndDestroy(statementStr);
       
  1585 #ifdef _DEBUG		
       
  1586 	if(!aProperties.Count())
       
  1587 		DEBUG_PRINTF4(_L("Property couldn't be found for column name=(%S), column id=%d and locale=%d."), &aIdColumnName, aIdColumnValue, aLocale);
       
  1588 #endif
       
  1589 	}
       
  1590 
       
  1591 void CScrRequestImpl::GetFilePropertiesSizeL(const RMessage2& aMessage) const
       
  1592 	{
       
  1593 	DEBUG_PRINTF(_L8("Returning the size of file properties."));
       
  1594 	
       
  1595 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1596 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
  1597 	
       
  1598 	TInt compFileId = FindComponentFileL(*fileName, componentId);
       
  1599 	
       
  1600 	iProperties.ResetAndDestroy();
       
  1601 	GetGeneralPropertiesArrayL(KFilePropertiesTable(), KCompFileIdColumnName, compFileId, KNonLocalized, iProperties);
       
  1602 	CleanupStack::PopAndDestroy(fileName);
       
  1603 	WriteArraySizeL(aMessage, 2, iProperties);
       
  1604 	}
       
  1605 
       
  1606 void CScrRequestImpl::GetFilePropertiesDataL(const RMessage2& aMessage) const
       
  1607 	{
       
  1608 	DEBUG_PRINTF(_L8("Returning the file properties data."));
       
  1609 	WriteArrayDataL(aMessage, 0, iProperties);	
       
  1610 	}
       
  1611 
       
  1612 CPropertyEntry* CScrRequestImpl::GetPropertyEntryL(CStatement& aStmt, const TDesC& aPropName, TInt aStartingIndex) const
       
  1613 	{
       
  1614 	CPropertyEntry *entry(0);
       
  1615 		
       
  1616 	if(!aStmt.IsFieldNullL(aStartingIndex))
       
  1617 		{
       
  1618 		TInt64 intVal = aStmt.Int64ColumnL(aStartingIndex);
       
  1619 		entry = CIntPropertyEntry::NewL(aPropName, intVal);
       
  1620 		}
       
  1621 	else if(!aStmt.IsFieldNullL(aStartingIndex+1))
       
  1622 		{
       
  1623 		TBool is8BitString = (aStmt.IntColumnL(aStartingIndex + 3) != 0);
       
  1624 		if (is8BitString)
       
  1625 			{
       
  1626 			TPtrC8 binaryVal(aStmt.BinaryColumnL(aStartingIndex+1));
       
  1627 			entry = CBinaryPropertyEntry::NewL(aPropName, binaryVal);			
       
  1628 			}
       
  1629 		else
       
  1630 			{
       
  1631 			TPtrC strVal(aStmt.StrColumnL(aStartingIndex+1));
       
  1632 			TLanguage locale = TLanguage(aStmt.IntColumnL(aStartingIndex + 2));
       
  1633 			entry = CLocalizablePropertyEntry::NewL(aPropName, strVal, locale);			
       
  1634 			}
       
  1635 		}
       
  1636 	else
       
  1637 		{// Should never come here - shows DB inconsistency
       
  1638 		DEBUG_PRINTF(_L("Both integer and string values are NULL. Inconsistency problem!"));
       
  1639 		User::Leave(KErrCorrupt);
       
  1640 		}	
       
  1641 	return entry;
       
  1642 	}
       
  1643 
       
  1644 CPropertyEntry* CScrRequestImpl::GetGeneralSinglePropertyL(const TDesC& aTableName, const TDesC& aIdColumnName , TInt aIdColumnValue, const TDesC& aPropName,  TLanguage aLocale) const
       
  1645 	{
       
  1646 	DEBUG_PRINTF5(_L("Getting general single property for %S. PropName=%S, Id=%d, Locale=%d"), &aIdColumnName , &aPropName, aIdColumnValue, aLocale);
       
  1647 	
       
  1648 	_LIT(KSelectSingleGeneralProperty, "SELECT IntValue,StrValue,Locale,IsStr8Bit FROM %S WHERE Name=? AND %S=? AND Locale=?;");
       
  1649 	TInt formattedLen = aTableName.Length() + aIdColumnName.Length();
       
  1650 	HBufC *statementStr = FormatStatementLC(KSelectSingleGeneralProperty, formattedLen, &aTableName, &aIdColumnName );
       
  1651 	
       
  1652 	CStatement *stmt = CreateGeneralPropertyStatementWithLocaleL(*statementStr, aIdColumnValue, aLocale, aPropName);
       
  1653 	if(!stmt)
       
  1654 		{
       
  1655 		DEBUG_PRINTF4(_L("Property couldn't be found for column name=(%S), column id=%d and locale=%d."), &aIdColumnName, aIdColumnValue, aLocale);
       
  1656 		CleanupStack::PopAndDestroy(statementStr);
       
  1657 		return NULL;
       
  1658 		}
       
  1659 	CleanupStack::PushL(stmt);
       
  1660 	
       
  1661 	CPropertyEntry *entry = GetPropertyEntryL(*stmt, aPropName, 0); // aStartingIndex=0 
       
  1662 	CleanupStack::PopAndDestroy(2, statementStr); // statementStr, stmt
       
  1663 	return entry;
       
  1664 	}
       
  1665 
       
  1666 void CScrRequestImpl::GetSingleFilePropertySizeL(const RMessage2& aMessage) const
       
  1667 	{
       
  1668 	DEBUG_PRINTF(_L8("Returning the size of single file property."));
       
  1669 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1670 	HBufC* fileName  = ReadFileNameFromMsgLC(aMessage);
       
  1671 	HBufC *propName = ReadDescLC(aMessage, 2);
       
  1672 	
       
  1673 	TInt compFileId = FindComponentFileL(*fileName, componentId);
       
  1674 	
       
  1675 	DeleteObjectZ(iSingleProperty);
       
  1676 	iSingleProperty = GetGeneralSinglePropertyL(KFilePropertiesTable(), KCompFileIdColumnName, compFileId, *propName, KNonLocalized);
       
  1677 	CleanupStack::PopAndDestroy(2, fileName); // fileName, propName
       
  1678 	WriteObjectSizeL(aMessage, 3, iSingleProperty);
       
  1679 	}
       
  1680 
       
  1681 void CScrRequestImpl::GetSingleFilePropertyDataL(const RMessage2& aMessage) const
       
  1682 	{
       
  1683 	DEBUG_PRINTF(_L8("Returning the single file property data."));
       
  1684 	WriteObjectDataL(aMessage, 0, iSingleProperty);	
       
  1685 	DeleteObjectZ(iSingleProperty); // Delete the object to prevent it to be resent.
       
  1686 	}
       
  1687 
       
  1688 void CScrRequestImpl::GetComponentFilesCountL(const RMessage2& aMessage) const
       
  1689 	{
       
  1690 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1691 
       
  1692 	DEBUG_PRINTF2(_L8("Returning the files count for component %d."), componentId);
       
  1693 	
       
  1694 	_LIT(KGetComponentFilesCount, "SELECT COUNT(CmpFileId) FROM ComponentsFiles WHERE ComponentId=?;");
       
  1695 	CStatement *stmt = iDbHandle->PrepareStatementLC(KGetComponentFilesCount);
       
  1696 	stmt->BindIntL(1, componentId);
       
  1697 
       
  1698 	TBool res = stmt->ProcessNextRowL();
       
  1699 	// DB Query did not return a single row for component files count query - internal error!
       
  1700 	__ASSERT_ALWAYS(res, User::Leave(KErrAbort));
       
  1701 
       
  1702 	TInt filesCountTmp = stmt->IntColumnL(0);
       
  1703 	__ASSERT_DEBUG(filesCountTmp >= 0, User::Leave(KErrAbort));
       
  1704 	TUint filesCount = static_cast<TUint>(filesCountTmp);
       
  1705 	CleanupStack::PopAndDestroy(stmt);
       
  1706 	
       
  1707 	TPckg<TUint> filesCountPkg(filesCount);
       
  1708 	aMessage.WriteL(1, filesCountPkg);
       
  1709 	}
       
  1710 
       
  1711 void CScrRequestImpl::GetFileComponentsL(const TDesC& aFileName, RArray<TComponentId>& aComponents) const
       
  1712 	{
       
  1713 	_LIT(KSelectFileComponents, "SELECT ComponentId FROM ComponentsFiles WHERE LocationHash=?;");
       
  1714 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectFileComponents);
       
  1715 	TUint32 hash = HashCaseInsensitiveL(aFileName);
       
  1716 	stmt->BindIntL(1, hash);
       
  1717 		
       
  1718 	while(stmt->ProcessNextRowL())
       
  1719 		{
       
  1720 		User::LeaveIfError(aComponents.InsertInOrder(stmt->IntColumnL(0)));
       
  1721 		}
       
  1722 	CleanupStack::PopAndDestroy(stmt);
       
  1723 	}
       
  1724 
       
  1725 void CScrRequestImpl::GetFileComponentsSizeL(const RMessage2& aMessage) const
       
  1726 	{
       
  1727 	HBufC *fileName = ReadDescLC(aMessage, 0);
       
  1728 	
       
  1729 	iFileComponents.Reset();
       
  1730 	GetFileComponentsL(*fileName, iFileComponents);
       
  1731 	CleanupStack::PopAndDestroy(fileName);
       
  1732 	
       
  1733 	WriteArraySizeL(aMessage, 1, iFileComponents);
       
  1734 	}
       
  1735 
       
  1736 void CScrRequestImpl::GetFileComponentsDataL(const RMessage2& aMessage) const
       
  1737 	{
       
  1738 	WriteArrayDataL(aMessage, 0, iFileComponents);
       
  1739 	}
       
  1740 	
       
  1741 void CScrRequestImpl::GetComponentPropertiesSizeL(const RMessage2& aMessage) const
       
  1742 	{
       
  1743 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1744 	TLanguage locale = TLanguage(aMessage.Int1());
       
  1745 	
       
  1746 	iProperties.ResetAndDestroy();
       
  1747 	GetGeneralPropertiesArrayL(KComponentPropertiesTable(), KComponentIdColumnName, componentId, locale, iProperties);
       
  1748 	WriteArraySizeL(aMessage, 2, iProperties);
       
  1749 	}
       
  1750 
       
  1751 void CScrRequestImpl::GetComponentPropertiesDataL(const RMessage2& aMessage) const
       
  1752 	{
       
  1753 	WriteArrayDataL(aMessage, 0, iProperties);
       
  1754 	}
       
  1755 
       
  1756 void CScrRequestImpl::GetComponentSinglePropertySizeL(const RMessage2& aMessage) const
       
  1757 	{ 
       
  1758 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1759 	HBufC *propName = ReadDescLC(aMessage, 1);
       
  1760 	TLanguage locale = TLanguage(aMessage.Int2());
       
  1761 	
       
  1762 	DeleteObjectZ(iSingleProperty);
       
  1763 	iSingleProperty = GetGeneralSinglePropertyL(KComponentPropertiesTable(), KComponentIdColumnName, componentId, *propName, locale);
       
  1764 	CleanupStack::PopAndDestroy(propName);
       
  1765 	WriteObjectSizeL(aMessage, 3, iSingleProperty);
       
  1766 	}
       
  1767 
       
  1768 void CScrRequestImpl::GetComponentSinglePropertyDataL(const RMessage2& aMessage) const
       
  1769 	{
       
  1770 	WriteObjectDataL(aMessage, 0, iSingleProperty);
       
  1771 	DeleteObjectZ(iSingleProperty); // Delete the object to prevent it to be resent.
       
  1772 	}
       
  1773 
       
  1774 TUint32 CScrRequestImpl::ReadAndHashGlobalIdL(const RMessage2& aMessage, TInt aGlobalIdNameSlot, TInt aSwTypeNameSlot) const
       
  1775 	{
       
  1776 	HBufC *globalIdName = ReadDescLC(aMessage, aGlobalIdNameSlot);
       
  1777 	HBufC *swTypeName = ReadDescLC(aMessage, aSwTypeNameSlot);
       
  1778 	
       
  1779 	// Concatenate the software type id with the global id name
       
  1780 	HBufC *globalId = GenerateGlobalIdL(*swTypeName, *globalIdName);
       
  1781 	CleanupStack::PushL(globalId);
       
  1782 	// Hash the concatenated value
       
  1783 	TUint32 globalIdHash = HashCaseSensitiveL(*globalId);
       
  1784 	CleanupStack::PopAndDestroy(3, globalIdName); // globalIdName, swTypeName, concatGlobalId
       
  1785 	return globalIdHash;
       
  1786 	}
       
  1787 
       
  1788 void CScrRequestImpl::GetComponentIdL(const RMessage2& aMessage) const
       
  1789 	{
       
  1790 	DEBUG_PRINTF(_L8("Returning the local component id of a received global id."));
       
  1791 	
       
  1792 	TUint32 globalIdHash = ReadAndHashGlobalIdL(aMessage, 0, 1);
       
  1793 	
       
  1794 	_LIT(KSelectComponentId, "SELECT ComponentId FROM Components WHERE GlobalIdHash=?;");
       
  1795 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectComponentId);
       
  1796 	stmt->BindIntL(1, globalIdHash);
       
  1797 			
       
  1798 	if(!stmt->ProcessNextRowL())
       
  1799 		{
       
  1800 		DEBUG_PRINTF2(_L8("There is no local component id corresponding to the supplied global id (hash=%d)."), globalIdHash);
       
  1801 		User::Leave(KErrNotFound);
       
  1802 		}
       
  1803 	
       
  1804 	TComponentId compId = stmt->IntColumnL(0);
       
  1805 	CleanupStack::PopAndDestroy(stmt);
       
  1806 	
       
  1807 	TPckg<TComponentId> componentIdDes(compId);
       
  1808 	aMessage.WriteL(2, componentIdDes);
       
  1809 	}
       
  1810 
       
  1811 void CScrRequestImpl::GetComponentWithGlobalIdSizeL(const RMessage2& aMessage) const
       
  1812 	{
       
  1813 	TUint32 globalIdHash = ReadAndHashGlobalIdL(aMessage, 0, 1);
       
  1814 	TLanguage locale = TLanguage(aMessage.Int2());
       
  1815 	
       
  1816 	_LIT(KConditionColumn, "GlobalIdHash");
       
  1817 	TInt returnSizeSlot=3;
       
  1818 	GetGeneralComponentEntrySizeL(aMessage, KConditionColumn(), globalIdHash, returnSizeSlot, locale, iComponentEntry);
       
  1819 	}
       
  1820 
       
  1821 void CScrRequestImpl::GetComponentWithGlobalIdDataL(const RMessage2& aMessage) const
       
  1822 	{
       
  1823 	WriteObjectDataL(aMessage, 0, iComponentEntry);
       
  1824 	DeleteObjectZ(iComponentEntry); // Delete the object to prevent the usage of this function
       
  1825 								    // without calling GetComponentWithGlobalIdSizeL.
       
  1826 	}
       
  1827 
       
  1828 CGlobalComponentId* CScrRequestImpl::ParseGlobalComponendIdLC(const TDesC& aGlobalId) const
       
  1829 	{
       
  1830 	TChar nullCr = '\0';
       
  1831 	TInt pos = aGlobalId.Locate(nullCr);
       
  1832 	__ASSERT_ALWAYS(pos != KErrNotFound, User::Leave(KErrCorrupt));
       
  1833 	
       
  1834 	TPtrC swTypeName = aGlobalId.Left(pos);
       
  1835 	TPtrC globalIdName = aGlobalId.Right(aGlobalId.Length() - pos - 1);
       
  1836 	
       
  1837 	return CGlobalComponentId::NewLC(globalIdName, swTypeName);
       
  1838 	}
       
  1839 
       
  1840 void CScrRequestImpl::GetGeneralDependencyListL(const TDesC& aSelectColumn, const TDesC& aConditionColumn, const TDesC& aConditionValue, RPointerArray<CVersionedComponentId> &aVerCompIdList) const
       
  1841 	{
       
  1842 	_LIT(KSelectDependencies, "SELECT %S,VersionFrom,VersionTo FROM ComponentDependencies WHERE %S=?;");
       
  1843 	TInt formattedLen = aSelectColumn.Length() + aConditionColumn.Length();
       
  1844 	HBufC *stmtStr = FormatStatementLC(KSelectDependencies(), formattedLen, &aSelectColumn, &aConditionColumn);
       
  1845 	
       
  1846 	CStatement *stmt = iDbHandle->PrepareStatementLC(*stmtStr);
       
  1847 	TUint32 conditionValueHash = HashCaseSensitiveL(aConditionValue);
       
  1848 	stmt->BindIntL(1, conditionValueHash);
       
  1849 	
       
  1850 	while(stmt->ProcessNextRowL())
       
  1851 		{
       
  1852 		TPtrC selectedGlobalId(stmt->StrColumnL(0));
       
  1853 		CGlobalComponentId *globalId = ParseGlobalComponendIdLC(selectedGlobalId);
       
  1854 		
       
  1855 		TPtrC versionFrom;
       
  1856 		ReadNullableStringFromStatementL(*stmt, versionFrom, 1);
       
  1857 		TPtrC versionTo;
       
  1858 		ReadNullableStringFromStatementL(*stmt, versionTo, 2);
       
  1859 		
       
  1860 		CVersionedComponentId *verCompId = CVersionedComponentId::NewLC(*globalId, &versionFrom, &versionTo);
       
  1861 		aVerCompIdList.AppendL(verCompId);
       
  1862 		
       
  1863 		CleanupStack::Pop(verCompId); // Ownership passed to the array
       
  1864 		CleanupStack::PopAndDestroy(globalId);
       
  1865 		}
       
  1866 	
       
  1867 	CleanupStack::PopAndDestroy(2, stmtStr); // stmtStr, stmt
       
  1868 	}
       
  1869 
       
  1870 void CScrRequestImpl::GetSupplierComponentsSizeL(const RMessage2& aMessage) const
       
  1871 	{
       
  1872 	HBufC *dependantGlobalId = ReadAndGetGlobalIdLC(aMessage, 0);
       
  1873 	
       
  1874 	_LIT(KSelectColumn, "SupplierGlobalId");
       
  1875 	_LIT(KConditionColumn, "DependantGlobalIdHash");
       
  1876 	iVerCompIdList.ResetAndDestroy();
       
  1877 	
       
  1878 	GetGeneralDependencyListL(KSelectColumn(), KConditionColumn(), *dependantGlobalId, iVerCompIdList);
       
  1879 	CleanupStack::PopAndDestroy(dependantGlobalId);
       
  1880 	WriteArraySizeL(aMessage, 1, iVerCompIdList);
       
  1881 	}
       
  1882 
       
  1883 void CScrRequestImpl::GetSupplierComponentsDataL(const RMessage2& aMessage) const
       
  1884 	{
       
  1885 	WriteArrayDataL(aMessage, 0, iVerCompIdList);
       
  1886 	}
       
  1887 
       
  1888 void CScrRequestImpl::GetDependantComponentsSizeL(const RMessage2& aMessage) const
       
  1889 	{
       
  1890 
       
  1891 	HBufC *supplierGlobalId = ReadAndGetGlobalIdLC(aMessage, 0);
       
  1892 		
       
  1893 	_LIT(KSelectColumn, "DependantGlobalId");
       
  1894 	_LIT(KConditionColumn, "SupplierGlobalIdHash");
       
  1895 	iVerCompIdList.ResetAndDestroy();
       
  1896 		
       
  1897 	GetGeneralDependencyListL(KSelectColumn(), KConditionColumn(), *supplierGlobalId, iVerCompIdList);
       
  1898 	CleanupStack::PopAndDestroy(supplierGlobalId);
       
  1899 	WriteArraySizeL(aMessage, 1, iVerCompIdList);
       
  1900 	}
       
  1901 
       
  1902 void CScrRequestImpl::GetDependantComponentsDataL(const RMessage2& aMessage) const
       
  1903 	{
       
  1904 	WriteArrayDataL(aMessage, 0, iVerCompIdList);
       
  1905 	}
       
  1906 		
       
  1907 void CScrRequestImpl::GetIsMediaPresentL(const RMessage2& aMessage) const
       
  1908 	{
       
  1909 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1910 	DEBUG_PRINTF2(_L8("Retrieving media presence of component(%d)."), componentId);
       
  1911 
       
  1912 	TBool result = CheckForMediaPresenceL(componentId);
       
  1913 	
       
  1914 	TPckg<TBool> resultPkg(result);
       
  1915 	aMessage.WriteL(1, resultPkg);	
       
  1916 	}
       
  1917 
       
  1918 TBool CScrRequestImpl::CheckForMediaPresenceL(TComponentId aComponentId) const
       
  1919 	{
       
  1920 	TInt componentDrivesBitmask = GetInstalledDrivesBitmaskL(aComponentId);	
       
  1921 	
       
  1922 	TDriveList presentDriveSet;
       
  1923 	User::LeaveIfError(iFs.DriveList(presentDriveSet));	
       
  1924 	
       
  1925 	// Check for each drive whether it is present in the system
       
  1926 	for (TInt drive=0; componentDrivesBitmask; componentDrivesBitmask >>= 1, ++drive)
       
  1927 		{
       
  1928 		if ((componentDrivesBitmask & 0x1) && (presentDriveSet.Length() <= drive || !presentDriveSet[drive]))
       
  1929 			{
       
  1930 			DEBUG_PRINTF3(_L8("Component %d registers a file at drive %c which is not present. Returning EFalse for IsMediaPresent)."), aComponentId, drive + 'a');
       
  1931 			return EFalse;			
       
  1932 			}
       
  1933 		}
       
  1934 	
       
  1935 	return ETrue;
       
  1936 	}
       
  1937 
       
  1938 void CScrRequestImpl::SetScomoStateL(const RMessage2& aMessage)
       
  1939 	{
       
  1940 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  1941 	TScomoState state = static_cast<TScomoState>(aMessage.Int1());
       
  1942 	DEBUG_PRINTF3(_L8("Updating the scomo state of component(%d). New value=%d."), componentId, state);
       
  1943 	
       
  1944 	_LIT(KUpdateScomoState, "UPDATE Components SET ScomoState=? WHERE ComponentId=?;");
       
  1945 	TInt numberOfValues = 2;
       
  1946 	ExecuteStatementL(KUpdateScomoState, numberOfValues, EValueInteger, state, EValueInteger, componentId);
       
  1947 	}
       
  1948 
       
  1949 void CScrRequestImpl::GetPluginUidWithMimeTypeL(const RMessage2& aMessage) const
       
  1950 	{
       
  1951 	DEBUG_PRINTF(_L8("Returning plugin for MIME type."));
       
  1952 	HBufC *mimeType = ReadDescLC(aMessage, 0);
       
  1953 	
       
  1954 	_LIT(KSelectPluginsWithMimeType, "SELECT SifPluginUid FROM SoftwareTypes WHERE SoftwareTypeId IN (SELECT SoftwareTypeId FROM MimeTypes WHERE MimeType=?);");
       
  1955 	CStatement* stmt = iDbHandle->PrepareStatementLC(KSelectPluginsWithMimeType);
       
  1956 	stmt->BindStrL(1, *mimeType);
       
  1957 	if(!stmt->ProcessNextRowL())
       
  1958 		{
       
  1959 		DEBUG_PRINTF2(_L("Sif Plugin Uid couldn't be found for Mime Type (%S)!"), mimeType);
       
  1960 		User::Leave(KErrSifUnsupportedSoftwareType);
       
  1961 		}
       
  1962 	TUint32 uid = stmt->IntColumnL(0);
       
  1963 	CleanupStack::PopAndDestroy(2, mimeType); // mimeType, stmt
       
  1964 	
       
  1965 	TPckg<TUint32> uidDes(uid);
       
  1966 	aMessage.WriteL(1, uidDes);
       
  1967 	}
       
  1968 
       
  1969 TBool CScrRequestImpl::GetIntSoftwareTypeDataForComponentLC(TComponentId aComponentId, const TDesC& aColumnName, TInt& aValue) const
       
  1970 	{
       
  1971 	_LIT(KSelectComponents, "SELECT SoftwareTypeId FROM Components WHERE ComponentId=?;");
       
  1972 	TBool found = EFalse;
       
  1973 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectComponents);
       
  1974 	stmt->BindIntL(1, aComponentId);
       
  1975 	if(!stmt->ProcessNextRowL())
       
  1976 		{
       
  1977 		DEBUG_PRINTF2(_L("Component Id (%d) doesn't exist in the SCR database!"), aComponentId);
       
  1978 		User::LeaveIfError(KErrNotFound);
       
  1979 		}
       
  1980 	TInt swTypeId = stmt->IntColumnL(0);
       
  1981 	CleanupStack::PopAndDestroy(stmt);
       
  1982 	
       
  1983 	_LIT(KSelectSoftwareTypes, "SELECT %S FROM SoftwareTypes WHERE SoftwareTypeId=?;");
       
  1984 	HBufC *statementStr = FormatStatementLC(KSelectSoftwareTypes(), aColumnName.Length(), &aColumnName);
       
  1985 	CStatement *stmtSwType = iDbHandle->PrepareStatementLC(*statementStr);
       
  1986 	stmtSwType->BindIntL(1, swTypeId);
       
  1987 	
       
  1988 	if(stmtSwType->ProcessNextRowL())
       
  1989 		{
       
  1990 		aValue = stmtSwType->IntColumnL(0);
       
  1991 		found = ETrue;
       
  1992 		}
       
  1993 	CleanupStack::PopAndDestroy(2, statementStr); // statementStr, stmtSwType
       
  1994 	return found;
       
  1995 	}
       
  1996 
       
  1997 TBool CScrRequestImpl::GetInstallerSidForComponentL(TComponentId aComponentId, TSecureId& aSid) const	
       
  1998 	{
       
  1999 	_LIT(KInstallerSecureId, "InstallerSecureId");
       
  2000 	TInt secureIdInt (0);
       
  2001 	TBool found = GetIntSoftwareTypeDataForComponentLC(aComponentId, KInstallerSecureId, secureIdInt);	
       
  2002 	aSid.iId = secureIdInt;
       
  2003 	return found;
       
  2004 	}
       
  2005 
       
  2006 TBool CScrRequestImpl::GetExecutionEnvSidForComponentL(TComponentId aComponentId, TSecureId& aSid) const
       
  2007 	{
       
  2008 	_LIT(KExecutionLayerSecureId, "ExecutionLayerSecureId");
       
  2009 	TInt secureIdInt(0);
       
  2010 	TBool found = GetIntSoftwareTypeDataForComponentLC(aComponentId, KExecutionLayerSecureId, secureIdInt);	
       
  2011 	aSid.iId = secureIdInt;
       
  2012 	return found;	
       
  2013 	}
       
  2014 
       
  2015 TBool CScrRequestImpl::IsInstallerOrExecutionEnvSidL(TSecureId& aSid) const
       
  2016 	{
       
  2017 	_LIT(KSelectStatement, "SELECT InstallerSecureId FROM SoftwareTypes WHERE InstallerSecureId=? OR ExecutionLayerSecureId=?;");
       
  2018 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectStatement);
       
  2019 	stmt->BindIntL(1, aSid);
       
  2020 	stmt->BindIntL(2, aSid);	
       
  2021 	TBool res = ETrue;
       
  2022 	if(!stmt->ProcessNextRowL())
       
  2023 		{
       
  2024 		DEBUG_PRINTF2(_L("%d is not an installer SID"), TUint32(aSid));
       
  2025 		res = EFalse;
       
  2026 		}
       
  2027 	CleanupStack::PopAndDestroy(stmt);
       
  2028 	return res;	
       
  2029 	}
       
  2030 
       
  2031 void CScrRequestImpl::GetPluginUidWithComponentIdL(const RMessage2& aMessage) const
       
  2032 	{
       
  2033 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  2034 	DEBUG_PRINTF2(_L8("Returning the plugin of component(%d)."), componentId);
       
  2035 	_LIT(KSifPluginUid, "SifPluginUid");
       
  2036 	TInt uid (0);
       
  2037 	TBool found = GetIntSoftwareTypeDataForComponentLC(componentId, KSifPluginUid, uid);
       
  2038 	__ASSERT_ALWAYS(found, User::Leave(KErrNotFound));
       
  2039 	
       
  2040 	TPckg<TUint32> uidDes(uid);
       
  2041 	aMessage.WriteL(1, uidDes);
       
  2042 	}
       
  2043 
       
  2044 // This function returns whether the SID looked up has been found in the software types table.
       
  2045 TBool CScrRequestImpl::GetSidsForSoftwareTypeL(const HBufC* aSoftwareTypeName, TSecureId& aInstallerSid, TSecureId& aExecutableEnvSid) const
       
  2046 	{
       
  2047 	DEBUG_PRINTF2(_L("Returning SIDs for software type(%S)."), aSoftwareTypeName);
       
  2048 	TBool found = EFalse;
       
  2049 	TUint32 swTypeId = HashCaseSensitiveL(*aSoftwareTypeName);
       
  2050 	
       
  2051 	_LIT(KSelectStatement, "SELECT ExecutionLayerSecureId, InstallerSecureId FROM SoftwareTypes WHERE SoftwareTypeId =?;");
       
  2052 	CStatement* stmt = iDbHandle->PrepareStatementLC(KSelectStatement);
       
  2053 	stmt->BindIntL(1, swTypeId);
       
  2054 	
       
  2055 	if(stmt->ProcessNextRowL())
       
  2056 		{
       
  2057 		aExecutableEnvSid = stmt->IntColumnL(0);
       
  2058 		aInstallerSid = stmt->IntColumnL(1);
       
  2059 		found = ETrue;
       
  2060 		}
       
  2061 	
       
  2062 	CleanupStack::PopAndDestroy(stmt);
       
  2063 	return found;
       
  2064 	}
       
  2065 
       
  2066 void IntersectSortedArraysL(RArray<TComponentId>& aLhs, RArray<TComponentId> aRhs)
       
  2067 	{
       
  2068 	RArray<TComponentId> tmp;
       
  2069 	CleanupClosePushL(tmp);
       
  2070 	TInt idxLhs(0);
       
  2071 	TInt idxRhs(0);
       
  2072 	TInt countLhs = aLhs.Count();
       
  2073 	TInt countRhs = aRhs.Count();
       
  2074 	
       
  2075 	while(idxLhs < countLhs && idxRhs < countRhs)
       
  2076 		{
       
  2077 		if(aLhs[idxLhs] < aRhs[idxRhs])
       
  2078 			++idxLhs;
       
  2079 		else if(aLhs[idxLhs] > aRhs[idxRhs])
       
  2080 			++idxRhs;
       
  2081 		else
       
  2082 			{
       
  2083 			tmp.AppendL(aRhs[idxRhs]);
       
  2084 			++idxRhs;
       
  2085 			++idxLhs;
       
  2086 			}
       
  2087 		}
       
  2088 	
       
  2089 	aLhs.Reset();
       
  2090 	CopyFixedLengthArrayL(aLhs, tmp);
       
  2091 	CleanupStack::PopAndDestroy(&tmp);
       
  2092 	}
       
  2093 
       
  2094 void CScrRequestImpl::GetComponentIdsHavingThePropertiesL(RArray<TComponentId>& aComponentIds, RPointerArray<CPropertyEntry> aProperties, TBool aDoIntersect) const
       
  2095 	{
       
  2096 	// GROUP BY is added at the end to avoid fetching twice components which have the same localizable values for different locales
       
  2097 	_LIT(KFindComponentsFromProperties, "SELECT ComponentId FROM ComponentProperties WHERE Name=? AND %S GROUP BY ComponentId;");
       
  2098 	_LIT(KPropertyIntValue,"IntValue=?");
       
  2099 	_LIT(KPropertyStrValue,"StrValue=?");
       
  2100 	_LIT(KPropertyLocalizedValue,"StrValue=? AND Locale=?");
       
  2101 			
       
  2102 	TInt propCount = aProperties.Count();
       
  2103 
       
  2104 	HBufC *statementStr(0);
       
  2105 	RArray<TComponentId> propCompIds;
       
  2106 	CleanupClosePushL(propCompIds);
       
  2107 	
       
  2108 	for(TInt i=0; i<propCount; ++i)
       
  2109 		{
       
  2110 		switch(aProperties[i]->PropertyType())
       
  2111 			{
       
  2112 			case CPropertyEntry::EIntProperty:
       
  2113 				statementStr = FormatStatementLC(KFindComponentsFromProperties, KPropertyIntValue().Length(), &KPropertyIntValue());
       
  2114 				break;
       
  2115 			case CPropertyEntry::EBinaryProperty:
       
  2116 				statementStr = FormatStatementLC(KFindComponentsFromProperties, KPropertyStrValue().Length(), &KPropertyStrValue());
       
  2117 				break;
       
  2118 			case CPropertyEntry::ELocalizedProperty:
       
  2119 				{
       
  2120 				CLocalizablePropertyEntry *localizedProp = static_cast<CLocalizablePropertyEntry *>(aProperties[i]);
       
  2121 				if (localizedProp->LocaleL() == KUnspecifiedLocale) // If the locale was not specified, then we match across all locales				
       
  2122 					statementStr = FormatStatementLC(KFindComponentsFromProperties, KPropertyStrValue().Length(), &KPropertyStrValue());
       
  2123 				else // Otherwise we match for a specific locale
       
  2124 					statementStr = FormatStatementLC(KFindComponentsFromProperties, KPropertyLocalizedValue().Length(), &KPropertyLocalizedValue());
       
  2125 				}
       
  2126 				break;				
       
  2127 			default:
       
  2128 				DEBUG_PRINTF(_L8("The property type couldn't be recognized."));
       
  2129 				User::Leave(KErrAbort);	
       
  2130 			}
       
  2131 				
       
  2132 		CStatement *stmt = iDbHandle->PrepareStatementLC(*statementStr);
       
  2133 		stmt->BindStrL(1, aProperties[i]->PropertyName());
       
  2134 				
       
  2135 		switch(aProperties[i]->PropertyType())
       
  2136 			{
       
  2137 			case CPropertyEntry::EIntProperty:
       
  2138 				{
       
  2139 				CIntPropertyEntry *intProp = static_cast<CIntPropertyEntry *>(aProperties[i]);
       
  2140 				stmt->BindInt64L(2, intProp->Int64Value());
       
  2141 				break;
       
  2142 				}
       
  2143 			case CPropertyEntry::EBinaryProperty:
       
  2144 				{
       
  2145 				CBinaryPropertyEntry *binaryProp = static_cast<CBinaryPropertyEntry *>(aProperties[i]);
       
  2146 				stmt->BindBinaryL(2, binaryProp->BinaryValue());
       
  2147 				break;
       
  2148 				}
       
  2149 			case CPropertyEntry::ELocalizedProperty:
       
  2150 				{
       
  2151 				CLocalizablePropertyEntry *localizedProp = static_cast<CLocalizablePropertyEntry *>(aProperties[i]);
       
  2152 				stmt->BindStrL(2, localizedProp->StrValue());
       
  2153 				if (localizedProp->LocaleL() != KUnspecifiedLocale)
       
  2154 					stmt->BindIntL(3, localizedProp->LocaleL());
       
  2155 				break;
       
  2156 				}
       
  2157 			default:
       
  2158 				DEBUG_PRINTF(_L8("The property type couldn't be recognized."));
       
  2159 				User::Leave(KErrAbort);	
       
  2160 			}
       
  2161 		
       
  2162 		while(stmt->ProcessNextRowL())
       
  2163 			{
       
  2164 			User::LeaveIfError(propCompIds.InsertInOrder(stmt->IntColumnL(0)));
       
  2165 			}
       
  2166 		
       
  2167 		CleanupStack::PopAndDestroy(2, statementStr); // stmt, statementStr
       
  2168 		
       
  2169 		if (aDoIntersect)
       
  2170 			{
       
  2171 			IntersectSortedArraysL(aComponentIds, propCompIds);
       
  2172 			}
       
  2173 		else
       
  2174 			{
       
  2175 			CopyFixedLengthArrayL(aComponentIds, propCompIds);
       
  2176 			aDoIntersect = ETrue; // If many properties are present in the filter, we need to intersect the component Ids on further iterations
       
  2177 			}
       
  2178 		
       
  2179 		propCompIds.Reset();
       
  2180 		}
       
  2181 	CleanupStack::PopAndDestroy(&propCompIds);
       
  2182 	}
       
  2183 
       
  2184 void ReallocStatementIfNeededL(RBuf& aStatementStr, TInt aAddedLength)
       
  2185 	{
       
  2186 	TInt freeSpace = aStatementStr.MaxLength() - aStatementStr.Length();
       
  2187 	TInt extraSpace = aAddedLength - freeSpace;
       
  2188 	if (extraSpace > 0)
       
  2189 		{
       
  2190 		aStatementStr.ReAllocL(aStatementStr.MaxLength() +  extraSpace);
       
  2191 		}	
       
  2192 	}
       
  2193 	
       
  2194 void AppendConditionToStatementL(RBuf& aStatementStr, const TDesC& aConditionStr, TBool& aIsFirstCondition)
       
  2195 	{
       
  2196 	TInt addedLength = 2 + aConditionStr.Length(); // 2 chars used by spaces
       
  2197 	
       
  2198 	_LIT(KConditionAnd, " AND");
       
  2199 	_LIT(KConditionWhere, " WHERE");
       
  2200 	
       
  2201 	if(aIsFirstCondition)
       
  2202 		{
       
  2203 		addedLength += KConditionWhere().Length();
       
  2204 		}
       
  2205 	else
       
  2206 		{
       
  2207 		addedLength += KConditionAnd().Length();
       
  2208 		}
       
  2209 	
       
  2210 	ReallocStatementIfNeededL(aStatementStr, addedLength);
       
  2211 	
       
  2212 	if(aIsFirstCondition)
       
  2213 		{
       
  2214 		aStatementStr.Append(KConditionWhere);
       
  2215 		aIsFirstCondition = EFalse;
       
  2216 		}
       
  2217 	else
       
  2218 		{
       
  2219 		aStatementStr.Append(KConditionAnd);
       
  2220 		}
       
  2221 	aStatementStr.Append(aConditionStr);
       
  2222 	}
       
  2223 
       
  2224 CStatement* CScrRequestImpl::CreateStatementObjectForComponentLocalizablesLC(const TDesC& aName, const TDesC& aVendor, TUint aSetFlag, TComponentId aComponentId /* = 0*/ ) const
       
  2225 	{
       
  2226 	_LIT(KSelectComponentLocalizables, "SELECT ComponentId,Name,Vendor FROM ComponentLocalizables");
       
  2227 	RBuf stmtStr;
       
  2228 	stmtStr.CreateL(100); // 100 should be enough for this statement
       
  2229 	stmtStr.CleanupClosePushL();
       
  2230 	stmtStr.Copy(KSelectComponentLocalizables);
       
  2231 	TBool isFirstCondition = ETrue;
       
  2232 	
       
  2233 	if(aComponentId > 0)
       
  2234 		{
       
  2235 		_LIT(KConditionComponentId, " ComponentId=?");
       
  2236 		AppendConditionToStatementL(stmtStr, KConditionComponentId, isFirstCondition);	
       
  2237 		}
       
  2238 	
       
  2239 	if (aSetFlag & CComponentFilter::EName)
       
  2240 		{
       
  2241 		_LIT(KConditionName, " Name=?");
       
  2242 		AppendConditionToStatementL(stmtStr, KConditionName, isFirstCondition);	
       
  2243 		}
       
  2244 		
       
  2245 	if (aSetFlag & CComponentFilter::EVendor)
       
  2246 		{
       
  2247 		_LIT(KConditionVendor, " Vendor=?");
       
  2248 		AppendConditionToStatementL(stmtStr, KConditionVendor, isFirstCondition);
       
  2249 		}		
       
  2250 	// Take care not to return the same component id twice in case we have the same name or vendor for two different locales
       
  2251 	_LIT(KComponentIdGroupBy, " GROUP BY ComponentId;");
       
  2252 	ReallocStatementIfNeededL(stmtStr, KComponentIdGroupBy().Length() + 1); // one space for the NULL char
       
  2253 	stmtStr.Append(KComponentIdGroupBy());
       
  2254 	// SQLite requires the statement string to end with NULL char.
       
  2255 	stmtStr.Append('\0');
       
  2256 	
       
  2257 	CStatement *stmt = iDbHandle->PrepareStatementLC(stmtStr);
       
  2258 	
       
  2259 	TInt bindIdx = 1;
       
  2260 	if(aComponentId > 0)
       
  2261 		{
       
  2262 		stmt->BindIntL(bindIdx++, aComponentId);
       
  2263 		}
       
  2264 	if (aSetFlag & CComponentFilter::EName)
       
  2265 		{
       
  2266 		stmt->BindStrL(bindIdx++, aName);
       
  2267 		}
       
  2268 	if (aSetFlag & CComponentFilter::EVendor)
       
  2269 		{
       
  2270 		stmt->BindStrL(bindIdx, aVendor);
       
  2271 		}
       
  2272 	CleanupStack::Pop(stmt);
       
  2273 	CleanupStack::PopAndDestroy(&stmtStr);
       
  2274 	CleanupStack::PushL(stmt);
       
  2275 	return stmt;
       
  2276 	}
       
  2277 
       
  2278 void CScrRequestImpl::GetComponentsHavingNameVendorL(RArray<TComponentId>& aComponentIds, const TDesC& aName, const TDesC& aVendor, TUint16 aSetFlag, TBool aDoIntersect) const
       
  2279 	{
       
  2280 	CStatement *stmt = CreateStatementObjectForComponentLocalizablesLC(aName, aVendor, aSetFlag); 
       
  2281 	
       
  2282 	RArray<TComponentId> foundCompIds;
       
  2283 	CleanupClosePushL(foundCompIds);
       
  2284 	
       
  2285 	while(stmt->ProcessNextRowL())
       
  2286 		{
       
  2287 		User::LeaveIfError(foundCompIds.InsertInOrder(stmt->IntColumnL(0)));
       
  2288 		}
       
  2289 	
       
  2290 	if (aDoIntersect)
       
  2291 		IntersectSortedArraysL(aComponentIds, foundCompIds);
       
  2292 	else
       
  2293 		CopyFixedLengthArrayL(aComponentIds, foundCompIds);
       
  2294 
       
  2295 	CleanupStack::PopAndDestroy(2, stmt); // stmt, foundCompIds
       
  2296 	}
       
  2297 
       
  2298 CComponentFilter* CScrRequestImpl::ReadComponentFilterL(const RMessage2& aMessage) const
       
  2299 	{
       
  2300 	CComponentFilter *filter = ReadObjectFromMessageLC<CComponentFilter>(aMessage, 0);
       
  2301 	CleanupStack::Pop(filter);
       
  2302 	return filter;
       
  2303 	}
       
  2304 
       
  2305 void AppendFilterConditionToStatementL(TUint16 aSetFlag, TUint16 aConditionFlag, RBuf& aStatementStr, const TDesC& aConditionStr, TBool& aIsFirstCondition)
       
  2306 	{
       
  2307 	if(aSetFlag & aConditionFlag)
       
  2308 		{
       
  2309 		AppendConditionToStatementL(aStatementStr, aConditionStr, aIsFirstCondition);
       
  2310 		}
       
  2311 	}
       
  2312 
       
  2313 void BindIntegerFilterToStatementL(CStatement& aStatement, TUint16 aSetFlag, TUint16 aConditionFlag, TInt aValue, TInt& aStmtIdx)
       
  2314 	{
       
  2315 	if(aSetFlag & aConditionFlag)
       
  2316 		{
       
  2317 		aStatement.BindIntL(aStmtIdx++, aValue);
       
  2318 		}
       
  2319 	}
       
  2320 
       
  2321 CStatement* CScrRequestImpl::OpenComponentViewL(CComponentFilter& aFilter, RArray<TComponentId>& aComponentFilterSuperset, TBool& aFilterSupersetInUse) const
       
  2322 	{
       
  2323 	aComponentFilterSuperset.Reset();
       
  2324 	aFilterSupersetInUse = EFalse;
       
  2325 
       
  2326 	TBool doIntersect = EFalse; // We should intersect component ids iff one of the previous filters on component ids was invoked
       
  2327 	if(aFilter.iSetFlag & CComponentFilter::EFile)
       
  2328 		{
       
  2329 		GetFileComponentsL(*aFilter.iFile, aComponentFilterSuperset);
       
  2330 		// The component Ids which own the given file is copied into componentIds array.
       
  2331 		doIntersect = ETrue;
       
  2332 		aFilterSupersetInUse = ETrue;
       
  2333 		}
       
  2334 	
       
  2335 	if(aFilter.iSetFlag & CComponentFilter::EProperty)
       
  2336 		{
       
  2337 		GetComponentIdsHavingThePropertiesL(aComponentFilterSuperset, aFilter.iPropertyList, doIntersect);
       
  2338 		// Inside the function, componentIds array is intersected with the components Ids which have the given properties.
       
  2339 		doIntersect = ETrue;
       
  2340 		aFilterSupersetInUse = ETrue;
       
  2341 		}
       
  2342 	
       
  2343 	if(aFilter.iSetFlag & (CComponentFilter::EName | CComponentFilter::EVendor))
       
  2344 		{
       
  2345 		GetComponentsHavingNameVendorL(aComponentFilterSuperset, *aFilter.iName, *aFilter.iVendor, aFilter.iSetFlag, doIntersect);
       
  2346 		// Inside the function, componentIds array is intersected with the components Ids which have the given name/vendor.
       
  2347 		aFilterSupersetInUse = ETrue;
       
  2348 		}
       
  2349 	
       
  2350 	_LIT(KSelectComponents, "SELECT ComponentId,SoftwareTypeId,SoftwareTypeName,Removable,Size,ScomoState,DRMProtected,Hidden,KnownRevoked,OriginVerified,GlobalId,InstalledDrives,Version,InstallTime FROM Components");
       
  2351 	
       
  2352 	RBuf statementStr;
       
  2353 	statementStr.CreateL(KSelectComponents().Length()+ 50); // A reasonable starting buffer length
       
  2354 	statementStr.CleanupClosePushL();
       
  2355 	statementStr.Copy(KSelectComponents);
       
  2356 	
       
  2357 	TBool isFirstCondition = ETrue;
       
  2358 	
       
  2359 	_LIT(KConditionSoftwareType, " SoftwareTypeId=?"); // as only unique sw type name can be defined in the filter.
       
  2360 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::ESoftwareType, statementStr, KConditionSoftwareType, isFirstCondition);
       
  2361 	
       
  2362 	_LIT(KConditionRemovable, " Removable=?");
       
  2363 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::ERemovable, statementStr, KConditionRemovable, isFirstCondition);
       
  2364 	
       
  2365 	_LIT(KConditionScomoState, " ScomoState=?");
       
  2366 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EScomoState, statementStr, KConditionScomoState, isFirstCondition);
       
  2367 	
       
  2368 	_LIT(KConditionInstalledDrives, " InstalledDrives&?"); // & -> bitwise AND operator
       
  2369 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EInstalledDrive, statementStr, KConditionInstalledDrives, isFirstCondition);
       
  2370 		
       
  2371 	_LIT(KConditionDrmProtected, " DRMProtected=?");
       
  2372 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EDrmProtected, statementStr, KConditionDrmProtected, isFirstCondition);
       
  2373 	
       
  2374 	_LIT(KConditionHidden, " Hidden=?");
       
  2375 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EHidden, statementStr, KConditionHidden, isFirstCondition);
       
  2376 	
       
  2377 	_LIT(KConditionKnownRevoked, " KnownRevoked=?");
       
  2378 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EKnownRevoked, statementStr, KConditionKnownRevoked, isFirstCondition);
       
  2379 
       
  2380 	_LIT(KConditionOriginVerified, " OriginVerified=?");
       
  2381 	AppendFilterConditionToStatementL(aFilter.iSetFlag, CComponentFilter::EOriginVerified, statementStr, KConditionOriginVerified, isFirstCondition);
       
  2382 		
       
  2383 	statementStr.Append(';');
       
  2384 	// SQLite requires the statement string to end with NULL char.
       
  2385 	statementStr.Append('\0');
       
  2386 	
       
  2387 	CStatement *stmt = iDbHandle->PrepareStatementLC(statementStr);
       
  2388 	TInt stmtIdx = 1;
       
  2389 	
       
  2390 	if(aFilter.iSetFlag & CComponentFilter::ESoftwareType)
       
  2391 		{
       
  2392 		TUint32 swTypeId = HashCaseSensitiveL(*aFilter.iSwType);
       
  2393 		stmt->BindIntL(stmtIdx++, swTypeId);
       
  2394 		}
       
  2395 	
       
  2396 	if(aFilter.iSetFlag & CComponentFilter::EInstalledDrive)
       
  2397 		{
       
  2398 		if (aFilter.iInstalledDrives.Length() != KMaxDrives)
       
  2399 			{
       
  2400 			DEBUG_PRINTF2(_L("Incorrect size of drive list supplied in filter, the string supplied was %S"), &aFilter.iInstalledDrives);
       
  2401 			User::Leave(KErrArgument);
       
  2402 			}
       
  2403 		TInt installedDrivesBitmask = InstalledDrivesToBitmaskL(aFilter.iInstalledDrives);
       
  2404 		stmt->BindIntL(stmtIdx++, installedDrivesBitmask);
       
  2405 		}
       
  2406 	
       
  2407 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::ERemovable, aFilter.iRemovable, stmtIdx);
       
  2408 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::EScomoState, aFilter.iScomoState, stmtIdx);
       
  2409 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::EDrmProtected, aFilter.iDrmProtected, stmtIdx);
       
  2410 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::EHidden, aFilter.iHidden, stmtIdx);
       
  2411 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::EKnownRevoked, aFilter.iKnownRevoked, stmtIdx);
       
  2412 	BindIntegerFilterToStatementL(*stmt, aFilter.iSetFlag, CComponentFilter::EOriginVerified, aFilter.iOriginVerified, stmtIdx);
       
  2413 	
       
  2414 	CleanupStack::Pop(stmt);
       
  2415 	CleanupStack::PopAndDestroy(&statementStr);
       
  2416 	return stmt;
       
  2417 	}
       
  2418 
       
  2419 void CScrRequestImpl::AddComponentEntryLocalizablesL(TComponentId aComponentId, CComponentEntry& aEntry, TLanguage aLocale, const CComponentFilter& aFilter) const
       
  2420 	{
       
  2421 	if(aFilter.iSetFlag & (CComponentFilter::EName | CComponentFilter::EVendor))
       
  2422 		{ // If a name or vendor is specified in the filter, the locale is ignored
       
  2423 		  // and the provided names are retrieved from the ComponentLocalizables table.
       
  2424 		CStatement *stmt = CreateStatementObjectForComponentLocalizablesLC(*aFilter.iName, *aFilter.iVendor, aFilter.iSetFlag, aComponentId);
       
  2425 		TBool res = stmt->ProcessNextRowL();
       
  2426 		// If the name and the vendor are not found, it means that there is a defect in this class, the filter shouldn't have returned the component in the first place		
       
  2427 		__ASSERT_ALWAYS(res, User::Leave(KErrNotFound)); 		
       
  2428 		DeleteObjectZ(aEntry.iName);
       
  2429 		aEntry.iName = stmt->StrColumnL(1).AllocL(); // Ownership is transferred to the entry object
       
  2430 		DeleteObjectZ(aEntry.iVendor);
       
  2431 		aEntry.iVendor = stmt->StrColumnL(2).AllocL(); // Ownership is transferred to the entry object
       
  2432 		CleanupStack::PopAndDestroy(stmt);
       
  2433 		}
       
  2434 	else
       
  2435 		{// if name and/or vendor are not defined in the filter, try to find them by using the nearest language algorithm. 
       
  2436 		AddComponentEntryLocalizablesL(aComponentId, aEntry, aLocale);
       
  2437 		}
       
  2438 	}
       
  2439 
       
  2440 
       
  2441 TBool CScrRequestImpl::IsSoftwareTypeExistingL(TInt aSoftwareTypeId) const
       
  2442 	{
       
  2443 	TBool result = EFalse;
       
  2444 	_LIT(KComponentSoftwareType, "SELECT SoftwareTypeId FROM SoftwareTypes WHERE SoftwareTypeId=?;");	
       
  2445 		
       
  2446 	CStatement *stmt = iDbHandle->PrepareStatementLC(KComponentSoftwareType);
       
  2447 	stmt->BindIntL(1, aSoftwareTypeId);
       
  2448 			
       
  2449 	if(stmt->ProcessNextRowL())
       
  2450 		{ // The software type exists. 
       
  2451 		result = ETrue;
       
  2452 		}
       
  2453 	CleanupStack::PopAndDestroy(stmt);
       
  2454 	return result;
       
  2455 	}
       
  2456 
       
  2457 void CScrRequestImpl::SubsessionAddLocalizableSoftwareTypeNameL(CStatement& aStmt, CComponentEntry& aEntry, TLanguage aLocale, CCompViewSubsessionContext* aSubsessionContext) const	
       
  2458 	{
       
  2459 	TInt softwareTypeId = aStmt.IntColumnL(1);
       
  2460 	// Check if we've already cached this software type name - caching is important here as fetching the same software type name for all components in the sub-session is expensive
       
  2461 	if (softwareTypeId == aSubsessionContext->iLastSoftwareTypeId)
       
  2462 		{
       
  2463 		DeleteObjectZ(aEntry.iSwType);
       
  2464 		aEntry.iSwType = aSubsessionContext->iLastSoftwareTypeName->AllocL();
       
  2465 		}
       
  2466 	else
       
  2467 		{
       
  2468 		AddSoftwareTypeNameToComponentEntryL(aStmt, aEntry, aLocale);
       
  2469 		// Save the last results - if the next component in the filter has the same software type id, we won't have to recalculate the name
       
  2470 		aSubsessionContext->iLastSoftwareTypeId = softwareTypeId;
       
  2471 		DeleteObjectZ(aSubsessionContext->iLastSoftwareTypeName);
       
  2472 		aSubsessionContext->iLastSoftwareTypeName = aEntry.iSwType->AllocL();
       
  2473 		}
       
  2474 	}
       
  2475 
       
  2476 CComponentEntry* CScrRequestImpl::GetNextComponentEntryL(CStatement& aStmt, CComponentFilter& aFilter, TLanguage aLocale, CCompViewSubsessionContext* aSubsessionContext) const
       
  2477 	{
       
  2478 	// Since the query does not account for filter's name, vendor, property and file conditions,
       
  2479 	// we intersect the resut of the query with components which answer these conditions, i.e. iComponentFilterSuperset 
       
  2480 	while (1)
       
  2481 		{
       
  2482 		if(!aStmt.ProcessNextRowL())
       
  2483 			{
       
  2484 			return NULL;
       
  2485 			}
       
  2486 		TComponentId queryComponentId = aStmt.IntColumnL(0); 
       
  2487 		if (!aSubsessionContext->iFilterSupersetInUse || aSubsessionContext->iComponentFilterSuperset.FindInOrder(queryComponentId) >= 0) 
       
  2488 			break; // The component id exists in both parts of the filter - return it.
       
  2489 		}
       
  2490 		
       
  2491 	CComponentEntry *component = CreateComponentEntryFromStatementHandleL(aStmt);
       
  2492 	CleanupStack::PushL(component);
       
  2493 	AddComponentEntryLocalizablesL(component->ComponentId(), *component, aLocale, aFilter);
       
  2494 	SubsessionAddLocalizableSoftwareTypeNameL(aStmt, *component, aLocale, aSubsessionContext);	
       
  2495 	CleanupStack::Pop(component);
       
  2496 	return component;
       
  2497 	}
       
  2498 
       
  2499 void CScrRequestImpl::NextComponentSizeL(const RMessage2& aMessage, CStatement* aStmt, CComponentFilter* aFilter, CComponentEntry*& aEntry, CCompViewSubsessionContext* aSubsessionContext) const
       
  2500 	{
       
  2501 	__ASSERT_ALWAYS(aStmt && aFilter, PanicClient(aMessage, KScrIllegalCallSequence));
       
  2502 	
       
  2503 	TLanguage locale = TLanguage(aMessage.Int0());
       
  2504 	
       
  2505 	DeleteObjectZ(aEntry);
       
  2506 	aEntry = GetNextComponentEntryL(*aStmt, *aFilter, locale, aSubsessionContext);
       
  2507 	TInt sizeSlot = 1;
       
  2508 	if(!aEntry)
       
  2509 		{
       
  2510 		DEBUG_PRINTF(_L8("Reached the end of the view."));
       
  2511 		WriteIntValueL(aMessage, sizeSlot, 0);
       
  2512 		return;
       
  2513 		}
       
  2514 	WriteObjectSizeL(aMessage, sizeSlot, aEntry);
       
  2515 	}
       
  2516 
       
  2517 void CScrRequestImpl::NextComponentDataL(const RMessage2& aMessage, CComponentEntry*& aEntry) const
       
  2518 	{
       
  2519 	DEBUG_PRINTF(_L8("Returning the component entry data."));
       
  2520 	WriteObjectDataL(aMessage, 0, aEntry);
       
  2521 	DeleteObjectZ(aEntry); // Delete the object to prevent it to be resent.
       
  2522 	}
       
  2523 
       
  2524 void CScrRequestImpl::NextComponentSetSizeL(const RMessage2& aMessage, CStatement* aStmt, CComponentFilter* aFilter, RPointerArray<CComponentEntry>& aEntryList, CCompViewSubsessionContext* aSubsessionContext) const
       
  2525 	{
       
  2526 	DEBUG_PRINTF(_L8("Returning the size of the next component entry set."));
       
  2527 	__ASSERT_ALWAYS(aStmt && aFilter, PanicClient(aMessage, KScrIllegalCallSequence));	
       
  2528 
       
  2529 	TInt maxArraySize = aMessage.Int0();
       
  2530 	TLanguage locale = TLanguage(aMessage.Int1());
       
  2531 	
       
  2532 	aEntryList.ResetAndDestroy();
       
  2533 	for(TInt i=0; i<maxArraySize; ++i)
       
  2534 		{
       
  2535 		CComponentEntry *entry = GetNextComponentEntryL(*aStmt, *aFilter, locale, aSubsessionContext);
       
  2536 		if(!entry)
       
  2537 			{
       
  2538 			break;
       
  2539 			}
       
  2540 		CleanupStack::PushL(entry);
       
  2541 		aEntryList.AppendL(entry);
       
  2542 		CleanupStack::Pop(entry); // Ownership is transferred
       
  2543 		}
       
  2544 	WriteArraySizeL(aMessage, 2, aEntryList);
       
  2545 	}
       
  2546 
       
  2547 void CScrRequestImpl::NextComponentSetDataL(const RMessage2& aMessage, RPointerArray<CComponentEntry>& aEntryList) const
       
  2548 	{
       
  2549 	DEBUG_PRINTF(_L8("Returning the next component entry set."));
       
  2550 	WriteArrayDataL(aMessage, 0, aEntryList);
       
  2551 	}
       
  2552 
       
  2553 void CScrRequestImpl::GetComponentIdListSizeL(const RMessage2& aMessage) const
       
  2554 	{
       
  2555 	DEBUG_PRINTF(_L8("Returning the required size to copy all components IDs from the components view."));
       
  2556 	// Get filter from the client
       
  2557 	CComponentFilter *filter = ReadComponentFilterL(aMessage);
       
  2558 	CleanupStack::PushL(filter);
       
  2559 	
       
  2560 	RArray<TComponentId> componentFilterSuperset;
       
  2561 	CleanupClosePushL(componentFilterSuperset);
       
  2562 	TBool filterSupersetInUse;
       
  2563 	// Create a statement based on the filter
       
  2564 	CStatement *stmt = OpenComponentViewL(*filter, componentFilterSuperset, filterSupersetInUse);
       
  2565 	CleanupStack::PushL(stmt);
       
  2566 	iComponentIdList.Reset();
       
  2567 	// Fetch all components from the row set and put them into the component list
       
  2568 	while(stmt->ProcessNextRowL())
       
  2569 		{
       
  2570 		TComponentId componentId = stmt->IntColumnL(0);
       
  2571 		if (filterSupersetInUse && componentFilterSuperset.FindInOrder(componentId) < 0) 
       
  2572 			continue; // The component id does not match the name/vendor/file/property filter - do not add it to the result		
       
  2573 		iComponentIdList.InsertInOrder(componentId);
       
  2574 		}
       
  2575 	// Release allocated memories
       
  2576 	CleanupStack::PopAndDestroy(3, filter); // stmt, componentFilterSuperset, filter
       
  2577 	WriteArraySizeL(aMessage, 1, iComponentIdList);
       
  2578 	}
       
  2579 
       
  2580 void CScrRequestImpl::GetComponentIdListDataL(const RMessage2& aMessage) const
       
  2581 	{
       
  2582 	DEBUG_PRINTF(_L8("Returning all components IDs from the components view."));
       
  2583 	WriteArrayDataL(aMessage, 0, iComponentIdList);
       
  2584 	}
       
  2585 
       
  2586 CStatement* CScrRequestImpl::OpenFileListStatementL(TComponentId aComponentId) const
       
  2587 	{
       
  2588 	_LIT(KSelectFilesOfComponent, "SELECT Location FROM ComponentsFiles WHERE ComponentId=?;");
       
  2589 	
       
  2590 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectFilesOfComponent);
       
  2591 	stmt->BindIntL(1, aComponentId);
       
  2592 	CleanupStack::Pop(stmt); // Ownership is transferred to the caller
       
  2593 	
       
  2594 	return stmt;
       
  2595 	}	
       
  2596 	
       
  2597 CStatement* CScrRequestImpl::OpenFileListL(const RMessage2& aMessage) const
       
  2598 	{
       
  2599 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  2600 	DEBUG_PRINTF2(_L8("Creating the requested file list for component(%d)."), componentId);
       
  2601 	return OpenFileListStatementL(componentId);
       
  2602 	}
       
  2603 
       
  2604 HBufC* CScrRequestImpl::GetNextFilePathL(CStatement& aStmt) const
       
  2605 	{
       
  2606 	if(!aStmt.ProcessNextRowL())
       
  2607 		{
       
  2608 		return NULL;
       
  2609 		}
       
  2610 	return aStmt.StrColumnL(0).AllocL();
       
  2611 	}
       
  2612 
       
  2613 void CScrRequestImpl::NextFileSizeL(const RMessage2& aMessage, CStatement* aStmt, HBufC*& aFilePath) const
       
  2614 	{
       
  2615 	__ASSERT_ALWAYS(aStmt, PanicClient(aMessage, KScrIllegalCallSequence));
       
  2616 	DeleteObjectZ(aFilePath);
       
  2617 	aFilePath = GetNextFilePathL(*aStmt);
       
  2618 	WriteObjectSizeL(aMessage, 0, aFilePath);
       
  2619 	}
       
  2620 
       
  2621 void CScrRequestImpl::NextFileDataL(const RMessage2& aMessage, HBufC*& aFilePath) const
       
  2622 	{
       
  2623 	WriteObjectDataL(aMessage, 0, aFilePath);
       
  2624 	DeleteObjectZ(aFilePath); // Delete the file path to prevent it to be resent.
       
  2625 	}
       
  2626 
       
  2627 void CScrRequestImpl::NextFileSetSizeL(const RMessage2& aMessage, CStatement* aStmt, RPointerArray<HBufC>& aFileList) const
       
  2628 	{
       
  2629 	__ASSERT_ALWAYS(aStmt, PanicClient(aMessage, KScrIllegalCallSequence));
       
  2630 	TInt maxArraySize = aMessage.Int0();
       
  2631 	aFileList.ResetAndDestroy();
       
  2632 	for(TInt i=0; i<maxArraySize; ++i)
       
  2633 		{
       
  2634 		HBufC *filePath = GetNextFilePathL(*aStmt);
       
  2635 		if(!filePath)
       
  2636 			{
       
  2637 			break;
       
  2638 			}
       
  2639 		CleanupStack::PushL(filePath);
       
  2640 		aFileList.AppendL(filePath);
       
  2641 		CleanupStack::Pop(filePath); // Ownership is transferred
       
  2642 		}
       
  2643 	WriteArraySizeL(aMessage, 1, aFileList);
       
  2644 	}
       
  2645 
       
  2646 void CScrRequestImpl::NextFileSetDataL(const RMessage2& aMessage, RPointerArray<HBufC>& aFileList) const
       
  2647 	{
       
  2648 	DEBUG_PRINTF(_L8("Returning the next file path set."));
       
  2649 	WriteArrayDataL(aMessage, 0, aFileList);
       
  2650 	}
       
  2651 
       
  2652 TComponentId CScrRequestImpl::GetComponentIdFromMsgL(const RMessage2& aMessage)
       
  2653 	{	
       
  2654 	return aMessage.Int0();
       
  2655 	}
       
  2656 
       
  2657 HBufC* CScrRequestImpl::GetSoftwareTypeNameFromMsgLC(const RMessage2& aMessage)
       
  2658 	{	
       
  2659 	switch (CScsServer::StripScsFunctionMask(aMessage.Function()))
       
  2660 		{
       
  2661 		case EAddComponent:
       
  2662 		case EAddComponentDependency:
       
  2663 		case EDeleteComponentDependency:
       
  2664 			{
       
  2665 			return ReadDescLC(aMessage, 0);
       
  2666 			}
       
  2667 		default:
       
  2668 			__ASSERT_ALWAYS(0, User::Invariant());
       
  2669 		}
       
  2670 	return NULL;
       
  2671 	}
       
  2672 
       
  2673 HBufC* CScrRequestImpl::ReadFileNameFromMsgLC(const RMessage2& aMessage)
       
  2674 	{
       
  2675 	return ReadDescLC(aMessage, 1);
       
  2676 	}
       
  2677 
       
  2678 void CScrRequestImpl::InitializeDbVersionL()
       
  2679 	{
       
  2680 	_LIT(KSelectStatement, "SELECT MajorVersion, MinorVersion, BuildNumber FROM ScrVersion;");
       
  2681 	CStatement* stmt = iDbHandle->PrepareStatementLC(KSelectStatement);
       
  2682 	if(!stmt->ProcessNextRowL())
       
  2683 		{
       
  2684 		DEBUG_PRINTF(_L("Could not find entries in the version table - internal problem"));
       
  2685 		User::Leave(KErrCorrupt);
       
  2686 		}
       
  2687 	
       
  2688 	iDbVersion.iMajor = stmt->IntColumnL(0);
       
  2689 	iDbVersion.iMinor = stmt->IntColumnL(1);
       
  2690 	iDbVersion.iBuild = stmt->IntColumnL(2);	
       
  2691 	CleanupStack::PopAndDestroy(stmt);
       
  2692 	DEBUG_PRINTF4(_L8("Opened SCR database with major version %d, minor version %d, and build number %d."), iDbVersion.iMajor,
       
  2693 			iDbVersion.iMinor, iDbVersion.iBuild);		
       
  2694 	}
       
  2695 
       
  2696 void CScrRequestImpl::VerifyDbVersionCompatibilityL() const
       
  2697 	{
       
  2698 	if (iDbVersion.iMajor != KDbInterfaceMajorVersion)
       
  2699 		{
       
  2700 		DEBUG_PRINTF3(_L8("The SCR DB is incompatible! Supported major version is %d, and the DB major version is %d"), KDbInterfaceMajorVersion, iDbVersion.iMajor);
       
  2701 		User::Leave(KErrCorrupt);
       
  2702 		}
       
  2703 	
       
  2704 	if (iDbVersion.iMinor > KDbInterfaceMinorVersion)
       
  2705 		{
       
  2706 		DEBUG_PRINTF3(_L8("The SCR DB supports newer features which are not available in this software version. The DB minor version is %d, while the supported minor version is %d"), iDbVersion.iMinor, KDbInterfaceMinorVersion);
       
  2707 		return;
       
  2708 		}	
       
  2709 	
       
  2710 	if (iDbVersion.iMinor < KDbInterfaceMinorVersion)
       
  2711 		{
       
  2712 		DEBUG_PRINTF3(_L8("The SCR DB does not support some newer features available in this software version. The DB minor version is %d, while the supported minor version is %d"), iDbVersion.iMinor, KDbInterfaceMinorVersion); 
       
  2713 		return;
       
  2714 		}	
       
  2715 	
       
  2716 	DEBUG_PRINTF4(_L8("The SCR DB has matching version with the supported interface. Supported major version is %d, minor version %d and build number %d"), KDbInterfaceMajorVersion, KDbInterfaceMinorVersion, KDbInterfaceBuildNumber);	
       
  2717 	}
       
  2718 
       
  2719 void ExtractNumberFromHexStringL(TInt& aPosition, const TDesC8& aString, TUint32& aIntValue)
       
  2720 	{
       
  2721 	TLex8 l(aString.Mid(aPosition, KUidStringLen));
       
  2722 	l.Val(aIntValue, EHex);
       
  2723 	aPosition += KUidStringLen;
       
  2724 	}
       
  2725 
       
  2726 void ParseUidHexStringL(const TDesC8& aUidString, TUint32& aSifPluginUid, TUint32& aInstallerSid, TUint32& aExecutionLayerSid)
       
  2727 	{
       
  2728 	__ASSERT_ALWAYS(aUidString.Length() >= 3*KUidStringLen, User::Leave(KErrArgument));
       
  2729 	TInt pos (0); // The starting position of aUidString
       
  2730 	ExtractNumberFromHexStringL(pos, aUidString, aSifPluginUid);
       
  2731 	ExtractNumberFromHexStringL(pos, aUidString, aInstallerSid);
       
  2732 	ExtractNumberFromHexStringL(pos, aUidString, aExecutionLayerSid);
       
  2733 	}
       
  2734 
       
  2735 TBool CompareLocalizedSoftwareTypeName(const CLocalizedSoftwareTypeName& aLeft, const CLocalizedSoftwareTypeName& aRight)
       
  2736 	{
       
  2737 	TBool result = EFalse;
       
  2738 	
       
  2739 	TRAPD(err, result = (aLeft.Locale() == aRight.Locale() && !aLeft.NameL().CompareF(aRight.NameL())));
       
  2740 	if (err != KErrNone)
       
  2741 		{
       
  2742 		DEBUG_PRINTF2(_L("CompareLocalizedSoftwareTypeName has left with error %d"), err);
       
  2743 		return EFalse;
       
  2744 		}
       
  2745 	else
       
  2746 		{
       
  2747 		return result;
       
  2748 		}
       
  2749 	}
       
  2750 
       
  2751 TBool CompareHBufDescs(const HBufC& aLeft, const HBufC& aRight)
       
  2752 	{
       
  2753 	return !aLeft.CompareF(aRight);
       
  2754 	}
       
  2755 
       
  2756 TBool CScrRequestImpl::IsSoftwareTypeExistingL(TUint32 aSwTypeId, TUint32 aSifPluginUid, TUint32 aInstallerSecureId, TUint32 aExecutionLayerSecureId, const RPointerArray<HBufC>& aMimeTypesArray, const RPointerArray<CLocalizedSoftwareTypeName>& aLocalizedNamesArray)
       
  2757 	{
       
  2758 	_LIT(KSelectSoftwareType, "SELECT SifPluginUid,InstallerSecureId,ExecutionLayerSecureId FROM SoftwareTypes WHERE SoftwareTypeId=?;");
       
  2759 	CStatement* stmt = iDbHandle->PrepareStatementLC(KSelectSoftwareType);
       
  2760 	stmt->BindIntL(1, aSwTypeId);
       
  2761 	if(!stmt->ProcessNextRowL())
       
  2762 		{
       
  2763 		DEBUG_PRINTF2(_L8("IsSoftwareTypeExistingL: Software Type Id (%d) doesn't exist in the SCR."), aSwTypeId);
       
  2764 		CleanupStack::PopAndDestroy(stmt);
       
  2765 		return EFalse;
       
  2766 		}
       
  2767 	TBool uidsNotEqual = aSifPluginUid != stmt->IntColumnL(0) ||
       
  2768 						 aInstallerSecureId != stmt->IntColumnL(1) ||
       
  2769 						 aExecutionLayerSecureId != stmt->IntColumnL(2);
       
  2770 	if(uidsNotEqual)
       
  2771 		{
       
  2772 		DEBUG_PRINTF(_L8("IsSoftwareTypeExistingL: One of the UIDs is different from the one in the database."));
       
  2773 		CleanupStack::PopAndDestroy(stmt);
       
  2774 		return EFalse;
       
  2775 		}
       
  2776 	CleanupStack::PopAndDestroy(stmt);
       
  2777 	
       
  2778 	_LIT(KSelectSwTypeNames, "SELECT Locale,Name FROM SoftwareTypeNames WHERE SoftwareTypeId=? AND Locale!=?;");
       
  2779 	CStatement* stmtNames = iDbHandle->PrepareStatementLC(KSelectSwTypeNames);
       
  2780 	stmtNames->BindIntL(1, aSwTypeId);
       
  2781 	stmtNames->BindIntL(2, KNonLocalized);
       
  2782 	TInt numOfFoundNames (0);
       
  2783 	while(stmtNames->ProcessNextRowL())
       
  2784 		{
       
  2785 		++numOfFoundNames;
       
  2786 		const TDesC& swTypeNameValue = stmtNames->StrColumnL(1);
       
  2787 		CLocalizedSoftwareTypeName *swTypeName = CLocalizedSoftwareTypeName::NewLC(swTypeNameValue, TLanguage(stmtNames->IntColumnL(0)));
       
  2788 		TInt ret = aLocalizedNamesArray.Find(swTypeName, TIdentityRelation<CLocalizedSoftwareTypeName>(CompareLocalizedSoftwareTypeName));
       
  2789 		CleanupStack::PopAndDestroy(swTypeName);
       
  2790 		if(KErrNotFound == ret)
       
  2791 			{
       
  2792 			DEBUG_PRINTF2(_L("IsSoftwareTypeExistingL: %S doesn't exist in the provided sofwtare type names list."), &swTypeNameValue);
       
  2793 			CleanupStack::PopAndDestroy(stmtNames);
       
  2794 			return EFalse;
       
  2795 			}
       
  2796 		}
       
  2797 	CleanupStack::PopAndDestroy(stmtNames);
       
  2798 	if(numOfFoundNames != aLocalizedNamesArray.Count())
       
  2799 		{
       
  2800 		DEBUG_PRINTF3(_L("IsSoftwareTypeExistingL: the number of provided software type names (%d) is different than the number of existing software type names (%d) in the SCR."), numOfFoundNames, aLocalizedNamesArray.Count());
       
  2801 		return EFalse;
       
  2802 		}
       
  2803 	
       
  2804 	_LIT(KSelectMimeTypes, "SELECT MimeType FROM MimeTypes WHERE SoftwareTypeId=?;");
       
  2805 	CStatement* stmtMimes = iDbHandle->PrepareStatementLC(KSelectMimeTypes);
       
  2806 	stmtMimes->BindIntL(1, aSwTypeId);
       
  2807 	TInt numOfFoundMimes (0);
       
  2808 	while(stmtMimes->ProcessNextRowL())
       
  2809 		{
       
  2810 		++numOfFoundMimes;
       
  2811 		HBufC *mimeType = stmtMimes->StrColumnL(0).AllocLC();
       
  2812 		TInt ret = aMimeTypesArray.Find(mimeType, TIdentityRelation<HBufC>(CompareHBufDescs));
       
  2813 		if(KErrNotFound == ret)
       
  2814 			{
       
  2815 			DEBUG_PRINTF2(_L("IsSoftwareTypeExistingL: %S doesn't exist in the provided MIME types list."), mimeType);
       
  2816 			CleanupStack::PopAndDestroy(2, stmtMimes); // stmtMimes, mimeType
       
  2817 			return EFalse;
       
  2818 			}
       
  2819 		CleanupStack::PopAndDestroy(mimeType);
       
  2820 		}
       
  2821 	CleanupStack::PopAndDestroy(stmtMimes);
       
  2822 	if(numOfFoundMimes != aMimeTypesArray.Count())
       
  2823 		{
       
  2824 		DEBUG_PRINTF3(_L("IsSoftwareTypeExistingL: the number of provided MIME types (%d) is different than the number of existing MIME types (%d) in the SCR."), numOfFoundMimes, aMimeTypesArray.Count());
       
  2825 		return EFalse;
       
  2826 		}
       
  2827 	// All software type details are identical
       
  2828 	DEBUG_PRINTF(_L8("IsSoftwareTypeExistingL: All software type details are identical. This is a software type update."));
       
  2829 	return ETrue;
       
  2830 	}
       
  2831 
       
  2832 void CScrRequestImpl::AddSoftwareTypeL(const RMessage2& aMessage)
       
  2833 	{
       
  2834 	DEBUG_PRINTF(_L8("Adding a new software type."));
       
  2835 	// NB SoftwareTypeId is the hash of unique software type name. Since this name is unique, it is expected
       
  2836 	// that there won't be any conflicts with software type ids. If an installer is uninstalled and then re-installed,
       
  2837 	// the same software type id will be assigned for it as its unique name is not changed. The advantage is that
       
  2838 	// the orphaned components will become non-orphaned again automatically when their installer is re-installed.
       
  2839 	// Otherwise, we would have to find a complex solution to associate the software type id of orphaned components
       
  2840 	// with the corresponding installer which had been re-installed.
       
  2841 	// Another advantage of this approach is that it is not mandatory to query SoftwareTypes table in order to get
       
  2842 	// the software type id of an installer. If the uniqe software type name of the installer is known, its hash
       
  2843 	// is simply calculated to obtain its software type id.
       
  2844 	
       
  2845 	// Slot-0 contains Unique Software Type Name
       
  2846 	HBufC *uniqueSwTypeName = ReadDescLC(aMessage, 0);
       
  2847 	TUint32 swTypeId = HashCaseSensitiveL(*uniqueSwTypeName);
       
  2848 	
       
  2849 	// Slot-1 contains the concatenated values of SifPluginUid, InstallerSecureId and ExecutionLayerSecureId in turn.
       
  2850 	HBufC8 *uidString = ReadDesc8LC(aMessage, 1);
       
  2851 	TUint32 sifPluginUid (0);
       
  2852 	TUint32 installerSecureId (0);
       
  2853 	TUint32 executionLayerSecureId (0);
       
  2854 	ParseUidHexStringL(*uidString, sifPluginUid, installerSecureId, executionLayerSecureId);
       
  2855 	CleanupStack::PopAndDestroy(uidString);
       
  2856 	
       
  2857 	// Slot-2 contains the list of MIME types
       
  2858 	RIpcReadStream mimeTypesReader;
       
  2859 	CleanupClosePushL(mimeTypesReader);
       
  2860 	mimeTypesReader.Open(aMessage, 2);
       
  2861 				
       
  2862 	RPointerArray<HBufC> mimeTypesArray;
       
  2863 	CleanupResetAndDestroyPushL(mimeTypesArray);
       
  2864 	InternalizePointersArrayL(mimeTypesArray, mimeTypesReader);
       
  2865 	
       
  2866 	// Slot-3 contains Localized Software Type Names
       
  2867 	RIpcReadStream localizedNamesReader;
       
  2868 	CleanupClosePushL(localizedNamesReader);
       
  2869 	localizedNamesReader.Open(aMessage, 3);
       
  2870 				
       
  2871 	RPointerArray<CLocalizedSoftwareTypeName> localizedNamesArray;
       
  2872 	CleanupResetAndDestroyPushL(localizedNamesArray);
       
  2873 	InternalizePointersArrayL(localizedNamesArray, localizedNamesReader);
       
  2874 	
       
  2875 	if (IsSoftwareTypeExistingL(swTypeId, sifPluginUid, installerSecureId, executionLayerSecureId, mimeTypesArray, localizedNamesArray))
       
  2876 		{ // If the software type exists, do nothing and return;	
       
  2877 		CleanupStack::PopAndDestroy(5, uniqueSwTypeName); // uniqueSwTypeName, mimeTypesReader, mimeTypesArray, localizedNamesReader, localizedNamesArray
       
  2878 		return; 
       
  2879 		}
       
  2880 	
       
  2881 	// First, insert the main record to SoftwareTypes table
       
  2882 	_LIT(KInsertSwType, "INSERT INTO SoftwareTypes(SoftwareTypeId,SifPluginUid,InstallerSecureId,ExecutionLayerSecureId) VALUES(?,?,?,?);");
       
  2883 	TInt numberOfValuesSwType = 4;
       
  2884 	ExecuteStatementL(KInsertSwType(), numberOfValuesSwType, EValueInteger, swTypeId, EValueInteger, sifPluginUid, EValueInteger, installerSecureId, EValueInteger, executionLayerSecureId);
       
  2885 	
       
  2886 	// Then, insert MIME types of this software type into MimeTypes table
       
  2887 	_LIT(KInsertMimeType, "INSERT INTO MimeTypes(SoftwareTypeId,MimeType) VALUES(?,?);");
       
  2888 	TInt numberOfValuesMimeType = 2;
       
  2889 	TInt countMimeTypes = mimeTypesArray.Count();
       
  2890 	for(TInt i=0; i<countMimeTypes; ++i)
       
  2891 		{
       
  2892 		ExecuteStatementL(KInsertMimeType(), numberOfValuesMimeType, EValueInteger, swTypeId, EValueString, mimeTypesArray[i]);
       
  2893 		}
       
  2894 		
       
  2895 	// Finally, insert unique and localized names into SoftwareTypeNames table
       
  2896 	_LIT(KInsertSwTypeName, "INSERT INTO SoftwareTypeNames(SoftwareTypeId,Locale,Name) VALUES(?,?,?);");
       
  2897 	TInt numberOfValuesSwTypeName = 3;
       
  2898 	ExecuteStatementL(KInsertSwTypeName(), numberOfValuesSwTypeName, EValueInteger, swTypeId, EValueInteger, KNonLocalized, EValueString, uniqueSwTypeName);
       
  2899 		
       
  2900 	TInt countNames = localizedNamesArray.Count();
       
  2901 	for(TInt i=0; i<countNames; ++i)
       
  2902 		{
       
  2903 		TLanguage locale = localizedNamesArray[i]->Locale();
       
  2904 		const TDesC& name = localizedNamesArray[i]->NameL();
       
  2905 		ExecuteStatementL(KInsertSwTypeName(), numberOfValuesSwTypeName, EValueInteger, swTypeId, EValueInteger, locale, EValueString, &name);
       
  2906 		}	
       
  2907 	CleanupStack::PopAndDestroy(5, uniqueSwTypeName); // uniqueSwTypeName, mimeTypesReader, mimeTypesArray, localizedNamesReader, localizedNamesArray
       
  2908 	}
       
  2909 
       
  2910 void CScrRequestImpl::DeleteSoftwareTypeL(const RMessage2& aMessage)
       
  2911 	{
       
  2912 	HBufC *uniqueSwTypeName = ReadDescLC(aMessage, 0);
       
  2913 	DEBUG_PRINTF2(_L("Deleting Software type (%S)."), uniqueSwTypeName);
       
  2914 	
       
  2915 	TUint32 swTypeId = HashCaseSensitiveL(*uniqueSwTypeName);
       
  2916 	CleanupStack::PopAndDestroy(uniqueSwTypeName);
       
  2917 	
       
  2918 	// First, delete software type names
       
  2919 	_LIT(KDeleteSoftwareTypeNames, "DELETE FROM SoftwareTypeNames WHERE SoftwareTypeId=?;");
       
  2920 	TInt numberOfValues = 1;
       
  2921 	ExecuteStatementL(KDeleteSoftwareTypeNames(), numberOfValues, EValueInteger, swTypeId);
       
  2922 	
       
  2923 	// Secondly, delete the actual software type record
       
  2924 	_LIT(KDeleteSoftwareType, "DELETE FROM SoftwareTypes WHERE SoftwareTypeId=?;");
       
  2925 	ExecuteStatementL(KDeleteSoftwareType(), numberOfValues, EValueInteger, swTypeId);
       
  2926 	
       
  2927 	// Thirdly, get the list of MIME types belong to the deleted software type. 
       
  2928 	// This list will be returned to the client with another request (GetDeletedMimeTypesL)
       
  2929 	_LIT(KSelectMimeTypes, "SELECT MimeType FROM MimeTypes WHERE SoftwareTypeId=?;");
       
  2930 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectMimeTypes);
       
  2931 	stmt->BindIntL(1, swTypeId);
       
  2932 	
       
  2933 	iDeletedMimeTypes.ResetAndDestroy();
       
  2934 	while(stmt->ProcessNextRowL())
       
  2935 		{
       
  2936 		iDeletedMimeTypes.AppendL(stmt->StrColumnL(0).AllocL());	
       
  2937 		}
       
  2938 	CleanupStack::PopAndDestroy(stmt);
       
  2939 	
       
  2940 	// Finally, delete the MIME types belong to the deleted software type name
       
  2941 	_LIT(KDeleteMimeTypes, "DELETE FROM MimeTypes WHERE SoftwareTypeId=?;");
       
  2942 	ExecuteStatementL(KDeleteMimeTypes(), numberOfValues, EValueInteger, swTypeId);
       
  2943 	WriteArraySizeL(aMessage, 1, iDeletedMimeTypes);
       
  2944 	}
       
  2945 
       
  2946 void CScrRequestImpl::GetDeletedMimeTypesL(const RMessage2& aMessage) const
       
  2947 	{
       
  2948 	WriteArrayDataL(aMessage, 0, iDeletedMimeTypes);
       
  2949 	iDeletedMimeTypes.ResetAndDestroy();
       
  2950 	}
       
  2951 
       
  2952 TBool CScrRequestImpl::GetIsComponentOrphanedL(TComponentId aComponentId) const	
       
  2953 	{
       
  2954 	_LIT(KComponentSoftwareTypeId, "SELECT SoftwareTypeId FROM Components WHERE ComponentId=?;");	
       
  2955 	
       
  2956 	CStatement *stmt = iDbHandle->PrepareStatementLC(KComponentSoftwareTypeId);
       
  2957 	stmt->BindIntL(1, aComponentId);
       
  2958 		
       
  2959 	if(!stmt->ProcessNextRowL())
       
  2960 		{ 
       
  2961 		DEBUG_PRINTF2(_L("Component Id (%d) couldn't be found!"), aComponentId);
       
  2962 		User::Leave(KErrNotFound);
       
  2963 		}
       
  2964 	
       
  2965 	TUint32 swTypeId = stmt->IntColumnL(0);
       
  2966 	CleanupStack::PopAndDestroy(stmt);
       
  2967 	
       
  2968 	// The component is orphaned iff the software type does not exist.
       
  2969 	return !IsSoftwareTypeExistingL(swTypeId);
       
  2970 	}
       
  2971 	
       
  2972 void CScrRequestImpl::GetIsComponentOrphanedL(const RMessage2& aMessage) const
       
  2973 	{
       
  2974 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  2975 	TBool result = GetIsComponentOrphanedL(componentId);
       
  2976 	DEBUG_PRINTF2(_L8("Retrieving whether the component(%d) is orphaned."), componentId);
       
  2977 
       
  2978 	TPckg<TBool> resultPkg(result);
       
  2979 	
       
  2980 	aMessage.WriteL(1, resultPkg);	
       
  2981 	}
       
  2982 
       
  2983 void CheckAndCreateLogFileL(RFs& aFs, const TDesC& aFileName)
       
  2984 	{
       
  2985 	TEntry entry;
       
  2986 	TInt err = aFs.Entry(aFileName, entry);
       
  2987 	
       
  2988 	if(KErrNone == err)
       
  2989 		return;
       
  2990 
       
  2991 	if (KErrPathNotFound == err)
       
  2992 		{
       
  2993 		User::LeaveIfError(aFs.MkDirAll(aFileName));
       
  2994 		}		
       
  2995 	else if(KErrNotFound != err)
       
  2996 		{
       
  2997 		DEBUG_PRINTF2(_L("The log file couldn't be opened. Error=%d."), err);
       
  2998 		User::Leave(err);	
       
  2999 		}
       
  3000 	
       
  3001 	RFileWriteStream stream;
       
  3002 	User::LeaveIfError(stream.Create(aFs, aFileName, EFileWrite | EFileShareAny | EFileStream));
       
  3003 	stream.PushL();
       
  3004 	stream.WriteInt32L(1); // The major version of the log file
       
  3005 	stream.WriteInt32L(0); // The minor version of the log file
       
  3006 	// Please note that the log file version is not used currently. It is implemented for a possible future need.
       
  3007 	// If the version format is changed, then the end of FlushLogEntriesArrayL function where the final log count is written must be updated.
       
  3008 	// FlushLogEntriesArrayL assumes that first 8 bytes store version information.
       
  3009 	stream.WriteInt32L(0); // The number of log records in the log file
       
  3010 	stream.CommitL();
       
  3011 	CleanupStack::PopAndDestroy(&stream);			
       
  3012 	}
       
  3013 
       
  3014 void CScrRequestImpl::FlushLogEntriesArrayL()
       
  3015 	{
       
  3016 	TInt logCount2bFlushed = iLogEntries.Count();
       
  3017 	if(!logCount2bFlushed)
       
  3018 		return; // No record to write into the log file.
       
  3019 	
       
  3020 	// Get the log file name
       
  3021 	HBufC *logFileName = UpdateFilePathDriveLC(KScrLogFileName, iFs.GetSystemDriveChar());
       
  3022 	// Check whether the log file exists. If not, create one.
       
  3023 	CheckAndCreateLogFileL(iFs, *logFileName);
       
  3024 	
       
  3025 	RFileReadStream readStream;
       
  3026 	User::LeaveIfError(readStream.Open(iFs, *logFileName, EFileRead|EFileShareExclusive|EFileStream));
       
  3027 	readStream.PushL();
       
  3028 	(void)readStream.ReadInt32L(); // skip the major version of the log file
       
  3029 	(void)readStream.ReadInt32L(); // skip the minor version of the log file
       
  3030 	TInt currentLogCount = readStream.ReadInt32L();
       
  3031 		
       
  3032 	if(KMaxScrLogEntries <= currentLogCount + logCount2bFlushed)
       
  3033 		{
       
  3034 		//Create a temporary file and read the log file in that
       
  3035 		//oldest entries will be removed in the temporary log file
       
  3036 		HBufC *tempLogName = UpdateFilePathDriveLC(KScrTempLogFileName, iFs.GetSystemDriveChar());
       
  3037 		TInt err = iFs.Delete(*tempLogName);
       
  3038 		__ASSERT_ALWAYS(err == KErrNotFound || err == KErrNone, User::Leave(err));
       
  3039 		CheckAndCreateLogFileL(iFs, *tempLogName);
       
  3040 		
       
  3041 		RFileWriteStream writeStream;
       
  3042 		User::LeaveIfError(writeStream.Open(iFs, *tempLogName, EFileWrite | EFileStream));
       
  3043 		writeStream.PushL();
       
  3044 		writeStream.Sink()->SeekL(MStreamBuf::EWrite,EStreamEnd); // Skip the version info and log count
       
  3045 			
       
  3046 		TInt tmpLogCount (0);
       
  3047 		CScrLogEntry *log = NULL;
       
  3048 			
       
  3049 		for (TInt i = logCount2bFlushed; i < currentLogCount; ++i, ++tmpLogCount)
       
  3050 			{
       
  3051 			log = CScrLogEntry::NewLC(readStream);		
       
  3052 			writeStream << *log;
       
  3053 			CleanupStack::PopAndDestroy(log); 					
       
  3054 			} // for
       
  3055 			
       
  3056 		currentLogCount = tmpLogCount; 
       
  3057 		writeStream.CommitL();
       
  3058 		CleanupStack::PopAndDestroy(&writeStream); 
       
  3059 		readStream.Release();
       
  3060 			
       
  3061 		RStsSession stsSession; // transaction service
       
  3062 		CleanupClosePushL(stsSession);
       
  3063 		stsSession.CreateTransactionL();				
       
  3064 			
       
  3065 		stsSession.RemoveL(*logFileName);
       
  3066 		stsSession.RegisterNewL(*logFileName);
       
  3067 		stsSession.RegisterTemporaryL(*tempLogName);
       
  3068 			
       
  3069 		TInt renameErr = iFs.Rename(*tempLogName,*logFileName);							
       
  3070 		if (KErrNone == renameErr)
       
  3071 			{
       
  3072 			// commit file changes.
       
  3073 			stsSession.CommitL();
       
  3074 			}
       
  3075 		else
       
  3076 			{
       
  3077 			// rollback file changes and leave with the error code.
       
  3078 			stsSession.RollBackL();
       
  3079 			DEBUG_PRINTF2(_L("The log file couldn't be renamed. Error=%d."), renameErr);
       
  3080 			User::Leave(renameErr);
       
  3081 			}
       
  3082 		CleanupStack::PopAndDestroy(2, tempLogName); // tempLogName, stsSession
       
  3083 		} // endif KMaxScrLogEntries <=
       
  3084 	
       
  3085 	CleanupStack::PopAndDestroy(&readStream);
       
  3086 	
       
  3087 	RFile file;
       
  3088 	User::LeaveIfError(file.Open(iFs, *logFileName, EFileRead|EFileWrite| EFileShareExclusive| EFileStream));
       
  3089 	CleanupClosePushL(file);
       
  3090 	TInt pos (0);
       
  3091 	User::LeaveIfError(file.Seek(ESeekEnd, pos));	
       
  3092 	RFileWriteStream stream(file, pos);
       
  3093 	stream.PushL();
       
  3094 	
       
  3095 	TInt startIdx = (logCount2bFlushed - KMaxScrLogEntries)>0 ? (logCount2bFlushed - KMaxScrLogEntries) : 0;
       
  3096 	TInt logCountFlushed (0);
       
  3097 	for(TInt i=startIdx; i<logCount2bFlushed; ++i, ++logCountFlushed)
       
  3098 		{
       
  3099 		iLogEntries[i]->ExternalizeL(stream);
       
  3100 		}
       
  3101 	iLogEntries.ResetAndDestroy();
       
  3102 	stream.CommitL();
       
  3103 	stream.Release();
       
  3104 	file.Close();
       
  3105 	
       
  3106 	// Update the log count
       
  3107 	User::LeaveIfError(stream.Open(iFs, *logFileName, EFileRead|EFileWrite|EFileShareExclusive|EFileStream));
       
  3108 	stream.Sink()->SeekL(MStreamBuf::EWrite,EStreamBeginning,8); // Skip the version info
       
  3109 	stream.WriteInt32L(logCountFlushed + currentLogCount);
       
  3110 	stream.CommitL();
       
  3111 	
       
  3112 	CleanupStack::PopAndDestroy(3, logFileName); // logFileName, file, stream
       
  3113 	}
       
  3114 
       
  3115 void CScrRequestImpl::GetLogFileHandleL(const RMessage2& aMessage) const
       
  3116 	{
       
  3117 	// Get the log file name
       
  3118 	HBufC *logFileName = UpdateFilePathDriveLC(KScrLogFileName, iFs.GetSystemDriveChar());
       
  3119 	// Check whether the log file exists. If not, create one.
       
  3120 	CheckAndCreateLogFileL(iFs, *logFileName);
       
  3121 	
       
  3122 	RFile file;
       
  3123 	User::LeaveIfError(file.Open(iFs, *logFileName, EFileRead | EFileShareAny | EFileStream));
       
  3124 	CleanupClosePushL(file);
       
  3125 		
       
  3126 	// Store the RFile handle into the package buffer in slot 0 and complete the message with the RFs handle
       
  3127 	User::LeaveIfError(file.TransferToClient(aMessage, 0));
       
  3128 	ASSERT(aMessage.IsNull());  // The message should have been completed
       
  3129 	CleanupStack::PopAndDestroy(2, logFileName); // logFileName, file
       
  3130 	}
       
  3131 
       
  3132 void CScrRequestImpl::GetIsComponentOnReadOnlyDriveL(const RMessage2& aMessage) const
       
  3133 	{
       
  3134 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  3135 	DEBUG_PRINTF2(_L8("Checking if the component(%d) is on read-only drive."), componentId);
       
  3136 	
       
  3137 	// Get the drives on which the component files' are registered
       
  3138 	TInt driveBitmask = GetInstalledDrivesBitmaskL(componentId);	
       
  3139 			
       
  3140 	TBool result = EFalse;
       
  3141 	
       
  3142 	for (TInt index = 0; index < KMaxDrives; ++index, driveBitmask >>= 1)
       
  3143 		{
       
  3144 		if ((driveBitmask & 0x1) && IsDriveReadOnlyL(index))
       
  3145 			{
       
  3146 			DEBUG_PRINTF3(_L8("Component %d has registered a file at read-only drive %c ."), componentId, index + 'a');
       
  3147 			result = ETrue;
       
  3148 			break;
       
  3149 			}
       
  3150 		}
       
  3151 	
       
  3152 	TPckg<TBool> resPkg(result);	
       
  3153 	aMessage.WriteL(1, resPkg);	
       
  3154 	}
       
  3155 
       
  3156 TBool CScrRequestImpl::IsDriveReadOnlyL(TInt driveIndex) const
       
  3157 	{
       
  3158 	TDriveInfo driveInfo;
       
  3159 	User::LeaveIfError(iFs.Drive(driveInfo,driveIndex));
       
  3160 		
       
  3161 	TBool result = EFalse;
       
  3162 	if ((driveInfo.iDriveAtt&KDriveAttRom) || (driveInfo.iType==EMediaRom))
       
  3163 		result = ETrue;
       
  3164 	
       
  3165 	return result;
       
  3166 	}
       
  3167 
       
  3168 void CScrRequestImpl::GetIsComponentPresentL(const RMessage2& aMessage) const
       
  3169 	{
       
  3170 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  3171 	DEBUG_PRINTF2(_L8("Checking if the component(%d) is available."), componentId);
       
  3172 	
       
  3173 	_LIT(KSelectCompPresent, "SELECT CompPresence FROM Components WHERE ComponentId=?;");
       
  3174 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectCompPresent);
       
  3175 	stmt->BindIntL(1, componentId);
       
  3176 	if(!stmt->ProcessNextRowL())
       
  3177 		{
       
  3178 		DEBUG_PRINTF2(_L8("Component (%d) couldn't be found in the SCR database."), componentId);
       
  3179 		User::Leave(KErrNotFound);
       
  3180 		}
       
  3181 	TBool result = (stmt->IntColumnL(0) == 1);
       
  3182 	CleanupStack::PopAndDestroy(stmt);
       
  3183 	
       
  3184 	// The default value for CompPresence is ETrue. So when we find that the SCR DB contains the 
       
  3185 	// default property value we check if the drives registered by the component are present.   
       
  3186 	if (result && !CheckForMediaPresenceL(componentId))
       
  3187 		{
       
  3188 		result = EFalse;
       
  3189 		}
       
  3190 				
       
  3191 	TPckg<TBool> isCompPresent(result);	
       
  3192 	aMessage.WriteL(1, isCompPresent);	
       
  3193 	}
       
  3194 
       
  3195 void CScrRequestImpl::SetIsComponentPresentL(const RMessage2& aMessage)
       
  3196 	{
       
  3197 	DEBUG_PRINTF(_L8("Setting the component as present."));
       
  3198 	_LIT(KColumnNameCompPresence, "CompPresence");
       
  3199 	ReadAndSetCommonComponentPropertyL(aMessage, KColumnNameCompPresence);	
       
  3200 	}
       
  3201 
       
  3202 void CScrRequestImpl::GetComponentSupportedLocalesListSizeL(const RMessage2& aMessage) const
       
  3203 	{
       
  3204 	TComponentId componentId = GetComponentIdFromMsgL(aMessage);
       
  3205 	DEBUG_PRINTF2(_L8("Returning the required size to copy all matching supported language IDs for component =(%d)"), componentId);
       
  3206 
       
  3207 	_LIT(KSelectMatchingSupportedLocales, "SELECT Locale FROM ComponentLocalizables WHERE ComponentId=?;");
       
  3208 	CStatement *stmt = iDbHandle->PrepareStatementLC(KSelectMatchingSupportedLocales);
       
  3209 	stmt->BindIntL(1, componentId);
       
  3210 	iMatchingSupportedLanguageList.Close();
       
  3211 	while(stmt->ProcessNextRowL())
       
  3212 		{
       
  3213 		TLanguage languageId = (TLanguage)stmt->IntColumnL(0);
       
  3214 		iMatchingSupportedLanguageList.Insert(languageId,iMatchingSupportedLanguageList.Count());
       
  3215 		}
       
  3216 	if (iMatchingSupportedLanguageList.Count() == 1)
       
  3217 	    {
       
  3218 	    iMatchingSupportedLanguageList.Close();
       
  3219 	    }
       
  3220 	
       
  3221 	// Release allocated memories
       
  3222 	CleanupStack::PopAndDestroy(1, stmt); // stmt
       
  3223 	WriteArraySizeL(aMessage, 1, iMatchingSupportedLanguageList);
       
  3224 	
       
  3225 	}
       
  3226 
       
  3227 void CScrRequestImpl::GetComponentSupportedLocalesListDataL(const RMessage2& aMessage) const
       
  3228 	{
       
  3229 	DEBUG_PRINTF(_L8("Getting the Data of matching supported languages"));
       
  3230 	WriteArrayDataL(aMessage, 0, iMatchingSupportedLanguageList);
       
  3231 	iMatchingSupportedLanguageList.Close();
       
  3232 	}