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

  1 mike  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 mike  1.1 **==============================================================================
 23           */
 24           
 25           #include "context.h"
 26 mike  1.3 #include <wsman/wsbuf.h>
 27 mike  1.1 #include <wql/wql.h>
 28           
 29           static const MI_Uint32 _MAGIC = 0x35eb3d3b;
 30           
 31           static MI_Result _ProcessResult(
 32               MI_Context* self_,
 33               MI_Result result,
 34               const MI_Char* message,
 35               const MI_Instance* error)
 36           {
 37               Context* self = (Context*)self_;
 38           
 39               if (!self || self->magic != _MAGIC)
 40                   return MI_RESULT_INVALID_PARAMETER;
 41           
 42               LOGD_CHAR(("post result from provider, %d", (int)result));
 43           
 44               /* If no instances matched during GetInstance over EnumerateInstance */
 45               if (self->instanceName && !self->matchedInstanceName)
 46               {
 47                   if (result == MI_RESULT_OK)
 48 mike  1.1             result = MI_RESULT_NOT_FOUND;
 49               }
 50           
 51               message = message;
 52               error = error;
 53           
 54               if (self->request && !self->cancelled)
 55               {
 56                   PostResultMsg* resp = PostResultMsg_New( self->request ? self->request->msgID : 0 );
 57           
 58                   if (!resp)
 59                       return MI_RESULT_FAILED;
 60           
 61                   resp->result = result;
 62                   Message_SetRequest(&resp->base,self->request);
 63                   (*self->request->callback)(&resp->base, self->request->callbackData);
 64                   PostResultMsg_Release(resp);
 65               }
 66           
 67               if (self->result)
 68                   *self->result = result;
 69 mike  1.1 
 70               /* destory context */
 71               Context_Destroy(self);
 72           
 73               return MI_RESULT_OK;
 74           }
 75           
 76           static MI_Boolean _FilterProperty(const MI_Char* name, void *data)
 77           {
 78               WQL* wql = (WQL*)data;
 79           
 80               if (WQL_ContainsProperty(wql, name))
 81                   return MI_FALSE;
 82               else
 83                   return MI_TRUE;
 84           }
 85           
 86           static MI_Result _PostInstanceToCallback(
 87               Context* self,
 88               const MI_Instance* instance)
 89           {
 90 mike  1.1     PostInstanceMsg* resp = PostInstanceMsg_New(self->request->msgID);
 91           
 92               if (!resp)
 93                   return MI_RESULT_FAILED;
 94           
 95               if (self->request->flags & WSMANFlag)
 96               {
 97                   const MI_ClassDecl* castToClassDecl = 0;
 98           
 99                   /* Enumerate response with 'base-properties-only' option 
100                       may require instance conversion */
101                   if (EnumerateInstancesReqTag == self->request->tag)
102                   {
103                       EnumerateInstancesReq* req = (EnumerateInstancesReq*)self->request;
104           
105                       if (req->requestClassName)
106                       {
107                           castToClassDecl = instance->classDecl;
108           
109                           while (castToClassDecl && 
110                               Zcasecmp(req->requestClassName, castToClassDecl->name) != 0)
111 mike  1.1                 {
112                               castToClassDecl = castToClassDecl->superClassDecl;
113                           }
114                       }
115                   }
116           
117                   {
118                       EnumerateInstancesReq* req = NULL;
119           
120                       if (EnumerateInstancesReqTag == self->request->tag)
121                           req = (EnumerateInstancesReq*)self->request;
122           
123                       if (req && req->wql)
124                       {
125                           WSBuf_InstanceToBuf(
126                               instance,
127                               _FilterProperty,
128                               req->wql,
129                               castToClassDecl,
130                               resp->base.batch, 
131                               self->request->flags,
132 mike  1.1                     &resp->packedInstancePtr, 
133                               &resp->packedInstanceSize);
134                       }
135                       else
136                       {
137                           WSBuf_InstanceToBuf(
138                               instance,
139                               NULL, /* filterProperty */
140                               NULL, /* filterPropertyData */
141                               castToClassDecl,
142                               resp->base.batch, 
143                               self->request->flags,
144                               &resp->packedInstancePtr, 
145                               &resp->packedInstanceSize);
146                       }
147                   }
148           
149                   resp->base.flags |= self->request->flags;
150               }
151               else
152               {
153 mike  1.1         EnumerateInstancesReq* req = NULL;
154           
155                   if (EnumerateInstancesReqTag == self->request->tag)
156                       req = (EnumerateInstancesReq*)self->request;
157           
158                   if (req && req->wql)
159                   {
160                       InstanceToBatch(instance, _FilterProperty, req->wql, 
161                           resp->base.batch, &resp->packedInstancePtr, 
162                           &resp->packedInstanceSize);
163                   }
164                   else
165                   {
166                       InstanceToBatch(instance, NULL, NULL, resp->base.batch, 
167                           &resp->packedInstancePtr, &resp->packedInstanceSize);
168                   }
169           
170                   resp->base.flags |= BinaryProtocolFlag;
171               }
172           
173               /* count message in for back-pressure feature (only Instances) */
174 mike  1.1     if (self->provider)
175                   Provider_NewInstanceCreated(self->provider, &resp->base);
176           
177           
178               Message_SetRequest(&resp->base,self->request);
179               (*self->request->callback)(&resp->base, self->request->callbackData);
180               PostInstanceMsg_Release(resp);
181           
182               return MI_RESULT_OK;
183           }
184           
185           /* successfully received instance from 'gi' - call invoke with this instance now */
186           static void _CallInvoke(
187               Context* self,
188               const MI_Instance* instance)
189           {
190               Context* ctx = (Context*)Batch_GetClear(self->request->batch, sizeof(Context));;
191           
192               Context_Init(ctx, self->provider);
193           
194               ctx->request = self->request;
195 mike  1.1     /* message will be freed in context release*/
196               Message_AddRef(ctx->request);
197           
198               /* disregard all other messages for this context */
199               self->cancelled = MI_TRUE;
200               /* ATTN! clone instance, since invoke can overlive instance (if it's async)!!! */
201               (*self->md->function)(self->prov_self, &ctx->base, 
202                   __nameSpace, __className, __methodName, instance, self->instParams);
203           }
204           
205           
206           static MI_Result MI_CALL _PostResult(
207               MI_Context* self_,
208               MI_Result result)
209           {
210               return _ProcessResult(self_, result, 0, 0);
211           }
212           
213           static MI_Result MI_CALL _PostResultWithMessage(
214               MI_Context* self_,
215               MI_Result result,
216 mike  1.1     const MI_Char* message)
217           {
218               return _ProcessResult(self_, result, message, 0);
219           }
220           
221           
222           static MI_Result MI_CALL _PostResultWithError(
223               _In_ MI_Context* self_,
224               MI_Result result,
225               _In_ const MI_Instance* error)
226           {
227               return _ProcessResult(self_, result, 0, error);
228           }
229           
230           static MI_Result MI_CALL _PostInstance(
231               MI_Context* self_,
232               const MI_Instance* instance)
233           {
234               Context* self = (Context*)self_;
235           
236               if (!self || self->magic != _MAGIC || !instance)
237 mike  1.1         return MI_RESULT_INVALID_PARAMETER;
238           
239               if (self->request && !self->cancelled)
240               {
241                   if (self->instanceName == NULL)
242                   {
243                       if (CTX_TYPE_INVOKE_WITH_INSTANCE == self->chainType)
244                       {
245                           _CallInvoke(self, instance);
246                           return MI_RESULT_OK;
247                       }
248                       else if (EnumerateInstancesReqTag == self->request->tag)
249                       {
250                           EnumerateInstancesReq* req = 
251                               (EnumerateInstancesReq*)self->request;
252           
253                           if (req->wql)
254                           {
255                               int r;
256           
257                               r = WQL_Eval(req->wql, WQL_LookupInstanceProperty, 
258 mike  1.1                         (void*)instance);
259           
260                               if (r == 0)
261                               {
262                                   /* Instance matched the query */
263                                   return _PostInstanceToCallback(self, instance);
264                               }
265                               else
266                               {
267                                   /* Mismatch or failure */
268                                   return MI_RESULT_OK;
269                               }
270                           }
271                       }
272           
273                       return _PostInstanceToCallback(self, instance);
274                   }
275                   else if (Instance_MatchKeys(instance, self->instanceName))
276                   {
277                       /* Handle GetInstance through EnumerateInstances */
278                       if (!self->matchedInstanceName)
279 mike  1.1             {
280                           self->matchedInstanceName = MI_TRUE;
281                           return _PostInstanceToCallback(self, instance);
282                       }
283                   }
284               }
285           
286               return MI_RESULT_OK;
287           }
288           
289           static MI_Result MI_CALL _ConstructInstance(
290               MI_Context* self_,
291               const MI_ClassDecl* classDecl,
292               MI_Instance* instance)
293           {
294               Context* self = (Context*)self_;
295           
296               if (!self || self->magic != _MAGIC || !instance || !classDecl)
297                   return MI_RESULT_INVALID_PARAMETER;
298           
299               return Instance_Construct(instance, classDecl, self->request->batch);
300 mike  1.1 }
301           
302           static MI_Result MI_CALL _ConstructParameters(
303               MI_Context* self_,
304               const MI_MethodDecl* methodDecl,
305               MI_Instance* instance)
306           {
307               Context* self = (Context*)self_;
308           
309               if (!self || self->magic != _MAGIC || !instance || !methodDecl)
310                   return MI_RESULT_INVALID_PARAMETER;
311           
312               return Parameters_Init(instance, methodDecl, self->request->batch);
313           }
314           
315           static MI_Result MI_CALL _NewInstance(
316               MI_Context* self_,
317               const MI_ClassDecl* classDecl,
318               MI_Instance** instance)
319           {
320               Context* self = (Context*)self_;
321 mike  1.1 
322               if (!self || self->magic != _MAGIC || !classDecl || !instance)
323                   return MI_RESULT_INVALID_PARAMETER;
324           
325               return Instance_New(instance, classDecl, self->request->batch);
326           }
327           
328           static MI_Result MI_CALL _NewDynamicInstance(
329               MI_Context* self_,
330               const MI_Char* className,
331               MI_Uint32 flags,
332               MI_Instance** instance)
333           {
334               Context* self = (Context*)self_;
335           
336               if (!self || self->magic != _MAGIC || !className || !instance)
337                   return MI_RESULT_INVALID_PARAMETER;
338           
339               return Instance_NewDynamic(instance, className, flags, 
340                   self->request->batch);
341           }
342 mike  1.1 
343           static MI_Result MI_CALL _NewParameters(
344               MI_Context* self_,
345               const MI_MethodDecl* methodDecl,
346               MI_Instance** instance)
347           {
348               Context* self = (Context*)self_;
349           
350               if (!self || self->magic != _MAGIC || !methodDecl || !instance)
351                   return MI_RESULT_INVALID_PARAMETER;
352           
353               return Parameters_New(instance, methodDecl, self->request->batch);
354           }
355           
356           static MI_Result MI_CALL _Canceled(
357               const MI_Context* self_,
358               MI_Boolean* flag)
359           {
360               Context* self = (Context*)self_;
361           
362               if (!self || self->magic != _MAGIC || !flag)
363 mike  1.1         return MI_RESULT_INVALID_PARAMETER;
364           
365               *flag = self->cancelled;
366               return MI_RESULT_OK;
367           }
368           
369           static MI_Result MI_CALL _PostIndication(
370               MI_Context* context,
371               const MI_Instance* indication,
372               MI_Uint32 subscriptionIDCount,
373               const MI_Char* bookmark)
374           {
375               /* ATTN: just use _PostInstance() for now */
376               MI_UNUSED(subscriptionIDCount);
377               MI_UNUSED(bookmark);
378               return _PostInstance(context, indication);
379           }
380           
381           static MI_Result MI_CALL _GetLocale(
382               const MI_Context* context,
383               MI_LocaleType localeType,
384 mike  1.1     MI_Char locale[MI_MAX_LOCALE_SIZE])
385           {
386               return MI_RESULT_NOT_SUPPORTED;
387           }
388           
389           static MI_Result MI_CALL _RegisterCancel(
390               MI_Context* context,
391               MI_CancelCallback callback,
392               void* callbackData)
393           {
394               return MI_RESULT_NOT_SUPPORTED;
395           }
396           
397           static MI_Result MI_CALL _RequestUnload(
398               MI_Context* self_)
399           {
400               Context* self = (Context*)self_;
401           
402               if (!self || self->magic != _MAGIC || !self->provider)
403                   return MI_RESULT_INVALID_PARAMETER;
404           
405 mike  1.1     Provider_SetRefuseUnloadFlag(self->provider, MI_FALSE);
406               return MI_RESULT_OK;
407           }
408           
409           static MI_Result MI_CALL _RefuseUnload(
410               MI_Context* self_)
411           {
412               Context* self = (Context*)self_;
413           
414               if (!self || self->magic != _MAGIC || !self->provider)
415                   return MI_RESULT_INVALID_PARAMETER;
416           
417               Provider_SetRefuseUnloadFlag(self->provider, MI_TRUE);
418               return MI_RESULT_OK;
419           }
420           
421           static MI_Result _GetLocalSession(
422               _In_ const MI_Context* context,
423               _Out_ MI_Session* session)
424           {
425               return MI_RESULT_NOT_SUPPORTED;
426 mike  1.1 }
427           
428           static MI_Result _SetStringOption(
429               _In_ MI_Context* context,
430               _In_z_ const MI_Char* name,
431               _In_z_ const MI_Char* value)
432           {
433               return MI_RESULT_NOT_SUPPORTED;
434           }
435           
436           static MI_Result _GetStringOption(
437               _In_  MI_Context* context,
438               _In_z_ const MI_Char* name,
439               _Outptr_result_z_  const MI_Char** value)
440           {
441               return MI_RESULT_NOT_SUPPORTED;
442           }
443           
444           static MI_Result _GetNumberOption(
445               _In_  MI_Context* context,
446               _In_z_ const MI_Char *name,
447 mike  1.1     _Out_opt_  MI_Uint32* value)
448           {
449               return MI_RESULT_NOT_SUPPORTED;
450           }      
451           
452           static MI_Result _GetCustomOption(
453               _In_  MI_Context* context,
454               _In_z_ const MI_Char* name,
455               _Out_opt_  MI_Type* valueType,
456               _Out_opt_  MI_Value* value)
457           {
458               return MI_RESULT_NOT_SUPPORTED;
459           }
460           
461           static MI_Result _GetCustomOptionCount(
462               _In_  MI_Context* context,
463               _Out_opt_ MI_Uint32* count)
464           {
465               return MI_RESULT_NOT_SUPPORTED;
466           }
467           
468 mike  1.1 static MI_Result _GetCustomOptionAt(
469               _In_  MI_Context* context,
470               _In_ MI_Uint32 index,
471               _Outptr_opt_result_maybenull_z_  const MI_Char** name,
472               _Out_opt_  MI_Type* valueType,
473               _Out_opt_  MI_Value* value)
474           {
475               return MI_RESULT_NOT_SUPPORTED;
476           }    
477           
478           static MI_Result _WriteMessage(
479               _In_ MI_Context* context,
480               MI_Uint32 channel,
481               _In_z_ const MI_Char* message)
482           {
483               return MI_RESULT_NOT_SUPPORTED;
484           }
485           
486           static MI_Result _WriteProgress(
487               _In_ MI_Context* context,
488               _In_z_ const MI_Char* activity,
489 mike  1.1     _In_z_ const MI_Char* currentOperation,
490               _In_z_ const MI_Char* statusDescription,
491               MI_Uint32 percentComplete,
492               MI_Uint32 secondsRemaining)
493           {
494               return MI_RESULT_NOT_SUPPORTED;
495           }
496           
497           static MI_Result _WriteStreamParameter(
498               _In_ MI_Context* context,
499               _In_z_ const MI_Char* name,
500               _In_ const MI_Value* value,
501               _In_ MI_Type type,
502               _In_ MI_Uint32 flags)
503           {
504               return MI_RESULT_NOT_SUPPORTED;
505           }
506           
507           static MI_Result _WriteCimError(
508               _In_ MI_Context* context,
509               _In_ const MI_Instance *error,
510 mike  1.1     _Out_ MI_Boolean *flag)
511           {
512               return MI_RESULT_NOT_SUPPORTED;
513           }     
514           
515           static MI_Result _PromptUser(
516               _In_ MI_Context* context,
517               _In_z_ const MI_Char* message, 
518               MI_PromptType promptType,
519               _Out_ MI_Boolean* result)
520           {
521               return MI_RESULT_NOT_SUPPORTED;
522           }    
523           
524           static MI_Result _ShouldProcess(
525               _In_ MI_Context* context,
526               _In_z_ const MI_Char* target,
527               _In_z_ const MI_Char* action,
528               _Out_ MI_Boolean* result)
529           {
530               return MI_RESULT_NOT_SUPPORTED;
531 mike  1.1 }
532           
533           static MI_Result _ShouldContinue(
534               _In_ MI_Context* context,
535               _In_z_ const MI_Char* message,
536               _Out_ MI_Boolean* result)
537           {
538               return MI_RESULT_NOT_SUPPORTED;
539           } 
540           
541           static MI_Result _PostError(
542               _In_ MI_Context* context,
543               MI_Uint32 resultCode,
544               _In_z_ const MI_Char* resultType,
545               _In_z_ const MI_Char* errorMessage)
546           {
547               return MI_RESULT_NOT_SUPPORTED;
548           }
549           
550           static MI_Result _PostCimError(
551               _In_ MI_Context* context,
552 mike  1.1     _In_ const MI_Instance *error)
553           {
554               return MI_RESULT_NOT_SUPPORTED;
555           }  
556           
557           static MI_Result _WriteError(
558               _In_ MI_Context* context,
559               MI_Uint32 resultCode,
560               _In_z_ const MI_Char* resultType,
561               _In_z_ const MI_Char* errorMessage,
562               _Out_ MI_Boolean *flag)
563           {
564               return MI_RESULT_NOT_SUPPORTED;
565           }
566           
567           MI_ContextFT __mi_contextFT =
568           {
569               _PostResult,
570               _PostResultWithMessage,
571               _PostResultWithError,
572               _PostInstance,
573 mike  1.1     _PostIndication,
574               _ConstructInstance,
575               _ConstructParameters,
576               _NewInstance,
577               _NewDynamicInstance,
578               _NewParameters,
579               _Canceled,
580               _GetLocale,
581               _RegisterCancel,
582               _RequestUnload,
583               _RefuseUnload,
584               _GetLocalSession,
585               _SetStringOption,
586               _GetStringOption,
587               _GetNumberOption,
588               _GetCustomOption,
589               _GetCustomOptionCount,
590               _GetCustomOptionAt,
591               _WriteMessage,
592               _WriteProgress,
593               _WriteStreamParameter,
594 mike  1.1     _WriteCimError,
595               _PromptUser,
596               _ShouldProcess,
597               _ShouldContinue,
598               _PostError,
599               _PostCimError,
600               _WriteError,
601           };
602           
603           void Context_Init(
604               Context* self,
605               Provider*   provider)
606           {
607               memset(self, 0, sizeof(Context));
608               self->base.ft = &__mi_contextFT;
609               self->magic = _MAGIC;
610               self->provider = provider;
611               Provider_Addref(self->provider);
612           }
613           
614           void Context_Destroy(
615 mike  1.1     Context* self)
616           {
617               Message* req = self ? self->request : 0;
618           
619               if (self)
620                   Provider_Release(self->provider);
621           
622               memset(self, -1, sizeof(Context));
623           
624               /* Context typ[ically allocated from message's batch
625                   so it may be freed right inside 'Release' call */
626               if (req)
627                   Message_Release(req);
628           }

ViewCVS 0.9.2