|
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__ |