diff -r 000000000000 -r e4d67989cc36 lowlevellibsandfws/pluginfw/Framework/frame/LoadManager.cpp --- /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 +#include "e32math.h" +#include "EComInternalErrorCodes.h" +#include +/** +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(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(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(aLibFunctionProxy); + + TImplementationProxy* implementationProxyRow = NULL; + TAny* newLPointer = GetNewLPointerAndProxyTableRowL(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(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(aLibFunctionProxy); + + TImplementationProxy3* implementationProxyRow = NULL; + TAny* newLPointer = GetNewLPointerAndProxyTableRowL(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(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; (indexImplementationUid() == 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(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(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(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); + }