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