diff -r e8965914fac7 -r 79647526f98c secureswitools/swisistools/source/interpretsislib/installer.cpp --- a/secureswitools/swisistools/source/interpretsislib/installer.cpp Tue Sep 14 21:31:28 2010 +0300 +++ b/secureswitools/swisistools/source/interpretsislib/installer.cpp Wed Sep 15 12:20:42 2010 +0300 @@ -138,7 +138,8 @@ { InstallSISFile sisFileName(shortName + KDirectorySeparator + *currStr, curr->iTargetDrive, curr->iGenerateStub, - curr->iNonRemovable, curr->iReadOnly, curr->iNotRegister, curr->iSUFlag); + curr->iNonRemovable, curr->iReadOnly, curr->iNotRegister, + curr->iSUFlag, curr->iGenerateRomStub); sisFiles.push_back(sisFileName); } @@ -153,7 +154,8 @@ || (shortName.find(L".sis",0) != std::wstring::npos)) { InstallSISFile sisFileName(shortName, curr->iTargetDrive, curr->iGenerateStub, - curr->iNonRemovable, curr->iReadOnly, curr->iNotRegister, curr->iSUFlag); + curr->iNonRemovable, curr->iReadOnly, curr->iNotRegister, + curr->iSUFlag, curr->iGenerateRomStub); sisFiles.push_back(sisFileName); } @@ -338,20 +340,21 @@ return MISSING_DEPENDENCY; } - if (!IsValidUpgrade(file, aInstallSISFile.iSUFlag, aInstallSISFile.iNonRemovable)) + if (!IsValidUpgrade(file, aInstallSISFile.iSUFlag, aInstallSISFile.iNonRemovable, aInstallSISFile.iGenerateRomStub)) { return INVALID_UPGRADE; } InstallableFiles installable; - GetInstallableFiles(file, installable, *iExpressionEvaluator, aInstallSISFile.iTargetDrive); + GetInstallableFiles(file, installable, *iExpressionEvaluator, aInstallSISFile.iTargetDrive, + iParamList.SystemDriveLetter(), aInstallSISFile.iGenerateRomStub); // Uninstall the same package (if found) prior to any installation - UninstallPkg(file); + UninstallPkg(file, aInstallSISFile.iGenerateRomStub); CheckDestinations(file, installable, aInstallSISFile); - InstallFiles(installable, iParamList.SystemDriveLetter()); + InstallFiles(installable, iParamList.SystemDriveLetter(), aInstallSISFile.iGenerateRomStub); UpdateRegistry(file, installable, aInstallSISFile, aInstallSISFile.iSUFlag); @@ -360,6 +363,11 @@ CreateStubSisFile(aInstallSISFile, file); } + if (aInstallSISFile.iGenerateRomStub) + { + CreateRomStubSisFile(aInstallSISFile, file); + } + FreeInstallableFiles(installable); return SUCCESS; @@ -458,7 +466,7 @@ return (stubExistsInRom && (romUpgradableSA || puInstall || spInstall)); } -void Installer::UninstallPkg(const SisFile& aSis) +void Installer::UninstallPkg(const SisFile& aSis, const bool aGenerateRomStub) { TUint32 uid = aSis.GetPackageUid(); TUint32 installType = aSis.GetInstallType(); @@ -466,7 +474,7 @@ // Check to see the SA is installed, otherwise, RemovePkg() will throw an exception if (iRegistry.IsInstalled(uid) && (installType == CSISInfo::EInstInstallation)) { - LINFO(L"Removing package \"" << aSis.GetPackageName() << L"\" prior to re-installation"); + LINFO(L"Removing package \"" << aSis.GetPackageName().c_str() << L"\" prior to re-installation"); // Remove all installed files for this Uid's packages and all the SisRegistry Entries iRegistry.RemovePkg(uid, true); @@ -478,8 +486,32 @@ iRegistry.RemoveEntry(uid, aSis.GetPackageName().c_str(), aSis.GetVendorName().c_str()); } - // Regenerate the ROM stub registry entries for eclipsing check later. - iRegistry.GenerateStubRegistry(); + if(!aGenerateRomStub) + { + // Regenerate the ROM stub registry entries for eclipsing check later. + iRegistry.GenerateStubRegistry(); + } + else + { + std::list stubFileEntries; + + iRegistry.GetStubFileEntries(uid, stubFileEntries); + if((!stubFileEntries.empty())) + { + LINFO(L"Rom Stub Upgrade, removing \"" << iRegistry.GetRomStubFile() << L"\" prior to re-installation"); + RemoveFile(iRegistry.GetRomStubFile()); + + std::list::const_iterator end = stubFileEntries.end(); + for (std::list::const_iterator curr = stubFileEntries.begin() ; + curr != end; ++curr) + { + std::wstring file = *curr; + file[0]='z'; + ConvertToLocalPath(file, iParamList.RomDrivePath()); + RemoveFile(file); + } + } + } } @@ -545,7 +577,7 @@ } -bool Installer::IsValidUpgrade(const SisFile& aFile, bool aSUFlag, bool aNonRemovable) +bool Installer::IsValidUpgrade(const SisFile& aFile, bool aSUFlag, bool aNonRemovable, bool aGenerateRomStub) { TUint32 pkg = aFile.GetPackageUid(); TUint32 installFlags = aFile.GetInstallFlags(); @@ -582,22 +614,44 @@ if (iRegistry.IsInstalled(pkg)) { - ValidateRegistry(aFile,pkg,installFlags,RUFlag,aNonRemovable); + if (aGenerateRomStub && (installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade)) + { + // Installing SP and PU to Rom (z) drive not allowed + std::stringstream err; + err << "Could not perform SP or PU upgrade for Rom (z) drive installation"; + + throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG); + } + else + { + ValidateRegistry(aFile,pkg,installFlags,RUFlag,aNonRemovable,aGenerateRomStub); + } } else if (installType == CSISInfo::EInstAugmentation || installType == CSISInfo::EInstPartialUpgrade) { - // Installing SP and PU without the base package - std::stringstream err; - err << "Could not perform upgrade - the base package 0x" << std::hex - << pkg << " is missing"; + if(iParamList.IsFlagSet(CParameterList::EFlagsRomInstallSet)) + { + // Installing SP and PU to Rom Drive is not supported. + std::stringstream err; + err << "Installing SP and PU to Rom (z) Drive is not supported."; + throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG); + } + else + { + // Installing SP and PU without the base package + std::stringstream err; + err << "Could not perform upgrade - the base package 0x" << std::hex + << pkg << " is missing"; - throw InterpretSisError(err.str(), MISSING_BASE_PACKAGE); + throw InterpretSisError(err.str(), MISSING_BASE_PACKAGE); + } } return true; } -void Installer::ValidateRegistry(const SisFile& aFile, TUint32 aPckgUid, TUint32 aInstallFlags, bool aRUFlag, bool aNonRemovable) +void Installer::ValidateRegistry(const SisFile& aFile, TUint32 aPckgUid, TUint32 aInstallFlags, + bool aRUFlag, bool aNonRemovable, bool aGenerateRomStub) { bool isSisNonRemovable = aInstallFlags & CSISInfo::EInstFlagNonRemovable; bool isBaseRemovable = false; @@ -613,14 +667,14 @@ if (installType == CSISInfo::EInstInstallation) { - if (inRom && !aRUFlag) + if (inRom && !aRUFlag && !aGenerateRomStub) { std::stringstream err; err << "Illegal SA upgrade to ROM package 0x" << std::hex << aPckgUid; throw InterpretSisError(err.str(), ATTEMPT_TO_UPGRADE_ROM_PKG); } // This is not a ROM base package, check is there a SIS stub base package present - else if (iRegistry.IsRomStubPackage(aPckgUid) && !aRUFlag) + else if (iRegistry.IsRomStubPackage(aPckgUid) && !aRUFlag && !aGenerateRomStub) { std::stringstream err; err << "Indirect SA upgrade to ROM package 0x" << std::hex << aPckgUid @@ -711,20 +765,21 @@ } bool Installer::GetInstallableFiles(const SisFile& aFile, InstallableFiles& aList, ExpressionEvaluator& aEvaluator, - int aInstallingDrive) + int aInstallingDrive, const int aSystemDrive, const bool aGenerateRomStub) { return aFile.GetInstallableFiles(aList, aEvaluator, - iConfigManager.GetLocalDrivePath(aInstallingDrive), aInstallingDrive); + iConfigManager.GetLocalDrivePath(aInstallingDrive), aInstallingDrive, aSystemDrive, aGenerateRomStub); } struct InstallFile { - InstallFile(const std::wstring& aCDrive, const int aSystemDrive) - : iSystemDrivePath(aCDrive), iSystemDrive(aSystemDrive) {} + InstallFile(const std::wstring& aCDrive, const int aSystemDrive, const bool aGenerateRomStub) + : iSystemDrivePath(aCDrive), iSystemDrive(aSystemDrive), iGenerateRomStub(aGenerateRomStub) {} const std::wstring& iSystemDrivePath; const int iSystemDrive; + const bool iGenerateRomStub; void operator()(const InstallableFile* aFile) { @@ -742,9 +797,21 @@ { // Unicode characters can not be displayed on DOS prompt std::string temporary = wstring2string(target); + if(temporary[0]=='$') + { + temporary[0] = iSystemDrive; + } std::wstring targetDisplay = string2wstring( temporary ); LINFO(L"Installing file: " << targetDisplay); + if(target[0]==L'$') + { + localTarget = target; + ConvertToLocalPath( localTarget, iSystemDrivePath ); + target[0] = iSystemDrive; + aFile->SetTarget(target); + } + std::wstring targetDirectory = localTarget.substr( 0, localTarget.rfind( KDirectorySeparator ) ); const unsigned char* buffer = NULL; TUint32 len; @@ -762,7 +829,7 @@ // if the FN option specified, leave the file creation if (fileNullOption) { - LINFO(L"File " << target << L" contains \"Delete-File-On-Uninstall\" option." ); + LINFO(L"File " << target.c_str() << L" contains \"Delete-File-On-Uninstall\" option." ); } else { @@ -789,7 +856,7 @@ } } - if (aFile->IsExecutable() && !fileNullOption) + if (aFile->IsExecutable() && !fileNullOption && !iGenerateRomStub) { // register the hash std::wstring basename = localTarget.substr( localTarget.rfind( KDirectorySeparator ) + 1 ); @@ -835,11 +902,16 @@ }; -void Installer::InstallFiles(const InstallableFiles& aList, const int aInstallDrive) +void Installer::InstallFiles(const InstallableFiles& aList, int aInstallDrive, const bool aGenerateRomStub) { + if(aGenerateRomStub) + { + aInstallDrive = 'z'; //Rom Drive + } + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(aInstallDrive); - std::for_each(aList.begin(), aList.end(), InstallFile(localTargetPath, aInstallDrive)); + std::for_each(aList.begin(), aList.end(), InstallFile(localTargetPath, aInstallDrive, aGenerateRomStub)); } @@ -1154,6 +1226,41 @@ return isEclipsable; } +/** This function handles file overwriting scenarios from Stub SIS files only and not from SISregistry. + (i.e: we are trying to install z:\somedir\somename.ext however it already exists) + @param aFile the SIS file to be installed + @param aTarget The fully qualified filename (full path and name) +*/ +void Installer::HandleRomFileOverwriting(const SisFile& aFile, const std::wstring& aTarget) +{ + // find out which Rom Stub this file belongs to + TUint32 owningUid = 0; + CSISController* sisController = iRegistry.GetStubControllerUid(aTarget); + + if(sisController) + { + owningUid=sisController->UID1(); + } + + // no package owns this file. Always allow orphaned file overwriting! + if (owningUid == 0) + { + LWARN(aTarget << L" overwrites orphaned file"); + } + else if (aFile.GetPackageUid() != owningUid) + { + std::wostringstream os; + os << aTarget.c_str() << L" overwrites file from package 0x" << std::hex << owningUid << L" \"" << sisController->SISInfo().PackageName(0) << L"\"" << std::endl; + iProblemFiles.append(os.str()); + iError = ECLIPSING_VIOLATION; + } + + if(sisController) + { + delete sisController; + } +} + /** This function handles overwriting scenarios (i.e: we are trying to install c:\somedir\somename.ext however it already exists) In this case we have 2 possibilities: 1) We are correctly overwriting the already present file (a PU) @@ -1283,9 +1390,6 @@ int num_of_files = aFiles.size(); TUint32 pkgUid = aFile.GetPackageUid(); TUint32 installType = aFile.GetInstallType(); - std::list stubFileEntries; - - iRegistry.GetStubFileEntries(pkgUid, stubFileEntries); // if a base package exists, check to see if it chains back to a ROM stub. If so, populate // iEclipsableRomFiles with the files owned by the ROM stub. Only ROM files can be eclipsed. @@ -1341,6 +1445,16 @@ continue; } } + + if(aInstallSISFile.iGenerateRomStub) + { + bool isOverwrite = FileExists(file->GetLocalTarget()); + // To check if We are incorrectly overwriting the file present. + if (isOverwrite) + { + HandleRomFileOverwriting(aFile, target); + } + } // additional platsec checks if (target.find(privatePath) != std::wstring::npos) @@ -1574,6 +1688,45 @@ } +void Installer::CreateRomStubSisFile(const InstallSISFile& aInstallSISFile, SisFile& aSis) +{ + + int targetDrive = aInstallSISFile.iTargetDrive; + std::wstring drivePath = iConfigManager.GetLocalDrivePath(targetDrive); + + #ifndef __TOOLS2_LINUX__ + drivePath.append(L"\\system\\install\\"); + #else + drivePath.append(L"/system/install/"); + #endif + + // build Rom Stub Pathname + if ( !MakeDir( drivePath ) ) + { + throw InterpretSisError(L"Directory Creation Error - "+drivePath, DIRECTORY_CREATION_ERROR); + } + + size_t found; + found=aInstallSISFile.iFileName.find_last_of(L"/\\"); + std::wstring sisFile = aInstallSISFile.iFileName.substr(found+1); + std::wstring sisFilename = sisFile.substr(0,sisFile.length()-4); + drivePath.append(sisFilename); + drivePath.append(L"_"); + std::wstringstream sUid; + sUid << std::hex << aSis.GetPackageUid(); + drivePath.append(sUid.str()); + drivePath.append(L".sis"); + + // Display the target SIS file. Format the stub SIS file string so it displays correctly. + std::wstring ctrlDrive(L"z:"); + std::wstring ctrlTarget = drivePath.substr(iConfigManager.GetLocalDrivePath(targetDrive).length(),drivePath.length()); + ctrlDrive.append(ctrlTarget); + + LINFO(L"\tCreating ROM stub: " << ctrlDrive); + aSis.MakeSISRomStub(drivePath); + // If the NR flag is set, change the file attribute to RO +} + void Installer::CreateStubSisFile(const InstallSISFile& aInstallSISFile, SisFile& aSis) { int targetDrive = aInstallSISFile.iTargetDrive;