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

   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**)&parameterSet->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              

ViewCVS 0.9.2