javatools/javarestoreconverter/src.s60/restoreconvertmidlet.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     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 }