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