|
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 // Implementation of the CLoadManager class |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @internalComponent |
|
20 @file |
|
21 */ |
|
22 |
|
23 #include "EComDebug.h" |
|
24 #include "UnloadPolicy.h" |
|
25 #include "LoadManager.h" |
|
26 #include "EComUidCodes.h" |
|
27 #include <ecom/ecomerrorcodes.h> |
|
28 #include "e32math.h" |
|
29 #include "EComInternalErrorCodes.h" |
|
30 #include <ecom/ecomextendedinterfaceerrorcodes.h> |
|
31 /** |
|
32 Standardized safe construction which leaves nothing on the cleanup stack. |
|
33 @return A pointer to the new class |
|
34 @post CLoadManager is fully constructed, and initialized. |
|
35 */ |
|
36 CLoadManager* CLoadManager::NewL() |
|
37 { |
|
38 return new(ELeave) CLoadManager(); |
|
39 } |
|
40 |
|
41 CLoadManager::~CLoadManager() |
|
42 { |
|
43 iInstanceInfoList.ResetAndDestroy(); |
|
44 iAllUnloadPolicies.ResetAndDestroy(); |
|
45 ClearGarbage(); |
|
46 } |
|
47 |
|
48 /** |
|
49 Notifies the interface implementation DLL that one of its objects has been destroyed if it exists, |
|
50 otherwise returns false to indicate no exist aImplementationUid. |
|
51 @param aInstanceKey A key specifying a previously created implementation. |
|
52 @pre CLoadManager is fully constructed, |
|
53 @post CLoadManager's interface implementation DLL references |
|
54 are decreased by one. The instance info representing the implementation |
|
55 is destroyed. |
|
56 */ |
|
57 TBool CLoadManager::DestroyedThis(TUid aInstanceKey) |
|
58 { |
|
59 // Clear the garbage list because we know we have finished with them |
|
60 ClearGarbage(); |
|
61 |
|
62 __ECOM_TRACE1("ECOM: Implementation Instance destroyed %x", aInstanceKey.iUid); |
|
63 |
|
64 // Sanity check that the pointer is divisible by four. A binary number is divisible |
|
65 // by four if and only if the two rightmost bits are both zero. |
|
66 // This is a compromised check for checking that the pointer is an address. |
|
67 if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0)) |
|
68 { |
|
69 __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey)); |
|
70 User::Leave(KErrNotFound); |
|
71 } |
|
72 |
|
73 // The instance info pointer is stored in the instance key. |
|
74 CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid); |
|
75 |
|
76 // Check that the pointer exists before using it |
|
77 TInt position = iInstanceInfoList.FindInAddressOrder(instanceInfo); |
|
78 if(position == KErrNotFound) |
|
79 { |
|
80 return EFalse; |
|
81 } |
|
82 |
|
83 CUnloadPolicy* policy = instanceInfo->UnloadPolicy(); |
|
84 if (policy != NULL) |
|
85 { |
|
86 // If needed, will move the policy to the garbage list, and remove policy from the unload policy list. |
|
87 Cleanup(policy); |
|
88 } |
|
89 iInstanceInfoList.Remove(position); |
|
90 // Remove the instance info item, finished with it. |
|
91 delete instanceInfo; |
|
92 return ETrue; |
|
93 } |
|
94 |
|
95 /** |
|
96 Check whether the policy Arrays are empty or not. |
|
97 @return Returns True if the policy Arrays are empty, otherwise return False. |
|
98 @pre CLoadManager is fully constructed, |
|
99 @post CLoadManager remains the same. |
|
100 */ |
|
101 TBool CLoadManager::PolicyArraysEmpty() const |
|
102 { |
|
103 if( (iAllUnloadPolicies.Count() == 0)&&(iInstanceInfoList.Count() == 0) ) |
|
104 { |
|
105 return ETrue; |
|
106 } |
|
107 else |
|
108 { |
|
109 return EFalse; |
|
110 } |
|
111 } |
|
112 |
|
113 /** |
|
114 Returns an implementation object to satisfy the specified interface. |
|
115 @param aUniqueImplementationUid The implementation to find. |
|
116 @param aEntry Information on the dll containing the implementation |
|
117 @param aCreationParameters A pointer to the creation parameter |
|
118 structure passed to the creation method when called. |
|
119 @param aCreationParamsFlag A boolean flag to indicate the existence or non-existence |
|
120 of aCreationParameters. Will be ETrue even for if the value of |
|
121 aCreationParameters is NULL. |
|
122 @param aInstanceKey A key specifying a previously created implementation. |
|
123 @return TAny* a pointer to the fully constructed instantiation. The pointer is |
|
124 guaranteed to be valid only until DestroyedThis is called. |
|
125 @pre CLoadManager is fully constructed, |
|
126 @post Fully constructed implementation is returned to the |
|
127 caller, and aUniqueUid contains the implementation Dll's |
|
128 unique UID. |
|
129 */ |
|
130 TAny* CLoadManager::ImplementationObjectL(const TUid& aUniqueImplementationUid, |
|
131 const TEntry& aEntry, |
|
132 TAny* aCreationParameters, |
|
133 TBool aCreationParamsFlag, |
|
134 TUid& aInstanceKey) |
|
135 { |
|
136 //if the implementation Uid here is Null or the entry returned by the ecomserver |
|
137 //contains nothing, we should leave with KErrNotFound |
|
138 if(aUniqueImplementationUid == KNullUid || (aEntry.iName).Length()==0) |
|
139 { |
|
140 User::Leave(KErrNotFound); |
|
141 } |
|
142 |
|
143 TAny* object = NULL; // Instantiation object |
|
144 CUnloadPolicy* policy = NULL; // Policy of implementation |
|
145 TLibraryFunction libFunctionProxy; // Library function proxy pointer |
|
146 |
|
147 GetUnloadPolicy(aUniqueImplementationUid,aEntry,policy); |
|
148 if (policy == NULL) |
|
149 { |
|
150 // No policy found, so create a new CUnloadPolicy and load DLL. |
|
151 policy = CUnloadPolicy::NewLC(aEntry); |
|
152 libFunctionProxy = policy->LoadDllAndReturnProxyL(); |
|
153 if (libFunctionProxy==NULL) |
|
154 { |
|
155 User::Leave(KErrNotFound); |
|
156 } |
|
157 iAllUnloadPolicies.AppendL(policy); |
|
158 CleanupStack::Pop(policy); // owned by iAllUnloadPolicies |
|
159 } |
|
160 else |
|
161 { |
|
162 // Found a policy. Load Dll if not already loaded. |
|
163 libFunctionProxy = policy->LoadDllAndReturnProxyL(); |
|
164 if (libFunctionProxy==NULL) |
|
165 { |
|
166 User::Leave(KErrNotFound); |
|
167 } |
|
168 } |
|
169 // Initial count of instances. This is used for cleanup purposes, to see if an instance |
|
170 // was added to the instance info list during the object creation. If a failure occurs |
|
171 // than the instance info that was added to the list will be removed. |
|
172 TInt initialCount = iInstanceInfoList.Count(); |
|
173 TInt err = KErrNone; |
|
174 |
|
175 if (aEntry[1] == KUidInterfaceImplementationCollection) |
|
176 { |
|
177 // PLUGIN1 dll. Create the implementation object. |
|
178 TRAP(err,object = ImplementationObject1L(aUniqueImplementationUid,aCreationParameters, |
|
179 aCreationParamsFlag,aInstanceKey,policy,libFunctionProxy)); |
|
180 } |
|
181 else if (aEntry[1] == KUidInterfaceImplementationCollection3) |
|
182 { |
|
183 // PLUGIN3 dll. Create the implementation object. |
|
184 TRAP(err,object = ImplementationObject3L(aUniqueImplementationUid,aCreationParameters, |
|
185 aCreationParamsFlag, aInstanceKey,policy, libFunctionProxy)); |
|
186 } |
|
187 else |
|
188 { |
|
189 err = KErrNotSupported; |
|
190 } |
|
191 |
|
192 if (err != KErrNone) |
|
193 { |
|
194 if (iInstanceInfoList.Count() > initialCount) |
|
195 { |
|
196 // If an instance was added to the instance list, remove it here. |
|
197 // The instance info pointer is stored in the instance key. We know its |
|
198 // valid because it was set by ecom in call to ImplementationObject1L or |
|
199 // ImplementationObject3L |
|
200 CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid); |
|
201 TInt pos = iInstanceInfoList.FindInAddressOrder(instanceInfo); |
|
202 if(pos != KErrNotFound) |
|
203 { |
|
204 iInstanceInfoList.Remove(pos); |
|
205 } |
|
206 } |
|
207 |
|
208 ClearGarbage(); |
|
209 // If needed, will move the policy to the garbage list, and remove policy from the unload policy list. |
|
210 Cleanup(policy); |
|
211 User::Leave(err); |
|
212 } |
|
213 |
|
214 __ECOM_TRACE2("ECOM: Implementation created (%03d) %x", ++iDebugInstantiationCounter, aUniqueImplementationUid.iUid); |
|
215 |
|
216 return object; |
|
217 } |
|
218 |
|
219 /** |
|
220 Returns an implementation object to satisfy the specified interface. |
|
221 @param aUniqueImplementationUid The implementation to find. |
|
222 @param aCreationParameters A pointer to the creation parameter |
|
223 structure passed to the creation method when called. |
|
224 @param aCreationParamsFlag A boolean flag to indicate the existence or non-existence |
|
225 of aCreationParameters. Will be ETrue even for if the value of |
|
226 aCreationParameters is NULL. |
|
227 @param aInstanceKey A key specifying a previously created implementation. |
|
228 @param aPolicy policy of implementation |
|
229 @param aLibFunctionProxy Library function proxy pointer. |
|
230 @return TAny* a pointer to the fully constructed instantiation. The pointer is |
|
231 guaranteed to be valid only until DestroyedThis is called. |
|
232 */ |
|
233 TAny* CLoadManager::ImplementationObject1L(const TUid& aUniqueImplementationUid, |
|
234 TAny* aCreationParameters, |
|
235 TBool aCreationParamsFlag, |
|
236 TUid& aInstanceKey, |
|
237 CUnloadPolicy* aPolicy, |
|
238 TLibraryFunction& aLibFunctionProxy) |
|
239 { |
|
240 TAny* object = NULL; // Instantiation object |
|
241 TInstantiationL proxy = reinterpret_cast<TInstantiationL>(aLibFunctionProxy); |
|
242 |
|
243 TImplementationProxy* implementationProxyRow = NULL; |
|
244 TAny* newLPointer = GetNewLPointerAndProxyTableRowL<TImplementationProxy,TInstantiationL>(aUniqueImplementationUid,implementationProxyRow,proxy); |
|
245 // Now create an instance info object to store the information about this instance derived from |
|
246 // the parameters just fetched. This must be created here since no leaves can occur after the object |
|
247 // instantiation below. |
|
248 CInstanceInfoSimple* instanceInfoSimple = CInstanceInfoSimple::NewL(aPolicy,implementationProxyRow); |
|
249 CleanupStack::PushL(instanceInfoSimple); |
|
250 |
|
251 // The pointer to instanceInfo will be used to identify this instance, and will |
|
252 // be returned to the caller for future identification of this instance. |
|
253 aInstanceKey.iUid = reinterpret_cast<TInt32>(instanceInfoSimple); |
|
254 |
|
255 // Add item to instance info list. This list will contain all of the instance objects. |
|
256 iInstanceInfoList.InsertInAddressOrderL(instanceInfoSimple); |
|
257 |
|
258 // Get the implementation object using the instantiation pointer fetched earlier. Note |
|
259 // that the object creation must be the last leaving operation to be performed. No leaves can occur |
|
260 // after this operation, as the instantiation object cannnot be deleted on the cleanup stack if |
|
261 // a leave occurs (cannot delete a TAny* pointer, the type is not known within ECOM). |
|
262 object = ImplementationObjectL(aCreationParameters, |
|
263 aCreationParamsFlag,newLPointer); |
|
264 |
|
265 CleanupStack::Pop(instanceInfoSimple); |
|
266 |
|
267 return object; |
|
268 } |
|
269 |
|
270 /** |
|
271 Returns an implementation object to satisfy the specified interface. |
|
272 @param aUniqueImplementationUid The implementation to find. |
|
273 @param aCreationParameters A pointer to the creation parameter |
|
274 structure passed to the creation method when called. |
|
275 @param aCreationParamsFlag A boolean flag to indicate the existence or non-existence |
|
276 of aCreationParameters. Will be ETrue even for if the value of |
|
277 aCreationParameters is NULL. |
|
278 @param aInstanceKey A key specifying a previously created implementation. |
|
279 @param aPolicy policy of implementation |
|
280 @param aLibFunctionProxy Library function proxy pointer. |
|
281 @return TAny* a pointer to the fully constructed instantiation. The pointer is |
|
282 guaranteed to be valid only until DestroyedThis is called. |
|
283 */ |
|
284 TAny* CLoadManager::ImplementationObject3L(const TUid& aUniqueImplementationUid, |
|
285 TAny* aCreationParameters, |
|
286 TBool aCreationParamsFlag, |
|
287 TUid& aInstanceKey, |
|
288 CUnloadPolicy* aPolicy, |
|
289 TLibraryFunction& aLibFunctionProxy) |
|
290 { |
|
291 TAny* object = NULL; // Instantiation object |
|
292 TInstantiation3L proxy = reinterpret_cast<TInstantiation3L>(aLibFunctionProxy); |
|
293 |
|
294 TImplementationProxy3* implementationProxyRow = NULL; |
|
295 TAny* newLPointer = GetNewLPointerAndProxyTableRowL<TImplementationProxy3,TInstantiation3L>(aUniqueImplementationUid,implementationProxyRow,proxy); |
|
296 |
|
297 // Now create an instance info object to store the information about this instance derived from |
|
298 // the parameters just fetched. This must be created here since no leaves can occur after the object |
|
299 // instantiation below. |
|
300 CInstanceInfoExtended* instanceInfoExtended = CInstanceInfoExtended::NewL(aPolicy,implementationProxyRow); |
|
301 CleanupStack::PushL(instanceInfoExtended); |
|
302 |
|
303 // The pointer to instanceInfo will be used to identify this instance, and will |
|
304 // be returned to the caller for future identification of this instance. |
|
305 aInstanceKey.iUid = reinterpret_cast<TInt32>(instanceInfoExtended); |
|
306 |
|
307 // Add item to instance info list. This list will contain all of the instance objects. |
|
308 iInstanceInfoList.InsertInAddressOrderL(instanceInfoExtended); |
|
309 |
|
310 // Get the implementation object using the instantiation pointer fetched earlier. Note |
|
311 // that the object creation must be the last leaving operation to be performed. No leaves can occur |
|
312 // after this operation, as the instantiation object cannnot be deleted on the cleanup stack if |
|
313 // a leave occurs (cannot delete a TAny* pointer, the type is not known within ECOM). |
|
314 object = ImplementationObjectL(aCreationParameters, |
|
315 aCreationParamsFlag,newLPointer); |
|
316 |
|
317 // The extended instance info requires an object set. This is done here |
|
318 // as the object is not known until now, but the instance info object was required to |
|
319 // be created earlier to avoid a leave after the object creation. |
|
320 instanceInfoExtended->SetObject(object); |
|
321 CleanupStack::Pop(instanceInfoExtended); |
|
322 |
|
323 return object; |
|
324 } |
|
325 |
|
326 /** |
|
327 Gets the main implementation object using the instantiation pointer provided |
|
328 @param aCreationParameters A pointer to the creation parameter |
|
329 structure passed to the creation method when called. |
|
330 @param aCreationParamsFlag A boolean flag to indicate the existence or non-existence |
|
331 of aCreationParameters. Will be ETrue even for if the value of |
|
332 aCreationParameters is NULL. |
|
333 @param aNewLpointer Instantation pointer. |
|
334 aCreationParameters is NULL. |
|
335 @return TAny* a pointer to the fully constructed instantiation. |
|
336 */ |
|
337 TAny* CLoadManager::ImplementationObjectL(TAny* aCreationParameters, |
|
338 TBool aCreationParamsFlag, |
|
339 const TAny* aNewLpointer) |
|
340 { |
|
341 TAny* object=NULL; |
|
342 |
|
343 // So cast to the correct type : This gives an ANSI C++ warning |
|
344 // When using a REINTERPRET_CAST so simply cast instead |
|
345 // Two different object creation one with creation parameters |
|
346 if (aCreationParamsFlag) |
|
347 { |
|
348 typedef TAny* (*TNewL)(TAny*); |
|
349 TNewL creationL = (TNewL)(aNewLpointer); |
|
350 object=creationL(aCreationParameters); |
|
351 } |
|
352 else |
|
353 { |
|
354 typedef TAny* (*TNewL)(); |
|
355 TNewL creationL = (TNewL)(aNewLpointer); |
|
356 object=creationL(); |
|
357 } |
|
358 |
|
359 return object; |
|
360 } |
|
361 |
|
362 /** |
|
363 Get the unload policy. |
|
364 @param aUniqueImplementationUid The implementation to find. |
|
365 @param aEntry Information on the dll containing the implementation |
|
366 @param aPolicy Return parameter containing the policy |
|
367 @return None |
|
368 */ |
|
369 void CLoadManager::GetUnloadPolicy(TUid aUniqueImplementationUid, |
|
370 const TEntry& aEntry, |
|
371 CUnloadPolicy*& aPolicy) |
|
372 { |
|
373 const TInt numImps = iInstanceInfoList.Count(); |
|
374 TBool foundImp = EFalse; |
|
375 TInt matchingDllIndex=0; |
|
376 TBool matchingDllFound=EFalse; |
|
377 CUnloadPolicy* policy = NULL; |
|
378 |
|
379 for (TInt index = 0; (index<numImps) && !foundImp; ++index) |
|
380 { |
|
381 //Check if there is existing mapping between the supplied implUid and a policy |
|
382 if(iInstanceInfoList[index]->ImplementationUid() == aUniqueImplementationUid) |
|
383 { |
|
384 policy = iInstanceInfoList[index]->UnloadPolicy(); |
|
385 |
|
386 foundImp = ETrue; |
|
387 } |
|
388 else |
|
389 { |
|
390 //if cannot find a mapping entry but current index has the same DLL as the one requested from |
|
391 //the client, store the index to this unloadPolicy for use later on if we have finished |
|
392 //searching the entire mapping list |
|
393 if (!matchingDllFound && (iInstanceInfoList[index]->UnloadPolicy()->DllEntryInformation().GetName()).CompareF(aEntry.iName)==0) |
|
394 { |
|
395 matchingDllIndex=index; |
|
396 matchingDllFound=ETrue; |
|
397 } |
|
398 } |
|
399 } |
|
400 |
|
401 //If we cannot find any mapping in the policy index array(iUnloadPolicyMapping) |
|
402 if(!foundImp) |
|
403 { |
|
404 //if not found but there is a matching DLL,we can simply create a new policy index mapping without |
|
405 //having to load the library again. |
|
406 if (matchingDllFound) |
|
407 { |
|
408 policy = iInstanceInfoList[matchingDllIndex]->UnloadPolicy(); |
|
409 } |
|
410 } |
|
411 |
|
412 aPolicy = policy; |
|
413 } |
|
414 |
|
415 /** |
|
416 Clears the policy inside the iGarbagePolicies attribute. |
|
417 @pre CLoadManager is fully constructed |
|
418 @post CLoadManager iGarbagePolicies is zero'd |
|
419 */ |
|
420 void CLoadManager::ClearGarbage() |
|
421 { |
|
422 if (iGarbagePolicy != NULL) |
|
423 { |
|
424 delete iGarbagePolicy; |
|
425 iGarbagePolicy=0; |
|
426 } |
|
427 } |
|
428 |
|
429 CLoadManager::CLoadManager() : |
|
430 CBase() |
|
431 { |
|
432 // Do nothing here |
|
433 } |
|
434 |
|
435 /** |
|
436 Returns the implementation ID for a given instance Key. |
|
437 @leave KErrNotFound |
|
438 @param aInstanceKey A key specifying a previously created implementation instance. |
|
439 @return TUid The uid of the corresponding implementation. |
|
440 @pre CLoadManager is fully constructed, |
|
441 @post CLoadManager remains the same. |
|
442 */ |
|
443 TUid CLoadManager::GetImplementationUidL(TUid aInstanceKey) |
|
444 { |
|
445 // Sanity check that the pointer is divisible by four. A binary number is divisible |
|
446 // by four if and only if the two rightmost bits are both zero. |
|
447 // This is a compromised check for checking that the pointer is an address. |
|
448 if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0)) |
|
449 { |
|
450 __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey)); |
|
451 User::Leave(KErrNotFound); |
|
452 } |
|
453 |
|
454 // The instance info pointer is stored in the instance key. |
|
455 CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid); |
|
456 |
|
457 // Check that the pointer exists before using it - leaves with KErrNotFound |
|
458 iInstanceInfoList.FindInAddressOrderL(instanceInfo); |
|
459 return instanceInfo->ImplementationUid(); |
|
460 } |
|
461 |
|
462 /** |
|
463 Fetches the requested extended interface from a specified implementation instance. |
|
464 @leave KErrNotFound |
|
465 @param aInstanceKey A key specifying a previously created implementation. |
|
466 @param aExtendedInterfaceUid Identifies an interface to fetch from the plug-in instance. |
|
467 @return TAny* A pointer to the extended interface, will be NULL if it does not exist. |
|
468 */ |
|
469 TAny* CLoadManager::GetExtendedInterfaceL(const TUid& aInstanceKey, const TUid& aExtendedInterfaceUid) |
|
470 { |
|
471 // Sanity check that the pointer is divisible by four. A binary number is divisible |
|
472 // by four if and only if the two rightmost bits are both zero. |
|
473 // This is a compromised check for checking that the pointer is an address. |
|
474 if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0)) |
|
475 { |
|
476 __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey)); |
|
477 User::Leave(KErrNotFound); |
|
478 } |
|
479 |
|
480 // The instance info pointer is stored in the instance key. |
|
481 CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid); |
|
482 |
|
483 // Check that the pointer exists before using it - leaves with KErrNotFound |
|
484 iInstanceInfoList.FindInAddressOrderL(instanceInfo); |
|
485 |
|
486 // Create the extension object. The instance info object will be populated with |
|
487 // the extension info during creation. |
|
488 TAny* object = instanceInfo->CreateExtObjectL(aExtendedInterfaceUid); |
|
489 return object; |
|
490 } |
|
491 |
|
492 /** |
|
493 Manually releases the requested interface. Does nothing if it does not exist. |
|
494 This interface is optional, normally the interfaces are cleaned up automatically. |
|
495 @leave KErrNotFound |
|
496 @param aInstanceKey A key specifying a previously created implementation. |
|
497 @param aExtendedInterfaceUid Identifies the interface to release |
|
498 @return None. |
|
499 */ |
|
500 void CLoadManager::ManuallyReleaseExtendedInterfaceL(const TUid& aInstanceKey, const TUid& aExtendedInterfaceUid) |
|
501 { |
|
502 // Sanity check that the pointer is divisible by four. A binary number is divisible |
|
503 // by four if and only if the two rightmost bits are both zero. |
|
504 // This is a compromised check for checking that the pointer is an address. |
|
505 if ((aInstanceKey.iUid == 0) || ((aInstanceKey.iUid & 0x00000003) != 0)) |
|
506 { |
|
507 __ASSERT_DEBUG(EFalse, User::Panic(KEComClientDLLPanicCategory, EEComPanic_InvalidImplementationInstanceKey)); |
|
508 User::Leave(KErrNotFound); |
|
509 } |
|
510 |
|
511 // The instance info pointer is stored in the instance key. |
|
512 CInstanceInfo* instanceInfo = reinterpret_cast<CInstanceInfo*>(aInstanceKey.iUid); |
|
513 |
|
514 // Check that the pointer exists before using it - leaves with KErrNotFound |
|
515 iInstanceInfoList.FindInAddressOrderL(instanceInfo); |
|
516 |
|
517 instanceInfo->DestroyExtObject(aExtendedInterfaceUid); |
|
518 } |
|
519 |
|
520 /** |
|
521 Utility method to move the policy to the garbage list, remove |
|
522 policy from the unload policy list. |
|
523 @param aPolicy Unload policy to clean up |
|
524 @return None. |
|
525 */ |
|
526 void CLoadManager::Cleanup(CUnloadPolicy* aPolicy) |
|
527 { |
|
528 if (aPolicy->DecreaseReference() == EDeleteMe) |
|
529 { |
|
530 // Move the policy to the garbage list |
|
531 iGarbagePolicy=aPolicy; |
|
532 |
|
533 TInt index = iAllUnloadPolicies.Find(aPolicy); |
|
534 if (index != KErrNotFound) |
|
535 { |
|
536 iAllUnloadPolicies.Remove(index); |
|
537 } |
|
538 } |
|
539 } |
|
540 |
|
541 // |
|
542 // CInstanceInfo |
|
543 /** |
|
544 Default constructor of CInstanceInfo |
|
545 @param aUnloadPolicy The CUnloadPolicy of the dll |
|
546 */ |
|
547 CInstanceInfo::CInstanceInfo(CUnloadPolicy* aUnloadPolicy): |
|
548 iUnloadPolicy(aUnloadPolicy) |
|
549 { |
|
550 // Do nothing here |
|
551 } |
|
552 |
|
553 /** |
|
554 Destructor of CInstanceInfo |
|
555 */ |
|
556 CInstanceInfo::~CInstanceInfo() |
|
557 { |
|
558 // Do nothing here |
|
559 } |
|
560 |
|
561 |
|
562 // |
|
563 // CInstanceInfoExtended |
|
564 /** |
|
565 Default constructor of CInstanceInfoExtended |
|
566 @param aUnloadPolicy The CUnloadPolicy of the dll |
|
567 @param aImplementationProxyRow The interface implementation proxy row entry |
|
568 */ |
|
569 CInstanceInfoExtended::CInstanceInfoExtended(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy3* aImplementationProxyRow): |
|
570 CInstanceInfo(aUnloadPolicy),iImplementationProxyRow(aImplementationProxyRow) |
|
571 { |
|
572 // Do nothing here |
|
573 } |
|
574 |
|
575 /** |
|
576 create an instance of CInstanceInfoExtended |
|
577 @param aUnloadPolicy The CUnloadPolicy of the dll |
|
578 @param aImplementationProxyRow The interface implementation proxy row entry |
|
579 @return A pointer to the newly created object. |
|
580 */ |
|
581 CInstanceInfoExtended* CInstanceInfoExtended::NewL(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy3* aImplementationProxyRow) |
|
582 { |
|
583 return new(ELeave) CInstanceInfoExtended(aUnloadPolicy,aImplementationProxyRow); |
|
584 } |
|
585 |
|
586 /** |
|
587 Sets the implementation object. |
|
588 @param aImplementationObject The object instance of this instances' implementation |
|
589 @return None |
|
590 */ |
|
591 void CInstanceInfoExtended::SetObject(TAny* aImplementationObject) |
|
592 { |
|
593 iImplementationObject = aImplementationObject; |
|
594 } |
|
595 |
|
596 /** |
|
597 Creates the extension interface object. This will use the get extended interface |
|
598 function pointer from the proxy table to fetch the extended interface from the |
|
599 plug-in implementation. |
|
600 @param aExtendedInterfaceUID The extended interface UID |
|
601 @return TAny* A pointer to an instance of an extended interface created |
|
602 */ |
|
603 TAny* CInstanceInfoExtended::CreateExtObjectL(const TUid& aExtendedInterfaceUID) |
|
604 { |
|
605 // Fetch the function pointer to create the extended interface |
|
606 TProxyExtendedInterfaceGetPtrL createFunctionPtrL = iImplementationProxyRow->iFuncPtrInterfaceGetL; |
|
607 if (createFunctionPtrL == NULL) |
|
608 { |
|
609 // No extension interface object can be created. Return NULL indicating that |
|
610 // no extended interface object is available. |
|
611 return NULL; |
|
612 } |
|
613 |
|
614 // Valid function pointer exists in proxy table. |
|
615 TAny* object = NULL; // Extended interface object (this points to the interface |
|
616 // within the object) |
|
617 TAny* releaseObject = NULL; // Eextended interface object (this points to the extended |
|
618 // object itself). Used to delete the extended interface |
|
619 // object later. |
|
620 TUint32 flags = 0; // Flags to allow the plug-in and ECOM to communicate |
|
621 // Create the extension object. |
|
622 object = createFunctionPtrL(iImplementationObject,aExtendedInterfaceUID,flags,releaseObject); |
|
623 |
|
624 if (flags & KReleaseRequiredMask) |
|
625 { |
|
626 // If release of the extended interface is required then save the release object pointer. |
|
627 // The interface object (returned by the function pointer call) and the release object |
|
628 // are not necessarily the same pointer. This is because the interface pointer is not |
|
629 // guaranteed to be the same as the pointer to the extended interface object. That |
|
630 // is why the release object is required to be fetched from the plug-in. |
|
631 |
|
632 // First perform some checks to ensure that the plugin is consistent |
|
633 TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease; |
|
634 |
|
635 if (release == NULL) |
|
636 { |
|
637 // ...the release object pointer must not be non null |
|
638 __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::CreateExtObjectL, release required but release function missing"); |
|
639 __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_CreateExtObjectL_NoReleaseFunc)); |
|
640 User::Leave(KEComErrNoExtendedInterfaceReleaseFunction); |
|
641 } |
|
642 |
|
643 if (releaseObject == NULL) |
|
644 { |
|
645 // ... the releaseObject must be non null |
|
646 __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::CreateExtObjectL, release required but release object missing"); |
|
647 __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_CreateExtObjectL_NoReleaseObj)); |
|
648 User::Leave(KEComErrNoExtendedInterfaceReleaseObject); |
|
649 } |
|
650 |
|
651 //Create the extended object info type and add it to the extended object info array. |
|
652 TExtendedObjectInfo extendedObjectInfo; |
|
653 extendedObjectInfo.iExtendedInterfaceObject = releaseObject; |
|
654 extendedObjectInfo.iExtendedInterfaceUID = aExtendedInterfaceUID; |
|
655 |
|
656 TInt err = iExtendedObjectInfo.Append(extendedObjectInfo); |
|
657 |
|
658 if (err != KErrNone) |
|
659 { |
|
660 if (release != NULL) |
|
661 { |
|
662 // Release the extended interface. Release must not leave. |
|
663 release(extendedObjectInfo.iExtendedInterfaceObject,extendedObjectInfo.iExtendedInterfaceUID); |
|
664 } |
|
665 User::Leave(err); |
|
666 } |
|
667 } |
|
668 |
|
669 return object; |
|
670 } |
|
671 |
|
672 |
|
673 /** |
|
674 Destroys the extension interface object. |
|
675 @param aExtendedInterfaceUID The extended interface UID |
|
676 @return None |
|
677 */ |
|
678 void CInstanceInfoExtended::DestroyExtObject(const TUid& aExtendedInterfaceUID) |
|
679 { |
|
680 // Get release interface |
|
681 TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease; |
|
682 |
|
683 if (release != NULL) |
|
684 { |
|
685 // Release extended interface. Find the extended object info. |
|
686 for(TInt i = 0; i < iExtendedObjectInfo.Count(); i++) |
|
687 { |
|
688 if (iExtendedObjectInfo[i].iExtendedInterfaceUID == aExtendedInterfaceUID) |
|
689 { |
|
690 TAny* releaseObject = iExtendedObjectInfo[i].iExtendedInterfaceObject; |
|
691 if (releaseObject == NULL) |
|
692 { |
|
693 // ... the releaseObject must be non null |
|
694 __ECOM_TRACE("ECOM: PANIC in CInstanceInfoExtended::DestroyExtObject, release required but release object missing"); |
|
695 __ASSERT_DEBUG(EFalse, User::Panic (KEComClientDLLPanicCategory, EEComPanic_CInstanceInfoExtended_DestroyExtObject_NoReleaseObj)); |
|
696 } |
|
697 |
|
698 // Release the extended interface. Release should not be leaving. |
|
699 release(releaseObject, iExtendedObjectInfo[i].iExtendedInterfaceUID); |
|
700 // Remove the extended object info element from the array. |
|
701 iExtendedObjectInfo.Remove(i); |
|
702 break; |
|
703 } |
|
704 } |
|
705 } |
|
706 } |
|
707 |
|
708 /** |
|
709 Destructor of CInstanceInfoExtended |
|
710 */ |
|
711 CInstanceInfoExtended::~CInstanceInfoExtended() |
|
712 { |
|
713 // Get release interface |
|
714 if (iImplementationProxyRow != NULL) |
|
715 { |
|
716 TProxyExtendedInterfaceReleasePtr release = iImplementationProxyRow->iFuncPtrInterfaceRelease; |
|
717 |
|
718 if (release != NULL) |
|
719 { |
|
720 // Release all extended interfaces (if any still to be released) |
|
721 for(TInt i = 0; i < iExtendedObjectInfo.Count(); i++) |
|
722 { |
|
723 // Release is supposed to be non-leavable. |
|
724 release(iExtendedObjectInfo[i].iExtendedInterfaceObject,iExtendedObjectInfo[i].iExtendedInterfaceUID); |
|
725 } |
|
726 } |
|
727 } |
|
728 |
|
729 iExtendedObjectInfo.Close(); |
|
730 } |
|
731 |
|
732 // |
|
733 // CInstanceInfoSimple |
|
734 /** |
|
735 Default constructor of CInstanceInfoSimple |
|
736 @param aUnloadPolicy The CUnloadPolicy of the dll |
|
737 @param aImplementationProxyRow The interface implementation proxy row entry |
|
738 */ |
|
739 CInstanceInfoSimple::CInstanceInfoSimple(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy* aImplementationProxyRow): |
|
740 CInstanceInfo(aUnloadPolicy),iImplementationProxyRow(aImplementationProxyRow) |
|
741 { |
|
742 // Do nothing here |
|
743 } |
|
744 |
|
745 /** |
|
746 Create an instance of CInstanceInfoSimple |
|
747 @param aUnloadPolicy The CUnloadPolicy of the dll |
|
748 @param aImplementationProxyRow The interface implementation proxy row entry |
|
749 @return A pointer to the newly created object. |
|
750 */ |
|
751 CInstanceInfoSimple* CInstanceInfoSimple::NewL(CUnloadPolicy* aUnloadPolicy,const TImplementationProxy* aImplementationProxyRow) |
|
752 { |
|
753 return new(ELeave) CInstanceInfoSimple(aUnloadPolicy,aImplementationProxyRow); |
|
754 } |