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 "messages.h"
26 #include "packing.h"
27 #include <assert.h>
28 #include "result.h"
29 #include "io.h"
30
31 /*
32 **==============================================================================
33 **
34 ** Local definitions
35 **
36 **==============================================================================
37 */
38
39 typedef enum _FieldType
40 {
41 FT_BOOLEAN = MI_BOOLEAN,
42 FT_UINT8 = MI_UINT8,
43 mike 1.1 FT_SINT8 = MI_SINT8,
44 FT_UINT16 = MI_UINT16,
45 FT_SINT16 = MI_SINT16,
46 FT_UINT32 = MI_UINT32,
47 FT_SINT32 = MI_SINT32,
48 FT_UINT64 = MI_UINT64,
49 FT_SINT64 = MI_SINT64,
50 FT_REAL32 = MI_REAL32,
51 FT_REAL64 = MI_REAL64,
52 FT_CHAR16 = MI_CHAR16,
53 FT_DATETIME = MI_DATETIME,
54 FT_STRING = MI_STRING,
55 FT_REFERENCE = MI_REFERENCE,
56 FT_INSTANCE = MI_INSTANCE,
57 FT_BOOLEANA = MI_BOOLEANA,
58 FT_UINT8A = MI_UINT8A,
59 FT_SINT8A = MI_SINT8A,
60 FT_UINT16A = MI_UINT16A,
61 FT_SINT16A = MI_SINT16A,
62 FT_UINT32A = MI_UINT32A,
63 FT_SINT32A = MI_SINT32A,
64 mike 1.1 FT_UINT64A = MI_UINT64A,
65 FT_SINT64A = MI_SINT64A,
66 FT_REAL32A = MI_REAL32A,
67 FT_REAL64A = MI_REAL64A,
68 FT_CHAR16A = MI_CHAR16A,
69 FT_DATETIMEA = MI_DATETIMEA,
70 FT_STRINGA = MI_STRINGA,
71 FT_REFERENCEA = MI_REFERENCEA,
72 FT_INSTANCEA = MI_INSTANCEA,
73 FT_RESULT,
74 FT_ATOMIC
75 }
76 FieldType;
77
78 /* Defines meta data for message field (to support printing) */
79 typedef struct Field
80 {
81 /* Name of field */
82 const char* name;
83
84 /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
85 mike 1.1 FieldType type;
86
87 /* Byte off within structure to this field */
88 size_t off;
89 }
90 Field;
91
92 typedef enum _MessageFieldType
93 {
94 MFT_END_OF_LIST, /* special type to terminate list of fields */
95 MFT_POINTER, /* Pointer that has to be converted */
96 MFT_POINTER_OPT, /* Pointer that has to be converted (may be null) */
97 MFT_POINTER_SET_NULL, /* Pointer that has to be nullified instead of converting */
98 MFT_INSTANCE, /* instance */
99 MFT_INSTANCE_OPT /* instance (maybe NULL) */
100 }
101 MessageFieldType;
102
103 /* Defines meta data for message field (to support packing/unpacking) */
104 typedef struct _MessageField
105 {
106 mike 1.1 /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */
107 MessageFieldType type;
108
109 /* Byte off within structure to this field and (for instance) to packed pointer/size */
110 size_t off;
111 size_t offPackedPtr;
112 size_t offPackedSize;
113 }
114 MessageField;
115
116 static const MessageField baseMessageFields[] =
117 {
118 {MFT_POINTER_SET_NULL,offsetof(Message, next),0,0},
119 {MFT_POINTER_SET_NULL,offsetof(Message, prev),0,0},
120 {MFT_POINTER_SET_NULL,offsetof(Message, request),0,0},
121 {MFT_POINTER_SET_NULL,offsetof(Message, callback),0,0},
122 {MFT_POINTER_SET_NULL,offsetof(Message, callbackData),0,0},
123 {MFT_POINTER_SET_NULL,offsetof(Message, dtor),0,0},
124 {MFT_POINTER_SET_NULL,offsetof(Message, dtorData),0,0},
125 {MFT_POINTER_OPT,offsetof(Message, libraryName),0,0},
126 {MFT_END_OF_LIST, 0, 0, 0}
127 mike 1.1 };
128
129 static const MessageField emptyMessageFields[] =
130 {
131 {MFT_END_OF_LIST, 0, 0, 0}
132 };
133
134 static const MessageField getInstanceMessageFields[] =
135 {
136 {MFT_POINTER,offsetof(GetInstanceReq, nameSpace),0,0},
137 {MFT_INSTANCE,offsetof(GetInstanceReq, instanceName),offsetof(GetInstanceReq, packedInstanceNamePtr),offsetof(GetInstanceReq, packedInstanceNameSize)},
138 {MFT_END_OF_LIST, 0, 0, 0}
139 };
140
141 static const MessageField postInstanceMessageFields[] =
142 {
143 {MFT_INSTANCE,offsetof(PostInstanceMsg, instance),offsetof(PostInstanceMsg, packedInstancePtr),offsetof(PostInstanceMsg, packedInstanceSize)},
144 {MFT_END_OF_LIST, 0, 0, 0}
145 };
146
147 static const MessageField enumerateInstancesMessageFields[] =
148 mike 1.1 {
149 {MFT_POINTER,offsetof(EnumerateInstancesReq, nameSpace),0,0},
150 {MFT_POINTER,offsetof(EnumerateInstancesReq, className),0,0},
151 {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, requestClassName),0,0},
152 {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryLanguage),0,0},
153 {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryExpression),0,0},
154 {MFT_END_OF_LIST, 0, 0, 0}
155 };
156
157 static const MessageField invokeMessageFields[] =
158 {
159 {MFT_POINTER,offsetof(InvokeReq, nameSpace),0,0},
160 {MFT_POINTER,offsetof(InvokeReq, function),0,0},
161 {MFT_POINTER_OPT,offsetof(InvokeReq, className),0,0},
162 {MFT_INSTANCE_OPT,offsetof(InvokeReq, instance),offsetof(InvokeReq, packedInstancePtr),offsetof(InvokeReq, packedInstanceSize)},
163 {MFT_INSTANCE_OPT,offsetof(InvokeReq, instanceParams),offsetof(InvokeReq, packedInstanceParamsPtr),offsetof(InvokeReq, packedInstanceParamsSize)},
164 {MFT_END_OF_LIST, 0, 0, 0}
165 };
166
167 static const MessageField associatorsOfMessageFields[] =
168 {
169 mike 1.1 {MFT_POINTER,offsetof(AssociatorsOfReq, nameSpace),0,0},
170 {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, className),0,0},
171 {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, assocClass),0,0},
172 {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultClass),0,0},
173 {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, role),0,0},
174 {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultRole),0,0},
175 {MFT_INSTANCE,offsetof(AssociatorsOfReq, instance),offsetof(AssociatorsOfReq, packedInstancePtr),offsetof(AssociatorsOfReq, packedInstanceSize)},
176 {MFT_END_OF_LIST, 0, 0, 0}
177 };
178
179 static const MessageField referencesOfMessageFields[] =
180 {
181 {MFT_POINTER,offsetof(ReferencesOfReq, nameSpace),0,0},
182 {MFT_POINTER_OPT,offsetof(ReferencesOfReq, className),0,0},
183 {MFT_POINTER_OPT,offsetof(ReferencesOfReq, assocClass),0,0},
184 {MFT_POINTER_OPT,offsetof(ReferencesOfReq, role),0,0},
185 {MFT_INSTANCE,offsetof(ReferencesOfReq, instance),offsetof(ReferencesOfReq, packedInstancePtr),offsetof(ReferencesOfReq, packedInstanceSize)},
186 {MFT_END_OF_LIST, 0, 0, 0}
187 };
188
189 static const MessageField subscribeRequestMessageFields[] =
190 mike 1.1 {
191 {MFT_POINTER,offsetof(SubscribeReq, nameSpace),0,0},
192 {MFT_POINTER,offsetof(SubscribeReq, className),0,0},
193 {MFT_POINTER,offsetof(SubscribeReq, filter),0,0},
194 {MFT_POINTER,offsetof(SubscribeReq, language),0,0},
195 {MFT_END_OF_LIST, 0, 0, 0}
196 };
197
198 static const MessageField subscribeResponseMessageFields[] =
199 {
200 {MFT_POINTER,offsetof(SubscribeRes, subscriptionID),0,0},
201 {MFT_END_OF_LIST, 0, 0, 0}
202 };
203
204 static const MessageField deleteInstanceMessageFields[] =
205 {
206 {MFT_POINTER,offsetof(DeleteInstanceReq, nameSpace),0,0},
207 {MFT_INSTANCE,offsetof(DeleteInstanceReq, instanceName),offsetof(DeleteInstanceReq, packedInstanceNamePtr),offsetof(DeleteInstanceReq, packedInstanceNameSize)},
208 {MFT_END_OF_LIST, 0, 0, 0}
209 };
210
211 mike 1.1 static const MessageField createInstanceMessageFields[] =
212 {
213 {MFT_POINTER,offsetof(CreateInstanceReq, nameSpace),0,0},
214 {MFT_INSTANCE,offsetof(CreateInstanceReq, instance),offsetof(CreateInstanceReq, packedInstancePtr),offsetof(CreateInstanceReq, packedInstanceSize)},
215 {MFT_END_OF_LIST, 0, 0, 0}
216 };
217
218 static const MessageField modifyInstanceMessageFields[] =
219 {
220 {MFT_POINTER,offsetof(ModifyInstanceReq, nameSpace),0,0},
221 {MFT_INSTANCE,offsetof(ModifyInstanceReq, instance),offsetof(ModifyInstanceReq, packedInstancePtr),offsetof(ModifyInstanceReq, packedInstanceSize)},
222 {MFT_END_OF_LIST, 0, 0, 0}
223 };
224
225 static const MessageField binProtocolNotificationFields[] =
226 {
227 {MFT_POINTER_OPT,offsetof(BinProtocolNotification, user),0,0},
228 {MFT_POINTER_OPT,offsetof(BinProtocolNotification, password),0,0},
229 {MFT_POINTER_OPT,offsetof(BinProtocolNotification, authFile),0,0},
230 {MFT_END_OF_LIST, 0, 0, 0}
231 };
232 mike 1.1
233 /* Entries in this array corresponds to MessageTag values:
234 GetInstanceReqTag = 1,
235 PostInstanceMsgTag = 2,
236 EnumerateInstancesReqTag = 3,
237 PostResultMsgTag = 4,
238 NoOpReqTag = 5,
239 NoOpRspTag = 6,
240 DispResultMsgTag = 7,
241 InvokeReqTag = 8,
242 AssociatorsOfReqTag = 9,
243 ReferencesOfReqTag = 10,
244 SubscribeReqTag = 11,
245 SubscribeResTag = 12,
246 DeleteInstanceReqTag = 13,
247 CreateInstanceReqTag = 14,
248 ModifyInstanceReqTag = 15,
249 BinProtocolNotificationTag = 16
250 */
251 typedef struct _MessageDeclaration
252 {
253 mike 1.1 const MessageField* fields;
254 size_t size;
255 MI_Boolean cloneRequired;
256 }
257 MessageDeclaration;
258
259 static const MessageDeclaration allMessages[] = {
260 {baseMessageFields, 0, MI_FALSE},
261 {getInstanceMessageFields, sizeof(GetInstanceReq), MI_TRUE},
262 {postInstanceMessageFields, sizeof(PostInstanceMsg), MI_TRUE},
263 {enumerateInstancesMessageFields, sizeof(EnumerateInstancesReq), MI_FALSE},
264 {emptyMessageFields, sizeof(PostResultMsg), MI_FALSE},
265 {emptyMessageFields, sizeof(NoOpReq), MI_FALSE},
266 {emptyMessageFields, sizeof(NoOpRsp), MI_FALSE},
267 {emptyMessageFields, sizeof(DispResultMsg), MI_FALSE},
268 {invokeMessageFields, sizeof(InvokeReq), MI_TRUE},
269 {associatorsOfMessageFields, sizeof(AssociatorsOfReq), MI_TRUE},
270 {referencesOfMessageFields, sizeof(ReferencesOfReq), MI_TRUE},
271 {subscribeRequestMessageFields, sizeof(SubscribeReq), MI_FALSE},
272 {subscribeResponseMessageFields, sizeof(SubscribeRes), MI_FALSE},
273 {deleteInstanceMessageFields, sizeof(DeleteInstanceReq), MI_TRUE},
274 mike 1.1 {createInstanceMessageFields, sizeof(CreateInstanceReq), MI_TRUE},
275 {modifyInstanceMessageFields, sizeof(ModifyInstanceReq), MI_TRUE},
276 {binProtocolNotificationFields, sizeof(BinProtocolNotification),MI_FALSE}
277 };
278
279 /*
280 **==============================================================================
281 **
282 ** Public definitions
283 **
284 **==============================================================================
285 */
286
287 Message* __Message_New(
288 MessageTag tag,
289 size_t structSize,
290 MI_Uint64 msgID,
291 MI_Uint32 flags)
292 {
293 Batch *batch;
294 Message* self;
295 mike 1.1
296 batch = Batch_New(BATCH_MAX_PAGES);
297
298 if (!batch)
299 return NULL;
300
301 /* Allocate heap space for message */
302 self = Batch_Get(batch, structSize);
303
304 if (!self)
305 return NULL;
306
307 /* Clear all fields */
308 memset(self, 0, structSize);
309
310 /* Set the tag */
311 self->tag = tag;
312
313 /* Set the message id and flags */
314 self->msgID = msgID;
315 self->flags = flags;
316 mike 1.1
317 /* ref-counter is set to 1, to balance NewMessage/Release Message pair*/
318 self->refCounter = 1;
319
320 /* Copy batch onto message (released by delete method) */
321 self->batch = batch;
322
323 return self;
324 }
325
326 /*
327 Decrements message's ref-counter and destroys
328 mesage if last reference was released
329 Parameters:
330 self - message to decref/release
331 */
332 void Message_Release(
333 Message* self)
334 {
335 if (AtomicDec(&self->refCounter))
336 {
337 mike 1.1 /* Call destructor */
338 if (self->dtor)
339 (*self->dtor)(self, self->dtorData);
340
341 /* Release linked request */
342 if (self->request)
343 Message_Release(self->request);
344
345 Batch_Destroy(self->batch);
346 }
347 }
348
349 static void _Message_Print(
350 const void* msg,
351 FILE* os,
352 const char* structName,
353 const Field fields[])
354 {
355 size_t i;
356
357 fprintf(os, "%s\n", structName);
358 mike 1.1 fprintf(os, "{\n");
359
360 for (i = 0; fields[i].name; i++)
361 {
362 const Field* f = &fields[i];
363
364 /* Print name */
365 fprintf(os, " %s=", f->name);
366
367 /* Print value */
368 switch (f->type)
369 {
370 case FT_UINT32:
371 {
372 MessageTag* p = (MessageTag*)((char*)msg + f->off);
373 fprintf(os, "%u", *p);
374 break;
375 }
376 case FT_RESULT:
377 {
378 MI_Result* p = (MI_Result*)((char*)msg + f->off);
379 mike 1.1 Fzprintf(os, MI_T("%u [%s]"),*p, Result_ToString(*p));
380
381 break;
382 }
383 case FT_ATOMIC:
384 {
385 AtomicInt* p = (AtomicInt*)((char*)msg + f->off);
386 Fzprintf(os, MI_T("%d"),(int)(*p));
387
388 break;
389 }
390 case FT_UINT64:
391 {
392 MI_Uint64* p = (MI_Uint64*)((char*)msg + f->off);
393 fprintf(os, UINT64_FMT, *p);
394 break;
395 }
396 case FT_BOOLEAN:
397 {
398 MI_Boolean* p = (MI_Boolean*)((char*)msg + f->off);
399 fprintf(os, "%s", *p ? "TRUE" : "FALSE");
400 mike 1.1 break;
401 }
402 case FT_STRING:
403 {
404 MI_Char** p = (MI_Char**)((char*)msg + f->off);
405
406 if (*p)
407 Fzprintf(os, MI_T("\"%s\""), *p);
408 else
409 fprintf(os, "NULL");
410 break;
411 }
412 case FT_STRINGA:
413 {
414 StringArray** p = (StringArray**)((char*)msg + f->off);
415
416 if (*p)
417 StringArray_Print(*p, os);
418 else
419 fprintf(os, "NULL");
420 break;
421 mike 1.1 }
422 case FT_INSTANCE:
423 {
424 MI_Instance** p = (MI_Instance**)((char*)msg + f->off);
425
426 if (*p)
427 {
428 fputc('\n', os);
429 MI_Instance_Print(*p, os, 1);
430 }
431 else
432 fprintf(os, "NULL\n");
433 break;
434 }
435 default:
436 break;
437 }
438
439 if (f->type != FT_INSTANCE)
440 fputc('\n', os);
441 }
442 mike 1.1
443 fprintf(os, "}\n");
444 }
445
446 void MessagePrint(const Message* msg, FILE* os)
447 {
448 switch ( msg->tag )
449 {
450 case GetInstanceReqTag:
451 {
452 const GetInstanceReq* m = (const GetInstanceReq*)msg;
453 GetInstanceReq_Print(m, os);
454 }
455 break;
456
457 case PostInstanceMsgTag:
458 {
459 const PostInstanceMsg* m = (const PostInstanceMsg*)msg;
460 PostInstanceMsg_Print(m, os);
461 }
462 break;
463 mike 1.1
464 case EnumerateInstancesReqTag:
465 {
466 const EnumerateInstancesReq* m = (const EnumerateInstancesReq*)msg;
467 EnumerateInstancesReq_Print(m, os);
468 }
469 break;
470
471 case PostResultMsgTag:
472 {
473 const PostResultMsg* m = (const PostResultMsg*)msg;
474 PostResultMsg_Print(m, os);
475 }
476 break;
477
478 case NoOpReqTag:
479 {
480 const NoOpReq* m = (const NoOpReq*)msg;
481 NoOpReq_Print(m, os);
482 }
483 break;
484 mike 1.1
485 case NoOpRspTag:
486 {
487 const NoOpRsp* m = (const NoOpRsp*)msg;
488 NoOpRsp_Print(m, os);
489 }
490 break;
491
492 case DispResultMsgTag:
493 {
494 const DispResultMsg* m = (const DispResultMsg*)msg;
495 DispResultMsg_Print(m, os);
496 }
497 break;
498
499 case InvokeReqTag:
500 {
501 const InvokeReq* m = (const InvokeReq*)msg;
502 InvokeReq_Print(m, os);
503 }
504 break;
505 mike 1.1
506 case AssociatorsOfReqTag:
507 {
508 const AssociatorsOfReq* m = (const AssociatorsOfReq*)msg;
509 AssociatorsOfReq_Print(m, os);
510 }
511 break;
512
513 case ReferencesOfReqTag:
514 {
515 const ReferencesOfReq* m = (const ReferencesOfReq*)msg;
516 ReferencesOfReq_Print(m, os);
517 }
518 break;
519
520 case SubscribeReqTag:
521 {
522 const SubscribeReq* m = (const SubscribeReq*)msg;
523 SubscribeReq_Print(m, os);
524 }
525 break;
526 mike 1.1
527 case SubscribeResTag:
528 {
529 const SubscribeRes* m = (const SubscribeRes*)msg;
530 SubscribeRes_Print(m, os);
531 }
532 break;
533
534 case DeleteInstanceReqTag:
535 {
536 const DeleteInstanceReq* m = (const DeleteInstanceReq*)msg;
537 DeleteInstanceReq_Print(m, os);
538 }
539 break;
540
541 case CreateInstanceReqTag:
542 {
543 const CreateInstanceReq* m = (const CreateInstanceReq*)msg;
544 CreateInstanceReq_Print(m, os);
545 }
546 break;
547 mike 1.1
548 case ModifyInstanceReqTag:
549 {
550 const ModifyInstanceReq* m = (const ModifyInstanceReq*)msg;
551 ModifyInstanceReq_Print(m, os);
552 }
553 break;
554
555 case BinProtocolNotificationTag:
556 {
557 const BinProtocolNotification* m = (const BinProtocolNotification*)msg;
558 BinProtocolNotification_Print(m, os);
559 }
560 break;
561
562 default:
563 fprintf(os, "unknown message tag %d\n", msg->tag);
564 break;
565
566 }
567 }
568 mike 1.1
569 /*
570 **==============================================================================
571 **
572 ** Field information.
573 **
574 **==============================================================================
575 */
576
577 void GetInstanceReq_Print(const GetInstanceReq* msg, FILE* os)
578 {
579 typedef GetInstanceReq Self;
580 static const Field fields[] =
581 {
582 {"tag", FT_UINT32, offsetof(Self, base.tag)},
583 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
584 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
585 {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
586 {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
587 {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
588 {NULL, 0, 0},
589 mike 1.1 };
590 _Message_Print(msg, os, "GetInstanceReq", fields);
591 }
592
593 void CreateInstanceReq_Print(const CreateInstanceReq* msg, FILE* os)
594 {
595 typedef CreateInstanceReq Self;
596 static const Field fields[] =
597 {
598 {"tag", FT_UINT32, offsetof(Self, base.tag)},
599 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
600 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
601 {"instanceName", FT_INSTANCE, offsetof(Self, instance)},
602 {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
603 {NULL, 0, 0},
604 };
605 _Message_Print(msg, os, "CreateInstanceReq", fields);
606 }
607
608 void ModifyInstanceReq_Print(const ModifyInstanceReq* msg, FILE* os)
609 {
610 mike 1.1 typedef ModifyInstanceReq Self;
611 static const Field fields[] =
612 {
613 {"tag", FT_UINT32, offsetof(Self, base.tag)},
614 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
615 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
616 {"instanceName", FT_INSTANCE, offsetof(Self, instance)},
617 {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
618 {NULL, 0, 0},
619 };
620 _Message_Print(msg, os, "ModifyInstanceReq", fields);
621 }
622
623 void DeleteInstanceReq_Print(const DeleteInstanceReq* msg, FILE* os)
624 {
625 typedef DeleteInstanceReq Self;
626 static const Field fields[] =
627 {
628 {"tag", FT_UINT32, offsetof(Self, base.tag)},
629 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
630 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
631 mike 1.1 {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)},
632 {NULL, 0, 0},
633 };
634 _Message_Print(msg, os, "DeleteInstanceReq", fields);
635 }
636
637 void InvokeReq_Print(const InvokeReq* msg, FILE* os)
638 {
639 typedef InvokeReq Self;
640 static const Field fields[] =
641 {
642 {"tag", FT_UINT32, offsetof(Self, base.tag)},
643 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
644 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
645 {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
646 {"className", FT_STRING, offsetof(Self, className)},
647 {"function", FT_STRING, offsetof(Self, function)},
648 {"instance", FT_INSTANCE, offsetof(Self, instance)},
649 {"instanceParams", FT_INSTANCE, offsetof(Self, instanceParams)},
650 {NULL, 0, 0},
651 };
652 mike 1.1 _Message_Print(msg, os, "InvokeReq", fields);
653 }
654
655 void AssociatorsOfReq_Print(const AssociatorsOfReq* msg, FILE* os)
656 {
657 typedef AssociatorsOfReq Self;
658 static const Field fields[] =
659 {
660 {"tag", FT_UINT32, offsetof(Self, base.tag)},
661 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
662 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
663 {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
664 {"assocClass", FT_STRING, offsetof(Self, assocClass)},
665 {"resultClass", FT_STRING, offsetof(Self, resultClass)},
666 {"role", FT_STRING, offsetof(Self, role)},
667 {"resultRole", FT_STRING, offsetof(Self, resultRole)},
668 {"instance", FT_INSTANCE, offsetof(Self, instance)},
669 {NULL, 0, 0},
670 };
671 _Message_Print(msg, os, "AssociatorsOfReq", fields);
672 }
673 mike 1.1
674 void ReferencesOfReq_Print(const ReferencesOfReq* msg, FILE* os)
675 {
676 typedef ReferencesOfReq Self;
677 static const Field fields[] =
678 {
679 {"tag", FT_UINT32, offsetof(Self, base.tag)},
680 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
681 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
682 {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
683 {"assocClass", FT_STRING, offsetof(Self, assocClass)},
684 {"role", FT_STRING, offsetof(Self, role)},
685 {"instance", FT_INSTANCE, offsetof(Self, instance)},
686 {NULL, 0, 0},
687 };
688 _Message_Print(msg, os, "ReferencesOfReq", fields);
689 }
690
691 void PostInstanceMsg_Print(const PostInstanceMsg* msg, FILE* os)
692 {
693 typedef PostInstanceMsg Self;
694 mike 1.1 static const Field fields[] =
695 {
696 {"tag", FT_UINT32, offsetof(Self, base.tag)},
697 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
698 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
699 {"instance", FT_INSTANCE, offsetof(Self, instance)},
700 {NULL, 0, 0},
701 };
702 _Message_Print(msg, os, "PostInstanceMsg", fields);
703 }
704
705 void PostResultMsg_Print(const PostResultMsg* msg, FILE* os)
706 {
707 typedef PostResultMsg Self;
708 static const Field fields[] =
709 {
710 {"tag", FT_UINT32, offsetof(Self, base.tag)},
711 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
712 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
713 {"result", FT_RESULT, offsetof(Self, result)},
714 {NULL, 0, 0},
715 mike 1.1 };
716 _Message_Print(msg, os, "PostResultMsg", fields);
717 }
718
719 void DispResultMsg_Print(const DispResultMsg* msg, FILE* os)
720 {
721 typedef DispResultMsg Self;
722 static const Field fields[] =
723 {
724 {"tag", FT_UINT32, offsetof(Self, base.tag)},
725 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
726 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
727 {"result", FT_RESULT, offsetof(Self, result)},
728 {"requestCounter", FT_ATOMIC, offsetof(Self, requestCounter)},
729 {NULL, 0, 0},
730 };
731 _Message_Print(msg, os, "DispResultMsg", fields);
732 }
733
734 void EnumerateInstancesReq_Print(
735 const EnumerateInstancesReq* msg,
736 mike 1.1 FILE* os)
737 {
738 typedef EnumerateInstancesReq Self;
739 static const Field fields[] =
740 {
741 {"tag", FT_UINT32, offsetof(Self, base.tag)},
742 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
743 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
744 {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
745 {"className", FT_STRING, offsetof(Self, className)},
746 {"requestClassName", FT_STRING, offsetof(Self, requestClassName)},
747 {"deepInheritance", FT_BOOLEAN, offsetof(Self, deepInheritance)},
748 {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)},
749 {"propertySet", FT_STRINGA, offsetof(Self, propertySet)},
750 {"queryLanguage", FT_STRING, offsetof(Self, queryLanguage)},
751 {"queryExpression", FT_STRING, offsetof(Self, queryExpression)},
752 {NULL, 0, 0},
753 };
754 _Message_Print(msg, os, "EnumerateInstancesReq", fields);
755 }
756
757 mike 1.1 void SubscribeReq_Print(const SubscribeReq* msg, FILE* os)
758 {
759 typedef SubscribeReq Self;
760 static const Field fields[] =
761 {
762 {"tag", FT_UINT32, offsetof(Self, base.tag)},
763 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
764 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
765 {"nameSpace", FT_STRING, offsetof(Self, nameSpace)},
766 {"className", FT_STRING, offsetof(Self, className)},
767 {"filter", FT_STRING, offsetof(Self, filter)},
768 {"language", FT_STRING, offsetof(Self, language)},
769 {NULL, 0, 0},
770 };
771 _Message_Print(msg, os, "SubscribeReq", fields);
772 }
773
774 void SubscribeRes_Print(const SubscribeRes* msg, FILE* os)
775 {
776 typedef SubscribeRes Self;
777 static const Field fields[] =
778 mike 1.1 {
779 {"tag", FT_UINT32, offsetof(Self, base.tag)},
780 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
781 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
782 {"subscriptionID", FT_STRING, offsetof(Self, subscriptionID)},
783 {NULL, 0, 0},
784 };
785 _Message_Print(msg, os, "SubscribeRes", fields);
786 }
787
788 void NoOpReq_Print(const NoOpReq* msg, FILE* os)
789 {
790 typedef NoOpReq Self;
791 static const Field fields[] =
792 {
793 {"tag", FT_UINT32, offsetof(Self, base.tag)},
794 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
795 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
796 {NULL, 0, 0},
797 };
798 _Message_Print(msg, os, "NoOpReq", fields);
799 mike 1.1 }
800
801 void NoOpRsp_Print(const NoOpRsp* msg, FILE* os)
802 {
803 typedef NoOpRsp Self;
804 static const Field fields[] =
805 {
806 {"tag", FT_UINT32, offsetof(Self, base.tag)},
807 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
808 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
809 {NULL, 0, 0},
810 };
811 _Message_Print(msg, os, "NoOpRsp", fields);
812 }
813
814 void BinProtocolNotification_Print(const BinProtocolNotification* msg, FILE* os)
815 {
816 typedef BinProtocolNotification Self;
817 static const Field fields[] =
818 {
819 {"tag", FT_UINT32, offsetof(Self, base.tag)},
820 mike 1.1 {"msgID", FT_UINT64, offsetof(Self, base.msgID)},
821 {"clientID", FT_UINT64, offsetof(Self, base.clientID)},
822 {NULL, 0, 0},
823 };
824 _Message_Print(msg, os, "BinProtocolNotification", fields);
825 }
826
827 static MI_Boolean _UnpackInstance(
828 Batch* batch,
829 void* ptr,
830 MI_Uint32 size,
831 MI_Instance** instanceOut)
832 {
833 MI_Result r;
834 Buf buf = BUF_INITIALIZER;
835
836 /* borrow pointer for unpacking, leaving it in the batch */
837 buf.data = ptr;
838 buf.size = size;
839
840 r = Instance_Unpack(instanceOut, &buf, batch, MI_FALSE);
841 mike 1.1 return r == MI_RESULT_OK;
842 }
843
844 static MI_Result _RestoreMessage(
845 Message* msg,
846 const Header_BatchInfoItem* ptrAdjustmentInfo,
847 size_t ptrAdjustmentInfoCount,
848 MI_Boolean skipInstanceUnpack,
849 const MessageField* messageFields)
850 {
851 char* chunk = (char*)msg;
852 Batch* batch = msg->batch;
853
854 while (messageFields->type != MFT_END_OF_LIST)
855 {
856 void** ptr = (void**)(chunk + messageFields->off);
857 switch (messageFields->type)
858 {
859 case MFT_POINTER_SET_NULL:
860 *ptr = 0;
861 break;
862 mike 1.1
863 case MFT_POINTER_OPT:
864 case MFT_POINTER:
865 if (*ptr)
866 {
867 if (!Batch_FixPointer(
868 batch,
869 ptrAdjustmentInfo,
870 ptrAdjustmentInfoCount,
871 ptr))
872 return MI_RESULT_INVALID_PARAMETER;
873 }
874 else if (messageFields->type == MFT_POINTER)
875 return MI_RESULT_INVALID_PARAMETER;
876
877 break;
878
879 case MFT_INSTANCE:
880 case MFT_INSTANCE_OPT:
881 {
882 void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
883 mike 1.1 MI_Uint32 packedSize = * (const MI_Uint32*)(chunk + messageFields->offPackedSize);
884
885 *ptr = 0;
886
887 if (*ptrPacked)
888 {
889 if (!Batch_FixPointer(
890 batch,
891 ptrAdjustmentInfo,
892 ptrAdjustmentInfoCount,
893 ptrPacked))
894 return MI_RESULT_INVALID_PARAMETER;
895
896 if (!skipInstanceUnpack && !_UnpackInstance(
897 batch,
898 *ptrPacked,
899 packedSize,
900 (MI_Instance**)ptr))
901 return MI_RESULT_INVALID_PARAMETER;
902 }
903 else if (messageFields->type == MFT_INSTANCE)
904 mike 1.1 return MI_RESULT_INVALID_PARAMETER;
905
906 }
907
908 break;
909
910 default:
911 break;
912 }
913
914 messageFields++;
915 }
916
917 return MI_RESULT_OK;
918 }
919
920 static MI_Result _Clone(
921 const Message* msgSrc,
922 Message* msg,
923 const MessageField* messageFields,
924 size_t size)
925 mike 1.1 {
926 char* chunk = (char*)msg;
927 Batch* batch = msg->batch;
928 const char* chunkSrc = (const char*)msgSrc;
929
930 /* copy all primitve data first */
931 memcpy(chunk + sizeof(Message), chunkSrc + sizeof(Message), size - sizeof(Message));
932
933 while (messageFields->type != MFT_END_OF_LIST)
934 {
935 void** ptr = (void**)(chunk + messageFields->off);
936 void** ptrSrc = (void**)(chunkSrc + messageFields->off);
937
938 switch (messageFields->type)
939 {
940 case MFT_POINTER_SET_NULL:
941 default:
942 break;
943
944 case MFT_POINTER_OPT:
945 case MFT_POINTER:
946 mike 1.1 if (*ptrSrc)
947 {
948 *ptr = Batch_Strdup2(batch, (const char*)*ptrSrc);
949
950 if (!*ptr)
951 return MI_RESULT_FAILED;
952 }
953 else if (messageFields->type == MFT_POINTER)
954 return MI_RESULT_INVALID_PARAMETER;
955
956 break;
957
958 case MFT_INSTANCE:
959 case MFT_INSTANCE_OPT:
960 {
961 void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr);
962 MI_Uint32* packedSize = (MI_Uint32*)(chunk + messageFields->offPackedSize);
963 const void* ptrPackedSrc = *(void**)(chunkSrc + messageFields->offPackedPtr);
964 MI_Uint32 packedSizeSrc = *(MI_Uint32*)(chunkSrc + messageFields->offPackedSize);
965
966 *ptr = 0;
967 mike 1.1
968 if (ptrPackedSrc)
969 {
970 /* Take existing packed instance if exist (received from binary protocol */
971 *packedSize = packedSizeSrc;
972 *ptrPacked = Batch_Get(batch, packedSizeSrc);
973
974 if (!*ptrPacked)
975 return MI_RESULT_FAILED;
976
977 memcpy(*ptrPacked, ptrPackedSrc, packedSizeSrc);
978 }
979 else if (*ptrSrc)
980 {
981 /* Pack instance in binary buffer (received form wsman) */
982 if (MI_RESULT_OK != InstanceToBatch(
983 (const MI_Instance*)(*ptrSrc),
984 NULL, /* filterProperties */
985 NULL, /* filterPropertiesData */
986 batch,
987 ptrPacked, packedSize))
988 mike 1.1 return MI_RESULT_FAILED;
989 }
990 else if (messageFields->type == MFT_INSTANCE)
991 /* Return error if non-optional parameter is missing */
992 return MI_RESULT_INVALID_PARAMETER;
993 }
994
995 break;
996 }
997
998 messageFields++;
999 }
1000
1001 return MI_RESULT_OK;
1002 }
1003 MI_Result MessageFromBatch(
1004 Batch* batch,
1005 void* originalMsgPtr,
1006 const Header_BatchInfoItem* ptrAdjustmentInfo,
1007 size_t ptrAdjustmentInfoCount,
1008 MI_Boolean skipInstanceUnpack,
1009 mike 1.1 Message** msgOut)
1010 {
1011 Message* msg = originalMsgPtr;
1012 MI_Uint32 index;
1013
1014 if (!Batch_FixPointer(
1015 batch,
1016 ptrAdjustmentInfo,
1017 ptrAdjustmentInfoCount,
1018 (void*)&msg))
1019 return MI_RESULT_INVALID_PARAMETER;
1020
1021 /* fix base part of message */
1022 msg->batch = batch;
1023 msg->refCounter = 1;
1024
1025 if (MI_RESULT_OK != _RestoreMessage(
1026 msg,
1027 ptrAdjustmentInfo,
1028 ptrAdjustmentInfoCount,
1029 skipInstanceUnpack,
1030 mike 1.1 baseMessageFields))
1031 return MI_RESULT_INVALID_PARAMETER;
1032
1033 index = (MI_Uint32)msg->tag;
1034
1035 if (index >= MI_COUNT(allMessages))
1036 return MI_RESULT_INVALID_PARAMETER;
1037
1038 if (MI_RESULT_OK != _RestoreMessage(
1039 msg,
1040 ptrAdjustmentInfo,
1041 ptrAdjustmentInfoCount,
1042 skipInstanceUnpack,
1043 allMessages[index].fields))
1044 return MI_RESULT_INVALID_PARAMETER;
1045
1046 *msgOut = msg;
1047 return MI_RESULT_OK;
1048 }
1049
1050 MI_Result MessagePackCloneForBinarySending(
1051 mike 1.1 Message* msgSrc,
1052 Message** msgOut)
1053 {
1054 Message* msg = msgSrc;
1055 MI_Uint32 index;
1056
1057 index = (MI_Uint32)msg->tag;
1058
1059 if (index >= MI_COUNT(allMessages))
1060 return MI_RESULT_INVALID_PARAMETER;
1061
1062 if (!allMessages[index].cloneRequired)
1063 {
1064 *msgOut = msg;
1065 Message_AddRef(msg);
1066 return MI_RESULT_OK;
1067 }
1068
1069 /* create a copy */
1070 msg = __Message_New(msgSrc->tag, allMessages[index].size, msgSrc->msgID, msgSrc->flags);
1071
1072 mike 1.1 if (!msg)
1073 return MI_RESULT_FAILED;
1074
1075 msg->clientID = msgSrc->clientID;
1076
1077 if (MI_RESULT_OK != _Clone(msgSrc, msg, allMessages[index].fields, allMessages[index].size))
1078 {
1079 Message_Release(msg);
1080 return MI_RESULT_FAILED;
1081 }
1082
1083 *msgOut = msg;
1084 return MI_RESULT_OK;
1085 }
|