lowlevellibsandfws/pluginfw/Framework/frame/EComServer.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lowlevellibsandfws/pluginfw/Framework/frame/EComServer.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,692 @@
+// 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:
+// The Implementation of the CEComServer singleton class which
+// instantiates an instance of the requested ECom Interface Implementation.
+// 
+//
+
+/**
+ @internalComponent
+ @file
+*/
+#include <e32base.h>
+#include <bautils.h>
+#include <startupdomaindefs.h>
+#include "EComDebug.h"
+#include <ecom/ecom.h>
+#include <ecom/ecomerrorcodes.h>
+#include <ecom/ecomresolverparams.h>
+#include <ecom/implementationinformation.h>
+
+#include "ServerStartupManager.h"
+#include "RegistryData.h"
+#include "Registrar.h"
+#include "DefaultResolver.h"
+#include "RomOnlyResolver.h"
+#include "TlsData.h"
+#include "EComServerStart.h"
+#include "EComMessageIds.h"
+#include "EComServerSession.h"
+#include "EComServer.h"
+#include "EComUidCodes.h"
+#include "EComPerformance.h"
+#include "DriveInfo.h"
+#include "FileUtils.h"
+#include "RegistryResolveTransaction.h"
+#include "resolvercache.h"
+#include "EComPatchDataConstantv2.h"
+
+#define UNUSED_VAR(a) a = a
+
+/** enum for special system events */
+enum TSpecialEvents
+	{
+	EBURInProgress,
+	ESWIInProgress
+	};
+
+/** The location of server INI file. */
+_LIT(KEComSrvrIniFile,"_:\\private\\10009D8F\\EComSrvr.ini");
+/** Buffer descriptor to hold full path and name of server INI file. */
+typedef TBuf<32> TEComSrvrIniFileName;
+
+_LIT(KEComSrvrIniFileROM,"Z:\\private\\10009D8F\\EComSrvr.ini");
+
+static void CloseAndDeleteImplInfoArray(TAny* aObject)
+	{
+	RImplInfoArray* array=reinterpret_cast<RImplInfoArray*>(aObject);
+	if (array)
+		{
+		array->Close();
+		}
+	delete array;
+	}
+//
+// Initiate server exit when the timer expires
+// by stopping the local scheduler.
+void CShutdown::RunL()
+	{
+	CActiveScheduler::Stop();
+	}
+
+CEComServer* CEComServer::NewLC()
+	{
+	// Standard 2 phase construction code
+	CEComServer* instance = new(ELeave) CEComServer;
+	CleanupStack::PushL(instance);
+	instance->ConstructL();
+	return instance;
+	}
+
+
+CEComServer::~CEComServer()
+	{
+	// Uninstall callbacks first. Do not want to receive any callback
+	// in destructor. TCallBackWithArg constructed with no argument
+	// is a null callback.
+	TCallBackWithArg nullCallback;
+	if (iRegistrar)
+		{
+		iRegistrar->InstallSwiEventCallBack(nullCallback);
+		iRegistrar->InstallBurEventCallBack(nullCallback);
+		}
+	if (iRegistryData)
+		{
+		iRegistryData->SetImplUpgradeCallBack(nullCallback);
+		}
+
+	// Ensure this deletion order is maintained - in particular the registrydata 
+	// must last longer than the others which hold a reference to it.
+
+	//remove the CServerStartupMgr
+	delete iServerStartupMgr;
+	// Then destroy the registrar object
+	delete iRegistrar;
+	// remove the registry data
+	delete iRegistryData;
+	
+	delete iResolverCache;
+
+	// Finally close down the file server connection
+	iFs.Close();
+	// Make sure the non-default resolver library is closed
+	iResolverLibrary.Close();
+	}
+
+
+CEComServer::CEComServer()
+: CServer2(CActive::EPriorityStandard)
+	{
+	// Do nothing
+	}
+
+
+void CEComServer::ConstructL()
+	{
+	START_TIMER
+	START_HEAP
+	StartL(KEComServerName);
+	// Connect to the file server
+	User::LeaveIfError(iFs.Connect());
+	__ECOM_TRACE("ECOM: Server INIT - File Server session initialised");
+	// construct the registry data handling object here
+	iRegistryData = CRegistryData::NewL(iFs);
+	__ECOM_TRACE("ECOM: Server INIT - Registry Data initialised");
+	// Then the registrar
+	iRegistrar = CRegistrar::NewL(*iRegistryData, *this, iFs);
+	__ECOM_TRACE("ECOM: Server INIT - Registrar initialised");
+	
+	//Then the CServerStartupMgr
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KSM2OSServicesDomain3, iFs);
+#else
+	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KBaseServicesDomain3, iFs);
+#endif //SYMBIAN_SYSTEM_STATE_MANAGEMENT
+
+	__ECOM_TRACE("ECOM: Server INIT - ServerStartupMgr initialised");
+	iServerStartupMgr->RegisterObserverL(iRegistrar);
+	
+	iServerStartupMgr->InitialiseL(IsSSA(iFs));
+	
+	iResolverCache = CCustomResolverCache::NewL(KCustomResolverCacheSize,
+		KCustomResolverCacheTimeout);
+
+	TCallBackWithArg eventCallback(&CEComServer::NotifyEvents, this);
+	iRegistrar->InstallSwiEventCallBack(eventCallback);
+	iRegistrar->InstallBurEventCallBack(eventCallback);
+	iRegistryData->SetImplUpgradeCallBack(eventCallback);
+
+	// The server is about to start so construct the transient shutdown guy
+	iShutdown.ConstructL();
+	// ensure that the server still exits even
+	// if the server start fails or the
+	// 1st client fails to connect
+	iShutdown.Start();
+	RECORD_INITIALISE_HEAP
+	RECORD_INITIALISE_RESULT
+	}
+	
+TBool CEComServer::IsSSA(RFs& aFs)
+	{
+	// Check Z drive first.
+	TBool isFileExisting = BaflUtils::FileExists(aFs, KEComSrvrIniFileROM);
+	// Check system drive next
+	if(!isFileExisting)
+		{
+		TEComSrvrIniFileName iniFile(KEComSrvrIniFile);
+		TEComFileUtils::SetToDrive(iniFile,iRegistryData->iSystemDrive);
+		isFileExisting = BaflUtils::FileExists(aFs, iniFile);
+		}
+	return !isFileExisting;		
+	}
+
+// Get implementation info for one implementation, and return to client
+void CEComServer::GetImplementationInformationL(const TUid& aImplementationUid,
+												CImplementationInformation*& aImplInfo,
+												const TClientRequest& aClientRequest)
+	{
+	TEntry dllInfo;
+	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
+		aClientRequest, aImplementationUid, KNullUid, dllInfo, aImplInfo, ETrue));
+	}
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
+												   const TEComResolverParams& aAdditionalParameters, 
+												   TUid aResolverUid,
+												   const RExtendedInterfacesArray& aExtendedInterfaces,
+												   const TClientRequest& aMessage
+												   ) 
+	{
+	RImplInfoArray* result = NULL;
+	CResolver* resolver = NULL;
+	//create registry resolver transaction
+	//get the TListImplParam parameters
+	TBool capability= ETrue;
+	if(!(aMessage.IsNull()))
+		{
+		TListImplParam listParam;
+  		TPckg<TListImplParam> listParamPkg(listParam);
+  		aMessage.ReadL(2,listParamPkg);
+  		capability=listParam.iCapabilityCheck;
+		}
+  	
+  	
+	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
+																								aExtendedInterfaces,
+																								aMessage,capability);
+	CleanupStack::PushL(registryResolveTransaction);
+	//create resolver
+	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
+	result = ListImplementationsL(aInterfaceUid, aAdditionalParameters, resolver);
+	//clean up
+	CleanupStack::PopAndDestroy(resolver);
+	CleanupStack::PopAndDestroy(registryResolveTransaction);
+	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
+		{
+		iResolverLibrary.Close();
+		}
+	return result;
+	}
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
+												   TUid aResolverUid,
+												   const RExtendedInterfacesArray& aExtendedInterfaces,
+												   const TClientRequest& aMessage
+												   ) 
+	{
+	RImplInfoArray* result = NULL;
+	CResolver* resolver = NULL;
+	//create registry resolver transaction
+	//get the TListImplParam parameters
+  		//get the TListImplParam parameters
+	TBool capability= ETrue;
+	if(!(aMessage.IsNull()))
+		{
+		TListImplParam listParam;
+  		TPckg<TListImplParam> listParamPkg(listParam);
+  		aMessage.ReadL(2,listParamPkg);
+  		capability=listParam.iCapabilityCheck;
+		}
+	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
+																								aExtendedInterfaces,
+																								aMessage,capability);
+	CleanupStack::PushL(registryResolveTransaction);
+	//create resolver
+	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
+	result = ListImplementationsL(aInterfaceUid, resolver);
+	//clean up
+	CleanupStack::PopAndDestroy(resolver);
+	CleanupStack::PopAndDestroy(registryResolveTransaction);
+	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
+		{
+		iResolverLibrary.Close();
+		}
+	return result;
+	}
+
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
+												   const TEComResolverParams& aAdditionalParameters,
+												   const RExtendedInterfacesArray& aExtendedInterfaces,
+												   const TClientRequest& aMessage) 
+	{
+	// Use the default resolver in the overloaded method.
+	return ListImplementationsL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid,aExtendedInterfaces, aMessage);
+	}
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid,
+												  const RExtendedInterfacesArray& aExtendedInterfaces,	
+												  const TClientRequest& aMessage) 
+	{
+	// Use the default resolver in the overloaded method.
+	return ListImplementationsL(aInterfaceUid, KDefaultResolverUid,aExtendedInterfaces, aMessage);
+	}
+
+// The private helper
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
+												   const TEComResolverParams& aAdditionalParameters, 
+												   CResolver* aResolver) const
+	{
+	if(!aResolver)
+		User::Leave(KEComErrNoResolver);
+	// Use the client provided resolver to build up the list.
+	RImplInfoArray* infoArray = aResolver->ListAllL(aInterfaceUid, aAdditionalParameters);
+	return infoArray;
+	}
+
+RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
+												  CResolver* aResolver) const
+	{
+	if(!aResolver)
+		User::Leave(KEComErrNoResolver);
+	// Use the provided resolver to build up the list.
+	RImplInfoArray* infoArray = &aResolver->ListAllL(aInterfaceUid);
+	// infoArray points to iImplementationInfo, which is owned by CRegistryResolveTransaction. 
+	// CRegistryResolveTransaction object is transient and will be destroyed before return the implementation
+	// info list to the CEComServerSession. Therefore, we need to have a copy to return
+	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
+	CleanupStack::PushL(TCleanupItem(CloseAndDeleteImplInfoArray,retList));
+	const TInt numImps = infoArray->Count();
+	for(TInt index = 0; index < numImps; ++index)
+		{	
+		retList->AppendL((*infoArray)[index]);
+		}
+	// Reset the member variable because we are passing ownership back
+	CleanupStack::Pop();
+	return retList;
+	}
+
+void CEComServer::GetResolvedDllInfoL(	const TUid aImplementationUid,
+										TEntry& aDllInfo,
+										TUid& aDtor_Key,
+										const TClientRequest& aClientRequest)
+	{
+	// No resolution to do create directly.
+	aDtor_Key = aImplementationUid;
+	CImplementationInformation* implInfo = NULL;
+	TUid dummyUid={0x00000000};
+	//We need to do the security check for the case that implementationUid is known.
+	//if implementationUid is unknown, the security check will be done in ListImplementationsL.
+	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
+		aClientRequest, aImplementationUid, dummyUid, aDllInfo, implInfo, ETrue));
+	}
+
+
+void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
+										const TEComResolverParams& aAdditionalParameters,
+										const RExtendedInterfacesArray& aExtendedInterfaces,
+										TEntry& aDllInfo, 
+										TUid& aDtor_Key,
+										const TClientRequest& aClientRequest)
+	{
+	GetResolvedDllInfoL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid, aExtendedInterfaces, aDllInfo, aDtor_Key, aClientRequest);
+	}
+
+
+void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
+										const TEComResolverParams& aAdditionalParameters,
+										const TUid aResolverUid,
+										const RExtendedInterfacesArray& aExtendedInterfaces,
+										TEntry& aDllInfo,
+										TUid& aDtor_Key,
+										const TClientRequest& aClientRequest)
+	{
+	CResolver* resolver = NULL;
+	TBool capability= ETrue;
+	//create registry resolver transaction
+	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
+																								aExtendedInterfaces,
+																								aClientRequest,capability);
+	CleanupStack::PushL(registryResolveTransaction);
+	//create resolver
+	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
+	aDtor_Key = resolver->IdentifyImplementationL(aInterfaceUid, aAdditionalParameters);
+
+	//clean up
+	CleanupStack::PopAndDestroy(resolver);
+	CleanupStack::PopAndDestroy(registryResolveTransaction);
+	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
+		{
+		iResolverLibrary.Close();
+		}
+	CImplementationInformation* implInfo = NULL;
+	//Don't need to do the security check because it has been done in IdentifyImplementationL.
+	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
+		aClientRequest, aDtor_Key, aInterfaceUid, aDllInfo, implInfo, EFalse));
+	}
+
+// Server Session management
+CSession2* CEComServer::NewSessionL(const TVersion& aVersion,const RMessage2& /* aMessage*/) const
+	{
+	const TVersionName version = CONST_CAST(TVersion&,aVersion).Name();
+	const TVersionName thisVersion = TVersion(KEComServerMajorVN,KEComServerMinorVN,KEComServerBuildVN).Name();
+	if(thisVersion != version)
+		User::Leave(KErrNotSupported);
+	return new(ELeave) CEComServerSession();
+	}
+
+//
+// A new session is being created
+// Cancel the shutdown timer if it was running
+//
+void CEComServer::AddSession()
+	{
+	++iSessionCount;
+	iShutdown.Cancel();
+	}
+
+//
+// A session is being destroyed
+// Start the shutdown timer if it is the last session.
+//
+void CEComServer::DropSession()
+	{
+	if (--iSessionCount==0)
+		iShutdown.Start();
+	}
+
+void CEComServer::Notification(TInt aCompletionCode)
+//
+// Pass on the signal to all clients
+//
+	{
+	iSessionIter.SetToFirst();
+	CSession2* s;
+	while ((s = iSessionIter++)!=0)
+		STATIC_CAST(CEComServerSession*,s)->CompleteNotifications(aCompletionCode);
+	}
+
+TInt CEComServer::RunError(TInt aError)
+//
+// Handle an error from CMySession::ServiceL()
+// A bad descriptor error implies a badly programmed client, so panic it;
+// otherwise report the error to the client
+//
+	{
+	if (aError == KErrBadDescriptor)
+		{
+		PanicClient(Message(), aError);
+		}
+	else
+		{
+		Message().Complete(aError);
+		}
+	//
+	// The leave will result in an early return from CServer::RunL(), skipping
+	// the call to request another message. So do that now in order to keep the
+	// server running.
+	ReStart();
+	return KErrNone;	// handled the error fully
+	}
+
+/**
+Creates resolver object with aResolverUid UID.
+The method leaves resolver onto the cleanup stack.
+@param aResolverUid Resolver UID.
+@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
+@return A pointer to the created CResolver object.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CResolver* CEComServer::CreateResolverLC(const TUid& aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
+	{
+	CResolver* resolver = NULL;
+	if(aResolverUid == KDefaultResolverUid)
+		{
+		// Create default resolver
+		resolver = static_cast<CResolver*>(CDefaultResolver::NewL(*aRegistryResolveTransaction));
+		CleanupStack::PushL(resolver);
+		}
+	else if(aResolverUid == KRomOnlyResolverUid)
+		{
+		// Create Rom Only resolver
+		resolver = static_cast<CResolver*>(CRomOnlyResolver::NewL(*aRegistryResolveTransaction));
+		CleanupStack::PushL(resolver);
+		}
+	else
+		{
+		// Create Custom Resolver
+		resolver = CreateCustomResolverLC(aResolverUid, aRegistryResolveTransaction);
+		}
+	return resolver;
+	}
+
+/**
+Creates custom resolver object with aResolverUid UID.
+The method leaves custom resolver onto the cleanup stack.
+@param aResolverUid Custom resolver UID.
+@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
+@return A pointer to the created CResolver object.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CResolver* CEComServer::CreateCustomResolverLC(TUid aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
+	{
+	typedef CResolver* (*TNewL)(MPublicRegistry&);
+	TNewL newL = NULL;
+	CResolver* resolver=NULL;
+
+	TProxyNewLPtr tmpPtr;
+	if (iResolverCache->CacheLookup(aResolverUid, tmpPtr)) // cache hit
+		{
+		newL = reinterpret_cast<TNewL>(tmpPtr);
+		resolver = newL(*aRegistryResolveTransaction);
+		CleanupStack::PushL(resolver);
+		return resolver;
+		}
+
+	TEntry resolverDllInfo;
+	// We should only load custom resolvers that are in the ROM
+	//Initialize the server cap to ProtServ
+	TCapabilitySet servercap(ECapabilityProtServ);
+	CImplementationInformation* implInfo = NULL;
+	TBool onWritableDrv = EFalse;  
+	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForServer(
+		servercap, aResolverUid, KEComResolverInterfaceUid, resolverDllInfo,
+		implInfo, onWritableDrv));
+
+	// Type of the function pointer which is the proxy into the interface implementation collection
+	typedef TImplementationProxy* (*TInstantiationL)(TInt&);
+	// Function at ordinal 1 is InstantiationMethodL()
+	const TInt KImplementationGroupProxy = 1;
+	// So cast to the correct type : This gives an ANSI C++ warning
+	// When using a REINTERPRET_CAST so simply cast instead
+
+	const TDesC& libraryPath = resolverDllInfo.iName;
+	// Make sure the non-default resolver library is closed
+	iResolverLibrary.Close();
+	User::LeaveIfError(iResolverLibrary.Load(libraryPath, resolverDllInfo.iType));
+	__ECOM_TRACE2("ECOM: Resolver Loaded UID:0x%X - %S", aResolverUid.iUid, &resolverDllInfo.iName);
+	TInstantiationL proxy= REINTERPRET_CAST(TInstantiationL, iResolverLibrary.Lookup(KImplementationGroupProxy));
+
+	// Scan the returned table for a UID match, and return the associated
+	// creation method if found.
+	TInt count = 0;
+	TImplementationProxy* implementationTable = proxy(count);
+	for(TInt i = 0; i < count; ++i)
+		{
+		if(aResolverUid == implementationTable[i].iImplementationUid)
+			{
+			newL = (TNewL)(implementationTable[i].iNewLFuncPtr);
+			}
+		}
+
+	if(newL)
+		{
+		if (IsCachable(onWritableDrv))
+			{
+			TUint32 flags = (onWritableDrv) ? EEntryIsOnReadWriteDrive : EEntryFlagsNone;
+			User::LeaveIfError(iResolverCache->CacheResolver(aResolverUid,
+				iResolverLibrary, (TProxyNewLPtr)newL, flags));
+			// Handle is now owned by iResolverCache.
+			iResolverLibrary.SetHandle(KNullHandle);
+			}
+
+		// Create the non-default resolver
+		resolver = newL(*aRegistryResolveTransaction);
+		CleanupStack::PushL(resolver);
+		}
+	else
+		{
+		User::Leave(KEComErrNoResolver);
+		}
+	return resolver;
+	}
+
+
+TBool CEComServer::RegistryIndexValid() const
+	{
+	return iRegistryData->IndexValid();
+	}
+	
+/** Callback function. CRegistryData uses this to notify of implementation
+upgrade. CDiscoverer uses this to notify state changes in SWI/BUR.
+@param aObj Pointer to CEComServer object.
+@param aEvent Identify the event.
+@param aData Data associated with the callback.
+@return none, not-used, ignored.
+*/
+TInt CEComServer::NotifyEvents(TAny* aObj, TInt aEvent, TAny* aData)
+	{
+	CEComServer* self = static_cast<CEComServer*>(aObj);
+	switch (aEvent)
+		{
+		case ECallBackId_ImplUpgrade:
+			{
+			TUid* uid = static_cast<TUid*>(aData);
+			self->NotifyUpgrade(*uid);
+			}
+			break;
+		case ECallBackId_SwiEvent:
+			self->NotifySWIEvent(aData);
+			break;
+		case ECallBackId_BurEvent:
+			self->NotifyBUREvent(aData);
+			break;
+		default:
+			__ECOM_TRACE1("ECOM: CEComServer::NotifyEvents received unknown event %d", aEvent);
+		}
+
+	return 0;
+	}
+
+/** This method is called when an implementation is upgraded.
+@param aImplementationUid identify the implementation being upgraded.
+*/
+void CEComServer::NotifyUpgrade(const TUid aImplementationUid)
+	{
+	// Ignore return code which indicates if the UID is actually in cache.
+	(void)iResolverCache->Remove(aImplementationUid);
+	}
+
+/** Called when there is SWI status change.
+@param aData is TCallBackState* indicating start or end of SWI. 
+*/
+void CEComServer::NotifySWIEvent(TAny* aData)
+	{
+	TCallBackState* state = static_cast<TCallBackState*>(aData);
+	UpdateSpecialEvents(ESWIInProgress, *state);
+	}
+
+/** Called when there is BUR status change.
+@param aData is TCallBackState* indicating start or end of BUR. 
+*/
+void CEComServer::NotifyBUREvent(TAny* aData)
+	{
+	TCallBackState* state = static_cast<TCallBackState*>(aData);
+	UpdateSpecialEvents(EBURInProgress, *state);
+	}
+
+/** Updates the BUR/SWI status.
+@param aBit Indicate which bit to update.
+@param aState Indicate start or end of event.
+*/
+void CEComServer::UpdateSpecialEvents(TUint32 aBit, TCallBackState aState)
+	{
+	TBitFlags32 oldstate = iSpecialEvents;
+
+	if (aState == ECallBackState_EventStart)
+		{
+		iSpecialEvents.Set( aBit );
+		}
+	else
+		{
+		iSpecialEvents.Clear( aBit );
+		}
+
+	if (oldstate.Value() == 0 && iSpecialEvents.Value() != 0)
+		{
+		// BUR or SWI start. Need to evict cached resolvers on RW drives.
+		iResolverCache->RemoveItemsWithFlags(EEntryIsOnReadWriteDrive);
+		}
+	}
+
+/** Determine if a resolver entry is cachable.
+@param aResolverEntry the resolver to check.
+@return ETrue if the resolver should be added to cache. EFalse otherwise.
+*/
+TBool CEComServer::IsCachable(TBool aEntryIsOnRWDrive)
+	{
+	// Check the following conditions:
+	// 1. DLL is on RW drive with BUR or SWI in progress.
+	// 2. Cache size and cache timeout non-zero.
+	return	iResolverCache->CachingEnabled() &&
+			!(iSpecialEvents.Value() && aEntryIsOnRWDrive);
+	}
+
+#ifdef __ECOM_SERVER_TESTABILITY__
+void CEComServer::ChangeStartupStateL(TInt aState) const
+	{
+	iServerStartupMgr->ChangeStartupStateL(aState);
+	}
+
+void CEComServer::ProcessCurrentStartupStateL() const
+	{
+	iServerStartupMgr->ResetRequestTransitionNotificationL();
+	iServerStartupMgr->ResetLastStateAcknowledgedL();
+	iServerStartupMgr->RunL();
+	}
+	
+TInt CEComServer::GetCurrentStartupState() const
+	{
+	return iServerStartupMgr->CurrentStartupState();
+	}
+#endif //__ECOM_SERVER_TESTABILITY__
+
+#ifdef __ECOM_SERVER_PERFORMANCE__
+void CEComServer::GetRegistryCountsL(TInt aType, RegistryCounts::TRegistryCounts& aCounts) const
+	{
+	iRegistryData->GetRegistryCountsL(aType, aCounts);
+	}	
+#endif //__ECOM_SERVER_PERFORMANCE__