|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Java platform 2.0 javarestoreconverter process |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <apacmdln.h> |
|
20 #include <apgcli.h> |
|
21 #include <driveinfo.h> |
|
22 #include <e32base.h> |
|
23 #include <pathinfo.h> |
|
24 #include <utf.h> |
|
25 #include <zipfile.h> |
|
26 |
|
27 #include "restoreconvertmidlet.h" |
|
28 |
|
29 #include "javacommonutils.h" |
|
30 #include "javaprocessconstants.h" |
|
31 #include "javastorage.h" |
|
32 #include "javastorageentry.h" |
|
33 #include "javastoragenames.h" |
|
34 #include "javasymbianoslayer.h" |
|
35 #include "javauids.h" |
|
36 #include "logger.h" |
|
37 |
|
38 |
|
39 using namespace java::storage; |
|
40 using namespace java::util; |
|
41 |
|
42 // MIDlet name and vendor max size is 255, |
|
43 // +1 added for terminating zero needed for logging |
|
44 const TInt KMaxBufferSize = 256; |
|
45 |
|
46 // character constants needed when parsing java attributes |
|
47 const TUint32 HT = 9; // horizontal tab |
|
48 const TUint32 LF = 10; // line feed |
|
49 const TUint32 CR = 13; // carriage return |
|
50 const TUint32 SP = 32; // space |
|
51 const TUint32 COLON = 58; // ':' |
|
52 |
|
53 |
|
54 _LIT(KJarFileNameSuffix, ".jar"); |
|
55 _LIT(KJadFileNameSuffix, ".jad"); |
|
56 _LIT(KFLJarFileNameSuffix, ".dm"); |
|
57 _LIT(KSDJarFileNameSuffix, ".dcf"); |
|
58 _LIT(KSMCBackSplash, "\\"); |
|
59 _LIT(KDriveText, "drive"); |
|
60 _LIT(KMidletName, "MIDlet-Name"); |
|
61 _LIT(KMidletVendor, "MIDlet-Vendor"); |
|
62 _LIT(KManifestEntryName, "META-INF/MANIFEST.MF"); |
|
63 |
|
64 // The directory where the java applications to be converted are searched from |
|
65 _LIT(KMidletSuiteInstallBasePath, ":\\Private\\102033E6\\MIDlets\\"); |
|
66 |
|
67 |
|
68 /** |
|
69 * To create new instance of this class. |
|
70 * |
|
71 * @param aFs - A reference to the file server. |
|
72 * @return Reference to the object of this class. |
|
73 * @exception If construction fails. |
|
74 * |
|
75 */ |
|
76 CRestoreConvertMIDlet* CRestoreConvertMIDlet::NewLC(RFs& aFs) |
|
77 { |
|
78 CRestoreConvertMIDlet* self = new(ELeave) CRestoreConvertMIDlet(aFs); |
|
79 CleanupStack::PushL(self); |
|
80 self->ConstructL(); |
|
81 return self; |
|
82 } |
|
83 |
|
84 /** |
|
85 * To do 1st phase construction for this object. |
|
86 * |
|
87 * Adds this active object to the scheduler. |
|
88 * |
|
89 * @param aFs - A reference to the file server. |
|
90 */ |
|
91 CRestoreConvertMIDlet::CRestoreConvertMIDlet(RFs& aFs) : |
|
92 CActive(EPriorityStandard), iFs(aFs), iNumberOfAppsToInstall(0) |
|
93 { |
|
94 CActiveScheduler::Add(this); |
|
95 } |
|
96 |
|
97 /** |
|
98 * To do 2nd phase construction for this object. |
|
99 * |
|
100 * @exception If the method is not able to allocate necessary buffers. |
|
101 */ |
|
102 void CRestoreConvertMIDlet::ConstructL() |
|
103 { |
|
104 iConvertServer = new(ELeave) RestoreServer(); |
|
105 iMIDletName = HBufC::NewL(KMaxBufferSize); |
|
106 iMIDletVendor = HBufC::NewL(KMaxBufferSize); |
|
107 } |
|
108 |
|
109 /** |
|
110 * Deletes this object. |
|
111 * All allocated resources are released. |
|
112 */ |
|
113 CRestoreConvertMIDlet::~CRestoreConvertMIDlet() |
|
114 { |
|
115 Cancel(); |
|
116 iInstallFiles.ResetAndDestroy(); |
|
117 iInstallFiles.Close(); |
|
118 |
|
119 iUninstallUids.clear(); |
|
120 |
|
121 iDirs.ResetAndDestroy(); |
|
122 iDirs.Close(); |
|
123 |
|
124 iIsJad.Reset(); |
|
125 |
|
126 delete iMIDletName; |
|
127 iMIDletName = NULL; |
|
128 |
|
129 delete iMIDletVendor; |
|
130 iMIDletVendor = NULL; |
|
131 |
|
132 delete iConvertServer; |
|
133 iConvertServer = NULL; |
|
134 } |
|
135 |
|
136 /** |
|
137 * To start silent installation. |
|
138 */ |
|
139 void CRestoreConvertMIDlet::Start() |
|
140 { |
|
141 iState = EFindOutDeviceDrives; |
|
142 CompleteRequest(); |
|
143 } |
|
144 |
|
145 /** |
|
146 * To stop whole preinstaller. |
|
147 * Stops the active scheduler. |
|
148 */ |
|
149 void CRestoreConvertMIDlet::Exit() |
|
150 { |
|
151 Deque(); |
|
152 CActiveScheduler::Stop(); |
|
153 } |
|
154 |
|
155 /** |
|
156 * To complete the request for this object. |
|
157 * |
|
158 * @Postconditions The following conditions are true immediately after |
|
159 * returning from this method. |
|
160 * - iStatus == KErrNone |
|
161 * - IsActive() == ETrue |
|
162 */ |
|
163 void CRestoreConvertMIDlet::CompleteRequest() |
|
164 { |
|
165 TRequestStatus *status = &iStatus; |
|
166 User::RequestComplete(status, KErrNone); |
|
167 if (!IsActive()) |
|
168 { |
|
169 SetActive(); |
|
170 } |
|
171 } |
|
172 |
|
173 /** |
|
174 * To run this active object. |
|
175 * |
|
176 * The state logic is: |
|
177 * |
|
178 * EFindOutDeviceDrives: |
|
179 * - find out all non-remote drives in the device |
|
180 * - mark externally mountable drives (removable drives) |
|
181 * - mark read only drives (ROM) |
|
182 * |
|
183 * EGetDriveToBeScanned: |
|
184 * - the drive to be scanned has been given as command line argument, |
|
185 * store it to iDrive |
|
186 * |
|
187 * EAppsInInstalledDirectories: |
|
188 * - go through all directories in iDirs one by one |
|
189 * and find all java applications in the subdirectories of the directory |
|
190 * - if only .jar/.dcf/.dm file is found it is added to iInstallFiles |
|
191 * - if .jad file is found, it is added to iInstallFiles |
|
192 * |
|
193 * EUninstallFromOMJ: |
|
194 * - uninstall all OMJ java applications in drive iDrive using Java Installer |
|
195 * command line options 'uninstallall -drive=<iDrive>' |
|
196 * - then for each java application in iInstallFiles try to find it from |
|
197 * Java Storage based on MIDlet suite name and vendor name. If the MIDlet |
|
198 * is still installed to OMJ (to some other drive than iDrive), it must |
|
199 * be uninstalled from OMJ to reset the state of MIDlet (RMS data etc) |
|
200 * to original state. The actual uninstallation is not done in this |
|
201 * state, the uids of the applications to be uninstalled are just added to |
|
202 * iUninstallUids in string format |
|
203 * |
|
204 * EExecuteRestoreServer: |
|
205 * - give list of uninstall uids and list of install files to restore server |
|
206 * - start restore server in another thread (it will listen to Comms messages) |
|
207 * - start Java Installer in poll mode |
|
208 * - when Java Installer polls for operations to be executed, the restore server |
|
209 * will first ask it to uninstall each Java application in the list of uninstall uids, |
|
210 * then restore server will ask Java Installer to install each .jad or .jar/.dcf/.dm file |
|
211 * in the list of install files. |
|
212 * Restore server will log whether each uninstallation / installation succeeds. |
|
213 * - after all uninstallations and installations have been done, restore server will ask |
|
214 * Java Installer to exit. |
|
215 * - after that this active object moves to next state. |
|
216 * |
|
217 * EExit: free resources and exit |
|
218 * |
|
219 */ |
|
220 void CRestoreConvertMIDlet::RunL() |
|
221 { |
|
222 switch (iState) |
|
223 { |
|
224 case EFindOutDeviceDrives: |
|
225 { |
|
226 LOG(EJavaConverters, EInfo, |
|
227 "CRestoreConvertMIDlet::RunL EFindOutDeviceDrives"); |
|
228 GetAllDeviceDrivesL(); |
|
229 iState = EGetDriveToBeScanned; |
|
230 CompleteRequest(); |
|
231 } |
|
232 break; |
|
233 |
|
234 case EGetDriveToBeScanned: |
|
235 { |
|
236 LOG(EJavaConverters, EInfo, |
|
237 "CRestoreConvertMIDlet::RunL EGetDriveToBeScanned"); |
|
238 |
|
239 HBufC *pBufCmdLine = HBufC::NewLC(User::CommandLineLength() + 10); |
|
240 TPtr args = pBufCmdLine->Des(); |
|
241 User::CommandLine(args); |
|
242 LOG1WSTR(EJavaConverters, EInfo, |
|
243 "Command line arguments of javarestoreconverter.exe are : %s", |
|
244 (wchar_t *)(args.PtrZ())); |
|
245 |
|
246 // Check which drive is to be restored now from command line. |
|
247 TDriveNumber drive = EDriveC; |
|
248 TInt idx = args.Find(KDriveText()); |
|
249 if (KErrNotFound == idx) |
|
250 { |
|
251 LOG1WSTR(EJavaConverters, EError, |
|
252 "no -drive<X> argument in javarestoreconveter.exe command line (%s)", |
|
253 (wchar_t *)(args.PtrZ())); |
|
254 User::Leave(KErrNotFound); |
|
255 } |
|
256 |
|
257 TChar driveChar = args[idx + KDriveText().Length()]; |
|
258 char argLetter = args[idx + KDriveText().Length()]; |
|
259 if (argLetter >= 'A' && argLetter <= 'J') |
|
260 { |
|
261 drive = (TDriveNumber)(argLetter - 'A'); |
|
262 } |
|
263 else if (argLetter >= 'a' && argLetter <= 'j') |
|
264 { |
|
265 drive = (TDriveNumber)(argLetter - 'a'); |
|
266 } |
|
267 else |
|
268 { |
|
269 User::Leave(KErrArgument); |
|
270 } |
|
271 CleanupStack::PopAndDestroy(pBufCmdLine); |
|
272 iDrive = drive; |
|
273 |
|
274 LOG1(EJavaConverters, EInfo, "Drive is %d", drive); |
|
275 |
|
276 // forget old search directories |
|
277 iDirs.ResetAndDestroy(); |
|
278 |
|
279 // The specified drive will be scanned for |
|
280 // java applications to be converted |
|
281 if (iDriveStatuses[drive] & DriveInfo::EDrivePresent) |
|
282 { |
|
283 (void)iFs.DriveToChar(drive, driveChar); |
|
284 |
|
285 // The base Java application install directory in this |
|
286 // drive must be scanned. |
|
287 // Reserve memory also for drive letter and terminating zero |
|
288 // for logging. |
|
289 HBufC *baseInstallDir = HBufC::NewLC(KMidletSuiteInstallBasePath().Length() + 2); |
|
290 |
|
291 TPtr dirPtr(baseInstallDir->Des()); |
|
292 dirPtr.Append(driveChar); |
|
293 dirPtr.Append(KMidletSuiteInstallBasePath()); |
|
294 |
|
295 // Add new search directory |
|
296 iDirs.AppendL(baseInstallDir); |
|
297 CleanupStack::Pop(baseInstallDir); |
|
298 } |
|
299 else |
|
300 { |
|
301 // Restoring MIDlets to drive X but drive X is not present |
|
302 ELOG1(EJavaConverters, |
|
303 "javarestoreconverter.exe: Drive number %d is not present", drive); |
|
304 User::Leave(KErrDisMounted); |
|
305 } |
|
306 |
|
307 iState = EAppsInInstalledDirectories; |
|
308 CompleteRequest(); |
|
309 } |
|
310 break; |
|
311 |
|
312 case EAppsInInstalledDirectories: |
|
313 { |
|
314 LOG(EJavaConverters, EInfo, |
|
315 "CRestoreConvertMIDlet::RunL EAppsInInstalledDirectories"); |
|
316 |
|
317 GetInstallFilesL(iDirs); |
|
318 |
|
319 |
|
320 iState = EUninstallFromOMJ; |
|
321 CompleteRequest(); |
|
322 } |
|
323 break; |
|
324 |
|
325 case EUninstallFromOMJ: |
|
326 { |
|
327 LOG(EJavaConverters, EInfo, |
|
328 "CRestoreConvertMIDlet::RunL EUninstallFromOMJ"); |
|
329 |
|
330 // Uninstall all Java applications in current drive |
|
331 UninstallAllFromDriveL(iDrive); |
|
332 |
|
333 // Check all Jad / Jar files in iInstallFiles and |
|
334 // add the Uids of those MIDlets still installed into OMJ |
|
335 // to iUninstallUids |
|
336 FindRemainingMIDletsToBeUninstalledL(); |
|
337 |
|
338 iState = EExecuteRestoreServer; |
|
339 CompleteRequest(); |
|
340 } |
|
341 break; |
|
342 |
|
343 case EExecuteRestoreServer: |
|
344 { |
|
345 LOG(EJavaConverters, EInfo, |
|
346 "CRestoreConvertMIDlet::RunL EExecuteRestoreServer"); |
|
347 |
|
348 if (iNumberOfAppsToInstall > 0) |
|
349 { |
|
350 // Uninstall all MIDlet suites in iUninstallUids and then |
|
351 // install all MIDlet suites in iInstallFiles. |
|
352 |
|
353 // Tell RestoreServer what should be uninstalled and what |
|
354 // should be converted |
|
355 iConvertServer->setOperations(iInstallFiles, iUninstallUids); |
|
356 |
|
357 // Start the server |
|
358 int err = iConvertServer->start(); |
|
359 if (0 != err) |
|
360 { |
|
361 // server cannot be started |
|
362 ELOG1(EJavaConverters, |
|
363 "Cannot start convert server, err %d", err); |
|
364 } |
|
365 |
|
366 // Starts Java Installer, waits until Java Installer exits |
|
367 RunJavaInstallerL(); |
|
368 |
|
369 iState = EExit; |
|
370 } |
|
371 else |
|
372 { |
|
373 iState = EExit; |
|
374 CompleteRequest(); |
|
375 } |
|
376 } |
|
377 break; |
|
378 |
|
379 case EExit: |
|
380 { |
|
381 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::RunL EExit"); |
|
382 |
|
383 // Stops the server if it is running |
|
384 iConvertServer->stop(); |
|
385 |
|
386 FullCleanup(); |
|
387 |
|
388 // The whole javaappconverter process is stopped. |
|
389 Exit(); |
|
390 } |
|
391 break; |
|
392 } |
|
393 } |
|
394 |
|
395 /** |
|
396 * To handle leave from RunL. |
|
397 * This method exits this active object using normal state machine |
|
398 * After calling this method this active object will exit. |
|
399 * |
|
400 * @param aError - A reason of error. |
|
401 * @return KErrNone. |
|
402 */ |
|
403 TInt CRestoreConvertMIDlet::RunError(TInt aError) |
|
404 { |
|
405 ELOG2(EJavaConverters, |
|
406 "CRestoreConvertMIDlet::RunError(%d) from state %d", aError, iState); |
|
407 |
|
408 Cancel(); |
|
409 |
|
410 iState = EExit; |
|
411 CompleteRequest(); |
|
412 |
|
413 return KErrNone; |
|
414 } |
|
415 |
|
416 /** |
|
417 * To do cancelling for this object. |
|
418 * |
|
419 */ |
|
420 void CRestoreConvertMIDlet::DoCancel() |
|
421 { |
|
422 ELOG1(EJavaConverters, |
|
423 "CRestoreConvertMIDlet::DoCancel from state %d", iState); |
|
424 |
|
425 // Check whether restore server must be stopped |
|
426 if (iState == EExecuteRestoreServer) |
|
427 { |
|
428 // Stops the server if it is running |
|
429 iConvertServer->stop(); |
|
430 } |
|
431 } |
|
432 |
|
433 /** |
|
434 * Add .jad files in the directories specified in aDirs to iInstallFiles. |
|
435 * If a directory does not contain a .jad file but it contains a .jar/.dcf/.dm file, |
|
436 * add that file to iInstallFiles |
|
437 * |
|
438 * @param aDirs - An array of directories to be scanned. |
|
439 * @exception Unable to alloc memory for the internal buffers. |
|
440 * @exception Unable to get directory's contents. |
|
441 */ |
|
442 void CRestoreConvertMIDlet::GetInstallFilesL(RPointerArray<HBufC>& aDirs) |
|
443 { |
|
444 // Number of MIDlet installation base directories to scan, |
|
445 // one directory per local drive |
|
446 const TInt nBaseDirs = aDirs.Count(); |
|
447 |
|
448 for (TInt i = 0; i < nBaseDirs; i++) |
|
449 { |
|
450 TFileName suitePath; |
|
451 |
|
452 // Form base directory path, MIDlets have been installed |
|
453 // to subdirectories of this directory |
|
454 const TPtrC& dir = ((HBufC *)(aDirs[i]))->Des(); |
|
455 TFileName baseSuitePath = dir; |
|
456 |
|
457 CDir *entryList; |
|
458 CDir *dirList; |
|
459 TInt err = iFs.GetDir(baseSuitePath, KEntryAttMatchMask, ESortNone, entryList, dirList); |
|
460 if (KErrNone != err) |
|
461 { |
|
462 WLOG1WSTR(EJavaConverters, |
|
463 "CRestoreConvertMIDlet::GetInstallFilesL Cannot list directory %s", |
|
464 (wchar_t *)(baseSuitePath.PtrZ())); |
|
465 |
|
466 // If no S60 Java application has been installed to the drive, |
|
467 // the directory does not exist but it is OK |
|
468 if (KErrPathNotFound != err) |
|
469 { |
|
470 User::Leave(err); |
|
471 } |
|
472 continue; |
|
473 } |
|
474 |
|
475 // Only midlet installation directory entries are meaningfull, |
|
476 // discard other possible entries |
|
477 delete entryList; |
|
478 |
|
479 TInt nCount = dirList->Count(); |
|
480 TEntry dirEntry; |
|
481 |
|
482 for (TInt nInd = 0; nInd < nCount; nInd++) |
|
483 { |
|
484 dirEntry = (*dirList)[nInd]; |
|
485 // Just to make sure this really is subdirectory |
|
486 if (dirEntry.IsDir()) |
|
487 { |
|
488 // Is this midlet suite subdir? |
|
489 // Midlet suite subdirs look like this "[102b567B]" |
|
490 // Must parse the value of the Uid as unsigned int to avoid |
|
491 // overflow |
|
492 TUint32 nUid; |
|
493 TLex lexer(dirEntry.iName); |
|
494 lexer.Inc(); |
|
495 err = lexer.Val(nUid, EHex); |
|
496 if (KErrNone != err) |
|
497 { |
|
498 // Not midlet suite subdir, skip it |
|
499 continue; |
|
500 } |
|
501 |
|
502 // Does the subdirectory contain any Jar files? |
|
503 suitePath = baseSuitePath; |
|
504 suitePath.Append(dirEntry.iName); |
|
505 suitePath.Append(KSMCBackSplash); |
|
506 |
|
507 CDir *suiteDirEntryList; |
|
508 err = iFs.GetDir(suitePath, KEntryAttMatchMask, ESortNone, suiteDirEntryList); |
|
509 if (KErrNone != err) |
|
510 { |
|
511 LOG1WSTR(EJavaConverters, EError, |
|
512 "CRestoreConvertMIDlet::GetInstallFilesL Cannot list content of suite dir %s", |
|
513 (wchar_t *)(suitePath.PtrZ())); |
|
514 User::Leave(err); |
|
515 return; |
|
516 } |
|
517 // If there is .jad or Jar file in suiteDirEntryList, adds |
|
518 // it to iInstallFiles. |
|
519 // Recognizes also DRM protected Jar files (.dm, .dcf) |
|
520 AddJadJarToInstallFilesL(suitePath, suiteDirEntryList); |
|
521 delete suiteDirEntryList; |
|
522 } |
|
523 } // for - loop all directory entries in a base installation directories |
|
524 delete dirList; |
|
525 |
|
526 } // for - loop all base installation directories |
|
527 |
|
528 if (iInstallFiles.Count() == 0) |
|
529 { |
|
530 WLOG(EJavaConverters, |
|
531 "CRestoreConvertMIDlet::GetInstallFilesL No MIDlets to convert"); |
|
532 } |
|
533 |
|
534 // how many applications to restore |
|
535 iNumberOfAppsToInstall = iInstallFiles.Count(); |
|
536 } |
|
537 |
|
538 /** |
|
539 * For each java application in iInstallFiles try to find it from |
|
540 * Java Storage based on MIDlet suite name and vendor name. If the MIDlet |
|
541 * is still installed to OMJ (to some other drive than iDrive), it must |
|
542 * be uninstalled from OMJ to reset the state of MIDlet (RMS data etc) |
|
543 * to original state. Add the uids of the applications to be uninstalled |
|
544 * to iUninstallUids in string format |
|
545 */ |
|
546 void CRestoreConvertMIDlet::FindRemainingMIDletsToBeUninstalledL() |
|
547 { |
|
548 TBool namesParsed; |
|
549 for (TInt nInd = 0; nInd < iNumberOfAppsToInstall; nInd++) |
|
550 { |
|
551 // Get the MIDlet-Name and MIDlet-Vendor from iInstallFiles[nInd] |
|
552 if (iIsJad[nInd] == 1) |
|
553 { |
|
554 namesParsed = ParseJadL(*iInstallFiles[nInd]); |
|
555 } |
|
556 else |
|
557 { |
|
558 // If file is .jar file, get the names from Manifest |
|
559 namesParsed = ParseJarL(*iInstallFiles[nInd]); |
|
560 } |
|
561 |
|
562 // Search for the MIDlet suite from Java Storage table APPLICATION_PACKAGE_TABLE |
|
563 // If it is found, add the suite Uid in string format to iUninstallUids |
|
564 if (namesParsed) |
|
565 { |
|
566 TPtr suite = iMIDletName->Des(); |
|
567 TPtr vendor = iMIDletVendor->Des(); |
|
568 std::wstring suiteUid = IsSuiteInstalled(suite, vendor); |
|
569 if (!suiteUid.empty()) |
|
570 { |
|
571 iUninstallUids.push_back(suiteUid); |
|
572 } |
|
573 } |
|
574 } |
|
575 } |
|
576 |
|
577 /** |
|
578 * Parse MIDlet-Name and MIDlet-Vendor parameters from JAD file. |
|
579 * Parameters are stored to iMIDletName and iMIDletVendor |
|
580 * |
|
581 * @param ETrue if parsing succeeds otherwise EFalse. |
|
582 */ |
|
583 TBool CRestoreConvertMIDlet::ParseJadL(const TDesC& aJadFileName) |
|
584 { |
|
585 HBufC *jadContent = NULL; |
|
586 // Trap leave thrown if reading jad content fails |
|
587 TRAPD(err, jadContent = GetJadContentL(aJadFileName)); |
|
588 if (KErrNone != err) |
|
589 { |
|
590 ELOG1(EJavaConverters, |
|
591 "CRestoreConvertMIDlet::ParseJadL Reading Jad content failed, error %d", |
|
592 err); |
|
593 return EFalse; |
|
594 } |
|
595 CleanupStack::PushL(jadContent); |
|
596 |
|
597 HBufC *midletName = ParseAttribute(jadContent, KMidletName); |
|
598 if (NULL == midletName) |
|
599 { |
|
600 ELOG(EJavaConverters, |
|
601 "CRestoreConvertMIDlet::ParseJadL Parsing midlet name failed."); |
|
602 CleanupStack::PopAndDestroy(jadContent); |
|
603 return EFalse; |
|
604 } |
|
605 // store midlet name to member variable and log it |
|
606 TPtr namePtr(iMIDletName->Des()); |
|
607 namePtr.Copy(*midletName); |
|
608 LOG1WSTR(EJavaConverters, EInfo, |
|
609 "CRestoreConvertMIDlet::ParseJadL MIDlet-Name %s", |
|
610 (wchar_t *)(namePtr.PtrZ())); |
|
611 delete midletName; |
|
612 |
|
613 HBufC *midletVendor = ParseAttribute(jadContent, KMidletVendor); |
|
614 if (NULL == midletVendor) |
|
615 { |
|
616 ELOG(EJavaConverters, |
|
617 "CRestoreConvertMIDlet::ParseJadL Parsing midlet vendor failed."); |
|
618 CleanupStack::PopAndDestroy(jadContent); |
|
619 return EFalse; |
|
620 } |
|
621 // store midlet vendor to member variable and log it |
|
622 TPtr vendorPtr(iMIDletVendor->Des()); |
|
623 vendorPtr.Copy(*midletVendor); |
|
624 LOG1WSTR(EJavaConverters, EInfo, |
|
625 "CRestoreConvertMIDlet::ParseJadL MIDlet-Vendor %s", |
|
626 (wchar_t *)(vendorPtr.PtrZ())); |
|
627 delete midletVendor; |
|
628 |
|
629 CleanupStack::PopAndDestroy(jadContent); |
|
630 return ETrue; |
|
631 } |
|
632 |
|
633 |
|
634 /** |
|
635 * Reads the whole content of the Jad file and returns it in |
|
636 * buffer in Symbian Unicode character set. |
|
637 * @param[in] aJadFile |
|
638 * @return pointer to HBufC that contains the Jad file, |
|
639 * ownership is transferred to caller |
|
640 * @exception If jad file content cannot be read |
|
641 */ |
|
642 HBufC *CRestoreConvertMIDlet::GetJadContentL(const TDesC& aJadFileName) |
|
643 { |
|
644 RFile jadFile; |
|
645 TInt err = jadFile.Open(iFs, aJadFileName, EFileRead); |
|
646 User::LeaveIfError(err); |
|
647 CleanupClosePushL(jadFile); |
|
648 |
|
649 // Reserve buffer for Jad in UTF-8 char set |
|
650 TInt jadSize = 0; |
|
651 err = jadFile.Size(jadSize); |
|
652 User::LeaveIfError(err); |
|
653 HBufC8 *bufUtf8Jad = HBufC8::NewL(jadSize); |
|
654 CleanupStack::PushL(bufUtf8Jad); |
|
655 |
|
656 // Read the content in Utf8 char set |
|
657 TPtr8 tmpPtr(bufUtf8Jad->Des()); |
|
658 err = jadFile.Read(tmpPtr, jadSize); |
|
659 User::LeaveIfError(err); |
|
660 |
|
661 // Convert to Unicode |
|
662 HBufC *bufUnicodeJad = |
|
663 CnvUtfConverter::ConvertToUnicodeFromUtf8L(*bufUtf8Jad); |
|
664 |
|
665 CleanupStack::PopAndDestroy(bufUtf8Jad); |
|
666 CleanupStack::PopAndDestroy(&jadFile); |
|
667 |
|
668 // Return to caller |
|
669 return bufUnicodeJad; |
|
670 } |
|
671 |
|
672 |
|
673 /** |
|
674 * Parse MIDlet-Name and MIDlet-Vendor parameters from Manifest inside |
|
675 * a .jar file. |
|
676 * Parameters are stored to iMIDletName and iMIDletVendor |
|
677 * |
|
678 * @param ETrue if parsing succeeds otherwise EFalse. |
|
679 */ |
|
680 TBool CRestoreConvertMIDlet::ParseJarL(const TDesC& aJarFileName) |
|
681 { |
|
682 HBufC *manifestContent = NULL; |
|
683 // Trap leave thrown if reading Manifest content fails |
|
684 TRAPD(err, manifestContent = GetManifestContentL(aJarFileName)); |
|
685 if (KErrNone != err) |
|
686 { |
|
687 ELOG1(EJavaConverters, |
|
688 "CRestoreConvertMIDlet::ParseJarL Reading Manifest failed, error %d", |
|
689 err); |
|
690 return EFalse; |
|
691 } |
|
692 CleanupStack::PushL(manifestContent); |
|
693 |
|
694 HBufC *midletName = ParseAttribute(manifestContent, KMidletName); |
|
695 if (NULL == midletName) |
|
696 { |
|
697 ELOG(EJavaConverters, |
|
698 "CRestoreConvertMIDlet::ParseJarL Parsing midlet name failed."); |
|
699 CleanupStack::PopAndDestroy(manifestContent); |
|
700 return EFalse; |
|
701 } |
|
702 // store midlet name to member variable and log it |
|
703 TPtr namePtr(iMIDletName->Des()); |
|
704 namePtr.Copy(*midletName); |
|
705 LOG1WSTR(EJavaConverters, EInfo, |
|
706 "CRestoreConvertMIDlet::ParseJarL MIDlet-Name %s", |
|
707 (wchar_t *)(namePtr.PtrZ())); |
|
708 delete midletName; |
|
709 |
|
710 HBufC *midletVendor = ParseAttribute(manifestContent, KMidletVendor); |
|
711 if (NULL == midletVendor) |
|
712 { |
|
713 ELOG(EJavaConverters, |
|
714 "CRestoreConvertMIDlet::ParseJarL Parsing midlet vendor failed."); |
|
715 CleanupStack::PopAndDestroy(manifestContent); |
|
716 return EFalse; |
|
717 } |
|
718 // store midlet vendor to member variable and log it |
|
719 TPtr vendorPtr(iMIDletVendor->Des()); |
|
720 vendorPtr.Copy(*midletVendor); |
|
721 LOG1WSTR(EJavaConverters, EInfo, |
|
722 "CRestoreConvertMIDlet::ParseJarL MIDlet-Vendor %s", |
|
723 (wchar_t *)(vendorPtr.PtrZ())); |
|
724 delete midletVendor; |
|
725 |
|
726 CleanupStack::PopAndDestroy(manifestContent); |
|
727 return ETrue; |
|
728 } |
|
729 |
|
730 |
|
731 /** |
|
732 * Reads the whole content of the Manifest inside Jar file |
|
733 * and returns it in buffer in Symbian Unicode character set. |
|
734 * @param[in] aJarFile |
|
735 * @return pointer to HBufC that contains the Manifest, |
|
736 * ownership is transferred to caller |
|
737 * @exception If Manifest content cannot be read |
|
738 */ |
|
739 HBufC *CRestoreConvertMIDlet::GetManifestContentL(const TDesC& aJarFileName) |
|
740 { |
|
741 CZipFile* zipFile = CZipFile::NewL(iFs, aJarFileName); |
|
742 CleanupStack::PushL(zipFile); |
|
743 |
|
744 // Seek manifest file |
|
745 CZipFileMember* zippedFile = |
|
746 zipFile->CaseSensitiveOrCaseInsensitiveMemberL(KManifestEntryName()); |
|
747 if (!zippedFile) |
|
748 { |
|
749 ELOG(EJavaConverters, |
|
750 "CRestoreConvertMIDlet::GetManifestContentL Package is missing manifest"); |
|
751 User::Leave(KErrNotFound); |
|
752 } |
|
753 CleanupStack::PushL(zippedFile); |
|
754 |
|
755 TUint uncompressedSize = zippedFile->UncompressedSize(); |
|
756 if ((TUint)uncompressedSize >= (KMaxTInt/2)) |
|
757 { |
|
758 ELOG(EJavaConverters, "CRestoreConvertMIDlet::GetManifestContentL Invalid manifest"); |
|
759 User::Leave(KErrCorrupt); |
|
760 } |
|
761 |
|
762 // Buffer to read Manifest into |
|
763 HBufC8* resultData = HBufC8::NewLC(uncompressedSize); |
|
764 |
|
765 RZipFileMemberReaderStream* zippedStream = 0; |
|
766 TInt err = zipFile->GetInputStreamL(zippedFile, zippedStream); |
|
767 User::LeaveIfError(err); |
|
768 CleanupStack::PushL(zippedStream); |
|
769 |
|
770 TPtr8 ptr(resultData->Des()); |
|
771 User::LeaveIfError(zippedStream->Read(ptr, uncompressedSize)); |
|
772 |
|
773 CleanupStack::PopAndDestroy(zippedStream); |
|
774 |
|
775 // Manifest buffer when converted to UCS-2 |
|
776 HBufC *manifestContent = HBufC16::NewL(uncompressedSize); |
|
777 TPtr16 ucsPtr(manifestContent->Des()); |
|
778 err = CnvUtfConverter::ConvertToUnicodeFromUtf8(ucsPtr, ptr); |
|
779 if (KErrNone != err) |
|
780 { |
|
781 ELOG1(EJavaConverters, |
|
782 "CRestoreConvertMIDlet::GetManifestContentL UTF-8 to unicode" |
|
783 " conversion failed: %d", err); |
|
784 User::Leave(err); |
|
785 } |
|
786 CleanupStack::PopAndDestroy(resultData); |
|
787 CleanupStack::PopAndDestroy(zippedFile); |
|
788 CleanupStack::PopAndDestroy(zipFile); |
|
789 |
|
790 // Return to caller |
|
791 return manifestContent; |
|
792 } |
|
793 |
|
794 |
|
795 std::wstring CRestoreConvertMIDlet::IsSuiteInstalled(TPtr& aSuiteName, TPtr& aVendorName) |
|
796 { |
|
797 std::wstring suiteName(desToWstring(aSuiteName)); |
|
798 std::wstring vendorName(desToWstring(aVendorName)); |
|
799 std::wstring suiteUid; |
|
800 |
|
801 // Find application uid based on names from Java Storage |
|
802 JavaStorage *js = JavaStorage::createInstance(); |
|
803 |
|
804 try |
|
805 { |
|
806 js->open(JAVA_DATABASE_NAME); |
|
807 |
|
808 JavaStorageEntry attribute; |
|
809 JavaStorageApplicationEntry_t findPattern; |
|
810 JavaStorageApplicationList_t foundEntries; |
|
811 |
|
812 // Get ID from APPLICATION_PACKAGE_TABLE based on PACKAGE_NAME and VENDOR |
|
813 attribute.setEntry(PACKAGE_NAME, suiteName); |
|
814 findPattern.insert(attribute); |
|
815 attribute.setEntry(VENDOR, vendorName); |
|
816 findPattern.insert(attribute); |
|
817 attribute.setEntry(ID, L""); |
|
818 findPattern.insert(attribute); |
|
819 |
|
820 js->search(APPLICATION_PACKAGE_TABLE , findPattern, foundEntries); |
|
821 |
|
822 // Anything found? |
|
823 if (foundEntries.size() > 0) |
|
824 { |
|
825 // The application package has been found, get the ID of the package |
|
826 suiteUid = foundEntries.front().begin()->entryValue(); |
|
827 LOG1WSTR(EJavaConverters, EInfo, |
|
828 "CRestoreConvertMIDlet::IsSuiteInstalled: Found suite by name. Uid is %s", |
|
829 suiteUid.c_str()); |
|
830 } |
|
831 } |
|
832 catch (JavaStorageException& e) |
|
833 { |
|
834 ELOG1(EJavaConverters, |
|
835 "CRestoreConvertMIDlet::IsSuiteInstalled: Java Storage exception %s", e.what()); |
|
836 } |
|
837 |
|
838 try |
|
839 { |
|
840 js->close(); |
|
841 } |
|
842 catch (JavaStorageException& e2) |
|
843 { |
|
844 WLOG1(EJavaConverters, |
|
845 "CRestoreConvertMIDlet::IsSuiteInstalled: Java Storage exception " |
|
846 "when closing storage %s", e2.what()); |
|
847 } |
|
848 |
|
849 delete js; |
|
850 |
|
851 // suiteUid is empty if suite was not found |
|
852 return suiteUid; |
|
853 } |
|
854 |
|
855 |
|
856 /** |
|
857 * Finds the java attribute specified by aAttributeName |
|
858 * from aBuf and returns the value of that attribute |
|
859 * in HBufC. |
|
860 * @param[in] aBuf contents of .jad / Manifest file |
|
861 * @param[in] aAttributeName the name of a java attribute |
|
862 * @return the value of the attribute. Caller gets the ownership of the |
|
863 * returned HBufC. |
|
864 * If the attribute is not found, returns NULL |
|
865 */ |
|
866 HBufC *CRestoreConvertMIDlet::ParseAttribute(const HBufC *aBuf, const TDesC& aAttributeName) |
|
867 { |
|
868 TInt nInd(0); |
|
869 TBool fullNameFound(EFalse); |
|
870 TUint32 ch; |
|
871 |
|
872 // Start parsing from the beginning |
|
873 TPtrC parsePtr = aBuf->Mid(nInd); |
|
874 |
|
875 do |
|
876 { |
|
877 // Find attribute name |
|
878 nInd = parsePtr.Find(aAttributeName); |
|
879 if (nInd < 0) |
|
880 { |
|
881 // Returns NULL if the attribute cannot be found |
|
882 return NULL; |
|
883 } |
|
884 |
|
885 // Check that the attribute name was preceded by line break or |
|
886 // it was at the beginning |
|
887 if (nInd == 0) |
|
888 { |
|
889 fullNameFound = ETrue; |
|
890 } |
|
891 else |
|
892 { |
|
893 ch = parsePtr[nInd-1]; |
|
894 if ((ch == CR) || (ch == LF)) |
|
895 { |
|
896 fullNameFound = ETrue; |
|
897 } |
|
898 else |
|
899 { |
|
900 // Name was just a part of longer string (not 'word match') |
|
901 fullNameFound = EFalse; |
|
902 // Skip to the last character of the found match. |
|
903 // We can skip because we are insterested only in 'word' matches |
|
904 // so the next cannot start inside the area we are skipping now. |
|
905 parsePtr.Set(parsePtr.Mid(nInd + aAttributeName.Length() - 1)); |
|
906 continue; |
|
907 } |
|
908 } |
|
909 |
|
910 // Check whether buffer ends after attribute name |
|
911 if (nInd + aAttributeName.Length() >= parsePtr.Length()) |
|
912 { |
|
913 // Buffer ends immediately after the found |
|
914 // attribute name instance. No attribute value |
|
915 return NULL; |
|
916 } |
|
917 |
|
918 // Check that there is a white space character or colon after |
|
919 // attribute name |
|
920 ch = parsePtr[nInd + aAttributeName.Length()]; |
|
921 if ((ch == COLON) || (ch == SP) || (ch == HT)) |
|
922 { |
|
923 fullNameFound = ETrue; |
|
924 } |
|
925 else |
|
926 { |
|
927 // Name was just a part of longer string (not 'word match') |
|
928 fullNameFound = EFalse; |
|
929 // Skip to the next character after the found match |
|
930 parsePtr.Set(parsePtr.Mid(nInd + aAttributeName.Length())); |
|
931 continue; |
|
932 } |
|
933 } |
|
934 while (!fullNameFound); |
|
935 |
|
936 // Skip to the end of the attribute name and find ':' after the name. |
|
937 // The skipped characters must be white space chacraters, otherwise |
|
938 // the attribute name is illegal and Java Installer will not accept |
|
939 // the Jad file / Manifest. |
|
940 parsePtr.Set(parsePtr.Mid(nInd + aAttributeName.Length() - 1)); |
|
941 nInd = parsePtr.Locate(COLON); |
|
942 if (nInd < 0) |
|
943 { |
|
944 return NULL; |
|
945 } |
|
946 nInd++; |
|
947 |
|
948 // Parse attribute value (CR or LF ends) |
|
949 TInt nEndInd = parsePtr.Locate(CR); |
|
950 TInt nTmpInd = parsePtr.Locate(LF); |
|
951 |
|
952 if (KErrNotFound == nEndInd) |
|
953 { |
|
954 nEndInd = parsePtr.Length() - 1; |
|
955 } |
|
956 if (KErrNotFound == nTmpInd) |
|
957 { |
|
958 nTmpInd = parsePtr.Length() - 1; |
|
959 } |
|
960 |
|
961 if (nTmpInd < nEndInd) |
|
962 { |
|
963 nEndInd = nTmpInd; |
|
964 } |
|
965 |
|
966 if (nEndInd < nInd) |
|
967 { |
|
968 return NULL; |
|
969 } |
|
970 |
|
971 TPtrC attributeValue = parsePtr.Mid(nInd, (nEndInd - nInd)); |
|
972 |
|
973 // Remove possible white space from the beginning and end of the value |
|
974 HBufC *bufValue = attributeValue.Alloc(); |
|
975 if (NULL == bufValue) |
|
976 { |
|
977 return NULL; |
|
978 } |
|
979 TPtr value = bufValue->Des(); |
|
980 value.Trim(); |
|
981 |
|
982 return bufValue; |
|
983 } // parseAttribute |
|
984 |
|
985 |
|
986 /** |
|
987 * Uninstall all Java 2.x MIDlets from drive given in aDrive |
|
988 * |
|
989 * @param aDrive uninstallation drive |
|
990 */ |
|
991 void CRestoreConvertMIDlet::UninstallAllFromDriveL(TDriveNumber &aDrive) |
|
992 { |
|
993 // Execute Java Installer with uninstallall -drive=X command line options |
|
994 |
|
995 LOG1(EJavaConverters, EInfo, |
|
996 "CRestoreConvertMIDlet::UninstallAllFromDriveL Going to uninstall " |
|
997 "MIDlets from drive number %d", aDrive); |
|
998 |
|
999 RProcess rJavaInstaller; |
|
1000 TBuf<256> commandLine; |
|
1001 |
|
1002 // Build command line used to pass all necessary info to Java Installer |
|
1003 commandLine = _L("javainstallerstarter"); |
|
1004 commandLine.Append(_L(" uninstallall -forceuninstall -captainmsgs=no")); |
|
1005 |
|
1006 // Run installer silently, do not send uninstall notification messages |
|
1007 commandLine.Append(_L(" -silent -skipotastatus -drive=")); |
|
1008 |
|
1009 // Add drive letter |
|
1010 commandLine.Append((TChar)('A' + aDrive)); |
|
1011 |
|
1012 // start JavaInstaller |
|
1013 #ifdef RD_JAVA_S60_RELEASE_5_0_IAD |
|
1014 TBuf<128> processName = _L("j9midps60"); |
|
1015 #else // RD_JAVA_S60_RELEASE_5_0_IAD |
|
1016 TBuf<128> processName = _L("javamidp"); |
|
1017 #endif // RD_JAVA_S60_RELEASE_5_0_IAD |
|
1018 |
|
1019 TInt err = rJavaInstaller.Create(processName, commandLine); |
|
1020 if (KErrNone == err) |
|
1021 { |
|
1022 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::UninstallAllFromDriveL calling Rendezvous"); |
|
1023 // This call will wait until Java Installer exits (or panics) |
|
1024 TRequestStatus status; |
|
1025 rJavaInstaller.Logon(status); |
|
1026 |
|
1027 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::UninstallAllFromDriveL calling Resume"); |
|
1028 rJavaInstaller.Resume(); |
|
1029 |
|
1030 // now wait until Java Installer exits |
|
1031 User::WaitForRequest(status); |
|
1032 if (status.Int() != KErrNone) |
|
1033 { |
|
1034 ELOG1(EJavaConverters, |
|
1035 "CRestoreConvertMIDlet::UninstallAllFromDriveL Installer exited with error %d", |
|
1036 status.Int()); |
|
1037 } |
|
1038 } |
|
1039 else |
|
1040 { |
|
1041 ELOG1(EJavaConverters, |
|
1042 "CRestoreConvertMIDlet::UninstallAllFromDriveL Cannot start Installer, error %d", err); |
|
1043 } |
|
1044 |
|
1045 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::UninstallAllFromDriveL calling RProcess::Close"); |
|
1046 // free resources before returning |
|
1047 rJavaInstaller.Close(); |
|
1048 } |
|
1049 |
|
1050 |
|
1051 /** |
|
1052 * Scan the content of one directory entry and add the name of |
|
1053 * .jad / .jar /.dcf/.dm file to iInstallFiles if |
|
1054 * the directory contains a valid, installed Java application. |
|
1055 * Recognizes also DRM protected jar files (.dm, .dcf) |
|
1056 * |
|
1057 * @param aSuitePathName - directory to be scanned. |
|
1058 * @param aSuiteDirEntryList - contents of the directory |
|
1059 * @exception Unable to alloc memory for the internal buffers. |
|
1060 */ |
|
1061 void CRestoreConvertMIDlet::AddJadJarToInstallFilesL( |
|
1062 const TFileName &aSuitePathName, |
|
1063 const CDir *aSuiteDirEntryList) |
|
1064 { |
|
1065 if (NULL == aSuiteDirEntryList) |
|
1066 { |
|
1067 return; |
|
1068 } |
|
1069 |
|
1070 TInt nCount = aSuiteDirEntryList->Count(); |
|
1071 if (0 == nCount) |
|
1072 { |
|
1073 return; |
|
1074 } |
|
1075 |
|
1076 TInt suffixPos; |
|
1077 TEntry dirEntry; |
|
1078 TBool jarFileInSuiteDir = EFalse; |
|
1079 TBool jadFileInSuiteDir = EFalse; |
|
1080 TFileName jadFullPathName; |
|
1081 TFileName jarFullPathName; |
|
1082 |
|
1083 for (TInt nInd = 0; nInd < nCount; nInd++) |
|
1084 { |
|
1085 dirEntry = (*aSuiteDirEntryList)[nInd]; |
|
1086 // Directory cannot be Jar file. |
|
1087 // Empty file cannot valid Jar file |
|
1088 if (dirEntry.IsDir() || (dirEntry.iSize == 0)) |
|
1089 { |
|
1090 continue; |
|
1091 } |
|
1092 // get the suffix of the name |
|
1093 suffixPos = dirEntry.iName.LocateReverse('.'); |
|
1094 if (suffixPos == KErrNotFound) |
|
1095 { |
|
1096 // File name does not contain '.' char |
|
1097 continue; |
|
1098 } |
|
1099 TPtrC suffix(dirEntry.iName.Mid(suffixPos)); |
|
1100 |
|
1101 // if the name ends with ".jar" the name is current candidate |
|
1102 // for the name to be added to iInstallFiles list |
|
1103 if (suffix.CompareF(KJarFileNameSuffix) == 0) |
|
1104 { |
|
1105 jarFullPathName = aSuitePathName; |
|
1106 jarFullPathName.Append(dirEntry.iName); |
|
1107 jarFileInSuiteDir = ETrue; |
|
1108 } |
|
1109 else if (suffix.CompareF(KJadFileNameSuffix) == 0) |
|
1110 { |
|
1111 // If .jad file is found, then it will be added |
|
1112 // to iInstallFiles list |
|
1113 jadFullPathName = aSuitePathName; |
|
1114 jadFullPathName.Append(dirEntry.iName); |
|
1115 jadFileInSuiteDir = ETrue; |
|
1116 } |
|
1117 else if (suffix.CompareF(KFLJarFileNameSuffix) == 0) |
|
1118 { |
|
1119 // forward locked and combined delivery DRM protected |
|
1120 // .jar files have suffix ".dm" |
|
1121 jarFullPathName = aSuitePathName; |
|
1122 jarFullPathName.Append(dirEntry.iName); |
|
1123 jarFileInSuiteDir = ETrue; |
|
1124 } |
|
1125 else if (suffix.CompareF(KSDJarFileNameSuffix) == 0) |
|
1126 { |
|
1127 // separate delivery DRM protected .jar files have suffix ".dcf" |
|
1128 jarFullPathName = aSuitePathName; |
|
1129 jarFullPathName.Append(dirEntry.iName); |
|
1130 jarFileInSuiteDir = ETrue; |
|
1131 } |
|
1132 } |
|
1133 |
|
1134 // If directory contains a Jar file, then add something to iInstallFiles |
|
1135 if (jarFileInSuiteDir) |
|
1136 { |
|
1137 // If directory contains also .jad file, add .jad file name to iInstallFiles |
|
1138 if (jadFileInSuiteDir) |
|
1139 { |
|
1140 // Reserve one char for null terminator |
|
1141 HBufC* path = HBufC::NewLC(jadFullPathName.Length() + 1); |
|
1142 TPtr pathPtr(path->Des()); |
|
1143 pathPtr.Append(jadFullPathName); |
|
1144 |
|
1145 LOG1WSTR(EJavaConverters, EInfo, |
|
1146 "CRestoreConvertMIDlet::AddJadJarToInstallFilesL Adding jad file %s", |
|
1147 (wchar_t *)(pathPtr.PtrZ())); |
|
1148 iInstallFiles.Append(path); |
|
1149 CleanupStack::Pop(path); |
|
1150 iIsJad.AppendL(1); |
|
1151 } |
|
1152 else |
|
1153 { |
|
1154 // Reserve one char for null terminator |
|
1155 HBufC* path = HBufC::NewLC(jarFullPathName.Length() + 1); |
|
1156 TPtr pathPtr(path->Des()); |
|
1157 pathPtr.Append(jarFullPathName); |
|
1158 |
|
1159 LOG1WSTR(EJavaConverters, EInfo, |
|
1160 "CRestoreConvertMIDlet::AddJadJarToInstallFilesL Adding jar file %s", |
|
1161 (wchar_t *)(pathPtr.PtrZ())); |
|
1162 iInstallFiles.Append(path); |
|
1163 CleanupStack::Pop(path); |
|
1164 iIsJad.AppendL(0); |
|
1165 } |
|
1166 } |
|
1167 } |
|
1168 |
|
1169 /** |
|
1170 * Start Java Installer in poll mode and then wait until it exits. |
|
1171 */ |
|
1172 void CRestoreConvertMIDlet::RunJavaInstallerL() |
|
1173 { |
|
1174 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::RunJavaInstaller"); |
|
1175 |
|
1176 RProcess rJavaInstaller; |
|
1177 TFileName fileName; |
|
1178 TInt err; |
|
1179 // Max one path name, user name and password and some options -> |
|
1180 // 1536 is enough |
|
1181 TBuf<1536> commandLine; |
|
1182 |
|
1183 // Build command line used to pass all necessary info to Java Installer |
|
1184 std::auto_ptr<HBufC> installerStarterDll( |
|
1185 stringToDes(java::runtime::JAVA_INSTALLER_STARTER_DLL)); |
|
1186 commandLine = installerStarterDll->Des(); |
|
1187 commandLine.Append(_L(" poll -address=convert")); |
|
1188 |
|
1189 // Run installer silently |
|
1190 commandLine.Append(_L(" -silent -skipotastatus -silentconversion")); |
|
1191 |
|
1192 // Convert old S60 applications so that applications uids, |
|
1193 // private data and RMS data are all preserved |
|
1194 commandLine.Append(_L(" -convert=yes")); |
|
1195 |
|
1196 // Upgrading MIDlets is allowed |
|
1197 commandLine.Append(_L(" -upgrade=yes")); |
|
1198 |
|
1199 // No OCSP checks for converted MIDlets |
|
1200 commandLine.Append(_L(" -ocsp=no")); |
|
1201 |
|
1202 // Allow upgrade even if version number has not increased |
|
1203 commandLine.Append(_L(" -overwrite=yes")); |
|
1204 |
|
1205 // Downloading .jar is not allowed. |
|
1206 commandLine.Append(_L(" -download=no")); |
|
1207 |
|
1208 // If upgrade install, automatically upgrade also the data |
|
1209 commandLine.Append(_L(" -upgrade_data=yes")); |
|
1210 |
|
1211 // MIDlets must be restored to the original drive |
|
1212 if (iDrive > -1) |
|
1213 { |
|
1214 TChar targetDrive; |
|
1215 err = RFs::DriveToChar(iDrive, targetDrive); |
|
1216 if (KErrNone == err) |
|
1217 { |
|
1218 commandLine.Append(_L(" -drive=")); |
|
1219 commandLine.Append(targetDrive); |
|
1220 } |
|
1221 } |
|
1222 |
|
1223 // start JavaInstaller |
|
1224 std::auto_ptr<HBufC> installerProcess( |
|
1225 stringToDes(java::runtime::JAVA_PROCESS)); |
|
1226 err = rJavaInstaller.Create(installerProcess->Des(), commandLine); |
|
1227 if (KErrNone == err) |
|
1228 { |
|
1229 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::RunJavaInstaller calling Rendezvous"); |
|
1230 // This call will wait until Java Installer exits (or panics) |
|
1231 rJavaInstaller.Logon(iStatus); |
|
1232 |
|
1233 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::RunJavaInstaller calling Resume"); |
|
1234 rJavaInstaller.Resume(); |
|
1235 } |
|
1236 else |
|
1237 { |
|
1238 ELOG1(EJavaConverters, |
|
1239 "CRestoreConvertMIDlet::RunJavaInstaller Cannot start Installer, error %d", err); |
|
1240 // CActive will trap the following leave, execution will go to RunError |
|
1241 User::Leave(err); |
|
1242 } |
|
1243 |
|
1244 LOG(EJavaConverters, EInfo, "CRestoreConvertMIDlet::RunJavaInstaller calling RProcess::Close"); |
|
1245 // free resources before returning |
|
1246 rJavaInstaller.Close(); |
|
1247 |
|
1248 // now wait until Java Installer exits |
|
1249 SetActive(); |
|
1250 } |
|
1251 |
|
1252 /** |
|
1253 * To cleanup member variables. |
|
1254 */ |
|
1255 void CRestoreConvertMIDlet::FullCleanup() |
|
1256 { |
|
1257 iDirs.ResetAndDestroy(); |
|
1258 iInstallFiles.ResetAndDestroy(); |
|
1259 iUninstallUids.clear(); |
|
1260 iIsJad.Reset(); |
|
1261 } |
|
1262 |
|
1263 |
|
1264 /** |
|
1265 * Checks all local drives in the device and stores the DriveInfo API drive |
|
1266 * status information for each drive to iDriveStatuses |
|
1267 * @exception Cannot get drive list. |
|
1268 */ |
|
1269 void CRestoreConvertMIDlet::GetAllDeviceDrivesL() |
|
1270 { |
|
1271 TDriveList driveList; |
|
1272 // get all drives |
|
1273 TInt err = iFs.DriveList(driveList); |
|
1274 if (KErrNone != err) |
|
1275 { |
|
1276 ELOG1(EJavaConverters, |
|
1277 "CRestoreConvertMIDlet::GetAllDeviceDrives cannot get drive list, err %d", err); |
|
1278 User::Leave(err); |
|
1279 } |
|
1280 |
|
1281 // store status of the non-remote, non-substed drives |
|
1282 TUint status = 0; |
|
1283 for (TInt drive = 0; drive < KMaxDrives; drive++) |
|
1284 { |
|
1285 iDriveStatuses[drive] = 0; |
|
1286 |
|
1287 if (driveList[drive] == 0) |
|
1288 { |
|
1289 // no such drive in this device |
|
1290 continue; |
|
1291 } |
|
1292 |
|
1293 err = DriveInfo::GetDriveStatus(iFs, drive, status); |
|
1294 if (KErrNone != err) |
|
1295 { |
|
1296 ELOG2(EJavaConverters, |
|
1297 "CRestoreConvertMIDlet::GetAllDeviceDrivesL cannot get drive %d status, err %d", |
|
1298 drive, err); |
|
1299 User::Leave(err); |
|
1300 } |
|
1301 // D drive is temporary RAM drive, skip it |
|
1302 // Drives J to Y are substed or remote drives, skip them |
|
1303 if ((drive == EDriveD) || ((drive >= EDriveJ) && (drive <= EDriveY))) |
|
1304 { |
|
1305 continue; |
|
1306 } |
|
1307 |
|
1308 iDriveStatuses[drive] = status; |
|
1309 } |
|
1310 } |