appfw/apparchitecture/aplist/aplappinforeader.cpp
changeset 0 2e3d3ce01487
child 29 6a787171e1de
child 62 924385140d98
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // aplappinforeader.cpp
       
    15 //
       
    16 
       
    17 #include "aplapplist.h"
       
    18 #include "aplapplistitem.h"
       
    19 #include "aplappinforeader.h"
       
    20 #include <apgaplst.h>
       
    21 #include <bautils.h>
       
    22 #include "APGICNFL.H" 
       
    23 #include "APFDEF.H"
       
    24 #include "../apgrfx/apprivate.h"		// KUidPrefixedNonNativeRegistrationResourceFile
       
    25 #include <barsc2.h>
       
    26 #include <barsread2.h>
       
    27 #include <e32uid.h>
       
    28 #include "../apgrfx/APGSTD.H"			// EPanicNullPointer
       
    29 #include "../apgrfx/apsecutils.h"		// CApaSecurityUtils
       
    30 
       
    31 const TUint KResourceOffsetMask = 0xFFFFF000;
       
    32 
       
    33 _LIT(KAppBinaryPathAndExtension, "\\sys\\bin\\.exe");
       
    34 const TInt KAppRegistrationInfoResourceId = 1;
       
    35 
       
    36 // The 2nd UID that defines a resource file as being an application registration resource file.
       
    37 const TUid KUidAppRegistrationFile = {0x101F8021};
       
    38 
       
    39 //
       
    40 // Local functions
       
    41 //
       
    42 
       
    43 extern void CleanupServiceArray(TAny* aServiceArray);	// Implemented in AplAppList.cpp
       
    44 
       
    45 // ApaUtils
       
    46 
       
    47 TBool ApaUtils::TypeUidIsForRegistrationFile(const TUidType& aUidType)
       
    48 	{ // static
       
    49 	return (aUidType[1].iUid==KUidAppRegistrationFile.iUid ||
       
    50 		   aUidType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile);
       
    51 	}
       
    52 
       
    53 
       
    54 //
       
    55 // CApaAppInfoReader
       
    56 //
       
    57 
       
    58 // The behaviour of the Take-methods of this class is a little non-standard, as it
       
    59 // transfers ownership of the pointer owned by a CApaAppInfoReader derived object
       
    60 // to the caller. This means that this function is only designed to be called once.
       
    61 // Doing things this way provides a small performance optimisation by enabling the caller
       
    62 // to delete it's stored pointer, and replace it with one returned by this function,
       
    63 // instead of having to copy the object (copying could be expensive for the methods
       
    64 // of this class that need to return arrays).
       
    65 
       
    66 
       
    67 CApaAppInfoReader* CApaAppInfoReader::NewL(RFs& aFs, const TDesC& aRegistrationFileName, TUid aAppUid)
       
    68 	{
       
    69 	CApaAppInfoReader* self = new(ELeave) CApaAppInfoReader(aFs, aRegistrationFileName, aAppUid);
       
    70 	CleanupStack::PushL(self);
       
    71 	self->ConstructL();
       
    72 	CleanupStack::Pop(self);
       
    73 	return self;
       
    74 	}
       
    75 
       
    76 CApaAppInfoReader::CApaAppInfoReader(RFs& aFs, const TDesC& aRegistrationFileName, TUid aAppUid) :
       
    77 	iFs(aFs),
       
    78 	iAppUid(aAppUid),
       
    79 	iTimeStamp(0),
       
    80 	iDefaultScreenNumber(0),
       
    81 	iNonMbmIconFile(EFalse),
       
    82 	iLocalisableResourceFileTimeStamp(0),
       
    83 	iApplicationLanguage(ELangNone),
       
    84 	iIndexOfFirstOpenService(KErrNotFound),
       
    85 	iRegistrationFileName(aRegistrationFileName)
       
    86 	{
       
    87 	}
       
    88 
       
    89 void CApaAppInfoReader::ConstructL()
       
    90 	{
       
    91 	iIconLoader = CApaIconLoader::NewL(iFs);
       
    92 	}
       
    93 
       
    94 CApaAppInfoReader::~CApaAppInfoReader()
       
    95 	{
       
    96 	delete iAppBinaryFullName;
       
    97 	delete iCaption;
       
    98 	delete iShortCaption;
       
    99 	delete iIcons;
       
   100 	if (iViewDataArray)
       
   101 		iViewDataArray->ResetAndDestroy();
       
   102 	
       
   103 	delete iViewDataArray;
       
   104 	delete iOwnedFileArray;
       
   105 	delete iIconFileName;
       
   106 	delete iLocalisableResourceFileName;
       
   107 	
       
   108 	if (iServiceArray)
       
   109  		{
       
   110  		CleanupServiceArray(iServiceArray);
       
   111  		iServiceArray = NULL;
       
   112   		}
       
   113   		
       
   114 	delete iOpaqueData;
       
   115 	delete iIconLoader;
       
   116 	}
       
   117 
       
   118 HBufC* CApaAppInfoReader::AppBinaryFullName()
       
   119 	{
       
   120 	HBufC* fileName = iAppBinaryFullName;
       
   121 	iAppBinaryFullName = NULL; // ownership transferred to caller
       
   122 	return fileName;
       
   123 	}
       
   124 
       
   125 TUidType CApaAppInfoReader::AppBinaryUidType() const
       
   126 	{
       
   127 	return iAppBinaryUidType;
       
   128 	}
       
   129 
       
   130 TTime CApaAppInfoReader::TimeStamp() const
       
   131 	{
       
   132 	return iTimeStamp;
       
   133 	}
       
   134 
       
   135 TTime CApaAppInfoReader::IconFileTimeStamp() const
       
   136      {
       
   137      return iIconFileTimeStamp;
       
   138      }
       
   139 
       
   140 void CApaAppInfoReader::Capability(TDes8& aCapabilityBuf) const
       
   141 	{
       
   142 	TApaAppCapabilityBuf buf(iCapability);
       
   143 	TApaAppCapability::CopyCapability(aCapabilityBuf, buf);
       
   144 	}
       
   145 
       
   146 TUint CApaAppInfoReader::DefaultScreenNumber() const
       
   147 	{
       
   148 	return iDefaultScreenNumber;
       
   149 	}
       
   150 
       
   151 HBufC* CApaAppInfoReader::Caption()
       
   152 	{
       
   153 	HBufC* caption = iCaption;
       
   154 	iCaption = NULL; // ownership transferred to caller
       
   155 	return caption;
       
   156 	}
       
   157 
       
   158 HBufC* CApaAppInfoReader::ShortCaption()
       
   159 	{
       
   160 	HBufC* shortCaption = iShortCaption;
       
   161 	iShortCaption = NULL; // ownership transferred to caller
       
   162 	return shortCaption;
       
   163 	}
       
   164 
       
   165 CApaAppIconArray* CApaAppInfoReader::Icons()
       
   166 	{
       
   167 	CApaAppIconArray* icons = iIcons;
       
   168 	iIcons = NULL; // ownership transferred to caller
       
   169 	return icons;
       
   170 	}
       
   171 
       
   172 TInt CApaAppInfoReader::NumOfAppIcons() const
       
   173 	{
       
   174 	return iNumOfAppIcons;
       
   175 	}
       
   176 
       
   177 CArrayPtrFlat<CApaAppViewData>* CApaAppInfoReader::Views()
       
   178 	{
       
   179 	CArrayPtrFlat<CApaAppViewData>* viewDataArray = iViewDataArray;
       
   180 	iViewDataArray = NULL; // ownership transferred to caller
       
   181 	return viewDataArray;
       
   182 	}
       
   183 	
       
   184 CDesCArray* CApaAppInfoReader::OwnedFiles()
       
   185 	{
       
   186 	CDesCArray* ownedFileArray = iOwnedFileArray;
       
   187 	iOwnedFileArray = NULL; // ownership transferred to caller
       
   188 	return ownedFileArray;
       
   189 	}
       
   190 
       
   191 HBufC* CApaAppInfoReader::IconFileName()
       
   192 	{
       
   193 	HBufC* iconFileName = iIconFileName;
       
   194 	iIconFileName = NULL; // ownership transferred to caller
       
   195 	return iconFileName;
       
   196 	}
       
   197 
       
   198 TBool CApaAppInfoReader::NonMbmIconFile() const
       
   199 	{
       
   200 	return iNonMbmIconFile;
       
   201 	}
       
   202 
       
   203 HBufC* CApaAppInfoReader::LocalisableResourceFileName()
       
   204 	{
       
   205 	HBufC* localisableResourceFileName = iLocalisableResourceFileName;
       
   206 	iLocalisableResourceFileName = NULL; // ownership transferred to caller
       
   207 	return localisableResourceFileName;
       
   208 	}
       
   209 
       
   210 TTime CApaAppInfoReader::LocalisableResourceFileTimeStamp() const
       
   211 	{
       
   212 	return iLocalisableResourceFileTimeStamp;
       
   213 	}
       
   214 	
       
   215 TLanguage CApaAppInfoReader::AppLanguage() const
       
   216 	{
       
   217 	return iApplicationLanguage;
       
   218 	}
       
   219 
       
   220 CArrayFixFlat<TApaAppServiceInfo>* CApaAppInfoReader::ServiceArray(TInt& aIndexOfFirstOpenService)
       
   221 	{
       
   222 	CArrayFixFlat<TApaAppServiceInfo>* serviceArray = iServiceArray;
       
   223 	iServiceArray = NULL;
       
   224 	aIndexOfFirstOpenService = iIndexOfFirstOpenService;
       
   225 	return serviceArray;
       
   226 	}
       
   227 
       
   228 HBufC8* CApaAppInfoReader::OpaqueData()
       
   229 	{
       
   230 	HBufC8* opaqueData = iOpaqueData;
       
   231 	iOpaqueData = NULL;
       
   232 	return opaqueData;
       
   233 	}
       
   234 
       
   235 CApaIconLoader* CApaAppInfoReader::IconLoader()
       
   236 	{
       
   237 	CApaIconLoader* iconLoader = iIconLoader;
       
   238 	iIconLoader = NULL; // ownership transferred to caller
       
   239 	return iconLoader;
       
   240 	}
       
   241 
       
   242 // reads as much info as it can
       
   243 // at least captions and icons must be setup on return from this method (using defaults if necessary)
       
   244 TBool CApaAppInfoReader::ReadL()
       
   245 	{
       
   246 	TEntry entry;
       
   247 	User::LeaveIfError(iFs.Entry(iRegistrationFileName, entry));
       
   248 	iTimeStamp = entry.iModified;
       
   249 	
       
   250 	TUint fileOffset = 0;
       
   251 	TInt fileLength = 0;
       
   252 	TUid firstUid(KExecutableImageUid);
       
   253 	TUid middleUid(KUidApp);
       
   254 
       
   255 	// in the case of a non-native application, the resource file
       
   256 	// has been padded with the application type uid
       
   257 	
       
   258 	if (TParsePtrC(iRegistrationFileName).Path().CompareF(KLitPathForNonNativeResourceAndIconFiles)==0)
       
   259 		{
       
   260 		fileOffset = sizeof(TCheckedUid);
       
   261 		fileLength = entry.iSize-fileOffset;
       
   262 		firstUid = KNullUid;
       
   263 		middleUid = entry[1];
       
   264 		if (middleUid == KNullUid)
       
   265 			User::Leave(KErrCorrupt);
       
   266 		}
       
   267 		
       
   268 	// set the TUidType for the app binary
       
   269 	// cannot read the TEntry info from the app binary because it's in \sys\bin
       
   270 	iAppBinaryUidType = TUidType(firstUid, middleUid, iAppUid);	
       
   271 
       
   272 	CResourceFile* registrationFile = CResourceFile::NewLC(iFs, iRegistrationFileName, fileOffset, fileLength);
       
   273 	RResourceReader	resourceReader;
       
   274 	resourceReader.OpenLC(registrationFile, KAppRegistrationInfoResourceId);	
       
   275 
       
   276 	TRAPD(err, ReadMandatoryInfoL(resourceReader));
       
   277 	if (err)
       
   278 		{
       
   279 		CleanupStack::PopAndDestroy();	// resourceReader
       
   280 		CleanupStack::PopAndDestroy(registrationFile);
       
   281 		return EFalse; // might have read something, but failed to setup enough info to make it worthwhile trying to read any more
       
   282 		}
       
   283 
       
   284 	CResourceFile* localisableFile = NULL;
       
   285 	TUint localisableResourceId = 1; // only initialising this here to keep the compiler happy, as it's concerned that the variable might be used without having been initialised. The variable should be initialised later, before it's used
       
   286 	TRAP(err, ReadNonLocalisableInfoL(resourceReader, localisableFile, localisableResourceId));
       
   287 
       
   288 	if (!err)
       
   289 		TRAP(err, ReadNonLocalisableOptionalInfoL(resourceReader, registrationFile, localisableFile));
       
   290 
       
   291 	TBool useDefaultIcons = ETrue;
       
   292 	if (!err && localisableFile)
       
   293 		TRAP(err, ReadLocalisableInfoL(*localisableFile, localisableResourceId, useDefaultIcons));
       
   294 
       
   295 	delete localisableFile;
       
   296 	localisableFile = NULL;
       
   297 	
       
   298 	// if anything went wrong, we tell the caller that the read was unsuccessful. Some
       
   299 	// of the members of this class may contain data which is not complete, but this doesn't matter
       
   300 	// because the caller shouldn't try to access the data if the read was unsuccessful
       
   301 	const TBool readSuccessful = (err == KErrNone);
       
   302 
       
   303 	if (useDefaultIcons)
       
   304 		{
       
   305 		delete iIcons;
       
   306 		iIcons = NULL;
       
   307 		TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL());
       
   308 		}
       
   309 
       
   310 	CleanupStack::PopAndDestroy();	// resourceReader
       
   311 	CleanupStack::PopAndDestroy(registrationFile);
       
   312 	return readSuccessful;
       
   313 	}
       
   314 
       
   315 
       
   316 // this method reads the minimum information required to register an app
       
   317 // if this fails (Leaves), we say the read has been unsuccessful
       
   318 void CApaAppInfoReader::ReadMandatoryInfoL(RResourceReader& aResourceReader)
       
   319 	{
       
   320 	aResourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   321 	aResourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   322 
       
   323 	// read LTEXT app_file
       
   324 	const TPtrC appFile(aResourceReader.ReadTPtrCL());
       
   325 	TParse parse; // this object gets used for 2 purposes: first to check that a TParsePtrC can be created over "appFile" without it panicking, and second to construct iAppBinaryFullName
       
   326 	User::LeaveIfError(parse.SetNoWild(appFile, NULL, NULL)); // do this before creating a TParsePtrC, since TParsePtrC's constructor panics if it fails (which would provide an easy way for malware to kill the Apparc server)
       
   327 	const TParsePtrC appFileParser(appFile);
       
   328 
       
   329 	// read LONG attributes
       
   330 	iCapability.iAttributes = aResourceReader.ReadUint32L();
       
   331 
       
   332 	if (!appFileParser.NamePresent())
       
   333 		User::Leave(KErrCorrupt);
       
   334 
       
   335 	const TPtrC appNameWithoutExtension(appFileParser.Name());
       
   336 	const TPtrC registrationFileDrive(TParsePtrC(iRegistrationFileName).Drive());
       
   337 	
       
   338 	if (iCapability.iAttributes & TApaAppCapability::ENonNative)
       
   339 		{
       
   340 		if (!appFileParser.PathPresent() || !appFileParser.ExtPresent())
       
   341 			User::Leave(KErrCorrupt);
       
   342 
       
   343 		const TPtrC appFilePath(appFileParser.Path());
       
   344 		const TPtrC appFileNameAndExt(appFileParser.NameAndExt());
       
   345 		TPtrC appFileDrive(registrationFileDrive);
       
   346 		if (appFileParser.DrivePresent())
       
   347 			appFileDrive.Set(appFileParser.Drive());
       
   348 
       
   349 		User::LeaveIfError(parse.SetNoWild(appFileDrive, &appFilePath, &appFileNameAndExt));
       
   350 		}
       
   351 	else if (iCapability.iAttributes & TApaAppCapability::EBuiltAsDll)
       
   352 		{
       
   353 		User::Leave(KErrNotSupported); // legacy dll-style app
       
   354 		}
       
   355 	else
       
   356 		{
       
   357 		// exe-style app
       
   358 		User::LeaveIfError(parse.SetNoWild(registrationFileDrive, &KAppBinaryPathAndExtension, &appNameWithoutExtension));
       
   359 		}
       
   360 
       
   361 	iAppBinaryFullName = parse.FullName().AllocL();
       
   362 	}
       
   363 
       
   364 
       
   365 HBufC* CApaAppInfoReader::CreateFullIconFileNameL(const TDesC& aIconFileName) const
       
   366 	{
       
   367 	HBufC* filename = NULL;
       
   368 	if (aIconFileName.Length() == 0)
       
   369 		return NULL;
       
   370 	/*
       
   371 	 * aIconFileName may contain a valid string in some format (for eg. URI format) other than path to a regular file on disk
       
   372 	 * and that can be a mbm or non-mbm file. Such a filename will be reported as invalid filename by iFs.IsValidName() method. 
       
   373 	 * aIconFileName will be returned since it is a valid string. 
       
   374 	 */	
       
   375 	if(!iFs.IsValidName(aIconFileName))
       
   376 		{
       
   377 		filename = aIconFileName.AllocL();
       
   378 		return filename;
       
   379 		}
       
   380 	
       
   381 	TParsePtrC parsePtr(aIconFileName);
       
   382 	if (parsePtr.IsWild() || !parsePtr.PathPresent() || !parsePtr.NamePresent())
       
   383 		return NULL;
       
   384 
       
   385 	// check for fully qualified icon filename
       
   386 	if (parsePtr.DrivePresent() && BaflUtils::FileExists(iFs, aIconFileName))
       
   387 		filename = aIconFileName.AllocL();
       
   388 	else
       
   389 		{
       
   390 		// check for icon file on same drive as localisable resource file
       
   391 		TParse parse;
       
   392 		TPtrC localisableResourceFileDrive = TParsePtrC(*iLocalisableResourceFileName).Drive();
       
   393 		TInt ret = parse.SetNoWild(localisableResourceFileDrive, &aIconFileName, NULL);
       
   394 		if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName()))
       
   395 			filename = parse.FullName().AllocL();
       
   396 		else
       
   397 			{
       
   398 			TPtrC registrationFileDrive = TParsePtrC(iRegistrationFileName).Drive();
       
   399 			if (TInt(TDriveUnit(registrationFileDrive)) != TInt(TDriveUnit(localisableResourceFileDrive)))
       
   400 				{
       
   401 				// check for icon file on same drive as registration file
       
   402 				ret = parse.SetNoWild(registrationFileDrive, &aIconFileName, NULL);
       
   403 				if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName()))
       
   404 					filename = parse.FullName().AllocL();
       
   405 				}
       
   406 			}
       
   407 		}
       
   408 
       
   409 	return filename;
       
   410 	}
       
   411 
       
   412 void CApaAppInfoReader::ReadLocalisableInfoL(const CResourceFile& aResourceFile, TUint aResourceId, TBool& aUseDefaultIcons)
       
   413 	{
       
   414 	RResourceReader resourceReader;
       
   415 	resourceReader.OpenLC(&aResourceFile, aResourceId);
       
   416 
       
   417 	resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   418 	resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   419 
       
   420 	// read LTEXT short_caption
       
   421 	iShortCaption = resourceReader.ReadHBufCL();
       
   422 
       
   423 	resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   424 	resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   425 
       
   426 	// read LTEXT caption
       
   427 	iCaption = resourceReader.ReadHBufCL();
       
   428 
       
   429 	// read WORD number_of_icons
       
   430 	const TInt numOfIcons = resourceReader.ReadInt16L();
       
   431 	iNumOfAppIcons = numOfIcons;
       
   432 
       
   433 	// read LTEXT icon_file
       
   434 	TPtrC iconFile = resourceReader.ReadTPtrCL();
       
   435 	
       
   436 	ASSERT(!iIconFileName);
       
   437 	iIconFileName = CreateFullIconFileNameL(iconFile);
       
   438 	if (iIconFileName)
       
   439 		{
       
   440 		TEntry entry;
       
   441 		TInt ret = iFs.Entry(*iIconFileName, entry);
       
   442 		if (KErrNone == ret)
       
   443 			iIconFileTimeStamp = entry.iModified;
       
   444 
       
   445 			
       
   446 		aUseDefaultIcons = EFalse;
       
   447 		if (iFs.IsValidName(*iIconFileName))
       
   448 			{
       
   449 			RFile file;
       
   450             TInt fileSize( 0 );
       
   451             User::LeaveIfError( file.Open(iFs, *iIconFileName, EFileShareReadersOnly ));
       
   452             CleanupClosePushL( file );
       
   453             User::LeaveIfError( file.Size( fileSize ) );
       
   454             CleanupStack::PopAndDestroy();//file
       
   455             if ( fileSize > 0  )
       
   456                 {
       
   457 				if(FileIsMbmWithGenericExtensionL(*iIconFileName))
       
   458 					{
       
   459 					if (numOfIcons > 0)
       
   460 						{
       
   461 						CApaAppIconArray* iconArray = CApaAppIconArray::NewAppIconsL(numOfIcons, *iIconFileName, *iIconLoader);
       
   462 						delete iIcons;
       
   463 						iIcons = iconArray;
       
   464 						}
       
   465 					else
       
   466 						{
       
   467 						aUseDefaultIcons = ETrue;		
       
   468 						}
       
   469 					}
       
   470 				else
       
   471 					{
       
   472 					iNonMbmIconFile = ETrue;
       
   473 					}
       
   474 				}
       
   475 				            //File is of size 0 with Valid filename 
       
   476 			else
       
   477                 {
       
   478                 aUseDefaultIcons = ETrue; 
       
   479                 }
       
   480             }
       
   481 			//If the filename is not a valid name then the file is treated as a non-mbm file.
       
   482 		else
       
   483 			{
       
   484 			iNonMbmIconFile = ETrue;
       
   485 			}
       
   486 		}
       
   487 
       
   488 	// read LEN WORD STRUCT view_list[]
       
   489 	const TInt numOfViews = resourceReader.ReadInt16L();
       
   490 	if (numOfViews > 0)
       
   491 		iViewDataArray = new(ELeave) CArrayPtrFlat<CApaAppViewData>(1);
       
   492 
       
   493 	for(TInt view = 0; view < numOfViews; ++view)
       
   494 		{
       
   495 		CApaAppViewData* viewData = CApaAppViewData::NewLC();
       
   496 		resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   497 		resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   498 
       
   499 		// read LONG uid
       
   500 		const TUid viewUid = {resourceReader.ReadInt32L()};
       
   501 		viewData->SetUid(viewUid);
       
   502 		// read LONG screen_mode
       
   503 		const TInt screenMode = {resourceReader.ReadInt32L()};
       
   504 		viewData->SetScreenMode(screenMode);
       
   505 
       
   506 		resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   507 		resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   508 
       
   509 		// read LTEXT caption
       
   510 		TPtrC viewCaption = resourceReader.ReadTPtrCL();
       
   511 		viewData->SetCaptionL(viewCaption);
       
   512 		// read WORD number_of_icons
       
   513 		const TInt numOfViewIcons = resourceReader.ReadInt16L();
       
   514 		viewData->SetNumOfViewIcons(numOfViewIcons);
       
   515 
       
   516 		// read LTEXT icon_file
       
   517 		TPtrC viewIconFile = resourceReader.ReadTPtrCL();
       
   518 		HBufC* const fullViewIconFileName = CreateFullIconFileNameL(viewIconFile);
       
   519 		if (fullViewIconFileName)
       
   520 			{
       
   521 			CleanupStack::PushL(fullViewIconFileName);
       
   522 			viewIconFile.Set(*fullViewIconFileName);
       
   523 			viewData->SetIconFileNameL(viewIconFile);
       
   524 			
       
   525 			if (iFs.IsValidName(viewIconFile))
       
   526 				{
       
   527 				if(!FileIsMbmWithGenericExtensionL(viewIconFile))
       
   528 					viewData->SetNonMbmIconFile(ETrue);
       
   529 				}
       
   530 			else	//If the filename is not a valid name then the file is treated as a non-mbm file.
       
   531 				viewData->SetNonMbmIconFile(ETrue);
       
   532 			}
       
   533 		else
       
   534 			{
       
   535 			viewIconFile.Set(KNullDesC);
       
   536 			if (numOfViewIcons > 0 && iIconFileName)
       
   537 				viewIconFile.Set(*iIconFileName); // default to app icon filename
       
   538 			}
       
   539 		if (numOfViewIcons > 0 && iFs.IsValidName(viewIconFile) && FileIsMbmWithGenericExtensionL(viewIconFile))
       
   540 			{
       
   541 			CApaAppIconArray* iconArray = CApaAppIconArray::NewViewIconsL(numOfViewIcons, viewIconFile, *iIconLoader);
       
   542 			viewData->SetIconArray(iconArray);
       
   543 			iconArray = NULL;
       
   544 			}
       
   545 
       
   546 		if (fullViewIconFileName)
       
   547 			CleanupStack::PopAndDestroy(fullViewIconFileName);
       
   548 
       
   549 		iViewDataArray->AppendL(viewData);
       
   550 		CleanupStack::Pop(viewData);
       
   551 		}
       
   552 
       
   553 	// Read LTEXT group_name
       
   554 	// If a localised group name has been specified, it overrides
       
   555 	// The group name (if any), specified by APP_REGISTRATION_INFO
       
   556 
       
   557 	TApaAppGroupName groupName;
       
   558 	TRAPD(ret, (groupName = resourceReader.ReadTPtrCL()));
       
   559 	if (ret != KErrNone)
       
   560 		{
       
   561 		 if (ret != KErrEof)
       
   562 	         User::Leave(ret);
       
   563 		}
       
   564 	else
       
   565 		{
       
   566 	     if (groupName.Length() > 0)
       
   567 			 iCapability.iGroupName = groupName;
       
   568 		}
       
   569 
       
   570 	CleanupStack::PopAndDestroy(&resourceReader);
       
   571 	}
       
   572 
       
   573 /*An MBM file may have a generic icon extension. In this case, as a way to check whether the file is an MBM one, 
       
   574 it is necessary to read the content of the fist four 32bit words of it and find out whether these words correspond to 
       
   575 KWriteonceFileStoreUid, KMultiBitmapFileImageUid, zero and KMultiBitmapFileImageChecksum respectively (defined in graphics/gditools/bmconv/bmconv.h).
       
   576 So the file is opened and the first 4 32 bit words are extracted and compared with the header information of standard MBM file.
       
   577 If they match, the function returns ETrue, else it returns EFalse */
       
   578 TBool CApaAppInfoReader::FileIsMbmWithGenericExtensionL(const TDesC& aFileName)
       
   579       { 
       
   580       if (aFileName.Length() > 0) 
       
   581             { 
       
   582             //open a file in Share mode - this will allow other methods to access it too
       
   583             RFile file;
       
   584             RFs fs;
       
   585             User::LeaveIfError(fs.Connect());
       
   586             CleanupClosePushL(fs);
       
   587             User::LeaveIfError(file.Open(fs,aFileName,EFileShareReadersOnly));
       
   588             //this is done beacuse the file can also be accessed by applist at the same time
       
   589             //buffer stores the 16 bytes of the file
       
   590             CleanupClosePushL(file);
       
   591             TBuf8<16> buffer;
       
   592             User::LeaveIfError(file.Read(buffer,16));
       
   593             CleanupStack::PopAndDestroy();//file
       
   594             CleanupStack::PopAndDestroy(&fs);//fs
       
   595             //we use a constant pointer to the buffer to read header info
       
   596         	TPtrC8 filePointer(buffer);
       
   597         	
       
   598             /*The first 16 bytes of an MBM file are the same for any generic MBM file.
       
   599             These are :
       
   600             KWriteOnceFileStoreUid = 0x10000037(Emulator MBM file) 0x10000041(ROM image)	
       
   601             KMultiBitMapFileImageUid = 0x10000042(Emulator MBM file) 	0x00000001(ROM image)
       
   602             Zero = 0x00000000(Emulator MBM file) 0x0000000C(ROM image)
       
   603             checksum = 0x47396439(Emulator MBM file) 0x10000040(ROM image)
       
   604             The first 16 bytes of the given file is compared with these standard values to ascertain it is MBM file*/
       
   605         	if((filePointer[3]==0x10)&&(filePointer[2]==0x00)&&(filePointer[1]==0x00)&&(filePointer[0]==0x37))
       
   606         		{//KWriteOnceFileStoreUid = 0x10000037
       
   607         		if((filePointer[7]==0x10)&&(filePointer[6]==0x00)&&(filePointer[5]==0x00)&&(filePointer[4]==0x42))
       
   608         			{//KMultiBitMapFileImageUid = 0x10000042
       
   609         			if((filePointer[11]==0x00)&&(filePointer[10]==0x00)&&(filePointer[9]==0x00)&&(filePointer[8]==0x00))
       
   610         				{//Zero = 0x00000000)
       
   611         				if((filePointer[15]==0x47)&&(filePointer[14]==0x39)&&(filePointer[13]==0x64)&&(filePointer[12]==0x39))
       
   612         					{//checksum = 0x47396439
       
   613         					return ETrue;
       
   614         					}
       
   615         				}
       
   616         			}
       
   617         		}
       
   618         	//Else Check for ROM Image MBM file's header
       
   619         	else if((filePointer[3]==0x10)&&(filePointer[2]==0x00)&&(filePointer[1]==0x00)&&(filePointer[0]==0x41))
       
   620         		{//KWriteOnceFileStoreUid = 0x10000041
       
   621         		if((filePointer[7]==0x00)&&(filePointer[6]==0x00)&&(filePointer[5]==0x00)&&(filePointer[4]==0x01))
       
   622         			{//KMultiBitMapFileImageUid = 0x00000001
       
   623         			if((filePointer[11]==0x00)&&(filePointer[10]==0x00)&&(filePointer[9]==0x00)&&(filePointer[8]==0x0C))
       
   624         				{//Zero = 0x0000000C)
       
   625         				if((filePointer[15]==0x10)&&(filePointer[14]==0x00)&&(filePointer[13]==0x00)&&(filePointer[12]==0x40))
       
   626         					{//checksum = 0x10000040
       
   627         					return ETrue;
       
   628         					}
       
   629         				}
       
   630         			}
       
   631         		}
       
   632         	}
       
   633       return EFalse;
       
   634       }
       
   635 
       
   636 HBufC8* CApaAppInfoReader::ReadOpaqueDataL(TUint aResourceId, const CResourceFile* aRegistrationFile, CResourceFile* aLocalisableResourceFile)
       
   637 	{ // static
       
   638 	HBufC8* opaqueData = NULL;
       
   639 	if (aResourceId == 0)
       
   640 		opaqueData = HBufC8::NewL(0);
       
   641 	else
       
   642 		{
       
   643 		if (aResourceId & KResourceOffsetMask)
       
   644 			{
       
   645 			// expecting opaque data to be in the localisable resource file
       
   646 			if (aLocalisableResourceFile)
       
   647 				{
       
   648 				aLocalisableResourceFile->ConfirmSignatureL();
       
   649 				opaqueData = aLocalisableResourceFile->AllocReadLC(aResourceId);
       
   650 				CleanupStack::Pop(opaqueData);
       
   651 				}
       
   652 			else
       
   653 				opaqueData = HBufC8::NewL(0);
       
   654 			}
       
   655 		else
       
   656 			{
       
   657 			// expecting opaque data to be in the registration file
       
   658 			__ASSERT_ALWAYS(aRegistrationFile, Panic(EPanicNullPointer));
       
   659 			opaqueData = aRegistrationFile->AllocReadLC(aResourceId); //lint !e613 Suppress ossible use of null pointer
       
   660 			CleanupStack::Pop(opaqueData);
       
   661 			}
       
   662 		}
       
   663 
       
   664 	return opaqueData;
       
   665 	}
       
   666 
       
   667 void CApaAppInfoReader::ReadNonLocalisableOptionalInfoL(RResourceReader& aResourceReader, const CResourceFile* aRegistrationFile, CResourceFile* aLocalisableResourceFile)
       
   668 	{
       
   669 	// read LEN WORD STRUCT service_list[]
       
   670 	TInt serviceCount = 0;
       
   671 	// service information was not present in the first release of the registration file
       
   672 	// APP_REGISTRATION_INFO resource struct
       
   673 	// this method must not leave if the registration file doesn't contain service information, so the
       
   674 	// following call to ReadInt16L is trapped to ensure this method doesn't leave just because
       
   675 	// there is no more information in the resource to read (KErrEof)
       
   676 	TRAPD(err, serviceCount = aResourceReader.ReadInt16L());
       
   677 	if (err)
       
   678 		{
       
   679 		if (err == KErrEof)
       
   680 			return; // end of resource reached
       
   681 		
       
   682 		User::Leave(err);
       
   683 		}
       
   684 	
       
   685 	if (!iServiceArray && serviceCount > 0)
       
   686 		iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
       
   687 
       
   688 	while (serviceCount--)
       
   689 		{
       
   690 		const TUid serviceUid = {aResourceReader.ReadUint32L()};
       
   691 		
       
   692 		if ((serviceUid == KOpenServiceUid) && (iOpenServiceIsLegacy))
       
   693 			{
       
   694 			ASSERT(iIndexOfFirstOpenService == 0);
       
   695 			// If we found an Open service in the SERVICE_INFO declaration
       
   696 			// then we must ignore the legacy one
       
   697 			(*iServiceArray)[0].Release();
       
   698 			iServiceArray->Delete(0);
       
   699 			iOpenServiceIsLegacy = EFalse;
       
   700 			iIndexOfFirstOpenService = KErrNotFound;
       
   701 			}
       
   702 		
       
   703 		CArrayFixFlat<TDataTypeWithPriority>* mimeTypesSupported = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(5);
       
   704 		CleanupStack::PushL(mimeTypesSupported);
       
   705 		ReadMimeTypesSupportedL(aResourceReader, *mimeTypesSupported);
       
   706 		
       
   707 		const TUint resourceId = aResourceReader.ReadUint32L();
       
   708 		HBufC8* opaqueData = NULL;
       
   709 		opaqueData = ReadOpaqueDataL(resourceId, aRegistrationFile, aLocalisableResourceFile);
       
   710 		CleanupStack::PushL(opaqueData);
       
   711 		
       
   712 		TApaAppServiceInfo serviceInfo(serviceUid, mimeTypesSupported, opaqueData); // takes ownership of opaqueData
       
   713 		iServiceArray->AppendL(serviceInfo);
       
   714 		CleanupStack::Pop(opaqueData);
       
   715 		CleanupStack::Pop(mimeTypesSupported);
       
   716 		if ((serviceUid == KOpenServiceUid) && (iIndexOfFirstOpenService < 0))
       
   717 			iIndexOfFirstOpenService = iServiceArray->Count() - 1;
       
   718 		}
       
   719 
       
   720 	// read LLINK opaque_data
       
   721 	const TUint resourceId = aResourceReader.ReadUint32L();
       
   722 	delete iOpaqueData;
       
   723 	iOpaqueData = NULL;
       
   724 	iOpaqueData = ReadOpaqueDataL(resourceId, aRegistrationFile, aLocalisableResourceFile);
       
   725 	}
       
   726 
       
   727 void CApaAppInfoReader::ReadNonLocalisableInfoL(RResourceReader& aResourceReader, CResourceFile*& aLocalisableResourceFile, TUint& aLocalisableResourceId)
       
   728 	{
       
   729 	ASSERT(aLocalisableResourceFile == NULL);
       
   730 
       
   731 	// read LTEXT localisable_resource_file
       
   732 	TPtrC localisableResourceFileName(aResourceReader.ReadTPtrCL());
       
   733 	if (localisableResourceFileName.Length() > 0 && iFs.IsValidName(localisableResourceFileName))
       
   734 		{
       
   735 		// determine the language specific name of the localisable resource file
       
   736 		TParse parse;
       
   737 		TParsePtrC parsePtr(iRegistrationFileName);
       
   738 		User::LeaveIfError(parse.SetNoWild(parsePtr.Drive(), &KAppResourceFileExtension, &localisableResourceFileName));
       
   739 		TFileName resourceFileName(parse.FullName());
       
   740 		BaflUtils::NearestLanguageFileV2(iFs, resourceFileName, iApplicationLanguage);
       
   741 		iLocalisableResourceFileName = resourceFileName.AllocL();
       
   742 
       
   743 		TEntry entry;
       
   744 		User::LeaveIfError(iFs.Entry(*iLocalisableResourceFileName, entry));
       
   745 		iLocalisableResourceFileTimeStamp = entry.iModified;
       
   746 	
       
   747 
       
   748 		// open the localisable resource file	
       
   749 		aLocalisableResourceFile = CResourceFile::NewL(iFs, resourceFileName, 0, 0);
       
   750 		}
       
   751 
       
   752 	// read LONG localisable_resource_id
       
   753 	aLocalisableResourceId = aResourceReader.ReadUint32L();
       
   754 	if (aLocalisableResourceFile && (aLocalisableResourceId & KResourceOffsetMask))
       
   755 		aLocalisableResourceFile->ConfirmSignatureL();
       
   756 
       
   757 	iCapability.iAppIsHidden = aResourceReader.ReadInt8L();
       
   758 	iCapability.iEmbeddability = static_cast<TApaAppCapability::TEmbeddability>(aResourceReader.ReadInt8L());
       
   759 	iCapability.iSupportsNewFile = aResourceReader.ReadInt8L();
       
   760 	iCapability.iLaunchInBackground = aResourceReader.ReadInt8L();
       
   761 	iCapability.iGroupName = aResourceReader.ReadTPtrCL();
       
   762 
       
   763 	// read BYTE default_screen_number
       
   764 	iDefaultScreenNumber = aResourceReader.ReadUint8L();
       
   765  	
       
   766 	//read the datatypes
       
   767 	CArrayFixFlat<TDataTypeWithPriority>* datatypes = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(5);
       
   768 	CleanupStack::PushL(datatypes);
       
   769 	ReadMimeTypesSupportedL(aResourceReader, *datatypes);
       
   770 	//dataTypes is deleted if 
       
   771 	// A. There are no legacy datatypes
       
   772 	// B. Control panel plugin apps are not allowed to register MIME types.If they happen to have any, these datatypes should be ignored.
       
   773 	if ((iCapability.iAttributes & TApaAppCapability::EControlPanelItem) || (datatypes->Count() == 0))
       
   774 		CleanupStack::PopAndDestroy(datatypes);
       
   775 	else
       
   776 		{
       
   777 		ASSERT(!iServiceArray);
       
   778 		iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
       
   779 		HBufC8* opaqueData = HBufC8::NewL(0);
       
   780 		CleanupStack::PushL(opaqueData);
       
   781 		TApaAppServiceInfo serviceInfo(KOpenServiceUid, datatypes, opaqueData);
       
   782 		iServiceArray->AppendL(serviceInfo);
       
   783 		CleanupStack::Pop(opaqueData);
       
   784 		CleanupStack::Pop(datatypes);
       
   785 		iIndexOfFirstOpenService = 0;
       
   786 		iOpenServiceIsLegacy = ETrue;
       
   787 		}
       
   788 
       
   789 	// read LEN WORD STRUCT file_ownership_list[]
       
   790 	const TInt fileOwnershipArraySize = aResourceReader.ReadInt16L();
       
   791 	if (fileOwnershipArraySize > 0)
       
   792 		iOwnedFileArray = new(ELeave) CDesCArraySeg(1);
       
   793 
       
   794 	for (TInt i=0; i < fileOwnershipArraySize; i++)
       
   795 		{
       
   796 		TPtrC fileNamePtr = aResourceReader.ReadTPtrCL();
       
   797 		iOwnedFileArray->AppendL(fileNamePtr);
       
   798 		}
       
   799 	}
       
   800 	
       
   801 void CApaAppInfoReader::ReadMimeTypesSupportedL(RResourceReader& aResourceReader,
       
   802 	CArrayFixFlat<TDataTypeWithPriority>& aMimeTypesSupported)
       
   803 	{
       
   804 	// read LEN WORD STRUCT datatype_list[]
       
   805 	const TInt dataTypeArraySize = aResourceReader.ReadInt16L();
       
   806 	if (dataTypeArraySize <= 0)
       
   807 		return;
       
   808 	
       
   809 	for (TInt i=0; i < dataTypeArraySize; i++)
       
   810 		{
       
   811 		TDataTypePriority priority = static_cast<TDataTypePriority>(aResourceReader.ReadInt32L());
       
   812         
       
   813 		//Check for data priority of UnTrusted apps however the trusted apps will not have any restrictions 
       
   814 		//over the data priority.	
       
   815 		//If an untrusted app has write device data capability (i.e. still has priority = KDataTypePrioritySystem),
       
   816 		//do not restrict to KDataTypeUnTrustedPriorityThreshold
       
   817 		if (priority > KDataTypeUnTrustedPriorityThreshold || priority == KDataTypePrioritySystem )
       
   818 		    {
       
   819 		    ReadAppSecurityInfo();
       
   820 
       
   821             if (priority == KDataTypePrioritySystem)
       
   822                 {
       
   823                 // Check that the app has capability WriteDeviceData
       
   824                 if (!iHasWriteDeviceDataCap)
       
   825                     priority = KDataTypePriorityNormal;
       
   826                 }
       
   827             else
       
   828                 {
       
   829                 //data priority for UnTrusted apps would be capped if it is greater than the threshold priority i.e, KMaxTInt16.
       
   830                 TInt match=iRegistrationFileName.MatchF(KLitPathForUntrustedRegistrationResourceFiles);
       
   831                 if (match != KErrNotFound && !iIsSidTrusted) 
       
   832                     {
       
   833                     //if registration file is in import directory and 
       
   834                     //its sid is in unprotected range - downgrade the priority
       
   835                     priority = KDataTypeUnTrustedPriorityThreshold;	
       
   836                     }
       
   837                 }
       
   838 		    }
       
   839 
       
   840 		TPtrC8 dataTypePtr = aResourceReader.ReadTPtrC8L();
       
   841 		TDataType dataType(dataTypePtr);
       
   842 		TDataTypeWithPriority dataTypeWithPriority(dataType, priority);
       
   843 		aMimeTypesSupported.AppendL(dataTypeWithPriority);
       
   844 		}
       
   845 	}
       
   846 
       
   847 // This method can be used to check whether app has a WriteDeviceCap 
       
   848 // and its sid is trusted
       
   849 void CApaAppInfoReader::ReadAppSecurityInfo()
       
   850     {
       
   851     if (!iSecurityInfoHasBeenRead)
       
   852         {
       
   853         __ASSERT_DEBUG( iAppBinaryFullName, Panic(EPanicNullPointer) );
       
   854         const TInt err = CApaSecurityUtils::CheckAppSecurity( *iAppBinaryFullName, 
       
   855                                         iHasWriteDeviceDataCap, iIsSidTrusted);
       
   856         if ( KErrNone != err )
       
   857             {
       
   858             iHasWriteDeviceDataCap = EFalse;
       
   859             iIsSidTrusted = EFalse;
       
   860             }
       
   861 
       
   862         iSecurityInfoHasBeenRead = ETrue;   
       
   863         }
       
   864     }
       
   865 
       
   866 //
       
   867 // Class CApaIconLoader
       
   868 //
       
   869 
       
   870 CApaIconLoader* CApaIconLoader::NewL(RFs& aFs)
       
   871 	{
       
   872 	CApaIconLoader* self = NewLC(aFs);
       
   873 	CleanupStack::Pop(self);
       
   874 	return self;
       
   875 	}
       
   876 
       
   877 CApaIconLoader* CApaIconLoader::NewLC(RFs& aFs)
       
   878 	{
       
   879 	CApaIconLoader* self = new(ELeave) CApaIconLoader(aFs);
       
   880 	CleanupStack::PushL(self);
       
   881 	self->ConstructL();
       
   882 	return self;
       
   883 	}
       
   884 
       
   885 CApaIconLoader::CApaIconLoader(RFs& aFs) : iFs(aFs)
       
   886 	{
       
   887 	}
       
   888 
       
   889 void CApaIconLoader::ConstructL()
       
   890 	{
       
   891 	} //lint !e1762 Suppress member function could be made const
       
   892 
       
   893 
       
   894 CApaIconLoader::~CApaIconLoader()
       
   895 	{
       
   896 	TInt arrayCount = iIconIndexArray.Count();
       
   897 	while (--arrayCount >= 0)
       
   898 		delete (iIconIndexArray[arrayCount].iFileName);
       
   899 
       
   900 	iIconIndexArray.Close();
       
   901 	iIconArrays.Close();
       
   902 	}
       
   903 
       
   904 void CApaIconLoader::AddIconArrayL(const CApaAppIconArray& aIcons)
       
   905 	{
       
   906 	iIconArrays.AppendL(&aIcons);
       
   907 	}
       
   908 
       
   909 void CApaIconLoader::LoadAllIconsL()
       
   910 	{
       
   911 	const TInt iconArraysCount = iIconArrays.Count();
       
   912 	CleanupClosePushL(iIconArrays);
       
   913 	for (TInt ii = 0; ii <iconArraysCount; ++ii)
       
   914 		iIconArrays[ii]->LoadIconsL();
       
   915 	CleanupStack::PopAndDestroy(&iIconArrays);
       
   916 	}
       
   917 
       
   918 // given an mbm filename, returns the next index to read from the file
       
   919 // always set aUseCache to EFalse on first call in a sequence of calls
       
   920 TInt CApaIconLoader::IconIndexL(const TDesC& aFileName, TBool& aUseCache)
       
   921 	{
       
   922 	if (aUseCache)
       
   923 		{
       
   924 		TInt ret = iIconIndexArray[iCachedArrayIndex].iIndex++;
       
   925 		return ret;
       
   926 		}
       
   927 	else
       
   928 		aUseCache = ETrue;
       
   929 
       
   930 	// if filename in array, get the next index
       
   931 	TInt ret = 0;
       
   932 	const TInt arrayCount = iIconIndexArray.Count();
       
   933 	TInt arrayIndex;
       
   934 	for (arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++)
       
   935 		{
       
   936 		__ASSERT_DEBUG(iIconIndexArray[arrayIndex].iFileName, Panic(EDPanicInvalidIconIndexArray));
       
   937 		if (iIconIndexArray[arrayIndex].iFileName->CompareF(aFileName) == 0)
       
   938 			{
       
   939 			ret = iIconIndexArray[arrayIndex].iIndex++;
       
   940 			iCachedArrayIndex = arrayIndex;
       
   941 			break;
       
   942 			}
       
   943 		}
       
   944 
       
   945 	if (arrayIndex >= arrayCount)
       
   946 		{
       
   947 		// filename not found, add it to array
       
   948 		TKeyValuePair keyValuePair;
       
   949 		keyValuePair.iFileName = aFileName.AllocL();
       
   950 		keyValuePair.iIndex = 0;
       
   951 		ret = keyValuePair.iIndex++;
       
   952 		User::LeaveIfError(iIconIndexArray.Append(keyValuePair));
       
   953 		iCachedArrayIndex = arrayCount;
       
   954 		}
       
   955 
       
   956 	return ret;
       
   957 	}
       
   958 	
       
   959 
       
   960 
       
   961 // returns EFalse if there was an error obtaining aMbmFileName's entry information,
       
   962 // otherwise returns ETrue.
       
   963 // Leaves if an error occurs while trying to populate aIcons or sort icons
       
   964 TBool CApaIconLoader::LoadIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CArrayPtr<CApaMaskedBitmap>& aIcons)
       
   965 	{
       
   966 	TEntry entry;
       
   967 	TInt error=iFs.Entry(aMbmFileName,entry);
       
   968 	if (error!=KErrNone)
       
   969 		return EFalse;
       
   970 
       
   971 	TInt iconIndex;
       
   972 	TInt fileIndex;
       
   973 	TBool useCache = EFalse;
       
   974 	
       
   975 	// create link to CApaAppList which owns this object as it has a separate share protected RFs
       
   976 	// which can be used to load bitmap icons 
       
   977 	CApaAppList* const appList = CApaAppList::Self();
       
   978 	
       
   979 	RFile mbmFile;
       
   980 	CleanupClosePushL(mbmFile);
       
   981 	User::LeaveIfError(mbmFile.Open(appList->ShareProtectedFileServer(), aMbmFileName, EFileShareReadersOnly));
       
   982 
       
   983 	for(iconIndex=0; iconIndex<aNumOfIcons; ++iconIndex)	
       
   984 		{		
       
   985 		CApaMaskedBitmap* bitmap = CApaMaskedBitmap::NewLC();
       
   986 		fileIndex = IconIndexL(aMbmFileName, useCache);
       
   987 		User::LeaveIfError(bitmap->Load(mbmFile, 2*fileIndex));
       
   988 		User::LeaveIfError((bitmap->Mask())->Load(mbmFile,2*fileIndex+1));		
       
   989 		aIcons.AppendL(bitmap);
       
   990 		CleanupStack::Pop(bitmap);		
       
   991 		}
       
   992 	
       
   993 	CleanupStack::PopAndDestroy(&mbmFile); // close mbmFile	
       
   994 
       
   995 	// now sort them in ascending order of size
       
   996 	TInt numberOfIcons = aIcons.Count();
       
   997 	// create a new array that we can sort by area, populated from aIcons
       
   998 	RPointerArray<CApaMaskedBitmap> ptrArray(numberOfIcons);
       
   999 	CleanupClosePushL(ptrArray);
       
  1000 	TLinearOrder<CApaMaskedBitmap> order(CApaIconLoader::CompareIcons);
       
  1001 	for (iconIndex=0; iconIndex<numberOfIcons; iconIndex++)
       
  1002 		User::LeaveIfError(ptrArray.InsertInOrderAllowRepeats(aIcons[iconIndex], order));
       
  1003 
       
  1004 	// copy the sorted icon pointers back into aIcons - must not Leave inside the loop below
       
  1005 	for (iconIndex=0; iconIndex<numberOfIcons; iconIndex++)
       
  1006 		aIcons[iconIndex]=ptrArray[iconIndex];
       
  1007 
       
  1008 	CleanupStack::PopAndDestroy(&ptrArray);
       
  1009 
       
  1010 	return ETrue;
       
  1011 	}
       
  1012 
       
  1013 TInt CApaIconLoader::CompareIcons(const CApaMaskedBitmap& aFirst, const CApaMaskedBitmap& aSecond)
       
  1014 	{ // static
       
  1015 	TSize sizeFirst = aFirst.SizeInPixels();
       
  1016 	TInt areaFirst = sizeFirst.iWidth*sizeFirst.iHeight;
       
  1017 	TSize sizeSecond = aSecond.SizeInPixels();
       
  1018 	TInt areaSecond = sizeSecond.iWidth*sizeSecond.iHeight;
       
  1019 	return areaFirst - areaSecond;
       
  1020 	}
       
  1021 
       
  1022 //
       
  1023 // Class CApaAppIconArray
       
  1024 //
       
  1025 
       
  1026 CApaAppIconArray* CApaAppIconArray::NewL()
       
  1027 	{
       
  1028 	return new(ELeave) CApaAppIconArray();
       
  1029 	}
       
  1030 
       
  1031 /* public factory functions */
       
  1032 CApaAppIconArray* CApaAppIconArray::NewAppIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader)
       
  1033 	{
       
  1034 	return NewL(aNumOfIcons,aMbmFileName,aIconLoader,ETrue);
       
  1035 	}
       
  1036 
       
  1037 CApaAppIconArray* CApaAppIconArray::NewViewIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader)
       
  1038 	{
       
  1039 	return NewL(aNumOfIcons,aMbmFileName,aIconLoader,EFalse);
       
  1040 	}
       
  1041 
       
  1042 CApaAppIconArray* CApaAppIconArray::NewDefaultIconsL()
       
  1043 	{
       
  1044 	CApaAppIconArray* self = NewL();
       
  1045 	CleanupStack::PushL(self);
       
  1046 	self->GetDefaultIconsL();
       
  1047 	CleanupStack::Pop(self);
       
  1048 	return self;
       
  1049 	}
       
  1050 
       
  1051 CApaAppIconArray* CApaAppIconArray::NewRealDefaultIconsLC(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader)
       
  1052 	{
       
  1053 	return NewLC(aNumOfIcons,aMbmFileName,aIconLoader,EFalse);
       
  1054 	}
       
  1055 
       
  1056 /* real NewL and NewLC, private */
       
  1057 CApaAppIconArray* CApaAppIconArray::NewL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons)
       
  1058 	{
       
  1059 	CApaAppIconArray* self = NewLC(aNumOfIcons,aMbmFileName,aIconLoader,aFallbackToDefaultIcons);
       
  1060 	CleanupStack::Pop(self);
       
  1061 	return self;
       
  1062 	}
       
  1063 
       
  1064 CApaAppIconArray* CApaAppIconArray::NewLC(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons)
       
  1065 	{
       
  1066 	CApaAppIconArray* self = new(ELeave) CApaAppIconArray(aNumOfIcons,aIconLoader,aFallbackToDefaultIcons);
       
  1067 	CleanupStack::PushL(self);
       
  1068 	self->ConstructL(aMbmFileName);
       
  1069 	return self;
       
  1070 	}
       
  1071 
       
  1072 CApaAppIconArray::CApaAppIconArray()
       
  1073 	{
       
  1074 	}
       
  1075 
       
  1076 CApaAppIconArray::CApaAppIconArray(TInt aNumOfIcons, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons) :
       
  1077 		iNumOfIcons(aNumOfIcons),
       
  1078 		iIconLoader(&aIconLoader),
       
  1079 		iFallbackToDefaultIcons(aFallbackToDefaultIcons)
       
  1080 	{
       
  1081 	}
       
  1082 
       
  1083 void CApaAppIconArray::ConstructL(const TDesC& aMbmFileName)
       
  1084 	{
       
  1085 	iMbmFileName = aMbmFileName.AllocL();
       
  1086 	ASSERT(iIconLoader);
       
  1087 	iIconLoader->AddIconArrayL(*this);
       
  1088 	}
       
  1089 
       
  1090 CApaAppIconArray::~CApaAppIconArray()
       
  1091 	{
       
  1092 	if(iDefaultIconsUsed)
       
  1093 		{
       
  1094 		ASSERT(iDefaultIconsProvider);
       
  1095 		if(iDefaultIconsProvider)
       
  1096 			iDefaultIconsProvider->ReleaseDefaultIconArray();
       
  1097 		}
       
  1098 
       
  1099 	delete iMbmFileName;
       
  1100 	if (iIcons)
       
  1101 		{
       
  1102 		iIcons->ResetAndDestroy();
       
  1103 		delete iIcons;
       
  1104 		}
       
  1105 
       
  1106 	iDefaultIconsProvider = NULL;
       
  1107 	iIconLoader = NULL;
       
  1108 	}
       
  1109 
       
  1110 // returns EFalse if there was an error obtaining iMbmFileName's entry information,
       
  1111 // otherwise returns ETrue or leaves with a system-wide error code
       
  1112 TBool CApaAppIconArray::LoadIconsL()
       
  1113 	{
       
  1114 	ASSERT(iIconLoader);
       
  1115 	ASSERT(!iDefaultIconsUsed);
       
  1116 	ASSERT(!iIcons);
       
  1117 	iIcons = new(ELeave) CArrayPtrFlat<CApaMaskedBitmap>(5);
       
  1118 	TBool badMbmEntryInfo = EFalse;
       
  1119 	TRAPD(err,badMbmEntryInfo = !iIconLoader->LoadIconsL(iNumOfIcons,*iMbmFileName,*iIcons));
       
  1120 
       
  1121 	// We'll be called by the iconLoader at most once, and after we've been called,
       
  1122 	// it might be destroyed. So we shouldn't keep a pointer to it anymore.
       
  1123 	iIconLoader = NULL;
       
  1124 
       
  1125 	if ((badMbmEntryInfo || err != KErrNone) && iFallbackToDefaultIcons)
       
  1126 		GetDefaultIconsL();
       
  1127 	else if (badMbmEntryInfo)
       
  1128 		return EFalse;
       
  1129 	else if (err != KErrNone)
       
  1130 		User::Leave(err);
       
  1131 
       
  1132 	return ETrue;
       
  1133 	}
       
  1134 
       
  1135 CApaMaskedBitmap* CApaAppIconArray::IconBySize(const TSize& aSize) const
       
  1136 	{
       
  1137 	if(iDefaultIconsUsed)
       
  1138 		return DefaultIcons().IconBySize(aSize);
       
  1139 	else if(iIcons == NULL && iIconLoader == NULL)
       
  1140 		{
       
  1141 		// Then we've been created with the default constructor, just pretend
       
  1142 		// there's no icon of the right size
       
  1143 		return NULL;
       
  1144 		}
       
  1145 	else if(iIcons == NULL)
       
  1146 		{
       
  1147 		// Arriving here means the the icons need loading but havn't been loaded yet.
       
  1148 		TRAPD(err, iIconLoader->LoadAllIconsL());
       
  1149 		if (err != KErrNone)
       
  1150 			return NULL;
       
  1151 		}
       
  1152 
       
  1153 	const TInt count = iIcons->Count();
       
  1154 	CApaMaskedBitmap* bmp=NULL;
       
  1155 	for (TInt ii=0;ii<count;ii++)
       
  1156 		{
       
  1157 		if ((*iIcons)[ii]->SizeInPixels()==aSize)
       
  1158 			bmp=(*iIcons)[ii];
       
  1159 		}
       
  1160 
       
  1161 	if (!bmp)
       
  1162 		{// if the exact size has not been found get one with nearest but smaller area
       
  1163 		TInt differenceOfClosest=KMaxTInt;
       
  1164 		TInt indexOfClosest=KMaxTInt;
       
  1165 		TInt reqArea=aSize.iHeight*aSize.iWidth;
       
  1166 		TSize bmpSize;
       
  1167 		TInt difference;
       
  1168 		for (TInt jj=0;jj<count;jj++)
       
  1169 			{
       
  1170 			bmpSize=(*iIcons)[jj]->SizeInPixels();
       
  1171 			difference=reqArea-bmpSize.iHeight*bmpSize.iWidth;
       
  1172 			if (difference<differenceOfClosest && difference>=0)
       
  1173 				{
       
  1174 				differenceOfClosest=difference;
       
  1175 				indexOfClosest=jj;
       
  1176 				}
       
  1177 			}
       
  1178 
       
  1179 		if (indexOfClosest<KMaxTInt)
       
  1180 			bmp=(*iIcons)[indexOfClosest];
       
  1181 		}
       
  1182 
       
  1183 	return bmp;
       
  1184 	}
       
  1185 
       
  1186 CArrayFixFlat<TSize>* CApaAppIconArray::IconSizesL() const
       
  1187 	{
       
  1188 	if(iDefaultIconsUsed)
       
  1189 		return DefaultIcons().IconSizesL();
       
  1190 	else if(iIcons == NULL && iIconLoader == NULL)
       
  1191 		return new(ELeave)CArrayFixFlat<TSize>(1);
       
  1192 	else if(iIcons == NULL)
       
  1193 		{
       
  1194 		// Arriving here means the the icons need loading but havn't been loaded yet.
       
  1195 		TRAPD(err, iIconLoader->LoadAllIconsL());
       
  1196 		if (err != KErrNone)
       
  1197 			return new(ELeave)CArrayFixFlat<TSize>(1);
       
  1198 		}
       
  1199 
       
  1200 	const TInt count=iIcons->Count();
       
  1201 	CArrayFixFlat<TSize>* arrayOfSizes=new(ELeave)CArrayFixFlat<TSize>(1);
       
  1202 	CleanupStack::PushL(arrayOfSizes);
       
  1203 	for(TInt ii=0;ii<count;ii++)
       
  1204 		arrayOfSizes->AppendL((*iIcons)[ii]->SizeInPixels());
       
  1205 
       
  1206 	CleanupStack::Pop(arrayOfSizes);
       
  1207 	return arrayOfSizes;
       
  1208 	}
       
  1209 
       
  1210 TInt CApaAppIconArray::Count() const
       
  1211 	{
       
  1212 	if(iDefaultIconsUsed)
       
  1213 		return DefaultIcons().Count();
       
  1214 	else if(iIcons == NULL && iIconLoader == NULL)
       
  1215 		return 0;
       
  1216 	else if(iIcons == NULL)
       
  1217 		{
       
  1218 		// Arriving here means the the icons need loading but havn't been loaded yet.
       
  1219 		TRAPD(err, iIconLoader->LoadAllIconsL());
       
  1220 		if (err != KErrNone)
       
  1221 			return 0;
       
  1222 		}
       
  1223 
       
  1224 	return iIcons->Count();
       
  1225 	}
       
  1226 
       
  1227 TBool CApaAppIconArray::DefaultIconsUsed() const
       
  1228 	{
       
  1229 	return iDefaultIconsUsed;
       
  1230 	}
       
  1231 
       
  1232 CApaMaskedBitmap* CApaAppIconArray::operator[](TInt aIndex) const
       
  1233 	{
       
  1234 	if(iDefaultIconsUsed)
       
  1235 		return DefaultIcons()[aIndex];
       
  1236 	else if(iIcons == NULL && iIconLoader == NULL)
       
  1237 		{
       
  1238 		Panic(EPanicIndexOutOfRange);
       
  1239 		return NULL;
       
  1240 		}
       
  1241 	else if(iIcons == NULL)
       
  1242 		{
       
  1243 		// Arriving here means the the icons need loading but havn't been loaded yet.
       
  1244 		TRAPD(err, iIconLoader->LoadAllIconsL());
       
  1245 		if (err != KErrNone)
       
  1246 			return NULL;
       
  1247 		}
       
  1248 
       
  1249 	return (*iIcons)[aIndex];
       
  1250 	}
       
  1251 
       
  1252 TBool CApaAppIconArray::AreAppIconsLoaded() const
       
  1253 	{
       
  1254 	if (iDefaultIconsUsed)
       
  1255 		return ETrue;
       
  1256 
       
  1257 	if (iNumOfIcons > 0 && !iIcons)
       
  1258 		return EFalse;	
       
  1259 
       
  1260 	return ETrue;
       
  1261 	}
       
  1262 
       
  1263 TBool CApaAppIconArray::AreViewIconsLoaded() const
       
  1264 	{
       
  1265 	if (iNumOfIcons > 0 && !iIcons )
       
  1266 		return EFalse;
       
  1267 
       
  1268 	return ETrue;	
       
  1269 	}
       
  1270 
       
  1271 void CApaAppIconArray::GetDefaultIconsL()
       
  1272 	{
       
  1273 	ASSERT(!iDefaultIconsUsed);
       
  1274 	iDefaultIconsProvider = CApaAppList::Self();
       
  1275 	ASSERT(iDefaultIconsProvider);
       
  1276 	iDefaultIconsProvider->AcquireDefaultIconArrayL();
       
  1277 	iDefaultIconsUsed = ETrue;
       
  1278 	delete iMbmFileName;
       
  1279 	iMbmFileName = NULL;
       
  1280 	if (iIcons)
       
  1281 		{
       
  1282 	 	iIcons->ResetAndDestroy();
       
  1283 		delete iIcons;
       
  1284 		iIcons = NULL;
       
  1285 		}
       
  1286 	}
       
  1287 
       
  1288 const CApaAppIconArray& CApaAppIconArray::DefaultIcons() const
       
  1289 	{
       
  1290 	ASSERT(iDefaultIconsUsed && iDefaultIconsProvider);
       
  1291 	return iDefaultIconsProvider->DefaultIconArray();
       
  1292 	}
       
  1293 
       
  1294 
       
  1295 
       
  1296