1 krisbash 1.1 /*============================================================================
2 * Copyright (C) Microsoft Corporation, All rights reserved.
3 *============================================================================
4 */
5 #include "class.h"
6 #include <base/types.h>
7 #include <pal/strings.h>
8 #include <base/batch.h>
9 #include "naming.h"
10 #include <base/instance.h>
11 #include <pal/atomic.h>
12
13 extern const MI_ClassExtendedFTInternal g_ClassExtendedFTInternal;
14 extern const MI_ParameterSetExtendedFTInternal g_parameterExtendedFTInternal;
15 extern const MI_QualifierSetFT g_qualifierFT;
16
17 typedef struct _MI_RCClass
18 {
19 /* public properties from MI_Class */
20 const MI_ClassFT *ft;
21 MI_CONST MI_ClassDecl *classDecl;
22 krisbash 1.1 MI_CONST MI_Char *namespaceName;
23 MI_CONST MI_Char *serverName;
24
25 /* Reserved properties */
26 Batch *batch;
27 ptrdiff_t refcount;
28 ptrdiff_t reserved3;
29 ptrdiff_t reserved4;
30
31 } MI_RCClass;
32
33
34 void GetMIValueFromVoid(MI_Type type, _In_opt_ const void *source, _Out_ MI_Value *value)
35 {
36 memset(value, 0, sizeof(MI_Value));
37 if (source == NULL)
38 {
39 return;
40 }
41
42 switch(type)
43 krisbash 1.1 {
44 case MI_BOOLEAN:
45 value->boolean = *(MI_Boolean*)source;
46 break;
47 case MI_UINT8:
48 value->uint8 = *(MI_Uint8*)source;
49 break;
50 case MI_SINT8:
51 value->sint8 = *(MI_Sint8*)source;
52 break;
53 case MI_UINT16:
54 value->uint16 = *(MI_Uint16*)source;
55 break;
56 case MI_SINT16:
57 value->sint16 = *(MI_Sint16*)source;
58 break;
59 case MI_UINT32:
60 value->uint32 = *(MI_Uint32*)source;
61 break;
62 case MI_SINT32:
63 value->sint32 = *(MI_Sint32*)source;
64 krisbash 1.1 break;
65 case MI_UINT64:
66 value->uint64 = *(MI_Uint64*)source;
67 break;
68 case MI_SINT64:
69 value->sint64 = *(MI_Sint64*)source;
70 break;
71 case MI_REAL32:
72 value->real32 = *(MI_Real32*)source;
73 break;
74 case MI_REAL64:
75 value->real64 = *(MI_Real64*)source;
76 break;
77 case MI_CHAR16:
78 value->char16 = *(MI_Char16*)source;
79 break;
80 case MI_DATETIME:
81 value->datetime = *(MI_Datetime*)source;
82 break;
83 case MI_STRING:
84 value->string = *(MI_Char**)source;
85 krisbash 1.1 break;
86 case MI_REFERENCE:
87 value->reference = *(MI_Instance**)source;
88 break;
89 case MI_INSTANCE:
90 value->instance = *(MI_Instance**)source;
91 break;
92 case MI_BOOLEANA:
93 value->booleana = *(MI_BooleanA*)source;
94 break;
95 case MI_UINT8A:
96 value->uint8a = *(MI_Uint8A*)source;
97 break;
98 case MI_SINT8A:
99 value->sint8a = *(MI_Sint8A*)source;
100 break;
101 case MI_UINT16A:
102 value->uint16a = *(MI_Uint16A*)source;
103 break;
104 case MI_SINT16A:
105 value->sint16a = *(MI_Sint16A*)source;
106 krisbash 1.1 break;
107 case MI_UINT32A:
108 value->uint32a = *(MI_Uint32A*)source;
109 break;
110 case MI_SINT32A:
111 value->sint32a = *(MI_Sint32A*)source;
112 break;
113 case MI_UINT64A:
114 value->uint64a = *(MI_Uint64A*)source;
115 break;
116 case MI_SINT64A:
117 value->sint64a = *(MI_Sint64A*)source;
118 break;
119 case MI_REAL32A:
120 value->real32a = *(MI_Real32A*)source;
121 break;
122 case MI_REAL64A:
123 value->real64a = *(MI_Real64A*)source;
124 break;
125 case MI_CHAR16A:
126 value->char16a = *(MI_Char16A*)source;
127 krisbash 1.1 break;
128 case MI_DATETIMEA:
129 value->datetimea = *(MI_DatetimeA*)source;
130 break;
131 case MI_STRINGA:
132 value->stringa = *(MI_StringA*)source;
133 break;
134 case MI_REFERENCEA:
135 value->referencea = *(MI_ReferenceA*)source;
136 break;
137 case MI_INSTANCEA:
138 value->instancea = *(MI_InstanceA*)source;
139 break;
140 }
141 }
142
143 MI_Result MI_CALL Class_New(
144 _In_ const MI_ClassDecl *classDecl,
145 _In_opt_z_ const MI_Char *namespaceName,
146 _In_opt_z_ const MI_Char *serverName,
147 _Out_ MI_Class **outboundNewClass)
148 krisbash 1.1 {
149 Batch *ourBatch = NULL;
150 MI_RCClass *newClass = NULL;
151
152 if (classDecl == NULL || outboundNewClass == NULL)
153 {
154 return MI_RESULT_INVALID_PARAMETER;
155 }
156 *outboundNewClass = NULL;
157 if(ourBatch == NULL)
158 {
159 ourBatch = Batch_New(BATCH_MAX_PAGES);
160 if (ourBatch == NULL)
161 {
162 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
163 }
164 }
165
166 newClass = Batch_GetClear(ourBatch, sizeof(MI_Class));
167 if (newClass == NULL)
168 {
169 krisbash 1.1 Batch_Delete(ourBatch);
170 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
171 }
172
173 if (namespaceName)
174 {
175 newClass->namespaceName = Batch_Tcsdup(ourBatch, namespaceName);
176 if (newClass->namespaceName == NULL)
177 {
178 Batch_Delete(ourBatch);
179 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
180 }
181 }
182 if (serverName)
183 {
184 newClass->serverName = Batch_Tcsdup(ourBatch, serverName);
185 if (newClass->serverName == NULL)
186 {
187 Batch_Delete(ourBatch);
188 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
189 }
190 krisbash 1.1 }
191 newClass->ft = (MI_ClassFT*)(&g_ClassExtendedFTInternal);
192 newClass->batch = ourBatch;
193 newClass->classDecl = Class_Clone_ClassDecl(ourBatch, classDecl);
194 if (newClass->classDecl == NULL)
195 {
196 Batch_Delete(ourBatch);
197
198 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
199 }
200
201 newClass->classDecl->owningClass = (MI_Class*)newClass;
202 newClass->refcount = 1;
203 *outboundNewClass = (MI_Class*) newClass;
204 return MI_RESULT_OK;
205 }
206
207 static MI_Uint32 _CalculateArraySize(MI_Type type, MI_Uint32 numberItems)
208 {
209 return Type_SizeOf(type&~MI_ARRAY) * numberItems;
210 }
211 krisbash 1.1
212
213 /*============================================================================
214 *
215 *============================================================================
216 */
217 MI_Array* Class_Clone_Array(
218 _Inout_ Batch *batch,
219 MI_Type type,
220 _In_ const MI_Array *array)
221 {
222 MI_Array *newArray = Batch_Get(batch, sizeof(MI_Array));
223 MI_Uint32 arraySize = 0;
224 MI_Uint32 arrayLoop = 0;
225 if (newArray == NULL)
226 {
227 return NULL; /* Returning NULL causes whole batch to destruct */
228 }
229 newArray->size = array->size;
230
231 arraySize = _CalculateArraySize(type, array->size);
232 krisbash 1.1
233 newArray->data = Batch_Get(batch, arraySize);
234 if (newArray->data == NULL)
235 {
236 return NULL; /* Returning NULL causes whole batch to destruct */
237 }
238 switch(type)
239 {
240 case MI_BOOLEANA:
241 case MI_UINT8A:
242 case MI_SINT8A:
243 case MI_UINT16A:
244 case MI_SINT16A:
245 case MI_UINT32A:
246 case MI_SINT32A:
247 case MI_UINT64A:
248 case MI_SINT64A:
249 case MI_REAL32A:
250 case MI_REAL64A:
251 case MI_CHAR16A:
252 case MI_DATETIMEA:
253 krisbash 1.1 memcpy(newArray->data, array->data, arraySize);
254 break;
255 case MI_STRINGA:
256 for (;arrayLoop != array->size; arrayLoop++)
257 {
258 if (((MI_Char**)(array->data))[arrayLoop])
259 {
260 ((MI_Char**)(newArray->data))[arrayLoop] = Batch_Tcsdup(batch, ((MI_Char**)(array->data))[arrayLoop]);
261 if (((MI_Char**)(newArray->data))[arrayLoop] == NULL)
262 {
263 return NULL; /* Returning NULL causes whole batch to destruct */
264 }
265 }
266 }
267 break;
268 case MI_REFERENCEA:
269 case MI_INSTANCEA:
270 for (;arrayLoop != array->size; arrayLoop++)
271 {
272 if (((MI_Instance**)(newArray->data))[arrayLoop])
273 {
274 krisbash 1.1 if (Instance_Clone(((MI_Instance**)(array->data))[arrayLoop], &((MI_Instance**)(newArray->data))[arrayLoop], batch) != MI_RESULT_OK)
275 {
276 return NULL; /* Returning NULL causes whole batch to destruct */
277 }
278 }
279 }
280 break;
281 default:
282 break;
283 }
284
285 return newArray;
286 }
287
288 /*============================================================================
289 *
290 *============================================================================
291 */
292 MI_Result Class_Clone_ArrayValue(
293 _Inout_ Batch *batch,
294 MI_Type type,
295 krisbash 1.1 _In_ void *destinationArrayStart,
296 MI_Uint32 arrayLocation,
297 _In_ const void *oldValueLocation)
298 {
299 switch(type)
300 {
301 case MI_BOOLEAN:
302 ((MI_Boolean*)destinationArrayStart)[arrayLocation] = *(MI_Boolean*)oldValueLocation;
303 break;
304 case MI_UINT8:
305 ((MI_Uint8*)destinationArrayStart)[arrayLocation] = *(MI_Uint8*)oldValueLocation;
306 break;
307 case MI_SINT8:
308 ((MI_Sint8*)destinationArrayStart)[arrayLocation] = *(MI_Sint8*)oldValueLocation;
309 break;
310 case MI_UINT16:
311 ((MI_Uint16*)destinationArrayStart)[arrayLocation] = *(MI_Uint16*)oldValueLocation;
312 break;
313 case MI_SINT16:
314 ((MI_Sint16*)destinationArrayStart)[arrayLocation] = *(MI_Sint16*)oldValueLocation;
315 break;
316 krisbash 1.1 case MI_UINT32:
317 ((MI_Uint32*)destinationArrayStart)[arrayLocation] = *(MI_Uint32*)oldValueLocation;
318 break;
319 case MI_SINT32:
320 ((MI_Sint32*)destinationArrayStart)[arrayLocation] = *(MI_Sint32*)oldValueLocation;
321 break;
322 case MI_UINT64:
323 ((MI_Uint64*)destinationArrayStart)[arrayLocation] = *(MI_Uint64*)oldValueLocation;
324 break;
325 case MI_SINT64:
326 ((MI_Sint64*)destinationArrayStart)[arrayLocation] = *(MI_Sint64*)oldValueLocation;
327 break;
328 case MI_REAL32:
329 ((MI_Real32*)destinationArrayStart)[arrayLocation] = *(MI_Real32*)oldValueLocation;
330 break;
331 case MI_REAL64:
332 ((MI_Real64*)destinationArrayStart)[arrayLocation] = *(MI_Real64*)oldValueLocation;
333 break;
334 case MI_CHAR16:
335 ((MI_Char16*)destinationArrayStart)[arrayLocation] = *(MI_Char16*)oldValueLocation;
336 break;
337 krisbash 1.1 case MI_DATETIME:
338 ((MI_Datetime*)destinationArrayStart)[arrayLocation] = *(MI_Datetime*)oldValueLocation;
339 break;
340 case MI_STRING:
341 {
342 MI_Char *string = NULL;
343 if (*(MI_Char**)oldValueLocation)
344 {
345 string = Batch_Tcsdup(batch, *(MI_Char**)oldValueLocation);
346 if (string == NULL)
347 {
348 return MI_RESULT_SERVER_LIMITS_EXCEEDED; /* Returning error causes whole batch to destruct */
349 }
350 }
351 ((MI_String*)destinationArrayStart)[arrayLocation] = string;
352 }
353 break;
354 case MI_REFERENCE:
355 case MI_INSTANCE:
356 {
357 MI_Instance *instance = NULL;
358 krisbash 1.1
359 if (*(MI_Char**)oldValueLocation)
360 {
361 if (Instance_Clone(*(MI_Instance**)oldValueLocation, &instance, batch) != MI_RESULT_OK)
362 {
363 return MI_RESULT_SERVER_LIMITS_EXCEEDED; /* Returning error causes whole batch to destruct */
364 }
365 }
366 ((MI_Instance**)destinationArrayStart)[arrayLocation] = instance;
367 }
368 break;
369 case MI_BOOLEANA:
370 case MI_UINT8A:
371 case MI_SINT8A:
372 case MI_UINT16A:
373 case MI_SINT16A:
374 case MI_UINT32A:
375 case MI_SINT32A:
376 case MI_UINT64A:
377 case MI_SINT64A:
378 case MI_REAL32A:
379 krisbash 1.1 case MI_REAL64A:
380 case MI_CHAR16A:
381 case MI_DATETIMEA:
382 case MI_STRINGA:
383 case MI_REFERENCEA:
384 case MI_INSTANCEA:
385 return MI_RESULT_INVALID_PARAMETER;
386 break;
387 }
388
389 return MI_RESULT_OK;;
390 }
391
392 /*============================================================================
393 *
394 *============================================================================
395 */
396 void* Class_Clone_Value(
397 _Inout_ Batch *batch,
398 MI_Type type,
399 _In_ const void *value)
400 krisbash 1.1 {
401 void *newValue = NULL;
402
403 switch(type)
404 {
405 case MI_BOOLEAN:
406 newValue = Batch_Get(batch, sizeof(MI_Boolean));
407 if (newValue == NULL)
408 {
409 return NULL; /* Returning NULL causes whole batch to destruct */
410 }
411 *(MI_Boolean*)newValue = *(MI_Boolean*)value;
412 break;
413 case MI_UINT8:
414 newValue = Batch_Get(batch, sizeof(MI_Uint8));
415 if (newValue == NULL)
416 {
417 return NULL; /* Returning NULL causes whole batch to destruct */
418 }
419 *(MI_Uint8*)newValue = *(MI_Uint8*)value;
420 break;
421 krisbash 1.1 case MI_SINT8:
422 newValue = Batch_Get(batch, sizeof(MI_Sint8));
423 if (newValue == NULL)
424 {
425 return NULL; /* Returning NULL causes whole batch to destruct */
426 }
427 *(MI_Sint8*)newValue = *(MI_Sint8*)value;
428 break;
429 case MI_UINT16:
430 newValue = Batch_Get(batch, sizeof(MI_Uint16));
431 if (newValue == NULL)
432 {
433 return NULL; /* Returning NULL causes whole batch to destruct */
434 }
435 *(MI_Uint16*)newValue = *(MI_Uint16*)value;
436 break;
437 case MI_SINT16:
438 newValue = Batch_Get(batch, sizeof(MI_SINT16));
439 if (newValue == NULL)
440 {
441 return NULL; /* Returning NULL causes whole batch to destruct */
442 krisbash 1.1 }
443 *(MI_Sint16*)newValue = *(MI_Sint16*)value;
444 break;
445 case MI_UINT32:
446 newValue = Batch_Get(batch, sizeof(MI_Uint32));
447 if (newValue == NULL)
448 {
449 return NULL; /* Returning NULL causes whole batch to destruct */
450 }
451 *(MI_Uint32*)newValue = *(MI_Uint32*)value;
452 break;
453 case MI_SINT32:
454 newValue = Batch_Get(batch, sizeof(MI_Sint32));
455 if (newValue == NULL)
456 {
457 return NULL; /* Returning NULL causes whole batch to destruct */
458 }
459 *(MI_Sint32*)newValue = *(MI_Sint32*)value;
460 break;
461 case MI_UINT64:
462 newValue = Batch_Get(batch, sizeof(MI_Uint64));
463 krisbash 1.1 if (newValue == NULL)
464 {
465 return NULL; /* Returning NULL causes whole batch to destruct */
466 }
467 *(MI_Uint64*)newValue = *(MI_Uint64*)value;
468 break;
469 case MI_SINT64:
470 newValue = Batch_Get(batch, sizeof(MI_Sint64));
471 if (newValue == NULL)
472 {
473 return NULL; /* Returning NULL causes whole batch to destruct */
474 }
475 *(MI_Sint64*)newValue = *(MI_Sint64*)value;
476 break;
477 case MI_REAL32:
478 newValue = Batch_Get(batch, sizeof(MI_Real32));
479 if (newValue == NULL)
480 {
481 return NULL; /* Returning NULL causes whole batch to destruct */
482 }
483 *(MI_Real32*)newValue = *(MI_Real32*)value;
484 krisbash 1.1 break;
485 case MI_REAL64:
486 newValue = Batch_Get(batch, sizeof(MI_Real64));
487 if (newValue == NULL)
488 {
489 return NULL; /* Returning NULL causes whole batch to destruct */
490 }
491 *(MI_Real64*)newValue = *(MI_Real64*)value;
492 break;
493 case MI_CHAR16:
494 newValue = Batch_Get(batch, sizeof(MI_Char16));
495 if (newValue == NULL)
496 {
497 return NULL; /* Returning NULL causes whole batch to destruct */
498 }
499 *(MI_Char16*)newValue = *(MI_Char16*)value;
500 break;
501 case MI_DATETIME:
502 newValue = Batch_Get(batch, sizeof(MI_Datetime));
503 if (newValue == NULL)
504 {
505 krisbash 1.1 return NULL; /* Returning NULL causes whole batch to destruct */
506 }
507 *(MI_Datetime*)newValue = *(MI_Datetime*)value;
508 break;
509 case MI_STRING:
510 {
511 MI_Char *string = NULL;
512 MI_Char **pointerToString = NULL;
513
514 pointerToString = (MI_Char**)Batch_Get(batch, sizeof(MI_Char**));
515 if (pointerToString == NULL)
516 {
517 return NULL; /* Returning NULL causes whole batch to destruct */
518 }
519 string = Batch_Tcsdup(batch, *(MI_Char**)value);
520 if (string == NULL)
521 {
522 return NULL; /* Returning NULL causes whole batch to destruct */
523 }
524 *pointerToString = string;
525
526 krisbash 1.1 newValue = pointerToString;
527 }
528 break;
529 case MI_REFERENCE:
530 case MI_INSTANCE:
531 {
532 MI_Instance *instance = NULL;
533 MI_Instance **pointerToInstance= NULL;
534
535 pointerToInstance = (MI_Instance**)Batch_Get(batch, sizeof(MI_Instance**));
536 if (pointerToInstance == NULL)
537 {
538 return NULL; /* Returning NULL causes whole batch to destruct */
539 }
540 if (Instance_Clone(*(MI_Instance**)value, &instance, batch) != MI_RESULT_OK)
541 {
542 return NULL; /* Returning NULL causes whole batch to destruct */
543 }
544 *pointerToInstance = instance;
545
546 newValue = pointerToInstance;
547 krisbash 1.1 }
548 break;
549 case MI_BOOLEANA:
550 case MI_UINT8A:
551 case MI_SINT8A:
552 case MI_UINT16A:
553 case MI_SINT16A:
554 case MI_UINT32A:
555 case MI_SINT32A:
556 case MI_UINT64A:
557 case MI_SINT64A:
558 case MI_REAL32A:
559 case MI_REAL64A:
560 case MI_CHAR16A:
561 case MI_DATETIMEA:
562 case MI_STRINGA:
563 case MI_REFERENCEA:
564 case MI_INSTANCEA:
565 newValue = Class_Clone_Array(batch, type, (MI_Array*)value);
566 break;
567 }
568 krisbash 1.1
569 return newValue;
570 }
571 /*============================================================================
572 *
573 *============================================================================
574 */
575 MI_Qualifier * Class_Clone_Qualifier(
576 _Inout_ Batch *batch,
577 MI_Qualifier MI_CONST* qualifier)
578 {
579 MI_Qualifier *newQualifier = Batch_Get(batch, sizeof(MI_Qualifier));
580 if (newQualifier == NULL)
581 {
582 return NULL; /* Returning NULL causes whole batch to destruct */
583 }
584 memset(newQualifier, 0, sizeof(*newQualifier));
585 newQualifier->name = Batch_Tcsdup(batch, qualifier->name);
586 if (newQualifier->name == NULL)
587 {
588 return NULL; /* Returning NULL causes whole batch to destruct */
589 krisbash 1.1 }
590 newQualifier->type = qualifier->type;
591 newQualifier->flavor = qualifier->flavor;
592 if (qualifier->value)
593 {
594 newQualifier->value = Class_Clone_Value(batch, qualifier->type, qualifier->value);
595 if (newQualifier->value == NULL)
596 {
597 return NULL; /* Returning NULL causes whole batch to destruct */
598 }
599 }
600 else
601 {
602 newQualifier->value = NULL;
603 }
604
605 return newQualifier;
606 }
607
608 /*============================================================================
609 *
610 krisbash 1.1 *============================================================================
611 */
612 MI_Qualifier MI_CONST* MI_CONST* Class_Clone_Qualifiers(
613 _Inout_ Batch *batch,
614 MI_Qualifier MI_CONST* MI_CONST* qualifiers,
615 MI_Uint32 numQualifiers)
616 {
617 MI_Qualifier **newQualifiers = Batch_Get(batch, sizeof(MI_Qualifier*)*numQualifiers);
618 MI_Uint32 qualifierIndex = 0;
619 if (newQualifiers == NULL)
620 {
621 return NULL; /* Returning NULL causes whole batch to destruct */
622 }
623 for (;qualifierIndex != numQualifiers; qualifierIndex++)
624 {
625 newQualifiers[qualifierIndex] = Class_Clone_Qualifier(batch, qualifiers[qualifierIndex]);
626 if (newQualifiers[qualifierIndex] == NULL)
627 {
628 return NULL; /* Returning NULL causes whole batch to destruct */
629 }
630 }
631 krisbash 1.1
632 return newQualifiers;
633 }
634
635 /*============================================================================
636 *
637 *============================================================================
638 */
639 MI_PropertyDecl * Class_Clone_Property(
640 _Inout_ Batch *batch,
641 MI_PropertyDecl MI_CONST* property)
642 {
643 MI_PropertyDecl *newProperty = Batch_Get(batch, sizeof(MI_PropertyDecl));
644 if (newProperty == NULL)
645 {
646 return NULL; /* Returning NULL causes whole batch to destruct */
647 }
648 memset(newProperty, 0, sizeof(*newProperty));
649 newProperty->flags = property->flags;
650 newProperty->code = property->code;
651 newProperty->name = Batch_Tcsdup(batch, property->name);
652 krisbash 1.1 if (newProperty->name == NULL)
653 {
654 return NULL; /* Returning NULL causes whole batch to destruct */
655 }
656 if (property->qualifiers && property->numQualifiers)
657 {
658 newProperty->qualifiers = Class_Clone_Qualifiers(batch, property->qualifiers, property->numQualifiers);
659 if (newProperty->qualifiers == NULL)
660 {
661 return NULL; /* Returning NULL causes whole batch to destruct */
662 }
663 newProperty->numQualifiers = property->numQualifiers;
664 }
665 newProperty->type = property->type;
666 if (property->className)
667 {
668 newProperty->className = Batch_Tcsdup(batch, property->className); /* embedded/reference stringly typed class name */
669 if (newProperty->className == NULL)
670 {
671 return NULL; /* Returning NULL causes whole batch to destruct */
672 }
673 krisbash 1.1 }
674 newProperty->subscript = property->subscript;
675 newProperty->offset = property->offset;
676 if (property->origin)
677 {
678 newProperty->origin = Batch_Tcsdup(batch, property->origin);
679 if (newProperty->origin == NULL)
680 {
681 return NULL; /* Returning NULL causes whole batch to destruct */
682 }
683 }
684 if (property->propagator)
685 {
686 newProperty->propagator = Batch_Tcsdup(batch, property->propagator);
687 if (newProperty->propagator == NULL)
688 {
689 return NULL; /* Returning NULL causes whole batch to destruct */
690 }
691 }
692 if (((property->flags & MI_FLAG_NULL) != MI_FLAG_NULL) && property->value)
693 {
694 krisbash 1.1 newProperty->value = Class_Clone_Value(batch, property->type, property->value);
695 if (newProperty->value == NULL)
696 {
697 return NULL; /* Returning NULL causes whole batch to destruct */
698 }
699 }
700 else
701 {
702 newProperty->value = NULL;
703 }
704 return newProperty;
705 }
706
707 /*============================================================================
708 *
709 *============================================================================
710 */
711 MI_PropertyDecl MI_CONST* MI_CONST* Class_Clone_Properties(
712 _Inout_ Batch *batch,
713 MI_PropertyDecl MI_CONST* MI_CONST* properties,
714 MI_Uint32 numProperties)
715 krisbash 1.1 {
716 MI_PropertyDecl **newProperties = Batch_Get(batch, sizeof(MI_PropertyDecl*)*numProperties);
717 MI_Uint32 propertyIndex = 0;
718 if (newProperties == NULL)
719 {
720 return NULL; /* Returning NULL causes whole batch to destruct */
721 }
722 for (;propertyIndex != numProperties; propertyIndex++)
723 {
724 newProperties[propertyIndex] = Class_Clone_Property(batch, properties[propertyIndex]);
725 if (newProperties[propertyIndex] == NULL)
726 {
727 return NULL; /* Returning NULL causes whole batch to destruct */
728 }
729 }
730
731 return newProperties;
732 }
733
734 /*============================================================================
735 *
736 krisbash 1.1 *============================================================================
737 */
738 MI_ParameterDecl * Class_Clone_Parameter(
739 _Inout_ Batch *batch,
740 MI_ParameterDecl MI_CONST* parameter,
741 const MI_Char *className)
742 {
743 MI_ParameterDecl *newParameter = Batch_Get(batch, sizeof(MI_ParameterDecl));
744 if (newParameter == NULL)
745 {
746 return NULL; /* Returning NULL causes whole batch to destruct */
747 }
748 memset(newParameter, 0, sizeof(*newParameter));
749 newParameter->flags = parameter->flags;
750 newParameter->code = parameter->code;
751 newParameter->name = Batch_Tcsdup(batch, parameter->name);
752 if (newParameter->name == NULL)
753 {
754 return NULL; /* Returning NULL causes whole batch to destruct */
755 }
756 if (parameter->qualifiers && parameter->numQualifiers)
757 krisbash 1.1 {
758 newParameter->qualifiers = Class_Clone_Qualifiers(batch, parameter->qualifiers, parameter->numQualifiers);
759 if (newParameter->qualifiers == NULL)
760 {
761 return NULL; /* Returning NULL causes whole batch to destruct */
762 }
763 newParameter->numQualifiers = parameter->numQualifiers;
764 }
765 newParameter->type = parameter->type;
766 if (parameter->className)
767 {
768 newParameter->className = Batch_Tcsdup(batch, parameter->className);
769 if (newParameter->className == NULL)
770 {
771 return NULL; /* Returning NULL causes whole batch to destruct */
772 }
773 }
774 newParameter->subscript = parameter->subscript;
775 newParameter->offset = parameter->offset;
776
777 return newParameter;
778 krisbash 1.1 }
779
780 /*============================================================================
781 *
782 *============================================================================
783 */
784 MI_ParameterDecl MI_CONST* MI_CONST* Class_Clone_Parameters(
785 _Inout_ Batch *batch,
786 MI_ParameterDecl MI_CONST* MI_CONST* parameters,
787 MI_Uint32 numParameters,
788 const MI_Char *className)
789 {
790 MI_ParameterDecl **newParameters = Batch_Get(batch, sizeof(MI_ParameterDecl*)*numParameters);
791 MI_Uint32 parameterIndex = 0;
792 if (newParameters == NULL)
793 {
794 return NULL; /* Returning NULL causes whole batch to destruct */
795 }
796 for (;parameterIndex != numParameters; parameterIndex++)
797 {
798 newParameters[parameterIndex] = Class_Clone_Parameter(batch, parameters[parameterIndex], className);
799 krisbash 1.1 if (newParameters[parameterIndex] == NULL)
800 {
801 return NULL; /* Returning NULL causes whole batch to destruct */
802 }
803 }
804
805 return newParameters;
806 }
807
808 /*============================================================================
809 *
810 *============================================================================
811 */
812 MI_MethodDecl * Class_Clone_Method(
813 _Inout_ Batch *batch,
814 MI_MethodDecl MI_CONST* method,
815 const MI_Char *className)
816 {
817 MI_MethodDecl *newMethod = Batch_Get(batch, sizeof(MI_MethodDecl));
818 if (newMethod == NULL)
819 {
820 krisbash 1.1 return NULL; /* Returning NULL causes whole batch to destruct */
821 }
822 memset(newMethod, 0, sizeof(*newMethod));
823 newMethod->flags = method->flags;
824 newMethod->code = method->code;
825 newMethod->name = Batch_Tcsdup(batch, method->name);
826 if (newMethod->name == NULL)
827 {
828 return NULL; /* Returning NULL causes whole batch to destruct */
829 }
830 if (method->qualifiers && method->numQualifiers)
831 {
832 newMethod->qualifiers = Class_Clone_Qualifiers(batch, method->qualifiers, method->numQualifiers);
833 if (newMethod->qualifiers == NULL)
834 {
835 return NULL; /* Returning NULL causes whole batch to destruct */
836 }
837 newMethod->numQualifiers = method->numQualifiers;
838 }
839 if (method->parameters && method->numParameters)
840 {
841 krisbash 1.1 newMethod->parameters = Class_Clone_Parameters(batch, method->parameters, method->numParameters, className);
842 if (newMethod->parameters == NULL)
843 {
844 return NULL; /* Returning NULL causes whole batch to destruct */
845 }
846 newMethod->numParameters = method->numParameters;
847 }
848 newMethod->size = method->size;
849 newMethod->returnType = method->returnType;
850 if (method->origin)
851 {
852 newMethod->origin = Batch_Tcsdup(batch, method->origin);
853 if (newMethod->origin == NULL)
854 {
855 return NULL; /* Returning NULL causes whole batch to destruct */
856 }
857 }
858 if (method->propagator)
859 {
860 newMethod->propagator = Batch_Tcsdup(batch, method->propagator);
861 if (newMethod->propagator == NULL)
862 krisbash 1.1 {
863 return NULL; /* Returning NULL causes whole batch to destruct */
864 }
865 }
866 /* Leave owning schema NULL otherwise we would need to potentially clone that and every other class in there */
867 newMethod->schema = NULL;
868 newMethod->function = method->function;
869 return newMethod;
870 }
871 /*============================================================================
872 *
873 *============================================================================
874 */
875 MI_MethodDecl MI_CONST* MI_CONST* Class_Clone_Methods(
876 _Inout_ Batch *batch,
877 MI_MethodDecl MI_CONST* MI_CONST* methods,
878 MI_Uint32 numMethod,
879 const MI_Char *className)
880 {
881 MI_MethodDecl **newMethods = Batch_Get(batch, sizeof(MI_MethodDecl*)*numMethod);
882 MI_Uint32 methodIndex = 0;
883 krisbash 1.1 if (newMethods == NULL)
884 {
885 return NULL; /* Returning NULL causes whole batch to destruct */
886 }
887 for (;methodIndex != numMethod; methodIndex++)
888 {
889 newMethods[methodIndex] = Class_Clone_Method(batch, methods[methodIndex], className);
890 if (newMethods[methodIndex] == NULL)
891 {
892 return NULL; /* Returning NULL causes whole batch to destruct */
893 }
894 }
895
896 return newMethods;
897 }
898
899 /*============================================================================
900 *
901 *============================================================================
902 */
903 MI_ClassDecl* Class_Clone_ClassDecl(
904 krisbash 1.1 _Inout_ Batch *batch,
905 _In_ const MI_ClassDecl *classDecl)
906 {
907 MI_ClassDecl *newClassDecl = Batch_Get(batch, sizeof(MI_ClassDecl));
908 if (newClassDecl == NULL)
909 {
910 return NULL; /* Returning NULL causes whole batch to destruct */
911 }
912 memset(newClassDecl, 0, sizeof(MI_ClassDecl));
913
914 newClassDecl->flags = classDecl->flags;
915 newClassDecl->code = classDecl->code;
916 newClassDecl->name = Batch_Tcsdup(batch, classDecl->name);
917 if (newClassDecl->name == NULL)
918 {
919 return NULL; /* Returning NULL causes whole batch to destruct */
920 }
921 if (classDecl->qualifiers && classDecl->numQualifiers)
922 {
923 newClassDecl->qualifiers = Class_Clone_Qualifiers(batch, classDecl->qualifiers, classDecl->numQualifiers);
924 if (newClassDecl->qualifiers == NULL)
925 krisbash 1.1 {
926 return NULL; /* Returning NULL causes whole batch to destruct */
927 }
928 newClassDecl->numQualifiers = classDecl->numQualifiers;
929 }
930 if (classDecl->properties && classDecl->numProperties)
931 {
932 newClassDecl->properties = Class_Clone_Properties(batch, classDecl->properties, classDecl->numProperties);
933 if (newClassDecl->properties == NULL)
934 {
935 return NULL; /* Returning NULL causes whole batch to destruct */
936 }
937 newClassDecl->numProperties = classDecl->numProperties;
938 }
939 newClassDecl->size = classDecl->size;
940 if (classDecl->superClass)
941 {
942 newClassDecl->superClass = Batch_Tcsdup(batch, classDecl->superClass);
943 if (newClassDecl->superClass == NULL)
944 {
945 return NULL; /* Returning NULL causes whole batch to destruct */
946 krisbash 1.1 }
947 }
948 if (classDecl->superClassDecl)
949 {
950 newClassDecl->superClassDecl = Class_Clone_ClassDecl(batch, classDecl->superClassDecl);
951 if (newClassDecl->superClassDecl == NULL)
952 {
953 return NULL; /* Returning NULL causes whole batch to destruct */
954 }
955 if (classDecl->superClassDecl->owningClass != 0)
956 newClassDecl->superClassDecl->owningClass = (MI_Class*)-1;
957 }
958 if (classDecl->methods && classDecl->numMethods)
959 {
960 newClassDecl->methods = Class_Clone_Methods(batch, classDecl->methods, classDecl->numMethods, classDecl->name);
961 if (newClassDecl->methods == NULL)
962 {
963 return NULL; /* Returning NULL causes whole batch to destruct */
964 }
965 newClassDecl->numMethods = classDecl->numMethods;
966 }
967 krisbash 1.1 /* Leave owning schema NULL otherwise we would need to potentially clone that and every other class in there */
968 newClassDecl->providerFT = classDecl->providerFT;
969
970 return newClassDecl;
971 }
972
973
974
975 /*============================================================================
976 *
977 *============================================================================
978 */
979 MI_EXTERN_C MI_Result MI_CALL Class_Construct(MI_Class* self, const MI_ClassDecl* classDecl)
980 {
981 if ((self == NULL) || (classDecl == NULL))
982 {
983 return MI_RESULT_INVALID_PARAMETER;
984 }
985
986 memset(self, 0, sizeof(MI_Class));
987
988 krisbash 1.1 self->classDecl = (MI_CONST MI_ClassDecl *)classDecl;
989 self->ft = (MI_ClassFT *)(&g_ClassExtendedFTInternal);
990
991 return MI_RESULT_OK;
992 }
993
994 /*============================================================================
995 *
996 *============================================================================
997 */
998 MI_Result MI_CALL Class_GetClassName(
999 _In_ const MI_Class* self,
1000 _Outptr_result_maybenull_z_ const MI_Char** className)
1001 {
1002 if ((self == NULL) || (className == NULL))
1003 {
1004 return MI_RESULT_INVALID_PARAMETER;
1005 }
1006 *className = self->classDecl->name;
1007
1008 return MI_RESULT_OK;
1009 krisbash 1.1 }
1010
1011 /*============================================================================
1012 *
1013 *============================================================================
1014 */
1015 MI_Result MI_CALL Class_GetNameSpace(
1016 _In_ const MI_Class* self,
1017 _Outptr_result_maybenull_z_ const MI_Char** nameSpace)
1018 {
1019 if ((self == NULL) || (nameSpace == NULL))
1020 {
1021 return MI_RESULT_INVALID_PARAMETER;
1022 }
1023 *nameSpace = self->namespaceName;
1024
1025 return MI_RESULT_OK;
1026 }
1027
1028 /*============================================================================
1029 *
1030 krisbash 1.1 *============================================================================
1031 */
1032 MI_Result MI_CALL Class_GetServerName(
1033 _In_ const MI_Class* self,
1034 _Outptr_result_maybenull_z_ const MI_Char** serverName)
1035 {
1036 if ((self == NULL) || (serverName == NULL))
1037 {
1038 return MI_RESULT_INVALID_PARAMETER;
1039 }
1040 *serverName = self->serverName;
1041
1042 return MI_RESULT_OK;
1043 }
1044
1045 /*============================================================================
1046 *
1047 *============================================================================
1048 */
1049 MI_Result MI_CALL Class_GetElementCount(
1050 _In_ const MI_Class* self,
1051 krisbash 1.1 _Out_ MI_Uint32* count)
1052 {
1053 if ((self == NULL) || (count == NULL))
1054 {
1055 return MI_RESULT_INVALID_PARAMETER;
1056 }
1057
1058 *count = self->classDecl->numProperties;
1059
1060 return MI_RESULT_OK;
1061 }
1062
1063 /*============================================================================
1064 *
1065 *============================================================================
1066 */
1067 MI_Result MI_CALL Class_GetElement(
1068 _In_ const MI_Class* self,
1069 _In_z_ const MI_Char* name,
1070 _Out_opt_ MI_Value* value,
1071 _Out_opt_ MI_Boolean* valueExists,
1072 krisbash 1.1 _Out_opt_ MI_Type* type,
1073 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1074 _Out_opt_ MI_QualifierSet *qualifierSet,
1075 _Out_opt_ MI_Uint32* flags,
1076 _Out_opt_ MI_Uint32* index)
1077 {
1078 MI_Uint32 ourIndex;
1079 MI_Uint32 code;
1080
1081 if ((self == NULL) || (name == NULL))
1082 {
1083 return MI_RESULT_INVALID_PARAMETER;
1084 }
1085
1086 code = Hash(name);
1087
1088 for (ourIndex = 0; ourIndex < self->classDecl->numProperties; ourIndex++)
1089 {
1090 if (self->classDecl->properties[ourIndex]->code == code && Tcscasecmp(name, self->classDecl->properties[ourIndex]->name) == 0)
1091 {
1092 MI_Result result;
1093 krisbash 1.1
1094 result = MI_Class_GetElementAt(self, ourIndex, NULL, value, valueExists, type, referenceClass, qualifierSet, flags);
1095 if ((result == MI_RESULT_OK) && index)
1096 {
1097 *index = ourIndex;
1098 }
1099 return result;
1100 }
1101 }
1102 return MI_RESULT_NO_SUCH_PROPERTY;
1103 }
1104
1105 /*============================================================================
1106 *
1107 *============================================================================
1108 */
1109 MI_Result MI_CALL Class_GetElementAt(
1110 _In_ const MI_Class* self,
1111 MI_Uint32 index,
1112 _Outptr_result_maybenull_z_ const MI_Char** name,
1113 _Out_opt_ MI_Value* value,
1114 krisbash 1.1 _Out_opt_ MI_Boolean* valueExists,
1115 _Out_opt_ MI_Type* type,
1116 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1117 _Out_opt_ MI_QualifierSet *qualifierSet,
1118 _Out_opt_ MI_Uint32* flags)
1119 {
1120 const MI_PropertyDecl *propertyDecl;
1121
1122 if (self == NULL)
1123 {
1124 return MI_RESULT_INVALID_PARAMETER;
1125 }
1126 if (index >= self->classDecl->numProperties)
1127 {
1128 return MI_RESULT_NO_SUCH_PROPERTY;
1129 }
1130 propertyDecl = self->classDecl->properties[index];
1131 if (name)
1132 {
1133 *name = propertyDecl->name;
1134 }
1135 krisbash 1.1 if (valueExists)
1136 {
1137 *valueExists = (propertyDecl->value != NULL);
1138 }
1139 if (value)
1140 {
1141 GetMIValueFromVoid(propertyDecl->type, propertyDecl->value, value);
1142 }
1143 if (type)
1144 {
1145 *type = (MI_Type) propertyDecl->type;
1146 }
1147 if (referenceClass)
1148 {
1149 *referenceClass = propertyDecl->className;
1150 }
1151 if (qualifierSet)
1152 {
1153 qualifierSet->ft = &g_qualifierFT;
1154 qualifierSet->reserved1 = propertyDecl->numQualifiers;
1155 qualifierSet->reserved2 = (ptrdiff_t)propertyDecl->qualifiers;
1156 krisbash 1.1 }
1157 if (flags)
1158 {
1159 *flags = propertyDecl->flags;
1160 }
1161
1162 return MI_RESULT_OK;
1163 }
1164
1165 /*============================================================================
1166 *
1167 *============================================================================
1168 */
1169 MI_Result MI_CALL Class_GetClassFlagsExt(
1170 _In_ const MI_Class* self,
1171 _Out_ MI_Uint32* flags)
1172 {
1173 if ((self == NULL) || (flags == NULL))
1174 {
1175 return MI_RESULT_INVALID_PARAMETER;
1176 }
1177 krisbash 1.1
1178 *flags = self->classDecl->flags;
1179
1180 return MI_RESULT_OK;
1181 }
1182
1183 /*============================================================================
1184 *
1185 *============================================================================
1186 */
1187 MI_Result MI_CALL Class_GetElementAtExt(
1188 _In_ const MI_Class* self,
1189 MI_Uint32 index,
1190 _Outptr_opt_result_maybenull_z_ const MI_Char** name,
1191 _Out_opt_ MI_Value* value,
1192 _Out_opt_ MI_Boolean* valueExists,
1193 _Out_opt_ MI_Type* type,
1194 _Out_opt_ MI_Uint32* subscript,
1195 _Out_opt_ MI_Uint32* offset,
1196 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1197 _Outptr_opt_result_maybenull_z_ MI_Char **originClass,
1198 krisbash 1.1 _Outptr_opt_result_maybenull_z_ MI_Char **propagatorClass,
1199 _Out_opt_ MI_QualifierSet *qualifierSet,
1200 _Out_opt_ MI_Uint32* flags)
1201 {
1202 const MI_PropertyDecl *propertyDecl;
1203
1204 MI_Result result = Class_GetElementAt(self, index, name, value, valueExists, type, referenceClass, qualifierSet, flags);
1205
1206 if(result != MI_RESULT_OK)
1207 {
1208 return result;
1209 }
1210
1211 propertyDecl = self->classDecl->properties[index];
1212
1213 if(subscript)
1214 {
1215 *subscript = propertyDecl->subscript;
1216 }
1217
1218 if(offset)
1219 krisbash 1.1 {
1220 *offset = propertyDecl->offset;
1221 }
1222
1223 if(originClass)
1224 {
1225 *originClass = propertyDecl->origin;
1226 }
1227
1228 if(propagatorClass)
1229 {
1230 *propagatorClass = propertyDecl->propagator;
1231 }
1232
1233 return MI_RESULT_OK;
1234 }
1235
1236 /*============================================================================
1237 *
1238 *============================================================================
1239 */
1240 krisbash 1.1 MI_Result MI_CALL Class_GetClassQualifierSet(
1241 _In_ const MI_Class* self,
1242 _Out_opt_ MI_QualifierSet *qualifierSet
1243 )
1244 {
1245 if ((self == NULL) ||
1246 (qualifierSet == NULL))
1247 {
1248 return MI_RESULT_INVALID_PARAMETER;
1249 }
1250
1251 qualifierSet->ft = &g_qualifierFT;
1252 qualifierSet->reserved1 = self->classDecl->numQualifiers;
1253 qualifierSet->reserved2 = (ptrdiff_t) self->classDecl->qualifiers;
1254
1255 return MI_RESULT_OK;
1256 }
1257
1258 /*============================================================================
1259 *
1260 *============================================================================
1261 krisbash 1.1 */
1262 MI_Result MI_CALL Class_GetMethodCount(
1263 _In_ const MI_Class* self,
1264 _Out_ MI_Uint32* count)
1265 {
1266 if ((self == NULL) || (count == NULL))
1267 {
1268 return MI_RESULT_INVALID_PARAMETER;
1269 }
1270
1271 *count = self->classDecl->numMethods;
1272
1273 return MI_RESULT_OK;
1274 }
1275
1276 /*============================================================================
1277 *
1278 *============================================================================
1279 */
1280 MI_Result MI_CALL Class_GetMethodAt(
1281 _In_ const MI_Class *self,
1282 krisbash 1.1 MI_Uint32 index,
1283 _Outptr_result_z_ const MI_Char **name,
1284 _Out_opt_ MI_QualifierSet *qualifierSet,
1285 _Out_opt_ MI_ParameterSet *parameterSet
1286 )
1287 {
1288 const MI_MethodDecl * methodDecl;
1289
1290 if ((self == NULL) || (name == NULL))
1291 {
1292 return MI_RESULT_INVALID_PARAMETER;
1293 }
1294
1295 if (index >= self->classDecl->numMethods)
1296 {
1297 return MI_RESULT_METHOD_NOT_FOUND;
1298 }
1299 methodDecl = self->classDecl->methods[index];
1300
1301 *name = methodDecl->name;
1302
1303 krisbash 1.1 if (qualifierSet)
1304 {
1305 const MI_QualifierSetFT **ft = (const MI_QualifierSetFT**)&qualifierSet->ft;
1306 *ft = &g_qualifierFT;
1307 qualifierSet->reserved1 = methodDecl->numQualifiers;
1308 qualifierSet->reserved2 = (ptrdiff_t) methodDecl->qualifiers;
1309 }
1310 if (parameterSet)
1311 {
1312 const MI_ParameterSetFT **ft = (const MI_ParameterSetFT**)¶meterSet->ft;
1313 *ft = (MI_ParameterSetFT *)(&g_parameterExtendedFTInternal);
1314 parameterSet->reserved1 = methodDecl->numParameters;
1315 parameterSet->reserved2 = (ptrdiff_t) methodDecl->parameters;
1316 }
1317 return MI_RESULT_OK;
1318 }
1319
1320 /*============================================================================
1321 *
1322 *============================================================================
1323 */
1324 krisbash 1.1 MI_Result MI_CALL Class_GetMethodAtExt(
1325 _In_ const MI_Class *self,
1326 MI_Uint32 index,
1327 _Outptr_result_z_ const MI_Char **name,
1328 _Outptr_opt_result_maybenull_z_ MI_Char **originClass,
1329 _Outptr_opt_result_maybenull_z_ MI_Char **propagatorClass,
1330 _Out_opt_ MI_QualifierSet *qualifierSet,
1331 _Out_opt_ MI_ParameterSet *parameterSet,
1332 _Out_opt_ MI_Uint32* flags
1333 )
1334 {
1335 const MI_MethodDecl * methodDecl;
1336
1337 MI_Result result = Class_GetMethodAt(self, index, name, qualifierSet, parameterSet);
1338
1339 if(result != MI_RESULT_OK)
1340 {
1341 return result;
1342 }
1343
1344 methodDecl = self->classDecl->methods[index];
1345 krisbash 1.1
1346 if(originClass)
1347 {
1348 *originClass = methodDecl->origin;
1349 }
1350
1351 if(propagatorClass)
1352 {
1353 *propagatorClass = methodDecl->propagator;
1354 }
1355
1356 if(flags)
1357 {
1358 *flags = methodDecl->flags;
1359 }
1360
1361 return MI_RESULT_OK;
1362 }
1363
1364 /*============================================================================
1365 *
1366 krisbash 1.1 *============================================================================
1367 */
1368 MI_Result MI_CALL Class_GetMethod(
1369 _In_ const MI_Class *self,
1370 _In_z_ const MI_Char *name,
1371 _Out_opt_ MI_QualifierSet *qualifierSet,
1372 _Out_opt_ MI_ParameterSet *parameterSet,
1373 _Out_opt_ MI_Uint32 *index
1374 )
1375 {
1376 MI_Uint32 ourIndex;
1377 MI_Uint32 code;
1378
1379 if ((self == NULL) || (name == NULL))
1380 {
1381 return MI_RESULT_INVALID_PARAMETER;
1382 }
1383
1384 code = Hash(name);
1385
1386 for (ourIndex = 0; ourIndex < self->classDecl->numMethods; ourIndex++)
1387 krisbash 1.1 {
1388 if (self->classDecl->methods[ourIndex]->code == code && Tcscasecmp(name, self->classDecl->methods[ourIndex]->name) == 0)
1389 {
1390 MI_Result result;
1391 const MI_Char *tmpName = NULL;
1392
1393 result = MI_Class_GetMethodAt(self, ourIndex, &tmpName, qualifierSet, parameterSet);
1394 if ((result == MI_RESULT_OK) && index)
1395 {
1396 *index = ourIndex;
1397 }
1398 return result;
1399 }
1400 }
1401 return MI_RESULT_METHOD_NOT_FOUND;
1402 }
1403
1404 /*============================================================================
1405 *
1406 *============================================================================
1407 */
1408 krisbash 1.1 MI_Result MI_CALL Class_GetParentClassName(
1409 _In_ const MI_Class *self,
1410 _Outptr_result_maybenull_z_ const MI_Char **name)
1411 {
1412 if ((self == NULL) || (name == NULL))
1413 {
1414 return MI_RESULT_INVALID_PARAMETER;
1415 }
1416
1417 *name = self->classDecl->superClass;
1418
1419 if (self->classDecl->superClass)
1420 {
1421 return MI_RESULT_OK;
1422 }
1423 else
1424 {
1425 return MI_RESULT_INVALID_SUPERCLASS;
1426 }
1427 }
1428
1429 krisbash 1.1 /*============================================================================
1430 * Not implemented since it is not required right now
1431 *============================================================================
1432 */
1433 MI_Result MI_CALL Class_GetParentClass(
1434 _In_ const MI_Class *self,
1435 _Outptr_ MI_Class **parentClass)
1436 {
1437 return MI_RESULT_FAILED;
1438 }
1439
1440 /*============================================================================
1441 *
1442 *============================================================================
1443 */
1444 MI_Result MI_CALL GetParentClassExt(
1445 _In_ const MI_Class* self,
1446 _Out_ MI_Class *parentClass)
1447 {
1448 if ((self == NULL) || (parentClass == NULL))
1449 {
1450 krisbash 1.1 return MI_RESULT_INVALID_PARAMETER;
1451 }
1452
1453 if(self->classDecl->superClassDecl)
1454 {
1455 return Class_Construct(parentClass, self->classDecl->superClassDecl);
1456 }
1457 else
1458 {
1459 return MI_RESULT_INVALID_SUPERCLASS;
1460 }
1461 }
1462
1463 /*============================================================================
1464 * Not implemented since it is not required right now; contract is Delete should never fail; so returning MI_RESULT_OK
1465 *============================================================================
1466 */
1467 MI_Result MI_CALL Class_RCDelete(
1468 _In_ MI_Class* self_)
1469 {
1470 MI_RCClass *self = (MI_RCClass*) self_;
1471 krisbash 1.1 if(self->refcount)
1472 {
1473 /* We were created from a _New, not a construct */
1474 if (Atomic_Dec(&self->refcount) == 0)
1475 {
1476 if (self->batch)
1477 Batch_Delete(self->batch);
1478 }
1479 }
1480 return MI_RESULT_OK;
1481 }
1482
1483 /*============================================================================
1484 * Not implemented since it is not required right now
1485 *============================================================================
1486 */
1487 MI_Result MI_CALL Class_RCClone(
1488 _In_ const MI_Class* self_,
1489 _Outptr_ MI_Class** outboundNewClass)
1490 {
1491 MI_RCClass *self = (MI_RCClass*) self_;
1492 krisbash 1.1 if (self->refcount == 0)
1493 {
1494 /* Created via construct so don't support clone */
1495 return MI_RESULT_FAILED;
1496 }
1497 else
1498 {
1499 /* Created via _New so we are refcounted */
1500 *outboundNewClass = (MI_Class*) self_;
1501 Atomic_Inc(&self->refcount);
1502 return MI_RESULT_OK;
1503 }
1504
1505 }
1506
1507 /*============================================================================
1508 *
1509 *============================================================================
1510 */
1511 MI_Result MI_CALL ParameterSet_GetParameterCount(
1512 _In_ const MI_ParameterSet *self,
1513 krisbash 1.1 _Out_ MI_Uint32 *count)
1514 {
1515 if (self && count)
1516 {
1517 *count = (MI_Uint32)self->reserved1;
1518 if (*count != 0)
1519 {
1520 (*count)--; /* Adjust for return type that is parameter[0] */
1521 }
1522 return MI_RESULT_OK;
1523 }
1524 else
1525 {
1526 return MI_RESULT_INVALID_PARAMETER;
1527 }
1528 }
1529
1530 /*============================================================================
1531 *
1532 *============================================================================
1533 */
1534 krisbash 1.1 MI_Result _ParameterSet_GetParameterAt(
1535 _In_ const MI_ParameterSet *self,
1536 MI_Uint32 index,
1537 _Outptr_result_z_ const MI_Char **name,
1538 _Out_ MI_Type *parameterType,
1539 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1540 _Out_ MI_QualifierSet *qualifierSet)
1541 {
1542 MI_ParameterDecl **parameterDecl;
1543
1544 if ((self == NULL) || (name == NULL) || (parameterType == NULL) || (qualifierSet == NULL))
1545 {
1546 return MI_RESULT_INVALID_PARAMETER;
1547 }
1548
1549 if (index >= self->reserved1)
1550 {
1551 /* index too high */
1552 return MI_RESULT_NOT_FOUND;
1553 }
1554
1555 krisbash 1.1 parameterDecl = (MI_ParameterDecl**) self->reserved2;
1556 *name = parameterDecl[index]->name;
1557 *parameterType = parameterDecl[index]->type;
1558 (*qualifierSet).ft = &g_qualifierFT;
1559 (*qualifierSet).reserved1 = parameterDecl[index]->numQualifiers;
1560 (*qualifierSet).reserved2 = (ptrdiff_t) parameterDecl[index]->qualifiers;
1561 if (referenceClass)
1562 {
1563 *referenceClass = parameterDecl[index]->className;
1564 }
1565 return MI_RESULT_OK;
1566 }
1567
1568 /*============================================================================
1569 *
1570 *============================================================================
1571 */
1572 MI_Result MI_CALL ParameterSet_GetMethodReturnType(
1573 _In_ const MI_ParameterSet *self,
1574 _Out_ MI_Type *returnType,
1575 _Out_ MI_QualifierSet *qualifierSet)
1576 krisbash 1.1 {
1577 const MI_Char *name = NULL;
1578 MI_Char *referenceClassName = NULL;
1579
1580 /* Return details are always at parameter[0] */
1581 return _ParameterSet_GetParameterAt(self, 0, &name, returnType, &referenceClassName, qualifierSet);
1582 }
1583
1584 /*============================================================================
1585 *
1586 *============================================================================
1587 */
1588 MI_Result MI_CALL ParameterSet_GetParameterAt(
1589 _In_ const MI_ParameterSet *self,
1590 MI_Uint32 index,
1591 _Outptr_result_z_ const MI_Char **name,
1592 _Out_ MI_Type *parameterType,
1593 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1594 _Out_ MI_QualifierSet *qualifierSet)
1595 {
1596 /* Return details are always at parameter[0] and can only be accessed through ParameterSet_GetMethodReturnType so
1597 krisbash 1.1 skip over it. Count was adjusted to compensate in ParameterSet_GetParameterCount to remove return item */
1598 index++;
1599
1600 return _ParameterSet_GetParameterAt(self, index, name, parameterType, referenceClass, qualifierSet);
1601 }
1602
1603 /*============================================================================
1604 *
1605 *============================================================================
1606 */
1607 MI_Result MI_CALL ParameterSet_GetParameterAtExt(
1608 _In_ const MI_ParameterSet *self,
1609 MI_Uint32 index,
1610 _Outptr_result_z_ const MI_Char **name,
1611 MI_Type *parameterType,
1612 _Out_opt_ MI_Uint32* subscript,
1613 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1614 _Out_ MI_QualifierSet *qualifierSet,
1615 _Out_opt_ MI_Uint32* flags)
1616 {
1617 MI_ParameterDecl **parameterDecl;
1618 krisbash 1.1 MI_Result result = ParameterSet_GetParameterAt(self, index, name, parameterType, referenceClass, qualifierSet);
1619
1620 if(result != MI_RESULT_OK)
1621 {
1622 return result;
1623 }
1624
1625 /* Return details are always at parameter[0] and can only be accessed through ParameterSet_GetMethodReturnType so
1626 skip over it. Count was adjusted to compensate in ParameterSet_GetParameterCount to remove return item */
1627 index++;
1628
1629 parameterDecl = (MI_ParameterDecl**) self->reserved2;
1630
1631 if(subscript)
1632 {
1633 *subscript = parameterDecl[index]->subscript;
1634 }
1635
1636 if(flags)
1637 {
1638 *flags = parameterDecl[index]->flags;
1639 krisbash 1.1 }
1640
1641 return MI_RESULT_OK;
1642 }
1643
1644 /*============================================================================
1645 *
1646 *============================================================================
1647 */
1648 MI_Result MI_CALL ParameterSet_GetParameter(
1649 _In_ const MI_ParameterSet *self,
1650 _In_z_ const MI_Char *name,
1651 _Out_ MI_Type *parameterType,
1652 _Outptr_opt_result_maybenull_z_ MI_Char **referenceClass,
1653 _Out_ MI_QualifierSet *qualifierSet,
1654 _Out_ MI_Uint32 *index)
1655 {
1656 MI_Uint32 myIndex;
1657 MI_Uint32 code;
1658
1659 if ((self == NULL) || (name == NULL) || (parameterType == NULL) || (qualifierSet == NULL) || (index == NULL))
1660 krisbash 1.1 {
1661 return MI_RESULT_INVALID_PARAMETER;
1662 }
1663
1664 code = Hash(name);
1665
1666 /* Remember, skipping over return type that is parameter[0] */
1667 for (myIndex = 1; myIndex < self->reserved1; myIndex++)
1668 {
1669 MI_ParameterDecl **parameterDecl = (MI_ParameterDecl**) self->reserved2;
1670 if (parameterDecl[myIndex]->code == code && Tcscasecmp(name, parameterDecl[myIndex]->name) == 0)
1671 {
1672 MI_Result tmpResult;
1673 const MI_Char *tmpName = NULL;
1674 tmpResult = _ParameterSet_GetParameterAt(self, myIndex, &tmpName, parameterType, referenceClass, qualifierSet);
1675 if (tmpResult == MI_RESULT_OK)
1676 {
1677 *index = (myIndex-1);
1678 }
1679 return tmpResult;
1680 }
1681 krisbash 1.1 }
1682
1683 return MI_RESULT_NOT_FOUND;
1684 }
1685
1686
1687 /*============================================================================
1688 *
1689 *============================================================================
1690 */
1691 MI_Result MI_CALL QualifierSet_GetQualifierCount(
1692 _In_ const MI_QualifierSet *self,
1693 _Out_ MI_Uint32 *count)
1694 {
1695 if ((self == NULL) || (count == NULL))
1696 {
1697 return MI_RESULT_INVALID_PARAMETER;
1698 }
1699 *count = (MI_Uint32) self->reserved1;
1700 return MI_RESULT_OK;
1701 }
1702 krisbash 1.1
1703 /*============================================================================
1704 *
1705 *============================================================================
1706 */
1707 MI_Result MI_CALL QualifierSet_GetQualifierAt(
1708 _In_ const MI_QualifierSet *self,
1709 MI_Uint32 index,
1710 _Outptr_result_z_ const MI_Char **name,
1711 _Out_ MI_Type *qualifierType,
1712 _Out_ MI_Uint32 *qualifierFlags, /* scope information */
1713 _Out_ MI_Value *qualifierValue
1714 )
1715 {
1716 MI_Qualifier **qualifierDecl;
1717
1718 if ((self == NULL) || (name == NULL) || (qualifierType == NULL) || (qualifierFlags == NULL) || (qualifierValue == NULL))
1719 {
1720 return MI_RESULT_INVALID_PARAMETER;
1721 }
1722 if (index >= self->reserved1)
1723 krisbash 1.1 {
1724 return MI_RESULT_NOT_FOUND;
1725 }
1726
1727 qualifierDecl = (MI_Qualifier**) self->reserved2;
1728 *name = qualifierDecl[index]->name;
1729 *qualifierType = qualifierDecl[index]->type;
1730
1731 *qualifierFlags = qualifierDecl[index]->flavor ;
1732 GetMIValueFromVoid(qualifierDecl[index]->type, qualifierDecl[index]->value, qualifierValue);
1733
1734 return MI_RESULT_OK;
1735 }
1736
1737
1738 /*============================================================================
1739 *
1740 *============================================================================
1741 */
1742 MI_Result MI_CALL QualifierSet_GetQualifier(
1743 _In_ const MI_QualifierSet *self,
1744 krisbash 1.1 _In_z_ const MI_Char *name,
1745 _Out_ MI_Type *qualifierType,
1746 _Out_ MI_Uint32 *qualifierFlags, /* scope information */
1747 _Out_ MI_Value *qualifierValue,
1748 _Out_ MI_Uint32 *index
1749 )
1750 {
1751 MI_Uint32 myIndex;
1752
1753 if ((self == NULL) || (name == NULL) || (qualifierType == NULL) || (qualifierFlags == NULL) || (qualifierValue == NULL) || (index == NULL))
1754 {
1755 return MI_RESULT_INVALID_PARAMETER;
1756 }
1757
1758 for (myIndex = 0; myIndex < self->reserved1; myIndex++)
1759 {
1760 MI_Qualifier **qualifierDecl = (MI_Qualifier**) self->reserved2;
1761 if (Tcscasecmp(name, qualifierDecl[myIndex]->name) == 0)
1762 {
1763 MI_Result tmpResult;
1764 const MI_Char *tmpName = NULL;
1765 krisbash 1.1 tmpResult = QualifierSet_GetQualifierAt(self, myIndex, &tmpName, qualifierType, qualifierFlags, qualifierValue);
1766 if (tmpResult == MI_RESULT_OK)
1767 {
1768 *index = myIndex;
1769 }
1770 return tmpResult;
1771 }
1772 }
1773
1774 return MI_RESULT_NOT_FOUND;
1775 }
1776
1777 /*Qualifier can be propogated only if
1778 1) It has ToSubClass qualifier
1779 2) It it not restricted. WMIV1 has no mechanism to tell if a qualifier is restricted, hence
1780 we are building the list of qualifiers we know are restricted. Note in future DMTF might introduce
1781 some more standard qualifiers which are not covered in this list.
1782 */
1783
1784 MI_Char *restrictedQualifier[] = {
1785 ZT("Abstract"),
1786 krisbash 1.1 ZT("Deprecated"),
1787 ZT("Experimental"),
1788 ZT("Override"),
1789 ZT("Version"),
1790 ZT("ClassVersion")
1791 };
1792 MI_Boolean CanQualifierBePropogated( _In_ MI_Qualifier *qualifier)
1793 {
1794 if(qualifier->flavor & MI_FLAG_TOSUBCLASS )
1795 {
1796 MI_Uint32 iCount;
1797 //Additional verification for other qualifiers.
1798 for(iCount = 0 ; iCount < (sizeof(restrictedQualifier)/sizeof(MI_Char*));iCount++)
1799 {
1800 if(Tcscasecmp(qualifier->name, restrictedQualifier[iCount]) == 0 )
1801 {
1802 return MI_FALSE;
1803 }
1804 }
1805 return MI_TRUE;
1806 }
1807 krisbash 1.1 return MI_FALSE;
1808 }
1809
1810 const MI_ClassExtendedFTInternal g_ClassExtendedFTInternal =
1811 {
1812 Class_GetClassName,
1813 Class_GetNameSpace,
1814 Class_GetServerName,
1815 Class_GetElementCount,
1816 Class_GetElement,
1817 Class_GetElementAt,
1818 Class_GetClassQualifierSet,
1819 Class_GetMethodCount,
1820 Class_GetMethodAt,
1821 Class_GetMethod,
1822 Class_GetParentClassName,
1823 Class_GetParentClass,
1824 Class_RCDelete,
1825 Class_RCClone,
1826 Class_GetClassFlagsExt,
1827 GetParentClassExt,
1828 krisbash 1.1 Class_GetElementAtExt,
1829 Class_GetMethodAtExt
1830 };
1831
1832 const MI_QualifierSetFT g_qualifierFT =
1833 {
1834 QualifierSet_GetQualifierCount,
1835 QualifierSet_GetQualifierAt,
1836 QualifierSet_GetQualifier
1837 };
1838
1839 const MI_ParameterSetExtendedFTInternal g_parameterExtendedFTInternal =
1840 {
1841 ParameterSet_GetMethodReturnType,
1842 ParameterSet_GetParameterCount,
1843 ParameterSet_GetParameterAt,
1844 ParameterSet_GetParameter,
1845 ParameterSet_GetParameterAtExt
1846 };
1847
|