installationservices/swi/source/apprscparser/apprscparser.cpp
branchRCL_3
changeset 66 8b7f4e561641
parent 65 7333d7932ef7
child 70 e8965914fac7
equal deleted inserted replaced
65:7333d7932ef7 66:8b7f4e561641
     1 /*
       
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * apprscreader.cpp 
       
    16 *
       
    17 */
       
    18 
       
    19 #include "apprscparser.h"
       
    20 #include "log.h"
       
    21 #include <bautils.h>
       
    22 #include <barsc2.h>
       
    23 #include <barsread2.h>
       
    24 #include <e32uid.h>
       
    25 #include "cleanuputils.h"
       
    26 
       
    27 const TUint KResourceOffsetMask = 0xFFFFF000;
       
    28 const TUid KOpenServiceUid = { 0x10208DCA };
       
    29 //const TInt KMaxOpaqueDataLength = 0x1000; TODO: Need to enforce this
       
    30 
       
    31 _LIT(KAppBinaryPathAndExtension, "\\sys\\bin\\.exe");
       
    32 _LIT(KAppResourceFileExtension,".rsc");
       
    33 _LIT(KThreeDigitSuffix,"%03d");
       
    34 _LIT(KTwoDigitSuffix,"%02d");
       
    35 _LIT(KApparcFilePath, "*10003a3f*");
       
    36 
       
    37 const TInt KAppRegistrationInfoResourceId = 1;
       
    38 // The 2nd UID that defines a resource file as being an application registration resource file.
       
    39 const TUid KUidAppRegistrationFile = {0x101F8021};
       
    40 const TInt EPanicNullPointer = 1;
       
    41 const TInt KAppUidValue16 = 0x100039CE;
       
    42 const TUid KUidApp={KAppUidValue16};
       
    43 
       
    44 CLocalizableRsc::~CLocalizableRsc()
       
    45     {
       
    46     delete iRscFile;
       
    47     }
       
    48 
       
    49 CLocalizableRsc* CLocalizableRsc::NewL()
       
    50     {
       
    51     CLocalizableRsc *self = CLocalizableRsc::NewLC();
       
    52     CleanupStack::Pop(self);
       
    53     return self;
       
    54     }
       
    55 
       
    56 CLocalizableRsc* CLocalizableRsc::NewLC()
       
    57     {
       
    58     CLocalizableRsc *self = new(ELeave) CLocalizableRsc();
       
    59     CleanupStack::PushL(self);
       
    60     return self;
       
    61     }
       
    62 
       
    63 //
       
    64 // CAppRegInfoReader
       
    65 //
       
    66 
       
    67 EXPORT_C CAppRegInfoReader* CAppRegInfoReader::NewL(RFs& aFs, const TDesC& aRegistrationFileName)
       
    68 	{
       
    69 	CAppRegInfoReader* self = new(ELeave) CAppRegInfoReader(aFs, aRegistrationFileName);
       
    70 	return self;
       
    71 	}
       
    72 
       
    73 EXPORT_C CAppRegInfoReader* CAppRegInfoReader::NewL(RFs& aFs, const RFile& aRegistrationFile)
       
    74     {
       
    75     CAppRegInfoReader* self = new(ELeave) CAppRegInfoReader(aFs, aRegistrationFile);
       
    76 	CleanupStack::PushL(self);
       
    77 	self->ConstructL();
       
    78 	CleanupStack::Pop(self);
       
    79     return self;
       
    80     }
       
    81 
       
    82 CAppRegInfoReader::CAppRegInfoReader(RFs& aFs, const TDesC& aRegistrationFileName) :
       
    83 	iFs(aFs),
       
    84 	iAppUid(TUid::Null()),	
       
    85 	iRegistrationFileName(&aRegistrationFileName)
       
    86 	{	
       
    87 	}
       
    88 
       
    89 CAppRegInfoReader::CAppRegInfoReader(RFs& aFs, const RFile& aRegistrationFile) :
       
    90     iFs(aFs),
       
    91     iAppUid(TUid::Null()),
       
    92     iRegFileHandle(&aRegistrationFile)
       
    93     {
       
    94     iUseRegFileHandle = ETrue;	
       
    95 	}
       
    96 
       
    97 void CAppRegInfoReader::ConstructL()
       
    98 	{
       
    99 	TFileName fileName;
       
   100 	User::LeaveIfError(iRegFileHandle->FullName(fileName));	
       
   101 	iRegistrationFileName = fileName.AllocL();	
       
   102 	}
       
   103 
       
   104 EXPORT_C CAppRegInfoReader::~CAppRegInfoReader()
       
   105 	{
       
   106 	delete iAppBinaryFullName;		
       
   107 	iLocalizableRscArray.ResetAndDestroy();
       
   108 	iDeviceSupportedLanguages.Close();
       
   109 	
       
   110 	if (iUseRegFileHandle)
       
   111 	    delete iRegistrationFileName; // We had created the filename from the handle
       
   112 	}
       
   113 
       
   114 EXPORT_C Usif::CApplicationRegistrationData* CAppRegInfoReader::ReadL(const RArray<TLanguage>& aAppLanguages)
       
   115     {
       
   116 	DEBUG_PRINTF(_L("Reading the application rsc file"));
       
   117 	TEntry entry;
       
   118 	if (!iUseRegFileHandle)
       
   119 	    {
       
   120         User::LeaveIfError(iFs.Entry(*iRegistrationFileName, entry));        
       
   121 	    }
       
   122 	else
       
   123 	    {
       
   124 	    // Reading the TUidType information fron the reg rsc file header
       
   125 	    TBuf8<sizeof(TCheckedUid)> uidBuf;
       
   126 	    TInt err = iRegFileHandle->Read(0, uidBuf, sizeof(TCheckedUid));
       
   127 	    if (err != KErrNone || uidBuf.Size() != sizeof(TCheckedUid))
       
   128 	        {
       
   129 	        DEBUG_PRINTF(_L("The file is not a valid registration resource file"));
       
   130 	        User::Leave(KErrCorrupt);
       
   131 	        }
       
   132 	    TCheckedUid uid(uidBuf);
       
   133 	    entry.iType=uid.UidType();
       
   134 	    }
       
   135 	
       
   136 	if (!TypeUidIsForRegistrationFile(entry.iType))
       
   137         {
       
   138         DEBUG_PRINTF(_L("The resource file doesn't have any application registration information"));
       
   139         User::Leave(KErrCorrupt); // We are only interested in application reg resource files
       
   140         }
       
   141 	
       
   142 	TUint fileOffset = 0;
       
   143 	TInt fileLength = 0;
       
   144 	TUid firstUid(KExecutableImageUid);
       
   145 	TUid middleUid(KUidApp);
       
   146 	
       
   147 	// Read the AppUid from the rsc file
       
   148 	iAppUid = entry.iType[2];
       
   149 	if (iAppUid == TUid::Null())
       
   150 	    {
       
   151 	    DEBUG_PRINTF2(_L("Application UID in the registration resource file %S is NULL"), iRegistrationFileName);
       
   152 	    User::Leave(KErrCorrupt); // Mandatory information missing
       
   153 	    }
       
   154 	
       
   155 	// Set the TUidType for the app binary
       
   156 	iAppBinaryUidType = TUidType(firstUid, middleUid, iAppUid);
       
   157 	// Check to see if we are only interested in any localized info
       
   158 	iReadOnlyOneLocalizedRscInfo = aAppLanguages.Count()?EFalse:ETrue;
       
   159 	
       
   160 	// We need to parse for all device supported languages. Populate iDeviceSupportedLanguages.
       
   161 	if (aAppLanguages.Count()>0)
       
   162 	    {             
       
   163         GetInstalledLanguagesL();
       
   164 	    }
       
   165 
       
   166 	DEBUG_PRINTF2(_L("Opening rsc file %S"), iRegistrationFileName); //TODO
       
   167 	CResourceFile* registrationFile = NULL;
       
   168 	if (iUseRegFileHandle)
       
   169 	    {
       
   170 	    fileLength = 0;        
       
   171         User::LeaveIfError(iRegFileHandle->Size(fileLength));
       
   172 
       
   173         if (fileLength > 0)
       
   174             {
       
   175             // Read the reg rsc file to a buffer
       
   176             HBufC8* fileBuffer = HBufC8::NewLC(fileLength);
       
   177             TPtr8 fileBufferPtr(fileBuffer->Des());
       
   178             iRegFileHandle->Read(0, fileBufferPtr);
       
   179             registrationFile = CResourceFile::NewL(*fileBuffer);
       
   180             CleanupStack::PopAndDestroy(fileBuffer);
       
   181             }
       
   182 	    }
       
   183 	else
       
   184 	    {
       
   185 	    registrationFile = CResourceFile::NewL(iFs, *iRegistrationFileName, fileOffset, fileLength);
       
   186 	    }
       
   187 	CleanupStack::PushL(registrationFile);
       
   188 	
       
   189 	RResourceReader	resourceReader;
       
   190 	resourceReader.OpenLC(registrationFile, KAppRegistrationInfoResourceId);	
       
   191 	DEBUG_PRINTF(_L("rsc file opened")); //TODO
       
   192 	
       
   193 	TRAPD(err, ReadMandatoryInfoL(resourceReader));
       
   194 	if (err)
       
   195 		{
       
   196 		DEBUG_PRINTF(_L("Error in ReadMandatoryInfoL"));
       
   197 		CleanupStack::PopAndDestroy(2, registrationFile); // resourceReader
       
   198 		User::Leave(err); // Might have read something, but failed to setup enough info to make it worthwhile trying to read any more
       
   199 		}
       
   200 	
       
   201 	TUint localizableResourceId = 1; // Only initialising this here to keep the compiler happy
       
   202 	TRAP(err, ReadNonLocalizableInfoL(resourceReader, localizableResourceId, iDeviceSupportedLanguages));
       
   203 
       
   204 	if (!err)
       
   205 	    {
       
   206         // Open the localizable resource file for identified languages
       
   207         for (TInt i=0; i < iLocalizableRscArray.Count(); ++i)
       
   208             {
       
   209             iLocalizableRscArray[i]->iRscFile = CResourceFile::NewL(iFs, iLocalizableRscArray[i]->iFileName, 0, 0);
       
   210             CResourceFile* currLocalizableFile = iLocalizableRscArray[i]->iRscFile;
       
   211 	        if (currLocalizableFile && (localizableResourceId & KResourceOffsetMask))
       
   212 	            currLocalizableFile->ConfirmSignatureL();	        
       
   213 	        }	    
       
   214 		TRAP(err, ReadNonLocalizableOptionalInfoL(resourceReader, registrationFile));
       
   215 		}
       
   216 		
       
   217 	if (!err)
       
   218 	    {
       
   219 	    // Read the localized resource information the identified languages
       
   220 	    for (TInt i=0; i < iLocalizableRscArray.Count(); ++i)
       
   221 	        {
       
   222 	        CResourceFile* currLocalizableFile = iLocalizableRscArray[i]->iRscFile;
       
   223 	        TFileName fileName = iLocalizableRscArray[i]->iFileName;
       
   224 	        DEBUG_PRINTF2(_L("Reading Localizable Info from : %S"), &fileName);
       
   225 	        // The following call can leave if the localized resource file is ill formed.
       
   226 	        // We'll try to parse other loclized files (if possible) in such a case.
       
   227 	        TRAPD(errLocalized, ReadLocalizableInfoL(*currLocalizableFile, localizableResourceId, iLocalizableRscArray[i]->iLanguage));
       
   228 	        if (errLocalized)
       
   229                 DEBUG_PRINTF3(_L("Error while reading file (%S) : %d"), &fileName, errLocalized);
       
   230 	        }
       
   231 	    }
       
   232 	
       
   233 	const TBool readSuccessful = (err == KErrNone);
       
   234 	DEBUG_PRINTF2(_L("Application rsc file parsed. Status : %d"), readSuccessful);
       
   235 	CleanupStack::PopAndDestroy(2, registrationFile); // resourceReader	
       
   236 	
       
   237 	Usif::CApplicationRegistrationData* appRegInfo = NULL;
       
   238 	if (readSuccessful)
       
   239 	    {	    
       
   240 	    RPointerArray<Usif::CPropertyEntry> appPropertiesArray;	    	    
       
   241 		appRegInfo = Usif::CApplicationRegistrationData::NewL(iOwnedFileArray, iServiceArray, iLocalizableAppInfoArray, 
       
   242                                         appPropertiesArray, iOpaqueDataArray, iAppUid, *iAppBinaryFullName, iAppCharacteristics, iDefaultScreenNumber);
       
   243 		
       
   244 		DEBUG_PRINTF2(_L("Count Languages (from client) : %d"), aAppLanguages.Count());
       
   245 		DEBUG_PRINTF2(_L("Count Languages (after reset) : %d"), iDeviceSupportedLanguages.Count());
       
   246 		DEBUG_PRINTF2(_L("Count of Loc files parsed : %d"), iLocalizableRscArray.Count());
       
   247 		DEBUG_PRINTF2(_L("Count of Loc data passed to SWI : %d"), iLocalizableAppInfoArray.Count());				
       
   248 	   }
       
   249 	else
       
   250 	    {
       
   251         // Cleanup the member arrays
       
   252         iOwnedFileArray.ResetAndDestroy(); 
       
   253         iServiceArray.ResetAndDestroy();
       
   254         iLocalizableAppInfoArray.ResetAndDestroy();
       
   255         iOpaqueDataArray.ResetAndDestroy();
       
   256 	    }
       
   257 	
       
   258 	return appRegInfo;
       
   259 	}
       
   260 
       
   261 // This method reads the minimum information required to register an app.
       
   262 // If this fails, we say the read has been unsuccessful.
       
   263 void CAppRegInfoReader::ReadMandatoryInfoL(RResourceReader& aResourceReader)
       
   264 	{
       
   265 	DEBUG_PRINTF(_L("Reading the mandatory application info"));
       
   266 	aResourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   267 	aResourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   268 
       
   269 	// Read LTEXT app_file
       
   270 	const TPtrC appFile(aResourceReader.ReadTPtrCL());
       
   271 	// This object gets used for 2 purposes: first to check that a TParsePtrC can be created 
       
   272 	// over "appFile" without it panicking, and second to construct iAppBinaryFullName
       
   273 	TParse parse;
       
   274 	// Do this before creating a TParsePtrC, since TParsePtrC's constructor panics if it fails 
       
   275 	// (which would provide an easy way for malware to kill the Apparc server)
       
   276 	User::LeaveIfError(parse.SetNoWild(appFile, NULL, NULL)); 
       
   277 	const TParsePtrC appFileParser(appFile);
       
   278 
       
   279 	// Read LONG attributes
       
   280 	iAppCharacteristics.iAttributes = aResourceReader.ReadUint32L();
       
   281 
       
   282 	if (!appFileParser.NamePresent())
       
   283 	    {
       
   284 	    DEBUG_PRINTF2(_L("Application Name in the registration resource file %S is not present"),iRegistrationFileName);
       
   285 		User::Leave(KErrCorrupt);
       
   286 	    }
       
   287 
       
   288 	const TPtrC appNameWithoutExtension(appFileParser.Name());
       
   289 	const TPtrC registrationFileDrive(TParsePtrC(*iRegistrationFileName).Drive());
       
   290 	
       
   291 	if (iAppCharacteristics.iAttributes & ENonNative)
       
   292 		{
       
   293         User::Leave(KErrNotSupported); // Non native apps need not have an applicaiton reg rsc file
       
   294 		}
       
   295 	else if (iAppCharacteristics.iAttributes & EBuiltAsDll)
       
   296 		{
       
   297 		User::Leave(KErrNotSupported); // Legacy dll-style app
       
   298 		}
       
   299 	else
       
   300 		{
       
   301 		// Exe-style app
       
   302 		User::LeaveIfError(parse.SetNoWild(registrationFileDrive, &KAppBinaryPathAndExtension, &appNameWithoutExtension));
       
   303 		}
       
   304 
       
   305 	iAppBinaryFullName = parse.FullName().AllocL();
       
   306 	DEBUG_PRINTF2(_L("App Binary FullName : %S"),iAppBinaryFullName); //TODO
       
   307 	DEBUG_PRINTF2(_L("AppUid : 0x%X"), iAppUid.iUid); //TODO
       
   308 	DEBUG_PRINTF2(_L("Attributes : %d"), iAppCharacteristics.iAttributes); //TODO
       
   309 	}
       
   310 
       
   311 HBufC* CAppRegInfoReader::CreateFullIconFileNameL(const TDesC& aIconFileName) const
       
   312 	{
       
   313 	HBufC* filename = NULL;
       
   314 	if (aIconFileName.Length() == 0)
       
   315 		return NULL;
       
   316 	
       
   317 	//aIconFileName may contain a valid string in some format (for eg. URI format) other than path to a regular file on disk
       
   318 	//and that can be a mbm or non-mbm file. Such a filename will be reported as invalid filename by iFs.IsValidName() method. 
       
   319 	//aIconFileName will be returned since it is a valid string. 	
       
   320 	if(!iFs.IsValidName(aIconFileName))
       
   321 		{
       
   322 		filename = aIconFileName.AllocL();
       
   323 		return filename;
       
   324 		}
       
   325 	
       
   326 	TParsePtrC parsePtr(aIconFileName);
       
   327 	if (parsePtr.IsWild() || !parsePtr.PathPresent() || !parsePtr.NamePresent())
       
   328 		return NULL;
       
   329 
       
   330 	// Check for fully qualified icon filename
       
   331 	if (parsePtr.DrivePresent() && BaflUtils::FileExists(iFs, aIconFileName))
       
   332 		filename = aIconFileName.AllocL();
       
   333 	else
       
   334 		{
       
   335 		// Check for icon file on same drive as localizable resource file
       
   336 		TParse parse;
       
   337 		TPtrC localizableResourceFileDrive = TParsePtrC(iTempLocalizableRscFileName).Drive();
       
   338 		TInt ret = parse.SetNoWild(localizableResourceFileDrive, &aIconFileName, NULL);
       
   339 		if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName()))
       
   340 			filename = parse.FullName().AllocL();
       
   341 		else
       
   342 			{
       
   343 			TPtrC registrationFileDrive = TParsePtrC(*iRegistrationFileName).Drive();
       
   344 			if (TInt(TDriveUnit(registrationFileDrive)) != TInt(TDriveUnit(localizableResourceFileDrive)))
       
   345 				{
       
   346 				// Check for icon file on same drive as registration file
       
   347 				ret = parse.SetNoWild(registrationFileDrive, &aIconFileName, NULL);
       
   348 				if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName()))
       
   349 					filename = parse.FullName().AllocL();
       
   350 				}
       
   351 			}
       
   352 		}
       
   353 	
       
   354 	return filename;
       
   355 	}
       
   356 
       
   357 void CAppRegInfoReader::ReadLocalizableInfoL(const CResourceFile& aResourceFile, TUint aResourceId, TLanguage aLanguage)
       
   358 	{
       
   359 	HBufC* caption = NULL;
       
   360     HBufC* shortCaption = NULL;   
       
   361     TInt numOfAppIcons = 0;
       
   362     HBufC* iconFileName = NULL;
       
   363 	    
       
   364 	RResourceReader resourceReader;
       
   365 	resourceReader.OpenLC(&aResourceFile, aResourceId);
       
   366 
       
   367 	resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   368 	resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   369 		
       
   370 	// Read LTEXT short_caption
       
   371 	shortCaption = resourceReader.ReadHBufCL();
       
   372 	
       
   373 	if (shortCaption)
       
   374         {
       
   375         DEBUG_PRINTF2(_L("ShortCaption : %S"), shortCaption); //TODO
       
   376         CleanupStack::PushL(shortCaption);
       
   377         }
       
   378     else
       
   379         {
       
   380         DEBUG_PRINTF(_L("ShortCaption is NULL")); //TODO
       
   381         }
       
   382 	
       
   383 	resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   384 	resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   385 
       
   386 	// Read LTEXT caption	
       
   387 	caption = resourceReader.ReadHBufCL();
       
   388 	
       
   389 	if (caption)
       
   390             {
       
   391             DEBUG_PRINTF2(_L("Caption : %S"), caption); //TODO
       
   392             CleanupStack::PushL(caption);
       
   393             }
       
   394         else
       
   395             {
       
   396             DEBUG_PRINTF(_L("Caption is NULL")); //TODO
       
   397             }
       
   398 
       
   399 	// Read WORD number_of_icons
       
   400 	numOfAppIcons = resourceReader.ReadInt16L();
       
   401 	DEBUG_PRINTF2(_L("NumOfIcons : %d"), numOfAppIcons); //TODO
       
   402 	
       
   403 	// Read LTEXT icon_file
       
   404 	HBufC* iconFile = resourceReader.ReadHBufCL();
       
   405 	if (iconFile)
       
   406 	    {
       
   407         if (iReadOnlyOneLocalizedRscInfo)
       
   408             iconFileName = iconFile; // We do not need to check if the icon file is present
       
   409         else
       
   410             {
       
   411             CleanupStack::PushL(iconFile);
       
   412             iconFileName = CreateFullIconFileNameL(*iconFile);
       
   413             CleanupStack::PopAndDestroy(iconFile);
       
   414             }
       
   415 	    }
       
   416 
       
   417 	if (iconFileName)
       
   418 	    {
       
   419 	    DEBUG_PRINTF2(_L("IconFileName : %S"), iconFileName); //TODO
       
   420 	    CleanupStack::PushL(iconFileName);
       
   421 	    }
       
   422 	else
       
   423 	    {
       
   424 	    DEBUG_PRINTF(_L("IconFileName is NULL")); //TODO
       
   425 	    }
       
   426 
       
   427 	// Create CCaptionAndIconInfo for the locale
       
   428 	Usif::CCaptionAndIconInfo* captionAndIconInfo = Usif::CCaptionAndIconInfo::NewLC(caption?*caption:_L(""), iconFileName?*iconFileName:_L(""), numOfAppIcons);			
       
   429 	
       
   430 	// Read LEN WORD STRUCT view_list[]
       
   431 	const TInt numOfViews = resourceReader.ReadInt16L();
       
   432 	
       
   433 	RPointerArray<Usif::CAppViewData> viewDataList;
       
   434 	CleanupResetAndDestroyPushL(viewDataList);
       
   435 	for(TInt view = 0; view < numOfViews; ++view)
       
   436 		{
       
   437 		DEBUG_PRINTF2(_L(" *** View Details for index %d ***"), view); //TODO
       
   438 		resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   439 		resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   440 
       
   441 		// Read LONG uid
       
   442 		const TUid viewUid = {resourceReader.ReadInt32L()};
       
   443 		DEBUG_PRINTF2(_L("ViewUid : 0x%X"), viewUid); //TODO
       
   444 		// Read LONG screen_mode
       
   445 		const TInt screenMode = {resourceReader.ReadInt32L()};
       
   446 		DEBUG_PRINTF2(_L("ScreenMode : %d"), screenMode); //TODO
       
   447 		
       
   448 		resourceReader.ReadUint32L(); // skip over LONG reserved_long
       
   449 		resourceReader.ReadUint32L(); // skip over LLINK reserved_llink
       
   450 
       
   451 		// Read LTEXT caption
       
   452 		HBufC* viewCaption = resourceReader.ReadHBufCL();
       
   453 		if (viewCaption)
       
   454             {
       
   455             DEBUG_PRINTF2(_L("ViewCaption : %S"), viewCaption); //TODO
       
   456             CleanupStack::PushL(viewCaption);
       
   457             }
       
   458         else
       
   459             {
       
   460             DEBUG_PRINTF(_L("ViewCaption is NULL")); //TODO
       
   461             }
       
   462 		
       
   463 		// Read WORD number_of_icons
       
   464 		const TInt numOfViewIcons = resourceReader.ReadInt16L();
       
   465 		DEBUG_PRINTF2(_L("NumOfViewIcons : %d"), numOfViewIcons); //TODO
       
   466 		
       
   467 		HBufC* fullViewIconFileName = NULL;
       
   468 		// Read LTEXT icon_file
       
   469 		HBufC* viewIconFile = resourceReader.ReadHBufCL();  
       
   470 		
       
   471         if (viewIconFile)
       
   472 		    {
       
   473 		    CleanupStack::PushL(viewIconFile);
       
   474             fullViewIconFileName = CreateFullIconFileNameL(*viewIconFile); 
       
   475             CleanupStack::PopAndDestroy(viewIconFile);
       
   476             if (fullViewIconFileName)
       
   477                 {               
       
   478                 CleanupStack::PushL(fullViewIconFileName);
       
   479                 DEBUG_PRINTF2(_L("ViewIconFileName : %S"), fullViewIconFileName); //TODO
       
   480                 }
       
   481             else
       
   482                 {
       
   483                 DEBUG_PRINTF(_L("ViewIconFileName is NULL")); //TODO
       
   484                 }            
       
   485 		    }
       
   486 				
       
   487 		// Create CCaptionAndIconInfo for the view
       
   488 		Usif::CCaptionAndIconInfo* viewCaptionAndIcon = Usif::CCaptionAndIconInfo::NewLC(viewCaption?*viewCaption:_L(""), fullViewIconFileName?*fullViewIconFileName:_L(""), numOfViewIcons);
       
   489 		// Create the view
       
   490 		Usif::CAppViewData* viewData = Usif::CAppViewData::NewLC(viewUid, screenMode, viewCaptionAndIcon);
       
   491 		
       
   492 		viewDataList.AppendL(viewData);
       
   493 		
       
   494 		CleanupStack::Pop(2, viewCaptionAndIcon); // viewData
       
   495 		if (fullViewIconFileName)
       
   496 		    CleanupStack::PopAndDestroy(fullViewIconFileName);
       
   497 		if (viewCaption)
       
   498 		    CleanupStack::PopAndDestroy(viewCaption);
       
   499 		}
       
   500 
       
   501 	// Read LTEXT group_name
       
   502 	TAppGroupName groupName;
       
   503 	TRAPD(ret, (groupName = resourceReader.ReadTPtrCL()));
       
   504 	if (ret != KErrNone)
       
   505 		{
       
   506 		 if (ret != KErrEof)
       
   507 	         User::Leave(ret);
       
   508 		}
       
   509 	
       
   510 	DEBUG_PRINTF2(_L("GroupName : %S"), &groupName); //TODO	
       
   511 	Usif::CLocalizableAppInfo* localizableAppInfo = Usif::CLocalizableAppInfo::NewLC(shortCaption?*shortCaption:_L(""), aLanguage, groupName, captionAndIconInfo, viewDataList);
       
   512 	iLocalizableAppInfoArray.AppendL(localizableAppInfo);
       
   513 	
       
   514 	CleanupStack::Pop(3, captionAndIconInfo); // localizableAppInfo, viewDataList
       
   515 	if (iconFileName)
       
   516 	    CleanupStack::PopAndDestroy(iconFileName);
       
   517 	if (caption)
       
   518 	    CleanupStack::PopAndDestroy(caption);
       
   519 	if (shortCaption)
       
   520 	    CleanupStack::PopAndDestroy(shortCaption);
       
   521 	CleanupStack::PopAndDestroy(&resourceReader);
       
   522 	}
       
   523 
       
   524 void CAppRegInfoReader::ReadOpaqueDataL(TUint aResourceId, const CResourceFile* aRegistrationFile, RPointerArray<Usif::COpaqueData>& aOpaqueDataArray)
       
   525     {
       
   526     if (aResourceId == 0)
       
   527         return;
       
   528     else
       
   529         {
       
   530         if (aResourceId & KResourceOffsetMask)
       
   531             {
       
   532             for (TInt i=0; i < iLocalizableRscArray.Count(); ++i)
       
   533                 {
       
   534                 CResourceFile* currLocalizableFile = iLocalizableRscArray[i]->iRscFile;                
       
   535                 currLocalizableFile->ConfirmSignatureL();
       
   536                 HBufC8* data = NULL;
       
   537                 TRAPD(err, data = currLocalizableFile->AllocReadL(aResourceId));                  
       
   538                 if(err == KErrNone)
       
   539                     {
       
   540                     DEBUG_PRINTF3(_L8("Opaque Data read (length %d) from the localizable resouce file : %S"), data->Length(), data);
       
   541                     CleanupStack::PushL(data);
       
   542                     Usif::COpaqueData* opaqueData = Usif::COpaqueData::NewL(*data, iLocalizableRscArray[i]->iLanguage);
       
   543                     aOpaqueDataArray.AppendL(opaqueData);
       
   544                     CleanupStack::PopAndDestroy(data);
       
   545                     }
       
   546                 }            
       
   547             }
       
   548         else
       
   549             {
       
   550             // Expecting opaque data to be in the registration file
       
   551             __ASSERT_ALWAYS(aRegistrationFile, Panic(EPanicNullPointer));
       
   552             HBufC8* data = aRegistrationFile->AllocReadLC(aResourceId);
       
   553             DEBUG_PRINTF3(_L8("Opaque Data read (length %d) from the registration resouce file : %S"), data->Length(), data);
       
   554             Usif::COpaqueData* opaqueData = Usif::COpaqueData::NewL(*data, TLanguage(0));
       
   555             aOpaqueDataArray.AppendL(opaqueData);
       
   556             CleanupStack::PopAndDestroy(data);
       
   557             }
       
   558         }
       
   559     }
       
   560 
       
   561 void CAppRegInfoReader::ReadNonLocalizableOptionalInfoL(RResourceReader& aResourceReader, const CResourceFile* aRegistrationFile)
       
   562 	{
       
   563 	DEBUG_PRINTF(_L("Reading the application non localized optional info"));
       
   564 	// Read LEN WORD STRUCT service_list[]
       
   565 	TInt serviceCount = 0;
       
   566 	// Service information was not present in the first release of the registration file
       
   567 	// APP_REGISTRATION_INFO resource struct.
       
   568 	// This method must not leave if the registration file doesn't contain service information, so the
       
   569 	// following call to ReadInt16L is trapped to ensure this method doesn't leave just because
       
   570 	// there is no more information in the resource to read (KErrEof)
       
   571 	TRAPD(err, serviceCount = aResourceReader.ReadInt16L());
       
   572 	if (err)
       
   573 		{
       
   574 		if (err == KErrEof)
       
   575 			return; // End of resource reached
       
   576 		
       
   577 		User::Leave(err);
       
   578 		}
       
   579 	DEBUG_PRINTF2(_L("Service count is : %d"), serviceCount); //TODO
       
   580 	
       
   581 	while (serviceCount--)
       
   582 		{
       
   583 		const TUid serviceUid = {aResourceReader.ReadUint32L()};
       
   584 		
       
   585 		if ((serviceUid == KOpenServiceUid) && (iLegacyDataTypesPresent))
       
   586 			{
       
   587             __ASSERT_DEBUG( iServiceArray.Count(), Panic(EPanicNullPointer) );
       
   588 			// Deleting the legacy datatypes
       
   589             Usif::CServiceInfo* firstElement = iServiceArray[0];
       
   590             iServiceArray.Remove(0);
       
   591             delete firstElement;
       
   592             iLegacyDataTypesPresent = EFalse;
       
   593 			}
       
   594 		
       
   595 		RPointerArray<Usif::CDataType> serviceDataTypes;
       
   596 		CleanupResetAndDestroyPushL(serviceDataTypes);
       
   597 		ReadMimeTypesSupportedL(aResourceReader, serviceDataTypes);
       
   598 		
       
   599 		const TUint resourceId = aResourceReader.ReadUint32L();
       
   600 		RPointerArray<Usif::COpaqueData> serviceOpaqueDataArray;
       
   601 		CleanupResetAndDestroyPushL(serviceOpaqueDataArray);
       
   602 		ReadOpaqueDataL(resourceId, aRegistrationFile, serviceOpaqueDataArray);
       
   603 						
       
   604 		Usif::CServiceInfo* serviceInfo = Usif::CServiceInfo::NewLC(serviceUid, serviceOpaqueDataArray, serviceDataTypes);
       
   605 		iServiceArray.AppendL(serviceInfo);
       
   606 		DEBUG_PRINTF3(_L("ServiceUid (index %d) is : 0x%X "), iServiceArray.Count()-1, serviceUid.iUid); //TODO
       
   607 		
       
   608 		CleanupStack::Pop(3, &serviceDataTypes); // serviceInfo, serviceOpaqueDataArray
       
   609 		}
       
   610 	
       
   611 	// Read LLINK opaque_data
       
   612 	const TUint resourceId = aResourceReader.ReadUint32L();
       
   613 	ReadOpaqueDataL(resourceId, aRegistrationFile, iOpaqueDataArray);
       
   614 	}
       
   615 
       
   616 void CAppRegInfoReader::ReadNonLocalizableInfoL(RResourceReader& aResourceReader, TUint& aLocalizableResourceId, const RArray<TLanguage>& aAppLanguages)
       
   617 	{
       
   618 	DEBUG_PRINTF(_L("Reading the application non localized info"));
       
   619 	
       
   620 	// Read LTEXT localizable_resource_file
       
   621 	TPtrC localizableResourceFileName(aResourceReader.ReadTPtrCL());
       
   622 	if (localizableResourceFileName.Length() > 0 && iFs.IsValidName(localizableResourceFileName))
       
   623 		{
       
   624 		// Determine the language specific name of the localizable resource file
       
   625 		TParse parse;
       
   626 		TParsePtrC parsePtr(*iRegistrationFileName);
       
   627 		User::LeaveIfError(parse.SetNoWild(parsePtr.Drive(), &KAppResourceFileExtension, &localizableResourceFileName));
       
   628 		TFileName localizableRscFileName(parse.FullName());
       
   629 		DEBUG_PRINTF2(_L("Localizable filename from rsc is : %S"), &localizableRscFileName); 
       
   630 		iTempLocalizableRscFileName = localizableRscFileName; // Store the rsc filename as read (before bafl makes any changes)
       
   631 		
       
   632 		// Check if we need to read more than one localized resource file
       
   633 		if (!aAppLanguages.Count())
       
   634 		    {
       
   635             TLanguage applicationLanguage;		    
       
   636             BaflUtils::NearestLanguageFileV2(iFs, localizableRscFileName, applicationLanguage);
       
   637 		
       
   638             // We are able to find a match
       
   639             if (BaflUtils::FileExists(iFs, iTempLocalizableRscFileName))
       
   640                 {
       
   641                 // We read here only for one locale, similar to AppArc's behaviour when parsing the resource file
       
   642                 CLocalizableRsc* localizedRsc = CLocalizableRsc::NewL();
       
   643                 localizedRsc->iFileName = localizableRscFileName;
       
   644                 if (ELangNone == applicationLanguage)
       
   645                     localizedRsc->iLanguage = TLanguage(0);
       
   646                 else
       
   647                     localizedRsc->iLanguage = applicationLanguage;
       
   648                 iLocalizableRscArray.Append(localizedRsc);
       
   649                 }
       
   650             else 
       
   651                 {
       
   652                 // The resource files are located in non-standard location (like in the case of GetComponentInfo).
       
   653                 // We need to find the temporary paths for localized resource files in this case.
       
   654                 // The reg file will be in some location like <path>\regfilename_reg.rsc and localized rsc file name
       
   655                 // would point to \resource\apps\localregfilename.rsc or \resource\apps\localregfilename.r01 etc.
       
   656                 // Changing the localized rsc file name to <path>\localregfilename.rsc
       
   657                 TFileName nonStdLocalizedRscFileName = parsePtr.DriveAndPath(); // Drive and path from Registration FileName
       
   658                 nonStdLocalizedRscFileName.Append(TParsePtrC(localizableRscFileName).NameAndExt()); // Name and extension of localized rsc file
       
   659                 iTempLocalizableRscFileName = nonStdLocalizedRscFileName; // For FindLocalizableResourceFilesL
       
   660                 
       
   661                 if (KErrNotFound == iTempLocalizableRscFileName.Match(KApparcFilePath))
       
   662                     {
       
   663                     applicationLanguage = User::Language();                
       
   664                     FindLocalizableResourceFilesL(applicationLanguage); 
       
   665                 
       
   666                     // If there is no match, check for default localizable rsc file
       
   667                     if (!iLocalizableRscArray.Count())
       
   668                         CheckForDefaultResourceFileL();
       
   669                     }
       
   670                 }            
       
   671 		    }
       
   672 		else
       
   673 		    {
       
   674             for (TInt i=0; i < aAppLanguages.Count(); ++i)
       
   675                 FindLocalizableResourceFilesL(aAppLanguages[i]);
       
   676             
       
   677             CheckForDefaultResourceFileL();
       
   678 		    }
       
   679 		}
       
   680         
       
   681 	// Read LONG localizable_resource_id
       
   682 	aLocalizableResourceId = aResourceReader.ReadUint32L();
       
   683 	DEBUG_PRINTF3(_L("LocalizableResourceId : %d : 0x%X "), aLocalizableResourceId, aLocalizableResourceId); //TODO
       
   684 	
       
   685 	DEBUG_PRINTF(_L("Reading app characteristics")); //TODO
       
   686 	iAppCharacteristics.iAppIsHidden = aResourceReader.ReadInt8L();
       
   687 	iAppCharacteristics.iEmbeddability = (Usif::TApplicationCharacteristics::TAppEmbeddability)aResourceReader.ReadInt8L();
       
   688 	iAppCharacteristics.iSupportsNewFile = aResourceReader.ReadInt8L();
       
   689 	iAppCharacteristics.iLaunchInBackground = aResourceReader.ReadInt8L();
       
   690 	iAppCharacteristics.iGroupName = aResourceReader.ReadTPtrCL();
       
   691 	iDefaultScreenNumber = aResourceReader.ReadUint8L();
       
   692  	
       
   693 	DEBUG_PRINTF2(_L("iAppIsHidden : %d"), iAppCharacteristics.iAppIsHidden); //TODO
       
   694 	DEBUG_PRINTF2(_L("iEmbeddability : %d"), iAppCharacteristics.iEmbeddability); //TODO
       
   695 	DEBUG_PRINTF2(_L("iSupportsNewFile : %d"), iAppCharacteristics.iSupportsNewFile); //TODO
       
   696 	DEBUG_PRINTF2(_L("iLaunchInBackground : %d"), iAppCharacteristics.iLaunchInBackground); //TODO
       
   697 	DEBUG_PRINTF2(_L("iGroupName : %S"), &(iAppCharacteristics.iGroupName)); //TODO
       
   698 	DEBUG_PRINTF2(_L("iDefaultScreenNumber : %d"), iDefaultScreenNumber); //TODO
       
   699 	
       
   700 	// Read the datatypes
       
   701 	RPointerArray<Usif::CDataType> dataTypes;
       
   702 	CleanupResetAndDestroyPushL(dataTypes);
       
   703 	RPointerArray<Usif::COpaqueData> opaqueDataArray;
       
   704 	CleanupResetAndDestroyPushL(opaqueDataArray);
       
   705 	ReadMimeTypesSupportedL(aResourceReader, dataTypes);
       
   706 	
       
   707 	// DataTypes are deleted if 
       
   708 	//  A. There are no legacy datatypes
       
   709 	//  B. Control panel plugin apps are not allowed to register MIME types.If they happen to have any, 
       
   710 	//     these datatypes should be ignored.
       
   711 	if ((iAppCharacteristics.iAttributes & EControlPanelItem) || (dataTypes.Count() == 0))
       
   712 	    {
       
   713 	    CleanupStack::Pop(2, &dataTypes); // opaqueDataArray
       
   714 	    dataTypes.ResetAndDestroy();
       
   715 	    opaqueDataArray.ResetAndDestroy();	    
       
   716 	    }
       
   717 	else
       
   718 		{
       
   719 		DEBUG_PRINTF(_L("Reading Open Service Datatypes")); //TODO
       
   720 		
       
   721 		Usif::CServiceInfo* serviceInfo = Usif::CServiceInfo::NewLC(KOpenServiceUid, opaqueDataArray, dataTypes);
       
   722 		iServiceArray.AppendL(serviceInfo);
       
   723 		DEBUG_PRINTF2(_L("ServiceUid (index %d) is : OpenServiceUid "), iServiceArray.Count()-1); //TODO
       
   724 		
       
   725 		CleanupStack::Pop(3, &dataTypes); // serviceInfo, opaqueDataArray
       
   726 		iLegacyDataTypesPresent = ETrue;
       
   727 		}
       
   728 
       
   729 	// Read LEN WORD STRUCT file_ownership_list[]
       
   730 	const TInt fileOwnershipArraySize = aResourceReader.ReadInt16L();
       
   731 	DEBUG_PRINTF2(_L("Owned File Array Size is : %d"), fileOwnershipArraySize); //TODO
       
   732 
       
   733 	DEBUG_PRINTF(_L("Reading Owned File Array")); //TODO
       
   734 	for (TInt i=0; i < fileOwnershipArraySize; i++)
       
   735 		{
       
   736 		TPtrC fileNamePtr = aResourceReader.ReadTPtrCL();
       
   737 		iOwnedFileArray.AppendL(fileNamePtr.AllocL());
       
   738 		DEBUG_PRINTF3(_L("File (index %d) is : %S "), i, &fileNamePtr); //TODO
       
   739 		}
       
   740 	}
       
   741 	
       
   742 void CAppRegInfoReader::ReadMimeTypesSupportedL(RResourceReader& aResourceReader, RPointerArray<Usif::CDataType>& aDataTypes)
       
   743     {
       
   744     DEBUG_PRINTF(_L("Reading MimeTypes supported")); //TODO
       
   745     // Read LEN WORD STRUCT datatype_list[]
       
   746     const TInt dataTypeArraySize = aResourceReader.ReadInt16L();
       
   747     DEBUG_PRINTF2(_L("DataType Array Size is : %d"), dataTypeArraySize); //TODO
       
   748     if (dataTypeArraySize <= 0)
       
   749         return;
       
   750     
       
   751     for (TInt i=0; i < dataTypeArraySize; i++)
       
   752         {
       
   753         TInt32 priority = aResourceReader.ReadInt32L();
       
   754                    
       
   755         TPtrC8 typePtr = aResourceReader.ReadTPtrC8L();
       
   756         TBuf16<KMaximumDataTypeLength> buf;
       
   757         buf.Copy(typePtr); 
       
   758         DEBUG_PRINTF3(_L("Service Info Priority (index %d) is : %d "), i, priority); //TODO
       
   759         DEBUG_PRINTF3(_L("Service Info Type (index %d) is : %S "), i, &buf); //TODO
       
   760         
       
   761         Usif::CDataType* dataType = Usif::CDataType::NewLC(priority, buf);        
       
   762         aDataTypes.AppendL(dataType);
       
   763         CleanupStack::Pop(dataType);
       
   764         }
       
   765     }
       
   766 
       
   767 void CAppRegInfoReader::CheckForDefaultResourceFileL()
       
   768     {
       
   769     if (BaflUtils::FileExists(iFs, iTempLocalizableRscFileName))   
       
   770         {      
       
   771         DEBUG_PRINTF2(_L("Default localized resource file is present : %S"), &iTempLocalizableRscFileName);
       
   772         CLocalizableRsc* localizedRsc = CLocalizableRsc::NewL();
       
   773         localizedRsc->iFileName = iTempLocalizableRscFileName;
       
   774         localizedRsc->iLanguage = TLanguage(0); //Non-localized details
       
   775         iLocalizableRscArray.Append(localizedRsc);
       
   776         }
       
   777     }
       
   778 
       
   779 // Find the correct localized resource file based on the given language
       
   780 void CAppRegInfoReader::FindLocalizableResourceFilesL(const TLanguage& aApplicationLanguage)
       
   781     {
       
   782     DEBUG_PRINTF2(_L("Finding localizable resource files for language : %d"), aApplicationLanguage);
       
   783         
       
   784     TLanguagePath langEquivalents;
       
   785     RArray<TLanguage> appLanguages;
       
   786     BaflUtils::GetEquivalentLanguageList(aApplicationLanguage, langEquivalents);
       
   787     TInt i = 0;
       
   788     while (langEquivalents[i] != ELangNone)
       
   789         {
       
   790         appLanguages.Append(langEquivalents[i]);
       
   791         ++i;
       
   792         }
       
   793     
       
   794     TInt newLength = iTempLocalizableRscFileName.Length() - 2;
       
   795     TFileName localizedRscFileNamePrefix(iTempLocalizableRscFileName.Left(newLength));
       
   796     DEBUG_PRINTF2(_L("FileName after trimming last digits : %S"), &localizedRscFileNamePrefix); //TODO
       
   797             
       
   798     for (TInt i=0; i < appLanguages.Count(); ++i)
       
   799         {                
       
   800         TFileName localizedRscFileName(localizedRscFileNamePrefix);
       
   801         if (appLanguages[i] > 99)
       
   802             localizedRscFileName.AppendFormat(KThreeDigitSuffix, appLanguages[i]);
       
   803         else
       
   804             localizedRscFileName.AppendFormat(KTwoDigitSuffix, appLanguages[i]);
       
   805         
       
   806         // Check if the file exist
       
   807         if (BaflUtils::FileExists(iFs, localizedRscFileName))
       
   808             {
       
   809             // Check if language already exists
       
   810             TInt rscCount = iLocalizableRscArray.Count();
       
   811             TBool isExists = EFalse;
       
   812             for(TInt j = 0; j < rscCount; j++)
       
   813                 {
       
   814                 if(appLanguages[i] == iLocalizableRscArray[j]->iLanguage)
       
   815                     {
       
   816                     isExists = ETrue;
       
   817                     break;
       
   818                     }
       
   819                 }
       
   820             
       
   821             if(!isExists)
       
   822                 {
       
   823                 CLocalizableRsc* localizedRsc = CLocalizableRsc::NewL();
       
   824                 localizedRsc->iFileName = localizedRscFileName;
       
   825                 localizedRsc->iLanguage = appLanguages[i];
       
   826                 iLocalizableRscArray.Append(localizedRsc);
       
   827                 DEBUG_PRINTF2(_L("Localized rsc file is : %S"), &localizedRscFileName);
       
   828                 }            
       
   829             break;
       
   830             }
       
   831         } 
       
   832     
       
   833     appLanguages.Close();
       
   834     }
       
   835 
       
   836 TBool CAppRegInfoReader::TypeUidIsForRegistrationFile(const TUidType& aUidType)
       
   837     {
       
   838     return (aUidType[1].iUid==KUidAppRegistrationFile.iUid);
       
   839     }
       
   840 
       
   841 void CAppRegInfoReader::Panic(TInt aPanic)
       
   842     {
       
   843     _LIT(KSWIAppRegInfoReaderPanic,"SWIAppRegInfoReaderPanic");
       
   844     User::Panic(KSWIAppRegInfoReaderPanic, aPanic);
       
   845     }
       
   846 
       
   847 void CAppRegInfoReader::GetInstalledLanguagesL()
       
   848     {
       
   849     _LIT(KLanguagesIni, "z:\\resource\\bootdata\\languages.txt");
       
   850     const TInt KReadBufSize = 10;
       
   851     
       
   852     iDeviceSupportedLanguages.Reset();
       
   853     
       
   854     RFile file;
       
   855     TInt err = file.Open(iFs, KLanguagesIni, EFileRead|EFileShareReadersOnly);
       
   856     if (KErrNone == err)
       
   857         {
       
   858         CleanupClosePushL(file);
       
   859         
       
   860         TFileText reader;
       
   861         reader.Set(file);
       
   862         err = reader.Seek(ESeekStart);
       
   863         if (KErrNone == err)
       
   864             {
       
   865             TBuf<KReadBufSize> readBuf;
       
   866             while(KErrNone == reader.Read(readBuf))
       
   867                 {
       
   868                 if (readBuf.Length() > 0)
       
   869                     {
       
   870                     TLex lex(readBuf);
       
   871                     lex.SkipSpace();
       
   872                     TInt language;
       
   873                     err = lex.Val(language);
       
   874                     if (KErrNone != err)
       
   875                         {
       
   876                         readBuf.Zero();
       
   877                         continue; // Read the next line
       
   878                         }
       
   879                     iDeviceSupportedLanguages.AppendL((TLanguage)language);
       
   880                     }
       
   881                 readBuf.Zero();
       
   882                 }
       
   883             }
       
   884         else
       
   885             {
       
   886             DEBUG_PRINTF3(_L("Reading %S failed with %d"), &KLanguagesIni, err);
       
   887             }
       
   888         
       
   889         CleanupStack::PopAndDestroy(&file);
       
   890         }
       
   891     else
       
   892         {
       
   893         DEBUG_PRINTF3(_L("Opening %S failed with %d"), &KLanguagesIni, err);
       
   894         }
       
   895     
       
   896     // If we are not able fetch the device languages, just parse for the current device language
       
   897     if (0 == iDeviceSupportedLanguages.Count())
       
   898         {
       
   899         iDeviceSupportedLanguages.AppendL(User::Language());
       
   900         }
       
   901     }