(file) Return to LifecycleContext.c CVS log (file) (dir) Up to [OMI] / omi / provmgr

  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              

ViewCVS 0.9.2