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