secureswitools/swisistools/source/interpretsislib/installer.cpp
branchRCL_3
changeset 73 79647526f98c
parent 66 8b7f4e561641
child 81 42552535c1ac
--- 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<std::wstring> 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<std::wstring>::const_iterator end = stubFileEntries.end();
+			for (std::list<std::wstring>::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<std::wstring> 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;