1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
|
8 krisbash 1.5 ** 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 mike 1.1 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15 krisbash 1.5 ** 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 mike 1.1 **
|
19 krisbash 1.5 ** See the Apache 2 License for the specific language governing permissions
|
20 mike 1.1 ** and limitations under the License.
21 **
22 **==============================================================================
23 */
24
25 #include <ctype.h>
26 #include "instance.h"
27 #include "helpers.h"
28 #include "naming.h"
29 #include "types.h"
30 #include "schemadecl.h"
31 #include "alloc.h"
32 #include "field.h"
|
33 krisbash 1.4 #include "class.h"
|
34 krisbash 1.5 #include <pal/intsafe.h>
|
35 krisbash 1.4 #include <stdio.h>
36 #ifdef _MSC_VER
37 #pragma prefast (disable: 28252)
38 #pragma prefast (disable: 28253)
39 #endif
40 #include <wchar.h>
|
41 mike 1.1
42
43 /*
44 **==============================================================================
45 **
46 ** Local definitions
47 **
48 **==============================================================================
49 */
50
51 /* Magic number of InstanceHeader */
52 static MI_Uint32 _MAGIC = 0xB26AEA60;
53
54 /* Number of default pages for a self-owned batch object */
|
55 krisbash 1.4 static MI_Uint32 _NUM_PAGES = INFINITE;
|
56 mike 1.1
57 /* The minimum number of reserved properties for a dynamic instance */
|
58 krisbash 1.5 static size_t _CAPACITY = 32;
|
59 mike 1.1
60 /* Find capacity (lesser of _CAPACITY or x rounded to power of 2) */
|
61 krisbash 1.5 static size_t _FindCapacity(size_t x)
|
62 mike 1.1 {
63 if (x <= _CAPACITY)
64 return _CAPACITY;
65 else
66 {
|
67 krisbash 1.5 size_t r = x - 1;
|
68 mike 1.1
69 r |= (r >> 1);
70 r |= (r >> 2);
71 r |= (r >> 4);
72 r |= (r >> 8);
73 r |= (r >> 16);
74
75 return r + 1;
76 }
77 }
78
|
79 krisbash 1.5 /*
|
80 mike 1.1 * Obtains the self pointer for this instance. For static instances, this
81 * it is the same as the instance parameter. For dynamic instances, the
82 * self pointer is given by instance->self.
83 */
84 MI_INLINE Instance* _SelfOf(const MI_Instance* instance)
85 {
86 Instance* self = (Instance*)instance;
87
88 if (self)
89 {
90 if (self->self)
91 self = self->self;
92
93 return self;
94 }
95
96 DEBUG_ASSERT(0);
97 return NULL;
98 }
99
|
100 krisbash 1.4 /* Return the index of the given property */
101 MI_Uint32 _FindFeatureDecl(
102 MI_FeatureDecl** features,
103 MI_Uint32 numFeatures,
104 const MI_Char* name)
105 {
106 MI_Uint32 code;
107 MI_FeatureDecl** start = features;
108 MI_FeatureDecl** p = start;
109 MI_FeatureDecl** end = start + numFeatures;
110
111 /* Zero-length CIM names are illegal */
112 if (*name == '\0')
113 return (MI_Uint32)-1;
114
115 code = Hash(name);
116
117 /* Find the property */
118 while (p != end)
119 {
120 if (p[0]->code == code && Tcscasecmp(p[0]->name, name) == 0)
121 krisbash 1.4 return (MI_Uint32)(p - start);
122 p++;
123 }
124
125 /* Not found */
126 return (MI_Uint32)-1;
127 }
128
129 /* Return the index of the given property */
130 MI_INLINE MI_Uint32 _FindPropertyDeclIndex(
131 const MI_ClassDecl* cd,
132 const MI_Char* name)
133 {
134 return _FindFeatureDecl(
135 (MI_FeatureDecl**)cd->properties,
136 cd->numProperties,
137 name);
138 }
139
|
140 mike 1.1 /* Return the index of the given property or (MI_Uin32)-1 if not found */
141 static MI_Uint32 _FindPropertyDecl(
142 const MI_ClassDecl* cd,
|
143 krisbash 1.4 const ZChar* name)
|
144 mike 1.1 {
145 MI_PropertyDecl** start = cd->properties;
146 MI_PropertyDecl** end = start + cd->numProperties;
147 MI_PropertyDecl** p = start;
148 MI_Uint32 code;
149
150 code = Hash(name);
151
|
152 krisbash 1.5 while (p != end)
|
153 mike 1.1 {
|
154 krisbash 1.4 if ((*p)->code == code && Tcscasecmp((*p)->name, name) == 0)
|
155 mike 1.1 return (MI_Uint32)(p - start);
156 p++;
157 }
158
159 return (MI_Uint32)-1;
160 }
161
|
162 krisbash 1.4
|
163 mike 1.2 static MI_PropertyDecl* _LookupPropertyDecl(
164 const MI_ClassDecl* cd,
|
165 krisbash 1.4 const ZChar* name)
|
166 mike 1.2 {
167 MI_Uint32 index = _FindPropertyDecl(cd, name);
168
169 if (index == (MI_Uint32)-1)
170 return NULL;
171
172 return cd->properties[index];
173 }
|
174 krisbash 1.4 static MI_Qualifier * _CloneQualifierDecl(
175 MI_Qualifier * qualifier,
176 _Inout_ Batch *batch)
177 {
178 MI_Qualifier *newQualifier = Batch_Get(batch, sizeof(MI_Qualifier));
179 if (newQualifier == NULL)
180 {
|
181 krisbash 1.5 return NULL;
|
182 krisbash 1.4 }
183 memset(newQualifier, 0, sizeof(*newQualifier));
184 newQualifier->name = Batch_Tcsdup(batch, qualifier->name);
185 if (newQualifier->name == NULL)
186 {
|
187 krisbash 1.5 return NULL;
|
188 krisbash 1.4 }
189 newQualifier->type = qualifier->type;
190 newQualifier->flavor = qualifier->flavor;
191 /* Clone only boolean values. */
192 if (qualifier->value && qualifier->type == MI_BOOLEAN)
193 {
194 newQualifier->value = Batch_Get(batch, sizeof(MI_Boolean));
195 if (newQualifier->value == NULL)
196 {
197 return NULL;
198 }
199 *(MI_Boolean*)newQualifier->value = *(MI_Boolean*)qualifier->value;
200 }
201 else
202 {
203 newQualifier->value = NULL;
204 }
205
206 return newQualifier;
207 }
208
209 krisbash 1.4 static MI_Qualifier **_CloneQualifierDecls(
210 MI_Qualifier **qualifiers,
211 MI_Uint32 numQualifiers,
212 _Inout_ Batch *batch)
213 {
214 MI_Qualifier **newQualifiers = Batch_Get(batch, sizeof(MI_Qualifier*)*numQualifiers);
215 MI_Uint32 qualifierIndex = 0;
216 if (newQualifiers == NULL)
217 {
|
218 krisbash 1.5 return NULL;
|
219 krisbash 1.4 }
220 for (;qualifierIndex != numQualifiers; qualifierIndex++)
221 {
222 newQualifiers[qualifierIndex] = _CloneQualifierDecl(qualifiers[qualifierIndex], batch);
223 if (newQualifiers[qualifierIndex] == NULL)
224 {
|
225 krisbash 1.5 return NULL;
|
226 krisbash 1.4 }
227 }
228
229 return newQualifiers;
230 }
|
231 mike 1.2
|
232 mike 1.1 static MI_PropertyDecl* _ClonePropertyDecl(
233 const MI_PropertyDecl* pd,
234 Batch* batch)
235 {
236 MI_PropertyDecl* p;
237
238 p = (MI_PropertyDecl*)BCalloc(batch, sizeof(MI_PropertyDecl), CALLSITE);
239
240 if (!p)
241 return NULL;
242
243 if (pd->name)
244 {
245 p->name = BStrdup(batch, pd->name, CALLSITE);
|
246 krisbash 1.4
|
247 mike 1.1 if (!p->name)
248 return NULL;
249 }
250
|
251 krisbash 1.4 p->code = pd->code;
|
252 mike 1.1 p->flags = pd->flags;
253 p->type = pd->type;
254 p->offset = pd->offset;
255
|
256 krisbash 1.4 if (pd->qualifiers && pd->numQualifiers)
257 {
258 p->qualifiers = _CloneQualifierDecls(pd->qualifiers, pd->numQualifiers, batch);
259 if (p->qualifiers == NULL)
260 {
261 return NULL; /* Returning NULL causes whole batch to destruct */
262 }
263 p->numQualifiers = pd->numQualifiers;
|
264 krisbash 1.5 }
|
265 krisbash 1.4
|
266 mike 1.1 return p;
267 }
268
269 static MI_PropertyDecl** _ClonePropertyDecls(
270 MI_PropertyDecl** properties,
|
271 krisbash 1.5 size_t size,
|
272 mike 1.1 Batch* batch)
273 {
274 MI_PropertyDecl** data;
275 MI_Uint32 i;
276
277 /* Allocate at least _CAPACITY properties */
|
278 krisbash 1.5 size_t cap = (size < _CAPACITY) ? _CAPACITY : size;
|
279 mike 1.1
280 /* Allocate properties array */
281 data = (MI_PropertyDecl**)BAlloc(batch, sizeof(MI_PropertyDecl*) * cap,
282 CALLSITE);
283 if (!data)
284 return NULL;
285
286 /* Copy each property */
287 for (i = 0; i < size; i++)
288 {
289 MI_PropertyDecl* pd = _ClonePropertyDecl(properties[i], batch);
290 if (!pd)
291 return NULL;
292
293 data[i] = pd;
294 }
295
296 return data;
297 }
298
|
299 krisbash 1.4 MI_ClassDecl* _CloneClassDecl(
|
300 mike 1.1 const MI_ClassDecl* cd,
301 Batch* batch)
302 {
303 MI_ClassDecl* p;
304
305 /* Instance.classDecl */
306 p = (MI_ClassDecl*)BCalloc(batch, sizeof(MI_ClassDecl), CALLSITE);
307 if (!p)
308 return NULL;
309
310 /* Instance.name */
311 if (cd->name)
312 {
313 p->name = BStrdup(batch, cd->name, CALLSITE);
|
314 krisbash 1.4
|
315 mike 1.1 if (!p->name)
316 return NULL;
317 }
318
|
319 krisbash 1.4 /* Instance.code */
320 p->code = cd->code;
321
|
322 mike 1.1 /* Instance.size */
323 p->size = cd->size;
324
325 /* Instance.properties */
326 {
|
327 krisbash 1.5 p->properties = _ClonePropertyDecls(cd->properties, cd->numProperties,
|
328 mike 1.1 batch);
329
330 if (!p->properties)
331 return NULL;
332
333 p->numProperties = cd->numProperties;
|
334 krisbash 1.5 }
335 p->owningClass = (MI_Class*)-1; //We are using this clone because it is a dynamic classDecl, so mark this classDecl as dynamic
|
336 mike 1.1 return p;
337 }
338
339 MI_INLINE InstanceHeader* _HeaderOf(Instance* self)
340 {
341 return self ? ((InstanceHeader*)self - 1) : NULL;
342 }
343
344 MI_INLINE Instance* _InstanceOf(InstanceHeader* self)
345 {
346 return self ? (Instance*)(self + 1) : NULL;
347 }
348
349 static Instance* _AllocInstance(Batch* batch, size_t size)
350 {
351 InstanceHeader* h = (InstanceHeader*)BCalloc(
|
352 krisbash 1.5 batch,
353 sizeof(InstanceHeader) + size,
|
354 mike 1.1 CALLSITE);
355
356 if (!h)
357 return NULL;
358
359 h->magic = _MAGIC;
360 h->u.refs = 1;
361 return _InstanceOf(h);
362 }
363
364 static Instance* _ReallocInstance(
|
365 krisbash 1.5 Batch* batch,
366 Instance* self,
367 size_t oldSize,
|
368 mike 1.1 size_t newSize)
369 {
370 InstanceHeader* h = (InstanceHeader*)BRealloc(
|
371 krisbash 1.5 batch,
372 _HeaderOf(self),
|
373 mike 1.1 sizeof(InstanceHeader) + oldSize,
374 sizeof(InstanceHeader) + newSize,
375 CALLSITE);
376
377 if (!h)
378 return NULL;
379
380 h->magic = _MAGIC;
381 h->u.refs = 1;
382
383 return _InstanceOf(h);
384 }
385
386 static void _FreeInstance(
|
387 krisbash 1.5 Batch* batch,
|
388 mike 1.1 Instance* self)
389 {
390 InstanceHeader* h = _HeaderOf(self);
391
392 if (h)
393 {
394 DEBUG_ASSERT(h->magic == _MAGIC);
395 #if defined(CONFIG_ENABLE_DEBUG)
396 memset(h, 0xDD, sizeof(InstanceHeader) + sizeof(Instance));
397 #endif
398 BFree(batch, h, CALLSITE);
399 }
400 }
401
402 /*
403 * Each dynamic instance is 'wrapped' inside another instance (referred to
|
404 krisbash 1.5 * by the self field). This requiredment is imposed by the
|
405 mike 1.1 * MI_Instance_AddElement() function, which does not allow the address of
406 * the instance to change. Hence, indirection is required to allow the inner
|
407 krisbash 1.5 * instance to be relocated in memory as new properties are added. The
|
408 mike 1.1 * resulting layout is depicted below.
|
409 krisbash 1.5 *
|
410 mike 1.1 * (Wrapper)
411 * +-------------+
412 * | MI_Instance |
413 * +---------+---+
414 * | | | (Inner)
415 * +---------+---+ +-------------+
416 * | self | ------> | MI_Instance |
417 * +---------+---+ +---------+---+
418 * | | |
419 * +---------+---+
420 * | | |
421 * +---------+---+
422 *
423 * All methods of the instance type, must resolve the self pointer using
|
424 krisbash 1.5 * _SelfOf(), which either returns the sole parameter itself (for static
|
425 mike 1.1 * instances) or the self field (for dynamic instances).
426 *
427 */
428 static Instance* _WrapInstance(
|
429 krisbash 1.5 Instance* self,
|
430 mike 1.1 Batch* batch)
431 {
432 Instance* wrapper;
433
434 if (!self)
435 return NULL;
436
437 /* Allocate space for outer wrapper instance */
438 wrapper = (Instance*)_AllocInstance(batch, sizeof(MI_Instance));
439 if (!wrapper)
440 return NULL;
441
442 /* Copy fields from inner instance to outer instance */
443 *wrapper = *self;
444
445 /* Set outer instance self to point to inner instance */
446 wrapper->self = self;
447
448 return wrapper;
449 }
450
451 mike 1.1 MI_Uint32 _CountKeys(
452 const Instance* self)
453 {
454 MI_Uint32 n = 0;
455 const MI_ClassDecl* cd = self->classDecl;
456 MI_Uint32 i;
457
458 for (i = 0; i < cd->numProperties; i++)
459 {
460 if (cd->properties[i]->flags & MI_FLAG_KEY)
461 n++;
462 }
463
464 return n;
465 }
466
467 /*
468 **==============================================================================
469 **
470 ** Public definitions
471 **
472 mike 1.1 **==============================================================================
473 */
474
475 MI_Result MI_CALL Instance_Construct(
476 MI_Instance* self_,
477 const MI_ClassDecl* classDecl,
478 Batch* batch_)
479 {
480 Instance* self = (Instance*)self_;
481 MI_ClassDecl* cd = (MI_ClassDecl*)classDecl;
482 Batch* batch = batch_;
483
484 /* Check for null arguments */
485 if (!self || !cd)
486 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
487
488 /* Create a new batch */
489 if (!batch)
490 {
491 batch = Batch_New(_NUM_PAGES);
492 if (!batch)
493 mike 1.1 return MI_RESULT_FAILED;
494 }
495
496 /* Zero-fill the object */
497 memset(self, 0, cd->size);
498
499 /* MI_Instance.ft */
500 self->ft = &__mi_instanceFT;
501
502 /* MI_Instance.self */
503 self->self = self;
504
|
505 krisbash 1.4 /* MI_Instance.classDecl */
506 if ((cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION)) && (cd->owningClass == NULL))
507 {
508 //Should be static
509 self->classDecl = cd;
510 }
511 else if ((cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION)) && (cd->owningClass != (MI_Class*)-1))
512 {
513 //Bump up the ref-count on the owning classDecl if it is a class AND it is not a static classDecl
514 MI_Class *newClass;
515 MI_Result result = MI_Class_Clone(cd->owningClass, &newClass);
516 if (result != MI_RESULT_OK)
517 return result;
518
519 self->classDecl = newClass->classDecl;
520 }
521 else if (cd->flags & (MI_FLAG_CLASS|MI_FLAG_ASSOCIATION|MI_FLAG_INDICATION))
522 {
523 if (!batch)
524 {
525 assert(0);
526 krisbash 1.4 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
527 }
528
529 //This is a class, so do a full clone
530 self->classDecl = Class_Clone_ClassDecl(batch, cd);
531 if (self->classDecl == NULL)
532 return MI_RESULT_FAILED;
533 }
534 else
535 {
536 if (!batch)
537 {
538 assert(0);
539 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
540 }
541
542 //This may be a parameter, so need to do a reduced clone
543 self->classDecl = _CloneClassDecl(cd, batch);
544 if (self->classDecl == NULL)
545 return MI_RESULT_FAILED;
546 }
|
547 mike 1.1
548 /* MI_Instance.batch */
549 self->batch = batch;
550
551 /* Flags */
552 self->releaseBatch = batch == batch_ ? MI_FALSE : MI_TRUE;
553
554 MI_RETURN(MI_RESULT_OK);
555 }
556
|
557 krisbash 1.4 _Use_decl_annotations_
|
558 mike 1.1 MI_Result Instance_New(
559 MI_Instance** selfOut,
560 const MI_ClassDecl* classDecl,
561 Batch* batch_)
562 {
563 Instance* self;
564 Batch* batch = batch_;
565 MI_Result r;
566
567 /* Check for null arguments */
|
568 krisbash 1.4 if (!selfOut || !classDecl)
|
569 mike 1.1 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
570
571 /* Null out selfOut */
572 *selfOut = NULL;
573
574 /* Create a new batch */
575 if (!batch)
576 {
577 batch = Batch_New(_NUM_PAGES);
578 if (!batch)
579 return MI_RESULT_FAILED;
580 }
581
582 /* Allocate structure */
583 self = _AllocInstance(batch, classDecl->size);
584 if (!self)
585 {
586 r = MI_RESULT_FAILED;
587 goto failed;
588 }
589
590 mike 1.1 /* Initialize the object */
591 r = Instance_Construct((MI_Instance*)self, classDecl, batch);
592 if (r != MI_RESULT_OK)
593 goto failed;
594
595 /* Arrange to release batch if we created it */
596 self->releaseBatch = batch == batch_ ? MI_FALSE : MI_TRUE;
597
598 *selfOut = (MI_Instance*)self;
599 MI_RETURN(MI_RESULT_OK);
600
601 failed:
602 if (batch != batch_)
603 Batch_Delete(batch);
604 return r;
605 }
606
|
607 krisbash 1.4 _Use_decl_annotations_
|
608 mike 1.1 MI_Result MI_CALL Instance_InitConvert(
609 MI_Instance* self_,
610 const MI_ClassDecl* cd1,
611 const MI_Instance* inst_,
612 MI_Boolean keysOnly,
613 MI_Boolean allowKeylessInst,
614 MI_Boolean copy,
|
615 krisbash 1.4 Batch* batch_,
616 MI_Uint32 flags)
|
617 mike 1.1 {
618 Instance* self;
619 const Instance* inst = _SelfOf(inst_);
620 MI_Uint32 i;
621 MI_Result r;
622 const MI_ClassDecl* cd2;
623 const MI_SchemaDecl* sd1;
624 Batch* batch = batch_;
625
|
626 krisbash 1.4 /* Check parameters */
627 if (!self_ || !cd1 || !inst)
628 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
629
630 /* Create a new batch */
631 if (!batch)
632 {
633 batch = Batch_New(_NUM_PAGES);
634 if (!batch)
635 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
636 }
637
|
638 mike 1.1 /* Resolve the schema declaration (based on type) */
639 if (cd1->flags & MI_FLAG_METHOD)
640 sd1 = ((MI_MethodDecl*)cd1)->schema;
641 else if (cd1->flags & MI_FLAG_CLASS)
642 sd1 = cd1->schema;
643 else
|
644 mike 1.2 {
|
645 mike 1.1 return MI_RESULT_FAILED;
|
646 mike 1.2 }
|
647 mike 1.1
648 cd2 = inst->classDecl;
649
650 /* Initialize the instance */
651 r = Instance_Construct(self_, cd1, batch);
652 if (r != MI_RESULT_OK)
|
653 mike 1.2 {
|
654 mike 1.1 goto failed;
|
655 mike 1.2 }
|
656 mike 1.1
657 /* Get the self pointer from the newly initialized instance */
658 self = _SelfOf(self_);
659
660 /* Arrange to release the batch */
661 self->releaseBatch = batch == batch_ ? MI_FALSE : MI_TRUE;
662
663 /* Copy the nameSpace */
664 if (inst->nameSpace)
665 {
666 self->nameSpace = BStrdup(batch, inst->nameSpace, CALLSITE);
667 if (!self->nameSpace)
668 {
|
669 krisbash 1.4 r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
|
670 mike 1.1 goto failed;
671 }
672 }
673
674 /* Copy the serverName */
675 if (inst->serverName)
676 {
677 self->serverName = BStrdup(batch, inst->serverName, CALLSITE);
678 if (!self->serverName)
679 {
|
680 krisbash 1.4 r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
|
681 mike 1.1 goto failed;
682 }
683 }
684
685 /* Validate that the two instances share the same key structure */
686 if (!allowKeylessInst)
687 {
688 for (i = 0; i < cd1->numProperties; i++)
689 {
690 const MI_PropertyDecl* pd1 = cd1->properties[i];
691
692 if (pd1->flags & MI_FLAG_KEY)
693 {
694 MI_Uint32 index;
695
696 index = _FindPropertyDecl(cd2, pd1->name);
697 if (index == (MI_Uint32)-1)
698 {
|
699 krisbash 1.4 if (pd1->value)
700 {
701 //add default key value
702 MI_Value* value = (MI_Value*)pd1->value;
703 r = MI_Instance_SetElementAt(self_, i, value, pd1->type, MI_FLAG_BORROW);
704 if (r != MI_RESULT_OK)
705 {
706 goto failed;
707 }
708
709 }
710 else
711 {
712 r = MI_RESULT_NO_SUCH_PROPERTY;
713 goto failed;
714 }
|
715 mike 1.1 }
716 }
717 }
718
719 for (i = 0; i < cd2->numProperties; i++)
720 {
721 const MI_PropertyDecl* pd2 = cd2->properties[i];
722
723 if (pd2->flags & MI_FLAG_KEY)
724 {
725 MI_Uint32 index;
726
727 index = _FindPropertyDecl(cd1, pd2->name);
728 if (index == (MI_Uint32)-1)
729 {
|
730 krisbash 1.4 r = MI_RESULT_NO_SUCH_PROPERTY;
|
731 mike 1.1 goto failed;
732 }
733 }
734 }
735 }
736
737 /* ATTN: ignore unknown properties? */
738
739 /* Set non-null properties */
740 for (i = 0; i < cd2->numProperties; i++)
741 {
742 const MI_PropertyDecl* pd2 = cd2->properties[i];
743 Field* field = (Field*)((char*)inst + pd2->offset);
744
745 /* If requested, ignore non-keys */
746 if (keysOnly && !(pd2->flags & MI_FLAG_KEY))
747 continue;
748
749 /* Set the non-null key values */
750 if (Field_GetExists(field, pd2->type))
751 {
752 mike 1.1 if (pd2->type == MI_STRING)
753 {
754 r = Instance_SetElementFromString(self_, pd2->name,
|
755 krisbash 1.4 ((MI_Value*)field)->string, flags);
|
756 mike 1.1
757 if (r != MI_RESULT_OK)
758 {
759 goto failed;
760 }
761 }
762 else if (pd2->type == MI_STRINGA)
763 {
764 r = Instance_SetElementFromStringA(self_, pd2->name,
|
765 krisbash 1.4 (const ZChar**)((MI_Value*)field)->stringa.data,
766 ((MI_Value*)field)->stringa.size,
767 flags);
|
768 mike 1.1
769 if (r != MI_RESULT_OK)
770 {
771 goto failed;
772 }
773 }
774 else if (pd2->type == MI_INSTANCE || pd2->type == MI_REFERENCE)
775 {
776 MI_Instance* tmpInst;
777 MI_ClassDecl* tmpCd;
|
778 mike 1.2 MI_Type type;
|
779 krisbash 1.4 MI_Boolean allowKeylessEmbedInst = (pd2->type == MI_INSTANCE) ? MI_TRUE : MI_FALSE;
|
780 mike 1.1
781 /* Find the class declaration in the schema */
|
782 krisbash 1.5 tmpCd = SchemaDecl_FindClassDecl(sd1,
|
783 mike 1.1 _SelfOf(((MI_Value*)field)->instance)->classDecl->name);
784
785 if (!tmpCd)
786 {
|
787 krisbash 1.4 r = MI_RESULT_NO_SUCH_PROPERTY;
|
788 mike 1.1 goto failed;
789 }
790
791 /* Allocate static instance of this class */
|
792 krisbash 1.4 r = Instance_New(&tmpInst, tmpCd, batch);
793 if (r != MI_RESULT_OK)
|
794 mike 1.1 {
795 goto failed;
796 }
797
798 /* Convert instance */
799 r = Instance_InitConvert(tmpInst, tmpCd,
|
800 krisbash 1.5 ((MI_Value*)field)->instance, keysOnly, allowKeylessEmbedInst, copy,
|
801 krisbash 1.4 ((Instance*)tmpInst)->batch, flags);
|
802 mike 1.1
803 if (r != MI_RESULT_OK)
804 {
805 __MI_Instance_Delete(tmpInst);
806 goto failed;
807 }
808
|
809 mike 1.2 /* Get the target property type */
|
810 mike 1.1 {
|
811 mike 1.2 MI_PropertyDecl* pd = _LookupPropertyDecl(cd1, pd2->name);
|
812 mike 1.1
|
813 mike 1.2 if (!pd)
|
814 mike 1.1 {
|
815 mike 1.2 r = MI_RESULT_NO_SUCH_PROPERTY;
|
816 mike 1.1 goto failed;
817 }
818
|
819 mike 1.2 type = pd->type;
820 }
821
822 /* Reject if not instance or reference */
|
823 mike 1.1
|
824 mike 1.2 switch (type)
825 {
826 case MI_INSTANCE:
827 case MI_REFERENCE:
828 {
829 MI_Value v;
830 v.instance = tmpInst;
|
831 mike 1.1
|
832 mike 1.2 r = __MI_Instance_SetElement(
|
833 krisbash 1.5 self_,
834 pd2->name,
835 &v,
|
836 mike 1.2 type,
837 MI_FLAG_ADOPT);
838
839 break;
840 }
841 case MI_INSTANCEA:
842 case MI_REFERENCEA:
843 {
844 MI_Value v;
845 v.instancea.size = 1;
|
846 krisbash 1.5 v.instancea.data =
|
847 mike 1.2 BAlloc(batch, sizeof(void*), CALLSITE);
848
849 if (!v.instancea.data)
850 {
851 __MI_Instance_Delete(tmpInst);
852 r = MI_RESULT_FAILED;
853 goto failed;
854 }
855
856 v.instancea.data[0] = tmpInst;
857
858 r = __MI_Instance_SetElement(
|
859 krisbash 1.5 self_,
860 pd2->name,
861 &v,
|
862 mike 1.2 type,
863 MI_FLAG_ADOPT);
864
865 break;
866 }
867 default:
868 {
869 r = MI_RESULT_TYPE_MISMATCH;
870 break;
871 }
|
872 mike 1.1 }
873
874 if (r != MI_RESULT_OK)
875 {
876 __MI_Instance_Delete(tmpInst);
877 r = MI_RESULT_TYPE_MISMATCH;
878 goto failed;
879 }
880 }
881 else if (pd2->type == MI_INSTANCEA || pd2->type == MI_REFERENCEA)
882 {
883 MI_Value v;
884 MI_Uint32 j;
|
885 krisbash 1.4 MI_Boolean allowKeylessEmbedInst = (pd2->type == MI_INSTANCEA) ? MI_TRUE : MI_FALSE;
|
886 mike 1.1
887 v.instancea.size = ((MI_Value*)field)->instancea.size;
|
888 krisbash 1.5 v.instancea.data = BAlloc(batch,
|
889 mike 1.1 v.instancea.size * sizeof(void*), CALLSITE);
890
891 if (!v.instancea.data)
892 {
|
893 krisbash 1.4 r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
|
894 mike 1.1 goto failed;
895 }
|
896 krisbash 1.5
|
897 mike 1.1 for (j = 0; j < v.instancea.size; j++)
898 {
899 MI_Instance* tmpInst;
900 MI_ClassDecl* tmpCd;
901
902 /* Find the schema declaration */
903 tmpCd = SchemaDecl_FindClassDecl(sd1, _SelfOf(((
904 MI_Value*)field)->instancea.data[j])->classDecl->name);
905
906 if (!tmpCd)
907 {
|
908 krisbash 1.4 r = MI_RESULT_NO_SUCH_PROPERTY;
|
909 mike 1.1 goto failed;
910 }
911
912 /* Allocate the instance for the provider */
|
913 krisbash 1.4 r = Instance_New(&tmpInst,tmpCd,batch);
914 if (r != MI_RESULT_OK)
|
915 mike 1.1 {
916 goto failed;
917 }
918
919 r = Instance_InitConvert(tmpInst, tmpCd,
|
920 krisbash 1.5 ((MI_Value*)field)->instancea.data[j], keysOnly, allowKeylessEmbedInst, copy,
|
921 krisbash 1.4 ((Instance*)tmpInst)->batch, flags);
|
922 mike 1.1
923 if (r != MI_RESULT_OK)
924 {
925 MI_Uint32 k;
926
927 for (k = 0; k < j; k++)
928 __MI_Instance_Delete(v.instancea.data[k]);
929
930 goto failed;
931 }
932
933 v.instancea.data[j] = tmpInst;
934 }
935
936 /* Set the value */
937 r = __MI_Instance_SetElement(self_, pd2->name, &v, pd2->type,
938 MI_FLAG_ADOPT);
939
|
940 krisbash 1.4 /* Allow conversion from reference array to instance array */
941 if (r == MI_RESULT_TYPE_MISMATCH && pd2->type == MI_INSTANCEA)
942 {
943 r = __MI_Instance_SetElement(self_, pd2->name, &v,
944 MI_REFERENCEA, MI_FLAG_ADOPT);
945 }
946
|
947 mike 1.1 if (r != MI_RESULT_OK)
948 {
949 for (j = 0; j < v.instancea.size; j++)
950 __MI_Instance_Delete(v.instancea.data[j]);
951
952 goto failed;
953 }
954 }
955 else
956 {
957 MI_Uint32 tmpFlags = copy ? 0 : MI_FLAG_BORROW;
958
959 /* Set the value */
960 r = __MI_Instance_SetElement(self_, pd2->name, (MI_Value*)field,
961 pd2->type, tmpFlags);
962
963 if (r != MI_RESULT_OK)
964 {
965 goto failed;
966 }
967 }
968 mike 1.1 }
969 }
970
971 failed:
972 if (batch != batch_)
973 Batch_Delete(batch);
974 return r;
975 }
976
977 MI_Result MI_CALL Instance_Clone(
|
978 krisbash 1.5 const MI_Instance* self_,
|
979 mike 1.1 MI_Instance** instOut,
980 Batch* batch_)
981 {
|
982 krisbash 1.4 const Instance* self;
|
983 mike 1.1 Batch* batch = batch_;
984 Instance* inst;
985 MI_Uint32 i;
986 MI_Result r;
987
|
988 krisbash 1.4 /* Check for externally defined instance */
989 if (self_ && self_->ft != &__mi_instanceFT && self_->ft != NULL)
990 return MI_Instance_Clone(self_, instOut);
991
992 self = _SelfOf(self_);
993
|
994 mike 1.1 /* Check for a null parameter */
995 if (!self || !instOut)
996 {
997 r = MI_RESULT_FAILED;
998 goto failed;
999 }
1000
1001 /* Create new batch? */
1002 if (!batch)
1003 {
1004 batch = Batch_New(_NUM_PAGES);
1005 if (!batch)
1006 return MI_RESULT_FAILED;
1007 }
1008
1009 /* Allocate the new instance */
1010 {
1011 MI_Uint32 cap = sizeof(MI_Instance) + _CAPACITY * sizeof(Field);
1012
1013 if (self->classDecl->size > cap)
1014 cap = self->classDecl->size;
1015 mike 1.1
1016 inst = _AllocInstance(batch, cap);
1017 if (!inst)
1018 {
1019 r = MI_RESULT_FAILED;
1020 goto failed;
1021 }
1022 }
1023
1024 /* Instance.self */
1025 inst->self = inst;
1026
1027 /* Instance.flags */
1028 if (batch != batch_)
1029 {
1030 inst->releaseBatch = MI_TRUE;
1031 }
1032
1033 /* Set Instance.batch */
1034 inst->batch = batch;
1035
1036 mike 1.1 /* Set MI_Instance.ft */
1037 inst->ft = &__mi_instanceFT;
1038
1039 /* Instance.nameSpace */
1040 if (self->nameSpace)
1041 {
1042 inst->nameSpace = BStrdup(batch, self->nameSpace, CALLSITE);
1043
1044 if (!inst->nameSpace)
1045 {
1046 r = MI_RESULT_FAILED;
1047 goto failed;
1048 }
1049 }
1050
1051 /* Instance.serverName */
1052 if (self->serverName)
1053 {
1054 inst->serverName = BStrdup(batch, self->serverName, CALLSITE);
1055
1056 if (!inst->serverName)
1057 mike 1.1 {
1058 r = MI_RESULT_FAILED;
1059 goto failed;
1060 }
1061 }
1062
1063 /* Set Instance.classDecl */
|
1064 krisbash 1.4 if ((self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)) && (self->classDecl->owningClass == NULL)) //static
1065 {
1066 inst->classDecl = self->classDecl;
1067 }
1068 else if ((self->classDecl->owningClass == (MI_Class*)-1) || !(self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)))
|
1069 mike 1.1 {
|
1070 krisbash 1.4 //classDecl is from a dynamic instance without a proper classDecl
|
1071 mike 1.1 inst->classDecl = _CloneClassDecl(self->classDecl, batch);
1072
1073 if (!inst->classDecl)
|
1074 krisbash 1.4 MI_RETURN(MI_RESULT_FAILED);
1075 }
1076 else if (self->classDecl->owningClass) //has a proper MI_Class owner so can clone it to bump refcount
1077 {
1078 MI_Class *clonedClass;
1079 MI_Result result = MI_Class_Clone(self->classDecl->owningClass, &clonedClass);
1080 if (result != MI_RESULT_OK)
1081 MI_RETURN(result);
1082 inst->classDecl = clonedClass->classDecl;
1083 }
1084 else//We had better do a hard clone
1085 {
1086 inst->classDecl = Class_Clone_ClassDecl(batch, self->classDecl);
1087 if (inst->classDecl == NULL)
1088 MI_RETURN(MI_RESULT_FAILED);
|
1089 mike 1.1 }
1090
1091 /* Clone each of the fields */
1092 for (i = 0; i < self->classDecl->numProperties; i++)
1093 {
1094 const MI_PropertyDecl* pd = self->classDecl->properties[i];
1095
1096 r = Field_Copy(
1097 (Field*)((char*)inst + pd->offset),
1098 pd->type,
1099 (Field*)((char*)self + pd->offset),
1100 batch);
1101
1102 if (r != MI_RESULT_OK)
1103 {
1104 r = MI_RESULT_FAILED;
1105 goto failed;
1106 }
1107 }
1108
1109 /* Wrapper dynamic instances */
1110 mike 1.1 if ((void*)self != (void*)self_)
1111 {
1112 inst = _WrapInstance(inst, batch);
1113 if (!inst)
1114 {
1115 r = MI_RESULT_FAILED;
1116 goto failed;
1117 }
1118 }
1119
1120 *instOut = (MI_Instance*)inst;
1121 return MI_RESULT_OK;
1122
1123 failed:
1124 if (batch != batch_)
1125 Batch_Delete(batch);
1126 return r;
1127 }
1128
1129 MI_Result MI_CALL Instance_SetClassName(
|
1130 krisbash 1.5 MI_Instance* self_,
|
1131 krisbash 1.4 const ZChar* className)
|
1132 mike 1.1 {
1133 Instance* self = _SelfOf(self_);
|
1134 krisbash 1.4 ZChar* oldClassName;
|
1135 mike 1.1
1136 /* Check parameters */
1137 if (!self || !className)
1138 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1139
1140 /* Save old className */
1141 oldClassName = self->classDecl->name;
1142
1143 /* Set new className */
1144 {
|
1145 krisbash 1.4 ZChar* tmp = BStrdup(self->batch, className, CALLSITE);
|
1146 mike 1.1
1147 if (!tmp)
1148 MI_RETURN(MI_RESULT_FAILED);
1149
1150 self->classDecl->name = tmp;
|
1151 krisbash 1.4 self->classDecl->code = Hash(tmp);
|
1152 mike 1.1 }
1153
1154 /* Free old className */
1155 if (oldClassName)
1156 BFree(self->batch, oldClassName, CALLSITE);
1157
1158 MI_RETURN(MI_RESULT_OK);
1159 }
1160
|
1161 krisbash 1.4 _Use_decl_annotations_
|
1162 mike 1.1 MI_Result MI_CALL Instance_NewDynamic(
1163 MI_Instance** selfOut,
|
1164 krisbash 1.4 const ZChar* className,
|
1165 mike 1.1 MI_Uint32 metaType,
1166 Batch* batch_)
1167 {
1168 Instance* self = NULL;
1169 Batch* batch = batch_;
1170 MI_Result r;
1171
1172 /* Reject null arguments */
1173 if (!selfOut || !className)
1174 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1175
1176 /* Null output self pointer */
1177 *selfOut = NULL;
1178
1179 /* Create batch if necessary */
1180 if (!batch)
1181 {
1182 batch = Batch_New(_NUM_PAGES);
1183 if (!batch)
1184 return MI_RESULT_FAILED;
1185 }
1186 mike 1.1
1187 /* Check that 'className' parameter is a legal CIM className */
1188 if (!LegalName(className))
1189 {
1190 r = MI_RESULT_INVALID_PARAMETER;
1191 goto failed;
1192 }
1193
1194 /* Allocate instance and reserve room for properties */
1195 {
|
1196 krisbash 1.5 self = _AllocInstance(batch,
|
1197 mike 1.1 sizeof(MI_Instance) + _CAPACITY * sizeof(Field));
1198
1199 if (!self)
1200 {
1201 r = MI_RESULT_FAILED;
1202 goto failed;
1203 }
1204
1205 self->self = self;
1206 }
1207
1208 /* Set Instance.classDecl */
1209 {
1210 MI_ClassDecl* cd;
1211
1212 /* Allocate and set Instance.classDecl */
1213 {
1214 cd = (MI_ClassDecl*)BCalloc(batch, sizeof(MI_ClassDecl), CALLSITE);
1215
1216 if (!cd)
1217 {
1218 mike 1.1 r = MI_RESULT_FAILED;
1219 goto failed;
1220 }
1221
|
1222 krisbash 1.4 cd->owningClass = (MI_Class*) -1; /* Mark as a dynamic instance */
|
1223 mike 1.1 self->classDecl = cd;
1224 }
|
1225 krisbash 1.5
|
1226 mike 1.1 /* MI_ClassDecl.flags: */
1227 if (metaType & MI_FLAG_ASSOCIATION)
1228 cd->flags |= MI_FLAG_ASSOCIATION;
1229 else if (metaType & MI_FLAG_INDICATION)
1230 cd->flags |= MI_FLAG_INDICATION;
1231 else if (metaType & MI_FLAG_METHOD)
1232 cd->flags |= MI_FLAG_METHOD;
1233 else if (metaType & MI_FLAG_CLASS)
1234 cd->flags |= MI_FLAG_CLASS;
1235 else
1236 cd->flags |= MI_FLAG_CLASS;
1237
1238 /* MI_ClassDecl.name: */
1239 {
1240 cd->name = BStrdup(batch, className, CALLSITE);
1241
1242 if (!cd->name)
1243 {
1244 r = MI_RESULT_FAILED;
1245 goto failed;
1246 }
|
1247 krisbash 1.4
|
1248 mike 1.1 }
1249
1250 /* MI_ClassDecl.code: */
|
1251 krisbash 1.4 cd->code = Hash(cd->name);
|
1252 mike 1.1
1253 /* MI_ClassDecl.properties: */
1254 {
1255 MI_PropertyDecl** data;
1256
1257 data = (MI_PropertyDecl**)BAlloc(batch,
1258 _CAPACITY * sizeof(MI_PropertyDecl), CALLSITE);
1259
1260 if (!data)
1261 {
1262 r = MI_RESULT_FAILED;
1263 goto failed;
1264 }
1265
1266 cd->properties = data;
1267 cd->numProperties = 0;
1268 }
1269
1270 /* MI_ClassDecl.size: */
1271 cd->size = sizeof(MI_Instance);
1272 }
1273 mike 1.1
1274 /* Set batch: */
1275 self->batch = batch;
1276
1277 /* Set flags */
1278 if (batch_)
1279 self->releaseBatch = MI_FALSE;
1280 else
1281 self->releaseBatch = MI_TRUE;
1282
1283 /* Set MI_Instance.ft: */
1284 self->ft = &__mi_instanceFT;
1285
1286 /* Set the self pointer */
1287 self->self = self;
1288
1289 /* Set output instance (creating a wrapper for it) */
1290 self = _WrapInstance(self, batch);
1291 if (!self)
1292 {
1293 r = MI_RESULT_FAILED;
1294 mike 1.1 goto failed;
1295 }
1296
1297 *selfOut = (MI_Instance*)self;
1298 MI_RETURN(MI_RESULT_OK);
1299
1300 failed:
1301 if (batch != batch_)
1302 Batch_Delete(batch);
1303 return r;
1304 }
1305
1306 MI_Boolean Instance_MatchKeys(
1307 const MI_Instance* self_,
1308 const MI_Instance* inst_)
1309 {
1310 Instance* self;
1311 Instance* inst;
1312
1313 /* Check parameters */
1314 if (!self_ || !inst_)
1315 mike 1.1 {
1316 return MI_FALSE;
1317 }
1318
1319 self = _SelfOf(self_);
1320 inst = _SelfOf(inst_);
1321
1322 /* Check parameters */
1323 if (!self || !inst)
1324 {
1325 return MI_FALSE;
1326 }
1327
1328 /* Verify they have the same number of keys (one or more) */
1329 {
1330 MI_Uint32 n = _CountKeys(self);
1331
1332 if (n == 0 || n != _CountKeys(inst))
1333 {
1334 return MI_FALSE;
1335 }
1336 mike 1.1 }
1337
1338 /* Verify that key fields are identical */
1339 {
1340 const MI_ClassDecl* cd1 = self->classDecl;
1341 const MI_ClassDecl* cd2 = inst->classDecl;
1342 MI_Uint32 i;
1343
1344 for (i = 0; i < cd1->numProperties; i++)
1345 {
1346 const MI_PropertyDecl* pd1 = cd1->properties[i];
1347 const MI_PropertyDecl* pd2;
1348 Field* f1;
1349 Field* f2;
1350 MI_Uint32 index;
1351
1352 if (pd1->flags & MI_FLAG_KEY)
1353 {
1354 index = _FindPropertyDecl(cd2, pd1->name);
1355
1356 if (index == (MI_Uint32)-1)
1357 mike 1.1 {
1358 return MI_FALSE;
1359 }
1360
1361 pd2 = cd2->properties[index];
1362
1363 if (!(pd2->flags & MI_FLAG_KEY))
1364 {
1365 return MI_FALSE;
1366 }
1367
1368 if (pd1->type != pd2->type)
1369 return MI_FALSE;
1370
1371 f1 = (Field*)((char*)self + pd1->offset);
1372 f2 = (Field*)((char*)inst + pd2->offset);
1373
1374 if (!Field_MatchKey(f1, f2, pd1->type))
1375 {
1376 return MI_FALSE;
1377 }
1378 mike 1.1 }
1379 }
1380 }
1381
1382 return MI_TRUE;
1383 }
1384
|
1385 krisbash 1.4 /* Get underline instance */
1386 Instance* Instance_GetSelf(
1387 const MI_Instance* self)
1388 {
1389 return _SelfOf( self );
1390 }
1391
|
1392 mike 1.1 /*
1393 **==============================================================================
1394 **
1395 ** MI_Instance function table and functions
1396 **
1397 **==============================================================================
1398 */
1399
1400 void __MI_Instance_Ref(MI_Instance* self)
1401 {
1402 InstanceHeader* h = _HeaderOf((Instance*)self);
1403
1404 if (h)
|
1405 krisbash 1.4 Atomic_Inc(&h->u.refs);
|
1406 mike 1.1 }
1407
1408 void __MI_Instance_Unref(MI_Instance* self)
1409 {
1410 InstanceHeader* h = _HeaderOf((Instance*)self);
1411
|
1412 krisbash 1.4 if (h && Atomic_Dec(&h->u.refs) == 0)
|
1413 mike 1.1 __MI_Instance_Delete((MI_Instance*)self);
1414 }
1415
1416 MI_Result MI_CALL __MI_Instance_Clone(
|
1417 krisbash 1.5 const MI_Instance* self,
|
1418 mike 1.1 MI_Instance** inst)
1419 {
1420 return Instance_Clone(self, inst, NULL);
1421 }
1422
1423 MI_Result MI_CALL __MI_Instance_Destruct(
1424 MI_Instance* self_)
1425 {
1426 Instance* self = _SelfOf(self_);
1427 Batch* batch;
1428 MI_Uint32 i;
|
1429 krisbash 1.4 MI_Boolean releaseBatch;
|
1430 mike 1.1
1431 /* Check for null parameter */
1432 if (!self)
1433 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1434
|
1435 krisbash 1.4 /* Save release flag */
1436 releaseBatch = self->releaseBatch;
1437
|
1438 mike 1.1 /* Save pointer to batch */
1439 batch = self->batch;
1440 if (!batch)
1441 MI_RETURN(MI_RESULT_FAILED);
1442
1443 /* Release serverName */
1444 if (self->serverName)
1445 BFree(batch, self->serverName, CALLSITE);
1446
1447 /* Release nameSpace */
1448 if (self->nameSpace)
1449 BFree(batch, self->nameSpace, CALLSITE);
1450
1451 /* Release all memory used by properties */
1452 for (i = 0; i < self->classDecl->numProperties; i++)
1453 {
1454 const MI_PropertyDecl* pd = self->classDecl->properties[i];
1455 Field* field = (Field*)((char*)self + pd->offset);
1456 Field_Destruct(field, pd->type, batch);
1457 }
1458
1459 mike 1.1 /* Free dynamic instance part (if any) */
1460 if ((void*)self != (void*)self_)
1461 {
1462 for (i = 0; i < self->classDecl->numProperties; i++)
1463 {
1464 MI_PropertyDecl* pd = self->classDecl->properties[i];
1465 BFree(batch, pd->name, CALLSITE);
1466 BFree(batch, pd, CALLSITE);
1467 }
1468
1469 BFree(batch, self->classDecl->name, CALLSITE);
1470 BFree(batch, self->classDecl->properties, CALLSITE);
1471 BFree(batch, self->classDecl, CALLSITE);
1472
1473 if ((void*)self != (void*)self_)
1474 _FreeInstance(batch, self);
1475 }
|
1476 krisbash 1.4 else
1477 {
1478 if ((self->classDecl->flags & (MI_FLAG_CLASS|MI_FLAG_INDICATION|MI_FLAG_ASSOCIATION)) && self->classDecl->owningClass)
1479 {
1480 //Bump down the ref-count on the owning MI_Class if there is one, deleting it if necessary
1481 MI_Class_Delete(self->classDecl->owningClass);
1482 }
1483 }
1484
1485 /* release batch */
1486 if (releaseBatch)
1487 Batch_Delete(batch);
|
1488 mike 1.1
1489 MI_RETURN(MI_RESULT_OK);
1490 }
1491
1492 MI_Result MI_CALL __MI_Instance_Delete(
1493 MI_Instance* self_)
1494 {
1495 Instance* self = _SelfOf(self_);
1496 MI_Result r;
1497 Batch* batch;
1498 MI_Boolean releaseBatch;
1499
1500 /* Check for null parameter */
1501 if (!self)
1502 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1503
1504 /* Save pointer to batch */
1505 batch = self->batch;
1506 if (!batch)
1507 MI_RETURN(MI_RESULT_FAILED);
1508
1509 mike 1.1 /* Save */
1510 releaseBatch = self->releaseBatch;
1511
1512 /* Destruct */
1513 r = __MI_Instance_Destruct(self_);
1514 if (r != MI_RESULT_OK)
1515 MI_RETURN(r);
1516
1517 /* Release self pointer */
|
1518 krisbash 1.4 if (MI_FALSE == releaseBatch)
1519 _FreeInstance(batch, (Instance*)self_);
|
1520 mike 1.1
1521 return r;
1522 }
1523
1524 MI_Result MI_CALL __MI_Instance_IsA(
1525 const MI_Instance* self_,
1526 const MI_ClassDecl* classDecl,
1527 MI_Boolean* resultOut)
1528 {
1529 Instance* self = _SelfOf(self_);
1530 const MI_ClassDecl* p;
1531
1532 if (!self || !classDecl)
1533 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1534
1535 for (p = self->classDecl; p; p = p->superClassDecl)
1536 {
1537 if (p == classDecl)
1538 {
1539 if (resultOut)
1540 *resultOut = MI_TRUE;
1541 mike 1.1 MI_RETURN(MI_RESULT_OK);
1542 }
1543 }
1544
1545 if (resultOut)
1546 *resultOut = MI_FALSE;
1547
1548 MI_RETURN(MI_RESULT_OK);
1549 }
1550
1551 MI_Result MI_CALL __MI_Instance_GetClassName(
|
1552 krisbash 1.5 const MI_Instance* self_,
|
1553 krisbash 1.4 const ZChar** classNameOut)
|
1554 mike 1.1 {
1555 Instance* self = _SelfOf(self_);
1556
1557 if (!self)
1558 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1559
1560 if (classNameOut)
1561 *classNameOut = self->classDecl->name;
1562
1563 MI_RETURN(MI_RESULT_OK);
1564 }
1565
1566 MI_Result MI_CALL __MI_Instance_SetNameSpace(
|
1567 krisbash 1.5 MI_Instance* self_,
|
1568 krisbash 1.4 const ZChar* nameSpace)
|
1569 mike 1.1 {
1570 Instance* self = _SelfOf(self_);
|
1571 krisbash 1.4 ZChar* oldNameSpace;
|
1572 mike 1.1
1573 /* Check parameters */
1574 if (!self)
1575 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1576
1577 /* Save old namespace */
1578 oldNameSpace = self->nameSpace;
1579
1580 /* Set new namespace */
1581 if (nameSpace)
1582 {
|
1583 krisbash 1.4 ZChar* tmp = BStrdup(self->batch, nameSpace, CALLSITE);
|
1584 mike 1.1
1585 if (!tmp)
1586 MI_RETURN(MI_RESULT_FAILED);
1587
1588 self->nameSpace = tmp;
1589 }
1590 else
1591 self->nameSpace = NULL;
1592
1593 /* Free old namespace */
1594 if (oldNameSpace)
1595 BFree(self->batch, oldNameSpace, CALLSITE);
1596
1597 MI_RETURN(MI_RESULT_OK);
1598 }
1599
1600 MI_Result MI_CALL __MI_Instance_GetNameSpace(
|
1601 krisbash 1.5 const MI_Instance* self_,
|
1602 krisbash 1.4 const ZChar** nameSpaceOut)
|
1603 mike 1.1 {
1604 Instance* self = _SelfOf(self_);
1605
1606 if (!self)
1607 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1608
1609 if (nameSpaceOut)
1610 *nameSpaceOut = self->nameSpace;
1611
1612 MI_RETURN(MI_RESULT_OK);
1613 }
1614
1615 MI_Result MI_CALL __MI_Instance_GetElementCount(
1616 const MI_Instance* self_,
1617 MI_Uint32* countOut)
1618 {
1619 Instance* self = _SelfOf(self_);
1620
1621 if (!self)
1622 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1623
1624 mike 1.1 if (countOut)
1625 *countOut = self->classDecl->numProperties;
1626
1627 MI_RETURN(MI_RESULT_OK);
1628 }
1629
1630 MI_Result MI_CALL __MI_Instance_AddElement(
1631 MI_Instance* self_,
|
1632 krisbash 1.4 const ZChar* name,
|
1633 mike 1.1 const MI_Value* value,
1634 MI_Type type,
1635 MI_Uint32 flags)
1636 {
1637 Instance* self = _SelfOf(self_);
1638 MI_Uint32 index;
1639 MI_ClassDecl* cd;
1640 MI_Uint32 tflags = 0;
1641
1642 if (flags & MI_FLAG_BORROW)
1643 tflags |= MI_FLAG_BORROW;
1644
1645 if (flags & MI_FLAG_NULL)
1646 tflags |= MI_FLAG_NULL;
1647
1648 /* Check for null arguments */
1649 if (!self || !name)
1650 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1651
1652 /* Reject attempts to extend a non-dynamic instances */
1653 if ((void*)self == (void*)self_)
1654 mike 1.1 MI_RETURN(MI_RESULT_FAILED);
1655
1656 /* Check that 'name' parameter is a legal CIM name */
1657 if (!LegalName(name))
1658 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1659
1660 /* Find the property with this name */
1661 index = _FindPropertyDecl(self->classDecl, name);
1662
1663 if (index != (MI_Uint32)-1)
1664 MI_RETURN(MI_RESULT_ALREADY_EXISTS);
1665
1666 /* Get pointer to class declaration */
1667 cd = (MI_ClassDecl*)self->classDecl;
1668
1669 /* Extend size of instance and properties array as needed */
1670 if (cd->numProperties == _FindCapacity(cd->numProperties))
1671 {
1672 MI_Uint32 cap;
1673 MI_PropertyDecl** data;
1674
1675 mike 1.1 /* Double old capacity */
1676 cap = 2 * cd->numProperties;
1677
1678 /* Reallocate properties array */
1679 data = (MI_PropertyDecl**)BRealloc(
|
1680 krisbash 1.5 self->batch,
1681 cd->properties,
|
1682 krisbash 1.4 cd->numProperties * sizeof(MI_PropertyDecl*),
1683 cap * sizeof(MI_PropertyDecl*),
|
1684 mike 1.1 CALLSITE);
1685
1686 if (!data)
1687 MI_RETURN(MI_RESULT_FAILED);
1688
1689 cd->properties = data;
|
1690 krisbash 1.5
|
1691 mike 1.1 /* Reallocate instance */
1692 self = _ReallocInstance(
|
1693 krisbash 1.5 self->batch,
1694 self,
|
1695 mike 1.1 sizeof(MI_Instance) + cd->numProperties * sizeof(Field),
1696 sizeof(MI_Instance) + cap * sizeof(Field));
1697 if (!self)
1698 MI_RETURN(MI_RESULT_FAILED);
1699
1700 /* Set new self */
1701 self->self = self;
1702 }
1703
1704 /* Create and add new property */
1705 {
1706 MI_PropertyDecl* pd;
1707
1708 /* Allocate new peroperty declaration */
1709 pd = (MI_PropertyDecl*)BCalloc(
1710 self->batch, sizeof(MI_PropertyDecl), CALLSITE);
1711
1712 if (!pd)
1713 MI_RETURN(MI_RESULT_FAILED);
1714
1715 /* MI_PropertyDecl.flags */
1716 mike 1.1 pd->flags = flags;
1717
1718 /* MI_PropertyDecl.name */
1719 pd->name = BStrdup(self->batch, name, CALLSITE);
1720
1721 if (!pd->name)
1722 MI_RETURN(MI_RESULT_FAILED);
1723
|
1724 krisbash 1.4 /* MI_PropertyDecl.code */
1725 pd->code = Hash(pd->name);
1726
|
1727 mike 1.1 /* MI_PropertyDecl.type */
1728 pd->type = type;
1729
1730 /* MI_PropertyDecl.offset */
1731 pd->offset = sizeof(MI_Instance) + cd->numProperties*sizeof(Field);
1732
1733 /* Add property to array */
1734 cd->properties[cd->numProperties++] = pd;
|
1735 krisbash 1.5
|
1736 mike 1.1 /* Clear the new field */
1737 memset((char*)self + pd->offset, 0, sizeof(Field));
1738
1739 /* Adjust size */
1740 cd->size += sizeof(Field);
1741 }
1742
1743 /* Reassign 'self' field (it may have changed) */
1744 ((Instance*)self_)->self = self;
1745
1746 /* Copy self of self wrapper */
1747 memcpy(self_, self, sizeof(MI_Instance));
1748
1749 /* Set the last property */
1750 MI_RETURN(__MI_Instance_SetElementAt(
1751 self_, cd->numProperties - 1, value, type, tflags));
1752 }
1753
1754 MI_Result MI_CALL __MI_Instance_SetElement(
|
1755 krisbash 1.5 MI_Instance* self_,
1756 const ZChar* name,
|
1757 mike 1.1 const MI_Value* value,
1758 MI_Type type,
1759 MI_Uint32 flags)
1760 {
1761 Instance* self = _SelfOf(self_);
1762 MI_Uint32 index;
1763
1764 /* Check for null arguments */
1765 if (!self || !name)
1766 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1767
1768 /* Find the property with this name */
1769 index = _FindPropertyDecl(self->classDecl, name);
1770
1771 if (index == (MI_Uint32)-1)
1772 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
1773
1774 MI_RETURN(__MI_Instance_SetElementAt(self_, index, value, type, flags));
1775 }
1776
1777 MI_Result MI_CALL __MI_Instance_SetElementAt(
|
1778 krisbash 1.5 MI_Instance* self_,
|
1779 mike 1.1 MI_Uint32 index,
1780 const MI_Value* value,
1781 MI_Type type,
1782 MI_Uint32 flags)
1783 {
1784 Instance* self = _SelfOf(self_);
1785 const MI_PropertyDecl* pd;
1786 char* field;
1787
1788 /* Check for null arguments */
1789 if (!self)
1790 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
|
1791 krisbash 1.5
|
1792 mike 1.1 /* Check whether index is in range */
1793 if (index > self->classDecl->numProperties)
1794 MI_RETURN(MI_RESULT_FAILED);
1795
1796 /* Get pointer to properties declaration */
1797 pd = self->classDecl->properties[index];
1798
1799 /* Check the type */
1800 if (type != (MI_Type)pd->type)
1801 MI_RETURN(MI_RESULT_TYPE_MISMATCH);
1802
1803 /* Get pointer to field */
1804 field = (char*)self + pd->offset;
1805
1806 /* Set the value */
1807 {
1808 MI_Result r = Field_Set(
|
1809 krisbash 1.4 (Field*)field,
|
1810 mike 1.1 pd->type,
1811 value,
1812 flags,
1813 self->batch);
1814
1815 if (r != MI_RESULT_OK)
1816 return r;
1817 }
1818
1819 MI_RETURN(MI_RESULT_OK);
1820 }
1821
1822 MI_Result MI_CALL __MI_Instance_GetElement(
|
1823 krisbash 1.5 const MI_Instance* self_,
1824 const ZChar* name,
|
1825 mike 1.1 MI_Value* valueOut,
1826 MI_Type* typeOut,
1827 MI_Uint32* flagsOut,
1828 MI_Uint32* indexOut)
1829 {
1830 Instance* self = _SelfOf(self_);
1831 MI_Uint32 index;
1832 MI_Result r;
1833
1834 /* Check for null arguments */
1835 if (!self || !name)
1836 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1837
1838 /* Find the property with this name */
1839 index = _FindPropertyDecl(self->classDecl, name);
1840
1841 if (index == (MI_Uint32)-1)
1842 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
1843
1844 r = __MI_Instance_GetElementAt(
1845 self_, index, NULL, valueOut, typeOut, flagsOut);
1846 mike 1.1
1847 if (r != MI_RESULT_OK)
1848 MI_RETURN(r);
1849
1850 if (indexOut)
1851 *indexOut = index;
1852
1853 MI_RETURN(MI_RESULT_OK);
1854 }
1855
1856 MI_Result MI_CALL __MI_Instance_GetElementAt(
1857 const MI_Instance* self_,
1858 MI_Uint32 index,
|
1859 krisbash 1.4 const ZChar** nameOut,
|
1860 mike 1.1 MI_Value* valueOut,
1861 MI_Type* typeOut,
1862 MI_Uint32* flagsOut)
1863 {
1864 Instance* self = _SelfOf(self_);
1865 const MI_PropertyDecl* pd;
1866 const Field* field;
1867
1868 /* Check for null arguments */
1869 if (!self)
1870 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1871
1872 /* Check for bounds error */
1873 if (index >= self->classDecl->numProperties)
1874 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1875
1876 pd = self->classDecl->properties[index];
1877
1878 /* Get pointer to field */
1879 field = (Field*)((char*)self + pd->offset);
1880
1881 mike 1.1 /* set nameOut */
1882 if (nameOut)
1883 *nameOut = pd->name;
1884
1885 /* set valueOut */
1886 if (valueOut)
1887 memcpy(valueOut, field, Type_SizeOf((MI_Type)pd->type));
1888
|
1889 krisbash 1.4 /* Set flagsOut */
|
1890 mike 1.1 if (flagsOut)
1891 {
|
1892 krisbash 1.4 MI_Uint8 fieldFlags = 0;
1893 *flagsOut = pd->flags & ~(MI_FLAG_NULL | MI_FLAG_NOT_MODIFIED);
|
1894 mike 1.1
1895 if (!Field_GetExists(field, (MI_Type)pd->type))
1896 *flagsOut |= MI_FLAG_NULL;
|
1897 krisbash 1.4
1898 /* get the field flags */
1899 switch ((MI_Type)pd->type)
1900 {
1901 case MI_UINT8:
1902 case MI_SINT8:
1903 case MI_BOOLEAN:
1904 {
1905 MI_Uint8Field* f = (MI_Uint8Field*)field;
1906 fieldFlags = f->flags;
1907 break;
1908 }
1909 case MI_UINT16:
1910 case MI_SINT16:
1911 case MI_CHAR16:
1912 {
1913 MI_Uint16Field* f = (MI_Uint16Field*)field;
1914 fieldFlags = f->flags;
1915 break;
1916 }
1917 case MI_UINT32:
1918 krisbash 1.4 case MI_SINT32:
1919 case MI_REAL32:
1920 {
1921 MI_Uint32Field* f = (MI_Uint32Field*)field;
1922 fieldFlags = f->flags;
1923 break;
1924 }
1925 case MI_UINT64:
1926 case MI_SINT64:
1927 case MI_REAL64:
1928 {
1929 MI_Uint64Field* f = (MI_Uint64Field*)field;
1930 fieldFlags = f->flags;
1931 break;
1932 }
1933 case MI_DATETIME:
1934 {
1935 MI_DatetimeField* f = (MI_DatetimeField*)field;
1936 fieldFlags = f->flags;
1937 break;
1938 }
1939 krisbash 1.4 case MI_STRING:
1940 {
1941 MI_StringField* f = (MI_StringField*)field;
1942 fieldFlags = f->flags;
1943 break;
1944 }
1945 case MI_INSTANCE:
1946 case MI_REFERENCE:
1947 {
1948 MI_InstanceField* f = (MI_InstanceField*)field;
1949 fieldFlags = f->flags;
1950 break;
1951 }
1952 case MI_BOOLEANA:
1953 case MI_UINT8A:
1954 case MI_SINT8A:
1955 case MI_UINT16A:
1956 case MI_SINT16A:
1957 case MI_UINT32A:
1958 case MI_SINT32A:
1959 case MI_UINT64A:
1960 krisbash 1.4 case MI_SINT64A:
1961 case MI_REAL32A:
1962 case MI_REAL64A:
1963 case MI_CHAR16A:
1964 case MI_DATETIMEA:
1965 case MI_INSTANCEA:
1966 case MI_REFERENCEA:
1967 case MI_STRINGA:
1968 {
1969 MI_StringAField* f = (MI_StringAField*)field;
1970 fieldFlags = f->flags;
1971 break;
1972 }
1973 }
1974 if ((fieldFlags & _MODIFIED) == 0)
1975 {
1976 *flagsOut |= MI_FLAG_NOT_MODIFIED;
1977 }
|
1978 mike 1.1 }
1979
1980 /* Set typeOut */
1981 if (typeOut)
1982 *typeOut = (MI_Type)pd->type;
1983
1984 MI_RETURN(MI_RESULT_OK);
1985 }
1986
1987 MI_Result MI_CALL __MI_Instance_ClearElement(
|
1988 krisbash 1.5 MI_Instance* self_,
|
1989 krisbash 1.4 const ZChar* name)
|
1990 mike 1.1 {
1991 Instance* self = _SelfOf(self_);
1992 MI_Uint32 index;
1993
1994 /* Check for null arguments */
1995 if (!self || !name)
1996 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1997
1998 /* Find the property with this name */
1999 index = _FindPropertyDecl(self->classDecl, name);
2000
2001 if (index == (MI_Uint32)-1)
2002 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
2003
2004 MI_RETURN(__MI_Instance_ClearElementAt(self_, index));
2005 }
2006
2007 MI_Result MI_CALL __MI_Instance_ClearElementAt(
|
2008 krisbash 1.5 MI_Instance* self_,
|
2009 mike 1.1 MI_Uint32 index)
2010 {
2011 Instance* self = _SelfOf(self_);
2012 const MI_PropertyDecl* pd;
2013 char* field;
2014
2015 /* Check for null arguments */
2016 if (!self)
2017 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
|
2018 krisbash 1.5
|
2019 mike 1.1 /* Check whether index is in range */
2020 if (index > self->classDecl->numProperties)
2021 MI_RETURN(MI_RESULT_FAILED);
2022
2023 /* Get pointer to properties declaration */
2024 pd = self->classDecl->properties[index];
2025
2026 /* Get pointer to field */
2027 field = (char*)self + pd->offset;
2028
2029 /* Clear the value */
|
2030 krisbash 1.4 Field_Clear((Field*)field, pd->type,
|
2031 mike 1.1 self->batch);
2032
2033 MI_RETURN(MI_RESULT_OK);
2034 }
2035
|
2036 krisbash 1.4 MI_Result MI_CALL __MI_Instance_GetServerName(
|
2037 mike 1.1 const MI_Instance* self_,
|
2038 krisbash 1.4 const ZChar** servername)
|
2039 mike 1.1 {
2040 Instance* self = _SelfOf(self_);
2041
2042 if (!self)
2043 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
2044
|
2045 krisbash 1.4 if (servername)
2046 *servername = self->serverName;
2047
2048 MI_RETURN(MI_RESULT_OK);
2049 }
2050
2051 MI_Result MI_CALL __MI_Instance_SetServerName(
2052 _Inout_ MI_Instance* self_,
2053 _In_z_ const ZChar* serverName)
2054 {
2055 Instance* self = _SelfOf(self_);
2056 Instance* selfOrg = (Instance*)self_;
2057 MI_Char* oldServerName;
|
2058 mike 1.1
|
2059 krisbash 1.4 /* Check parameters */
2060 if (!self)
2061 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
|
2062 mike 1.1
|
2063 krisbash 1.4 /* Save old namespace */
2064 oldServerName = self->serverName;
|
2065 mike 1.1
|
2066 krisbash 1.4 /* Set new namespace */
2067 if (serverName)
2068 {
2069 MI_Char* tmp;
|
2070 mike 1.1
|
2071 krisbash 1.4 tmp = BStrdup(self->batch, serverName, CALLSITE);
|
2072 mike 1.1
|
2073 krisbash 1.4 if (!tmp)
2074 MI_RETURN(MI_RESULT_SERVER_LIMITS_EXCEEDED);
|
2075 mike 1.1
|
2076 krisbash 1.4 self->serverName = tmp;
|
2077 mike 1.1 }
|
2078 krisbash 1.4 else
2079 self->serverName = NULL;
|
2080 mike 1.1
|
2081 krisbash 1.4 if (selfOrg != self)
2082 selfOrg->serverName = self->serverName;
|
2083 mike 1.1
|
2084 krisbash 1.4 /* Free old namespace */
2085 if (oldServerName)
2086 BFree(self->batch, oldServerName, CALLSITE);
|
2087 mike 1.1
2088 MI_RETURN(MI_RESULT_OK);
2089 }
2090
|
2091 krisbash 1.4 MI_Result MI_CALL __MI_Instance_GetClass(
2092 _In_ const MI_Instance* self_,
2093 _Outptr_ MI_Class** instanceClass)
2094 {
2095 Instance* self = _SelfOf(self_);
2096
2097 return Class_New(self->classDecl, self->nameSpace, self->serverName, instanceClass);
2098 }
2099
2100 MI_Result MI_CALL MI_Instance_GetClassExt(
|
2101 krisbash 1.5 _In_ const MI_Instance *self,
|
2102 krisbash 1.4 _Inout_ MI_Class* classToGet)
|
2103 mike 1.1 {
|
2104 krisbash 1.5 if ((self == NULL) || (classToGet == NULL))
|
2105 krisbash 1.4 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
|
2106 krisbash 1.5
|
2107 krisbash 1.4 return Class_Construct(classToGet, self->classDecl);
|
2108 mike 1.1 }
2109
|
2110 krisbash 1.4 MI_Result Instance_SetElementArray(
|
2111 krisbash 1.5 _Out_ MI_Instance* self_,
|
2112 krisbash 1.4 _In_z_ const MI_Char* name,
2113 MI_Type type,
2114 MI_Uint32 flags,
2115 MI_Uint32 numberArrayItems,
2116 _Out_ MI_Uint32 *elementId
2117 )
2118 {
2119 MI_Result result;
2120 Instance* self = _SelfOf(self_);
2121 MI_Uint32 index;
2122 MI_ArrayField *fieldValue;
2123 MI_Value nullValue;
2124
2125 //Find the ID of the entry
2126 /* Check for null arguments */
2127 if (!self || !name)
2128 MI_RETURN(MI_RESULT_INVALID_PARAMETER);
2129
2130 /* Find the property with this name */
2131 index = _FindPropertyDeclIndex(self->classDecl, name);
2132
2133 krisbash 1.4 if (index == (MI_Uint32)-1)
2134 MI_RETURN(MI_RESULT_NO_SUCH_PROPERTY);
2135
2136 //SetElementAt with NULL value
2137 nullValue.array.data = NULL;
2138 nullValue.array.size = 0;
2139 result = __MI_Instance_SetElementAt(self_, index, &nullValue, type|MI_ARRAY, flags);
2140 if (result != MI_RESULT_OK)
2141 {
2142 return result;
2143 }
2144
2145 //Get the array field
2146 fieldValue = (MI_ArrayField*)((char*)self + self->classDecl->properties[index]->offset);
2147
2148 //Allocate the element array
2149 fieldValue->value.size = 0; //We set the size as 0, but as items are added the number is increased
2150 if (numberArrayItems)
2151 {
2152 fieldValue->value.data = Batch_Get(self->batch, numberArrayItems*Type_SizeOf(type));
2153 if (fieldValue->value.data == NULL)
2154 krisbash 1.4 {
2155 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
2156 }
2157 }
2158 else
2159 {
2160 fieldValue->value.data = NULL;
2161 }
2162 *elementId = index;
2163 return MI_RESULT_OK;
2164 }
2165
2166 MI_Result Instance_SetElementArrayItem(
2167 _Out_ MI_Instance* self_,
|
2168 krisbash 1.5 MI_Uint32 elementId,
|
2169 krisbash 1.4 MI_Value value)
|
2170 mike 1.1 {
|
2171 krisbash 1.4 Instance* self = _SelfOf(self_);
2172 MI_ArrayField *fieldValue;
|
2173 krisbash 1.5 MI_Type type;
|
2174 krisbash 1.4 MI_Result result;
2175
2176 type = (MI_Type)(self->classDecl->properties[elementId]->type & ~16); //Remove array part of type;
2177
2178 fieldValue = (MI_ArrayField*)((char*)self + self->classDecl->properties[elementId]->offset);
2179
2180 result = Class_Clone_ArrayValue(self->batch, type, fieldValue->value.data, fieldValue->value.size, &value);
2181 if (result != MI_RESULT_OK)
2182 return result;
2183
2184 //Bump how many array items we have in value
2185 fieldValue->value.size++;
2186 fieldValue->exists = MI_TRUE;
2187
2188 return MI_RESULT_OK;
|
2189 mike 1.1 }
2190
|
2191 krisbash 1.4 MI_Boolean Instance_IsDynamic(
2192 _In_ MI_Instance *self_)
|
2193 mike 1.1 {
|
2194 krisbash 1.4 Instance* self = _SelfOf(self_);
2195 if (self != (void*)self_)
2196 return MI_TRUE;
2197 else
2198 return MI_FALSE;
|
2199 mike 1.1 }
2200
|
2201 krisbash 1.5 /*
|
2202 krisbash 1.4 * Verifies that all key properties of the instance have non-NULL values. A
2203 * NULL key property means that it is a malformed instance.
2204 *
2205 * Note: __MI_Instance_* functions are used in case the provided instance
2206 * does not have a function table.
2207 */
2208 MI_Boolean Instance_ValidateNonNullKeys(
2209 const MI_Instance* self )
|
2210 mike 1.1 {
|
2211 krisbash 1.4 MI_Uint32 i = 0;
|
2212 krisbash 1.5
|
2213 krisbash 1.4 if (Instance_IsDynamic((MI_Instance*)self))
2214 {
2215 /* Dynamic instance
|
2216 krisbash 1.5 * Since it doesn't have a MI_ClassDecl, the best we can do is to
|
2217 krisbash 1.4 * validate whether all of its key properties are non-NULL. */
2218 MI_Uint32 count = 0;
2219 MI_Result result = __MI_Instance_GetElementCount( self, &count );
2220 if (MI_RESULT_OK != result)
2221 return MI_FALSE;
2222 for (i = 0; i < count; i++)
2223 {
2224 MI_Uint32 flags = 0;
2225 MI_Result result = __MI_Instance_GetElementAt( self, i, NULL, NULL, NULL, &flags );
2226 if (MI_RESULT_OK != result)
2227 return MI_FALSE;
|
2228 krisbash 1.5 if ((MI_FLAG_KEY & flags) &&
|
2229 krisbash 1.4 (MI_FLAG_NULL & flags))
2230 return MI_FALSE;
2231 }
2232 return MI_TRUE;
2233 }
2234 else
2235 {
2236 /* Static instance
2237 * Validate that each key property is non-NULL */
2238 const MI_ClassDecl* cd = self->classDecl;
2239 for (i = 0; i < cd->numProperties; i++)
2240 {
2241 if (cd->properties[i]->flags & MI_FLAG_KEY)
2242 {
2243 MI_Uint32 flags = 0;
2244 MI_Result result = __MI_Instance_GetElementAt( self, i, NULL, NULL, NULL, &flags );
2245 if (MI_RESULT_OK != result)
2246 return MI_FALSE;
2247 if (MI_FLAG_NULL & flags)
2248 return MI_FALSE;
2249 }
2250 krisbash 1.4 }
2251 return MI_TRUE;
2252 }
|
2253 mike 1.1 }
2254
|
2255 krisbash 1.4
|
2256 mike 1.1 MI_InstanceFT __mi_instanceFT =
2257 {
2258 __MI_Instance_Clone,
2259 __MI_Instance_Destruct,
2260 __MI_Instance_Delete,
2261 __MI_Instance_IsA,
2262 __MI_Instance_GetClassName,
2263 __MI_Instance_SetNameSpace,
2264 __MI_Instance_GetNameSpace,
2265 __MI_Instance_GetElementCount,
2266 __MI_Instance_AddElement,
2267 __MI_Instance_SetElement,
2268 __MI_Instance_SetElementAt,
2269 __MI_Instance_GetElement,
2270 __MI_Instance_GetElementAt,
2271 __MI_Instance_ClearElement,
2272 __MI_Instance_ClearElementAt,
2273 __MI_Instance_GetServerName,
2274 __MI_Instance_SetServerName,
2275 __MI_Instance_GetClass,
2276 };
|