diff -r aba6b8104af3 -r 84a16765cd86 installationservices/swinstallationfw/source/sifcommon.cpp --- /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 +#include +#include + +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* 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(aStream.ReadInt32L()); + self->iInstallStatus = static_cast(aStream.ReadInt32L()); + self->iComponentId = aStream.ReadInt32L(); + self->iAuthenticity = static_cast(aStream.ReadInt32L()); + UnpackCapabilitySet(aStream.ReadInt32L(), self->iUserGrantableCaps); + self->iMaxInstalledSize = aStream.ReadInt32L(); + self->iHasExe = aStream.ReadInt32L(); + + const TInt numChildren = aStream.ReadInt32L(); + for (TInt i=0; iiChildren.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(iAuthenticity)); + aStream.WriteInt32L(PackCapabilitySet(iUserGrantableCaps)); + aStream.WriteInt32L(iMaxInstalledSize); + aStream.WriteInt32L(iHasExe); + + const TInt numChildren = iChildren.Count(); + aStream.WriteInt32L(numChildren); + for (TInt i=0; iExternalizeL(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::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(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; iCompareF(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 buf; + buf.Copy(reinterpret_cast(&aValue), sizeof(TInt)/2); + AddStringL(aName, buf); + } + +EXPORT_C void COpaqueNamedParams::GetNamesL(RPointerArray& aNames) const + { + InternalizeFromExternalBufferL(); + + const TInt len = iParams.Count(); + for (TInt i=0; iDes()); + 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& refParams = const_cast&>(iParams); + + TInt len = aStream.ReadInt32L(); + for (TInt i=0; iSize(), 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; iCompareF(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(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& refParams = const_cast&>(iParams); + refParams.Reset(); + } + + void COpaqueNamedParams::CleanupExternalBuffer() const + { + delete iExternalBuffer; + iExternalBuffer = NULL; + iDeferredInternalization = EFalse; + }