secureswitools/swisistools/source/interpretsislib/rommanager.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
--- /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 <iostream>
+#include <fstream>
+
+// 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<std::wstring>& 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<std::wstring> dirContents;
+	GetDirContents(romDir, dirContents);
+
+	std::list<std::wstring>::iterator curr = dirContents.begin();
+	std::list<std::wstring>::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<std::wstring>& aLogFileNames )
+:   iLogFileNames( aLogFileNames )
+    {
+    for( std::list<std::wstring>::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<std::wstring>& 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<std::wstring>& 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 );
+    }