diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/interpretsislib/rommanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/interpretsislib/rommanager.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,576 @@ +/* +* Copyright (c) 2007-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) + +// System includes +#include +#include + +// User includes +#include "rommanager.h" +#include "parameterlist.h" +#include "stringutils.h" +#include "is_utils.h" + +// String constants +const std::wstring KRomManagerSysBinPath = L"z:\\sys\\bin\\"; +const std::string KRomManagerRomDrive = "Z:\\"; +const std::string KRomManagerRomLogProcessingFile = "Processing file "; +const std::string KRomManagerRomLogReadingResource = "Reading resource "; +const std::string KRomManagerRomLogReadingResource2 = " to rom linear address"; +const std::string KRomManagerRomLogUids = "Uids: "; +const std::string KRomManagerRomLogSecureId = "Secure ID: "; +const std::string KRomManagerRomLogVendorId = "Vendor ID: "; +const std::string KRomManagerRomLogDeviceFileName = "Device file name: "; + + +RomEntry::RomEntry( const std::string& aSourceLogFile ) +: iSourceLogFile( aSourceLogFile ), iSecInfo( 0 ), iUid1( 0 ), iUid2( 0 ), iUid3( 0 ) + { + iSecInfo = new SBinarySecurityInfo(); + iEnvFileName = ""; + iRomFileName = ""; + } + + +RomEntry::~RomEntry() + { + delete iSecInfo; + } + + +RomManager::RomManager() + { + } + +RomManager* RomManager::New( const CParameterList& aParamList ) + { + RomManager* ret = NULL; + + // + // Are we dealing with a full EPOC32-based environment, i.e. "-z" on the Command Line + // or are we working with ROM/ROFSBUILD log files ("-r"). + // + if ( aParamList.IsFlagSet(CParameterList::EFlagsDisableZDriveChecksSet)) + { + ret = new RomManagerEmpty(); + } + else if ( aParamList.RomLogFileNames().size() ) + { + ret = new RomManagerLogFiles( aParamList.RomLogFileNames() ); + } + else + { + ret = new RomManagerFileSystem( aParamList.RomDrivePath() ); + } + // + return ret; + } + + +RomManagerFileSystem::RomManagerFileSystem( const std::wstring& aPath ) +: iRomPath( aPath ) + { + } + +bool RomManagerFileSystem::RomFileExists( const std::wstring& aFileName ) + { + std::wstring target = std::wstring( aFileName ); + ConvertToLocalPath( target, iRomPath ); + bool exists = FileExists( target ); + return exists; + } + +void RomManagerFileSystem::FindAllAdornedVariants(const std::wstring& aSearchNameWild, std::list& aAdornedFileNamesFound) + { + // do nothing + } + +bool RomManagerFileSystem::SidExistsInRom(std::wstring& aFile, TUint32 aSid) + { + std::wstring romDir(KRomManagerSysBinPath); + ConvertToLocalPath( romDir, iRomPath ); + + // search through the binaries on the ROM drive + // to find a matching SID + std::list dirContents; + GetDirContents(romDir, dirContents); + + std::list::iterator curr = dirContents.begin(); + std::list::iterator end = dirContents.end(); + for ( ; curr != end; ++curr ) + { + std::wstring romFile(KRomManagerSysBinPath); + romFile.append(*curr); + + SBinarySecurityInfo info; + ReadSecurityInfo(info,romFile); + + TUint32 sid = info.iSecureId; + + if (sid != 0 && sid == aSid) + { + aFile = KRomManagerSysBinPath + romFile; + return true; + } + } + return false; + } + +TInt RomManagerFileSystem::ReadSecurityInfo( SBinarySecurityInfo& aInfo, const std::wstring aFileName ) + { + // Need to convert the file name to the local path so it can find it + std::wstring target = std::wstring( aFileName ); + ConvertToLocalPath( target, iRomPath ); + return ::ReadSecurityInfo(aInfo,target); + } + +RomManagerLogFiles::RomManagerLogFiles( const std::list& aLogFileNames ) +: iLogFileNames( aLogFileNames ) + { + for( std::list::const_iterator it = aLogFileNames.begin() ; it != aLogFileNames.end(); it++ ) + { + std::string narrowLogFileName = Ucs2ToUtf8( *it ); + std::string narrowUpperCaseLogFileName = StringUtils::ToUpper( narrowLogFileName ); + + // Get the base name + int dotPos = narrowUpperCaseLogFileName.find( ".LOG" ); + if ( dotPos == std::string::npos ) + { + } + else + { + const std::string baseName = narrowLogFileName.substr( 0, dotPos ); + + // Two step process. First, read the log, then, if the log file didn't + // contain sufficient meta data (old version of ROFS/ROMBUILD) we resort + // to reading a corresponding OBY too (if it exists). + const bool needToReadOby = ReadLogFile( narrowLogFileName ); + + if ( needToReadOby ) + { + ReadObyFile( baseName + ".OBY" ); + } + } + } + } + + +RomManagerLogFiles::~RomManagerLogFiles() + { + for( RomEntryMap::iterator it=iEntriesIndexedByEnvFileName.begin(); it != iEntriesIndexedByEnvFileName.end(); it++ ) + { + RomEntry* entry = (*it).second; + delete entry; + } + } + + +bool RomManagerLogFiles::RomFileExists( const std::wstring& aFileName ) + { + bool exists = false; + + // Get filename & convert it to uppercase, since our map key is + // also in upper case form. + std::string narrowFileName = Ucs2ToUtf8( aFileName ); + narrowFileName = StringUtils::ToUpper( narrowFileName ); + + // Do we have a corresponding entry? + RomEntry* entry = iEntriesIndexedByRomFileName[ narrowFileName ]; + if ( entry != NULL ) + { + exists = true; + } + // + return exists; + } + +void RomManagerLogFiles::FindAllAdornedVariants(const std::wstring& aSearchNameWild, std::list& aAdornedFileNamesFound) + { + RomEntryMap::const_iterator curr = iEntriesIndexedByRomFileName.begin(); + RomEntryMap::const_iterator end = iEntriesIndexedByRomFileName.end(); + + std::wstring searchNameWild = StringUtils::ToUpper(aSearchNameWild); + + for ( ; curr != end ; ++curr) + { + std::wstring romFile = Utf8ToUcs2(curr->first); + if (StringUtils::WildcardCompare(searchNameWild,romFile)) + { + aAdornedFileNamesFound.push_back(romFile); + } + } + } + +bool RomManagerLogFiles::SidExistsInRom(std::wstring& aFile, TUint32 aSid) + { + RomEntryMap::const_iterator curr = iEntriesIndexedByRomFileName.begin(); + RomEntryMap::const_iterator end = iEntriesIndexedByRomFileName.end(); + + for ( ; curr != end ; ++curr) + { + RomEntry* romEntry = curr->second; + if (romEntry) + { + if (romEntry->Type() == RomEntry::ETypeBinary) + { + TUint32 romSid = romEntry->SecurityInfo().iSecureId; + if (romSid != 0 && romSid == aSid) + { + aFile = Utf8ToUcs2(romEntry->RomFileName()); + return true; + } + } + } + } + return false; + } + +TInt RomManagerLogFiles::ReadSecurityInfo( SBinarySecurityInfo& aInfo, const std::wstring aFileName ) + { + TInt err = -1; + + // Get filename & convert it to uppercase, since our map key is + // also in upper case form. + std::string narrowFileName = Ucs2ToUtf8( aFileName ); + narrowFileName = StringUtils::ToUpper( narrowFileName ); + + // Do we have a corresponding entry? + RomEntry* entry = iEntriesIndexedByRomFileName[ narrowFileName ]; + if ( entry != NULL ) + { + if ( entry->Type() == RomEntry::ETypeBinary) + { + aInfo.iSecureId = entry->SecurityInfo().iSecureId; + aInfo.iVendorId = entry->SecurityInfo().iVendorId; + err = 0; + } + } + // + return err; + } + + +void RomManagerLogFiles::ReadObyFile( const std::string& aFileName ) + { + std::wstring fileName = Utf8ToUcs2( aFileName ); + if ( FileExists( fileName ) ) + { + std::ifstream stream; + stream.open( aFileName.c_str(), std::ios::binary ); + // + if ( !stream.fail() ) + { + try + { + std::string line; + // + while( std::getline( stream, line ) ) + { + line = StringUtils::TrimWhiteSpace( line ); + if ( line.length() ) + { + ProcessObyFileLine( aFileName, line ); + } + } + // + stream.close(); + } + catch( const RomManagerException& e ) + { + stream.close(); + throw e; + } + } + else + { + throw RomManagerException( RomManagerException::ETypeUnableToOpenCorrespondingOBY, aFileName ); + } + } + else + { + throw RomManagerException( RomManagerException::ETypeUnableToFindCorrespondingOBY, aFileName ); + } + } + + +void RomManagerLogFiles::ProcessObyFileLine( const std::string& aFileName, std::string& aLine ) + { + int breakPos = std::string::npos; + RomEntry::TType type = RomEntry::ETypeBinary; + // + if ( StringUtils::CheckForMatch( "file=", aLine ) ) + { + breakPos = aLine.find_first_of( "\"" ); + type = RomEntry::ETypeBinary; + } + else if ( StringUtils::CheckForMatch( "data=", aLine ) ) + { + breakPos = aLine.find_first_of( "\"" ); + type = RomEntry::ETypeData; + } + else if ( StringUtils::CheckForMatch( "extension[", aLine ) ) + { + // extension[0x0B080004]=\epoc32\release\ARMV5\urel\esound.ldd "Sys\Bin\esound.ldd" + const std::string KRemainingExtensionDataText = "0xXXXXXXXX]="; + + if ( aLine.length() > KRemainingExtensionDataText.length() ) + { + aLine = aLine.substr( KRemainingExtensionDataText.length() ); + breakPos = aLine.find_first_of( "\"" ); + } + } + else if ( StringUtils::CheckForMatch( "primary[", aLine ) ) + { + // primary[0x0A080004]=\epoc32\release\ARMV5\urel\_ekern.exe "Sys\Bin\ekern.exe" + const std::string KRemainingPrimaryDataText = "0xXXXXXXXX]="; + + if ( aLine.length() > KRemainingPrimaryDataText.length() ) + { + aLine = aLine.substr( KRemainingPrimaryDataText.length() ); + breakPos = aLine.find_first_of( "\"" ); + } + } + else if ( StringUtils::CheckForMatch( "device[", aLine ) ) + { + // device[0x0C080004]=\epoc32\release\ARMV5\urel\esound.ldd "Sys\Bin\esound.ldd" + const std::string KRemainingDeviceDataText = "0xXXXXXXXX]="; + + if ( aLine.length() > KRemainingDeviceDataText.length() ) + { + aLine = aLine.substr( KRemainingDeviceDataText.length() ); + breakPos = aLine.find_first_of( "\"" ); + } + } + + if ( breakPos != std::string::npos ) + { + // The env file name must be upper case, since our string indicies + // require this. + std::string envFileName = StringUtils::TrimWhiteSpace( aLine.substr( 0, breakPos ) ); + envFileName = StringUtils::ToUpper( envFileName ); + + std::string romFileName = StringUtils::TrimWhiteSpace( aLine.substr( breakPos ) ); + romFileName = KRomManagerRomDrive + romFileName.substr( 1, romFileName.size() - 2 ); + + // See if we can locate the ROM entry based upon the environment + // file name. This should agree with the pre-parsed ROMBUILD/ROFSBUILD + // log file that we read prior to this method. + RomEntry* file = iEntriesIndexedByEnvFileName[ envFileName ]; + + // Update the entry with the (presumed missing) 'in-place' Symbian OS + // file name. + if ( file != NULL ) + { + romFileName = StringUtils::ToUpper( romFileName ); + file->SetRomFileName( romFileName ); + + // Update type info + file->SetType( type ); + + // ... and make an index entry in the index-by-rom-filename-map + iEntriesIndexedByRomFileName[ romFileName ] = file; + } + } + } + + +bool RomManagerLogFiles::ReadLogFile( const std::string& aFileName ) + { + bool obyParsingRequired = true; + std::ifstream stream; + stream.open( aFileName.c_str(), std::ios::binary ); + + if ( !stream.fail() ) + { + try + { + std::string line; + RomEntry* currentEntry = NULL; + // + while( std::getline( stream, line ) ) + { + line = StringUtils::TrimWhiteSpace( line ); + if ( line.length() ) + { + ProcessLogFileLine( line, currentEntry, aFileName, obyParsingRequired ); + } + } + // + stream.close(); + } + catch( const RomManagerException& e ) + { + stream.close(); + throw e; + } + } + else + { + throw RomManagerException( RomManagerException::ETypeUnableToOpenLogFile, aFileName ); + } + // + return obyParsingRequired; + } + + +void RomManagerLogFiles::ProcessLogFileLine( std::string& aLine, RomEntry*& aCurrentEntry, const std::string& aFileName, bool& aObyParsingRequired ) + { + const bool isBinary = StringUtils::CheckForMatch( KRomManagerRomLogProcessingFile, aLine ); + const bool isData = StringUtils::CheckForMatch( KRomManagerRomLogReadingResource, aLine ); + // + if ( isBinary || isData ) + { + // Save any existing entry + if ( aCurrentEntry != NULL ) + { + // Env file name + iEntriesIndexedByEnvFileName[ aCurrentEntry->EnvFileName() ] = aCurrentEntry; + + // Rom file name (if set) + if ( aCurrentEntry->RomFileName().length() ) + { + iEntriesIndexedByRomFileName[ aCurrentEntry->RomFileName() ] = aCurrentEntry; + } + } + + // If this is a data entry, then we must remove everything after the "to rom linear address" + // text, since this is not part of the filename. + if ( isData ) + { + const std::string::size_type linAddrTextPos = aLine.find( KRomManagerRomLogReadingResource2 ); + if ( linAddrTextPos != std::string::npos ) + { + aLine = aLine.substr( 0, linAddrTextPos ); + } + } + + // Indicies are upper case file names. + aLine = StringUtils::ToUpper( aLine ); + + // Create a new entry + aCurrentEntry = new RomEntry( aFileName ); + aCurrentEntry->SetEnvFileName( aLine ); + + // Set type depending on whether its data or binary + if ( isData ) + { + aCurrentEntry->SetType( RomEntry::ETypeData ); + } + else if ( isBinary ) + { + aCurrentEntry->SetType( RomEntry::ETypeBinary ); + } + } + else if ( aCurrentEntry && StringUtils::CheckForMatch( KRomManagerRomLogUids, aLine ) ) + { + std::istringstream stringStream( aLine ); + // + TUint32 uid1 = 0; + stringStream >> std::hex >> uid1; + aCurrentEntry->SetUid1( uid1 ); + // + TUint32 uid2 = 0; + stringStream >> std::hex >> uid2; + aCurrentEntry->SetUid2( uid2 ); + // + TUint32 uid3 = 0; + stringStream >> std::hex >> uid3; + aCurrentEntry->SetUid3( uid3 ); + } + else if ( aCurrentEntry && StringUtils::CheckForMatch( KRomManagerRomLogSecureId, aLine ) ) + { + std::istringstream stringStream( aLine ); + // + TUint32 sid = 0; + stringStream >> std::hex >> sid; + aCurrentEntry->SecurityInfo().iSecureId = sid; + } + else if ( aCurrentEntry && StringUtils::CheckForMatch( KRomManagerRomLogVendorId, aLine ) ) + { + std::istringstream stringStream( aLine ); + // + TUint32 vid = 0; + stringStream >> std::hex >> vid; + aCurrentEntry->SecurityInfo().iVendorId = vid; + } + else if ( aCurrentEntry && StringUtils::CheckForMatch( KRomManagerRomLogDeviceFileName, aLine ) ) + { + // Indicies are upper case file names. + aLine = StringUtils::ToUpper( KRomManagerRomDrive + aLine ); + aCurrentEntry->SetRomFileName( aLine ); + + // If we see this marker, then ROMBUILD & ROFSBUILD are supplied with the extended + // meta data that includes "in-device" file name, hence we don't need to parse + // the OBY file in order to obtain this information + aObyParsingRequired = false; + } + } + + +bool RomManagerEmpty::RomFileExists( const std::wstring& aFileName ) + { + //default return value as there is no Z drive present + return false; + } + +TInt RomManagerEmpty::ReadSecurityInfo( SBinarySecurityInfo& aInfo, const std::wstring aFileName ) + { + // return non zero error value + return -1; + } + +void RomManagerEmpty::FindAllAdornedVariants(const std::wstring& aSearchNameWild, std::list& aAdornedFileNamesFound) + { + // default return value as there is no Z drive present + } + +bool RomManagerEmpty::SidExistsInRom(std::wstring& aFile, TUint32 aSid) + { + // default return value as there is no Z drive present + return false; + } + +void RomManagerException::Display() const + { + std::ostringstream stream; + stream << "ROM/ROFS OBY/LOG file problem - "; + // + switch( iType ) + { + case ETypeUnableToOpenLogFile: + stream << "\'" << iFileName << "\'" << " (ROM/ROFSBUILD LOG file) could not be read"; + break; + case ETypeUnableToOpenCorrespondingOBY: + stream << "\'" << iFileName << "\'" << " (ROM/ROFSBUILD OBY file) could not be read"; + break; + case ETypeUnableToFindCorrespondingOBY: + stream << "\'" << iFileName << "\'" << " (ROM/ROFSBUILD OBY file) could not be found"; + break; + + default: + stream << "Unknown error"; + break; + } + // + stream << std::endl; + std::wstring finalMessage = Utf8ToUcs2( stream.str() ); + // + LERROR( finalMessage ); + }