secureswitools/swisistools/source/sisxlibrary/siscontroller.cpp
changeset 0 ba25891c3a9e
child 26 04d4a7bbc3e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/sisxlibrary/siscontroller.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2004-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
+
+#include "siscontroller.h"
+#include "utils.h"
+
+const unsigned short KRawSkipCount = 8;
+	// count of fields signed by sign sis, all up to but excluding iDataIndex
+
+bool CSISController::iSkip = false;
+int CSISController::iLastCtlID = -2;
+
+CSISController::CSISController (const CSISController& aInitialiser) :
+		CStructure <CSISFieldRoot::ESISController> (aInitialiser),
+		iInfo (aInitialiser.iInfo),
+		iSupportedOptions (aInitialiser.iSupportedOptions),
+		iSupportedLanguages (aInitialiser.iSupportedLanguages),
+		iPrerequisites (aInitialiser.iPrerequisites),
+		iProperties (aInitialiser.iProperties),
+		iLogo (aInitialiser.iLogo),
+		iInstallBlock (aInitialiser.iInstallBlock),
+		iSignatures (aInitialiser.iSignatures),
+		iDataIndex (aInitialiser.iDataIndex),
+		iRawBuffer (NULL),
+		iRawBufferSize(0),
+		iBufferSize (0)
+	{
+	InsertMembers ();
+	if (aInitialiser.iRawBuffer)
+		{
+		try
+			{
+			iRawBuffer = new TUint8 [aInitialiser.iBufferSize];
+			memcpy (iRawBuffer, aInitialiser.iRawBuffer, aInitialiser.iBufferSize);
+			iRawBufferSize = aInitialiser.iRawBufferSize;
+			iBufferSize = aInitialiser.iBufferSize;
+			}
+		catch (...)
+			{
+			}
+		}
+	}
+
+
+void CSISController::InsertMembers ()
+	{
+	// if you change these, change Read and Write (for SignSIS) and KRawSkipCount
+	InsertMember (iInfo);
+	InsertMember (iSupportedOptions);
+	InsertMember (iSupportedLanguages);
+	InsertMember (iPrerequisites);
+	InsertMember (iProperties);
+	InsertMember (iLogo);
+	InsertMember (iInstallBlock);
+	InsertMember (iSignatures);
+	InsertMember (iDataIndex);
+	}
+
+int CSISController::DeleteDirectory(std::string& aDirectory)
+	{
+	return RemoveDirectoryA(aDirectory.c_str());
+	}
+
+void CSISController::Read (TSISStream& aFile, const CSISFieldRoot::TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType)
+	{
+	delete [] iRawBuffer;
+	iRawBuffer = NULL;
+	iRawBufferSize = iBufferSize = 0;
+	iRawBuffer = new TUint8 [aContainerSize];
+	iControllerID = ++iLastCtlID;
+	try
+		{
+		iBufferSize = aContainerSize;
+		TSISStream::pos_type pos = aFile.tell ();
+		CSISHeader header;
+		header.Read (aFile, aContainerSize, aArrayType);
+		assert (header.DataType () == CSISFieldRoot::ESISController);
+		iRawBufferSize = header.DataSize();
+		aFile.read (iRawBuffer, iRawBufferSize);
+		aFile.seek (pos);
+		if (iSkip)
+			{
+			assert (aArrayType == CSISFieldRoot::ESISUndefined);	// arrays not tested
+			iBufferSize = CStructure <CSISFieldRoot::ESISController>::SkipRead (aFile, header.DataSize(), aArrayType, KRawSkipCount, true);
+			}
+		else
+			{
+			iBufferSize = CStructure <CSISFieldRoot::ESISController>::SkipRead (aFile, header.DataSize(), aArrayType, KRawSkipCount, false);
+			aFile.seek (pos);
+			CStructure <CSISFieldRoot::ESISController>::Read (aFile, header.DataSize(), aArrayType);
+			}
+		}
+	catch (...)
+		{
+		delete [] iRawBuffer;
+		iRawBuffer = NULL;
+		iBufferSize = 0;
+		iRawBufferSize = 0;
+		throw CSISException (CSISException::EFileFormat, L"error while reading sis");
+		}
+	}
+
+
+void CSISController::Write (TSISStream& aFile, const bool aIsArrayElement) const
+	{
+	if (! iRawBuffer)
+		{
+		CStructure <CSISFieldRoot::ESISController>::Write (aFile, aIsArrayElement);
+		}
+	else
+		{
+		RawSkipWrite (aFile, aIsArrayElement, iRawBuffer, iBufferSize, KRawSkipCount);
+		}
+	}
+
+void CSISController::AddSignatureChain(CSignatureCertChainData& aSISSigCertChain)
+	{
+	iSignatures.Push (aSISSigCertChain);	
+	}
+
+void CSISController::RemoveSignature ()
+	{
+	CSISException::ThrowIf (iSignatures.size () == 0, CSISException::ENotSigned, L"input file");
+	CSISFieldRoot::TFieldSize size = iSignatures.Last ().ByteCountWithHeader (false);
+	assert (size < iBufferSize);
+	iSignatures.Pop ();
+	iBufferSize -= size;
+	iRawBufferSize -= size;
+	}
+
+void CSISController::Load (const std::wstring& aFileName)
+	{
+	TSISStream input;
+	HANDLE file = ::MakeSISOpenFile(aFileName.c_str(),GENERIC_READ,OPEN_EXISTING);
+	CSISException::ThrowIf ((INVALID_HANDLE_VALUE == file), 
+							CSISException::EFileProblem, std::wstring (L"cannot open ") + aFileName);
+	bool success = input.import (file, NULL);
+	
+	TUint32 len = ::GetFileSize(file,0);
+
+	::CloseHandle(file);
+	
+	CSISException::ThrowIf (! success, CSISException::EFileProblem, std::wstring (L"cannot read ") + aFileName);
+
+	TUint32 controllerSize;
+	input.seek (0);
+	input>>controllerSize;
+
+	CSISException::ThrowIf ((controllerSize+4) != len, CSISException::EFileProblem, aFileName + std::wstring (L" Is not a valid SIS or SIS Controller"));
+
+	input.seek (0); 
+
+	//default parameter CSISFieldRoot::ESISController is passed to ensure that the 
+	//Stub SIS Controller file reading starts from the controller length 
+	Read (input, len,CSISFieldRoot::ESISController); 
+}
+
+
+void CSISController::AddPackageEntry(std::wostream& aStream, bool aVerbose) const
+	{
+	iSupportedLanguages.AddPackageEntry(aStream, aVerbose);
+	iInfo.AddPackageEntry(aStream, aVerbose);
+	iPrerequisites.AddPackageEntry(aStream, aVerbose);
+	iSupportedOptions.AddPackageEntry(aStream, aVerbose);
+	iProperties.AddPackageEntry(aStream, aVerbose);
+	iLogo.AddPackageEntry(aStream, aVerbose);
+	iInstallBlock.AddPackageEntry(aStream, aVerbose);
+	for(int i = 0; i < iSignatures.size(); ++i)
+		{
+		iSignatures[i].AddPackageEntry(aStream, aVerbose);
+		}
+	}
+
+TUint64 CSISController::ControllerSizeForHash() const
+	{
+	TUint64 ctlSize = ByteCount(false);
+	TUint64 size = ctlSize - iSignatures.ByteCountWithHeader(false) - iDataIndex.ByteCountWithHeader(false);
+	if(CSISHeader::IsBigHeader(ctlSize))
+		{
+		size += 8;
+		}
+	else
+		{
+		size += 4;
+		}
+	
+	return size;
+	}
+