lowlevellibsandfws/pluginfw/Framework/frame/LoadManager.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lowlevellibsandfws/pluginfw/Framework/frame/LoadManager.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,754 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Implementation of the CLoadManager class
+// 
+//
+
+/**
+ @internalComponent
+ @file
+*/
+
+#include "EComDebug.h"
+#include "UnloadPolicy.h"
+#include "LoadManager.h"
+#include "EComUidCodes.h"
+#include <ecom/ecomerrorcodes.h>
+#include "e32math.h"
+#include "EComInternalErrorCodes.h"
+#include <ecom/ecomextendedinterfaceerrorcodes.h>
+/**
+Standardized safe construction which leaves nothing on the cleanup stack.
+@return			A pointer to the new class
+@post			CLoadManager is fully constructed, and initialized.
+ */
+CLoadManager* CLoadManager::NewL()
+	{
+	return new(ELeave) CLoadManager();
+	}
+
+CLoadManager::~CLoadManager()
+	{
+	iInstanceInfoList.ResetAndDestroy();
+	iAllUnloadPolicies.ResetAndDestroy();
+	ClearGarbage();
+	}
+
+/**
+Notifies the interface implementation DLL that one of its objects has been destroyed if it exists,
+otherwise returns false to indicate no exist aImplementationUid.
+@param          aInstanceKey A key specifying a previously created implementation.
+@pre 			CLoadManager is fully constructed,
+@post			CLoadManager's interface implementation DLL references
+				are decreased by one. The instance info representing the implementation
+				is destroyed.
+*/
+TBool CLoadManager::DestroyedThis(TUid aInstanceKey)
+	{
+	// Clear the garbage list because we know we have finished with them
+	ClearGarbage();
+
+	__ECOM_TRACE1("ECOM: Implementation Instance destroyed %x", aInstanceKey.iUid);
+
+	// Sanity check that the pointer is divisible by four. A binary number is divisible
+	// by four if and only if the two rightmost bits are both zero.
+	// This is a compromised check for checking that the pointer is an address.
+    if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0))
+        {
+	    __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey));
+	    User::Leave(KErrNotFound);
+        }
+
+	// The instance info pointer is stored in the instance key.
+	CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid);
+
+	// Check that the pointer exists before using it
+	TInt position = iInstanceInfoList.FindInAddressOrder(instanceInfo);
+	if(position == KErrNotFound)
+		{
+		return EFalse;
+		}
+	
+	CUnloadPolicy* policy = instanceInfo->UnloadPolicy();
+	if (policy != NULL)
+		{
+		// If needed, will move the policy to the garbage list, and remove policy from the unload policy list.
+		Cleanup(policy);
+		}
+	iInstanceInfoList.Remove(position);
+	// Remove the instance info item, finished with it.
+	delete instanceInfo;
+	return ETrue;
+	}
+
+/**
+Check whether the policy Arrays are empty or not.
+@return            Returns True if the policy Arrays are empty, otherwise return False.
+@pre             CLoadManager is fully constructed,
+@post            CLoadManager remains the same.
+*/
+TBool CLoadManager::PolicyArraysEmpty() const 
+    {
+    if( (iAllUnloadPolicies.Count() == 0)&&(iInstanceInfoList.Count() == 0) )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+/**
+Returns an implementation object to satisfy the specified interface.
+@param			aUniqueImplementationUid The implementation to find.
+@param			aEntry Information on the dll containing the implementation
+@param			aCreationParameters A pointer to the creation parameter
+				structure passed to the creation method when called.
+@param			aCreationParamsFlag A boolean flag to indicate the existence or non-existence
+				of aCreationParameters. Will be ETrue even for if the value of
+				aCreationParameters is NULL.
+@param          aInstanceKey A key specifying a previously created implementation.
+@return			TAny* a pointer to the fully constructed instantiation. The pointer is
+				guaranteed to be valid only until DestroyedThis is called.
+@pre 			CLoadManager is fully constructed,
+@post			Fully constructed implementation is returned to the
+				caller, and aUniqueUid contains the implementation Dll's
+				unique UID.
+*/
+TAny* CLoadManager::ImplementationObjectL(const TUid& aUniqueImplementationUid,
+										 const TEntry& aEntry,
+										 TAny* aCreationParameters,
+										 TBool aCreationParamsFlag,
+										 TUid& aInstanceKey)
+	{
+	//if the implementation Uid here is Null or the entry returned by the ecomserver
+	//contains nothing, we should leave with KErrNotFound
+	if(aUniqueImplementationUid == KNullUid || (aEntry.iName).Length()==0)
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	TAny* object = NULL;               // Instantiation object
+	CUnloadPolicy* policy = NULL;      // Policy of implementation
+	TLibraryFunction libFunctionProxy; // Library function proxy pointer
+
+	GetUnloadPolicy(aUniqueImplementationUid,aEntry,policy);
+	if (policy == NULL)
+		{
+		// No policy found, so create a new CUnloadPolicy and load DLL.
+		policy = CUnloadPolicy::NewLC(aEntry);
+		libFunctionProxy = policy->LoadDllAndReturnProxyL();
+		if (libFunctionProxy==NULL)
+			{
+			User::Leave(KErrNotFound);
+			}
+		iAllUnloadPolicies.AppendL(policy);
+		CleanupStack::Pop(policy);	// owned by iAllUnloadPolicies
+		}
+	else
+		{
+		// Found a policy. Load Dll if not already loaded.
+		libFunctionProxy = policy->LoadDllAndReturnProxyL();
+		if (libFunctionProxy==NULL)
+			{
+			User::Leave(KErrNotFound);
+			}
+		}
+	// Initial count of instances. This is used for cleanup purposes, to see if an instance
+	// was added to the instance info list during the object creation. If a failure occurs
+	// than the instance info that was added to the list will be removed.
+	TInt initialCount = iInstanceInfoList.Count();
+	TInt err = KErrNone;
+
+	if (aEntry[1] == KUidInterfaceImplementationCollection)
+		{
+		// PLUGIN1 dll. Create the implementation object.
+		TRAP(err,object = ImplementationObject1L(aUniqueImplementationUid,aCreationParameters,
+			aCreationParamsFlag,aInstanceKey,policy,libFunctionProxy));
+		}
+	else if (aEntry[1] == KUidInterfaceImplementationCollection3)
+		{
+		// PLUGIN3 dll. Create the implementation object.
+		TRAP(err,object = ImplementationObject3L(aUniqueImplementationUid,aCreationParameters,
+			aCreationParamsFlag, aInstanceKey,policy, libFunctionProxy));
+		}
+	else
+		{
+		err = KErrNotSupported;
+		}
+	
+	if (err != KErrNone)
+		{
+		if (iInstanceInfoList.Count() > initialCount)
+			{
+			// If an instance was added to the instance list, remove it here.
+			// The instance info pointer is stored in the instance key. We know its
+			// valid because it was set by ecom in call to ImplementationObject1L or
+			// ImplementationObject3L
+			CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid);
+			TInt pos = iInstanceInfoList.FindInAddressOrder(instanceInfo);
+			if(pos != KErrNotFound)
+				{
+				iInstanceInfoList.Remove(pos);
+				}
+			}
+
+		ClearGarbage();
+		// If needed, will move the policy to the garbage list, and remove policy from the unload policy list.
+		Cleanup(policy);
+		User::Leave(err);
+		}
+		
+	__ECOM_TRACE2("ECOM: Implementation created (%03d) %x", ++iDebugInstantiationCounter, aUniqueImplementationUid.iUid);
+			
+	return object;
+	}
+
+/**
+Returns an implementation object to satisfy the specified interface.
+@param			aUniqueImplementationUid The implementation to find.
+@param			aCreationParameters A pointer to the creation parameter
+				structure passed to the creation method when called.
+@param			aCreationParamsFlag A boolean flag to indicate the existence or non-existence
+				of aCreationParameters. Will be ETrue even for if the value of
+				aCreationParameters is NULL.
+@param          aInstanceKey A key specifying a previously created implementation.
+@param          aPolicy policy of implementation
+@param          aLibFunctionProxy Library function proxy pointer.
+@return			TAny* a pointer to the fully constructed instantiation. The pointer is
+				guaranteed to be valid only until DestroyedThis is called.
+*/
+TAny* CLoadManager::ImplementationObject1L(const TUid& aUniqueImplementationUid,
+										 TAny* aCreationParameters,
+										 TBool aCreationParamsFlag,
+										 TUid& aInstanceKey,
+										 CUnloadPolicy* aPolicy,
+										 TLibraryFunction& aLibFunctionProxy)
+	{
+	TAny* object = NULL; // Instantiation object
+	TInstantiationL proxy = reinterpret_cast<TInstantiationL>(aLibFunctionProxy);
+
+	TImplementationProxy* implementationProxyRow = NULL;
+	TAny* newLPointer = GetNewLPointerAndProxyTableRowL<TImplementationProxy,TInstantiationL>(aUniqueImplementationUid,implementationProxyRow,proxy);
+	// Now create an instance info object to store the information about this instance derived from
+	// the parameters just fetched. This must be created here since no leaves can occur after the object
+	// instantiation below.
+	CInstanceInfoSimple* instanceInfoSimple = CInstanceInfoSimple::NewL(aPolicy,implementationProxyRow);
+	CleanupStack::PushL(instanceInfoSimple);
+
+	// The pointer to instanceInfo will be used to identify this instance, and will
+	// be returned to the caller for future identification of this instance.
+	aInstanceKey.iUid = reinterpret_cast<TInt32>(instanceInfoSimple);
+
+	// Add item to instance info list. This list will contain all of the instance objects.
+	iInstanceInfoList.InsertInAddressOrderL(instanceInfoSimple);
+
+	// Get the implementation object using the instantiation pointer fetched earlier. Note
+	// that the object creation must be the last leaving operation to be performed. No leaves can occur
+	// after this operation, as the instantiation object cannnot be deleted on the cleanup stack if
+	// a leave occurs (cannot delete a TAny* pointer, the type is not known within ECOM).
+	object = ImplementationObjectL(aCreationParameters, 
+	 aCreationParamsFlag,newLPointer);
+
+	CleanupStack::Pop(instanceInfoSimple);
+
+	return object;
+	}
+
+/**
+Returns an implementation object to satisfy the specified interface.
+@param			aUniqueImplementationUid The implementation to find.
+@param			aCreationParameters A pointer to the creation parameter
+				structure passed to the creation method when called.
+@param			aCreationParamsFlag A boolean flag to indicate the existence or non-existence
+				of aCreationParameters. Will be ETrue even for if the value of
+				aCreationParameters is NULL.
+@param          aInstanceKey A key specifying a previously created implementation.
+@param          aPolicy policy of implementation
+@param          aLibFunctionProxy Library function proxy pointer.
+@return			TAny* a pointer to the fully constructed instantiation. The pointer is
+				guaranteed to be valid only until DestroyedThis is called.
+*/
+TAny* CLoadManager::ImplementationObject3L(const TUid& aUniqueImplementationUid,
+										 TAny* aCreationParameters,
+										 TBool aCreationParamsFlag,
+										 TUid& aInstanceKey,
+										 CUnloadPolicy* aPolicy,
+										 TLibraryFunction& aLibFunctionProxy)
+	{
+	TAny* object = NULL;  // Instantiation object
+	TInstantiation3L proxy = reinterpret_cast<TInstantiation3L>(aLibFunctionProxy);
+
+	TImplementationProxy3* implementationProxyRow = NULL;
+	TAny* newLPointer = GetNewLPointerAndProxyTableRowL<TImplementationProxy3,TInstantiation3L>(aUniqueImplementationUid,implementationProxyRow,proxy);
+
+	// Now create an instance info object to store the information about this instance derived from
+	// the parameters just fetched. This must be created here since no leaves can occur after the object
+	// instantiation below.
+	CInstanceInfoExtended* instanceInfoExtended = CInstanceInfoExtended::NewL(aPolicy,implementationProxyRow);
+	CleanupStack::PushL(instanceInfoExtended);
+
+	// The pointer to instanceInfo will be used to identify this instance, and will
+	// be returned to the caller for future identification of this instance.
+	aInstanceKey.iUid = reinterpret_cast<TInt32>(instanceInfoExtended);
+
+	// Add item to instance info list. This list will contain all of the instance objects.
+	iInstanceInfoList.InsertInAddressOrderL(instanceInfoExtended);
+
+	// Get the implementation object using the instantiation pointer fetched earlier. Note
+	// that the object creation must be the last leaving operation to be performed. No leaves can occur
+	// after this operation, as the instantiation object cannnot be deleted on the cleanup stack if
+	// a leave occurs (cannot delete a TAny* pointer, the type is not known within ECOM).
+	object = ImplementationObjectL(aCreationParameters, 
+	 aCreationParamsFlag,newLPointer);
+
+	// The extended instance info requires an object set. This is done here
+	// as the object is not known until now, but the instance info object was required to
+	// be created earlier to avoid a leave after the object creation.
+	instanceInfoExtended->SetObject(object);
+	CleanupStack::Pop(instanceInfoExtended);
+
+	return object;
+	}
+
+/**
+Gets the main implementation object using the instantiation pointer provided
+@param			aCreationParameters A pointer to the creation parameter
+				structure passed to the creation method when called.
+@param			aCreationParamsFlag A boolean flag to indicate the existence or non-existence
+				of aCreationParameters. Will be ETrue even for if the value of
+				aCreationParameters is NULL.
+@param			aNewLpointer Instantation pointer.
+				aCreationParameters is NULL.
+@return			TAny* a pointer to the fully constructed instantiation.
+*/
+TAny* CLoadManager::ImplementationObjectL(TAny* aCreationParameters,
+										 TBool aCreationParamsFlag,
+										 const TAny* aNewLpointer)
+	{
+	TAny* object=NULL;
+
+	// So cast to the correct type : This gives an ANSI C++ warning
+	// When using a REINTERPRET_CAST so simply cast instead
+	// Two different object creation one with creation parameters
+	if (aCreationParamsFlag)
+		{
+		typedef TAny* (*TNewL)(TAny*);
+		TNewL creationL = (TNewL)(aNewLpointer);
+		object=creationL(aCreationParameters);
+		}
+	else
+		{
+		typedef TAny* (*TNewL)();
+		TNewL creationL = (TNewL)(aNewLpointer);
+		object=creationL();
+		}
+
+	return object;
+	}
+
+/**
+Get the unload policy.
+@param			aUniqueImplementationUid The implementation to find.
+@param			aEntry Information on the dll containing the implementation
+@param			aPolicy Return parameter containing the policy
+@return			None
+*/
+void CLoadManager::GetUnloadPolicy(TUid aUniqueImplementationUid,
+							  const TEntry& aEntry,
+							  CUnloadPolicy*& aPolicy)
+	{
+	const TInt numImps = iInstanceInfoList.Count();
+	TBool foundImp = EFalse;
+	TInt matchingDllIndex=0;
+	TBool matchingDllFound=EFalse;
+	CUnloadPolicy* policy = NULL;
+
+	for (TInt index = 0; (index<numImps) && !foundImp; ++index)
+		{
+		//Check if there is existing mapping between the supplied implUid and a policy
+		if(iInstanceInfoList[index]->ImplementationUid() == aUniqueImplementationUid)
+			{
+			policy = iInstanceInfoList[index]->UnloadPolicy();
+
+			foundImp = ETrue;
+			}
+		else
+			{
+			//if cannot find a mapping entry but current index has the same DLL as the one requested from
+			//the client, store the index to this unloadPolicy for use later on if we have finished
+			//searching the entire mapping list
+			if (!matchingDllFound && (iInstanceInfoList[index]->UnloadPolicy()->DllEntryInformation().GetName()).CompareF(aEntry.iName)==0)
+				{
+				matchingDllIndex=index;
+				matchingDllFound=ETrue;
+				}
+			}
+		}
+
+	//If we cannot find any mapping in the policy index array(iUnloadPolicyMapping)
+	if(!foundImp)
+		{
+		//if not found but there is a matching DLL,we can simply create a new policy index mapping without
+		//having to load the library again.
+		if (matchingDllFound)
+			{
+			policy = iInstanceInfoList[matchingDllIndex]->UnloadPolicy();
+			}
+		}
+
+	aPolicy = policy;
+	}
+
+/**
+Clears the policy inside the iGarbagePolicies attribute.
+@pre			CLoadManager is fully constructed
+@post			CLoadManager iGarbagePolicies is zero'd
+*/
+void CLoadManager::ClearGarbage()
+	{
+	if (iGarbagePolicy != NULL)
+		{
+		delete iGarbagePolicy;
+		iGarbagePolicy=0;
+		}
+	}
+
+CLoadManager::CLoadManager() :
+	CBase()
+	{
+	// Do nothing here
+	}
+
+/**
+Returns the implementation ID for a given instance Key.
+@leave			KErrNotFound
+@param			aInstanceKey A key specifying a previously created implementation instance.
+@return			TUid The uid of the corresponding implementation.
+@pre 			CLoadManager is fully constructed,
+@post			CLoadManager remains the same.
+*/
+TUid CLoadManager::GetImplementationUidL(TUid aInstanceKey)
+	{
+	// Sanity check that the pointer is divisible by four. A binary number is divisible
+	// by four if and only if the two rightmost bits are both zero.
+	// This is a compromised check for checking that the pointer is an address.
+    if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0))
+        {
+	    __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey));
+	    User::Leave(KErrNotFound);
+        }
+
+	// The instance info pointer is stored in the instance key.
+	CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid);
+
+	// Check that the pointer exists before using it - leaves with KErrNotFound
+	iInstanceInfoList.FindInAddressOrderL(instanceInfo);
+	return instanceInfo->ImplementationUid();
+	}
+
+/**
+Fetches the requested extended interface from a specified implementation instance.
+@leave			KErrNotFound
+@param 			aInstanceKey A key specifying a previously created implementation.
+@param 			aExtendedInterfaceUid Identifies an interface to fetch from the plug-in instance.
+@return			TAny* A pointer to the extended interface, will be NULL if it does not exist.
+*/
+TAny* CLoadManager::GetExtendedInterfaceL(const TUid& aInstanceKey, const TUid& aExtendedInterfaceUid)
+	{
+	// Sanity check that the pointer is divisible by four. A binary number is divisible
+	// by four if and only if the two rightmost bits are both zero.
+	// This is a compromised check for checking that the pointer is an address.
+    if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0))
+        {
+	    __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey));
+	    User::Leave(KErrNotFound);
+        }
+
+	// The instance info pointer is stored in the instance key.
+	CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid);
+
+	// Check that the pointer exists before using it - leaves with KErrNotFound
+	iInstanceInfoList.FindInAddressOrderL(instanceInfo);
+	
+	// Create the extension object. The instance info object will be populated with
+	// the extension info during creation.
+	TAny* object = instanceInfo->CreateExtObjectL(aExtendedInterfaceUid);
+	return object;
+	}
+
+/**
+Manually releases the requested interface. Does nothing if it does not exist.
+This interface is optional, normally the interfaces are cleaned up automatically.
+@leave			KErrNotFound
+@param			aInstanceKey A key specifying a previously created implementation.
+@param			aExtendedInterfaceUid Identifies the interface to release
+@return None.
+*/
+void CLoadManager::ManuallyReleaseExtendedInterfaceL(const TUid& aInstanceKey, const TUid& aExtendedInterfaceUid)
+	{
+	// Sanity check that the pointer is divisible by four. A binary number is divisible
+	// by four if and only if the two rightmost bits are both zero.
+	// This is a compromised check for checking that the pointer is an address.
+    if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0))
+        {
+	    __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey));
+	    User::Leave(KErrNotFound);
+        }
+        
+	// The instance info pointer is stored in the instance key.
+	CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid);
+
+	// Check that the pointer exists before using it - leaves with KErrNotFound
+	iInstanceInfoList.FindInAddressOrderL(instanceInfo);
+	
+	instanceInfo->DestroyExtObject(aExtendedInterfaceUid);
+	}
+
+/**
+Utility method to move the policy to the garbage list, remove
+policy from the unload policy list.
+@param aPolicy Unload policy to clean up
+@return None.
+*/
+void CLoadManager::Cleanup(CUnloadPolicy* aPolicy)
+	{
+	if (aPolicy->DecreaseReference() == EDeleteMe)
+		{
+		// Move the policy to the garbage list
+		iGarbagePolicy=aPolicy;
+
+		TInt index = iAllUnloadPolicies.Find(aPolicy);
+		if (index != KErrNotFound)
+			{
+			iAllUnloadPolicies.Remove(index);
+			}
+		}
+	}
+
+//
+// CInstanceInfo
+/**
+Default constructor of CInstanceInfo
+@param			aUnloadPolicy The CUnloadPolicy of the dll
+*/
+CInstanceInfo::CInstanceInfo(CUnloadPolicy* aUnloadPolicy):
+	iUnloadPolicy(aUnloadPolicy)
+	{
+	// Do nothing here
+	}
+
+/** 
+Destructor of CInstanceInfo
+*/
+CInstanceInfo::~CInstanceInfo()
+	{
+	// Do nothing here
+	}
+
+
+//
+// CInstanceInfoExtended
+/**
+Default constructor of CInstanceInfoExtended
+@param			aUnloadPolicy The CUnloadPolicy of the dll
+@param			aImplementationProxyRow The interface implementation proxy row entry
+*/
+CInstanceInfoExtended::CInstanceInfoExtended(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy3* aImplementationProxyRow):
+	CInstanceInfo(aUnloadPolicy),iImplementationProxyRow(aImplementationProxyRow)
+	{
+	// Do nothing here
+	}
+
+/**
+create an instance of CInstanceInfoExtended
+@param			aUnloadPolicy The CUnloadPolicy of the dll
+@param			aImplementationProxyRow The interface implementation proxy row entry
+@return			A pointer to the newly created object.
+*/
+CInstanceInfoExtended* CInstanceInfoExtended::NewL(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy3* aImplementationProxyRow)
+	{
+	return new(ELeave) CInstanceInfoExtended(aUnloadPolicy,aImplementationProxyRow);
+	}
+
+/**
+Sets the implementation object.
+@param			aImplementationObject The object instance of this instances' implementation
+@return			None
+*/
+void CInstanceInfoExtended::SetObject(TAny* aImplementationObject)
+	{
+	iImplementationObject = aImplementationObject;
+	}
+
+/**
+Creates the extension interface object. This will use the get extended interface
+function pointer from the proxy table to fetch the extended interface from the
+plug-in implementation.
+@param			aExtendedInterfaceUID The extended interface UID
+@return			TAny* A pointer to an instance of an extended interface created
+*/
+TAny* CInstanceInfoExtended::CreateExtObjectL(const TUid& aExtendedInterfaceUID)
+	{
+	// Fetch the function pointer to create the extended interface
+	TProxyExtendedInterfaceGetPtrL createFunctionPtrL = iImplementationProxyRow->iFuncPtrInterfaceGetL;
+	if (createFunctionPtrL == NULL)
+		{
+		// No extension interface object can be created. Return NULL indicating that
+		// no extended interface object is available.
+		return NULL;
+		}
+
+	// Valid function pointer exists in proxy table.
+	TAny* object = NULL;         // Extended interface object (this points to the interface
+							     // within the object)
+	TAny* releaseObject = NULL;  // Eextended interface object (this points to the extended
+								 // object itself). Used to delete the extended interface
+								 // object later.
+	TUint32 flags = 0;           // Flags to allow the plug-in and ECOM to communicate
+	// Create the extension object.
+	object = createFunctionPtrL(iImplementationObject,aExtendedInterfaceUID,flags,releaseObject);
+
+	if (flags & KReleaseRequiredMask)
+		{
+		// If release of the extended interface is required then save the release object pointer.
+		// The interface object (returned by the function pointer call) and the release object
+		// are not necessarily the same pointer. This is because the  interface pointer is not
+		// guaranteed to be the same as the pointer to the extended interface object. That
+		// is why the release object is required to be fetched from the plug-in.
+
+        // First perform some checks to ensure that the plugin is consistent 
+        TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease;
+                
+        if (release == NULL)
+            {
+            // ...the release object pointer must not be non null
+            __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::CreateExtObjectL, release required but release function missing");
+	        __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_CreateExtObjectL_NoReleaseFunc));
+            User::Leave(KEComErrNoExtendedInterfaceReleaseFunction);
+            }
+            
+        if (releaseObject == NULL)
+            {
+            // ... the releaseObject must be non null
+            __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::CreateExtObjectL, release required but release object missing");
+	        __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_CreateExtObjectL_NoReleaseObj));
+           User::Leave(KEComErrNoExtendedInterfaceReleaseObject);
+ 		    }
+            
+		//Create the extended object info type and add it to the extended object info array.
+		TExtendedObjectInfo extendedObjectInfo;
+		extendedObjectInfo.iExtendedInterfaceObject = releaseObject;
+		extendedObjectInfo.iExtendedInterfaceUID = aExtendedInterfaceUID;
+
+		TInt err = iExtendedObjectInfo.Append(extendedObjectInfo);
+
+		if (err != KErrNone)
+			{
+			if (release != NULL)
+				{
+				// Release the extended interface. Release must not leave.
+				release(extendedObjectInfo.iExtendedInterfaceObject,extendedObjectInfo.iExtendedInterfaceUID);
+				}
+			User::Leave(err);
+			}
+		}
+
+	return object;
+	}
+
+
+/**
+Destroys the extension interface object.
+@param			aExtendedInterfaceUID The extended interface UID
+@return			None
+*/
+void CInstanceInfoExtended::DestroyExtObject(const TUid& aExtendedInterfaceUID)
+	{
+	// Get release interface
+	TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease;
+
+	if (release != NULL)
+		{
+		// Release extended interface. Find the extended object info.
+		for(TInt i = 0; i < iExtendedObjectInfo.Count(); i++)
+			{
+			if (iExtendedObjectInfo[i].iExtendedInterfaceUID == aExtendedInterfaceUID)
+				{
+				TAny* releaseObject = iExtendedObjectInfo[i].iExtendedInterfaceObject;
+                if (releaseObject == NULL)
+                    {
+                    // ... the releaseObject must be non null
+                    __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::DestroyExtObject, release required but release object missing");
+	                __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_DestroyExtObject_NoReleaseObj));	              
+		            }
+
+				// Release the extended interface. Release should not be leaving.
+				release(releaseObject, iExtendedObjectInfo[i].iExtendedInterfaceUID);
+				// Remove the extended object info element from the array.
+				iExtendedObjectInfo.Remove(i);
+				break;
+				}
+			}
+		}
+	}
+
+/**
+Destructor of CInstanceInfoExtended
+*/
+CInstanceInfoExtended::~CInstanceInfoExtended()
+	{
+	// Get release interface
+	if (iImplementationProxyRow != NULL)
+		{
+		TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease;
+
+		if (release != NULL)
+			{
+			// Release all extended interfaces (if any still to be released)
+			for(TInt i = 0; i < iExtendedObjectInfo.Count(); i++)
+				{
+				// Release is supposed to be non-leavable.
+				release(iExtendedObjectInfo[i].iExtendedInterfaceObject,iExtendedObjectInfo[i].iExtendedInterfaceUID);
+				}
+			}
+		}
+
+	iExtendedObjectInfo.Close();
+	}
+
+//
+// CInstanceInfoSimple
+/**
+Default constructor of CInstanceInfoSimple
+@param			aUnloadPolicy The CUnloadPolicy of the dll
+@param			aImplementationProxyRow The interface implementation proxy row entry
+*/
+CInstanceInfoSimple::CInstanceInfoSimple(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy* aImplementationProxyRow):
+	CInstanceInfo(aUnloadPolicy),iImplementationProxyRow(aImplementationProxyRow)
+	{
+	// Do nothing here
+	}
+
+/**
+Create an instance of CInstanceInfoSimple
+@param			aUnloadPolicy The CUnloadPolicy of the dll
+@param			aImplementationProxyRow The interface implementation proxy row entry
+@return			A pointer to the newly created object.
+*/
+CInstanceInfoSimple* CInstanceInfoSimple::NewL(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy* aImplementationProxyRow)
+	{
+	return new(ELeave) CInstanceInfoSimple(aUnloadPolicy,aImplementationProxyRow);
+	}