diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/interpretsislib/sisregistry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/interpretsislib/sisregistry.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,2146 @@ +/* +* Copyright (c) 2006-2009 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" +* 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: +* +*/ + + +#pragma warning (disable: 4786) + +#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + +#include "dbhelper.h" +#include "dblayer.h" +#include "dbconstants.h" +#include "is_utils.h" +#include "xmlgenerator.h" +#include "xmlparser.h" +#include "util.h" +#include +#include +#include +#include + +#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK +// constants +#define IGNORE_FORMATTING -1 +#define ENABLE 1 +#define DISABLE 0 +// System Includes +#include +#include +#include +#include +#include + +#ifndef __TOOLS2_LINUX__ +#include +#endif + +// SisX Library Includes +#include "sisfiledescription.h" +#include "sisstring.h" + +// User Includes +#include "sisregistry.h" +#include "errors.h" +#include "rommanager.h" +#include "stringutils.h" +#include "is_utils.h" +#include "sisfile.h" +#include "sisregistrypackage.h" +#include "sisregistryobject.h" +#include "configmanager.h" + +// Constants +const std::wstring SisRegistry::KPathToRegistry(L"\\sys\\install\\sisregistry/"); +const std::wstring SisRegistry::KPathToRomStubs(L"\\system\\install\\"); +const std::wstring SisRegistry::KPathToRegistryVersionMarker(L"\\system\\data\\"); +const std::wstring KRegistryEntry(L"00000000.reg"); +const std::wstring KControllerEntry(L"00000000_0000.ctl"); +const std::wstring KBackupLst(L"backup.lst"); + +const int SisRegistry::KSisRegistryMajorVersion = 5; +const int SisRegistry::KSisRegistryMinorVersion = 1; + +// Supported SisRegistry versions +const std::wstring SisRegistry::KRegistryFormat(L"sisregistry_?.?.txt"); +const std::wstring SisRegistry::KRegistryV40(L"sisregistry_4.0.txt"); +const std::wstring SisRegistry::KRegistryV51(L"sisregistry_5.1.txt"); +const std::wstring SisRegistry::KRegistryV52(L"sisregistry_5.2.txt"); +const std::wstring SisRegistry::KRegistryV53(L"sisregistry_5.3.txt"); +const std::wstring SisRegistry::KRegistryV54(L"sisregistry_5.4.txt"); +const std::wstring SisRegistry::KRomStubDir(L"z:\\system\\install\\"); +const std::wstring SisRegistry::KRomRegistryVersionMarker(L"z:\\system\\data\\"); + +const std::string SisRegistry::KRegistryV40string("4.0"); +const std::string SisRegistry::KRegistryV50string("5.0"); +const std::string SisRegistry::KRegistryV51string("5.1"); +const std::string SisRegistry::KRegistryV52string("5.2"); +const std::string SisRegistry::KRegistryV53string("5.3"); +const std::string SisRegistry::KRegistryV54string("5.4"); + +#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK +const std::wstring SisRegistry::NativeSoftwareType(L"native"); + +#ifdef _MSC_VER +// "." and ".ctl" +// VC does not have ".." entry +const int KDirFileCount = 2; + +#else +// "." ".." and ".ctl" +const int KDirFileCount = 3; + +#endif + +#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + +// KRegDirFileCount is the number of directory entries present +// in the reg directory when there is no upgrade is made to the +// package. i.e. one .reg and one .ctl file +// +#ifdef _MSC_VER +// "." ".reg" and ".ctl" +// VC does not have ".." entry +const int KRegDirFileCount = 3; + +#else +// "." ".." ".reg" and ".ctl" +const int KRegDirFileCount = 4; + +#endif + +// function object for determining if all characters are valid hex chars +struct AllHexDigits + { + bool result; + + AllHexDigits() : result(true) {} + void operator()(char a) + { + if (!((a >= '0' && a <= '9') || + (a >= 'a' && a <= 'f') || + (a >= 'A' && a <= 'F'))) + { + result = false; + } + } + }; + +// function object for retreiving keys from the sisregistry entry map +struct CopyUids + { + CopyUids(std::vector& uids) : iUids(uids) {} + std::vector& iUids; + + void operator()(SisRegistry::EntryMap::value_type& a) + { iUids.push_back(a.first); } + }; + + +struct FindFile + { + FindFile(const std::wstring& aFile) : iFile(aFile), iFileDescr(0) {} + + bool operator()(const SisRegistry::EntryMap::value_type& val) + { + const SisRegistryObject& obj = *val.second; + return (iFileDescr = obj.GetFile(iFile)) != 0; + } + + std::wstring iFile; + const FileDescription* iFileDescr; + }; + + +struct FindFile2 + { + FindFile2(TUint32 aSid, const FileDescription*& aFd) : + iSid(aSid), iFileDescr(aFd) {} + + bool operator()(const SisRegistry::EntryMap::value_type& val) + { + const SisRegistryObject& obj = *val.second; + if (iFileDescr = obj.GetFile(iSid)) + { + return true; + } + return false; + } + + TUint32 iSid; + const FileDescription*& iFileDescr; + }; + + +struct Contains + { + const std::wstring& iFile; + + Contains(const std::wstring& aFilename) : iFile(aFilename) + {} + + SisRegistryObject* operator()(const SisRegistry::EntryMap::value_type& aObj) + { + if (aObj.second->GetFile(iFile) != 0) + { + return aObj.second; + } + } + }; + +SisRegistry::SisRegistry( CParameterList& aOptions, RomManager& aRomManager, ConfigManager& aConfigManager) +: iParamList( aOptions ), iRomManager( aRomManager ), iConfigManager( aConfigManager ) + { + // Determine which version of the SisRegistry to generate + if (iParamList.RegistryVersionExists() == false) + { + ReadSisRegistryVersion(); + } + + if(iParamList.RegistryVersionExists()) + { + LINFO(L"Using SIS Registry v" << iParamList.RegistryMajorVersion() << L"." << iParamList.RegistryMinorVersion()); + + std::wstring registryPathDriveC = KPathToRegistry; + + ConvertToLocalPath( registryPathDriveC, iParamList.SystemDrivePath() ); + + ReadRegistry( registryPathDriveC ); + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + // this code is for handling the database registry implementation + else + { + LINFO(L"Using database implementation of SIS Registry"); + + int val = iParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet); + if ( + (iParamList.RomLogFileNames().size() != 0 && iParamList.RomDrivePath().size() == 0 ) || + iParamList.IsFlagSet( CParameterList::EFlagsDisableZDriveChecksSet) + ) + { + iDbHelper = new DbHelper(iParamList.SystemDrivePath(), true); + } + else + { + iDbHelper = new DbHelper(iParamList.RomDrivePath(), false); + } + } + #endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + GenerateStubRegistry(); + } + + +SisRegistry::~SisRegistry() + { + if(iParamList.RegistryVersionExists()) + { + EntryMap::const_iterator end = iEntries.end(); + for (EntryMap::const_iterator curr = iEntries.begin() ; + curr != end; ++curr) + { + delete curr->second; + } + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + delete iDbHelper; + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } +/** + * If the ROM drive has been defined, find the marker file in the stub directory + * e.g. z:\system\data\. If using the ROM/ROFS logs, find the marker file in the + * logs. If not found, then check to see if the marker file exists in the ROM stub directory + * specified using the -t option. If still not found, use the default version of the Sis Registry. + */ +void SisRegistry::ReadSisRegistryVersion() + { + // ROM drive defined + if (iParamList.IsFlagSet(CParameterList::EFlagsZDriveSet)) + { + // ROM SisRegistry marker file + std::wstring stubPathZ = KPathToRegistryVersionMarker; + ConvertToLocalPath( stubPathZ, iParamList.RomDrivePath() ); + + FindMarkerAndSetVersion(stubPathZ); + } + // ROM/ROFS logs defined + else if (iParamList.IsFlagSet(CParameterList::EFlagsRomRofsLogFilesSet)) + { + // Check the stub dir + if (iParamList.IsFlagSet(CParameterList::EFlagsStubDirectorySet)) + { + // ROM SisRegistry marker file + std::wstring customStubPath = iParamList.SisStubPath(); + + FindMarkerAndSetVersion(customStubPath); + } + + // Search in the ROM/ROFS logs. This takes precedence over the stub dir + if(iRomManager.RomFileExists(KPathToRegistryVersionMarker+KRegistryV40)) + { + iParamList.SetRegistryMajorVersion(4); + iParamList.SetRegistryMinorVersion(0); + } + else if(iRomManager.RomFileExists(KRomRegistryVersionMarker+KRegistryV51)) + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(1); + } + else if(iRomManager.RomFileExists(KRomRegistryVersionMarker+KRegistryV52)) + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(2); + } + else if(iRomManager.RomFileExists(KRomRegistryVersionMarker+KRegistryV53)) + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(3); + } + else if(iRomManager.RomFileExists(KRomRegistryVersionMarker+KRegistryV54)) + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(4); + } + } + #ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + // No valid ROM stub marker (sisregistry_x.x.txt) found! + // Revert to the default (5.1) SisRegistry version as defined + // by KSisRegistryMajorVersion and KSisRegistryMinorVersion + if (iParamList.RegistryMajorVersion() == 0 && iParamList.RegistryMinorVersion() == 0) + { + iParamList.SetRegistryMajorVersion(KSisRegistryMajorVersion); + iParamList.SetRegistryMinorVersion(KSisRegistryMinorVersion); + } + #endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + + +void SisRegistry::FindMarkerAndSetVersion(const std::wstring& aPath) + { + // Make sure the system\data directory name is properly terminated. + std::wstring basePath = StringUtils::EnsureDirectoryTerminated( aPath ); + + std::list systemDir; + GetDirContents( basePath, systemDir ); + + // Loop on the system\data files until we find a SisRegistry marker file + std::list::iterator curr = systemDir.begin(); + while (curr != systemDir.end()) + { + std::wstring fileFound ( *curr ); + + // Found the SisRegistry marker file + if (fileFound.compare(KRegistryV40) == 0) + { + iParamList.SetRegistryMajorVersion(4); + iParamList.SetRegistryMinorVersion(0); + } + else if (fileFound.compare(KRegistryV51) == 0) // introduced isRemovable flag + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(1); + } + else if (fileFound.compare(KRegistryV52) == 0) // fixed DEF114705 - SIS controller incorrect + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(2); + } + else if (fileFound.compare(KRegistryV53) == 0) // introduced SU cert flag + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(3); + } + else if (fileFound.compare(KRegistryV54) == 0) // Support for exact & equivalent device supported languages + { + iParamList.SetRegistryMajorVersion(5); + iParamList.SetRegistryMinorVersion(4); + } + + ++curr; + } + } + + + + +bool SisRegistry::IsPackageDir(const std::wstring& aString) + { + AllHexDigits digits; + std::for_each(aString.begin(), aString.end(), digits); + return aString.length() == 8 && digits.result; + } + +TBool SisRegistry::IsInstalled(TUint32 aUid) const + { + if(iParamList.RegistryVersionExists()) + { + return iEntries.find(aUid) != iEntries.end();; + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + return iDbHelper->IsInstalled(aUid); + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + return false; + } + + +const SisRegistryObject& SisRegistry::GetRegistryObject(TUint32 aUid) const + { + if(iParamList.RegistryVersionExists()) + { + EntryMap::const_iterator end = iEntries.end(); + for (EntryMap::const_iterator curr = iEntries.begin() ; + curr != end; ++curr) + { + if ((curr->first == aUid) && ((*curr->second).GetIndex() == 0)) + { + return *curr->second; + } + } + } + + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + SisRegistryObject* sisRegistryObject = new SisRegistryObject(iConfigManager); + if(iDbHelper->InternalizeIfExists(*sisRegistryObject, aUid)) + { + return *sisRegistryObject; + } + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + throw std::runtime_error("Couldn't find specified package"); + } + +SisRegistryObject* SisRegistry::GetRegistryObjectPtr(TUint32 aUid) + { + if(iParamList.RegistryVersionExists()) + { + EntryMap::const_iterator end = iEntries.end(); + for (EntryMap::const_iterator curr = iEntries.begin() ; + curr != end; ++curr) + { + if ((curr->first == aUid) && ((curr->second)->GetIndex() == 0)) + { + return curr->second; + } + } + } + + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + SisRegistryObject* sisRegistryObject = new SisRegistryObject(iConfigManager); + if(iDbHelper->InternalizeIfExists(*sisRegistryObject, aUid)) + { + return sisRegistryObject; + } + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + throw std::runtime_error("Couldn't find specified package"); + } + +const SisRegistryPackage& SisRegistry::SidToPackage(TUint32 aSid) + { + const FileDescription* fileDesc = 0; + FindFile2 fileFinder(aSid, fileDesc); + + EntryMap::iterator x = std::find_if(iEntries.begin(), + iEntries.end(), + fileFinder); + + if (x != iEntries.end()) + { + return *x->second; + } + else + { + throw std::runtime_error("Couldn't find specified file"); + } + } + + +void SisRegistry::SidToFileName(TUint32 aSid, std::wstring& aFileName) + { + if(iParamList.RegistryVersionExists()) + { + const FileDescription* fileDesc = 0; + FindFile2 fileFinder(aSid, fileDesc); + + EntryMap::iterator x = std::find_if(iEntries.begin(), + iEntries.end(), + fileFinder); + + if (x != iEntries.end()) + { + aFileName = fileFinder.iFileDescr->GetTarget(); + } + else + { + throw std::runtime_error("Couldn't find specified file"); + } + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + aFileName = iDbHelper->SidToFileName(aSid); + if(aFileName.empty()) + { + throw std::runtime_error("Couldn't find specified file"); + } + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + + +bool SisRegistry::SidExists(TUint32 aSid) const + { + if(iParamList.RegistryVersionExists()) + { + const FileDescription* fileDesc = 0; + FindFile2 fileFinder(aSid, fileDesc); + + EntryMap::const_iterator x = std::find_if(iEntries.begin(), + iEntries.end(), + fileFinder); + + return x != iEntries.end(); + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + return iDbHelper->SidExists(aSid); + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + return false; + } + + +void SisRegistry::RemoveEntry(const TUint32 aUid, const std::wstring& aPackageName, const std::wstring& aVendorName) + { + if(iParamList.RegistryVersionExists()) + { + EntryMap::iterator it = iEntries.find(aUid); + + while(it != iEntries.end()) + { + if (aUid == it->first && + aPackageName == it->second->GetPackageName() && + aVendorName == it->second->GetVendorName()) + { + LINFO(L"Removing package \"" << it->second->GetPackageName() + << L"\" prior to re-installation"); + + // Remove .reg file + std::wstring registryPath = it->second->GetRegistryDir( iParamList.SystemDrivePath() ); + RemoveFile(registryPath + StringUtils::BuildSisRegistryFileName( it->second->GetIndex() )); + + // Remove .ctl file + int drive = tolower(it->second->GetSelectedDrive()); + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(drive); + registryPath = it->second->GetRegistryDir( localTargetPath ); + RemoveFile(registryPath + StringUtils::BuildControllerFileName( it->second->GetIndex(), 0 )); + + // Remove the installed files for this SisRegistryObject + const FileDescriptions& files = it->second->GetFileDescriptions(); + + RemoveInstalledFiles(files, localTargetPath); + + // Clean up the SisRegistryObject + delete it->second; + iEntries.erase(it); + + return; + } + ++it; + } + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + + // the vendor name here is the unique vendore name + TInt32 componentId = iDbHelper->GetComponentId(aUid, aPackageName, aVendorName); + if(componentId == DbHelper::Absent) + { + return; + } + + LINFO(L"Removing package \"" << aPackageName << L"\" prior to re-installation"); + + // Remove .ctl file + int drive = tolower(iDbHelper->GetSelectedDrive(componentId)); + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(drive); + std::wstring registryPath = GetRegistryDir( localTargetPath,componentId ); + RemoveFile(registryPath + StringUtils::BuildControllerFileName( iDbHelper->GetIndex(componentId), 0 )); + + // Remove the installed files for this SisRegistryObject + const FileDescriptions& files = iDbHelper->GetFileDescriptions(componentId); + + RemoveInstalledFiles(files, localTargetPath); + + iDbHelper->RemoveEntry(componentId); + + } + #endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } +void SisRegistry::RemovePkg(const TUint32& aUid, bool aSkipRomStub) + { + if(iParamList.RegistryVersionExists()) + { + RemovePkgLegacy(aUid,aSkipRomStub); + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + RemovePkgWithScr(aUid,aSkipRomStub); + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + +void SisRegistry::RemovePkgLegacy(const TUint32& aUid, bool aSkipRomStub) + { + EntryMap::iterator currObj = iEntries.find(aUid); + + if (currObj == iEntries.end()) + { + // No SisRegistry file found!! + std::stringstream err; + err << " SisRegistry entry for 0x" << std::hex << aUid << L" Not found"; + + throw std::runtime_error(err.str()); + } + + std::list regDirFiles; + std::wstring path = currObj->second->GetRegistryDir( iParamList.SystemDrivePath() ); + + GetDirContents(path, regDirFiles); + + if (regDirFiles.size() == KRegDirFileCount && currObj->second->GetInRom()) + { + // I.e. there are only .., one .reg and one .ctl file present + // check whether it is a ROM stub object (without any upgrades) + + if (aSkipRomStub) + { + // Since this is only a ROM stub entry, leave it as it is; + // to avoid regenerate it again. + return; + } + + std::stringstream err; + err << "Illegal uninstall of ROM package 0x" << std::hex << aUid; + throw InterpretSisError(err.str(), ATTEMPT_TO_UNINSTALL_ROM_PKG); + } + + std::list::iterator currFile = regDirFiles.begin(); + + // Remove all the .reg and .ctl files in the system drive for this package + while (currFile != regDirFiles.end()) + { + if (*currFile != L"." && *currFile != L"..") + { + RemoveFile(path + *currFile); + } + + ++currFile; + } + + // Remove the installed files for all packages (SA, SP, PU) + while (currObj != iEntries.end()) + { + // For ROM stub, the SelectedDrive = 0; as there could be ROM->SP. + // Therefore, the rest can only apply to at least a ROM stub upgrades + int drive = tolower(currObj->second->GetSelectedDrive()); + + if (drive) + { + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(drive); + path = currObj->second->GetRegistryDir( localTargetPath ); + + regDirFiles.clear(); + GetDirContents(path, regDirFiles); + + currFile = regDirFiles.begin(); + + // Remove all the .ctl files for this package + while (currFile != regDirFiles.end()) + { + if (*currFile != L"." && *currFile != L"..") + { + RemoveFile(path + *currFile); + } + ++currFile; + } + + // This iterator's object has the same Uid as aUid + const FileDescriptions& files = currObj->second->GetFileDescriptions(); + + RemoveInstalledFiles(files, localTargetPath); + } + + + // Clean up the SisRegistryObject + delete currObj->second; + iEntries.erase(currObj); + + currObj = iEntries.find(aUid); + } + } + +std::wstring SisRegistry::GetRegistryDir( const std::wstring& aDrivePath, TUint32 aUid ) const + { + std::wstring ret = StringUtils::MakePathFromSID( aDrivePath + L"/sys/install/sisregistry/", aUid ); + return ret; + } + +void SisRegistry::RemoveInstalledFiles(const FileDescriptions& aFileDes, std::wstring& aLocalPath) +{ + FileDescriptions::const_iterator curr = aFileDes.begin(); + FileDescriptions::const_iterator end = aFileDes.end(); + + for ( ; curr != end ; ++curr) + { + std::wstring target((*curr)->GetTarget()); + + ConvertToLocalPath(target, aLocalPath); + RemoveFile(target); + RemoveHashForFile(target, iParamList.SystemDriveLetter(), iParamList.SystemDrivePath()); + } +} + + +void SisRegistry::AddRegistryEntry( const SisFile& aSis, const InstallableFiles& aFiles, + const InstallSISFile& aInstallSISFile ) + { + SisRegistryObject* obj = new SisRegistryObject( aSis, aFiles, aInstallSISFile.iTargetDrive, + iParamList.RegistryMajorVersion(), iParamList.RegistryMinorVersion(), aInstallSISFile.iSUFlag, iConfigManager ); + + // Generate .reg and .ctl file for native installation. + // Installation based on database registration, generate only the .ctl file. + GenerateRegistryEntry(*obj, aSis); + + if(iParamList.RegistryVersionExists()) + { + // Add the registry entry to the registry + iEntries.insert(EntryMap::value_type(obj->GetUid(),obj)); + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + // if the entry already exists then remove it first + // this is the case where an in rom application is getting + // overwritten by an SA type. + // in case of db the entry is stored in the database from where first it has + // to be removed and then readded based on the updated registry object which is + // in memory. In case of file based registry update this is done is a separate + // way, it reads the existing registry entry and store it in memory, and updates the same + // entry in memory and then over-writes the old registry entry with the update entry. + TInt32 componentId = iDbHelper->GetComponentId(obj->GetUid(), obj->GetInstallType() ); + if(componentId != DbHelper::Absent) + { + iDbHelper->RemoveEntry(componentId); + } + obj->SetValidationStatus(iParamList.OriginVerificationStatus()); + GenerateDbRegistryEntry(*obj, iParamList.OriginVerificationStatus()); + } + #endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + } + +void SisRegistry::UpdateRegistryEntry(const SisFile& aSis, + const InstallableFiles& aFiles, const InstallSISFile& aInstallSISFile) +{ + TUint32 pkg = aSis.GetPackageUid(); + + SisRegistryObject* obj = GetRegistryObjectPtr(pkg); + obj->UpgradeEntry(aSis, aFiles, aInstallSISFile.iTargetDrive, aInstallSISFile.iSUFlag, iConfigManager); + + // Update/Create the .reg and .ctl files + GenerateRegistryEntry(*obj, aSis); + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + if(!iParamList.RegistryVersionExists()) + { + TUint32 componentId = iDbHelper->GetComponentId(pkg); + // remove the application from database + iDbHelper->RemoveEntry(componentId); + + obj->SetValidationStatus(iParamList.OriginVerificationStatus()); + GenerateDbRegistryEntry(*obj, iParamList.OriginVerificationStatus()); + } + + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK +} + +const SisRegistryObject* SisRegistry::OwningPackage( const std::wstring& aFilename, TUint32& aUid ) const +{ + if(iParamList.RegistryVersionExists()) + { + // Loop through iEntries, then loop through file desc for spec UID, then return the obj + for (EntryMap::const_iterator curr = iEntries.begin() ; + curr != iEntries.end() ; + ++curr) + { + // Get the file descriptions + if (curr->second->GetFile(aFilename) != 0) + { + aUid = curr->first; + return curr->second; + } + } + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + aUid = iDbHelper->GetUidFromFileName(aFilename); + if(aUid != 0) + { + SisRegistryObject* sisRegistryObject = new SisRegistryObject(iConfigManager); + if(iDbHelper->InternalizeIfExists(*sisRegistryObject,aUid)) + { + return sisRegistryObject; + } + } + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + return NULL; + } + + +void SisRegistry::RemoveBackupLst() + { + std::wstring backup = KPathToRegistry + KBackupLst; + ConvertToLocalPath( backup, iParamList.SystemDrivePath() ); + + if ( FileExists( backup ) ) + { + RemoveFile( backup ); + } + } + + +void SisRegistry::ReadStubs( const std::wstring& aDirectory ) + { + // Make sure the directory name is properly terminated. + std::wstring basePath = StringUtils::EnsureDirectoryTerminated( aDirectory ); + + std::list stubDirs; + GetDirContents( basePath, stubDirs ); + + std::list::iterator curr; + + for(curr = stubDirs.begin(); curr!= stubDirs.end(); ++curr) + { + std::wstring stubPath ( basePath + *curr ); + + if( !IsSisValid(stubPath) ) + continue; + + _TCHAR* fileName = const_cast<_TCHAR *>(stubPath.c_str()); + std::auto_ptr sisController(ReadStubController( fileName )); + + if (!sisController.get()) + { + LERROR(L"\tCannot create CSISController for "<< stubPath); + continue; + } + + if (IsInstalled(sisController->UID1())) + { + // Has already been upgraded + continue; + } + + SisRegistryObject* aObj = new SisRegistryObject(*sisController, iRomManager, + iParamList.RegistryMajorVersion(), + iParamList.RegistryMinorVersion(), + iConfigManager); + GenerateStubRegistry(aObj,sisController.get()); + + } // for + } + + +TBool SisRegistry::IsSisValid(const std::wstring& aStubPath) + { + int dotIndex = aStubPath.rfind(L"."); + if(dotIndex == std::wstring::npos) + return false; + std::wstring extOfString = aStubPath.substr(dotIndex+1); + std::wstring extOfStringUpper = StringUtils::ToUpper(extOfString); + if (extOfStringUpper != L"SIS" && extOfStringUpper != L"SISX") + return false; + return true; + } + +void SisRegistry::GenerateStubRegistry(SisRegistryObject* aSisRegistryObject, CSISController* aSisController) + { + // create the directory to be used for storing reg and ctl files + std::wstring regPath = aSisRegistryObject->GetRegistryDir( L"" ); + ConvertToLocalPath( regPath, iParamList.SystemDrivePath() ); + if ( !MakeDir( regPath ) ) + { + throw InterpretSisError(L"Directory Creation Error - "+regPath, DIRECTORY_CREATION_ERROR); + } + + LINFO(L"\tAdding ROM Stub: 0x" << std::hex << aSisRegistryObject->GetUid() << L" \"" << aSisRegistryObject->GetPackageName() << L"\""); + + if(iParamList.RegistryVersionExists()) + { + iEntries.insert( EntryMap::value_type( aSisRegistryObject->GetUid(), aSisRegistryObject ) ); + + // Create the ROM Stub registry entries + + std::fstream regFile; + std::wstring reg = regPath+KRegistryEntry; + + OpenFile( reg, regFile, std::ios::out | std::ios::binary ); + + Serialiser s(regFile); + + // Create the .reg file: + s << aSisRegistryObject; + + regFile.close(); + } + + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + GenerateDbRegistryEntry(*aSisRegistryObject, iParamList.OriginVerificationStatus()); + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + // Create the .ctl file: + std::fstream ctlFile; + OpenFile( regPath+KControllerEntry, ctlFile, std::ios::out | std::ios::binary ); + + const unsigned char* ctl = aSisController->RawBuffer(); + int len = aSisController->BufferSize(); + + ctlFile.write((const char*)&len, 4); + ctlFile.write((char*)ctl, len); + ctlFile.close(); + } + +bool SisRegistry::IsFileWideCard(const std::wstring& aFileName) + { + return (aFileName.find(L'?') != std::wstring::npos || + aFileName.find(L'*') != std::wstring::npos || + aFileName[aFileName.length() - 1] == L'\\'); + } + + +void SisRegistry::GenerateStubRegistry() + { + if (!iParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet)) + { + // If the -z option were used to launch the tool, then read any + // SIS stubs that we have gathered from the emulated z:\system\install + // location. + if (iParamList.IsFlagSet(CParameterList::EFlagsZDriveSet)) + { + std::wstring stubPathZ = KPathToRomStubs; + ConvertToLocalPath( stubPathZ, iParamList.RomDrivePath() ); + ReadStubs( stubPathZ ); + } + + // If an additional SIS stub path were specified, we'll + // also handle that here too. + if (iParamList.IsFlagSet(CParameterList::EFlagsStubDirectorySet)) + { + bool readCustomStubPath = true; + std::wstring customStubPath = iParamList.SisStubPath(); + + // But make sure we don't read the same directory twice! + const bool haveRomDrive = iParamList.IsFlagSet(CParameterList::EFlagsZDriveSet); + if ( haveRomDrive ) + { + std::wstring stubPathZ = KPathToRomStubs; + ConvertToLocalPath( stubPathZ, iParamList.RomDrivePath() ); + readCustomStubPath = ( stubPathZ != customStubPath ); + } + + if ( readCustomStubPath ) + { + ReadStubs( customStubPath ); + } + } + } + } + + +void SisRegistry::ReadRegistry( const std::wstring& aRegistryBasePath ) + { + std::list regDirs; + GetDirContents( aRegistryBasePath, regDirs ); + + std::list::iterator curr = regDirs.begin(); + + LINFO(L"Reconstructing SIS Registry..."); + + for( curr = regDirs.begin(); curr != regDirs.end(); ++curr ) + { + struct stat s; + const std::wstring entryPath = aRegistryBasePath + *curr; + const int err = GetStat(entryPath.c_str(), &s); + + if ( err ) + continue; + + const bool isDir = (s.st_mode & S_IFDIR) != 0; + + if (isDir && IsPackageDir(*curr)) + { + ExtractRegistryFiles(entryPath); + } + } + } + + +void SisRegistry::ExtractRegistryFiles(const std::wstring& aPath) + { + std::list contents; + GetDirContents(aPath, contents); + + for (std::list::iterator c = contents.begin(); c != contents.end(); ++c) + { + if (c->find(L".reg",0) == std::wstring::npos) + continue; + + std::fstream input; + std::wstring filename(aPath + L"\\" + *c); + + OpenFile(filename.c_str(), input, std::fstream::in | std::fstream::binary); + + if (!input.good()) + continue; + + SisRegistryObject* obj = new SisRegistryObject(iConfigManager); + + if (!obj) + { + throw std::runtime_error("Cannot create SisRegistryObject for " + Ucs2ToUtf8(filename)); + } + Deserialiser des(input); + + des >> *obj; + iEntries.insert(EntryMap::value_type(obj->GetUid(), obj)); + + LINFO(L"\tExtracting: 0x" << std::hex << obj->GetUid() << L" \"" << obj->GetPackageName() << L"\""); + + } + } + + +bool SisRegistry::IsRomStubPackage(const TUint32 aUid) + { + CSISController* sisController = GetStubController(aUid); + + if (sisController) + { + delete sisController; + return true; + } + + return false; + } + + +void SisRegistry::GetStubFileEntries(const TUint32 aUid, std::list& aFilesEntries) + { + std::auto_ptr sisController(GetStubController(aUid)); + + if (!sisController.get()) + return; + const CSISInstallBlock& installBlock = sisController->InstallBlock(); + int fileCount = installBlock.FileCount(); + + for (int i = 0; i < fileCount; ++i) + { + std::wstring target(installBlock.FileDescription(i).Target().GetString()); + aFilesEntries.push_back(target); + } + } + + +CSISController* SisRegistry::GetStubController(const TUint32 aUid) + { + if (iParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet)) + { + return NULL; + } + // If the -z option were used to launch the tool, then read any + // SIS stubs that we have gathered from the emulated Z:\System\Install + // location. + if (iParamList.IsFlagSet(CParameterList::EFlagsZDriveSet)) + { + std::wstring stubPathZ = KPathToRomStubs; + ConvertToLocalPath( stubPathZ, iParamList.RomDrivePath() ); + CSISController* sisController = GetStubControllerInDir( stubPathZ, aUid ); + + if (sisController) + { + return sisController; + } + } + + // If an additional SIS stub path were specified, we'll + // also handle that here too. + if (iParamList.IsFlagSet(CParameterList::EFlagsStubDirectorySet)) + { + bool readCustomStubPath = true; + std::wstring customStubPath = iParamList.SisStubPath(); + + // But make sure we don't read the same directory twice! + const bool haveRomDrive = iParamList.IsFlagSet(CParameterList::EFlagsZDriveSet); + if ( haveRomDrive ) + { + std::wstring stubPathZ = KPathToRomStubs; + ConvertToLocalPath( stubPathZ, iParamList.RomDrivePath() ); + readCustomStubPath = ( stubPathZ != customStubPath ); + } + + if ( readCustomStubPath ) + { + CSISController* sisController = GetStubControllerInDir( customStubPath, aUid ); + + if (sisController) + { + return sisController; + } + } + } + return NULL; + } + + +CSISController* SisRegistry::GetStubControllerInDir( const std::wstring& aDirectory, const TUint32 aUid) +{ + // Make sure the directory name is properly terminated. + std::wstring basePath = StringUtils::EnsureDirectoryTerminated( aDirectory ); + + std::list stubDirs; + GetDirContents( basePath, stubDirs ); + + std::list::iterator curr; + for (curr = stubDirs.begin(); curr != stubDirs.end() ; ++curr) + { + std::wstring stubPath ( basePath + *curr ); + int dotIndex = stubPath.rfind(L"."); + if(dotIndex == std::wstring::npos) + continue; + + std::wstring extOfString = stubPath.substr(dotIndex+1); + + std::wstring extOfStringUpper = StringUtils::ToUpper(extOfString); + if (extOfStringUpper != L"SIS" && extOfStringUpper != L"SISX") + continue; + + _TCHAR* fileName = const_cast<_TCHAR *>(stubPath.c_str()); + CSISController* sisController = ReadStubController( fileName ); + + if (!sisController) + continue; + + if (sisController->UID1() == aUid) + { + return sisController; + } + delete sisController; + } + return NULL; +} + + +CSISController* SisRegistry::ReadStubController( const wchar_t* aFileName ) + { + const bool isSisFile = CSISContents::IsSisFile(aFileName); + CSISController* sisController = NULL; + + if (isSisFile) + { + LWARN(L"\tIgnoring invalid SIS stub: " << aFileName); + return sisController; + } + SisRegistryObject* aObj = NULL; + + TSISStream input; + std::wstring fileName = FixPathDelimiters(aFileName); + HANDLE file = ::MakeSISOpenFile(fileName.c_str(),GENERIC_READ,OPEN_EXISTING); + if (INVALID_HANDLE_VALUE == file) + { + LERROR(L" Error : Cannot open file : " << fileName << std::endl); + throw CSISException(CSISException::EFileProblem, std::wstring (L"cannot open ") + fileName); + } + bool success = input.import (file, NULL); + ::CloseHandle(file); + if(!success) + { + LERROR(L" Error : Cannot read file : " << fileName << std::endl); + throw CSISException(CSISException::EFileProblem, std::wstring (L"cannot read ") + fileName); + } + + sisController = new CSISController; + sisController->Read(input, input.length()); + + return sisController; + } + +void SisRegistry::GenerateRegistryEntry(SisRegistryObject& aObj, const SisFile& aSis) + { + + SetNextIndex(aObj); + + if(iParamList.RegistryVersionExists()) + { + GenerateRegFile(aObj); + } + + GenerateCtlFile(aObj, aSis); + } + +void SisRegistry::SetNextIndex(SisRegistryObject& aObj) const + { + TUint32 pkgUid = aObj.GetUid(); + TUint32 installType = aObj.GetInstallType(); + int index = 0; + + if(iParamList.RegistryVersionExists()) + { + if (installType == CSISInfo::EInstAugmentation) + { + // set the .reg and .ctl file index for SP installation + index = aObj.NextSisRegistryIndex( iParamList.SystemDrivePath() ); + + if (index == 0) + { + // No SisRegistry file found!! + std::wstring msg = StringUtils::MakePathFromSID ( iParamList.SystemDrivePath()+L"\\", pkgUid ); + + msg.append(L" does not have any SisRegistry file"); + + throw std::runtime_error( Ucs2ToUtf8(msg) ); + } + + aObj.SetIndex( index ); + + if ( !CheckSisRegistryDirPresent(iParamList.SystemDrivePath(), pkgUid) ) + { + // c:\sys\install\sisregistry\\ directory not exist + std::wstring msg = StringUtils::MakePathFromSID ( iParamList.SystemDrivePath()+L"\\", pkgUid ); + + msg.append(L" directory NOT found"); + + throw std::runtime_error( Ucs2ToUtf8(msg) ); + } + } + } + + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + else + { + if (installType == CSISInfo::EInstAugmentation) + { + // set .ctl file index for SP installation + index = iDbHelper->GetIndex(pkgUid); + + int nextIndex = index +1; + aObj.SetIndex( nextIndex ); + + if ( !CheckSisRegistryDirPresent(iParamList.SystemDrivePath(), pkgUid) ) + { + std::wstring msg = StringUtils::MakePathFromSID ( iParamList.SystemDrivePath()+L"\\", pkgUid ); + + msg.append(L" directory NOT found"); + + throw std::runtime_error( Ucs2ToUtf8(msg) ); + } + } + } + + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + + } + +void SisRegistry::GenerateRegFile(SisRegistryObject& aObj) const + { + TUint32 installType = aObj.GetInstallType(); + + std::wstring regPath = aObj.GetRegistryDir( L"" ); + ConvertToLocalPath( regPath, iParamList.SystemDrivePath() ); + + if (installType == CSISInfo::EInstInstallation) + { + if ( !MakeDir( regPath ) ) + { + throw InterpretSisError(L"Directory Creation Error - "+regPath, DIRECTORY_CREATION_ERROR); + } + } + + std::fstream regFile; + std::wstring reg = regPath + StringUtils::BuildSisRegistryFileName(aObj.GetIndex()); + + OpenFile( reg, regFile, std::ios::out | std::ios::binary ); + + Serialiser s(regFile); + s << aObj; + + regFile.close(); + } + +void SisRegistry::GenerateCtlFile(SisRegistryObject& aObj, const SisFile& aSis) const + { + TUint32 pkgUid = aObj.GetUid(); + TUint32 installType = aObj.GetInstallType(); + // Controller + int index = 0; + + if (installType == CSISInfo::EInstPartialUpgrade) + { + index = aObj.NextSisControllerIndex( iParamList.SystemDrivePath() ); + + if (index == 0) + { + // No SIS controller file found!! + std::wstring msg = StringUtils::MakePathFromSID ( iParamList.SystemDrivePath()+L"\\", pkgUid ); + + msg.append(L" does not have any Sis Controller file"); + + throw std::runtime_error( Ucs2ToUtf8(msg) ); + } + } + + // Finally, externalise the new controller file + std::fstream ctlFile; + std::wstring ctlPath = aObj.GetRegistryDir( L"" ); + ConvertToLocalPath( ctlPath, iParamList.SystemDrivePath() ); + + if (installType == CSISInfo::EInstInstallation) + { + if ( !MakeDir( ctlPath ) ) + { + throw InterpretSisError(L"Directory Creation Error - "+ctlPath, DIRECTORY_CREATION_ERROR); + } + } + + std::wstring ctrl = ctlPath + StringUtils::BuildControllerFileName( aObj.GetIndex(), index ); + + + OpenFile( ctrl, ctlFile, std::ios::out | std::ios::binary ); + + const char* ctl = 0; + int len = 0; + aSis.GetControllerData(ctl, len); + ctlFile.write((const char*)&len, 4); + ctlFile.write(ctl, len); + ctlFile.close(); + + int targetDrive = tolower(aObj.GetSelectedDrive()); + + if (iConfigManager.IsTargetDriveExt(targetDrive)) + { + // For external target drive, generate the ctl file to that drive also + std::wstring ctlPath = aObj.GetRegistryDir( L"" ); + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(targetDrive); + + ConvertToLocalPath( ctlPath, localTargetPath ); + + if ( !MakeDir( ctlPath ) ) + { + throw InterpretSisError(L"Directory Creation Error - "+ctlPath, DIRECTORY_CREATION_ERROR); + } + + ctrl = ctlPath + StringUtils::BuildControllerFileName( aObj.GetIndex(), index ); + + OpenFile( ctrl, ctlFile, std::ios::out | std::ios::binary ); + + ctlFile.write((const char*)&len, 4); + ctlFile.write(ctl, len); + ctlFile.close(); + } + } + + +int SisRegistry::GetAugmentationsNumber(TUint32 aUid) +{ + int num = 0; + if(iParamList.RegistryVersionExists()) + { + EntryMap::const_iterator x = iEntries.begin(); + + for (;x != iEntries.end(); ++x) + { + if (x->first == aUid && x->second->GetIndex() != 0 ) + ++num; + } + } + #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + else + { + TInt32 componentId = iDbHelper->GetComponentId(aUid); + TInt index = iDbHelper->GetIndex(componentId); + if( index != DbHelper::Absent ) + num = ++index; + } + #endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + return num; +} +#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK + +std::wstring SisRegistry::FormatVersionToString( const Version& aVersion ) + { + std::wstringstream versionText; + versionText << aVersion.GetMajor() << L"." << aVersion.GetMinor() << L"." << aVersion.GetBuild(); + return versionText.str(); + } + +const DbHelper* SisRegistry::GetDbHelper() const + { + return iDbHelper; + } + +void SisRegistry::GenerateDbRegistryEntry(const SisRegistryObject& aSisRegistryObject, bool aOriginVerified) + { + // store the object in registry database + XmlDetails::TScrPreProvisionDetail scrPreProvisionDetail; + // for sis file entries the software type would always be Native. + scrPreProvisionDetail.iSoftwareTypeName = SisRegistry::NativeSoftwareType; + XmlDetails::TScrPreProvisionDetail::TComponent component = CreateRegistryEntry(aSisRegistryObject); + + SetOriginVerification(component, aOriginVerified); + + scrPreProvisionDetail.iComponents.push_back(component); + UpdateInstallationInformation(scrPreProvisionDetail); + } + +void SisRegistry::SetOriginVerification(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, bool aOriginVerified) + { + // If not origin verified, set so. By default origin is verified. + if (!aOriginVerified) + { + aComponent.iComponentDetails.iOriginVerified = 0; + } + } + +void SisRegistry::UpdateInstallationInformation(XmlDetails::TScrPreProvisionDetail aScrPreProvisionDetail) + { + CXmlGenerator xmlgenerator; + char* tmpFileName = tmpnam(NULL); + std::wstring filename(string2wstring(tmpFileName)); + + xmlgenerator.WritePreProvisionDetails(filename , aScrPreProvisionDetail); + + std::string executable = "scrtool.exe"; + std::string command; + command = executable + " -d " + GetDbPath() + " -p " + tmpFileName; + + int error = system(command.c_str()); + + if(error != 0) + { + std::string err = "Scrtool failed to upload the database registry entry."; + LERROR(L"Scrtool failed to upload the database registry entry."); + throw InterpretSisError(err, DATABASE_UPDATE_FAILED); + } + + error = remove(tmpFileName); + + if(error != 0) + { + LERROR(L"Temporary file removal failed."); + } + + } + +std::string SisRegistry::GetDbPath() + { + if ( + (iParamList.RomLogFileNames().size() != 0 && iParamList.RomDrivePath().size() == 0 ) || + iParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet) + ) + { + return wstring2string(iParamList.SystemDrivePath()) + "\\sys\\install\\scr\\scr.db"; + } + + return wstring2string(iParamList.RomDrivePath()) + "\\sys\\install\\scr\\provisioned\\scr.db"; + + } + +std::string SisRegistry::GetEpocRoot() + { + const char* epocRoot = getenv("EPOCROOT"); + if(NULL == epocRoot) + { + std::string err = "EPOCROOT environment variable not specified. Please specify it as part of your environment variable." \ + "It should point uptil the start of the epoc32 directory."; + LERROR(L"EPOCROOT environment variable not specified. Please specify it as part of your environment variable." \ + "It should point uptil the start of the epoc32 directory."); + throw InterpretSisError(err, ENV_NOT_SPECIFIED); + } + std::string epocRootStr(epocRoot); + return epocRootStr; + } + + +std::wstring SisRegistry::GetGlobalId( TUint32 aUid , TInt aInstallType, std::wstring aPackageName) + { + wchar_t textGlobalId[20]; + +#ifdef _MSC_VER + swprintf(textGlobalId,L"%08x",aUid); +#else + swprintf(textGlobalId,20,L"%08x",aUid); +#endif + + std::wstring globalId = textGlobalId; + + if( aInstallType == CSISInfo::EInstAugmentation || aInstallType == CSISInfo::EInstPreInstalledPatch ) + { + if(aPackageName.empty()) + { + std::string err = "Package Name not specified for global id creation."; + LERROR(L"Package Name not specified for global id creation."); + throw InterpretSisError(err, GLOBALID_CREATION_ERROR); + } + globalId += L"_" + aPackageName; + } + return globalId; + } + +void SisRegistry::RemovePkgWithScr(TUint32 aUid, bool aSkipRomStub) + { + TUint32 componentId = iDbHelper->GetComponentId(aUid); + + if ( DbHelper::Absent == componentId ) + { + // No database entry found!! + std::stringstream err; + err << " SisRegistry entry for 0x" << std::hex << aUid << L" Not found"; + throw InterpretSisError(err.str(), DATABASE_ENTRY_MISSING); + } + + std::list regDirFiles; + std::wstring path = GetRegistryDir( iParamList.SystemDrivePath(), aUid ); + + GetDirContents(path, regDirFiles); + + // The directory should only consist of the .ctl file. Comparison with + // 2 is for the ctl file and link to the parent directory. + if ( regDirFiles.size() == KDirFileCount && iDbHelper->GetInRom(componentId)) + { + // I.e. there are only one .ctl file present + // check whether it is a ROM stub object (without any upgrades) + + if (aSkipRomStub) + { + // Since this is only a ROM stub entry, leave it as it is; + // to avoid regenerate it again. + return; + } + + std::stringstream err; + err << "Illegal uninstall of ROM package 0x" << std::hex << aUid; + throw InterpretSisError(err.str(), ATTEMPT_TO_UNINSTALL_ROM_PKG); + } + + std::list::iterator currFile = regDirFiles.begin(); + + // Remove all .ctl files in the system drive for this package + while (currFile != regDirFiles.end()) + { + if (*currFile != L"." && *currFile != L"..") + { + RemoveFile(path + *currFile); + } + + ++currFile; + } + + // Remove the installed files for all packages (SA, SP, PU) + // retrieve component id for the specified uid + std::vector compIdList = iDbHelper->GetComponentIdList(aUid); + std::vector ::iterator compIter; + for( compIter = compIdList.begin(); compIter != compIdList.end() ; ++compIter ) + { + // For ROM stub, the SelectedDrive = 0; as there could be ROM->SP. + // Therefore, the rest can only apply to at least a ROM stub upgrades + int drive = tolower(iDbHelper->GetSelectedDrive(*compIter)); + + if (drive) + { + std::wstring localTargetPath = iConfigManager.GetLocalDrivePath(drive); + path = GetRegistryDir( localTargetPath, aUid ); + + regDirFiles.clear(); + GetDirContents(path, regDirFiles); + + currFile = regDirFiles.begin(); + + // Remove all the .ctl files for this package + while (currFile != regDirFiles.end()) + { + if (*currFile != L"." && *currFile != L"..") + { + RemoveFile(path + *currFile); + } + ++currFile; + } + + // This iterator's object has the same Uid as aUid + const FileDescriptions& files = iDbHelper->GetFileDescriptions(*compIter); + + RemoveInstalledFiles(files, localTargetPath); + + } + // remove the application from database + iDbHelper->RemoveEntry(*compIter); + } + } + +TUint32 SisRegistry::GetUid(TUint32 aSid) const + { + return iDbHelper->GetUid(aSid); + } + +TUint32 SisRegistry::GetUid(const std::wstring& aSidFile) const + { + return iDbHelper->GetUid(aSidFile); + } + +bool SisRegistry::GetInRom(TUint32 aUid) const + { + TUint32 componentId = iDbHelper->GetComponentId(aUid); + return iDbHelper->GetInRom(componentId); + } + +XmlDetails::TScrPreProvisionDetail::TComponent SisRegistry::CreateRegistryEntry(const SisRegistryObject& aSisRegistryObject) + { + + XmlDetails::TScrPreProvisionDetail::TComponent component; + + // add registry token information + AddSisRegistryToken(component, dynamic_cast (aSisRegistryObject)); + + + // update SisregistryObject + AddLocalizedNames(component,aSisRegistryObject); + + // This flag cannot be made optional as it is used in queries + AddComponentProperty(component, DbConstants::CompInstallType, aSisRegistryObject.GetInstallType(), IGNORE_FORMATTING); + + AddComponentDependencies(component, aSisRegistryObject); + AddEmbeddedPackages(component, aSisRegistryObject.GetEmbeddedPackages()); + AddProperties(component, aSisRegistryObject.GetProperties()); + AddFileDescription(component, aSisRegistryObject.GetFileDescriptions()); + + // inROM + if(DbConstants::KDefaultIsInRom != aSisRegistryObject.GetInRom()) + AddComponentProperty(component, DbConstants::CompInRom, aSisRegistryObject.GetInRom(), IGNORE_FORMATTING ); + + // isSigned + if(DbConstants::KDefaultIsSigned != aSisRegistryObject.GetSigned()) + AddComponentProperty(component, DbConstants::CompIsSigned, aSisRegistryObject.GetSigned(), IGNORE_FORMATTING); + + // SignedBySuCert + if(DbConstants::KDefaultIsSignedBySuCert != aSisRegistryObject.GetSignedBySuCert()) + AddComponentProperty(component, DbConstants::CompSignedBySuCert, aSisRegistryObject.GetSignedBySuCert(), IGNORE_FORMATTING); + + // DeletablePreinstalled + if(DbConstants::KDefaultIsDeletablePreInstalled != aSisRegistryObject.GetPreInstalled()) + AddComponentProperty(component, DbConstants::CompDeletablePreinstalled, aSisRegistryObject.GetPreInstalled(), IGNORE_FORMATTING); + + // iTrust + if(DbConstants::KDefaultTrustValue != aSisRegistryObject.GetTrust()) + AddComponentProperty(component, DbConstants::CompTrust, aSisRegistryObject.GetTrust(), IGNORE_FORMATTING ); + + // iRemoveWithLastDependent + if(DbConstants::KDefaultRemoveWithLastDependent != aSisRegistryObject.GetRemoveWithLastDependent()) + AddComponentProperty(component, DbConstants::CompIsRemoveWithLastDependent, aSisRegistryObject.GetRemoveWithLastDependent(), IGNORE_FORMATTING ); + + // iTrustTimeStamp will be deprecated + // 64 bit value + std::wstring strTimeStamp = Utils::Int64ToWideString(aSisRegistryObject.GetTrustTimeStamp()); + AddComponentProperty(component, DbConstants::CompTrustTimeStamp, strTimeStamp, IGNORE_FORMATTING, false ); + + // iTrustStatus + AddTrustStatus(component, aSisRegistryObject.GetTrustStatus() ); + + // installChainIndices + AddInstallChainIndices(component, aSisRegistryObject.GetInstallChainIndices() ); + + // iIsRemovable + if(aSisRegistryObject.GetIsRemovable() ) + { + component.iComponentDetails.iIsRemovable = 1; + } + else + { + component.iComponentDetails.iIsRemovable = 0; + } + + // iIsHidden + if(aSisRegistryObject.GetIsHidden() ) + { + component.iComponentDetails.iIsHidden = 1; + } + else + { + component.iComponentDetails.iIsHidden = 0; + } + + return component; + } + +void SisRegistry::AddSisRegistryToken ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const SisRegistryToken& aSisRegistryToken + ) + { + // add sisregistrypackage details + AddSisRegistryPackage( aComponent, dynamic_cast(aSisRegistryToken), aSisRegistryToken.GetLanguage() ); + + // add sid count + // sids would be added later alongwith their corresponding executables. + int sidCount = aSisRegistryToken.GetSids().size(); + if (DbConstants::KDefaultSidCount != sidCount) + AddComponentProperty( aComponent, DbConstants::CompSidCount, sidCount, IGNORE_FORMATTING); + + if( sidCount > 0) + { + AddComponentProperty(aComponent, DbConstants::CompSidsPresent, ENABLE, IGNORE_FORMATTING); + } + + AddControllerInfo(aComponent, aSisRegistryToken.GetControllerInfo()); + + AddVersion(aComponent, aSisRegistryToken.GetVersion()); + + if (aSisRegistryToken.GetLanguage() != DbConstants::KDefaultInstalledLanguage) + AddComponentProperty( aComponent, DbConstants::CompLanguage, aSisRegistryToken.GetLanguage(), IGNORE_FORMATTING); + + if (aSisRegistryToken.GetSelectedDrive() != DbConstants::KDefaultInstalledDrive) + AddComponentProperty( aComponent, DbConstants::CompSelectedDrive, aSisRegistryToken.GetSelectedDrive(), IGNORE_FORMATTING); + + } + +void SisRegistry::AddSisRegistryPackage ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const SisRegistryPackage& aSisRegistryPackage, + int aLanguage + ) + { + + // vendor + AddComponentProperty( aComponent, DbConstants::CompUniqueVendorName, aSisRegistryPackage.GetVendorName(),IGNORE_FORMATTING,false); + // uid + std::wstringstream strPropName; + strPropName << DbConstants::CompUid; + + std::wstringstream strPropValue; + TInt32 uid = aSisRegistryPackage.GetUid(); + strPropValue << uid; + + XmlDetails::TScrPreProvisionDetail::TComponentProperty + compProperty = CreateComponentProperty(strPropName.str(), strPropValue.str(), true, false); + + aComponent.iComponentProperties.push_back(compProperty); + + // index + AddComponentProperty( aComponent, DbConstants::CompIndex, aSisRegistryPackage.GetIndex(),IGNORE_FORMATTING ); + + // calculate the globalid for this component + int installType = dynamic_cast(aSisRegistryPackage).GetInstallType(); + std::wstring globalId = GetGlobalId(aSisRegistryPackage.GetUid(), installType, aSisRegistryPackage.GetPackageName()); + + aComponent.iComponentDetails.iGlobalId = globalId; + } + +void SisRegistry::AddControllerInfo ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const std::vector& aControllerInfo + ) + { + if(DbConstants::KDefaultControllerCount != aControllerInfo.size()) + AddComponentProperty( aComponent, DbConstants::CompControllerCount, aControllerInfo.size(), IGNORE_FORMATTING); + + std::vector::const_iterator controllerInfoIter; + int count = 0; + for(controllerInfoIter = aControllerInfo.begin() ; controllerInfoIter != aControllerInfo.end() ; ++controllerInfoIter ) + { + std::wstring version = FormatVersionToString((*controllerInfoIter)->GetVersion()); + AddComponentProperty( aComponent, DbConstants::CompControllerVersion, version, count, false); + + // offset + AddComponentProperty( aComponent, DbConstants::CompControllerOffset, (*controllerInfoIter)->GetOffset(), count ); + + // add hash information + AddHashContainer(aComponent, (*controllerInfoIter)->GetHashContainer(), count ); + ++count; + } + } + +void SisRegistry::AddVersion ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const Version& aVersion + ) + { + aComponent.iComponentDetails.iVersion.iMajor = Utils::IntegerToWideString(aVersion.GetMajor()); + aComponent.iComponentDetails.iVersion.iMinor = Utils::IntegerToWideString(aVersion.GetMinor()); + aComponent.iComponentDetails.iVersion.iBuild = Utils::IntegerToWideString(aVersion.GetBuild()); + } + +void SisRegistry::AddHashContainer ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const HashContainer& aHashContainer, + int aCount + ) + { + if (aHashContainer.GetHashId() != HashContainer::EHashSHA) + AddComponentProperty( aComponent, DbConstants::CompControllerHashAlgorithm, aHashContainer.GetHashId(), aCount); + + int algorithmId = aHashContainer.GetHashId(); + // The property is a concatenation of the algorithm id and the hash data + const std::string hashData = aHashContainer.GetData(); + + std::string encodedHashData = Util::Base64Encode(hashData); + std::wstring wideHashData = Utils::string2wstring(encodedHashData); + AddComponentProperty( aComponent, DbConstants::CompControllerHashData, wideHashData, aCount, true); + + } + + +void SisRegistry::AddLocalizedNames(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, const SisRegistryObject& aSisRegistryObject) + { + TInt size = aSisRegistryObject.GetMatchingSupportedLanguages().size(); + if ( 0 == size ) + { + XmlDetails::TScrPreProvisionDetail::TComponentLocalizable componentLocalizable; + componentLocalizable.iVendor = aSisRegistryObject.GetVendorLocalizedName(); + componentLocalizable.iName = aSisRegistryObject.GetPackageName(); + componentLocalizable.iLocale = aSisRegistryObject.GetLanguage(); + aComponent.iComponentLocalizables.push_back(componentLocalizable); + } + else + { + for ( TInt i=0; i < size; i++) + { + XmlDetails::TScrPreProvisionDetail::TComponentLocalizable componentLocalizable; + componentLocalizable.iName = aSisRegistryObject.GetLocalizedPackageNames()[i]->GetString(); + componentLocalizable.iLocale = aSisRegistryObject.GetMatchingSupportedLanguages().at(i); + componentLocalizable.iVendor = aSisRegistryObject.GetLocalizedVendorNames()[i]->GetString(); + aComponent.iComponentLocalizables.push_back(componentLocalizable); + } + } + } + +void SisRegistry::AddComponentDependencies(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, const SisRegistryObject& aSisRegistryObject) + { + const std::vector& dependencies = aSisRegistryObject.GetDependencies(); + if(dependencies.size() == 0) + return; + + std::wstring dependentGlobalId = GetGlobalId( aSisRegistryObject.GetUid(), aSisRegistryObject.GetInstallType(), aSisRegistryObject.GetPackageName() ); + + XmlDetails::TScrPreProvisionDetail::TComponentDependency componentDependency; + componentDependency.iDependentId = dependentGlobalId; + + + for(std::vector::const_iterator depIter = dependencies.begin() ; depIter != dependencies.end() ; ++depIter) + { + XmlDetails::TScrPreProvisionDetail::TComponentDependency::TComponentDependencyDetail componentDependencyDetail; + + TUint32 uid = (*depIter)->GetUid(); + std::wstring supplierGlobalId = GetGlobalId(uid,CSISInfo::EInstInstallation,L""); + componentDependencyDetail.iSupplierId = supplierGlobalId; + + // add fromVersion + std::wstring fromVersion = FormatVersionToString((*depIter)->GetFromVersion()); + componentDependencyDetail.iFromVersion = fromVersion; + + // add toVersion + std::wstring toVersion = FormatVersionToString((*depIter)->GetToVersion()); + componentDependencyDetail.iToVersion = toVersion; + + componentDependency.iComponentDependencyList.push_back(componentDependencyDetail); + } + aComponent.iComponentDependency = componentDependency; + } + +void SisRegistry::AddEmbeddedPackages(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, const std::vector& aEmbeddedPackages ) + { + // EmbeddedPckgCount + int embeddedPckgCount = aEmbeddedPackages.size(); + if (DbConstants::KDefaultEmbeddedPackageCount != embeddedPckgCount) + AddComponentProperty(aComponent, DbConstants::CompEmbeddedPackageCount, embeddedPckgCount, IGNORE_FORMATTING ); + + if( embeddedPckgCount > 0) + { + AddComponentProperty(aComponent, DbConstants::CompEmbeddedPackagePresent, ENABLE, IGNORE_FORMATTING ); + } + + + std::vector::const_iterator pckgIter; + + int count = 0; + for(pckgIter = aEmbeddedPackages.begin() ; pckgIter != aEmbeddedPackages.end() ; ++pckgIter, ++count) + { + // package uid + AddComponentProperty( aComponent, DbConstants::CompEmbeddedPackageUid, (*pckgIter)->GetUid(), count); + // package name + AddComponentProperty( aComponent, DbConstants::CompEmbeddedPackageName, (*pckgIter)->GetPackageName(), count, false); + // vendor name + AddComponentProperty( aComponent, DbConstants::CompEmbeddedPackageVendor, (*pckgIter)->GetVendorName(), count, false); + // index + AddComponentProperty( aComponent, DbConstants::CompEmbeddedPackageIndex, (*pckgIter)->GetIndex(), count); + } + + } + + +void SisRegistry::AddProperties(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, const std::vector& aProperties ) + { + if (aProperties.size() != DbConstants::KDefaultCompPropertyCount) + AddComponentProperty(aComponent, DbConstants::CompPropertyCount, aProperties.size(), IGNORE_FORMATTING ); + + std::vector::const_iterator propIter; + + int count = 0; + for(propIter = aProperties.begin() ; propIter != aProperties.end() ; ++propIter, ++count) + { + // key + AddComponentProperty( aComponent, DbConstants::CompPropertyKey, (*propIter)->GetKey(), count); + // value + AddComponentProperty( aComponent, DbConstants::CompPropertyValue, (*propIter)->GetValue(), count); + } + } + + +void SisRegistry::AddFileDescription(XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, const std::vector& aFileDescription ) + { + std::vector::const_iterator filedesIter; + int wildcardFileCount = 0; + int exeFileIndex = 0; + for(filedesIter = aFileDescription.begin() ; filedesIter != aFileDescription.end(); ++filedesIter) + { + // if it has wild card characters then add it as part of componentproperties table + if( IsFileWideCard((*filedesIter)->GetTarget()) ) + { + // file target + AddComponentProperty( aComponent, DbConstants::WCFileName, (*filedesIter)->GetTarget(), wildcardFileCount++, false); + continue; + } + + TInt sid = (*filedesIter)->GetSid(); + if( sid != 0 ) + { + // add sid file format + AddComponentProperty(aComponent, DbConstants::CompSidFileName, (*filedesIter)->GetTarget(), exeFileIndex, false); + AddComponentProperty(aComponent, DbConstants::CompSid, sid, exeFileIndex); + ++exeFileIndex; + } + + // add the location in the component files table + XmlDetails::TScrPreProvisionDetail::TComponentFile componentFile; + componentFile.iLocation = (*filedesIter)->GetTarget(); + AddFileDescriptionAsFileProperty(componentFile, *filedesIter); + aComponent.iComponentFiles.push_back(componentFile); + } + + if (DbConstants::KDefaultWildCardFileCount != wildcardFileCount) + AddComponentProperty(aComponent, DbConstants::CompWildCardFileCount, wildcardFileCount, IGNORE_FORMATTING); + } + +void SisRegistry::AddFileDescriptionAsFileProperty ( XmlDetails::TScrPreProvisionDetail::TComponentFile& aComponentFile, + const FileDescription* aFileDescription + ) + { + // mime type + if( !aFileDescription->GetMimeType().empty()) + { + AddFileProperty( aComponentFile, DbConstants::FileMimeType, aFileDescription->GetMimeType(), true); + } + // operation + if(aFileDescription->GetOperation() != CSISFileDescription::EOpInstall) + { + AddFileProperty( aComponentFile, DbConstants::FileSisFileOperation, aFileDescription->GetOperation(), false); + } + // operation option + if( aFileDescription->GetOperationOptions() ) + { + AddFileProperty( aComponentFile, DbConstants::FileFileOperationOptions, aFileDescription->GetOperationOptions(), false); + } + + // uncompressed length + if( aFileDescription->GetUncompressedLength() ) + { + AddFileProperty( aComponentFile, DbConstants::FileUncompressedLength, aFileDescription->GetUncompressedLength(), false); + } + + // file index + if( aFileDescription->GetIndex() ) + { + AddFileProperty( aComponentFile, DbConstants::FileIndex, aFileDescription->GetIndex(), false); + } + + // sid + if( aFileDescription->GetSid() ) + { + AddFileProperty( aComponentFile, DbConstants::FileSid, aFileDescription->GetSid(), false); + } + + // filehash algorithm + if (aFileDescription->GetHash().GetHashId() != HashContainer::EHashSHA ) + { + AddFileProperty( aComponentFile, DbConstants::FileHashAlgorithm, aFileDescription->GetHash().GetHashId(), false); + } + // file hash data + if(!aFileDescription->GetHash().GetData().empty()) + { + std::string binHashData = Util::Base64Encode(aFileDescription->GetHash().GetData()); + std::wstring hashData = Utils::string2wstring(binHashData); + AddFileProperty( aComponentFile, DbConstants::FileHashData, hashData, true); + } + } + +void SisRegistry::AddTrustStatus ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const TrustStatus& aTrustStatus + ) + { + // iValidationStatus + AddComponentProperty( aComponent, DbConstants::CompTrustValidationStatus, aTrustStatus.GetValidationStatus(), IGNORE_FORMATTING); + } + + +void SisRegistry::AddInstallChainIndices ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const std::vector& aInstallChainIndices + ) + { + if (aInstallChainIndices.size() != DbConstants::KDefaultChainIndex) + AddComponentProperty( aComponent, DbConstants::CompInstallChainIndexCount, aInstallChainIndices.size(), IGNORE_FORMATTING); + + std::vector::const_iterator chainIndicesIter; + int count = 0; + for(chainIndicesIter = aInstallChainIndices.begin(); chainIndicesIter != aInstallChainIndices.end() ; ++chainIndicesIter) + { + AddComponentProperty(aComponent, DbConstants::CompInstallChainIndex, *chainIndicesIter, count++); + } + } + +void SisRegistry::AddComponentProperty ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const std::wstring& aPropName, + int aPropValue, + int aCount + ) + { + std::wstringstream strPropName; + + if(aCount != IGNORE_FORMATTING) + { + strPropName << aPropName << aCount; + } + else + { + strPropName << aPropName; + } + + std::wstringstream strPropValue; + strPropValue << aPropValue; + + XmlDetails::TScrPreProvisionDetail::TComponentProperty + compProperty = CreateComponentProperty(strPropName.str(), strPropValue.str(), true, false); + + aComponent.iComponentProperties.push_back(compProperty); + + } + +void SisRegistry::AddComponentProperty ( XmlDetails::TScrPreProvisionDetail::TComponent& aComponent, + const std::wstring& aPropName, + const std::wstring& aPropValue, + int aCount, + bool aIsBinary + ) + { + std::wstringstream strPropName; + + if(aCount != IGNORE_FORMATTING) + { + strPropName << aPropName << aCount; + } + else + { + strPropName << aPropName; + } + + XmlDetails::TScrPreProvisionDetail::TComponentProperty compProperty; + + if(aIsBinary) + { + compProperty = CreateComponentProperty(strPropName.str(), aPropValue,false, true); + } + else + { + compProperty = CreateComponentProperty(strPropName.str(), aPropValue,false, false); + } + + aComponent.iComponentProperties.push_back(compProperty); + } + +void SisRegistry::AddFileProperty ( XmlDetails::TScrPreProvisionDetail::TComponentFile& aComponentFile, + const std::wstring& aPropName, + const std::wstring& aPropValue, + bool aIsBinary + ) + { + XmlDetails::TScrPreProvisionDetail::TComponentFile::TFileProperty fileProperty; + + fileProperty.iName = aPropName; + fileProperty.iValue = aPropValue; + fileProperty.iIsIntValue = !aIsBinary; + aComponentFile.iFileProperties.push_back(fileProperty); + } + +void SisRegistry::AddFileProperty ( XmlDetails::TScrPreProvisionDetail::TComponentFile& aComponentFile, + const std::wstring& aPropName, + int aPropValue, + bool aIsBinary + ) + { + std::wstringstream strPropValue; + strPropValue << aPropValue; + AddFileProperty(aComponentFile, aPropName, strPropValue.str(), aIsBinary); + } + +XmlDetails::TScrPreProvisionDetail::TComponentProperty + SisRegistry::CreateComponentProperty( const std::wstring& aPropName, const std::wstring& aPropValue, + bool aIsInt, bool aIsStr8Bit, int aLocale + ) + { + XmlDetails::TScrPreProvisionDetail::TComponentProperty componentProperty; + + componentProperty.iName = aPropName; + componentProperty.iLocale = aLocale; + componentProperty.iValue = aPropValue; + componentProperty.iIsIntValue = aIsInt; + componentProperty.iIsStr8Bit = aIsStr8Bit; + + return componentProperty; + } + +#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK