os/ossrv/lowlevellibsandfws/pluginfw/Framework/frame/EComServer.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/lowlevellibsandfws/pluginfw/Framework/frame/EComServer.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,692 @@
     1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// The Implementation of the CEComServer singleton class which
    1.18 +// instantiates an instance of the requested ECom Interface Implementation.
    1.19 +// 
    1.20 +//
    1.21 +
    1.22 +/**
    1.23 + @internalComponent
    1.24 + @file
    1.25 +*/
    1.26 +#include <e32base.h>
    1.27 +#include <bautils.h>
    1.28 +#include <startupdomaindefs.h>
    1.29 +#include "EComDebug.h"
    1.30 +#include <ecom/ecom.h>
    1.31 +#include <ecom/ecomerrorcodes.h>
    1.32 +#include <ecom/ecomresolverparams.h>
    1.33 +#include <ecom/implementationinformation.h>
    1.34 +
    1.35 +#include "ServerStartupManager.h"
    1.36 +#include "RegistryData.h"
    1.37 +#include "Registrar.h"
    1.38 +#include "DefaultResolver.h"
    1.39 +#include "RomOnlyResolver.h"
    1.40 +#include "TlsData.h"
    1.41 +#include "EComServerStart.h"
    1.42 +#include "EComMessageIds.h"
    1.43 +#include "EComServerSession.h"
    1.44 +#include "EComServer.h"
    1.45 +#include "EComUidCodes.h"
    1.46 +#include "EComPerformance.h"
    1.47 +#include "DriveInfo.h"
    1.48 +#include "FileUtils.h"
    1.49 +#include "RegistryResolveTransaction.h"
    1.50 +#include "resolvercache.h"
    1.51 +#include "EComPatchDataConstantv2.h"
    1.52 +
    1.53 +#define UNUSED_VAR(a) a = a
    1.54 +
    1.55 +/** enum for special system events */
    1.56 +enum TSpecialEvents
    1.57 +	{
    1.58 +	EBURInProgress,
    1.59 +	ESWIInProgress
    1.60 +	};
    1.61 +
    1.62 +/** The location of server INI file. */
    1.63 +_LIT(KEComSrvrIniFile,"_:\\private\\10009D8F\\EComSrvr.ini");
    1.64 +/** Buffer descriptor to hold full path and name of server INI file. */
    1.65 +typedef TBuf<32> TEComSrvrIniFileName;
    1.66 +
    1.67 +_LIT(KEComSrvrIniFileROM,"Z:\\private\\10009D8F\\EComSrvr.ini");
    1.68 +
    1.69 +static void CloseAndDeleteImplInfoArray(TAny* aObject)
    1.70 +	{
    1.71 +	RImplInfoArray* array=reinterpret_cast<RImplInfoArray*>(aObject);
    1.72 +	if (array)
    1.73 +		{
    1.74 +		array->Close();
    1.75 +		}
    1.76 +	delete array;
    1.77 +	}
    1.78 +//
    1.79 +// Initiate server exit when the timer expires
    1.80 +// by stopping the local scheduler.
    1.81 +void CShutdown::RunL()
    1.82 +	{
    1.83 +	CActiveScheduler::Stop();
    1.84 +	}
    1.85 +
    1.86 +CEComServer* CEComServer::NewLC()
    1.87 +	{
    1.88 +	// Standard 2 phase construction code
    1.89 +	CEComServer* instance = new(ELeave) CEComServer;
    1.90 +	CleanupStack::PushL(instance);
    1.91 +	instance->ConstructL();
    1.92 +	return instance;
    1.93 +	}
    1.94 +
    1.95 +
    1.96 +CEComServer::~CEComServer()
    1.97 +	{
    1.98 +	// Uninstall callbacks first. Do not want to receive any callback
    1.99 +	// in destructor. TCallBackWithArg constructed with no argument
   1.100 +	// is a null callback.
   1.101 +	TCallBackWithArg nullCallback;
   1.102 +	if (iRegistrar)
   1.103 +		{
   1.104 +		iRegistrar->InstallSwiEventCallBack(nullCallback);
   1.105 +		iRegistrar->InstallBurEventCallBack(nullCallback);
   1.106 +		}
   1.107 +	if (iRegistryData)
   1.108 +		{
   1.109 +		iRegistryData->SetImplUpgradeCallBack(nullCallback);
   1.110 +		}
   1.111 +
   1.112 +	// Ensure this deletion order is maintained - in particular the registrydata 
   1.113 +	// must last longer than the others which hold a reference to it.
   1.114 +
   1.115 +	//remove the CServerStartupMgr
   1.116 +	delete iServerStartupMgr;
   1.117 +	// Then destroy the registrar object
   1.118 +	delete iRegistrar;
   1.119 +	// remove the registry data
   1.120 +	delete iRegistryData;
   1.121 +	
   1.122 +	delete iResolverCache;
   1.123 +
   1.124 +	// Finally close down the file server connection
   1.125 +	iFs.Close();
   1.126 +	// Make sure the non-default resolver library is closed
   1.127 +	iResolverLibrary.Close();
   1.128 +	}
   1.129 +
   1.130 +
   1.131 +CEComServer::CEComServer()
   1.132 +: CServer2(CActive::EPriorityStandard)
   1.133 +	{
   1.134 +	// Do nothing
   1.135 +	}
   1.136 +
   1.137 +
   1.138 +void CEComServer::ConstructL()
   1.139 +	{
   1.140 +	START_TIMER
   1.141 +	START_HEAP
   1.142 +	StartL(KEComServerName);
   1.143 +	// Connect to the file server
   1.144 +	User::LeaveIfError(iFs.Connect());
   1.145 +	__ECOM_TRACE("ECOM: Server INIT - File Server session initialised");
   1.146 +	// construct the registry data handling object here
   1.147 +	iRegistryData = CRegistryData::NewL(iFs);
   1.148 +	__ECOM_TRACE("ECOM: Server INIT - Registry Data initialised");
   1.149 +	// Then the registrar
   1.150 +	iRegistrar = CRegistrar::NewL(*iRegistryData, *this, iFs);
   1.151 +	__ECOM_TRACE("ECOM: Server INIT - Registrar initialised");
   1.152 +	
   1.153 +	//Then the CServerStartupMgr
   1.154 +
   1.155 +#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
   1.156 +	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KSM2OSServicesDomain3, iFs);
   1.157 +#else
   1.158 +	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KBaseServicesDomain3, iFs);
   1.159 +#endif //SYMBIAN_SYSTEM_STATE_MANAGEMENT
   1.160 +
   1.161 +	__ECOM_TRACE("ECOM: Server INIT - ServerStartupMgr initialised");
   1.162 +	iServerStartupMgr->RegisterObserverL(iRegistrar);
   1.163 +	
   1.164 +	iServerStartupMgr->InitialiseL(IsSSA(iFs));
   1.165 +	
   1.166 +	iResolverCache = CCustomResolverCache::NewL(KCustomResolverCacheSize,
   1.167 +		KCustomResolverCacheTimeout);
   1.168 +
   1.169 +	TCallBackWithArg eventCallback(&CEComServer::NotifyEvents, this);
   1.170 +	iRegistrar->InstallSwiEventCallBack(eventCallback);
   1.171 +	iRegistrar->InstallBurEventCallBack(eventCallback);
   1.172 +	iRegistryData->SetImplUpgradeCallBack(eventCallback);
   1.173 +
   1.174 +	// The server is about to start so construct the transient shutdown guy
   1.175 +	iShutdown.ConstructL();
   1.176 +	// ensure that the server still exits even
   1.177 +	// if the server start fails or the
   1.178 +	// 1st client fails to connect
   1.179 +	iShutdown.Start();
   1.180 +	RECORD_INITIALISE_HEAP
   1.181 +	RECORD_INITIALISE_RESULT
   1.182 +	}
   1.183 +	
   1.184 +TBool CEComServer::IsSSA(RFs& aFs)
   1.185 +	{
   1.186 +	// Check Z drive first.
   1.187 +	TBool isFileExisting = BaflUtils::FileExists(aFs, KEComSrvrIniFileROM);
   1.188 +	// Check system drive next
   1.189 +	if(!isFileExisting)
   1.190 +		{
   1.191 +		TEComSrvrIniFileName iniFile(KEComSrvrIniFile);
   1.192 +		TEComFileUtils::SetToDrive(iniFile,iRegistryData->iSystemDrive);
   1.193 +		isFileExisting = BaflUtils::FileExists(aFs, iniFile);
   1.194 +		}
   1.195 +	return !isFileExisting;		
   1.196 +	}
   1.197 +
   1.198 +// Get implementation info for one implementation, and return to client
   1.199 +void CEComServer::GetImplementationInformationL(const TUid& aImplementationUid,
   1.200 +												CImplementationInformation*& aImplInfo,
   1.201 +												const TClientRequest& aClientRequest)
   1.202 +	{
   1.203 +	TEntry dllInfo;
   1.204 +	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
   1.205 +		aClientRequest, aImplementationUid, KNullUid, dllInfo, aImplInfo, ETrue));
   1.206 +	}
   1.207 +
   1.208 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
   1.209 +												   const TEComResolverParams& aAdditionalParameters, 
   1.210 +												   TUid aResolverUid,
   1.211 +												   const RExtendedInterfacesArray& aExtendedInterfaces,
   1.212 +												   const TClientRequest& aMessage
   1.213 +												   ) 
   1.214 +	{
   1.215 +	RImplInfoArray* result = NULL;
   1.216 +	CResolver* resolver = NULL;
   1.217 +	//create registry resolver transaction
   1.218 +	//get the TListImplParam parameters
   1.219 +	TBool capability= ETrue;
   1.220 +	if(!(aMessage.IsNull()))
   1.221 +		{
   1.222 +		TListImplParam listParam;
   1.223 +  		TPckg<TListImplParam> listParamPkg(listParam);
   1.224 +  		aMessage.ReadL(2,listParamPkg);
   1.225 +  		capability=listParam.iCapabilityCheck;
   1.226 +		}
   1.227 +  	
   1.228 +  	
   1.229 +	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
   1.230 +																								aExtendedInterfaces,
   1.231 +																								aMessage,capability);
   1.232 +	CleanupStack::PushL(registryResolveTransaction);
   1.233 +	//create resolver
   1.234 +	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
   1.235 +	result = ListImplementationsL(aInterfaceUid, aAdditionalParameters, resolver);
   1.236 +	//clean up
   1.237 +	CleanupStack::PopAndDestroy(resolver);
   1.238 +	CleanupStack::PopAndDestroy(registryResolveTransaction);
   1.239 +	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
   1.240 +		{
   1.241 +		iResolverLibrary.Close();
   1.242 +		}
   1.243 +	return result;
   1.244 +	}
   1.245 +
   1.246 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
   1.247 +												   TUid aResolverUid,
   1.248 +												   const RExtendedInterfacesArray& aExtendedInterfaces,
   1.249 +												   const TClientRequest& aMessage
   1.250 +												   ) 
   1.251 +	{
   1.252 +	RImplInfoArray* result = NULL;
   1.253 +	CResolver* resolver = NULL;
   1.254 +	//create registry resolver transaction
   1.255 +	//get the TListImplParam parameters
   1.256 +  		//get the TListImplParam parameters
   1.257 +	TBool capability= ETrue;
   1.258 +	if(!(aMessage.IsNull()))
   1.259 +		{
   1.260 +		TListImplParam listParam;
   1.261 +  		TPckg<TListImplParam> listParamPkg(listParam);
   1.262 +  		aMessage.ReadL(2,listParamPkg);
   1.263 +  		capability=listParam.iCapabilityCheck;
   1.264 +		}
   1.265 +	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
   1.266 +																								aExtendedInterfaces,
   1.267 +																								aMessage,capability);
   1.268 +	CleanupStack::PushL(registryResolveTransaction);
   1.269 +	//create resolver
   1.270 +	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
   1.271 +	result = ListImplementationsL(aInterfaceUid, resolver);
   1.272 +	//clean up
   1.273 +	CleanupStack::PopAndDestroy(resolver);
   1.274 +	CleanupStack::PopAndDestroy(registryResolveTransaction);
   1.275 +	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
   1.276 +		{
   1.277 +		iResolverLibrary.Close();
   1.278 +		}
   1.279 +	return result;
   1.280 +	}
   1.281 +
   1.282 +
   1.283 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
   1.284 +												   const TEComResolverParams& aAdditionalParameters,
   1.285 +												   const RExtendedInterfacesArray& aExtendedInterfaces,
   1.286 +												   const TClientRequest& aMessage) 
   1.287 +	{
   1.288 +	// Use the default resolver in the overloaded method.
   1.289 +	return ListImplementationsL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid,aExtendedInterfaces, aMessage);
   1.290 +	}
   1.291 +
   1.292 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid,
   1.293 +												  const RExtendedInterfacesArray& aExtendedInterfaces,	
   1.294 +												  const TClientRequest& aMessage) 
   1.295 +	{
   1.296 +	// Use the default resolver in the overloaded method.
   1.297 +	return ListImplementationsL(aInterfaceUid, KDefaultResolverUid,aExtendedInterfaces, aMessage);
   1.298 +	}
   1.299 +
   1.300 +// The private helper
   1.301 +
   1.302 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
   1.303 +												   const TEComResolverParams& aAdditionalParameters, 
   1.304 +												   CResolver* aResolver) const
   1.305 +	{
   1.306 +	if(!aResolver)
   1.307 +		User::Leave(KEComErrNoResolver);
   1.308 +	// Use the client provided resolver to build up the list.
   1.309 +	RImplInfoArray* infoArray = aResolver->ListAllL(aInterfaceUid, aAdditionalParameters);
   1.310 +	return infoArray;
   1.311 +	}
   1.312 +
   1.313 +RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
   1.314 +												  CResolver* aResolver) const
   1.315 +	{
   1.316 +	if(!aResolver)
   1.317 +		User::Leave(KEComErrNoResolver);
   1.318 +	// Use the provided resolver to build up the list.
   1.319 +	RImplInfoArray* infoArray = &aResolver->ListAllL(aInterfaceUid);
   1.320 +	// infoArray points to iImplementationInfo, which is owned by CRegistryResolveTransaction. 
   1.321 +	// CRegistryResolveTransaction object is transient and will be destroyed before return the implementation
   1.322 +	// info list to the CEComServerSession. Therefore, we need to have a copy to return
   1.323 +	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
   1.324 +	CleanupStack::PushL(TCleanupItem(CloseAndDeleteImplInfoArray,retList));
   1.325 +	const TInt numImps = infoArray->Count();
   1.326 +	for(TInt index = 0; index < numImps; ++index)
   1.327 +		{	
   1.328 +		retList->AppendL((*infoArray)[index]);
   1.329 +		}
   1.330 +	// Reset the member variable because we are passing ownership back
   1.331 +	CleanupStack::Pop();
   1.332 +	return retList;
   1.333 +	}
   1.334 +
   1.335 +void CEComServer::GetResolvedDllInfoL(	const TUid aImplementationUid,
   1.336 +										TEntry& aDllInfo,
   1.337 +										TUid& aDtor_Key,
   1.338 +										const TClientRequest& aClientRequest)
   1.339 +	{
   1.340 +	// No resolution to do create directly.
   1.341 +	aDtor_Key = aImplementationUid;
   1.342 +	CImplementationInformation* implInfo = NULL;
   1.343 +	TUid dummyUid={0x00000000};
   1.344 +	//We need to do the security check for the case that implementationUid is known.
   1.345 +	//if implementationUid is unknown, the security check will be done in ListImplementationsL.
   1.346 +	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
   1.347 +		aClientRequest, aImplementationUid, dummyUid, aDllInfo, implInfo, ETrue));
   1.348 +	}
   1.349 +
   1.350 +
   1.351 +void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
   1.352 +										const TEComResolverParams& aAdditionalParameters,
   1.353 +										const RExtendedInterfacesArray& aExtendedInterfaces,
   1.354 +										TEntry& aDllInfo, 
   1.355 +										TUid& aDtor_Key,
   1.356 +										const TClientRequest& aClientRequest)
   1.357 +	{
   1.358 +	GetResolvedDllInfoL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid, aExtendedInterfaces, aDllInfo, aDtor_Key, aClientRequest);
   1.359 +	}
   1.360 +
   1.361 +
   1.362 +void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
   1.363 +										const TEComResolverParams& aAdditionalParameters,
   1.364 +										const TUid aResolverUid,
   1.365 +										const RExtendedInterfacesArray& aExtendedInterfaces,
   1.366 +										TEntry& aDllInfo,
   1.367 +										TUid& aDtor_Key,
   1.368 +										const TClientRequest& aClientRequest)
   1.369 +	{
   1.370 +	CResolver* resolver = NULL;
   1.371 +	TBool capability= ETrue;
   1.372 +	//create registry resolver transaction
   1.373 +	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
   1.374 +																								aExtendedInterfaces,
   1.375 +																								aClientRequest,capability);
   1.376 +	CleanupStack::PushL(registryResolveTransaction);
   1.377 +	//create resolver
   1.378 +	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
   1.379 +	aDtor_Key = resolver->IdentifyImplementationL(aInterfaceUid, aAdditionalParameters);
   1.380 +
   1.381 +	//clean up
   1.382 +	CleanupStack::PopAndDestroy(resolver);
   1.383 +	CleanupStack::PopAndDestroy(registryResolveTransaction);
   1.384 +	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
   1.385 +		{
   1.386 +		iResolverLibrary.Close();
   1.387 +		}
   1.388 +	CImplementationInformation* implInfo = NULL;
   1.389 +	//Don't need to do the security check because it has been done in IdentifyImplementationL.
   1.390 +	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
   1.391 +		aClientRequest, aDtor_Key, aInterfaceUid, aDllInfo, implInfo, EFalse));
   1.392 +	}
   1.393 +
   1.394 +// Server Session management
   1.395 +CSession2* CEComServer::NewSessionL(const TVersion& aVersion,const RMessage2& /* aMessage*/) const
   1.396 +	{
   1.397 +	const TVersionName version = CONST_CAST(TVersion&,aVersion).Name();
   1.398 +	const TVersionName thisVersion = TVersion(KEComServerMajorVN,KEComServerMinorVN,KEComServerBuildVN).Name();
   1.399 +	if(thisVersion != version)
   1.400 +		User::Leave(KErrNotSupported);
   1.401 +	return new(ELeave) CEComServerSession();
   1.402 +	}
   1.403 +
   1.404 +//
   1.405 +// A new session is being created
   1.406 +// Cancel the shutdown timer if it was running
   1.407 +//
   1.408 +void CEComServer::AddSession()
   1.409 +	{
   1.410 +	++iSessionCount;
   1.411 +	iShutdown.Cancel();
   1.412 +	}
   1.413 +
   1.414 +//
   1.415 +// A session is being destroyed
   1.416 +// Start the shutdown timer if it is the last session.
   1.417 +//
   1.418 +void CEComServer::DropSession()
   1.419 +	{
   1.420 +	if (--iSessionCount==0)
   1.421 +		iShutdown.Start();
   1.422 +	}
   1.423 +
   1.424 +void CEComServer::Notification(TInt aCompletionCode)
   1.425 +//
   1.426 +// Pass on the signal to all clients
   1.427 +//
   1.428 +	{
   1.429 +	iSessionIter.SetToFirst();
   1.430 +	CSession2* s;
   1.431 +	while ((s = iSessionIter++)!=0)
   1.432 +		STATIC_CAST(CEComServerSession*,s)->CompleteNotifications(aCompletionCode);
   1.433 +	}
   1.434 +
   1.435 +TInt CEComServer::RunError(TInt aError)
   1.436 +//
   1.437 +// Handle an error from CMySession::ServiceL()
   1.438 +// A bad descriptor error implies a badly programmed client, so panic it;
   1.439 +// otherwise report the error to the client
   1.440 +//
   1.441 +	{
   1.442 +	if (aError == KErrBadDescriptor)
   1.443 +		{
   1.444 +		PanicClient(Message(), aError);
   1.445 +		}
   1.446 +	else
   1.447 +		{
   1.448 +		Message().Complete(aError);
   1.449 +		}
   1.450 +	//
   1.451 +	// The leave will result in an early return from CServer::RunL(), skipping
   1.452 +	// the call to request another message. So do that now in order to keep the
   1.453 +	// server running.
   1.454 +	ReStart();
   1.455 +	return KErrNone;	// handled the error fully
   1.456 +	}
   1.457 +
   1.458 +/**
   1.459 +Creates resolver object with aResolverUid UID.
   1.460 +The method leaves resolver onto the cleanup stack.
   1.461 +@param aResolverUid Resolver UID.
   1.462 +@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
   1.463 +@return A pointer to the created CResolver object.
   1.464 +@leave System-wide error codes, including KErrNoMemory.
   1.465 +*/
   1.466 +CResolver* CEComServer::CreateResolverLC(const TUid& aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
   1.467 +	{
   1.468 +	CResolver* resolver = NULL;
   1.469 +	if(aResolverUid == KDefaultResolverUid)
   1.470 +		{
   1.471 +		// Create default resolver
   1.472 +		resolver = static_cast<CResolver*>(CDefaultResolver::NewL(*aRegistryResolveTransaction));
   1.473 +		CleanupStack::PushL(resolver);
   1.474 +		}
   1.475 +	else if(aResolverUid == KRomOnlyResolverUid)
   1.476 +		{
   1.477 +		// Create Rom Only resolver
   1.478 +		resolver = static_cast<CResolver*>(CRomOnlyResolver::NewL(*aRegistryResolveTransaction));
   1.479 +		CleanupStack::PushL(resolver);
   1.480 +		}
   1.481 +	else
   1.482 +		{
   1.483 +		// Create Custom Resolver
   1.484 +		resolver = CreateCustomResolverLC(aResolverUid, aRegistryResolveTransaction);
   1.485 +		}
   1.486 +	return resolver;
   1.487 +	}
   1.488 +
   1.489 +/**
   1.490 +Creates custom resolver object with aResolverUid UID.
   1.491 +The method leaves custom resolver onto the cleanup stack.
   1.492 +@param aResolverUid Custom resolver UID.
   1.493 +@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
   1.494 +@return A pointer to the created CResolver object.
   1.495 +@leave System-wide error codes, including KErrNoMemory.
   1.496 +*/
   1.497 +CResolver* CEComServer::CreateCustomResolverLC(TUid aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
   1.498 +	{
   1.499 +	typedef CResolver* (*TNewL)(MPublicRegistry&);
   1.500 +	TNewL newL = NULL;
   1.501 +	CResolver* resolver=NULL;
   1.502 +
   1.503 +	TProxyNewLPtr tmpPtr;
   1.504 +	if (iResolverCache->CacheLookup(aResolverUid, tmpPtr)) // cache hit
   1.505 +		{
   1.506 +		newL = reinterpret_cast<TNewL>(tmpPtr);
   1.507 +		resolver = newL(*aRegistryResolveTransaction);
   1.508 +		CleanupStack::PushL(resolver);
   1.509 +		return resolver;
   1.510 +		}
   1.511 +
   1.512 +	TEntry resolverDllInfo;
   1.513 +	// We should only load custom resolvers that are in the ROM
   1.514 +	//Initialize the server cap to ProtServ
   1.515 +	TCapabilitySet servercap(ECapabilityProtServ);
   1.516 +	CImplementationInformation* implInfo = NULL;
   1.517 +	TBool onWritableDrv = EFalse;  
   1.518 +	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForServer(
   1.519 +		servercap, aResolverUid, KEComResolverInterfaceUid, resolverDllInfo,
   1.520 +		implInfo, onWritableDrv));
   1.521 +
   1.522 +	// Type of the function pointer which is the proxy into the interface implementation collection
   1.523 +	typedef TImplementationProxy* (*TInstantiationL)(TInt&);
   1.524 +	// Function at ordinal 1 is InstantiationMethodL()
   1.525 +	const TInt KImplementationGroupProxy = 1;
   1.526 +	// So cast to the correct type : This gives an ANSI C++ warning
   1.527 +	// When using a REINTERPRET_CAST so simply cast instead
   1.528 +
   1.529 +	const TDesC& libraryPath = resolverDllInfo.iName;
   1.530 +	// Make sure the non-default resolver library is closed
   1.531 +	iResolverLibrary.Close();
   1.532 +	User::LeaveIfError(iResolverLibrary.Load(libraryPath, resolverDllInfo.iType));
   1.533 +	__ECOM_TRACE2("ECOM: Resolver Loaded UID:0x%X - %S", aResolverUid.iUid, &resolverDllInfo.iName);
   1.534 +	TInstantiationL proxy= REINTERPRET_CAST(TInstantiationL, iResolverLibrary.Lookup(KImplementationGroupProxy));
   1.535 +
   1.536 +	// Scan the returned table for a UID match, and return the associated
   1.537 +	// creation method if found.
   1.538 +	TInt count = 0;
   1.539 +	TImplementationProxy* implementationTable = proxy(count);
   1.540 +	for(TInt i = 0; i < count; ++i)
   1.541 +		{
   1.542 +		if(aResolverUid == implementationTable[i].iImplementationUid)
   1.543 +			{
   1.544 +			newL = (TNewL)(implementationTable[i].iNewLFuncPtr);
   1.545 +			}
   1.546 +		}
   1.547 +
   1.548 +	if(newL)
   1.549 +		{
   1.550 +		if (IsCachable(onWritableDrv))
   1.551 +			{
   1.552 +			TUint32 flags = (onWritableDrv) ? EEntryIsOnReadWriteDrive : EEntryFlagsNone;
   1.553 +			User::LeaveIfError(iResolverCache->CacheResolver(aResolverUid,
   1.554 +				iResolverLibrary, (TProxyNewLPtr)newL, flags));
   1.555 +			// Handle is now owned by iResolverCache.
   1.556 +			iResolverLibrary.SetHandle(KNullHandle);
   1.557 +			}
   1.558 +
   1.559 +		// Create the non-default resolver
   1.560 +		resolver = newL(*aRegistryResolveTransaction);
   1.561 +		CleanupStack::PushL(resolver);
   1.562 +		}
   1.563 +	else
   1.564 +		{
   1.565 +		User::Leave(KEComErrNoResolver);
   1.566 +		}
   1.567 +	return resolver;
   1.568 +	}
   1.569 +
   1.570 +
   1.571 +TBool CEComServer::RegistryIndexValid() const
   1.572 +	{
   1.573 +	return iRegistryData->IndexValid();
   1.574 +	}
   1.575 +	
   1.576 +/** Callback function. CRegistryData uses this to notify of implementation
   1.577 +upgrade. CDiscoverer uses this to notify state changes in SWI/BUR.
   1.578 +@param aObj Pointer to CEComServer object.
   1.579 +@param aEvent Identify the event.
   1.580 +@param aData Data associated with the callback.
   1.581 +@return none, not-used, ignored.
   1.582 +*/
   1.583 +TInt CEComServer::NotifyEvents(TAny* aObj, TInt aEvent, TAny* aData)
   1.584 +	{
   1.585 +	CEComServer* self = static_cast<CEComServer*>(aObj);
   1.586 +	switch (aEvent)
   1.587 +		{
   1.588 +		case ECallBackId_ImplUpgrade:
   1.589 +			{
   1.590 +			TUid* uid = static_cast<TUid*>(aData);
   1.591 +			self->NotifyUpgrade(*uid);
   1.592 +			}
   1.593 +			break;
   1.594 +		case ECallBackId_SwiEvent:
   1.595 +			self->NotifySWIEvent(aData);
   1.596 +			break;
   1.597 +		case ECallBackId_BurEvent:
   1.598 +			self->NotifyBUREvent(aData);
   1.599 +			break;
   1.600 +		default:
   1.601 +			__ECOM_TRACE1("ECOM: CEComServer::NotifyEvents received unknown event %d", aEvent);
   1.602 +		}
   1.603 +
   1.604 +	return 0;
   1.605 +	}
   1.606 +
   1.607 +/** This method is called when an implementation is upgraded.
   1.608 +@param aImplementationUid identify the implementation being upgraded.
   1.609 +*/
   1.610 +void CEComServer::NotifyUpgrade(const TUid aImplementationUid)
   1.611 +	{
   1.612 +	// Ignore return code which indicates if the UID is actually in cache.
   1.613 +	(void)iResolverCache->Remove(aImplementationUid);
   1.614 +	}
   1.615 +
   1.616 +/** Called when there is SWI status change.
   1.617 +@param aData is TCallBackState* indicating start or end of SWI. 
   1.618 +*/
   1.619 +void CEComServer::NotifySWIEvent(TAny* aData)
   1.620 +	{
   1.621 +	TCallBackState* state = static_cast<TCallBackState*>(aData);
   1.622 +	UpdateSpecialEvents(ESWIInProgress, *state);
   1.623 +	}
   1.624 +
   1.625 +/** Called when there is BUR status change.
   1.626 +@param aData is TCallBackState* indicating start or end of BUR. 
   1.627 +*/
   1.628 +void CEComServer::NotifyBUREvent(TAny* aData)
   1.629 +	{
   1.630 +	TCallBackState* state = static_cast<TCallBackState*>(aData);
   1.631 +	UpdateSpecialEvents(EBURInProgress, *state);
   1.632 +	}
   1.633 +
   1.634 +/** Updates the BUR/SWI status.
   1.635 +@param aBit Indicate which bit to update.
   1.636 +@param aState Indicate start or end of event.
   1.637 +*/
   1.638 +void CEComServer::UpdateSpecialEvents(TUint32 aBit, TCallBackState aState)
   1.639 +	{
   1.640 +	TBitFlags32 oldstate = iSpecialEvents;
   1.641 +
   1.642 +	if (aState == ECallBackState_EventStart)
   1.643 +		{
   1.644 +		iSpecialEvents.Set( aBit );
   1.645 +		}
   1.646 +	else
   1.647 +		{
   1.648 +		iSpecialEvents.Clear( aBit );
   1.649 +		}
   1.650 +
   1.651 +	if (oldstate.Value() == 0 && iSpecialEvents.Value() != 0)
   1.652 +		{
   1.653 +		// BUR or SWI start. Need to evict cached resolvers on RW drives.
   1.654 +		iResolverCache->RemoveItemsWithFlags(EEntryIsOnReadWriteDrive);
   1.655 +		}
   1.656 +	}
   1.657 +
   1.658 +/** Determine if a resolver entry is cachable.
   1.659 +@param aResolverEntry the resolver to check.
   1.660 +@return ETrue if the resolver should be added to cache. EFalse otherwise.
   1.661 +*/
   1.662 +TBool CEComServer::IsCachable(TBool aEntryIsOnRWDrive)
   1.663 +	{
   1.664 +	// Check the following conditions:
   1.665 +	// 1. DLL is on RW drive with BUR or SWI in progress.
   1.666 +	// 2. Cache size and cache timeout non-zero.
   1.667 +	return	iResolverCache->CachingEnabled() &&
   1.668 +			!(iSpecialEvents.Value() && aEntryIsOnRWDrive);
   1.669 +	}
   1.670 +
   1.671 +#ifdef __ECOM_SERVER_TESTABILITY__
   1.672 +void CEComServer::ChangeStartupStateL(TInt aState) const
   1.673 +	{
   1.674 +	iServerStartupMgr->ChangeStartupStateL(aState);
   1.675 +	}
   1.676 +
   1.677 +void CEComServer::ProcessCurrentStartupStateL() const
   1.678 +	{
   1.679 +	iServerStartupMgr->ResetRequestTransitionNotificationL();
   1.680 +	iServerStartupMgr->ResetLastStateAcknowledgedL();
   1.681 +	iServerStartupMgr->RunL();
   1.682 +	}
   1.683 +	
   1.684 +TInt CEComServer::GetCurrentStartupState() const
   1.685 +	{
   1.686 +	return iServerStartupMgr->CurrentStartupState();
   1.687 +	}
   1.688 +#endif //__ECOM_SERVER_TESTABILITY__
   1.689 +
   1.690 +#ifdef __ECOM_SERVER_PERFORMANCE__
   1.691 +void CEComServer::GetRegistryCountsL(TInt aType, RegistryCounts::TRegistryCounts& aCounts) const
   1.692 +	{
   1.693 +	iRegistryData->GetRegistryCountsL(aType, aCounts);
   1.694 +	}	
   1.695 +#endif //__ECOM_SERVER_PERFORMANCE__