diff -r f5050f1da672 -r 04becd199f91 javatools/javaappconverter/src.s60/silentmidletconvert.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javatools/javaappconverter/src.s60/silentmidletconvert.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,953 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Java platform 2.0 javaappconverter process +* +*/ + + +#include +#include +#include +#include + +#include "silentmidletconvert.h" +#include "javauids.h" +#include "javacommonutils.h" +#include "logger.h" +#include "javaprocessconstants.h" +#include "javasymbianoslayer.h" + + +using namespace java::util; + +_LIT(KJarFileNameSuffix, ".jar"); +_LIT(KJadFileNameSuffix, ".jad"); +_LIT(KFLJarFileNameSuffix, ".dm"); +_LIT(KSDJarFileNameSuffix, ".dcf"); +_LIT(KSMCBackSplash, "\\"); + +// The directory where the java applications to be converted are searched from +_LIT(KMidletSuiteInstallBasePath, ":\\Private\\102033E6\\MIDlets\\"); + + +/** + * To create new instance of this class. + * + * @param aFs - A reference to the file server. + * @return Reference to the object of this class. + * @exception If construction fails. + * + */ +CSilentMIDletConvert* CSilentMIDletConvert::NewLC(RFs& aFs) +{ + CSilentMIDletConvert* self = new(ELeave) CSilentMIDletConvert(aFs); + CleanupStack::PushL(self); + self->ConstructL(); + return self; +} + +/** + * To do 1st phase construction for this object. + * + * Adds this active object to the scheduler. + * + * @param aFs - A reference to the file server. + */ +CSilentMIDletConvert::CSilentMIDletConvert(RFs& aFs) : + CActive(EPriorityStandard), iFs(aFs), iNumberOfAppsToInstall(0), + iDefaultTargetInstallationDrive(-1) +{ + CActiveScheduler::Add(this); +} + +/** + * To do 2nd phase construction for this object. + * + * @exception If the method is not able to allocate necessary buffers. + */ +void CSilentMIDletConvert::ConstructL() +{ + JELOG2(EJavaConverters); + + iConvertServer = new(ELeave) ConvertServer(); +} + +/** + * Deletes this object. + * All allocated resources are released. + */ +CSilentMIDletConvert::~CSilentMIDletConvert() +{ + JELOG2(EJavaConverters); + Cancel(); + iInstallFiles.ResetAndDestroy(); + iInstallFiles.Close(); + + iDirs.ResetAndDestroy(); + iDirs.Close(); + + delete iConvertServer; + iConvertServer = NULL; +} + +/** + * To start silent installation. + */ +void CSilentMIDletConvert::Start() +{ + JELOG2(EJavaConverters); + iState = EFindOutDeviceDrives; + CompleteRequest(); +} + +/** + * To stop whole preinstaller. + * Stops the active scheduler. + */ +void CSilentMIDletConvert::Exit() +{ + Deque(); + CActiveScheduler::Stop(); +} + +/** + * To complete the request for this object. + * + * @Postconditions The following conditions are true immediately after + * returning from this method. + * - iStatus == KErrNone + * - IsActive() == ETrue + */ +void CSilentMIDletConvert::CompleteRequest() +{ + JELOG2(EJavaConverters); + + TRequestStatus *status = &iStatus; + User::RequestComplete(status, KErrNone); + if (!IsActive()) + { + SetActive(); + } +} + +/** + * To run this active object. + * + * The state logic is: + * + * EFindOutDeviceDrives: find out all non-remote drives in the device + * - mark externally mountable drives (removable drives) + * - mark read only drives (ROM) + * + * EFindOutDrivesToBeScannedNow: make list of drives to be scanned + * - start with all mounted drives + * + * EAppsInInstalledDirectories: go through all directories in iDirs one by one + * and find all java applications in the subdirectories of the directory + * - if only .jar/.dcf/.dm file is found it is added to iInstallFiles + * - if .jad file is found, it is added to iInstallFiles + * + * ECheckWhichAppsShouldBeConverted: for each java application check from + * AppArc whether it should be converted + * - if the application has been installed, convert it + * + * EExecuteConvertServer: give list of install files to preinstall server, + * start Java Installer in poll mode, start convert server in another thread, + * convert server will give the names of the .jad or .jar/.dcf/.dm files to Java Installer + * when it polls them, convert server will log whether each installation + * succeeded. After all install files have been polled, convert server will ask + * Java Installer to exit. After that this active object moves to next state. + * + * EMarkConversionDone: remove 'uids' data file created by javaapppreconverter + * + * EExit: free resources and exit + * + */ +void CSilentMIDletConvert::RunL() +{ + JELOG2(EJavaConverters); + + switch (iState) + { + case EFindOutDeviceDrives: + { + LOG(EJavaConverters, EInfo, + "CSilentMIDletConvert::RunL EFindOutDeviceDrives"); + GetAllDeviceDrivesL(); + iState = EFindOutDrivesToBeScannedNow; + CompleteRequest(); + } + break; + + case EFindOutDrivesToBeScannedNow: + { + LOG(EJavaConverters, EInfo, + "CSilentMIDletConvert::RunL EFindOutDrivesToBeScannedNow"); + + TChar driveChar = 'C'; + + // forget old search directories + iDirs.ResetAndDestroy(); + + for (TInt drive = 0; drive < KMaxDrives; drive++) + { + // All present drives will be scanned for + // java applications to be converted + if (iDriveStatuses[drive] & DriveInfo::EDrivePresent) + { + (void)iFs.DriveToChar(drive, driveChar); + + // The base Java application install directory in this + // drive must be scanned. + // Reserve memory also for drive letter and terminating zero + // for logging. + HBufC *baseInstallDir = HBufC::NewLC(KMidletSuiteInstallBasePath().Length() + 2); + + TPtr dirPtr(baseInstallDir->Des()); + dirPtr.Append(driveChar); + dirPtr.Append(KMidletSuiteInstallBasePath()); + + // Add new search directory + iDirs.AppendL(baseInstallDir); + CleanupStack::Pop(baseInstallDir); + } + } + + iState = EAppsInInstalledDirectories; + CompleteRequest(); + } + break; + + case EAppsInInstalledDirectories: + { + LOG(EJavaConverters, EInfo, + "CSilentMIDletConvert::RunL EAppsInInstalledDirectories"); + + GetInstallFilesL(iDirs); + + iState = ECheckWhichAppsShouldBeConverted; + CompleteRequest(); + } + break; + + case ECheckWhichAppsShouldBeConverted: + { + LOG(EJavaConverters, EInfo, + "CSilentMIDletConvert::RunL ECheckWhichAppsShouldBeConverted"); + + // Check all Jad / Jar files in iInstallFiles and remove those + // that need not be converted (those that cannot be found from + // AppArc). Updates also iNumberOfAppsToInstall + CheckNeedToInstall(); + + iState = EExecuteConvertServer; + CompleteRequest(); + } + break; + + case EExecuteConvertServer: + { + LOG(EJavaConverters, EInfo, + "CSilentMIDletConvert::RunL EExecuteConvertServer"); + + if (iNumberOfAppsToInstall > 0) + { + // Install all MIDlet Suites still in iInstallFiles. + + // Pass iInstallFiles to ConvertServer + iConvertServer->setInstallFiles(iInstallFiles); + + // Start the server + int err = iConvertServer->start(); + if (0 != err) + { + // server cannot be started + ELOG1(EJavaConverters, + "Cannot start convert server, err %d", err); + } + + // Starts Java Installer, waits until Java Installer exits + RunJavaInstallerL(); + + iState = EMarkConversionDone; + } + else + { + iState = EMarkConversionDone; + CompleteRequest(); + } + } + break; + + case EMarkConversionDone: + { + // If this line is executed, converting old midlets succeeded. + // Remove the 'uids' data file so that conversion will not be + // done again if OMJ sis package is installed again to the same device. + RemoveDataFile(); + + iState = EExit; + CompleteRequest(); + } + break; + + case EExit: + { + LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunL EExit"); + + // Stops the server if it is running + iConvertServer->stop(); + + FullCleanup(); + + // The whole javaappconverter process is stopped. + Exit(); + } + break; + + } +} + +/** + * To handle leave from RunL. + * This method exits this active object using normal state machine + * After calling this method this active object will exit. + * + * @param aError - A reason of error. + * @return KErrNone. + */ +TInt CSilentMIDletConvert::RunError(TInt aError) +{ + ELOG2(EJavaConverters, + "CSilentMIDletConvert::RunError(%d) from state %d", aError, iState); + + Cancel(); + + iState = EExit; + CompleteRequest(); + + return KErrNone; +} + +/** + * To do cancelling for this object. + * + */ +void CSilentMIDletConvert::DoCancel() +{ + ELOG1(EJavaConverters, + "CSilentMIDletConvert::DoCancel from state %d", iState); + + // Check whether convert server must be stopped + if (iState == EExecuteConvertServer) + { + // Stops the server if it is running + iConvertServer->stop(); + } +} + +/** + * Add .jad files in the directories specified in aDirs to iInstallFiles. + * If a directory does not contain a .jad file but it contains a .jar/.dcf/.dm file, + * add that file to iInstallFiles + * + * @param aDirs - An array of directories to be scanned. + * @exception Unable to alloc memory for the internal buffers. + * @exception Unable to get directory's contents. + */ +void CSilentMIDletConvert::GetInstallFilesL(RPointerArray& aDirs) +{ + JELOG2(EJavaConverters); + + // Number of MIDlet installation base directories to scan, + // one directory per local drive + const TInt nBaseDirs = aDirs.Count(); + + for (TInt i = 0; i < nBaseDirs; i++) + { + TFileName suitePath; + + // Form base directory path, MIDlets have been installed + // to subdirectories of this directory + const TPtrC& dir = ((HBufC *)(aDirs[i]))->Des(); + TFileName baseSuitePath = dir; + + CDir *entryList; + CDir *dirList; + TInt err = iFs.GetDir(baseSuitePath, KEntryAttMatchMask, ESortNone, entryList, dirList); + if (KErrNone != err) + { + WLOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::GetInstallFilesL Cannot list directory %s", + (wchar_t *)(baseSuitePath.PtrZ())); + + // If no S60 Java application has been installed to the drive, + // the directory does not exist but it is OK + if (KErrPathNotFound != err) + { + User::Leave(err); + } + continue; + } + + // Only midlet installation directory entries are meaningfull, + // discard other possible entries + delete entryList; + + TInt nCount = dirList->Count(); + TEntry dirEntry; + + for (TInt nInd = 0; nInd < nCount; nInd++) + { + dirEntry = (*dirList)[nInd]; + // Just to make sure this really is subdirectory + if (dirEntry.IsDir()) + { + // Is this midlet suite subdir? + // Midlet suite subdirs look like this "[102b567B]" + // Must parse the value of the Uid as unsigned int to avoid + // overflow + TUint32 nUid; + TLex lexer(dirEntry.iName); + lexer.Inc(); + err = lexer.Val(nUid, EHex); + if (KErrNone != err) + { + // Not midlet suite subdir, skip it + continue; + } + + // Does the subdirectory contain any Jar files? + suitePath = baseSuitePath; + suitePath.Append(dirEntry.iName); + suitePath.Append(KSMCBackSplash); + + CDir *suiteDirEntryList; + err = iFs.GetDir(suitePath, KEntryAttMatchMask, ESortNone, suiteDirEntryList); + if (KErrNone != err) + { + ELOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::GetInstallFilesL Cannot list content of suite dir %s", + (wchar_t *)(suitePath.PtrZ())); + User::Leave(err); + return; + } + // If there is .jad or Jar file in suiteDirEntryList, adds + // it to iInstallFiles. + // Recognizes also DRM protected Jar files (.dm, .dcf) + AddJadJarToInstallFilesL(suitePath, suiteDirEntryList); + delete suiteDirEntryList; + } + } // for - loop all directory entries in a base installation directories + delete dirList; + + } // for - loop all base installation directories + + if (iInstallFiles.Count() == 0) + { + WLOG(EJavaConverters, + "CSilentMIDletConvert::GetInstallFilesL No MIDlets to convert"); + } +} + +/** + * Check all Jad / Jar files in iInstallFiles and remove those + * that need not be converted. Updates also iNumberOfAppsToInstall. + */ +void CSilentMIDletConvert::CheckNeedToInstall() +{ + // It is too late to check from AppArc whether the application is a + // valid java application or no. The Java registry dll:s have been eclipsed and + // old apps are now invalid. + // javaapppreconverter has stored the Uids of the valid midlets to 'uids' file + // in to the data subdirectory of this process. + // ReadMidletUids() can be used to read the uids of the valid midlets to array. + // If uid is in the array, it is valid. + TFileName uidsDataFilePathName(KUidsImportDataFilePathName); + RArray validUids = ReadMidletUids(uidsDataFilePathName); + + // loop through iInstallFiles one be one + TInt nNumberOfAppsToInstall = 0; + TInt err; + TInt nFiles = iInstallFiles.Count(); + TParse fp; + for (TInt nInd = 0; nInd < nFiles; nInd++) + { + // get the directory path of the current iInstallFiles[nInd] + err = fp.Set(*(iInstallFiles[nInd]), NULL, NULL); + if (KErrNone != err) + { + WLOG1(EJavaConverters, + "CSilentMIDletConvert::CheckNeedToInstall Cannot parse install file name %s", + iInstallFiles[nInd]); + continue; + } + + TPtrC installDir = fp.DriveAndPath(); + + // read Java applications uid(s) from 'uids' file in the directory + RArray appUids = ReadMidletUids(installDir); + + // For each app uid, check whether it is uid of an valid java application. + // If yes, make conversion installation for the .jad/Jar file + // in this directory. + TInt nIndUids; + TInt nCountUids = appUids.Count(); + for (nIndUids = 0; nIndUids < nCountUids; nIndUids++) + { + err = validUids.Find(appUids[nIndUids]); + if (KErrNotFound == err) + { + LOG1(EJavaConverters, EInfo, + "CSilentMIDletConvert::CheckNeedToInstall Midlet with Uid %x " + "was not registered to AppArc", + appUids[nIndUids].iUid); + + // Do not convert any app in this Midlet suite + delete iInstallFiles[nInd]; + iInstallFiles[nInd] = NULL; + break; + } + else + { + // The application is valid, so it should be converted + nNumberOfAppsToInstall++; + } + } + appUids.Close(); + } + validUids.Close(); + + // how many applications to convert + iNumberOfAppsToInstall = nNumberOfAppsToInstall; +} + +/** + * Read the midlet uids from file 'uids' in the directory + * given in parameter aDir and return them in RArray + * + * @param aDir - directory that contains 'uids' file + * @return the midlet uids in RArray. Caller must destroy the RArray + */ +RArray CSilentMIDletConvert::ReadMidletUids(const TPtrC& aDir) +{ + RArray midletUids; + RFile fileUids; + TFileName nameUids = aDir; + nameUids.Append(_L("uids")); + + TInt err = fileUids.Open(iFs, nameUids, EFileRead); + if (KErrNone != err) + { + // cannot open "uids" file + nameUids.Append(0); + WLOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::ReadMidletUids cannot open uids file in dir %s", + (wchar_t *)(&(nameUids[0]))); + WLOG1(EJavaConverters, "Error is %d", err); + return midletUids; + } + + TInt fileSize(0); + err = fileUids.Size(fileSize); + if (fileSize < 8) + { + // valid "uids" file contains at least the uid of the suite and + // uid of at least one midlet + fileUids.Close(); + // invalid "uids" file + nameUids.Append(0); + WLOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::ReadMidletUids invalid uids file in dir %s", + (wchar_t *)(&(nameUids[0]))); + return midletUids; + } + + // reserve buffer for one uid + TBuf8<4> readBuf; + TDes8 readBufDes(readBuf); + + // The first uid is suite uid but we are not interested in it. Skip it. + err = fileUids.Read(readBufDes); + if (KErrNone != err) + { + fileUids.Close(); + // cannot read "uids" file + nameUids.Append(0); + WLOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::ReadMidletUids cannot read uids file in dir %s", + (wchar_t *)(&(nameUids[0]))); + WLOG1(EJavaConverters, "Error is %d", err); + return midletUids; + } + + // Now read rest of the file one uid at a time + TInt nReadBytes = readBufDes.Length(); + TUint midletUidValue; + TUint temp; + + while (nReadBytes == 4) + { + err = fileUids.Read(readBufDes); + if (KErrNone != err) + { + fileUids.Close(); + // cannot read "uids" file + nameUids.Append(0); + WLOG1WSTR(EJavaConverters, + "CSilentMIDletConvert::ReadMidletUids(2) cannot from uids file in dir %s", + (wchar_t *)(&(nameUids[0]))); + WLOG1(EJavaConverters, "Error is %d", err); + return midletUids; + } + + nReadBytes = readBufDes.Length(); + if (nReadBytes == 4) + { + // One whole midlet id was read to buffer. + // 4 bytes per midlet, least significant byte first + TUid midletUid; + + midletUidValue = readBufDes[0]; + temp = readBufDes[1]; + midletUidValue += temp<<8; + temp = readBufDes[2]; + midletUidValue += temp<<16; + temp = readBufDes[3]; + midletUidValue += temp<<24; + + midletUid.iUid = midletUidValue; + midletUids.Append(midletUid); + } + } + + fileUids.Close(); + + return midletUids; +} + +/** + * Scan the content of one directory entry and add the name of + * .jad / .jar /.dcf/.dm file to iInstallFiles if + * the directory contains a valid, installed Java application. + * Recognizes also DRM protected jar files (.dm, .dcf) + * + * @param aSuitePathName - directory to be scanned. + * @param aSuiteDirEntryList - contents of the directory + * @exception Unable to alloc memory for the internal buffers. + */ +void CSilentMIDletConvert::AddJadJarToInstallFilesL( + const TFileName &aSuitePathName, + const CDir *aSuiteDirEntryList) +{ + JELOG2(EJavaConverters); + + if (NULL == aSuiteDirEntryList) + { + return; + } + + TInt nCount = aSuiteDirEntryList->Count(); + if (0 == nCount) + { + return; + } + + TInt suffixPos; + TEntry dirEntry; + TBool jarFileInSuiteDir = EFalse; + TBool jadFileInSuiteDir = EFalse; + TFileName jadFullPathName; + TFileName jarFullPathName; + + for (TInt nInd = 0; nInd < nCount; nInd++) + { + dirEntry = (*aSuiteDirEntryList)[nInd]; + // Directory cannot be Jar file. + // Empty file cannot valid Jar file + if (dirEntry.IsDir() || (dirEntry.iSize == 0)) + { + continue; + } + // get the suffix of the name + suffixPos = dirEntry.iName.LocateReverse('.'); + if (suffixPos == KErrNotFound) + { + // File name does not contain '.' char + continue; + } + TPtrC suffix(dirEntry.iName.Mid(suffixPos)); + + // if the name ends with ".jar" the name is current candidate + // for the name to be added to iInstallFiles list + if (suffix.CompareF(KJarFileNameSuffix) == 0) + { + jarFullPathName = aSuitePathName; + jarFullPathName.Append(dirEntry.iName); + jarFileInSuiteDir = ETrue; + } + else if (suffix.CompareF(KJadFileNameSuffix) == 0) + { + // If .jad file is found, then it will be added + // to iInstallFiles list + jadFullPathName = aSuitePathName; + jadFullPathName.Append(dirEntry.iName); + jadFileInSuiteDir = ETrue; + } + else if (suffix.CompareF(KFLJarFileNameSuffix) == 0) + { + // forward locked and combined delivery DRM protected + // .jar files have suffix ".dm" + jarFullPathName = aSuitePathName; + jarFullPathName.Append(dirEntry.iName); + jarFileInSuiteDir = ETrue; + } + else if (suffix.CompareF(KSDJarFileNameSuffix) == 0) + { + // separate delivery DRM protected .jar files have suffix ".dcf" + jarFullPathName = aSuitePathName; + jarFullPathName.Append(dirEntry.iName); + jarFileInSuiteDir = ETrue; + } + } + + // If directory contains a Jar file, then add something to iInstallFiles + if (jarFileInSuiteDir) + { + // If directory contains also .jad file, add .jad file name to iInstallFiles + if (jadFileInSuiteDir) + { + // Reserve one char for null terminator + HBufC* path = HBufC::NewLC(jadFullPathName.Length() + 1); + TPtr pathPtr(path->Des()); + pathPtr.Append(jadFullPathName); + + LOG1WSTR(EJavaConverters, EInfo, + "CSilentMIDletConvert::AddJadJarToInstallFilesL Adding jad file %s", + (wchar_t *)(pathPtr.PtrZ())); + iInstallFiles.Append(path); + CleanupStack::Pop(path); + } + else + { + // Reserve one char for null terminator + HBufC* path = HBufC::NewLC(jarFullPathName.Length() + 1); + TPtr pathPtr(path->Des()); + pathPtr.Append(jarFullPathName); + + LOG1WSTR(EJavaConverters, EInfo, + "CSilentMIDletConvert::AddJadJarToInstallFilesL Adding jar file %s", + (wchar_t *)(pathPtr.PtrZ())); + iInstallFiles.Append(path); + CleanupStack::Pop(path); + } + } +} + +/** + * Start Java Installer in poll mode and then wait until it exits. + */ +void CSilentMIDletConvert::RunJavaInstallerL() +{ + LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller"); + + RProcess rJavaInstaller; + TFileName fileName; + TInt err; + // Max one path name, user name and password and some options -> + // 1536 is enough + TBuf<1536> commandLine; + + // Build command line used to pass all necessary info to Java Installer + std::auto_ptr installerStarterDll( + stringToDes(java::runtime::JAVA_INSTALLER_STARTER_DLL)); + commandLine = installerStarterDll->Des(); + commandLine.Append(_L(" poll -address=convert")); + + // Run installer silently + commandLine.Append(_L(" -silent")); + + // Convert old S60 applications so that applications uids, + // private data and RMS data are all preserved + commandLine.Append(_L(" -convert=yes")); + + // Upgrading MIDlets is allowed + commandLine.Append(_L(" -upgrade=yes")); + + // No OCSP checks for converted MIDlets + commandLine.Append(_L(" -ocsp=no")); + + // Allow upgrade even if version number has not increased + commandLine.Append(_L(" -overwrite=yes")); + + // Downloading .jar is not allowed. + commandLine.Append(_L(" -download=no")); + + // If upgrade install, automatically upgrade also the data + commandLine.Append(_L(" -upgrade_data=yes")); + + // If the device has an internal drive with much free disk space, + // install all converted applications to that drive + if (iDefaultTargetInstallationDrive > -1) + { + TChar targetDrive; + err = RFs::DriveToChar(iDefaultTargetInstallationDrive, targetDrive); + if (KErrNone == err) + { + commandLine.Append(_L(" -drive=")); + commandLine.Append(targetDrive); + } + } + + // start JavaInstaller + std::auto_ptr installerProcess( + stringToDes(java::runtime::JAVA_PROCESS)); + err = rJavaInstaller.Create(installerProcess->Des(), commandLine); + if (KErrNone == err) + { + LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling Rendezvous"); + // This call will wait until Java Installer exits (or panics) + rJavaInstaller.Logon(iStatus); + + LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling Resume"); + rJavaInstaller.Resume(); + } + else + { + ELOG1(EJavaConverters, + "CSilentMIDletConvert::RunJavaInstaller Cannot start Installer, error %d", err); + // CActive will trap the following leave, execution will go to RunError + User::Leave(err); + } + + LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling RProcess::Close"); + // free resources before returning + rJavaInstaller.Close(); + + // now wait until Java Installer exits + SetActive(); +} + +/** + * To cleanup member variables. + */ +void CSilentMIDletConvert::FullCleanup() +{ + JELOG2(EJavaConverters); + + iDirs.ResetAndDestroy(); + iInstallFiles.ResetAndDestroy(); +} + + +/** + * Checks all local drives in the device and stores the DriveInfo API drive + * status information for each drive to iDriveStatuses + * @exception Cannot get drive list. + */ +void CSilentMIDletConvert::GetAllDeviceDrivesL() +{ + JELOG2(EJavaConverters); + + TDriveList driveList; + // get all drives + TInt err = iFs.DriveList(driveList); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CSilentMIDletConvert::GetAllDeviceDrives cannot get drive list, err %d", err); + User::Leave(err); + } + + // store status of the non-remote, non-substed drives + TInt64 requiredFreeDiskSpace = KMinimumFreeDiskSpace; + TUint status = 0; + for (TInt drive = 0; drive < KMaxDrives; drive++) + { + iDriveStatuses[drive] = 0; + + if (driveList[drive] == 0) + { + // no such drive in this device + continue; + } + + err = DriveInfo::GetDriveStatus(iFs, drive, status); + if (KErrNone != err) + { + ELOG2(EJavaConverters, + "CSilentMIDletConvert::GetAllDeviceDrivesL cannot get drive %d status, err %d", + drive, err); + User::Leave(err); + } + // D drive is temporary RAM drive, skip it + // Drives J to Y are substed or remote drives, skip them + if ((drive == EDriveD) || ((drive >= EDriveJ) && (drive <= EDriveY))) + { + continue; + } + + iDriveStatuses[drive] = status; + + // If the device has an internal (non-removable) drive with much + // free disk space, use that drive as the target installation drive + // when making the conversion installations. + // Skip drives A: to D:, C: drive is not valid target drive because + // we do not want to fill C: drive unnecessarily + if (drive < EDriveE) + { + continue; + } + // drive must be internal and visible to the user but + // it must NOT be corrupted or in exclusive use or read only + if ((status & DriveInfo::EDriveInternal) && + (!(status & DriveInfo::EDriveCorrupt)) && + (!(status & DriveInfo::EDriveInUse)) && + (!(status & DriveInfo::EDriveReadOnly)) && + (status & DriveInfo::EDriveUserVisible)) + { + // Is there 'enough' free disk space for conversion + TVolumeInfo volumeInfo; + err = iFs.Volume(volumeInfo, drive); + if (KErrNone == err) + { + if (volumeInfo.iFree > requiredFreeDiskSpace) + { + iDefaultTargetInstallationDrive = drive; + + // If some other internal drive has even more free + // disk space, it will be used as the target drive + requiredFreeDiskSpace = volumeInfo.iFree; + } + } + } + } +} + +/** + * Remove the data file that contain information about the midlets to be converted. + */ +void CSilentMIDletConvert::RemoveDataFile() +{ + TFileName dataFile(KUidsImportDataFilePathName); + dataFile.Append(KUidsImportDataFileName); + + TInt err = iFs.Delete(dataFile); + if (KErrNone != err) + { + ELOG1(EJavaConverters, + "CSilentMIDletConvert::RemoveDataFile: Cannot delete data file, err %d ", + err); + } +}