lowlevellibsandfws/pluginfw/Framework/frame/EComServer.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // The Implementation of the CEComServer singleton class which
       
    15 // instantiates an instance of the requested ECom Interface Implementation.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @internalComponent
       
    21  @file
       
    22 */
       
    23 #include <e32base.h>
       
    24 #include <bautils.h>
       
    25 #include <startupdomaindefs.h>
       
    26 #include "EComDebug.h"
       
    27 #include <ecom/ecom.h>
       
    28 #include <ecom/ecomerrorcodes.h>
       
    29 #include <ecom/ecomresolverparams.h>
       
    30 #include <ecom/implementationinformation.h>
       
    31 
       
    32 #include "ServerStartupManager.h"
       
    33 #include "RegistryData.h"
       
    34 #include "Registrar.h"
       
    35 #include "DefaultResolver.h"
       
    36 #include "RomOnlyResolver.h"
       
    37 #include "TlsData.h"
       
    38 #include "EComServerStart.h"
       
    39 #include "EComMessageIds.h"
       
    40 #include "EComServerSession.h"
       
    41 #include "EComServer.h"
       
    42 #include "EComUidCodes.h"
       
    43 #include "EComPerformance.h"
       
    44 #include "DriveInfo.h"
       
    45 #include "FileUtils.h"
       
    46 #include "RegistryResolveTransaction.h"
       
    47 #include "resolvercache.h"
       
    48 #include "EComPatchDataConstantv2.h"
       
    49 
       
    50 #define UNUSED_VAR(a) a = a
       
    51 
       
    52 /** enum for special system events */
       
    53 enum TSpecialEvents
       
    54 	{
       
    55 	EBURInProgress,
       
    56 	ESWIInProgress
       
    57 	};
       
    58 
       
    59 /** The location of server INI file. */
       
    60 _LIT(KEComSrvrIniFile,"_:\\private\\10009D8F\\EComSrvr.ini");
       
    61 /** Buffer descriptor to hold full path and name of server INI file. */
       
    62 typedef TBuf<32> TEComSrvrIniFileName;
       
    63 
       
    64 _LIT(KEComSrvrIniFileROM,"Z:\\private\\10009D8F\\EComSrvr.ini");
       
    65 
       
    66 static void CloseAndDeleteImplInfoArray(TAny* aObject)
       
    67 	{
       
    68 	RImplInfoArray* array=reinterpret_cast<RImplInfoArray*>(aObject);
       
    69 	if (array)
       
    70 		{
       
    71 		array->Close();
       
    72 		}
       
    73 	delete array;
       
    74 	}
       
    75 //
       
    76 // Initiate server exit when the timer expires
       
    77 // by stopping the local scheduler.
       
    78 void CShutdown::RunL()
       
    79 	{
       
    80 	CActiveScheduler::Stop();
       
    81 	}
       
    82 
       
    83 CEComServer* CEComServer::NewLC()
       
    84 	{
       
    85 	// Standard 2 phase construction code
       
    86 	CEComServer* instance = new(ELeave) CEComServer;
       
    87 	CleanupStack::PushL(instance);
       
    88 	instance->ConstructL();
       
    89 	return instance;
       
    90 	}
       
    91 
       
    92 
       
    93 CEComServer::~CEComServer()
       
    94 	{
       
    95 	// Uninstall callbacks first. Do not want to receive any callback
       
    96 	// in destructor. TCallBackWithArg constructed with no argument
       
    97 	// is a null callback.
       
    98 	TCallBackWithArg nullCallback;
       
    99 	if (iRegistrar)
       
   100 		{
       
   101 		iRegistrar->InstallSwiEventCallBack(nullCallback);
       
   102 		iRegistrar->InstallBurEventCallBack(nullCallback);
       
   103 		}
       
   104 	if (iRegistryData)
       
   105 		{
       
   106 		iRegistryData->SetImplUpgradeCallBack(nullCallback);
       
   107 		}
       
   108 
       
   109 	// Ensure this deletion order is maintained - in particular the registrydata 
       
   110 	// must last longer than the others which hold a reference to it.
       
   111 
       
   112 	//remove the CServerStartupMgr
       
   113 	delete iServerStartupMgr;
       
   114 	// Then destroy the registrar object
       
   115 	delete iRegistrar;
       
   116 	// remove the registry data
       
   117 	delete iRegistryData;
       
   118 	
       
   119 	delete iResolverCache;
       
   120 
       
   121 	// Finally close down the file server connection
       
   122 	iFs.Close();
       
   123 	// Make sure the non-default resolver library is closed
       
   124 	iResolverLibrary.Close();
       
   125 	}
       
   126 
       
   127 
       
   128 CEComServer::CEComServer()
       
   129 : CServer2(CActive::EPriorityStandard)
       
   130 	{
       
   131 	// Do nothing
       
   132 	}
       
   133 
       
   134 
       
   135 void CEComServer::ConstructL()
       
   136 	{
       
   137 	START_TIMER
       
   138 	START_HEAP
       
   139 	StartL(KEComServerName);
       
   140 	// Connect to the file server
       
   141 	User::LeaveIfError(iFs.Connect());
       
   142 	__ECOM_TRACE("ECOM: Server INIT - File Server session initialised");
       
   143 	// construct the registry data handling object here
       
   144 	iRegistryData = CRegistryData::NewL(iFs);
       
   145 	__ECOM_TRACE("ECOM: Server INIT - Registry Data initialised");
       
   146 	// Then the registrar
       
   147 	iRegistrar = CRegistrar::NewL(*iRegistryData, *this, iFs);
       
   148 	__ECOM_TRACE("ECOM: Server INIT - Registrar initialised");
       
   149 	
       
   150 	//Then the CServerStartupMgr
       
   151 
       
   152 #ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
       
   153 	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KSM2OSServicesDomain3, iFs);
       
   154 #else
       
   155 	iServerStartupMgr = new(ELeave) CServerStartupMgr(KDmHierarchyIdStartup, KBaseServicesDomain3, iFs);
       
   156 #endif //SYMBIAN_SYSTEM_STATE_MANAGEMENT
       
   157 
       
   158 	__ECOM_TRACE("ECOM: Server INIT - ServerStartupMgr initialised");
       
   159 	iServerStartupMgr->RegisterObserverL(iRegistrar);
       
   160 	
       
   161 	iServerStartupMgr->InitialiseL(IsSSA(iFs));
       
   162 	
       
   163 	iResolverCache = CCustomResolverCache::NewL(KCustomResolverCacheSize,
       
   164 		KCustomResolverCacheTimeout);
       
   165 
       
   166 	TCallBackWithArg eventCallback(&CEComServer::NotifyEvents, this);
       
   167 	iRegistrar->InstallSwiEventCallBack(eventCallback);
       
   168 	iRegistrar->InstallBurEventCallBack(eventCallback);
       
   169 	iRegistryData->SetImplUpgradeCallBack(eventCallback);
       
   170 
       
   171 	// The server is about to start so construct the transient shutdown guy
       
   172 	iShutdown.ConstructL();
       
   173 	// ensure that the server still exits even
       
   174 	// if the server start fails or the
       
   175 	// 1st client fails to connect
       
   176 	iShutdown.Start();
       
   177 	RECORD_INITIALISE_HEAP
       
   178 	RECORD_INITIALISE_RESULT
       
   179 	}
       
   180 	
       
   181 TBool CEComServer::IsSSA(RFs& aFs)
       
   182 	{
       
   183 	// Check Z drive first.
       
   184 	TBool isFileExisting = BaflUtils::FileExists(aFs, KEComSrvrIniFileROM);
       
   185 	// Check system drive next
       
   186 	if(!isFileExisting)
       
   187 		{
       
   188 		TEComSrvrIniFileName iniFile(KEComSrvrIniFile);
       
   189 		TEComFileUtils::SetToDrive(iniFile,iRegistryData->iSystemDrive);
       
   190 		isFileExisting = BaflUtils::FileExists(aFs, iniFile);
       
   191 		}
       
   192 	return !isFileExisting;		
       
   193 	}
       
   194 
       
   195 // Get implementation info for one implementation, and return to client
       
   196 void CEComServer::GetImplementationInformationL(const TUid& aImplementationUid,
       
   197 												CImplementationInformation*& aImplInfo,
       
   198 												const TClientRequest& aClientRequest)
       
   199 	{
       
   200 	TEntry dllInfo;
       
   201 	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
       
   202 		aClientRequest, aImplementationUid, KNullUid, dllInfo, aImplInfo, ETrue));
       
   203 	}
       
   204 
       
   205 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
       
   206 												   const TEComResolverParams& aAdditionalParameters, 
       
   207 												   TUid aResolverUid,
       
   208 												   const RExtendedInterfacesArray& aExtendedInterfaces,
       
   209 												   const TClientRequest& aMessage
       
   210 												   ) 
       
   211 	{
       
   212 	RImplInfoArray* result = NULL;
       
   213 	CResolver* resolver = NULL;
       
   214 	//create registry resolver transaction
       
   215 	//get the TListImplParam parameters
       
   216 	TBool capability= ETrue;
       
   217 	if(!(aMessage.IsNull()))
       
   218 		{
       
   219 		TListImplParam listParam;
       
   220   		TPckg<TListImplParam> listParamPkg(listParam);
       
   221   		aMessage.ReadL(2,listParamPkg);
       
   222   		capability=listParam.iCapabilityCheck;
       
   223 		}
       
   224   	
       
   225   	
       
   226 	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
       
   227 																								aExtendedInterfaces,
       
   228 																								aMessage,capability);
       
   229 	CleanupStack::PushL(registryResolveTransaction);
       
   230 	//create resolver
       
   231 	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
       
   232 	result = ListImplementationsL(aInterfaceUid, aAdditionalParameters, resolver);
       
   233 	//clean up
       
   234 	CleanupStack::PopAndDestroy(resolver);
       
   235 	CleanupStack::PopAndDestroy(registryResolveTransaction);
       
   236 	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
       
   237 		{
       
   238 		iResolverLibrary.Close();
       
   239 		}
       
   240 	return result;
       
   241 	}
       
   242 
       
   243 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
       
   244 												   TUid aResolverUid,
       
   245 												   const RExtendedInterfacesArray& aExtendedInterfaces,
       
   246 												   const TClientRequest& aMessage
       
   247 												   ) 
       
   248 	{
       
   249 	RImplInfoArray* result = NULL;
       
   250 	CResolver* resolver = NULL;
       
   251 	//create registry resolver transaction
       
   252 	//get the TListImplParam parameters
       
   253   		//get the TListImplParam parameters
       
   254 	TBool capability= ETrue;
       
   255 	if(!(aMessage.IsNull()))
       
   256 		{
       
   257 		TListImplParam listParam;
       
   258   		TPckg<TListImplParam> listParamPkg(listParam);
       
   259   		aMessage.ReadL(2,listParamPkg);
       
   260   		capability=listParam.iCapabilityCheck;
       
   261 		}
       
   262 	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
       
   263 																								aExtendedInterfaces,
       
   264 																								aMessage,capability);
       
   265 	CleanupStack::PushL(registryResolveTransaction);
       
   266 	//create resolver
       
   267 	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
       
   268 	result = ListImplementationsL(aInterfaceUid, resolver);
       
   269 	//clean up
       
   270 	CleanupStack::PopAndDestroy(resolver);
       
   271 	CleanupStack::PopAndDestroy(registryResolveTransaction);
       
   272 	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
       
   273 		{
       
   274 		iResolverLibrary.Close();
       
   275 		}
       
   276 	return result;
       
   277 	}
       
   278 
       
   279 
       
   280 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
       
   281 												   const TEComResolverParams& aAdditionalParameters,
       
   282 												   const RExtendedInterfacesArray& aExtendedInterfaces,
       
   283 												   const TClientRequest& aMessage) 
       
   284 	{
       
   285 	// Use the default resolver in the overloaded method.
       
   286 	return ListImplementationsL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid,aExtendedInterfaces, aMessage);
       
   287 	}
       
   288 
       
   289 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid,
       
   290 												  const RExtendedInterfacesArray& aExtendedInterfaces,	
       
   291 												  const TClientRequest& aMessage) 
       
   292 	{
       
   293 	// Use the default resolver in the overloaded method.
       
   294 	return ListImplementationsL(aInterfaceUid, KDefaultResolverUid,aExtendedInterfaces, aMessage);
       
   295 	}
       
   296 
       
   297 // The private helper
       
   298 
       
   299 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
       
   300 												   const TEComResolverParams& aAdditionalParameters, 
       
   301 												   CResolver* aResolver) const
       
   302 	{
       
   303 	if(!aResolver)
       
   304 		User::Leave(KEComErrNoResolver);
       
   305 	// Use the client provided resolver to build up the list.
       
   306 	RImplInfoArray* infoArray = aResolver->ListAllL(aInterfaceUid, aAdditionalParameters);
       
   307 	return infoArray;
       
   308 	}
       
   309 
       
   310 RImplInfoArray* CEComServer::ListImplementationsL(TUid aInterfaceUid, 
       
   311 												  CResolver* aResolver) const
       
   312 	{
       
   313 	if(!aResolver)
       
   314 		User::Leave(KEComErrNoResolver);
       
   315 	// Use the provided resolver to build up the list.
       
   316 	RImplInfoArray* infoArray = &aResolver->ListAllL(aInterfaceUid);
       
   317 	// infoArray points to iImplementationInfo, which is owned by CRegistryResolveTransaction. 
       
   318 	// CRegistryResolveTransaction object is transient and will be destroyed before return the implementation
       
   319 	// info list to the CEComServerSession. Therefore, we need to have a copy to return
       
   320 	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
       
   321 	CleanupStack::PushL(TCleanupItem(CloseAndDeleteImplInfoArray,retList));
       
   322 	const TInt numImps = infoArray->Count();
       
   323 	for(TInt index = 0; index < numImps; ++index)
       
   324 		{	
       
   325 		retList->AppendL((*infoArray)[index]);
       
   326 		}
       
   327 	// Reset the member variable because we are passing ownership back
       
   328 	CleanupStack::Pop();
       
   329 	return retList;
       
   330 	}
       
   331 
       
   332 void CEComServer::GetResolvedDllInfoL(	const TUid aImplementationUid,
       
   333 										TEntry& aDllInfo,
       
   334 										TUid& aDtor_Key,
       
   335 										const TClientRequest& aClientRequest)
       
   336 	{
       
   337 	// No resolution to do create directly.
       
   338 	aDtor_Key = aImplementationUid;
       
   339 	CImplementationInformation* implInfo = NULL;
       
   340 	TUid dummyUid={0x00000000};
       
   341 	//We need to do the security check for the case that implementationUid is known.
       
   342 	//if implementationUid is unknown, the security check will be done in ListImplementationsL.
       
   343 	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
       
   344 		aClientRequest, aImplementationUid, dummyUid, aDllInfo, implInfo, ETrue));
       
   345 	}
       
   346 
       
   347 
       
   348 void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
       
   349 										const TEComResolverParams& aAdditionalParameters,
       
   350 										const RExtendedInterfacesArray& aExtendedInterfaces,
       
   351 										TEntry& aDllInfo, 
       
   352 										TUid& aDtor_Key,
       
   353 										const TClientRequest& aClientRequest)
       
   354 	{
       
   355 	GetResolvedDllInfoL(aInterfaceUid, aAdditionalParameters, KDefaultResolverUid, aExtendedInterfaces, aDllInfo, aDtor_Key, aClientRequest);
       
   356 	}
       
   357 
       
   358 
       
   359 void CEComServer::GetResolvedDllInfoL(  const TUid aInterfaceUid,
       
   360 										const TEComResolverParams& aAdditionalParameters,
       
   361 										const TUid aResolverUid,
       
   362 										const RExtendedInterfacesArray& aExtendedInterfaces,
       
   363 										TEntry& aDllInfo,
       
   364 										TUid& aDtor_Key,
       
   365 										const TClientRequest& aClientRequest)
       
   366 	{
       
   367 	CResolver* resolver = NULL;
       
   368 	TBool capability= ETrue;
       
   369 	//create registry resolver transaction
       
   370 	CRegistryResolveTransaction* registryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,
       
   371 																								aExtendedInterfaces,
       
   372 																								aClientRequest,capability);
       
   373 	CleanupStack::PushL(registryResolveTransaction);
       
   374 	//create resolver
       
   375 	resolver = CreateResolverLC(aResolverUid,registryResolveTransaction);
       
   376 	aDtor_Key = resolver->IdentifyImplementationL(aInterfaceUid, aAdditionalParameters);
       
   377 
       
   378 	//clean up
       
   379 	CleanupStack::PopAndDestroy(resolver);
       
   380 	CleanupStack::PopAndDestroy(registryResolveTransaction);
       
   381 	if ((aResolverUid != KDefaultResolverUid) && (aResolverUid != KRomOnlyResolverUid))
       
   382 		{
       
   383 		iResolverLibrary.Close();
       
   384 		}
       
   385 	CImplementationInformation* implInfo = NULL;
       
   386 	//Don't need to do the security check because it has been done in IdentifyImplementationL.
       
   387 	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForClientL(
       
   388 		aClientRequest, aDtor_Key, aInterfaceUid, aDllInfo, implInfo, EFalse));
       
   389 	}
       
   390 
       
   391 // Server Session management
       
   392 CSession2* CEComServer::NewSessionL(const TVersion& aVersion,const RMessage2& /* aMessage*/) const
       
   393 	{
       
   394 	const TVersionName version = CONST_CAST(TVersion&,aVersion).Name();
       
   395 	const TVersionName thisVersion = TVersion(KEComServerMajorVN,KEComServerMinorVN,KEComServerBuildVN).Name();
       
   396 	if(thisVersion != version)
       
   397 		User::Leave(KErrNotSupported);
       
   398 	return new(ELeave) CEComServerSession();
       
   399 	}
       
   400 
       
   401 //
       
   402 // A new session is being created
       
   403 // Cancel the shutdown timer if it was running
       
   404 //
       
   405 void CEComServer::AddSession()
       
   406 	{
       
   407 	++iSessionCount;
       
   408 	iShutdown.Cancel();
       
   409 	}
       
   410 
       
   411 //
       
   412 // A session is being destroyed
       
   413 // Start the shutdown timer if it is the last session.
       
   414 //
       
   415 void CEComServer::DropSession()
       
   416 	{
       
   417 	if (--iSessionCount==0)
       
   418 		iShutdown.Start();
       
   419 	}
       
   420 
       
   421 void CEComServer::Notification(TInt aCompletionCode)
       
   422 //
       
   423 // Pass on the signal to all clients
       
   424 //
       
   425 	{
       
   426 	iSessionIter.SetToFirst();
       
   427 	CSession2* s;
       
   428 	while ((s = iSessionIter++)!=0)
       
   429 		STATIC_CAST(CEComServerSession*,s)->CompleteNotifications(aCompletionCode);
       
   430 	}
       
   431 
       
   432 TInt CEComServer::RunError(TInt aError)
       
   433 //
       
   434 // Handle an error from CMySession::ServiceL()
       
   435 // A bad descriptor error implies a badly programmed client, so panic it;
       
   436 // otherwise report the error to the client
       
   437 //
       
   438 	{
       
   439 	if (aError == KErrBadDescriptor)
       
   440 		{
       
   441 		PanicClient(Message(), aError);
       
   442 		}
       
   443 	else
       
   444 		{
       
   445 		Message().Complete(aError);
       
   446 		}
       
   447 	//
       
   448 	// The leave will result in an early return from CServer::RunL(), skipping
       
   449 	// the call to request another message. So do that now in order to keep the
       
   450 	// server running.
       
   451 	ReStart();
       
   452 	return KErrNone;	// handled the error fully
       
   453 	}
       
   454 
       
   455 /**
       
   456 Creates resolver object with aResolverUid UID.
       
   457 The method leaves resolver onto the cleanup stack.
       
   458 @param aResolverUid Resolver UID.
       
   459 @param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
       
   460 @return A pointer to the created CResolver object.
       
   461 @leave System-wide error codes, including KErrNoMemory.
       
   462 */
       
   463 CResolver* CEComServer::CreateResolverLC(const TUid& aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
       
   464 	{
       
   465 	CResolver* resolver = NULL;
       
   466 	if(aResolverUid == KDefaultResolverUid)
       
   467 		{
       
   468 		// Create default resolver
       
   469 		resolver = static_cast<CResolver*>(CDefaultResolver::NewL(*aRegistryResolveTransaction));
       
   470 		CleanupStack::PushL(resolver);
       
   471 		}
       
   472 	else if(aResolverUid == KRomOnlyResolverUid)
       
   473 		{
       
   474 		// Create Rom Only resolver
       
   475 		resolver = static_cast<CResolver*>(CRomOnlyResolver::NewL(*aRegistryResolveTransaction));
       
   476 		CleanupStack::PushL(resolver);
       
   477 		}
       
   478 	else
       
   479 		{
       
   480 		// Create Custom Resolver
       
   481 		resolver = CreateCustomResolverLC(aResolverUid, aRegistryResolveTransaction);
       
   482 		}
       
   483 	return resolver;
       
   484 	}
       
   485 
       
   486 /**
       
   487 Creates custom resolver object with aResolverUid UID.
       
   488 The method leaves custom resolver onto the cleanup stack.
       
   489 @param aResolverUid Custom resolver UID.
       
   490 @param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
       
   491 @return A pointer to the created CResolver object.
       
   492 @leave System-wide error codes, including KErrNoMemory.
       
   493 */
       
   494 CResolver* CEComServer::CreateCustomResolverLC(TUid aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction)
       
   495 	{
       
   496 	typedef CResolver* (*TNewL)(MPublicRegistry&);
       
   497 	TNewL newL = NULL;
       
   498 	CResolver* resolver=NULL;
       
   499 
       
   500 	TProxyNewLPtr tmpPtr;
       
   501 	if (iResolverCache->CacheLookup(aResolverUid, tmpPtr)) // cache hit
       
   502 		{
       
   503 		newL = reinterpret_cast<TNewL>(tmpPtr);
       
   504 		resolver = newL(*aRegistryResolveTransaction);
       
   505 		CleanupStack::PushL(resolver);
       
   506 		return resolver;
       
   507 		}
       
   508 
       
   509 	TEntry resolverDllInfo;
       
   510 	// We should only load custom resolvers that are in the ROM
       
   511 	//Initialize the server cap to ProtServ
       
   512 	TCapabilitySet servercap(ECapabilityProtServ);
       
   513 	CImplementationInformation* implInfo = NULL;
       
   514 	TBool onWritableDrv = EFalse;  
       
   515 	User::LeaveIfError(iRegistryData->GetImplementationDllInfoForServer(
       
   516 		servercap, aResolverUid, KEComResolverInterfaceUid, resolverDllInfo,
       
   517 		implInfo, onWritableDrv));
       
   518 
       
   519 	// Type of the function pointer which is the proxy into the interface implementation collection
       
   520 	typedef TImplementationProxy* (*TInstantiationL)(TInt&);
       
   521 	// Function at ordinal 1 is InstantiationMethodL()
       
   522 	const TInt KImplementationGroupProxy = 1;
       
   523 	// So cast to the correct type : This gives an ANSI C++ warning
       
   524 	// When using a REINTERPRET_CAST so simply cast instead
       
   525 
       
   526 	const TDesC& libraryPath = resolverDllInfo.iName;
       
   527 	// Make sure the non-default resolver library is closed
       
   528 	iResolverLibrary.Close();
       
   529 	User::LeaveIfError(iResolverLibrary.Load(libraryPath, resolverDllInfo.iType));
       
   530 	__ECOM_TRACE2("ECOM: Resolver Loaded UID:0x%X - %S", aResolverUid.iUid, &resolverDllInfo.iName);
       
   531 	TInstantiationL proxy= REINTERPRET_CAST(TInstantiationL, iResolverLibrary.Lookup(KImplementationGroupProxy));
       
   532 
       
   533 	// Scan the returned table for a UID match, and return the associated
       
   534 	// creation method if found.
       
   535 	TInt count = 0;
       
   536 	TImplementationProxy* implementationTable = proxy(count);
       
   537 	for(TInt i = 0; i < count; ++i)
       
   538 		{
       
   539 		if(aResolverUid == implementationTable[i].iImplementationUid)
       
   540 			{
       
   541 			newL = (TNewL)(implementationTable[i].iNewLFuncPtr);
       
   542 			}
       
   543 		}
       
   544 
       
   545 	if(newL)
       
   546 		{
       
   547 		if (IsCachable(onWritableDrv))
       
   548 			{
       
   549 			TUint32 flags = (onWritableDrv) ? EEntryIsOnReadWriteDrive : EEntryFlagsNone;
       
   550 			User::LeaveIfError(iResolverCache->CacheResolver(aResolverUid,
       
   551 				iResolverLibrary, (TProxyNewLPtr)newL, flags));
       
   552 			// Handle is now owned by iResolverCache.
       
   553 			iResolverLibrary.SetHandle(KNullHandle);
       
   554 			}
       
   555 
       
   556 		// Create the non-default resolver
       
   557 		resolver = newL(*aRegistryResolveTransaction);
       
   558 		CleanupStack::PushL(resolver);
       
   559 		}
       
   560 	else
       
   561 		{
       
   562 		User::Leave(KEComErrNoResolver);
       
   563 		}
       
   564 	return resolver;
       
   565 	}
       
   566 
       
   567 
       
   568 TBool CEComServer::RegistryIndexValid() const
       
   569 	{
       
   570 	return iRegistryData->IndexValid();
       
   571 	}
       
   572 	
       
   573 /** Callback function. CRegistryData uses this to notify of implementation
       
   574 upgrade. CDiscoverer uses this to notify state changes in SWI/BUR.
       
   575 @param aObj Pointer to CEComServer object.
       
   576 @param aEvent Identify the event.
       
   577 @param aData Data associated with the callback.
       
   578 @return none, not-used, ignored.
       
   579 */
       
   580 TInt CEComServer::NotifyEvents(TAny* aObj, TInt aEvent, TAny* aData)
       
   581 	{
       
   582 	CEComServer* self = static_cast<CEComServer*>(aObj);
       
   583 	switch (aEvent)
       
   584 		{
       
   585 		case ECallBackId_ImplUpgrade:
       
   586 			{
       
   587 			TUid* uid = static_cast<TUid*>(aData);
       
   588 			self->NotifyUpgrade(*uid);
       
   589 			}
       
   590 			break;
       
   591 		case ECallBackId_SwiEvent:
       
   592 			self->NotifySWIEvent(aData);
       
   593 			break;
       
   594 		case ECallBackId_BurEvent:
       
   595 			self->NotifyBUREvent(aData);
       
   596 			break;
       
   597 		default:
       
   598 			__ECOM_TRACE1("ECOM: CEComServer::NotifyEvents received unknown event %d", aEvent);
       
   599 		}
       
   600 
       
   601 	return 0;
       
   602 	}
       
   603 
       
   604 /** This method is called when an implementation is upgraded.
       
   605 @param aImplementationUid identify the implementation being upgraded.
       
   606 */
       
   607 void CEComServer::NotifyUpgrade(const TUid aImplementationUid)
       
   608 	{
       
   609 	// Ignore return code which indicates if the UID is actually in cache.
       
   610 	(void)iResolverCache->Remove(aImplementationUid);
       
   611 	}
       
   612 
       
   613 /** Called when there is SWI status change.
       
   614 @param aData is TCallBackState* indicating start or end of SWI. 
       
   615 */
       
   616 void CEComServer::NotifySWIEvent(TAny* aData)
       
   617 	{
       
   618 	TCallBackState* state = static_cast<TCallBackState*>(aData);
       
   619 	UpdateSpecialEvents(ESWIInProgress, *state);
       
   620 	}
       
   621 
       
   622 /** Called when there is BUR status change.
       
   623 @param aData is TCallBackState* indicating start or end of BUR. 
       
   624 */
       
   625 void CEComServer::NotifyBUREvent(TAny* aData)
       
   626 	{
       
   627 	TCallBackState* state = static_cast<TCallBackState*>(aData);
       
   628 	UpdateSpecialEvents(EBURInProgress, *state);
       
   629 	}
       
   630 
       
   631 /** Updates the BUR/SWI status.
       
   632 @param aBit Indicate which bit to update.
       
   633 @param aState Indicate start or end of event.
       
   634 */
       
   635 void CEComServer::UpdateSpecialEvents(TUint32 aBit, TCallBackState aState)
       
   636 	{
       
   637 	TBitFlags32 oldstate = iSpecialEvents;
       
   638 
       
   639 	if (aState == ECallBackState_EventStart)
       
   640 		{
       
   641 		iSpecialEvents.Set( aBit );
       
   642 		}
       
   643 	else
       
   644 		{
       
   645 		iSpecialEvents.Clear( aBit );
       
   646 		}
       
   647 
       
   648 	if (oldstate.Value() == 0 && iSpecialEvents.Value() != 0)
       
   649 		{
       
   650 		// BUR or SWI start. Need to evict cached resolvers on RW drives.
       
   651 		iResolverCache->RemoveItemsWithFlags(EEntryIsOnReadWriteDrive);
       
   652 		}
       
   653 	}
       
   654 
       
   655 /** Determine if a resolver entry is cachable.
       
   656 @param aResolverEntry the resolver to check.
       
   657 @return ETrue if the resolver should be added to cache. EFalse otherwise.
       
   658 */
       
   659 TBool CEComServer::IsCachable(TBool aEntryIsOnRWDrive)
       
   660 	{
       
   661 	// Check the following conditions:
       
   662 	// 1. DLL is on RW drive with BUR or SWI in progress.
       
   663 	// 2. Cache size and cache timeout non-zero.
       
   664 	return	iResolverCache->CachingEnabled() &&
       
   665 			!(iSpecialEvents.Value() && aEntryIsOnRWDrive);
       
   666 	}
       
   667 
       
   668 #ifdef __ECOM_SERVER_TESTABILITY__
       
   669 void CEComServer::ChangeStartupStateL(TInt aState) const
       
   670 	{
       
   671 	iServerStartupMgr->ChangeStartupStateL(aState);
       
   672 	}
       
   673 
       
   674 void CEComServer::ProcessCurrentStartupStateL() const
       
   675 	{
       
   676 	iServerStartupMgr->ResetRequestTransitionNotificationL();
       
   677 	iServerStartupMgr->ResetLastStateAcknowledgedL();
       
   678 	iServerStartupMgr->RunL();
       
   679 	}
       
   680 	
       
   681 TInt CEComServer::GetCurrentStartupState() const
       
   682 	{
       
   683 	return iServerStartupMgr->CurrentStartupState();
       
   684 	}
       
   685 #endif //__ECOM_SERVER_TESTABILITY__
       
   686 
       
   687 #ifdef __ECOM_SERVER_PERFORMANCE__
       
   688 void CEComServer::GetRegistryCountsL(TInt aType, RegistryCounts::TRegistryCounts& aCounts) const
       
   689 	{
       
   690 	iRegistryData->GetRegistryCountsL(aType, aCounts);
       
   691 	}	
       
   692 #endif //__ECOM_SERVER_PERFORMANCE__