1 krisbash 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 krisbash 1.1 **==============================================================================
23 */
24
25 #include "LifecycleContext.h"
26 #include "SubMgr.h"
27 #include "CIM_InstCreation.h"
28 #include "CIM_InstDeletion.h"
29 #include "CIM_InstMethodCall.h"
30 #include "CIM_InstModification.h"
31 #include "CIM_InstRead.h"
32 #include "indicationSchema.h"
33 #include <base/instance.h>
34 #include <base/log.h>
35 #include <pal/format.h>
36 #include <pal/cpu.h>
37 #include <pal/palcommon.h>
38 #include <indication/common/indilog.h>
39
40 static const MI_Uint32 _LIFECYCLE_MAGIC = 0xFEEDCAFE;
41
42 extern MI_CONST MI_ClassDecl CIM_InstCreation_rtti;
43 krisbash 1.1 extern MI_CONST MI_ClassDecl CIM_InstDeletion_rtti;
44 extern MI_CONST MI_ClassDecl CIM_InstMethodCall_rtti;
45 extern MI_CONST MI_ClassDecl CIM_InstModification_rtti;
46 extern MI_CONST MI_ClassDecl CIM_InstRead_rtti;
47
48 /*
49 * This method takes advantage of the fact that the underlying layout of
50 * properties within all concrete lifecycle indication classes is identical.
51 * If the layout ever changes, this method must be updated (highly unlikely).
52 */
53 MI_Result _SetCommonProperties(
54 MI_Instance* instToFill,
55 const MI_Instance* sourceInstance )
56 {
57 MI_Result result = MI_RESULT_OK;
58 MI_Value value;
59 PAL_Datetime now;
60
61 /*
62 * Set CIM_Indication properties
63 */
64 krisbash 1.1 // TODO: Populate values correctly
65 /* MI_ConstStringField IndicationIdentifier */
66 value.string = PAL_T("MSFT:IndicationIdentifier");
67 result = MI_Instance_SetElement( instToFill, PAL_T("IndicationIdentifier"), &value, MI_STRING, 0 );
68 if (MI_RESULT_OK != result)
69 {
70 trace_FailedToSet_IndicationIdentifier();
71 return result;
72 }
73
74 /* MI_ConstStringAField CorrelatedIndications * /
75 result = MI_Instance_SetElement( instToFill, PAL_T("CorrelatedIndications"), &value, MI_STRINGA, 0 );
76 if (MI_RESULT_OK != result)
77 {
78 trace_FailedToSet_CorrelatedIndications();
79 return result;
80 }
81 */
82
83 /* MI_ConstDatetimeField IndicationTime */
84 if (0 == CPU_GetLocalTimestamp(&now) )
85 krisbash 1.1 {
86 memcpy( &value.datetime, &now, sizeof(MI_Datetime) );
87 result = MI_Instance_SetElement( instToFill, PAL_T("IndicationTime"), &value, MI_DATETIME, 0 );
88 if (MI_RESULT_OK != result)
89 {
90 trace_FailedToSet_IndicationTime();
91 return result;
92 }
93 }
94
95 /* MI_ConstUint16Field PerceivedSeverity * /
96 result = MI_Instance_SetElement( instToFill, PAL_T("PerceivedSeverity"), &value, MI_UINT16, 0 );
97 if (MI_RESULT_OK != result)
98 {
99 trace_FailedToSet_PerceivedSeverity();
100 return result;
101 }
102
103 / * MI_ConstStringField OtherSeverity * /
104 result = MI_Instance_SetElement( instToFill, PAL_T("OtherSeverity"), &value, MI_STRING, 0 );
105 if (MI_RESULT_OK != result)
106 krisbash 1.1 {
107 trace_FailedToSet_OtherSeverity();
108 return result;
109 }
110
111 / * MI_ConstStringField IndicationFilterName * /
112 result = MI_Instance_SetElement( instToFill, PAL_T("IndicationFilterName"), &value, MI_STRING, 0 );
113 if (MI_RESULT_OK != result)
114 {
115 trace_FailedToSet_IndicationFilterName();
116 return result;
117 }
118
119 / * MI_ConstStringField SequenceContext * /
120 result = MI_Instance_SetElement( instToFill, PAL_T("SequenceContext"), &value, MI_STRING, 0 );
121 if (MI_RESULT_OK != result)
122 {
123 trace_FailedToSet_SequenceContext();
124 return result;
125 }
126
127 krisbash 1.1 / * MI_ConstSint64Field SequenceNumber * /
128 result = MI_Instance_SetElement( instToFill, PAL_T("SequenceNumber"), &value, MI_SINT64, 0 );
129 if (MI_RESULT_OK != result)
130 {
131 trace_FailedToSet_SequenceNumber();
132 return result;
133 }
134
135 / *
136 * Set CIM_InstIndication properties
137 * /
138
139 / * MI_ConstReferenceField SourceInstance */
140 if (sourceInstance)
141 {
142 value.reference = (MI_Instance*)sourceInstance;
143 result = MI_Instance_SetElement( instToFill, PAL_T("SourceInstance"), &value, MI_INSTANCE, 0 );
144 if (MI_RESULT_OK != result)
145 {
146 trace_FailedToSet_SourceInstance();
147 return result;
148 krisbash 1.1 }
149 }
150
151 /* MI_ConstStringField SourceInstanceModelPath * /
152 result = MI_Instance_SetElement( instToFill, PAL_T("SourceInstanceModelPath"), &value, MI_STRING, 0 );
153 if (MI_RESULT_OK != result)
154 {
155 trace_FailedToSet_SourceInstanceModelPath();
156 return result;
157 }
158
159 / * MI_ConstStringField SourceInstanceHost * /
160 result = MI_Instance_SetElement( instToFill, PAL_T("SourceInstanceHost"), &value, MI_STRING, 0 );
161 if (MI_RESULT_OK != result)
162 {
163 trace_FailedToSet_SourceInstanceHost();
164 return result;
165 }
166 */
167 return MI_RESULT_OK;
168 }
169 krisbash 1.1
170 MI_Result _PostToAllSubscribers(
171 _In_ SubscriptionManager* subMgr,
172 _In_ MI_Instance* instanceToPost,
173 _In_ MI_Uint32 postTargetType )
174 {
175 MI_Boolean atLeastOneDelivered = MI_FALSE;
176 SubMgrSubscriptionPtr* sublist;
177 MI_Result r;
178 size_t count = 0;
179 size_t i;
180
181 r = SubMgr_GetSubscriptionList(subMgr, &sublist, &count);
182 if ( r != MI_RESULT_OK )
183 return r;
184
185 /* For each subscription, use its context to PostInstance of instCreation. */
186 r = MI_RESULT_FAILED;
187 for (i = 0; i < count; i++)
188 {
189 /*
190 krisbash 1.1 * This action is done through Context to:
191 * 1. Conform to the existing API
192 * 2. Avoid exposure of internal code via Context.h
193 * 3. Reuse indication posting code
194 *
195 * This is a best-effort action. Intermediate failures will be
196 * ignored.
197 */
198 SubscriptionContext* ctx = sublist[i]->subscribeCtx;
199 if (0 != (postTargetType & LifeContext_ConvertSupportedType( sublist[i]->msg->targetType )) )
200 {
201 if (MI_RESULT_OK == (r = MI_Context_PostIndication( &ctx->baseCtx.base, instanceToPost, 0, NULL ) ) )
202 {
203 atLeastOneDelivered = MI_TRUE;
204 }
205 }
206 SubMgrSubscription_Release(sublist[i]);
207 }
208 return (atLeastOneDelivered ? MI_RESULT_OK : r);
209 }
210
211 krisbash 1.1 /*
212 * Groups all common indication preparation actions for re-use. This
213 * function is targetted for Post handlers that set additional properties
214 * on the indication prior to forwarding it.
215 *
216 * Note: The caller must call MI_Instance_Destruct on instanceToPost to ensure
217 * proper cleanup.
218 */
219 MI_Result _CommonIndicationPrep(
220 _In_ MI_LifecycleIndicationContext* context,
221 _In_ MI_Instance* indicationToPost,
222 _In_ const MI_Instance* sourceInstance,
223 _In_ const MI_ClassDecl* classDecl )
224 {
225 MI_Result result = MI_RESULT_OK;
226 LifecycleContext* lifeContext = (LifecycleContext*)context;
227 SubscriptionManager* subMgr = lifeContext->provider->subMgr;
228
229 /* Basic validity checks to prevent unnecessary work: don't create the
230 * indication if there is no listener to receive it. */
231 if ( (MI_FALSE == SubMgr_IsEnabled ( subMgr )) ||
232 krisbash 1.1 (MI_TRUE == SubMgr_IsSubListEmpty ( subMgr )))
233 {
234 trace_LifecycleContext_Post_InvalidState();
235 return MI_RESULT_FAILED;
236 }
237
238 /* Create indication to post based on the input instance */
239
240 result = Instance_Construct( indicationToPost, classDecl, NULL );
241 if (MI_RESULT_OK != result)
242 {
243 trace_FailedToConstructInstance(tcs(classDecl->name));
244 return result;
245 }
246
247 result = _SetCommonProperties( indicationToPost, sourceInstance );
248 if (MI_RESULT_OK != result)
249 {
250 trace_FailedToSet_CommonProperties(tcs(classDecl->name));
251 return result;
252 }
253 krisbash 1.1
254 return result;
255 }
256
257 /*
258 * Wrapper for handling indications with no additional properties beyond
259 * those from CIM_Indication and CIM_InstIndication.
260 */
261 MI_Result _CommonPostSimple(
262 _In_ MI_LifecycleIndicationContext* context,
263 _In_ MI_Instance* indicationToPost,
264 _In_ const MI_Instance* sourceInstance,
265 _In_ const MI_ClassDecl* classDecl,
266 _In_ MI_Uint32 postTargetType )
267 {
268 MI_Result result = MI_RESULT_OK;
269
270 if (!context || !sourceInstance || ((LifecycleContext*)context)->magic != _LIFECYCLE_MAGIC)
271 {
272 trace_NullInputParameterForClass(tcs(classDecl->name));
273 return MI_RESULT_INVALID_PARAMETER;
274 krisbash 1.1 }
275
276 result = _CommonIndicationPrep( context, indicationToPost, sourceInstance, classDecl );
277 if (MI_RESULT_OK != result)
278 {
279 goto Lifecycle_CommonEnd;
280 }
281
282 result = _PostToAllSubscribers( ((LifecycleContext*)context)->provider->subMgr, indicationToPost, postTargetType );
283
284 Lifecycle_CommonEnd:
285 if (indicationToPost->ft)
286 {
287 MI_Instance_Destruct( indicationToPost );
288 }
289 return result;
290 }
291
292 MI_Result _PostCreate(
293 _In_ MI_LifecycleIndicationContext* context,
294 _In_ const MI_Instance* instance)
295 krisbash 1.1 {
296 CIM_InstCreation instCreation;
297
298 memset( &instCreation, 0, sizeof(CIM_InstCreation) );
299
300 return _CommonPostSimple( context, &instCreation.__instance, instance, &CIM_InstCreation_rtti, MI_LIFECYCLE_INDICATION_CREATE );
301 }
302
303 MI_Result _PostModify(
304 _In_ MI_LifecycleIndicationContext* context,
305 _In_ const MI_Instance* originalInstance,
306 _In_ const MI_Instance* instance)
307 {
308 MI_Result result = MI_RESULT_OK;
309 CIM_InstModification instModification;
310 MI_Value value;
311
312 if (!context || !originalInstance || !instance || ((LifecycleContext*)context)->magic != _LIFECYCLE_MAGIC)
313 {
314 trace_NullInputParameterForClass(tcs(CIM_InstModification_rtti.name));
315 return MI_RESULT_INVALID_PARAMETER;
316 krisbash 1.1 }
317
318 memset( &instModification, 0, sizeof(CIM_InstModification) );
319
320 result = _CommonIndicationPrep( context, &instModification.__instance, instance, &CIM_InstModification_rtti );
321 if (MI_RESULT_OK != result)
322 {
323 goto Lifecycle_ModifyEnd;
324 }
325
326 /* MI_ConstReferenceField PreviousInstance */
327 value.reference = (MI_Instance*)originalInstance;
328 result = MI_Instance_SetElement( &instModification.__instance, PAL_T("PreviousInstance"), &value, MI_INSTANCE, 0 );
329 if (MI_RESULT_OK != result)
330 {
331 trace_FailedToSet_PreviousInstance();
332 goto Lifecycle_ModifyEnd;
333 }
334
335 result = _PostToAllSubscribers( ((LifecycleContext*)context)->provider->subMgr, &instModification.__instance, MI_LIFECYCLE_INDICATION_MODIFY);
336
337 krisbash 1.1 Lifecycle_ModifyEnd:
338 if (instModification.__instance.ft)
339 {
340 MI_Instance_Destruct( &instModification.__instance );
341 }
342 return result;
343 }
344
345 MI_Result _PostDelete(
346 _In_ MI_LifecycleIndicationContext* context,
347 _In_ const MI_Instance* originalInstance)
348 {
349 CIM_InstDeletion instDeletion;
350
351 memset( &instDeletion, 0, sizeof(CIM_InstDeletion) );
352
353 return _CommonPostSimple( context, &instDeletion.__instance, originalInstance, &CIM_InstDeletion_rtti, MI_LIFECYCLE_INDICATION_DELETE );
354 }
355
356 MI_Result _PostRead(
357 _In_ MI_LifecycleIndicationContext* context,
358 krisbash 1.1 _In_ const MI_Instance* instance)
359 {
360 CIM_InstRead instRead;
361
362 memset( &instRead, 0, sizeof(CIM_InstRead) );
363
364 return _CommonPostSimple( context, &instRead.__instance, instance, &CIM_InstRead_rtti, MI_LIFECYCLE_INDICATION_READ );
365 }
366
367 MI_Result _PostMethodCall(
368 _In_ MI_LifecycleIndicationContext* context,
369 _In_ const MI_Instance* instance,
370 _In_z_ const MI_Char* methodName,
371 _In_ MI_Boolean precall,
372 _In_opt_ const MI_Instance* parameter,
373 _In_opt_z_ const MI_Char* returnvalue)
374 {
375 MI_Result result = MI_RESULT_OK;
376 CIM_InstMethodCall instMethodCall;
377 MI_Value value;
378
379 krisbash 1.1 if (!context || !instance || !methodName || ((LifecycleContext*)context)->magic != _LIFECYCLE_MAGIC)
380 {
381 trace_NullInputParameterForClass(tcs(CIM_InstMethodCall_rtti.name));
382 return MI_RESULT_INVALID_PARAMETER;
383 }
384
385 memset( &instMethodCall, 0, sizeof(CIM_InstMethodCall) );
386
387 result = _CommonIndicationPrep( context, &instMethodCall.__instance, instance, &CIM_InstMethodCall_rtti );
388 if (MI_RESULT_OK != result)
389 {
390 goto Lifecycle_MethodCallEnd;
391 }
392
393 /* MI_ConstStringField MethodName */
394 value.string = (MI_Char*)methodName;
395 result = MI_Instance_SetElement( &instMethodCall.__instance, PAL_T("MethodName"), &value, MI_STRING, 0 );
396 if (MI_RESULT_OK != result)
397 {
398 trace_FailedToSet_MethodName();
399 goto Lifecycle_MethodCallEnd;
400 krisbash 1.1 }
401
402 /* MI_ConstReferenceField MethodParameters */
403 value.reference = (MI_Instance*)parameter;
404 result = MI_Instance_SetElement( &instMethodCall.__instance, PAL_T("MethodParameters"), &value, MI_INSTANCE, 0 );
405 if (MI_RESULT_OK != result)
406 {
407 trace_FailedToSet_MethodParameters();
408 goto Lifecycle_MethodCallEnd;
409 }
410
411 /* MI_ConstStringField ReturnValue */
412 value.string = (MI_Char*)returnvalue;
413 result = MI_Instance_SetElement( &instMethodCall.__instance, PAL_T("ReturnValue"), &value, MI_STRING, 0 );
414 if (MI_RESULT_OK != result)
415 {
416 trace_FailedToSet_ReturnValue();
417 goto Lifecycle_MethodCallEnd;
418 }
419
420 /* MI_ConstBooleanField PreCall */
421 krisbash 1.1 value.boolean = precall;
422 result = MI_Instance_SetElement( &instMethodCall.__instance, PAL_T("PreCall"), &value, MI_BOOLEAN, 0 );
423 if (MI_RESULT_OK != result)
424 {
425 trace_FailedToSet_PreCall();
426 goto Lifecycle_MethodCallEnd;
427 }
428
429 result = _PostToAllSubscribers( ((LifecycleContext*)context)->provider->subMgr, &instMethodCall.__instance, MI_LIFECYCLE_INDICATION_METHODCALL);
430
431 Lifecycle_MethodCallEnd:
432 if (instMethodCall.__instance.ft)
433 {
434 MI_Instance_Destruct( &instMethodCall.__instance );
435 }
436 return result;
437 }
438
439 MI_Result _PostResult(
440 _In_ MI_LifecycleIndicationContext* context,
441 _In_ MI_Result result)
442 krisbash 1.1 {
443 LifecycleContext* lifeContext = (LifecycleContext*)context;
444
445 if (!context || lifeContext->magic != _LIFECYCLE_MAGIC)
446 {
447 trace_NullInputParameter();
448 return MI_RESULT_INVALID_PARAMETER;
449 }
450
451 trace_DisablingLifeCycleIndicationsForClass(tcs(lifeContext->provider->classDecl->name));
452
453 return Provider_TerminateIndication( lifeContext->provider, result, NULL, NULL );
454 }
455
456 // TODO: Only make this callable during provider load?
457 MI_Result MI_CALL _SetSupportedTypes(
458 _In_ MI_LifecycleIndicationContext* context,
459 _In_ MI_Uint32 types)
460 {
461 LifecycleContext* lifeContext = (LifecycleContext*)context;
462
463 krisbash 1.1 if (!context || lifeContext->magic != _LIFECYCLE_MAGIC)
464 {
465 trace_NullInputParameter();
466 return MI_RESULT_INVALID_PARAMETER;
467 }
468
469 lifeContext->supportedTypesFromProv = types;
470
471 return MI_RESULT_OK;
472 }
473
474 MI_Result _GetLifecycleIndicationTypes(
475 _In_ MI_LifecycleIndicationContext* context,
476 _Out_ MI_Uint32* types)
477 {
478 LifecycleContext* lifeContext = (LifecycleContext*)context;
479
480 if (!context || !types || lifeContext->magic != _LIFECYCLE_MAGIC)
481 {
482 trace_NullInputParameter();
483 return MI_RESULT_INVALID_PARAMETER;
484 krisbash 1.1 }
485
486 *types = lifeContext->supportedTypesFromProv;
487
488 return MI_RESULT_OK;
489 }
490
491 MI_Result _RegisterLifecycleCallback(
492 _In_ MI_LifecycleIndicationContext* context,
493 _In_ MI_LifecycleIndicationCallback callback,
494 _In_opt_ void* callbackData)
495 {
496 LifecycleContext* lifeContext = (LifecycleContext*)context;
497
498 if (!context || !callback || lifeContext->magic != _LIFECYCLE_MAGIC)
499 {
500 trace_NullInputParameter();
501 return MI_RESULT_INVALID_PARAMETER;
502 }
503
504 lifeContext->lifecycleCallback = callback;
505 krisbash 1.1 lifeContext->callbackData = callbackData;
506
507 return MI_RESULT_OK;
508 }
509
510 static MI_Result _ValidateContext(MI_LifecycleIndicationContext* self_)
511 {
512 LifecycleContext* lifeContext = (LifecycleContext*)self_;
513 if (!self_ || lifeContext->magic != _LIFECYCLE_MAGIC)
514 {
515 trace_NullInputParameter();
516 return MI_RESULT_INVALID_PARAMETER;
517 }
518 return MI_RESULT_OK;
519 }
520
521 static MI_Result MI_CALL _ConstructInstance(
522 MI_LifecycleIndicationContext* self_,
523 const MI_ClassDecl* classDecl,
524 MI_Instance* instance)
525 {
526 krisbash 1.1 MI_Result r = _ValidateContext(self_);
527 if (r == MI_RESULT_OK)
528 return Instance_Construct(instance, classDecl, NULL);
529 return r;
530 }
531
532 static MI_Result MI_CALL _ConstructParameters(
533 MI_LifecycleIndicationContext* self_,
534 const MI_MethodDecl* methodDecl,
535 MI_Instance* instance)
536 {
537 MI_Result r = _ValidateContext(self_);
538 if (r == MI_RESULT_OK)
539 return Parameters_Init(instance, methodDecl, NULL);
540 return r;
541 }
542
543 static MI_Result MI_CALL _NewInstance(
544 MI_LifecycleIndicationContext* self_,
545 const MI_ClassDecl* classDecl,
546 MI_Instance** instance)
547 krisbash 1.1 {
548 MI_Result r = _ValidateContext(self_);
549 if (r == MI_RESULT_OK)
550 return Instance_New(instance, classDecl, NULL);
551 return r;
552 }
553
554 static MI_Result MI_CALL _NewDynamicInstance(
555 MI_LifecycleIndicationContext* self_,
556 const ZChar* className,
557 MI_Uint32 flags,
558 MI_Instance** instance)
559 {
560 MI_Result r = _ValidateContext(self_);
561 if (r == MI_RESULT_OK)
562 return Instance_NewDynamic(instance, className, flags, NULL);
563 return r;
564 }
565
566 static MI_Result MI_CALL _NewParameters(
567 MI_LifecycleIndicationContext* self_,
568 krisbash 1.1 const MI_MethodDecl* methodDecl,
569 MI_Instance** instance)
570 {
571
572 return Parameters_New(instance, methodDecl, NULL);
573 }
574
575 MI_LifecycleIndicationContextFT __mi_lifecycle_contextFT =
576 {
577 _PostCreate,
578 _PostModify,
579 _PostDelete,
580 _PostRead,
581 _PostMethodCall,
582 _PostResult,
583 _ConstructInstance,
584 _ConstructParameters,
585 _NewInstance,
586 _NewDynamicInstance,
587 _NewParameters,
588 _SetSupportedTypes,
589 krisbash 1.1 _GetLifecycleIndicationTypes,
590 _RegisterLifecycleCallback
591 };
592
593 LifecycleContext* LifeContext_New()
594 {
595 LifecycleContext* context = (LifecycleContext*)PAL_Calloc(1, sizeof(LifecycleContext));
596 if (!context)
597 LOGD_ALLOC_OOM;
598 return context;
599 }
600
601 _Use_decl_annotations_
602 void LifeContext_Delete(
603 LifecycleContext* context )
604 {
605 if (context)
606 {
607 memset(context, 0xFF, sizeof(LifecycleContext));
608 PAL_Free(context);
609 }
610 krisbash 1.1 }
611
612 _Use_decl_annotations_
613 void LifeContext_Init(
614 LifecycleContext* context,
615 Provider* provider )
616 {
617 DEBUG_ASSERT ( provider && provider->subMgr );
618
619 context->base.ft = &__mi_lifecycle_contextFT;
620 context->magic = _LIFECYCLE_MAGIC;
621 context->provider = provider;
622 context->supportedTypesFromProv = MI_LIFECYCLE_INDICATION_ALL;
623 }
624
625 /*
626 * Converts SubscriptionTargetType enum values to bit flags that are compatible
627 * with the MI API's type field.
628 */
629 _Use_decl_annotations_
630 MI_Uint32 LifeContext_ConvertSupportedType(
631 krisbash 1.1 SubscriptionTargetType type )
632 {
633 MI_Uint32 miType = MI_LIFECYCLE_INDICATION_NONE;
634 switch(type)
635 {
636 case SUBSCRIP_TARGET_LIFECYCLE_CREATE:
637 miType = MI_LIFECYCLE_INDICATION_CREATE;
638 break;
639 case SUBSCRIP_TARGET_LIFECYCLE_MODIFY:
640 miType = MI_LIFECYCLE_INDICATION_MODIFY;
641 break;
642 case SUBSCRIP_TARGET_LIFECYCLE_DELETE:
643 miType = MI_LIFECYCLE_INDICATION_DELETE;
644 break;
645 case SUBSCRIP_TARGET_LIFECYCLE_READ:
646 miType = MI_LIFECYCLE_INDICATION_READ;
647 break;
648 case SUBSCRIP_TARGET_LIFECYCLE_METHODCALL:
649 miType = MI_LIFECYCLE_INDICATION_METHODCALL;
650 break;
651 case SUBSCRIP_TARGET_LIFECYCLE_ALL:
652 krisbash 1.1 miType = MI_LIFECYCLE_INDICATION_ALL;
653 break;
654 /* Fallthorugh intentional */
655 case SUBSCRIP_TARGET_UNSUPPORTED:
656 case SUBSCRIP_TARGET_DEFAULT:
657 default:
658 miType = MI_LIFECYCLE_INDICATION_NONE;
659 }
660 return miType;
661 }
662
663 /*
664 * In this check, any requested bits that are not supported will get zeroed,
665 * causing the comparison against the original value to fail.
666 */
667 _Use_decl_annotations_
668 MI_Boolean LifeContext_IsTypeSupported(
669 LifecycleContext* context,
670 MI_Uint32 supportedTypeToCheck )
671 {
672 MI_Uint32 convertedToMiType = LifeContext_ConvertSupportedType( supportedTypeToCheck );
673 krisbash 1.1
674 if ( MI_LIFECYCLE_INDICATION_NONE == context->supportedTypesFromProv ||
675 MI_LIFECYCLE_INDICATION_NONE == convertedToMiType )
676 {
677 return MI_FALSE;
678 }
679
680 if ( context->supportedTypesFromProv & convertedToMiType )
681 {
682 return MI_TRUE;
683 }
684 else
685 {
686 return MI_FALSE;
687 }
688 }
689
690 // TODO: return result here and check against the provider's advertised type.
691 _Use_decl_annotations_
692 void LifeContext_UpdateSupportedTypes(
693 LifecycleContext* context )
694 krisbash 1.1 {
695 MI_Uint32 indicationType = MI_LIFECYCLE_INDICATION_NONE;
696 SubscriptionManager* subMgr = NULL;
697 SubMgrSubscription* sub = NULL;
698
699 if (NULL == context->lifecycleCallback)
700 {
701 return;
702 }
703
704 /* Iterate through the subscriptions and gather the various subscriptions
705 * additively. */
706 subMgr = context->provider->subMgr;
707 for (sub = (SubMgrSubscription*)subMgr->subscrList.head; sub; sub = sub->next)
708 {
709 indicationType |= LifeContext_ConvertSupportedType( sub->msg->targetType );
710 if (MI_LIFECYCLE_INDICATION_ALL == indicationType)
711 {
712 break; /* All bits are set. There is no point to continuing the search. */
713 }
714 }
715 krisbash 1.1
716 if (indicationType != context->supportedTypesAggr)
717 {
718 /* A change in registration occurred, so notify the provider. */
719 context->supportedTypesAggr = indicationType;
720
721 context->lifecycleCallback( indicationType, context->callbackData );
722 }
723 }
724
|