|
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 } |