secureswitools/swisistools/source/sisxlibrary/siscontents.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file 
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 #ifdef _MSC_VER
       
    25 #pragma warning (disable: 4786)
       
    26 #endif // _MSC_VER
       
    27 //
       
    28 // Note: This file may contain code to generate corrupt files for test purposes.
       
    29 // Such code is excluded from production builds by use of compiler defines;
       
    30 // it is recommended that such code should be removed if this code is ever published publicly.
       
    31 //
       
    32 
       
    33 #include <iostream>
       
    34 #include <stdio.h>
       
    35 #include <string>
       
    36 #include <sys/stat.h>
       
    37 
       
    38 #include "siscontents.h"
       
    39 #include "utils.h"
       
    40 #include "utility_interface.h"
       
    41 
       
    42 #include <fstream>
       
    43 
       
    44 CSISContents::TStub CSISContents::iStub = CSISContents::EStubNone;
       
    45 
       
    46 
       
    47 
       
    48 void CSISContents::InsertMembers ()
       
    49 	{
       
    50 	InsertMember (iControllerChecksum);
       
    51 	InsertMember (iDataChecksum);
       
    52 	InsertMember (iController);
       
    53 	InsertMember (iData);
       
    54 	}
       
    55 
       
    56 
       
    57 CSISContents::CSISContents (const CSISContents& aInitialiser) :
       
    58 		CStructure <CSISFieldRoot::ESISContents> (aInitialiser),
       
    59 		iControllerChecksum (aInitialiser.iControllerChecksum), 
       
    60 		iDataChecksum (aInitialiser.iDataChecksum),
       
    61 		iController (aInitialiser.iController),
       
    62 		iData (aInitialiser.iData)
       
    63 	{ 
       
    64 	InsertMembers (); 
       
    65 	}
       
    66 
       
    67 bool CSISContents::IsSisFile(const std::wstring& aFileName)
       
    68 	{
       
    69 	TSISStream input;
       
    70 	std::wstring fileName = FixPathDelimiters(aFileName);
       
    71 	HANDLE file = ::MakeSISOpenFile(fileName.c_str(),GENERIC_READ,OPEN_EXISTING);
       
    72 	CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), 
       
    73 							CSISException::EFileProblem, std::wstring (L"cannot open ") + fileName);
       
    74 	bool success = input.import (file, NULL);
       
    75 	::CloseHandle(file);
       
    76 	CSISException::ThrowIf (! success, CSISException::EFileProblem, std::wstring (L"cannot read ") + fileName);
       
    77 	return IsSisFile(input);
       
    78 	}
       
    79 
       
    80 bool CSISContents::IsSisFile(TSISStream& aStream)
       
    81 	{
       
    82 	CSISUid::TUid uid [4];
       
    83 	aStream.seek (0);
       
    84 	aStream >> uid [0] >> uid [1] >> uid [2] >> uid [3];
       
    85 	bool isSisFile = false;
       
    86 	if( uid [0] == KUidSISXApp )
       
    87 		{
       
    88 		isSisFile = true;
       
    89 		}
       
    90 	else if(uid[2] == KUidLegacySisFile)
       
    91 		{
       
    92 		throw CSISException (CSISException::ELegacyFormat, L"file is a unspported legacy SIS file.");
       
    93 		}
       
    94 
       
    95 	return isSisFile;
       
    96 	}
       
    97 
       
    98 
       
    99 void CSISContents::Load (const std::wstring& aFileName, TUint64* size)
       
   100 	{
       
   101 	TSISStream input;
       
   102 	std::wstring fileName = FixPathDelimiters(aFileName);
       
   103 	HANDLE file = ::MakeSISOpenFile(fileName.c_str(),GENERIC_READ,OPEN_EXISTING);
       
   104 	if (INVALID_HANDLE_VALUE == file)
       
   105 		{
       
   106 		SISLogger::Log(L" Error : Cannot open file : ");
       
   107 		SISLogger::Log(fileName);
       
   108 		SISLogger::Log(L"\n");
       
   109 		throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot open ") + fileName);
       
   110 		}
       
   111 	bool success = input.import (file, size);
       
   112 	::CloseHandle(file);
       
   113 	if(!success)
       
   114 		{
       
   115 		SISLogger::Log(L" Error : Cannot read file : ");
       
   116 		SISLogger::Log(fileName);
       
   117 		SISLogger::Log(L"\n");
       
   118 		throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot read ") + fileName);
       
   119 		}
       
   120 	CSISUid::TUid uid [4];
       
   121 	input.seek (0);
       
   122 	input >> uid [0] >> uid [1] >> uid [2] >> uid [3];
       
   123 	if( uid [0] != KUidSISXApp )
       
   124 		{
       
   125 		SISLogger::Log(fileName);
       
   126 		SISLogger::Log(L" is not a SIS file .\n");
       
   127 		if(uid[2] == KUidLegacySisFile)
       
   128 			{
       
   129 			throw CSISException (CSISException::ELegacyFormat, fileName + L" is a unspported legacy SIS file.");
       
   130 			}
       
   131 		throw CSISException (CSISException::EFileFormat, fileName + L" is not a SIS file.");
       
   132 		}
       
   133 		
       
   134 	CSISException::ThrowIf (uid [3] != UidChecksum (uid [0], uid [1], uid [2]),
       
   135 							CSISException::EFileFormat,
       
   136 							std::wstring (fileName) + L" has invalid UID checksum");
       
   137 	Read (input, input.length ());
       
   138 	Verify (LanguageCount ());
       
   139 	}
       
   140 
       
   141 void CSISContents::Save (const std::wstring& aFileName)	const
       
   142 	{
       
   143 	TSISStream output;
       
   144 	if (iStub == EStubROM)
       
   145 		{
       
   146 		iController.Content ().Write (output, false);
       
   147 		}
       
   148 	else
       
   149 		{
       
   150 		OutputHeaderUids (output);
       
   151 		Write (output, false);
       
   152 		}
       
   153 	// remove R/O attributes from file in case it exists already
       
   154 	_wchmod(aFileName.c_str(),_S_IREAD | _S_IWRITE);
       
   155 	HANDLE file = ::MakeSISOpenFile(aFileName.c_str(),GENERIC_WRITE,CREATE_ALWAYS);
       
   156 	CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), 
       
   157 							CSISException::EFileProblem, std::wstring (L"cannot create ") + aFileName);
       
   158 	bool written = output.exportfile (file);
       
   159 	::CloseHandle(file);
       
   160 	if (! written)
       
   161 		{
       
   162 		::MakeSISDeleteFile(aFileName.c_str());
       
   163 		throw CSISException (CSISException::EFileProblem, std::wstring (L"cannot write to ") + aFileName);
       
   164 		}
       
   165 	}
       
   166 
       
   167 
       
   168 
       
   169 TCRC CSISContents::UIDCheck (const void *pPtr)
       
   170 	{
       
   171 	const unsigned char *pB = reinterpret_cast <const unsigned char *> (pPtr);
       
   172 	const unsigned char *pE = pB + (KUidInstallCount * sizeof (CSISUid::TUid));
       
   173 	unsigned char buf [(KUidInstallCount * sizeof(DWORD))>>1];
       
   174 	unsigned char *pT = (&buf[0]);
       
   175 	while (pB < pE)
       
   176 		{
       
   177 		*pT++ = (*pB);
       
   178 		pB += 2;
       
   179 		}
       
   180 	TCRC reply (0); 
       
   181 	DoTheCrc (reply, reinterpret_cast <const TUint8*> (buf), (KUidInstallCount * sizeof(DWORD))>>1);
       
   182 	return reply;
       
   183 	}
       
   184 
       
   185 void CSISContents::OutputHeaderUids (TSISStream& output) const
       
   186 	{
       
   187 	CSISUid::TUid uid [KUidInstallCount + 1];
       
   188 	uid [0] = KUidSISXApp;
       
   189 	uid [1] = 0;				// Reserved for future use
       
   190 	uid [2] = UID1 ();
       
   191 	uid [3] = UidChecksum (uid [0], uid [1], uid [2]);
       
   192 	for (unsigned short index = 0; index <= KUidInstallCount; index++) 
       
   193 		{
       
   194 		output << uid [index];
       
   195 		}
       
   196 	}
       
   197 
       
   198 CSISUid::TUid CSISContents::UidChecksum (const CSISUid::TUid aUid1, const CSISUid::TUid aUid2, const CSISUid::TUid aUid3)
       
   199 	{
       
   200 	CSISUid::TUid uid [3];
       
   201 
       
   202 	uid [0] = aUid1;
       
   203 	uid [1] = aUid2;
       
   204 	uid [2] = aUid3;
       
   205 
       
   206 	TCRC crcHigh (UIDCheck ((reinterpret_cast <char*> (uid)) + 1));
       
   207 	TCRC crcLow (UIDCheck (reinterpret_cast <char*> (uid)));
       
   208 	return static_cast <CSISUid::TUid> ((static_cast <unsigned int> (crcHigh) << 16) + static_cast <unsigned int> (crcLow));
       
   209 	}
       
   210 
       
   211 void CSISContents::EmbedFile (const std::wstring& aFile, const CSISUid::TUid& aUid, CSISInstallBlock& aInstall)
       
   212 	{
       
   213 	EmbedPackage (aInstall, aFile, aUid);
       
   214 	}
       
   215 
       
   216 void CSISContents::EmbedPackage (CSISInstallBlock& aInstallBlock, const std::wstring& aFile, const CSISUid::TUid& aUid)
       
   217 	{
       
   218 	std::auto_ptr<CSISContents> embed (new CSISContents());
       
   219 	embed->Load (aFile);
       
   220 
       
   221 	//makesis doesn't support embedded packages of type PA and PP.
       
   222 	if(embed->iData.Stub ())
       
   223 		{
       
   224 		SISLogger::Log(aFile);
       
   225 		SISLogger::Log(L" is a stub.\t \n");
       
   226 		SISLogger::Log(L"WARNING : Embedded Preinstalled Stub (PA/PP type) SIS file is not supported.\n");
       
   227 		throw CSISException (CSISException::EFileFormat, "Stub File");
       
   228 		} 
       
   229 
       
   230 	if (aUid != 0)
       
   231 		{
       
   232 		CSISException::ThrowIf (embed->UID1 () != aUid, CSISException::EUID, aFile + L" contains incorrect UID");
       
   233 		}
       
   234 	TUint32 index = iData.AppendData (embed->iData);
       
   235 	if (index > 0)
       
   236 		{
       
   237 		embed->SetDataIndex (index);
       
   238 		}
       
   239 	aInstallBlock.Embed (embed->iController.Content (), index);
       
   240 	}
       
   241 
       
   242 void CSISContents::Verify (const TUint32 aLanguages) const
       
   243 	{
       
   244 	assert (aLanguages == LanguageCount ());
       
   245 	CSISException::ThrowIf (aLanguages == 0, CSISException::ELanguage, "no languages defined");		
       
   246 	CStructure <CSISFieldRoot::ESISContents>::Verify (aLanguages);
       
   247 	}
       
   248 
       
   249 
       
   250 void CSISContents::PrepareCrcs ()
       
   251 	{
       
   252 	if ((iDbgFlag & EDbgDataChecksum) == 0)
       
   253 		{
       
   254 		iDataChecksum.Set (iData.Crc ());
       
   255 		}
       
   256 	if ((iDbgFlag & EDbgControllerChecksum) == 0)
       
   257 		{
       
   258 		iControllerChecksum.Set (iController.Crc ());
       
   259 		}
       
   260 	}
       
   261 
       
   262 void CSISContents::WriteSIS (std::wstring aTargetFileName)
       
   263 	{
       
   264 	MakeNeat ();	// MakeNeat () should ensure at least one language defined
       
   265 	assert (LanguageCount () > 0);
       
   266 
       
   267 	switch (iStub)
       
   268 		{
       
   269 	case EStubPreInstalled :
       
   270 		iController.Content ().SetNow ();
       
   271 		iData.SetStub ();
       
   272 		iDataChecksum.Set(0);
       
   273 		SetDebugOption(EDbgDataChecksum);
       
   274 		break;
       
   275 	case EStubROM :
       
   276 			{
       
   277 			// The below piece of code tries to put .sis extension not .SIS as target sisfile name.
       
   278 			std::wstring::size_type count (aTargetFileName.size ());
       
   279 			if (	(count >= 4) &&
       
   280 					(aTargetFileName [count - 4] == L'.'))
       
   281 				{
       
   282 				count -= 3;
       
   283 				std::wstring extension (aTargetFileName.substr (count));
       
   284 				if (	(toupper(extension [0]) == L'S') &&
       
   285 						(toupper(extension [1]) == L'I') &&
       
   286 						(toupper(extension [2]) == L'S'))
       
   287 					{
       
   288 					aTargetFileName = aTargetFileName.substr (0, count);
       
   289 					aTargetFileName += std::wstring (L"sis");
       
   290 					}
       
   291 				}
       
   292 			}
       
   293 			// Leave the date and time initialised to 1st Jan 2004, so that ROM stub
       
   294 			// files don't change every time they are built.
       
   295 		break;
       
   296 	default:
       
   297 		iController.Content ().SetNow ();
       
   298 		break;
       
   299 		}
       
   300 
       
   301 	PrepareCrcs ();
       
   302 	Verify (LanguageCount ());
       
   303 #ifdef GENERATE_ERRORS
       
   304 	if (CSISFieldRoot::IsAnyBugSet ())
       
   305 		{
       
   306 		CreateDefects ();
       
   307 		}
       
   308 #endif // GENERATE_ERRORS
       
   309 
       
   310 	Save (aTargetFileName);
       
   311 	}
       
   312 
       
   313 void CSISContents::AddPackageEntry(std::wostream& aStream, bool aVerbose) const
       
   314 	{
       
   315 	iControllerChecksum.AddPackageEntry(aStream, aVerbose);
       
   316 	iDataChecksum.AddPackageEntry(aStream, aVerbose);
       
   317 	iController.AddPackageEntry(aStream, aVerbose); // CSISCompressed
       
   318 	Controller().AddPackageEntry(aStream, aVerbose);
       
   319 	iData.AddPackageEntry(aStream, aVerbose);
       
   320 	}