diff -r 84a16765cd86 -r 98b66e4fb0be installationservices/swi/source/swis/server/installationplanner.cpp --- a/installationservices/swi/source/swis/server/installationplanner.cpp Fri Mar 19 09:33:35 2010 +0200 +++ b/installationservices/swi/source/swis/server/installationplanner.cpp Fri Apr 16 15:05:20 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" @@ -33,6 +33,7 @@ #include "siscontentprovider.h" #include "sishelperclient.h" #include "securitypolicy.h" +#include "secutils.h" #include @@ -66,6 +67,7 @@ #include "sisregistryserverconst.h" #include "dessisdataprovider.h" #include "adornedutilities.h" +#include "sislauncherclient.h" using namespace Swi; using namespace Swi::Sis; @@ -981,16 +983,6 @@ // Size of this controller only!! TInt64 size = iContentProvider.TotalSizeL(aController.InstallBlock(), iExpressionEvaluator, EFalse); - #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - // Invoke the drive selection part when the planner is not in info collection mode. Otherwise do not. - if (IsInInfoCollectionMode()) - { - // for GetInfo purposes we select an existing system drive. We need to make sure that a valid drive is selected for installation planning, and in any case no files will get copied there, - application->UserSelections().SetDrive(iSystemDriveChar); - } - else - { - #endif // If the package is partial upgrade, extract drive from the registry, and dont // display the drive selection option except where we are upgrading a ROM stub if(error == KErrNone && aController.Info().InstallType() == EInstPartialUpgrade && !registryEntry.IsInRomL()) @@ -1002,20 +994,32 @@ // any assumptions about where to install the upgrade // we need to ask the user where they would like to install // this upgrade - ChooseDriveDialogL(*content, *application, size); + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + if(IsInInfoCollectionMode()) + { + application->UserSelections().SetDrive(iSystemDriveChar); + const_cast (aController).SetDriveSelectionRequired(ETrue); + } + else + { + #endif + ChooseDriveDialogL(*content, *application, size); + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + #endif } else { // install partial upgrade on the same drive as base package application->UserSelections().SetDrive(drive); } - } + } else if(error == KErrNotFound && aController.Info().InstallType() == EInstPartialUpgrade && - iFilesFromPlannedControllers[baseControllerIndex]->Drive() != TChar(KNoDriveSelected)) + iCurrentController > 0 && iFilesFromPlannedControllers[baseControllerIndex]->Drive() != TChar(KNoDriveSelected) ) { //Use the base package's drive application->UserSelections().SetDrive(iFilesFromPlannedControllers[baseControllerIndex]->Drive()); - } + } else if((aController.Info().InstallType() == EInstInstallation || aController.Info().InstallType() == EInstAugmentation) && iIsPropagated) @@ -1037,11 +1041,21 @@ else if (IsUserDriveSelectionRequiredL(aController.InstallBlock())) { // User needs to choose which drive will be used for the installation - ChooseDriveDialogL(*content, *application, size); + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + if(IsInInfoCollectionMode()) + { + application->UserSelections().SetDrive(iSystemDriveChar); + const_cast (aController).SetDriveSelectionRequired(ETrue); + } + else + { + #endif + ChooseDriveDialogL(*content, *application, size); + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + #endif } - #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - } - #endif + CleanupStack::PopAndDestroy(content); // To accurately display the space avaialble for next controller @@ -1067,7 +1081,335 @@ // Process the actual controller, then return the application ProcessInstallBlockL(aController.InstallBlock(), *application, aFilesToCapabilityCheck, *filesList); - + + //Publishing the UID of the associated package. + TUid publishUid = aController.Info().Uid().Uid(); + if(!(Swi::SecUtils::IsPackageUidPresent(publishUid, iUidList))) + { + TInt err = Swi::SecUtils::PublishPackageUid(publishUid, iUidList); + if(err == KErrNone) + { + DEBUG_PRINTF2(_L("CInstallationPlanner::ProcessControllerL published Uid %x."), publishUid.iUid); + } + else if(err == KErrOverflow) + { + DEBUG_PRINTF2(_L("CInstallationPlanner::ProcessControllerL failed to publish Uid %x as the array, holding the uids, exceeded its upper limit."),publishUid.iUid); + } + else if(err == KErrNotFound) + { + DEBUG_PRINTF2(_L("CInstallationPlanner::ProcessControllerL failed to publish Uid %x as the property is not been defined."),publishUid.iUid); + } + else + { + DEBUG_PRINTF3(_L("CInstallationPlanner::ProcessControllerL failed to publish Uid %x with error %d."),publishUid.iUid, err); + User::Leave(err); + } + } + + // Filtering of rsc files from the set of files to be copied and using parser to + // extract app uid,foldername,filename and iconfilename + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + if(IsInInfoCollectionMode()) + { + _LIT(KApparcRegDir, "\\private\\10003a3f\\import\\apps\\"); + _LIT(KApparcRegistrationFileExtn,".rsc"); + + //Getting the list of files to be added from CApplication Object + RPointerArray listOfFilesToBeAdded = application->FilesToAdd(); + //Stores the registration resource files which are passed to the apparc parser + RPointerArray regFilesArray; + CleanupResetAndDestroyPushL(regFilesArray); + RPointerArray listOfFilesToBeExtracted; + CleanupClosePushL(listOfFilesToBeExtracted); + RFs fs; + RArray drives; // Array of system drives + RArray driveSpaces; // Space available on each drive + CleanupClosePushL(drives); + CleanupClosePushL(driveSpaces); + TInt64 currentAvailableDriveSpace = 0 ; + TInt64 totalApplicationDataSize = 0; + CSisRegistryFileDescription* currentFileDescription = NULL; + + //Obtain the disk space available on the drives + iSisHelper.FillDrivesAndSpacesL(drives, driveSpaces); + TChar systemDrive = RFs::GetSystemDriveChar(); + TInt driveIndex = drives.Find(systemDrive); + currentAvailableDriveSpace = driveSpaces[driveIndex]; //first drive is 'C' drive only + + //Opening a file server session + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + User::LeaveIfError(fs.ShareProtected()); + + TInt noOfFilesToBeAdded = listOfFilesToBeAdded.Count(); + // Processing each file and checking if a file is an resource file(*_reg.rsc or *.rsc or *.r%d) + for(TInt i=0 ; i < noOfFilesToBeAdded ; i++) + { + HBufC* targetFileName; + targetFileName = listOfFilesToBeAdded[i]->Target().Alloc(); + CleanupStack::PushL(targetFileName); + TParsePtrC filename(*targetFileName); + TBool isApparcFile = EFalse; + TBuf<10> extension = TParsePtrC(*targetFileName).Ext(); + + if(!extension.Compare(KApparcRegistrationFileExtn)) // for resource files *_reg.rsc or *.rsc + { + isApparcFile = ETrue; + } + else + { + TInt extnLength = extension.Length(); + HBufC* extn; + if(extnLength == 4) //for localizable resource files with extn like .r01 + { + extn = extension.Right(2).AllocLC(); + } + else if(extnLength == 5) + { + extn = extension.Right(3).AllocLC(); //for localizable resource files with extn like .r101 + } + else + { + CleanupStack::PopAndDestroy(targetFileName); + continue; + } + + //Check to find if the extension is of valid localizable resource files + TInt value = 0; + // Declare the variable + TLex lex(*extn); + // Convert the descriptor into the integer number + TInt err = lex.Val(value); + if(err == KErrNone) + { + isApparcFile = ETrue; + } + CleanupStack::PopAndDestroy(extn); + } + + //If its an apparc file(rsc) file then add its size to the total application size + if(isApparcFile) + { + listOfFilesToBeExtracted.AppendL(listOfFilesToBeAdded[i]); + totalApplicationDataSize += listOfFilesToBeAdded[i]->UncompressedLength(); + } + CleanupStack::PopAndDestroy(targetFileName); + } + + //Here we do extraction of rsc files ,before extracting files we check if there is an enough space on the disk(C drive) + //to extract the files then extract the file to a temporary location and + //check if it is a registration resource file(using target path) then store it into an array. + TInt noOfFilesToBeExtracted = listOfFilesToBeExtracted.Count(); + DEBUG_PRINTF2(_L("Total number resource files (registration/localizable)to be extracted is %d"), noOfFilesToBeExtracted); + if(0 != noOfFilesToBeExtracted) + { + + //Check if there is enough space to extract the resource (registration or localizable) files + if(totalApplicationDataSize > currentAvailableDriveSpace) + { + //No memory to extract the file + User::LeaveIfError(KErrDiskFull); + } + + //Extraction of rsc file to a temporary location and if it is a reg resource filr append t to an array for parsing + for (TInt i = 0 ; i < noOfFilesToBeExtracted ; i++) + { + TFileName resourceFileName; + _LIT(KResourceFileNameFmt, "%c:\\resource\\install\\temp\\0x%08x\\%S"); // Pakage Uid + TFileName finalToBeExtracted = TParsePtrC(listOfFilesToBeExtracted[i]->Target()).NameAndExt(); + resourceFileName.Format(KResourceFileNameFmt, TUint(systemDrive), aController.Info().Uid().Uid().iUid, + &finalToBeExtracted); + + TInt err = fs.MkDirAll(resourceFileName); + if (err!= KErrNone && err != KErrAlreadyExists) + User::LeaveIfError(err); + + RFile resourceFile; + User::LeaveIfError(resourceFile.Replace(fs, resourceFileName, + EFileStream|EFileWrite|EFileRead|EFileShareExclusive)); + CleanupClosePushL(resourceFile); + + // Extract resource file to a temporary file. + DEBUG_PRINTF2(_L("Current resource file (registration/localizable) to be extraced is %S"), &resourceFileName); + User::LeaveIfError(iSisHelper.ExtractFileL(fs, resourceFile, + listOfFilesToBeExtracted[i]->Index(), application->AbsoluteDataIndex(), UiHandler())); + + CleanupStack::PopAndDestroy(&resourceFile); + + // If target of the file is apparc's private folder then it is registration resource file for an app + TParsePtrC filename(listOfFilesToBeExtracted[i]->Target()); + if (filename.Path().Left(KApparcRegDir().Length()).CompareF(KApparcRegDir) == 0) + { + HBufC* regResourceFileName = resourceFileName.AllocL(); + + regFilesArray.AppendL(regResourceFileName); + } + } + //Since the files have been extracted the available disk space is reduced + currentAvailableDriveSpace -= totalApplicationDataSize; + } + + DEBUG_PRINTF(_L8("Finished extracting all resource files (registration/localizable) successfuly")); + //Pass each registration resource file to the parser to fetch the app info and then if icon file is present fetch the icon file + //to a temporary location. + + TInt noOfRegFilesToBeParsed = regFilesArray.Count(); + DEBUG_PRINTF2(_L("Total number Registration Resource files to be parsed is %d"), noOfRegFilesToBeParsed); + for(TInt i = 0 ; i < noOfRegFilesToBeParsed ; i++) + { + Usif::CApplicationRegistrationData *appData = NULL; + CNativeComponentInfo::CNativeApplicationInfo* applicationInfo = NULL; + RArray languages; + TFileName iconFile; + // Calling the apparc parser to fetch the app info from the resouce files + + DEBUG_PRINTF2(_L("Current Registration Resource file to be parsed is %S"), regFilesArray[i]); + + // Ask the launcher to parse the registration resource file + RSisLauncherSession launcher; + CleanupClosePushL(launcher); + User::LeaveIfError(launcher.Connect()); + RFile file; + User::LeaveIfError(file.Open(fs, *regFilesArray[i], EFileRead)); + RArray appLanguages; + CleanupClosePushL(appLanguages); + TRAPD(err,appData=launcher.SyncParseResourceFileL(file, appLanguages)); + CleanupStack::PopAndDestroy(&appLanguages); + file.Close(); + CleanupStack::PopAndDestroy(&launcher); // popping and destroying as it is not reqd further. + + DEBUG_PRINTF2(_L("Finished Parsing Registration Resource file %S successfuly"), regFilesArray[i]); + if(KErrCorrupt == err) + { + continue; + } + else if(KErrNone != err) + { + User::Leave(err); + } + + CleanupStack::PushL(appData); + TUid appuid = appData->AppUid(); + HBufC* appname = appData->AppFile().AllocLC(); + TBuf<100> finalAppName = TParsePtrC(*appname).NameAndExt(); + const RPointerArray aLocalizableAppInfoList = appData->LocalizableAppInfoList(); + HBufC* groupName = NULL; + HBufC* iconFileName = NULL; + TInt fileSize = 0 ; + + //If localizable info for an app is present then get the localized group name else get it from app registration data + if(0 == aLocalizableAppInfoList.Count()) + { + groupName = appData->GroupName().AllocLC(); + DEBUG_PRINTF2(_L("Application Group Name %S"), groupName); + //Since locale does not exists no need to extract, create CNativeApplicationInfo without iconFileName + applicationInfo = Swi::CNativeComponentInfo::CNativeApplicationInfo::NewLC(appuid, finalAppName, *groupName, *iconFileName); + } + else + { + Usif::CLocalizableAppInfo* localizedInfo = NULL; + const Usif::CCaptionAndIconInfo* captionAndIconInfo = NULL; + localizedInfo = aLocalizableAppInfoList[0]; + groupName = localizedInfo->GroupName().AllocLC(); + captionAndIconInfo = localizedInfo->CaptionAndIconInfo(); + //Check if caption and icon info for an app is present or not, if present extract the icon file. + if(captionAndIconInfo) + { + TBuf<100> finalIconFileName; + iconFileName = captionAndIconInfo->IconFileName().AllocLC(); + if(iconFileName != NULL) + { + finalIconFileName = TParsePtrC(*iconFileName).NameAndExt(); + + _LIT(KIconFileNameFmt, "%c:\\resource\\install\\icon\\0x%08x\\%S"); // Applicaiton Uid + iconFile.Format(KIconFileNameFmt, TUint(systemDrive), appuid.iUid, + &finalIconFileName); + + TInt err = fs.MkDirAll(iconFile); + if (err!= KErrNone && err != KErrAlreadyExists) + User::LeaveIfError(err); + + //Find from the list of files to be copied , the file description of the icon file returned by the parser + for(TInt k = 0; k < listOfFilesToBeAdded.Count() ; k++) + { + currentFileDescription = listOfFilesToBeAdded[k]; + if(TParsePtrC(currentFileDescription->Target()).NameAndExt().Compare(finalIconFileName)) + { + break; + } + } + //Check if there is enough space to extract the icon file + fileSize = currentFileDescription->UncompressedLength(); + if(currentAvailableDriveSpace < fileSize) + { + //No memory to extract the file + User::LeaveIfError(KErrDiskFull); + } + + //Extracting the icon file to a temp location + RFile tempIconFile; + TInt index = 1; + TBuf<10> integerAppendStr; + // Check if file already exists, if yes then create file with another name (e.g. *_1 or *_2) + while(1) + { + err = tempIconFile.Create(fs, iconFile, EFileStream|EFileWrite|EFileRead|EFileShareExclusive); + if(err == KErrAlreadyExists) + { + integerAppendStr.TrimAll(); + integerAppendStr.Format(_L("%d"), index++); + TInt pos = iconFile.Length()-TParsePtrC(iconFile).Ext().Length(); + iconFile.Insert(pos,integerAppendStr); + } + else if(err == KErrNone) + { + //Everthing is fine, proceed + break; + } + else + { + tempIconFile.Close(); + User::Leave(err); + } + } + CleanupClosePushL(tempIconFile); + + DEBUG_PRINTF2(_L("Icon file to be extraced is %S"), &iconFile); + User::LeaveIfError(iSisHelper.ExtractFileL(fs, tempIconFile, listOfFilesToBeAdded[i]->Index(), application->AbsoluteDataIndex(), UiHandler())); + DEBUG_PRINTF(_L8("Finished extracting Icon file successfuly")); + //After copy the available disk space is reduced + currentAvailableDriveSpace -= fileSize; + CleanupStack::PopAndDestroy(2,iconFileName); //file,iconFileSize + + //Create CNativeApplicationInfo with iconFileName + applicationInfo = Swi::CNativeComponentInfo::CNativeApplicationInfo::NewLC(appuid, finalAppName, *groupName, iconFile); + } + else + { + //Since iconFileName does not exists no need to extract, create CNativeApplicationInfo without iconName + applicationInfo = Swi::CNativeComponentInfo::CNativeApplicationInfo::NewLC(appuid, finalAppName, *groupName, *iconFileName); + } + } + } + + DEBUG_PRINTF2(_L("Application Uid 0x%08x"), appuid); + DEBUG_PRINTF2(_L("Application Name %S"), appname); + DEBUG_PRINTF2(_L("Application Group Name %S"), groupName); + DEBUG_PRINTF2(_L("Application Icon File Name %S"), &iconFile); + + const_cast (aController).AddApplicationInfoL(applicationInfo); + CleanupStack::Pop(applicationInfo); + CleanupStack::PopAndDestroy(3, appData); //groupName,appName,appData + languages.Close(); + } + + CleanupStack::PopAndDestroy(3,&drives); //fs,driveSpaces,drives + CleanupStack::Pop(&listOfFilesToBeExtracted); + listOfFilesToBeExtracted.Close(); + CleanupStack::PopAndDestroy(®FilesArray); + } + #endif + //Append planned controllers list iFilesFromPlannedControllers.AppendL(filesList); CleanupStack::Pop(filesList); @@ -1089,8 +1431,7 @@ CleanupStack::Pop(application); return application; } - - + // Prepare the eclipsable files list from the right source according to the upgrade. void CInstallationPlanner::PrepareEclipsableFilesListL(const Sis::CController& aController) {