installationservices/swinstallationfw/source/sifcommon.cpp
changeset 24 84a16765cd86
child 25 98b66e4fb0be
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swinstallationfw/source/sifcommon.cpp	Fri Mar 19 09:33:35 2010 +0200
@@ -0,0 +1,682 @@
+/*
+* Copyright (c) 2008-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: 
+*
+*/
+
+
+#include <f32file.h>
+#include <usif/sif/sifcommon.h>
+#include <s32mem.h>
+
+using namespace Usif;
+
+/**
+	The COpaqueNamedParams and CComponentInfo containers implement the deferred internalization
+	logic. This mechanism is necessary because these containers may be passed through IPC between
+	the SIF client and server. Hence, they must be externalized and internalized on both sides.
+	However, The SIF client doesn't implement an active object and therefore it cannot internalize
+	parameters returned by the SIF server. This de-serialization is done by the deferred internalization
+	logic when the user accesses them first time.
+	Hence, all the get methods, for example Name(), GetIntByName(), StringByNameL(), call the
+	InternalizeFromExternalBufferL() method which calls ConstInternalizeL() in order to unpack
+	the data recived from the SIF server if there is any. ConstInternalizeL() is a const method despite
+	the fact it modifies class'es members. This is done to keep the get methods const as expected by
+	the users.
+ */
+
+// ##########################################################################################
+
+namespace
+	{
+	TInt PackCapabilitySet(const TCapabilitySet& aCapSet)
+		{
+		TInt caps=0;
+		for (TInt c=0; c<ECapability_Limit; ++c)
+			{
+			if (aCapSet.HasCapability(TCapability(c)))
+				{
+				caps += (1<<c);
+				}
+			}
+		return caps;
+		}
+
+	void UnpackCapabilitySet(TInt aPackedCapSet, TCapabilitySet& aCapSet)
+		{
+		for (TInt c=0; c<ECapability_Limit; ++c)
+			{
+			const TInt cap = 1<<c;
+			if (aPackedCapSet&cap)
+				{
+				aCapSet.AddCapability(TCapability(c));
+				}
+			}
+		}
+	}
+
+// ##########################################################################################
+ 
+EXPORT_C TSecurityContext::TSecurityContext(const RMessage2& aMessage): iMsg(aMessage)
+	{
+	}
+
+EXPORT_C TBool TSecurityContext::HasCapability(TCapability aCapability) const
+	{
+	return iMsg.HasCapability(aCapability);
+	}
+
+EXPORT_C void TSecurityContext::HasCapabilityL(TCapability aCapability) const
+	{
+	iMsg.HasCapabilityL(aCapability);
+	}
+
+EXPORT_C TSecureId TSecurityContext::SecureId() const
+	{
+	return iMsg.SecureId();
+	}
+
+// ##########################################################################################
+
+CComponentInfo::CNode::CNode() : iAuthenticity(ENotAuthenticated)
+	{
+	iUserGrantableCaps.SetEmpty();
+	}
+
+EXPORT_C CComponentInfo::CNode::~CNode()
+	{
+	delete iSoftwareTypeName;
+	delete iComponentName;
+	delete iGlobalComponentId;
+	delete iVersion;
+	delete iVendor;
+
+	iChildren.Close();
+	}
+
+EXPORT_C CComponentInfo::CNode* CComponentInfo::CNode::NewLC(const TDesC& aSoftwareTypeName, const TDesC& aComponentName,
+															const TDesC& aVersion, const TDesC& aVendor, TScomoState aScomoState,
+															TInstallStatus aInstallStatus, TComponentId aComponentId,
+															const TDesC& aGlobalComponentId, TAuthenticity aAuthenticity,
+															const TCapabilitySet& aUserGrantableCaps, TInt aMaxInstalledSize,
+															TBool aHasExe,
+															RPointerArray<CNode>* aChildren)
+	{
+	// We leave if aSoftwareTypeName, aComponentName, aVersion, aVendor or aGlobalComponentId exceeds KMaxDescriptorLength
+	if (aSoftwareTypeName.Length() > KMaxDescriptorLength ||
+		aComponentName.Length() > KMaxDescriptorLength ||
+		aVersion.Length() > KMaxDescriptorLength ||
+		aVendor.Length() > KMaxDescriptorLength ||
+		aGlobalComponentId.Length() > KMaxDescriptorLength)
+		{
+		User::Leave(KErrOverflow);
+		}
+		
+
+	// Since the max heap buffer length is 2K, which is more than (num of parameters * KMaxDescriptorLength), we just assert this condition
+	__ASSERT_ALWAYS(aSoftwareTypeName.Length() + aComponentName.Length() + aVersion.Length() + aVendor.Length() + 
+					aGlobalComponentId.Length() <= KMaxHeapBufLength, User::Leave(KErrOverflow));
+
+	// Create an instance of CNode
+	CNode* self = new (ELeave) CNode();
+	CleanupStack::PushL(self);
+
+	// Copy Software Type Name, Component Name, Version, aVendor, aGlobalComponentId
+	self->iSoftwareTypeName = aSoftwareTypeName.AllocL();
+	self->iComponentName = aComponentName.AllocL();
+	self->iVersion = aVersion.AllocL();
+	self->iVendor = aVendor.AllocL();
+	self->iGlobalComponentId = aGlobalComponentId.AllocL();
+
+	// Others
+	self->iScomoState = aScomoState;
+	self->iInstallStatus = aInstallStatus;
+	self->iComponentId = aComponentId;
+	self->iAuthenticity = aAuthenticity;
+	self->iUserGrantableCaps = aUserGrantableCaps;
+	self->iMaxInstalledSize = aMaxInstalledSize;
+	self->iHasExe = aHasExe;
+
+	// Embedded Components
+	if(aChildren != NULL)
+		{
+		for (TInt i=aChildren->Count()-1; i>=0; --i)
+			{
+			self->iChildren.InsertL((*aChildren)[i], 0);
+			aChildren->Remove(i);
+			}
+		}
+	
+	return self;
+	}
+
+EXPORT_C void CComponentInfo::CNode::AddChildL(CComponentInfo::CNode* aChild)
+	{
+	if (aChild == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	iChildren.AppendL(aChild);
+	}
+
+CComponentInfo::CNode* CComponentInfo::CNode::NewL(RReadStream& aStream)
+	{
+	// Create an instance of CNode
+	CNode* self = new (ELeave) CNode();
+	CleanupStack::PushL(self);
+	
+	self->iSoftwareTypeName = HBufC::NewL(aStream, KMaxDescriptorLength);
+	self->iComponentName = HBufC::NewL(aStream, KMaxDescriptorLength);
+	self->iVersion = HBufC::NewL(aStream, KMaxDescriptorLength);
+	self->iVendor = HBufC::NewL(aStream, KMaxDescriptorLength);
+	self->iGlobalComponentId = HBufC::NewL(aStream, KMaxDescriptorLength);
+	self->iScomoState = static_cast<TScomoState>(aStream.ReadInt32L());
+	self->iInstallStatus = static_cast<TInstallStatus>(aStream.ReadInt32L());
+	self->iComponentId = aStream.ReadInt32L();
+	self->iAuthenticity = static_cast<TAuthenticity>(aStream.ReadInt32L());
+	UnpackCapabilitySet(aStream.ReadInt32L(), self->iUserGrantableCaps);
+	self->iMaxInstalledSize = aStream.ReadInt32L();
+	self->iHasExe = aStream.ReadInt32L();
+
+	const TInt numChildren = aStream.ReadInt32L();
+	for (TInt i=0; i<numChildren; ++i)
+		{
+		CNode* node = CNode::NewL(aStream);
+		CleanupStack::PushL(node);
+		self->iChildren.AppendL(node);
+		CleanupStack::Pop(node);
+		}
+	
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CComponentInfo::CNode::ExternalizeL(RWriteStream& aStream) const
+	{
+	ASSERT (iSoftwareTypeName!=NULL && iComponentName!=NULL && iVersion!=NULL && iVendor!=NULL && iGlobalComponentId!=NULL);
+
+	aStream << *iSoftwareTypeName;
+	aStream << *iComponentName;
+	aStream << *iVersion;
+	aStream << *iVendor;
+	aStream << *iGlobalComponentId;
+
+	aStream.WriteInt32L(iScomoState);
+	aStream.WriteInt32L(iInstallStatus);
+	aStream.WriteInt32L(iComponentId);
+	aStream.WriteInt32L(static_cast<TInt>(iAuthenticity));
+	aStream.WriteInt32L(PackCapabilitySet(iUserGrantableCaps));
+	aStream.WriteInt32L(iMaxInstalledSize);
+	aStream.WriteInt32L(iHasExe);
+	
+	const TInt numChildren = iChildren.Count();
+	aStream.WriteInt32L(numChildren);
+	for (TInt i=0; i<numChildren; ++i)
+		{
+		iChildren[i]->ExternalizeL(aStream);
+		}
+	}
+
+EXPORT_C const TDesC& CComponentInfo::CNode::SoftwareTypeName() const
+	{
+	return *iSoftwareTypeName;
+	}
+
+EXPORT_C const TDesC& CComponentInfo::CNode::ComponentName() const
+	{
+	return *iComponentName;
+	}
+
+EXPORT_C const TDesC& CComponentInfo::CNode::Version() const
+	{
+	return *iVersion;
+	}
+
+EXPORT_C const TDesC& CComponentInfo::CNode::Vendor() const
+	{
+	return *iVendor;
+	}
+
+EXPORT_C TScomoState CComponentInfo::CNode::ScomoState() const
+	{
+	return iScomoState;
+	}
+
+EXPORT_C TInstallStatus CComponentInfo::CNode::InstallStatus() const
+	{
+	return iInstallStatus;
+	}
+
+EXPORT_C TComponentId CComponentInfo::CNode::ComponentId() const
+	{
+	return iComponentId;
+	}
+
+EXPORT_C const TDesC& CComponentInfo::CNode::GlobalComponentId() const
+	{
+	return *iGlobalComponentId;
+	}
+
+EXPORT_C TAuthenticity CComponentInfo::CNode::Authenticity() const
+	{
+	return iAuthenticity;
+	}
+
+EXPORT_C const TCapabilitySet& CComponentInfo::CNode::UserGrantableCaps() const
+	{
+	return iUserGrantableCaps;
+	}
+
+EXPORT_C TInt CComponentInfo::CNode::MaxInstalledSize() const
+	{
+	return iMaxInstalledSize;
+	}
+
+EXPORT_C TBool CComponentInfo::CNode::HasExecutable() const
+	{
+	return iHasExe;
+	}
+
+EXPORT_C const RPointerArray<CComponentInfo::CNode>& CComponentInfo::CNode::Children() const
+	{
+	return iChildren;
+	}
+
+// ##########################################################################################
+
+CComponentInfo::CComponentInfo() : iExternalBufferPtr(NULL, 0, 0)
+	{
+	}
+
+EXPORT_C CComponentInfo::~CComponentInfo()
+	{
+	delete iRootNode;
+
+	CleanupExternalBuffer();
+	}
+
+EXPORT_C CComponentInfo* CComponentInfo::NewL()
+	{
+	return new (ELeave) CComponentInfo;
+	}
+
+EXPORT_C CComponentInfo* CComponentInfo::NewLC()
+	{
+	CComponentInfo* self = new (ELeave) CComponentInfo;
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+EXPORT_C const CComponentInfo::CNode& CComponentInfo::RootNodeL() const
+	{
+	InternalizeFromExternalBufferL();
+	
+	if (iRootNode == NULL)
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	return *iRootNode;
+	}
+
+EXPORT_C void CComponentInfo::SetRootNodeL(CNode* aRootNode)
+	{
+	InternalizeFromExternalBufferL();
+	
+	if (aRootNode == NULL)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+	delete iRootNode;
+	iRootNode = aRootNode;
+	}
+
+EXPORT_C void CComponentInfo::SetRootNodeAsChildL(CNode& aParentNode)
+	{
+	InternalizeFromExternalBufferL();
+	
+	if (iRootNode == NULL)
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	aParentNode.AddChildL(iRootNode);
+	iRootNode = NULL;
+	}
+
+EXPORT_C void CComponentInfo::ExternalizeL(RWriteStream& aStream) const
+	{
+	InternalizeFromExternalBufferL();
+	
+	aStream.WriteInt8L(iRootNode != NULL);
+	
+	if (iRootNode != NULL)
+		{
+		iRootNode->ExternalizeL(aStream);
+		}
+	}
+
+void CComponentInfo::ConstInternalizeL(RReadStream& aStream) const
+	{
+	CNode*& rootNode = const_cast<CNode*&>(iRootNode);
+	delete rootNode;
+	rootNode = NULL;
+	
+	if (aStream.ReadInt8L() != 0)
+		{
+		rootNode = CNode::NewL(aStream);
+		}
+	}
+
+void CComponentInfo::CleanupExternalBuffer() const
+	{
+	delete iExternalBuffer;
+	iExternalBuffer = NULL;
+	iDeferredInternalization = EFalse;
+	}
+
+void CComponentInfo::InternalizeFromExternalBufferL() const
+	{
+	if (iDeferredInternalization)
+		{
+		iDeferredInternalization = EFalse;
+
+		RDesReadStream rs(*iExternalBuffer);
+		CleanupClosePushL(rs);
+		ConstInternalizeL(rs);
+		CleanupStack::PopAndDestroy(&rs);
+
+		CleanupExternalBuffer();
+		}
+	}
+
+EXPORT_C void CComponentInfo::PrepareForIpcL(TIpcArgs& aIpcArgs, TInt aIndex)
+	{
+	delete iExternalBuffer;
+	iExternalBuffer = NULL;
+
+	iExternalBuffer = HBufC8::NewL(KMaxComponentInfoStreamedSize);
+	iExternalBufferPtr.Set(iExternalBuffer->Des());
+	
+	aIpcArgs.Set(aIndex, &iExternalBufferPtr);
+	
+	iDeferredInternalization = ETrue;
+	}
+
+// ##########################################################################################
+
+COpaqueNamedParams::COpaqueNamedParams()
+	: iExternalBuffer(NULL), iExternalBufferPtr(NULL, 0, 0), iDeferredInternalization(EFalse), iExternalizedSize(sizeof(TInt))
+	{
+	}
+
+EXPORT_C COpaqueNamedParams::~COpaqueNamedParams()
+	{
+	Cleanup();
+	iParams.Close();
+	CleanupExternalBuffer();
+	}
+
+EXPORT_C COpaqueNamedParams* COpaqueNamedParams::NewL()
+	{
+	return new (ELeave) COpaqueNamedParams;
+	}
+
+EXPORT_C COpaqueNamedParams* COpaqueNamedParams::NewLC()
+	{
+	COpaqueNamedParams* self = new (ELeave) COpaqueNamedParams;
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+void COpaqueNamedParams::VerifyExternalizedSizeForNewParamL(TInt aNameSize, TInt aValueSize) const
+	{
+	const TInt load = 2*sizeof(TInt) + aNameSize + aValueSize;
+	if (aNameSize > KMaxDescriptorLength || aValueSize > KMaxDescriptorLength ||
+		iExternalizedSize + load > KMaxExternalizedSize)
+		{
+		User::Leave(KErrOverflow);
+		}
+	iExternalizedSize += load;
+	}
+
+void COpaqueNamedParams::VerifyExternalizedSizeForExistingParamL(TInt aOldValueSize, TInt aNewValueSize) const
+	{
+	const TInt diff = aNewValueSize - aOldValueSize;
+	if (aNewValueSize > KMaxDescriptorLength ||
+		iExternalizedSize + diff > KMaxExternalizedSize)
+		{
+		User::Leave(KErrOverflow);
+		}
+	iExternalizedSize += diff;
+	}
+
+EXPORT_C void COpaqueNamedParams::AddStringL(const TDesC& aName, const TDesC& aValue)
+	{
+	HBufC* value = HBufC::NewLC(aValue.Length());
+	TPtr bufValue(value->Des());
+	bufValue.Copy(aValue);
+
+	const TInt len = iParams.Count();
+	for (TInt i=0; i<len; ++i)
+		{
+		if (iParams[i].iName->CompareF(aName) == 0)
+			{
+			VerifyExternalizedSizeForExistingParamL(iParams[i].iValue->Size(), value->Size());
+			delete iParams[i].iValue;
+			iParams[i].iValue = value;
+			CleanupStack::Pop(value);
+			return;
+			}
+		}
+
+	VerifyExternalizedSizeForNewParamL(aName.Size(), aValue.Size());
+
+	HBufC* name = HBufC::NewLC(aName.Length());
+	TPtr bufName(name->Des());
+	bufName.Copy(aName);
+
+	TItem item = {name, value};
+	iParams.AppendL(item);
+
+	CleanupStack::Pop(2, value);
+	}
+
+EXPORT_C void COpaqueNamedParams::AddIntL(const TDesC& aName, TInt aValue)
+	{
+  	// Assumption: the code below won't be compiled in __KERNEL_MODE__ so HBufC is always defined as HBufC16
+  	TBuf<sizeof(TInt)/2> buf;
+  	buf.Copy(reinterpret_cast<TUint16*>(&aValue), sizeof(TInt)/2);
+	AddStringL(aName, buf);
+	}
+
+EXPORT_C void COpaqueNamedParams::GetNamesL(RPointerArray<HBufC>& aNames) const
+	{
+	InternalizeFromExternalBufferL();
+
+	const TInt len = iParams.Count();
+	for (TInt i=0; i<len; ++i)
+		{
+		const TDesC& ref = *iParams[i].iName;
+		HBufC* name = HBufC::NewLC(ref.Length());
+		TPtr bufName(name->Des());
+		bufName.Copy(ref);
+		aNames.AppendL(name);
+		CleanupStack::Pop(name);
+		}
+	}
+	
+EXPORT_C void COpaqueNamedParams::ExternalizeL(RWriteStream& aStream) const
+	{
+	InternalizeFromExternalBufferL();
+
+	TInt len = iParams.Count();
+	aStream.WriteInt32L(len);
+	for (TInt i=0; i<len; ++i)
+		{
+		aStream << *iParams[i].iName;
+		aStream << *iParams[i].iValue;
+		}
+	}
+
+EXPORT_C void COpaqueNamedParams::InternalizeL(RReadStream& aStream)
+	{
+	Cleanup();
+	ConstInternalizeL(aStream);
+	}
+
+void COpaqueNamedParams::ConstInternalizeL(RReadStream& aStream) const
+	{
+	RArray<TItem>& refParams = const_cast<RArray<TItem>&>(iParams);
+	
+	TInt len = aStream.ReadInt32L();
+	for (TInt i=0; i<len; ++i)
+		{
+		HBufC* name = HBufC::NewLC(aStream, KMaxDescriptorLength);
+		HBufC* value = HBufC::NewLC(aStream, KMaxDescriptorLength);
+
+		// We need to update iExternalizedSize here because its value must correspond to the params beind added from aStream
+		VerifyExternalizedSizeForNewParamL(name->Size(), value->Size());
+
+		TItem item = {name, value};
+		refParams.AppendL(item);
+
+		CleanupStack::Pop(2, name);
+		}
+	}
+
+EXPORT_C void COpaqueNamedParams::PrepareArgumentsForIpcL(TIpcArgs& aIpcArgs, TInt aIndex) const
+	{
+	delete iExternalBuffer;
+	iExternalBuffer = NULL;
+	iExternalBuffer = HBufC8::NewL(iExternalizedSize);
+	iExternalBufferPtr.Set(iExternalBuffer->Des());
+	
+	RDesWriteStream ws(iExternalBufferPtr);
+	CleanupClosePushL(ws);
+	ExternalizeL(ws);
+	ws.CommitL();
+	CleanupStack::PopAndDestroy(&ws);
+	
+	aIpcArgs.Set(aIndex, &iExternalBufferPtr);
+	}
+
+EXPORT_C void COpaqueNamedParams::PrepareResultsForIpcL(TIpcArgs& aIpcArgs, TInt aIndex)
+	{
+	delete iExternalBuffer;
+	iExternalBuffer = NULL;
+	iExternalBuffer = HBufC8::NewL(KMaxExternalizedSize);
+	iExternalBufferPtr.Set(iExternalBuffer->Des());
+	
+	RDesWriteStream ws(iExternalBufferPtr);
+	CleanupClosePushL(ws);
+	ws.WriteInt32L(0); // Write the initial count of results, so that the object will be valid even if no results are added
+	CleanupStack::PopAndDestroy(&ws);
+	
+	aIpcArgs.Set(aIndex, &iExternalBufferPtr);
+	
+	iDeferredInternalization = ETrue;
+	}
+
+void COpaqueNamedParams::InternalizeFromExternalBufferL() const
+	{
+	if (iDeferredInternalization)
+		{
+		iDeferredInternalization = EFalse;
+
+		ConstCleanup();
+		
+		RDesReadStream rs(*iExternalBuffer);
+		CleanupClosePushL(rs);
+		ConstInternalizeL(rs);
+		CleanupStack::PopAndDestroy(&rs);
+
+		CleanupExternalBuffer();
+		}
+	}
+
+EXPORT_C const TDesC& COpaqueNamedParams::StringByNameL(const TDesC& aName) const
+	{
+	InternalizeFromExternalBufferL();
+	
+	const TInt len = iParams.Count();
+	for (TInt i=0; i<len; ++i)
+		{
+		if (iParams[i].iName->CompareF(aName) == 0)
+			{
+			return *iParams[i].iValue;
+			}
+		}
+	return KNullDesC;    
+	}
+
+EXPORT_C TBool COpaqueNamedParams::GetIntByNameL(const TDesC& aName, TInt& aValue) const
+	{
+	InternalizeFromExternalBufferL();
+
+	const TDesC& value = StringByNameL(aName);
+	if (value == KNullDesC)
+		{
+		return EFalse;
+		}
+	aValue = *(reinterpret_cast<const TUint*>(value.Ptr()));
+	return ETrue;
+	}
+
+EXPORT_C TInt COpaqueNamedParams::IntByNameL(const TDesC& aName) const
+	{
+	InternalizeFromExternalBufferL();
+
+	TInt val;
+	if (!GetIntByNameL(aName, val))
+		{
+		User::Leave(KErrNotFound);
+		}
+	return val;
+	}
+
+EXPORT_C TInt COpaqueNamedParams::CountL() const
+	{
+	InternalizeFromExternalBufferL();
+	return iParams.Count();
+	}
+	
+EXPORT_C void COpaqueNamedParams::Cleanup()
+	{
+	ConstCleanup();
+	}
+
+void COpaqueNamedParams::ConstCleanup() const
+	{
+	// Cleanup internal params
+	iExternalizedSize = sizeof(TInt);
+
+	const TInt len = iParams.Count();
+	for (TInt i=0; i<len; ++i)
+		{
+		delete iParams[i].iName;
+		delete iParams[i].iValue;
+		}
+	RArray<TItem>& refParams = const_cast<RArray<TItem>&>(iParams);
+	refParams.Reset();
+	}
+
+	void COpaqueNamedParams::CleanupExternalBuffer() const
+	{
+	delete iExternalBuffer;
+	iExternalBuffer = NULL;
+	iDeferredInternalization = EFalse;
+	}