diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/sisxlibrary/siscontents.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/sisxlibrary/siscontents.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,320 @@ +/* +* 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: +* +*/ + + +/** + @file + @internalComponent + @released +*/ +#ifdef _MSC_VER +#pragma warning (disable: 4786) +#endif // _MSC_VER +// +// Note: This file may contain code to generate corrupt files for test purposes. +// Such code is excluded from production builds by use of compiler defines; +// it is recommended that such code should be removed if this code is ever published publicly. +// + +#include +#include +#include +#include + +#include "siscontents.h" +#include "utils.h" +#include "utility_interface.h" + +#include + +CSISContents::TStub CSISContents::iStub = CSISContents::EStubNone; + + + +void CSISContents::InsertMembers () + { + InsertMember (iControllerChecksum); + InsertMember (iDataChecksum); + InsertMember (iController); + InsertMember (iData); + } + + +CSISContents::CSISContents (const CSISContents& aInitialiser) : + CStructure (aInitialiser), + iControllerChecksum (aInitialiser.iControllerChecksum), + iDataChecksum (aInitialiser.iDataChecksum), + iController (aInitialiser.iController), + iData (aInitialiser.iData) + { + InsertMembers (); + } + +bool CSISContents::IsSisFile(const std::wstring& aFileName) + { + TSISStream input; + std::wstring fileName = FixPathDelimiters(aFileName); + HANDLE file = ::MakeSISOpenFile(fileName.c_str(),GENERIC_READ,OPEN_EXISTING); + CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), + CSISException::EFileProblem, std::wstring (L"cannot open ") + fileName); + bool success = input.import (file, NULL); + ::CloseHandle(file); + CSISException::ThrowIf (! success, CSISException::EFileProblem, std::wstring (L"cannot read ") + fileName); + return IsSisFile(input); + } + +bool CSISContents::IsSisFile(TSISStream& aStream) + { + CSISUid::TUid uid [4]; + aStream.seek (0); + aStream >> uid [0] >> uid [1] >> uid [2] >> uid [3]; + bool isSisFile = false; + if( uid [0] == KUidSISXApp ) + { + isSisFile = true; + } + else if(uid[2] == KUidLegacySisFile) + { + throw CSISException (CSISException::ELegacyFormat, L"file is a unspported legacy SIS file."); + } + + return isSisFile; + } + + +void CSISContents::Load (const std::wstring& aFileName, TUint64* size) + { + TSISStream input; + std::wstring fileName = FixPathDelimiters(aFileName); + HANDLE file = ::MakeSISOpenFile(fileName.c_str(),GENERIC_READ,OPEN_EXISTING); + if (INVALID_HANDLE_VALUE == file) + { + SISLogger::Log(L" Error : Cannot open file : "); + SISLogger::Log(fileName); + SISLogger::Log(L"\n"); + throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot open ") + fileName); + } + bool success = input.import (file, size); + ::CloseHandle(file); + if(!success) + { + SISLogger::Log(L" Error : Cannot read file : "); + SISLogger::Log(fileName); + SISLogger::Log(L"\n"); + throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot read ") + fileName); + } + CSISUid::TUid uid [4]; + input.seek (0); + input >> uid [0] >> uid [1] >> uid [2] >> uid [3]; + if( uid [0] != KUidSISXApp ) + { + SISLogger::Log(fileName); + SISLogger::Log(L" is not a SIS file .\n"); + if(uid[2] == KUidLegacySisFile) + { + throw CSISException (CSISException::ELegacyFormat, fileName + L" is a unspported legacy SIS file."); + } + throw CSISException (CSISException::EFileFormat, fileName + L" is not a SIS file."); + } + + CSISException::ThrowIf (uid [3] != UidChecksum (uid [0], uid [1], uid [2]), + CSISException::EFileFormat, + std::wstring (fileName) + L" has invalid UID checksum"); + Read (input, input.length ()); + Verify (LanguageCount ()); + } + +void CSISContents::Save (const std::wstring& aFileName) const + { + TSISStream output; + if (iStub == EStubROM) + { + iController.Content ().Write (output, false); + } + else + { + OutputHeaderUids (output); + Write (output, false); + } + // remove R/O attributes from file in case it exists already + _wchmod(aFileName.c_str(),_S_IREAD | _S_IWRITE); + HANDLE file = ::MakeSISOpenFile(aFileName.c_str(),GENERIC_WRITE,CREATE_ALWAYS); + CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), + CSISException::EFileProblem, std::wstring (L"cannot create ") + aFileName); + bool written = output.exportfile (file); + ::CloseHandle(file); + if (! written) + { + ::MakeSISDeleteFile(aFileName.c_str()); + throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot write to ") + aFileName); + } + } + + + +TCRC CSISContents::UIDCheck (const void *pPtr) + { + const unsigned char *pB = reinterpret_cast (pPtr); + const unsigned char *pE = pB + (KUidInstallCount * sizeof (CSISUid::TUid)); + unsigned char buf [(KUidInstallCount * sizeof(DWORD))>>1]; + unsigned char *pT = (&buf[0]); + while (pB < pE) + { + *pT++ = (*pB); + pB += 2; + } + TCRC reply (0); + DoTheCrc (reply, reinterpret_cast (buf), (KUidInstallCount * sizeof(DWORD))>>1); + return reply; + } + +void CSISContents::OutputHeaderUids (TSISStream& output) const + { + CSISUid::TUid uid [KUidInstallCount + 1]; + uid [0] = KUidSISXApp; + uid [1] = 0; // Reserved for future use + uid [2] = UID1 (); + uid [3] = UidChecksum (uid [0], uid [1], uid [2]); + for (unsigned short index = 0; index <= KUidInstallCount; index++) + { + output << uid [index]; + } + } + +CSISUid::TUid CSISContents::UidChecksum (const CSISUid::TUid aUid1, const CSISUid::TUid aUid2, const CSISUid::TUid aUid3) + { + CSISUid::TUid uid [3]; + + uid [0] = aUid1; + uid [1] = aUid2; + uid [2] = aUid3; + + TCRC crcHigh (UIDCheck ((reinterpret_cast (uid)) + 1)); + TCRC crcLow (UIDCheck (reinterpret_cast (uid))); + return static_cast ((static_cast (crcHigh) << 16) + static_cast (crcLow)); + } + +void CSISContents::EmbedFile (const std::wstring& aFile, const CSISUid::TUid& aUid, CSISInstallBlock& aInstall) + { + EmbedPackage (aInstall, aFile, aUid); + } + +void CSISContents::EmbedPackage (CSISInstallBlock& aInstallBlock, const std::wstring& aFile, const CSISUid::TUid& aUid) + { + std::auto_ptr embed (new CSISContents()); + embed->Load (aFile); + + //makesis doesn't support embedded packages of type PA and PP. + if(embed->iData.Stub ()) + { + SISLogger::Log(aFile); + SISLogger::Log(L" is a stub.\t \n"); + SISLogger::Log(L"WARNING : Embedded Preinstalled Stub (PA/PP type) SIS file is not supported.\n"); + throw CSISException (CSISException::EFileFormat, "Stub File"); + } + + if (aUid != 0) + { + CSISException::ThrowIf (embed->UID1 () != aUid, CSISException::EUID, aFile + L" contains incorrect UID"); + } + TUint32 index = iData.AppendData (embed->iData); + if (index > 0) + { + embed->SetDataIndex (index); + } + aInstallBlock.Embed (embed->iController.Content (), index); + } + +void CSISContents::Verify (const TUint32 aLanguages) const + { + assert (aLanguages == LanguageCount ()); + CSISException::ThrowIf (aLanguages == 0, CSISException::ELanguage, "no languages defined"); + CStructure ::Verify (aLanguages); + } + + +void CSISContents::PrepareCrcs () + { + if ((iDbgFlag & EDbgDataChecksum) == 0) + { + iDataChecksum.Set (iData.Crc ()); + } + if ((iDbgFlag & EDbgControllerChecksum) == 0) + { + iControllerChecksum.Set (iController.Crc ()); + } + } + +void CSISContents::WriteSIS (std::wstring aTargetFileName) + { + MakeNeat (); // MakeNeat () should ensure at least one language defined + assert (LanguageCount () > 0); + + switch (iStub) + { + case EStubPreInstalled : + iController.Content ().SetNow (); + iData.SetStub (); + iDataChecksum.Set(0); + SetDebugOption(EDbgDataChecksum); + break; + case EStubROM : + { + // The below piece of code tries to put .sis extension not .SIS as target sisfile name. + std::wstring::size_type count (aTargetFileName.size ()); + if ( (count >= 4) && + (aTargetFileName [count - 4] == L'.')) + { + count -= 3; + std::wstring extension (aTargetFileName.substr (count)); + if ( (toupper(extension [0]) == L'S') && + (toupper(extension [1]) == L'I') && + (toupper(extension [2]) == L'S')) + { + aTargetFileName = aTargetFileName.substr (0, count); + aTargetFileName += std::wstring (L"sis"); + } + } + } + // Leave the date and time initialised to 1st Jan 2004, so that ROM stub + // files don't change every time they are built. + break; + default: + iController.Content ().SetNow (); + break; + } + + PrepareCrcs (); + Verify (LanguageCount ()); +#ifdef GENERATE_ERRORS + if (CSISFieldRoot::IsAnyBugSet ()) + { + CreateDefects (); + } +#endif // GENERATE_ERRORS + + Save (aTargetFileName); + } + +void CSISContents::AddPackageEntry(std::wostream& aStream, bool aVerbose) const + { + iControllerChecksum.AddPackageEntry(aStream, aVerbose); + iDataChecksum.AddPackageEntry(aStream, aVerbose); + iController.AddPackageEntry(aStream, aVerbose); // CSISCompressed + Controller().AddPackageEntry(aStream, aVerbose); + iData.AddPackageEntry(aStream, aVerbose); + }