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

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include <common.h>
  26           #include "wsmanbuffer.h"
  27           #include <base/log.h>
  28           #include <base/result.h>
  29           #include <base/instance.h>
  30           #include <base/strings.h>
  31           #include <base/field.h>
  32           #include <base/messages.h>
  33           #include <base/helpers.h>
  34           #include <base/time.h>
  35           #include <base/io.h>
  36           
  37           #define T MI_T
  38           
  39           #if 0
  40           #define ENABLE_TRACING
  41           #endif
  42           
  43 mike  1.1 #ifdef  ENABLE_TRACING
  44           #define PRINTF(a)  printf a
  45           #else
  46           #define PRINTF(a)
  47           #endif
  48           
  49           #define XML_CR    MI_T("\n")
  50           
  51           /*
  52           **==============================================================================
  53           **
  54           ** Local datatypes:
  55           **
  56           **==============================================================================
  57           */
  58           typedef struct _BUF_FaultItem
  59           {
  60               const MI_Char*  action;
  61               MI_Uint32       actionSize;
  62               const char* code;       /* sender/receiver */
  63               const char* subCode;    /* wsa:XXX */
  64 mike  1.1     const char* defaultTest;
  65           } 
  66           BUF_FaultItem;
  67           
  68           typedef struct _BUF_CIMErrorItem
  69           {
  70               WSBUF_FAULT_CODE    faultCode;
  71               const MI_Char* description;
  72           } 
  73           BUF_CIMErrorItem;
  74           
  75           typedef struct _Char_Encoding
  76           {
  77               const MI_Char*  str;
  78               MI_Uint32       size;
  79           } 
  80           Char_Encoding;
  81           
  82           /*
  83           **==============================================================================
  84           **
  85 mike  1.1 ** Forward declarations:
  86           **
  87           **==============================================================================
  88           */
  89           static MI_Result _PackInstance(
  90               WS_Buffer* buf,
  91               const MI_Instance* instance,
  92               MI_Boolean (*filterProperty)(const MI_Char* name, void* data),
  93               void* filterPropertyData,
  94               const MI_ClassDecl* castToClassDecl,
  95               MI_Uint32 flags,
  96               MI_Boolean embedded);
  97           
  98           static MI_Result _PackEPR(
  99               WS_Buffer* buf,
 100               const MI_Instance* instance);
 101           
 102           /*
 103           **==============================================================================
 104           **
 105           ** Static data:
 106 mike  1.1 **
 107           **==============================================================================
 108           */
 109           
 110           static const BUF_FaultItem s_faults[] = {
 111               /* WSBUF_FAULT_INTERNAL_ERROR */
 112               {
 113                   LIT(MI_T("http://schemas.dmtf.org/wbem/wsman/1/wsman/fault")),
 114                   "SOAP-ENV:Receiver",
 115                   "wsman:InternalError",
 116                   "The service cannot comply with the request due to internal processing errors."
 117               },
 118               /* WSBUF_FAULT_NOT_SUPPORTED */
 119               {
 120                   LIT(MI_T("http://schemas.dmtf.org/wbem/wsman/1/wsman/fault")),
 121                   "SOAP-ENV:Sender",
 122                   "wsman:UnsupportedFeature",
 123                   "not supported"
 124               },
 125               /* WSBUF_FAULT_NOT_UNDERSTOOD */
 126               {
 127 mike  1.1         LIT(MI_T("http://schemas.xmlsoap.org/ws/2004/08/addressing/fault")),
 128                   "SOAP-ENV:MustUnderstand",
 129                   0,
 130                   "Header not understood"
 131               },
 132               /* WSBUF_FAULT_DESTINATION_UNREACHABLE */
 133               {
 134                   LIT(MI_T("http://schemas.xmlsoap.org/ws/2004/08/addressing/fault")),
 135                   "SOAP-ENV:Sender",
 136                   "wsa:DestinationUnreachable",
 137                   "No route can be determined to reach the destination role defined by the Addressing To header."
 138               },
 139               /* WSBUF_FAULT_ACCESS_DENIED */
 140               {
 141                   LIT(MI_T("http://schemas.dmtf.org/wbem/wsman/1/wsman/fault")),
 142                   "SOAP-ENV:Sender",
 143                   "wsman:AccessDenied",
 144                   "The sender was not authorized to access the resource."
 145               },
 146               /* WSBUF_FAULT_ENCODING_LIMIT */
 147               {
 148 mike  1.1         LIT(MI_T("http://schemas.dmtf.org/wbem/wsman/1/wsman/fault")),
 149                   "SOAP-ENV:Sender",
 150                   "wsman:EncodingLimit",
 151                   "An internal encoding limit was exceeded in a request or would be violated if the message were processed."
 152               }
 153           };
 154           
 155           static const BUF_CIMErrorItem   s_cimerrors[] = {
 156               /* MI_RESULT_OK = 0, */
 157               {
 158                   0,
 159                   0
 160               },
 161               /* MI_RESULT_FAILED = 1, */
 162               {
 163                   WSBUF_FAULT_INTERNAL_ERROR,
 164                   MI_T("CIM ERROR:FAILED: A general error occurred, not covered by a more specific error code.")
 165               },
 166           
 167               /* MI_RESULT_ACCESS_DENIED = 2, */
 168               {
 169 mike  1.1         WSBUF_FAULT_ACCESS_DENIED,
 170                   MI_T("CIM ERROR:ACCESS_DENIED: Access to a CIM resource is not available to the client.")
 171               },
 172           
 173               /* MI_RESULT_INVALID_NAMESPACE = 3, */
 174               {
 175                   WSBUF_FAULT_DESTINATION_UNREACHABLE,
 176                   MI_T("CIM ERROR:INVALID_NAMESPACE: The target namespace does not exist.")
 177               },
 178           
 179               /* MI_RESULT_INVALID_PARAMETER  = 4,*/
 180               {
 181                   WSBUF_FAULT_INTERNAL_ERROR,
 182                   MI_T("CIM ERROR:INVALID_PARAMETER: One or more parameter values passed to the method are not valid.")
 183               },
 184           
 185               /* MI_RESULT_INVALID_CLASS = 5, */
 186               {
 187                   WSBUF_FAULT_DESTINATION_UNREACHABLE,
 188                   MI_T("CIM ERROR:INVALID_CLASS: The specified class does not exist.")
 189               },
 190 mike  1.1 
 191               /* MI_RESULT_NOT_FOUND = 6,*/
 192               {
 193                   WSBUF_FAULT_DESTINATION_UNREACHABLE,
 194                   MI_T("CIM ERROR:NOT_FOUND: The requested object cannot be found.")
 195               },
 196           
 197               /* MI_RESULT_NOT_SUPPORTED = 7, */
 198               {
 199                   WSBUF_FAULT_NOT_SUPPORTED,
 200                   MI_T("CIM ERROR:NOT_SUPPORTED: The requested operation is not supported.")
 201               }
 202           
 203           #if 0
 204               /* The operation cannot be invoked because the class has subclasses. */
 205               MI_RESULT_CLASS_HAS_CHILDREN = 8,
 206           
 207               /* The operation cannot be invoked because the class has instances. */
 208               MI_RESULT_CLASS_HAS_INSTANCES = 9,
 209           
 210               /* The operation cannot be invoked because the superclass does not exist. */
 211 mike  1.1     MI_RESULT_INVALID_SUPERCLASS = 10,
 212           
 213               /* The operation cannot be invoked because an object already exists. */
 214               MI_RESULT_ALREADY_EXISTS = 11,
 215           
 216               /* The specified property does not exist. */
 217               MI_RESULT_NO_SUCH_PROPERTY = 12,
 218           
 219               /* The value supplied is not compatible with the type. */
 220               MI_RESULT_TYPE_MISMATCH = 13,
 221           
 222               /* The query language is not recognized or supported. */
 223               MI_RESULT_QUERY_LANGUAGE_NOT_SUPPORTED = 14,
 224           
 225               /* The query is not valid for the specified query language. */
 226               MI_RESULT_INVALID_QUERY = 15,
 227           
 228               /* The extrinsic method cannot be invoked. */
 229               MI_RESULT_METHOD_NOT_AVAILABLE = 16,
 230           
 231               /* The specified extrinsic method does not exist. */
 232 mike  1.1     MI_RESULT_METHOD_NOT_FOUND = 17,
 233           
 234               /* The specified namespace is not empty. */
 235               MI_RESULT_NAMESPACE_NOT_EMPTY = 20,
 236           
 237               /* The enumeration identified by the specified context is invalid. */
 238               MI_RESULT_INVALID_ENUMERATION_CONTEXT = 21,
 239           
 240               /* The specified operation timeout is not supported by the CIM Server. */
 241               MI_RESULT_INVALID_OPERATION_TIMEOUT = 22,
 242           
 243               /* The Pull operation has been abandoned. */
 244               MI_RESULT_PULL_HAS_BEEN_ABANDONED = 23,
 245           
 246               /* The attempt to abandon a concurrent Pull operation failed. */
 247               MI_RESULT_PULL_CANNOT_BE_ABANDONED = 24,
 248           
 249               /* Using a filter in the enumeration is not supported by the CIM server. */
 250               MI_RESULT_FILTERED_ENUMERATION_NOT_SUPPORTED = 25,
 251           
 252               /* The CIM server does not support continuation on error. */
 253 mike  1.1     MI_RESULT_CONTINUATION_ON_ERROR_NOT_SUPPORTED = 26,
 254           
 255               /* The operation failed because server limits were exceeded. */
 256               MI_RESULT_SERVER_LIMITS_EXCEEDED = 27,
 257           
 258               /* The CIM server is shutting down and cannot process the operation. */
 259               MI_RESULT_SERVER_IS_SHUTTING_DOWN = 28
 260           #endif
 261           };
 262           
 263           // Defines encodings of special characters. Just use a 7-bit ASCII character
 264           // as an index into this array to retrieve its string encoding and encoding
 265           // length in bytes.
 266           static const Char_Encoding s_encodedChars127[128] =
 267           {
 268               {LIT(MI_T("&#0;"))},
 269               {LIT(MI_T("&#1;"))},
 270               {LIT(MI_T("&#2;"))},
 271               {LIT(MI_T("&#3;"))},
 272               {LIT(MI_T("&#4;"))},
 273               {LIT(MI_T("&#5;"))},
 274 mike  1.1     {LIT(MI_T("&#6;"))},
 275               {LIT(MI_T("&#7;"))},
 276               {LIT(MI_T("&#8;"))},
 277               {LIT(MI_T("&#9;"))},
 278               {LIT(MI_T("&#10;"))},
 279               {LIT(MI_T("&#11;"))},
 280               {LIT(MI_T("&#12;"))},
 281               {LIT(MI_T("&#13;"))},
 282               {LIT(MI_T("&#14;"))},
 283               {LIT(MI_T("&#15;"))},
 284               {LIT(MI_T("&#16;"))},
 285               {LIT(MI_T("&#17;"))},
 286               {LIT(MI_T("&#18;"))},
 287               {LIT(MI_T("&#19;"))},
 288               {LIT(MI_T("&#20;"))},
 289               {LIT(MI_T("&#21;"))},
 290               {LIT(MI_T("&#22;"))},
 291               {LIT(MI_T("&#23;"))},
 292               {LIT(MI_T("&#24;"))},
 293               {LIT(MI_T("&#25;"))},
 294               {LIT(MI_T("&#26;"))},
 295 mike  1.1     {LIT(MI_T("&#27;"))},
 296               {LIT(MI_T("&#28;"))},
 297               {LIT(MI_T("&#29;"))},
 298               {LIT(MI_T("&#30;"))},
 299               {LIT(MI_T("&#31;"))},
 300               {LIT(MI_T(" "))},
 301               {LIT(MI_T("!"))},
 302               {LIT(MI_T("&quot;"))},
 303               {LIT(MI_T("#"))},
 304               {LIT(MI_T("$"))},
 305               {LIT(MI_T("%"))},
 306               {LIT(MI_T("&amp;"))},
 307               {LIT(MI_T("&apos;"))},
 308               {LIT(MI_T("("))},
 309               {LIT(MI_T(")"))},
 310               {LIT(MI_T("*"))},
 311               {LIT(MI_T("+"))},
 312               {LIT(MI_T(","))},
 313               {LIT(MI_T("-"))},
 314               {LIT(MI_T("."))},
 315               {LIT(MI_T("/"))},
 316 mike  1.1     {LIT(MI_T("0"))},
 317               {LIT(MI_T("1"))},
 318               {LIT(MI_T("2"))},
 319               {LIT(MI_T("3"))},
 320               {LIT(MI_T("4"))},
 321               {LIT(MI_T("5"))},
 322               {LIT(MI_T("6"))},
 323               {LIT(MI_T("7"))},
 324               {LIT(MI_T("8"))},
 325               {LIT(MI_T("9"))},
 326               {LIT(MI_T(":"))},
 327               {LIT(MI_T(";"))},
 328               {LIT(MI_T("&lt;"))},
 329               {LIT(MI_T("="))},
 330               {LIT(MI_T("&gt;"))},
 331               {LIT(MI_T("?"))},
 332               {LIT(MI_T("@"))},
 333               {LIT(MI_T("A"))},
 334               {LIT(MI_T("B"))},
 335               {LIT(MI_T("C"))},
 336               {LIT(MI_T("D"))},
 337 mike  1.1     {LIT(MI_T("E"))},
 338               {LIT(MI_T("F"))},
 339               {LIT(MI_T("G"))},
 340               {LIT(MI_T("H"))},
 341               {LIT(MI_T("I"))},
 342               {LIT(MI_T("J"))},
 343               {LIT(MI_T("K"))},
 344               {LIT(MI_T("L"))},
 345               {LIT(MI_T("M"))},
 346               {LIT(MI_T("N"))},
 347               {LIT(MI_T("O"))},
 348               {LIT(MI_T("P"))},
 349               {LIT(MI_T("Q"))},
 350               {LIT(MI_T("R"))},
 351               {LIT(MI_T("S"))},
 352               {LIT(MI_T("T"))},
 353               {LIT(MI_T("U"))},
 354               {LIT(MI_T("V"))},
 355               {LIT(MI_T("W"))},
 356               {LIT(MI_T("X"))},
 357               {LIT(MI_T("Y"))},
 358 mike  1.1     {LIT(MI_T("Z"))},
 359               {LIT(MI_T("["))},
 360               {LIT(MI_T("\\"))},
 361               {LIT(MI_T("]"))},
 362               {LIT(MI_T("^"))},
 363               {LIT(MI_T("_"))},
 364               {LIT(MI_T("`"))},
 365               {LIT(MI_T("a"))},
 366               {LIT(MI_T("b"))},
 367               {LIT(MI_T("c"))},
 368               {LIT(MI_T("d"))},
 369               {LIT(MI_T("e"))},
 370               {LIT(MI_T("f"))},
 371               {LIT(MI_T("g"))},
 372               {LIT(MI_T("h"))},
 373               {LIT(MI_T("i"))},
 374               {LIT(MI_T("j"))},
 375               {LIT(MI_T("k"))},
 376               {LIT(MI_T("l"))},
 377               {LIT(MI_T("m"))},
 378               {LIT(MI_T("n"))},
 379 mike  1.1     {LIT(MI_T("o"))},
 380               {LIT(MI_T("p"))},
 381               {LIT(MI_T("q"))},
 382               {LIT(MI_T("r"))},
 383               {LIT(MI_T("s"))},
 384               {LIT(MI_T("t"))},
 385               {LIT(MI_T("u"))},
 386               {LIT(MI_T("v"))},
 387               {LIT(MI_T("w"))},
 388               {LIT(MI_T("x"))},
 389               {LIT(MI_T("y"))},
 390               {LIT(MI_T("z"))},
 391               {LIT(MI_T("{"))},
 392               {LIT(MI_T("|"))},
 393               {LIT(MI_T("}"))},
 394               {LIT(MI_T("~"))},
 395               {LIT(MI_T("&#127;"))}
 396           };
 397           
 398           /* Table used to identify special characters */
 399           static const char s_specialChars[256] =
 400 mike  1.1 {
 401               1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 402               0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,
 403               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 404               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
 405               1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 406               1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 407               1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 408               1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 409           };
 410           
 411           /*
 412           **==============================================================================
 413           **
 414           ** Local definitions:
 415           **
 416           **==============================================================================
 417           */
 418           MI_INLINE MI_Boolean _Field_GetExists(
 419               const void* field, 
 420               MI_Type type)
 421 mike  1.1 {
 422               return Field_GetExists((const Field*)field, type);
 423           }
 424           
 425           static MI_Result _ReallocPage(
 426               WS_Buffer* buf,
 427               MI_Uint32 newSize)
 428           {
 429               Page* new_page;
 430           
 431               /* round up to next 1k */
 432           #define WSMAN_BUF_CAPACITY 1024
 433               newSize = ((newSize + WSMAN_BUF_CAPACITY) / WSMAN_BUF_CAPACITY)  * WSMAN_BUF_CAPACITY;
 434               new_page = (Page*)realloc(buf->page, sizeof(Page) + newSize);
 435           
 436               if (!new_page)
 437                   return MI_RESULT_FAILED;
 438           
 439               buf->page = new_page;
 440               buf->page->u.s.size = newSize;
 441               return MI_RESULT_OK;
 442 mike  1.1 }
 443           
 444           #if 0
 445           #if (MI_CHAR_TYPE == 1)
 446           #define FIRST_HIGH_SURROGATE  0xD800
 447           #define LAST_HIGH_SURROGATE   0xDBFF
 448           
 449           static void _UTF16toUTF8(
 450               MI_Char16 c,
 451               char* s)
 452           {
 453               static const MI_Uint8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 454               MI_Uint8* tgt = (MI_Uint8*)s;
 455               MI_Uint32 numberOfBytes;
 456           
 457               /* not a valid single char */
 458               if (c >= FIRST_HIGH_SURROGATE
 459                   && c <= LAST_HIGH_SURROGATE)
 460               {
 461                   s[0] = '?';
 462                   s[1] = 0;
 463 mike  1.1         return;
 464               }
 465           
 466               if (c < 0x80)
 467               {
 468                   numberOfBytes = 1;
 469               }
 470               else if (c < 0x800)
 471               {
 472                   numberOfBytes = 2;
 473               }
 474               else 
 475               {
 476                   numberOfBytes = 3;
 477               }
 478           
 479               tgt += numberOfBytes;
 480           
 481               switch (numberOfBytes)
 482               {
 483                   case 3:
 484 mike  1.1         *--tgt = (MI_Uint8)((c | 0x80) & 0xBF);
 485                   c >>= 6;
 486                   case 2:
 487                   *--tgt = (MI_Uint8)((c | 0x80) & 0xBF);
 488                   c >>= 6;
 489                   case 1:
 490                   *--tgt =  (MI_Uint8)(c | firstByteMark[numberOfBytes]);
 491               }
 492           }
 493           #endif
 494           #endif
 495           
 496           /*
 497           **==============================================================================
 498           **
 499           ** Public API:
 500           **
 501           **==============================================================================
 502           */
 503           MI_Result WSBuf_Init(
 504               WS_Buffer* buf,
 505 mike  1.1     MI_Uint32 initialSize)
 506           {
 507               buf->page = (Page*)malloc(sizeof(Page) + initialSize);
 508               buf->position = 0;
 509           
 510               if (!buf->page)
 511               {
 512                   return MI_RESULT_FAILED;
 513               }
 514           
 515               buf->page->u.s.size = initialSize;
 516               buf->page->u.s.next = 0;
 517               /* Put empty string inside */
 518               ((MI_Char*)(buf->page +1))[0] = 0;
 519               return MI_RESULT_OK;
 520           }
 521           
 522           MI_Result WSBuf_Destroy(
 523               WS_Buffer* buf)
 524           {
 525               if (buf->page)
 526 mike  1.1         free(buf->page);
 527           
 528               return MI_RESULT_OK;
 529           }
 530           
 531           #if (MI_CHAR_TYPE == 1)
 532           Page* WSBuf_StealPage(
 533               WS_Buffer* buf)
 534           {
 535               Page* res = buf->page;
 536           
 537               if (!res)
 538                   return 0;
 539           
 540               buf->page = 0;
 541               res->u.s.size = buf->position;
 542               buf->position = 0;
 543           
 544               return res;
 545           }
 546           #else
 547 mike  1.1 Page* WSBuf_StealPage(
 548               WS_Buffer* buf)
 549           {
 550           
 551               if (!buf->page)
 552                   return 0;
 553           
 554               /* convert wchar_t to utf-8 
 555                   unfortunately, Windows does not support wchat -> utf8 conversion in crt */
 556           
 557               {
 558                   Page* res;
 559                   const MI_Char* text = ((MI_Char*)(buf->page +1));
 560                   int size = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, 0, NULL);
 561           
 562                   if (size == 0)
 563                       goto failed;
 564           
 565                   res = (Page*)malloc(sizeof(Page) + size);
 566           
 567                   if (!res)
 568 mike  1.1             goto failed;
 569           
 570                   if (WideCharToMultiByte(CP_UTF8, 0, text, -1, (char*)(res + 1), size, 0, NULL) == 0) 
 571                   {
 572                       free(res);
 573                       goto failed;
 574                   }
 575           
 576                   res->u.s.size = size - 1;
 577                   res->u.s.next = 0;
 578           
 579                   free(buf->page);
 580                   buf->page = 0;
 581                   buf->position = 0;
 582                   return res;
 583               }
 584           
 585           failed:
 586               free(buf->page);
 587               buf->page = 0;
 588               return 0;
 589 mike  1.1 }
 590           #endif
 591           
 592           MI_Result WSBuf_AddUint32(
 593               WS_Buffer* buf,
 594               MI_Uint32 x)
 595           {
 596               MI_Char tmp[12];
 597               size_t size;
 598               const MI_Char* s = Uint32ToZStr(tmp, x, &size);
 599               return WSBuf_AddLit(buf, s, (MI_Uint32)size);
 600           }
 601           
 602           MI_Result __WSBuf_AddLit(
 603               WS_Buffer* buf,
 604               const MI_Char* str,
 605               MI_Uint32 size)
 606           {
 607               MI_Uint32 n = (size + 1) * sizeof(MI_Char);
 608           
 609               /* Extend buffer (WSBuf_AddLit determined it was too small) */
 610 mike  1.1     if (_ReallocPage(buf, n + buf->position) != MI_RESULT_OK)
 611                   return MI_RESULT_FAILED;
 612           
 613               /* Add string */
 614               {
 615                   char* data = ((char*)(buf->page+1)) + buf->position;
 616                   memcpy( data, str, n - sizeof(MI_Char));
 617                   ((MI_Char*)data)[size] = 0;
 618           
 619                   buf->position += n - sizeof(MI_Char);
 620               }
 621           
 622               return MI_RESULT_OK;
 623           }
 624           
 625           /* Add string with proper xml encoding */
 626           MI_Result WSBuf_AddString(
 627               WS_Buffer* buf,
 628               const MI_Char* str)
 629           {
 630           #if (MI_CHAR_TYPE == 1)
 631 mike  1.1     /* Process leading non-special characters in the hope that little will
 632                * be left over to be encoded the expensive way below this block.
 633                */
 634               {
 635                   const unsigned char* start = (const unsigned char*)str;
 636                   const unsigned char* p = start;
 637           
 638                   while (!s_specialChars[*p])
 639                       p++;
 640           
 641                   if (p != start)
 642                   {
 643                       if (WSBuf_AddLit(buf, (const char*)start, (MI_Uint32)(p - start)))
 644                           return MI_RESULT_FAILED;
 645           
 646                       str = (const char*)p;
 647                   }
 648           
 649                   if (!*str)
 650                       return MI_RESULT_OK;
 651               }
 652 mike  1.1 #endif
 653           
 654               /* Now encode what remains (starting with first special char hit above) */
 655               {
 656                   /*MI_Uint32 size = (MI_Uint32)((MI_Strlen(str) + 1)*sizeof(MI_Char));*/
 657                   MI_Char* pos = (MI_Char*)(((char*)(buf->page +1)) + buf->position);
 658                   MI_Char* end = (MI_Char*)(((char*)(buf->page +1)) + buf->page->u.s.size);
 659           
 660                   /* Add reamingin characters (next character is special) */
 661                   while (*str)
 662                   {
 663                       const MI_Char* item;
 664                       size_t size_chars;
 665                       MI_Uint32 c = (MI_Uint32)(MI_Sint16)*str;
 666           
 667                       /* if c is ascii ?*/
 668                       if (c < 128)
 669                       {
 670                           item = s_encodedChars127[c].str;
 671                           size_chars = s_encodedChars127[c].size;
 672                       }
 673 mike  1.1             else
 674                       {
 675                           item = str;
 676                           size_chars = 1;
 677                       }
 678           
 679                       /* Extend buffer if needed */
 680                       if ( (size_t)(end - pos) <= (size_chars + 1))
 681                       {
 682                           size_t current_pos = 
 683                               (pos - ((MI_Char*)(buf->page +1))) * sizeof(MI_Char);
 684           
 685                           if (_ReallocPage(buf, (MI_Uint32)(buf->page->u.s.size + size_chars * sizeof(MI_Char))) != MI_RESULT_OK)
 686                               return MI_RESULT_FAILED;
 687           
 688                           pos = (MI_Char*)(((char*)(buf->page +1)) + current_pos);
 689                           end = (MI_Char*)(((char*)(buf->page +1)) + buf->page->u.s.size);
 690                       }
 691           
 692                       if (1 == size_chars)
 693                           *pos = *item;
 694 mike  1.1             else
 695                           memcpy( pos, item, size_chars * sizeof(MI_Char));
 696           
 697                       pos += size_chars;
 698                       str++;
 699                   }
 700           
 701                   buf->position = (MI_Uint32)((pos - ((MI_Char*)(buf->page +1))) * sizeof(MI_Char));
 702           
 703                   /* put \0 at the end */
 704                   ((MI_Char*)(((char*)(buf->page +1)) + buf->position))[0] = 0;
 705           
 706                   return MI_RESULT_OK;
 707               }
 708           }
 709           
 710           #if (MI_CHAR_TYPE != 1)
 711           MI_Result WSBuf_AddCharStringNoEncoding(
 712               WS_Buffer* buf,
 713               const char* str)
 714           {
 715 mike  1.1     return WSBuf_AddCharLit(buf, str, (MI_Uint32)strlen(str));
 716           }
 717           
 718           MI_Result WSBuf_AddCharLit(
 719               WS_Buffer* buf,
 720               const char* str,
 721               MI_Uint32 size_)
 722           {
 723               MI_Uint32 size = (MI_Uint32)((size_ + 1)*sizeof(MI_Char));
 724           
 725               /* Extend buffer if needed */
 726               if (size + buf->position > buf->page->u.s.size &&
 727                   _ReallocPage(buf, size + buf->position) != MI_RESULT_OK)
 728                   return MI_RESULT_FAILED;
 729           
 730               {
 731                   MI_Char* data = (MI_Char*)(((char*)(buf->page +1)) + buf->position);
 732                   MI_Uint32 i;
 733           
 734                   for (i = 0; i < size_; i++)
 735                   {
 736 mike  1.1             *data++ = *str++;
 737                   }
 738                   buf->position += size - sizeof(MI_Char);
 739               }
 740           
 741               return MI_RESULT_OK;
 742           }
 743           
 744           #endif
 745           
 746           /* Callback to tag writer:
 747               allows to write properties for both values/EPRs with the same routine */
 748           typedef MI_Result (*PropertyTagWriter)(
 749               WS_Buffer* buf,
 750               const MI_Char* name,
 751               MI_Boolean start);
 752           
 753           INLINE MI_Result PropertyTagWriter_PropStart(
 754               WS_Buffer* buf,
 755               const MI_Char* name)
 756           {
 757 mike  1.1     MI_Uint32 n = (MI_Uint32)Zlen(name);
 758           
 759               if (MI_RESULT_OK != WSBuf_AddLit3(buf, '<', 'p', ':') ||
 760                   MI_RESULT_OK != WSBuf_AddLit(buf, name, n) ||
 761                   MI_RESULT_OK != WSBuf_AddLit1(buf,'>'))
 762               {
 763                   return MI_RESULT_FAILED;
 764               }
 765           
 766               return MI_RESULT_OK;
 767           }
 768           
 769           INLINE MI_Result PropertyTagWriter_PropEnd(
 770               WS_Buffer* buf,
 771               const MI_Char* name)
 772           {
 773               MI_Uint32 n = (MI_Uint32)Zlen(name);
 774           
 775               if (MI_RESULT_OK != WSBuf_AddLit4(buf, '<', '/', 'p', ':') || 
 776                   MI_RESULT_OK != WSBuf_AddLit(buf, name, n) ||
 777                   MI_RESULT_OK != WSBuf_AddLit2(buf, '>', '\n'))
 778 mike  1.1     {
 779                   return MI_RESULT_FAILED;
 780               }
 781           
 782               return MI_RESULT_OK;
 783           }
 784           
 785           static MI_Result PropertyTagWriter_Prop(
 786               WS_Buffer* buf,
 787               const MI_Char* name,
 788               MI_Boolean start)
 789           {
 790               if (start)
 791                   return PropertyTagWriter_PropStart(buf, name);
 792               else
 793                   return PropertyTagWriter_PropEnd(buf, name);
 794           }
 795           
 796           static MI_Result PropertyTagWriter_EPR(
 797               WS_Buffer* buf,
 798               const MI_Char* name,
 799 mike  1.1     MI_Boolean start)
 800           {
 801               if (start)
 802               {
 803                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("<wsman:Selector Name=\""))) ||
 804                       MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,name) ||
 805                       MI_RESULT_OK != WSBuf_AddLit2(buf, '"', '>')
 806                       )
 807                       return MI_RESULT_FAILED;
 808               }
 809               else
 810               {
 811                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wsman:Selector>") XML_CR)) 
 812                       )
 813                       return MI_RESULT_FAILED;
 814               }
 815           
 816               return MI_RESULT_OK;
 817           }
 818           
 819           static MI_Result _PackFieldNil(
 820 mike  1.1     WS_Buffer* buf,
 821               const MI_Char* name)
 822           {
 823               if ( MI_RESULT_OK != WSBuf_AddLit3(buf, '<', 'p', ':') ||
 824                   MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,name) ||
 825                   MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T(" xsi:nil=\"true\"/>") XML_CR)) )
 826                   return MI_RESULT_FAILED;
 827           
 828               return MI_RESULT_OK;
 829           }
 830           
 831           static MI_Result _PackFieldString(
 832               WS_Buffer* buf,
 833               PropertyTagWriter writer,
 834               const MI_Char* name,
 835               const MI_Char* value)
 836           {
 837               if ( MI_RESULT_OK != writer(buf,name,MI_TRUE) ||
 838                   MI_RESULT_OK != WSBuf_AddString(buf,value) ||
 839                   MI_RESULT_OK != writer(buf,name,MI_FALSE)
 840                   )
 841 mike  1.1         return MI_RESULT_FAILED;
 842           
 843               return MI_RESULT_OK;
 844           }
 845           
 846           static MI_Result _PackFieldStringLit(
 847               WS_Buffer* buf,
 848               PropertyTagWriter writer,
 849               const MI_Char* name,
 850               const MI_Char* value,
 851               MI_Uint32 valueSize)
 852           {
 853               if ( MI_RESULT_OK != writer(buf,name,MI_TRUE) ||
 854                   MI_RESULT_OK != WSBuf_AddLit(buf,value,valueSize) ||
 855                   MI_RESULT_OK != writer(buf,name,MI_FALSE)  
 856                   )
 857                   return MI_RESULT_FAILED;
 858           
 859               return MI_RESULT_OK;
 860           }
 861           
 862 mike  1.1 static MI_Result _PackFieldEmbeddedInstance(
 863               WS_Buffer* buf,
 864               const MI_Char* name,
 865               const MI_Instance* value)
 866           {
 867               if ( MI_RESULT_OK != PropertyTagWriter_PropStart(buf,name) ||
 868                   MI_RESULT_OK != _PackInstance(buf,value,NULL,NULL,0,WSMAN_ObjectFlag,MI_TRUE) ||
 869                   MI_RESULT_OK != PropertyTagWriter_PropEnd(buf,name)  
 870                   )
 871                   return MI_RESULT_FAILED;
 872           
 873               return MI_RESULT_OK;
 874           }
 875           
 876           static MI_Result _PackFieldRef(
 877               WS_Buffer* buf,
 878               const MI_Char* name,
 879               const MI_Instance* value)
 880           {
 881               if ( MI_RESULT_OK != PropertyTagWriter_PropStart(buf,name) ||
 882                   MI_RESULT_OK != _PackEPR(buf,value) ||
 883 mike  1.1         MI_RESULT_OK != PropertyTagWriter_PropEnd(buf,name)  
 884                   )
 885                   return MI_RESULT_FAILED;
 886           
 887               return MI_RESULT_OK;
 888           }
 889           
 890           static MI_Result _PackFieldUint32(
 891               WS_Buffer* buf,
 892               PropertyTagWriter writer,
 893               const MI_Char* name,
 894               MI_Uint32 value)
 895           {
 896               MI_Char tmp[11];
 897               size_t size;
 898               const MI_Char* str = Uint32ToZStr(tmp, value, &size);
 899               return _PackFieldStringLit(buf,writer, name, str, (MI_Uint32)size);
 900           }
 901           
 902           static MI_Result _PackFieldUint64(
 903               WS_Buffer* buf,
 904 mike  1.1     PropertyTagWriter writer,
 905               const MI_Char* name,
 906               MI_Uint64 value)
 907           {
 908               MI_Char tmp[21];
 909               size_t size;
 910               const MI_Char* str = Uint64ToZStr(tmp, value, &size);
 911               return _PackFieldStringLit(buf, writer, name, str, (MI_Uint32)size);
 912           }
 913           
 914           static MI_Result _PackFieldSint32(
 915               WS_Buffer* buf,
 916               PropertyTagWriter writer,
 917               const MI_Char* name,
 918               MI_Sint32 value)
 919           {
 920               MI_Char s[24];
 921           
 922               MI_Sint32 size = Szprintf(s, MI_COUNT(s), MI_T("%d"), value);
 923               return _PackFieldStringLit(buf,writer,name,s,size);
 924           }
 925 mike  1.1 
 926           static MI_Result _PackFieldSint64(
 927               WS_Buffer* buf,
 928               PropertyTagWriter writer,
 929               const MI_Char* name,
 930               MI_Sint64 value)
 931           {
 932               MI_Char s[24];
 933           
 934               MI_Sint32 size = Szprintf(s, MI_COUNT(s), SINT64_FMT_T, value);
 935               return _PackFieldStringLit(buf,writer,name,s,size);
 936           }
 937           
 938           static MI_Result _PackFieldReal64(
 939               WS_Buffer* buf,
 940               PropertyTagWriter writer,
 941               const MI_Char* name,
 942               MI_Real64 value)
 943           {
 944               MI_Char s[24];
 945           
 946 mike  1.1     MI_Sint32 size = Szprintf(s, MI_COUNT(s), MI_T("%g"), value);
 947               return _PackFieldStringLit(buf,writer,name,s,size);
 948           }
 949           
 950           static MI_Result _PackFieldDatetime(
 951               WS_Buffer* buf,
 952               PropertyTagWriter writer,
 953               const MI_Char* name,
 954               const MI_Datetime* p)
 955           {
 956               MI_Char tmp[64];
 957               FormatWSManDatetime(p, tmp);
 958               return _PackFieldStringLit(buf, writer, name, tmp, (MI_Uint32)Zlen(tmp));
 959           }
 960           
 961           static MI_Result _PackValue(
 962               WS_Buffer* buf,
 963               PropertyTagWriter writer,
 964               const MI_Char* name,
 965               const void* field, 
 966               MI_Type type)
 967 mike  1.1 {
 968               switch(type)
 969               {
 970                   case MI_BOOLEAN:
 971                   {
 972                       MI_Boolean* f = (MI_Boolean*)field;
 973           
 974                       if (*f)
 975                           return _PackFieldStringLit(buf,writer,name,LIT(MI_T("TRUE")));
 976                       else
 977                           return _PackFieldStringLit(buf,writer,name,LIT(MI_T("FALSE")));
 978                   }
 979                   case MI_UINT8:
 980                   {
 981                       MI_Uint8* f = (MI_Uint8*)field;
 982           
 983                       return _PackFieldUint32(buf,writer,name,*f);
 984                   }
 985                   case MI_UINT16:
 986                   {
 987                       MI_Uint16* f = (MI_Uint16*)field;
 988 mike  1.1 
 989                       return _PackFieldUint32(buf,writer,name,*f);
 990                   }
 991                   case MI_UINT32:
 992                   {
 993                       MI_Uint32* f = (MI_Uint32*)field;
 994           
 995                       return _PackFieldUint32(buf,writer,name,*f);
 996                   }
 997                   case MI_UINT64:
 998                   {
 999                       MI_Uint64* f = (MI_Uint64*)field;
1000           
1001                       return _PackFieldUint64(buf,writer,name,*f);
1002                   }
1003                   case MI_SINT8:
1004                   {
1005                       MI_Sint8* f = (MI_Sint8*)field;
1006           
1007                       return _PackFieldSint32(buf,writer,name,*f);
1008                   }
1009 mike  1.1         case MI_SINT16:
1010                   {
1011                       MI_Sint16* f = (MI_Sint16*)field;
1012           
1013                       return _PackFieldSint32(buf,writer,name,*f);
1014                   }
1015                   case MI_SINT32:
1016                   {
1017                       MI_Sint32* f = (MI_Sint32*)field;
1018           
1019                       return _PackFieldSint32(buf,writer,name,*f);
1020                   }
1021                   case MI_SINT64:
1022                   {
1023                       MI_Sint64* f = (MI_Sint64*)field;
1024           
1025                       return _PackFieldSint64(buf,writer,name,*f);
1026                   }
1027                   case MI_REAL32:
1028                   {
1029                       MI_Real32* f = (MI_Real32*)field;
1030 mike  1.1 
1031                       return _PackFieldReal64(buf,writer,name,*f);
1032                   }
1033                   case MI_REAL64:
1034                   {
1035                       MI_Real64* f = (MI_Real64*)field;
1036           
1037                       return _PackFieldReal64(buf,writer,name,*f);
1038                   }
1039                   case MI_DATETIME:
1040                   {
1041                       MI_Datetime* f = (MI_Datetime*)field;
1042           
1043                       return _PackFieldDatetime(buf,writer,name,&*f);
1044                   }
1045                   case MI_CHAR16:
1046                   {
1047                       MI_Char16* f = (MI_Char16*)field;
1048           #if 0
1049           #if (MI_CHAR_TYPE == 1)
1050                       char s[6];
1051 mike  1.1             memset(s,0,sizeof(s));
1052           
1053                       _UTF16toUTF8(*f,s);
1054           #else
1055                       /* whcar_t - 
1056                       steal page will translate it */
1057                       wchar_t s[2] = {0, 0};
1058           
1059                       s[0] = *f;
1060           #endif
1061           
1062                       /* ATTN: convert it to utf8 and encode as a string */
1063                       return _PackFieldString(buf,writer,name,s);
1064           #else
1065                       return _PackFieldUint32(buf,writer,name,(MI_Uint32)*f);
1066           #endif
1067                   }
1068                   case MI_INSTANCE:
1069                   {
1070                       MI_Instance** f = (MI_Instance**)field;
1071           
1072 mike  1.1             return _PackFieldEmbeddedInstance(buf,name,*f);
1073                   }
1074                   case MI_REFERENCE:
1075                   {
1076                       MI_Instance** f = (MI_Instance**)field;
1077           
1078                       return _PackFieldRef(buf,name,*f);
1079                   }
1080                   case MI_STRING:
1081                   {
1082                       MI_String* f = (MI_String*)field;
1083           
1084                       return _PackFieldString(buf,writer,name,*f);
1085                   }
1086                   default:
1087                       break;
1088               }
1089           
1090               return MI_RESULT_OK;
1091           }
1092           
1093 mike  1.1 static MI_Result _PackField(
1094               WS_Buffer* buf,
1095               PropertyTagWriter writer,
1096               const MI_Char* name,
1097               const void* field, 
1098               MI_Type type)
1099           {
1100               /* Check if value is null */
1101               if (!_Field_GetExists(field, type))
1102                   return _PackFieldNil(buf, name);
1103           
1104               /* Check if type is array:
1105                   Arrays are encoded the same way regular instances are 
1106                   with repeating instance as many times as many elements are in array */
1107               if (type & MI_ARRAY_BIT)
1108               {
1109                   MI_ArrayField* f = (MI_ArrayField*)field;
1110                   MI_Uint32 i;
1111                   MI_Type stype = type & ~MI_ARRAY_BIT;
1112                   char* currentValue = (char*)f->value.data;
1113           
1114 mike  1.1         for (i = 0; i < f->value.size; i++)
1115                   {
1116                       if (MI_RESULT_OK != _PackValue(buf,writer,name,currentValue,stype))
1117                           return MI_RESULT_FAILED;
1118           
1119                       currentValue += Type_SizeOf(stype);
1120                   }
1121                   return MI_RESULT_OK;
1122               }
1123           
1124               return _PackValue(buf,writer,name,field,type);
1125           }
1126           
1127           static MI_Result _PackEPR(
1128               WS_Buffer* buf,
1129               const MI_Instance* instance)
1130           {
1131               Instance* self = (Instance*)instance;
1132               const MI_ClassDecl* cd = self->classDecl;
1133               MI_Uint32 i;
1134           
1135 mike  1.1     /* Put EPR header */
1136               if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>") XML_CR
1137                       MI_T("<wsa:ReferenceParameters>") XML_CR 
1138                       MI_T("<wsman:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/") )) ||
1139                   MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,cd->name) ||
1140                   MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wsman:ResourceURI>") XML_CR 
1141                       MI_T("<wsman:SelectorSet>") XML_CR )) )
1142                   return MI_RESULT_FAILED;
1143           
1144               /* namespace (if present)*/
1145               if (self->nameSpace)
1146               {
1147               }
1148           
1149               /* Put properties */
1150               for ( i = 0; i < cd->numProperties; i++ )
1151               {
1152                   const MI_PropertyDecl* pd = cd->properties[i];
1153                   const void* value = (char*)self + pd->offset;
1154           
1155                   if ((pd->flags & MI_FLAG_KEY) == 0)
1156 mike  1.1             continue;
1157           
1158                   /* skip null values */
1159                   if (!_Field_GetExists(value,(MI_Type)pd->type))
1160                       continue;
1161           
1162                   if (MI_RESULT_OK != _PackValue(buf, PropertyTagWriter_EPR, pd->name, value, (MI_Type)pd->type))
1163                       return MI_RESULT_FAILED;
1164               }
1165           
1166               /* close EPR */
1167               if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wsman:SelectorSet>") XML_CR
1168                       MI_T("</wsa:ReferenceParameters>") XML_CR )) )
1169                   return MI_RESULT_FAILED;
1170           
1171               return MI_RESULT_OK;
1172           }
1173           
1174           static MI_Result _PackInstance(
1175               WS_Buffer* buf,
1176               const MI_Instance* instance,
1177 mike  1.1     MI_Boolean (*filterProperty)(const MI_Char* name, void* data),
1178               void* filterPropertyData,
1179               const MI_ClassDecl* castToClassDecl,
1180               MI_Uint32 flags,
1181               MI_Boolean embedded)
1182           {
1183               Instance* self = (Instance*)instance;
1184               const MI_ClassDecl* cd = castToClassDecl ? castToClassDecl : self->classDecl;
1185               MI_Uint32 i;
1186           
1187               /* Check for null arguments */
1188               if (!self || !buf)
1189                   MI_RETURN(MI_RESULT_INVALID_PARAMETER);
1190           
1191               /* For Object & EPR, add <Item> tag */
1192               if ((flags & WSMAN_ObjectAndEPRFlag) == WSMAN_ObjectAndEPRFlag)
1193               {
1194                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("<wsman:Item>") XML_CR)))
1195                       return MI_RESULT_FAILED;
1196               }
1197           
1198 mike  1.1     /* If object was requested */
1199               if ((flags & WSMAN_ObjectFlag) == WSMAN_ObjectFlag)
1200               {
1201                   /* Put classname */
1202                   if ( MI_RESULT_OK != WSBuf_AddLit3(buf, '<', 'p', ':') ||
1203                       MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,cd->name) ||
1204                       MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T(" xmlns:p=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"))) ||
1205                       MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,cd->name) ||
1206                       MI_RESULT_OK != WSBuf_AddLit2(buf, '"', '\n'))
1207                       return MI_RESULT_FAILED;
1208           
1209                   if (embedded)
1210                   {
1211                       if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T(" xsi:type=\""))) ||
1212                           MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,cd->name) ||
1213                           MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("_Type\"") XML_CR)))
1214                           return MI_RESULT_FAILED;
1215                   }
1216                   if ( MI_RESULT_OK != WSBuf_AddLit2(buf, '>', '\n'))
1217                       return MI_RESULT_FAILED;
1218           
1219 mike  1.1         /* Put properties */
1220                   for ( i = 0; i < cd->numProperties; i++ )
1221                   {
1222                       const MI_PropertyDecl* pd = cd->properties[i];
1223                       const void* value = (char*)self + pd->offset;
1224           
1225                       if (filterProperty && (*filterProperty)(pd->name, filterPropertyData))
1226                           continue;
1227           
1228                       if (MI_RESULT_OK != _PackField(buf, PropertyTagWriter_Prop, pd->name, value, (MI_Type)pd->type))
1229                           return MI_RESULT_FAILED;
1230                   }
1231           
1232                   /* close class */
1233                   if ( MI_RESULT_OK != WSBuf_AddLit4(buf, '<', '/', 'p', ':') ||
1234                       MI_RESULT_OK != WSBuf_AddStringNoEncoding(buf,cd->name) ||
1235                       MI_RESULT_OK != WSBuf_AddLit2(buf, '>', '\n'))
1236                       return MI_RESULT_FAILED;
1237               }
1238           
1239               /* If EPR was requested */
1240 mike  1.1     if ((flags & WSMAN_EPRFlag) == WSMAN_EPRFlag)
1241               {
1242                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("<wsa:EndpointReference>") XML_CR)) ||
1243                       MI_RESULT_OK != _PackEPR(buf,instance) ||
1244                       MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wsa:EndpointReference>") XML_CR)))
1245                       return MI_RESULT_FAILED;
1246               }
1247           
1248               /* If EPR was requested */
1249               if ((flags & WSMAN_CreatedEPRFlag) == WSMAN_CreatedEPRFlag)
1250               {
1251                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("<wxf:ResourceCreated>") XML_CR)) ||
1252                       MI_RESULT_OK != _PackEPR(buf,instance) ||
1253                       MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wxf:ResourceCreated>") XML_CR)))
1254                       return MI_RESULT_FAILED;
1255               }
1256           
1257               /* For Object & EPR, add </Item> tag */
1258               if ((flags & WSMAN_ObjectAndEPRFlag) == WSMAN_ObjectAndEPRFlag)
1259               {
1260                   if ( MI_RESULT_OK != WSBuf_AddLit(buf,LIT(MI_T("</wsman:Item>") XML_CR)))
1261 mike  1.1             return MI_RESULT_FAILED;
1262               }
1263           
1264           
1265               return MI_RESULT_OK;
1266           }
1267           
1268           MI_Result WSBuf_InstanceToBuf(
1269               const MI_Instance* instance,
1270               MI_Boolean (*filterProperty)(const MI_Char* name, void* data),
1271               void* filterPropertyData,
1272               const MI_ClassDecl* castToClassDecl,
1273               Batch* batch,
1274               MI_Uint32 flags,
1275               void** ptrOut,
1276               MI_Uint32* sizeOut)
1277           {
1278               WS_Buffer buf;
1279               MI_Result r;
1280               Page* page;
1281           
1282 mike  1.1     r = WSBuf_Init(&buf,1024);
1283           
1284               if (MI_RESULT_OK != r)
1285                   return r;
1286           
1287               r = _PackInstance(&buf, instance, filterProperty, 
1288                   filterPropertyData, castToClassDecl, flags,MI_FALSE);
1289           
1290               if (MI_RESULT_OK != r)
1291               {
1292                   WSBuf_Destroy(&buf);
1293                   return r;
1294               }
1295           
1296               page = WSBuf_StealPage(&buf);
1297               Batch_AttachPage(batch, page);
1298           
1299               *ptrOut = page + 1;
1300               *sizeOut = (MI_Uint32)page->u.s.size;
1301               return MI_RESULT_OK;
1302           }
1303 mike  1.1 
1304           void WSBuf_GenerateMessageID(
1305               MI_Char msgID[WS_MSG_ID_SIZE])
1306           {
1307               //WS-Management qualifies the use of wsa:MessageID and wsa:RelatesTo as follows:
1308               //R5.4.6.4-1: The MessageID and RelatesTo URIs may be of any format, as long as they are valid
1309               //URIs according to RFC 3986. Two URIs are considered different even if the characters in the
1310               //URIs differ only by case.
1311               //The following two formats are endorsed by this specification. The first is considered a best
1312               //practice because it is backed by RFC 4122:
1313               //urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1314               //or
1315               //uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1316               //In these formats, each x is an uppercase or lowercase hexadecimal digit (lowercase is required
1317               //by RFC 4122); there are no spaces or other tokens. The value may be a DCE-style universally
1318               //unique identifier (UUID) with provable uniqueness properties in this format, however, it is not
1319               //necessary to have provable uniqueness properties in the URIs used in the wsa:MessageID and
1320               //wsa:RelatesTo headers.
1321               //Regardless of format, the URI should not exceed the maximum defined in R13.1-6.
1322               //UUIDs have a numeric meaning as well as a string meaning, and this can lead to confusion. A UUID
1323               //in lowercase is a different URI from the same UUID in uppercase. This is because URIs are case1619
1324 mike  1.1     //tive. If a UUID is converted to its decimal equivalent the case of the original characters is lost.
1325               //WS-Management works with the URI value itself, not the underlying decimal equivalent
1326               //representation. Services are free to interpret the URI in any way, but are not allowed to alter the case
1327               //usage when repeating the message or any of the MessageID values in subsequent messages.
1328               //The RFC 4122 requires the digits to be lowercase, which is the responsibility of the client. The service
1329               //simply processes the values as URI values and is not required to analyze the URI for correctness or
1330               //compliance. The service replicates the client usage in the wsa:RelatesTo reply header and is not
1331               //allowed to alter the case usage.
1332               //R5.4.6.4-2: The MessageID should be generated according to any algorithm that ensures that no
1333               //two MessageIDs are repeated. Because the value is treated as case-sensitive (R5.4.6.4-1),
1334               //confusion can arise if the same value is reused differing only in case. As a result, the service shall
1335               //not create or employ MessageID values that differ only in case. For any message transmitted by
1336               //the service, the MessageID shall not be reused.
1337           
1338               static MI_Uint64  s1, s2;
1339           
1340               if (!s1)
1341                   Time_Now(&s1);
1342           
1343               s2++;
1344           
1345 mike  1.1     /* ADC */
1346               if (!s2)
1347                   s1++;
1348           
1349               Szprintf(msgID, WS_MSG_ID_SIZE,
1350                   MI_T("uuid:%08X-%04X-%04X-%04X-%08X%04X"),
1351                   (MI_Uint32)(s1 & 0xFFFFFFFF),
1352                   (MI_Uint32)((s1 >> 32) & 0xFFFF),
1353                   (MI_Uint32)((s1 >> 48) & 0xFFFF),
1354                   (MI_Uint32)((s2 >> 48) & 0xFFFF),
1355                   (MI_Uint32)(s2 & 0xFFFFFFFF),
1356                   (MI_Uint32)((s2 >> 32) & 0xFFFF) );
1357           }
1358           
1359           MI_Result WSBuf_CreateSoapResponseHeader(
1360               WS_Buffer   *buf,
1361               const MI_Char*  action,
1362               MI_Uint32       actionSize,
1363               const char*     relatesTo)
1364           {
1365               MI_Char msgID[WS_MSG_ID_SIZE];
1366 mike  1.1 
1367               /* Response header */
1368               if (MI_RESULT_OK != WSBuf_AddLit(buf, 
1369                   LIT(
1370                   MI_T("<SOAP-ENV:Envelope ")         
1371                   MI_T("xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\" ")
1372                   MI_T("xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" ")
1373                   MI_T("xmlns:wsen=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" ")
1374                   MI_T("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
1375                   MI_T("xmlns:wsmb=\"http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd\" ")
1376                   MI_T("xmlns:wsman=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\" ")
1377                   MI_T("xmlns:wxf=\"http://schemas.xmlsoap.org/ws/2004/09/transfer\" ")
1378                   MI_T("xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" ")
1379                   MI_T("xmlns:wsmid=\"http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd\" >")
1380                   XML_CR
1381                   MI_T("<SOAP-ENV:Header>")                                                       XML_CR
1382                   MI_T("<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>")    XML_CR
1383                   MI_T("<wsa:Action>")))  )
1384               {
1385                   goto failed;
1386               }
1387 mike  1.1 
1388               if (MI_RESULT_OK != WSBuf_AddLit(buf, action, actionSize))
1389                   goto failed;
1390           
1391               if (MI_RESULT_OK != WSBuf_AddLit(buf, 
1392                       LIT(MI_T("</wsa:Action>")           XML_CR
1393                       MI_T("<wsa:MessageID>" ))))
1394                   goto failed;
1395           
1396               /* Generate new uniqueue msg id */
1397               WSBuf_GenerateMessageID(msgID);
1398           
1399               if (MI_RESULT_OK != WSBuf_AddLit(buf, msgID, WS_MSG_ID_SIZE - 1))
1400                   goto failed;
1401           
1402               if (MI_RESULT_OK != WSBuf_AddLit(buf,
1403                   LIT(MI_T("</wsa:MessageID>")    XML_CR)))
1404                   goto failed;
1405           
1406               if (relatesTo)
1407               {
1408 mike  1.1         if (MI_RESULT_OK != WSBuf_AddLit(buf,
1409                       LIT(MI_T("<wsa:RelatesTo>"))))
1410                       goto failed;
1411           
1412                   if (MI_RESULT_OK != WSBuf_AddCharStringNoEncoding(buf, relatesTo))
1413                       goto failed;
1414           
1415                   if (MI_RESULT_OK != WSBuf_AddLit(buf,
1416                       LIT(MI_T("</wsa:RelatesTo>")        XML_CR)))
1417                       goto failed;
1418               }
1419           
1420               return MI_RESULT_OK;
1421           
1422           failed:
1423               return MI_RESULT_FAILED;
1424           }
1425           
1426           
1427           
1428           Page* WSBuf_CreateFaultResponsePage(
1429 mike  1.1     WSBUF_FAULT_CODE faultCode,
1430               const char* notUnderstoodTag,
1431               const char* requestMessageID,
1432               const MI_Char* descriptionText)
1433           {
1434               WS_Buffer   outBuf;
1435               const BUF_FaultItem* fault;
1436           
1437               if ( ((MI_Uint32)faultCode) >= MI_COUNT(s_faults))
1438               {
1439                   fault = s_faults + 0; /* internal error */
1440               }
1441               else
1442               {
1443                   fault = s_faults + (MI_Uint32)faultCode;
1444               }
1445           
1446           
1447               /* prepare soap response with error */
1448               if (WSBuf_Init(&outBuf, 1024) != MI_RESULT_OK)
1449                   return 0;
1450 mike  1.1 
1451               /* fault header */
1452               if (MI_RESULT_OK != WSBuf_CreateSoapResponseHeader(&outBuf,
1453                   fault->action, fault->actionSize, requestMessageID))
1454                   goto failed;
1455           
1456               if (notUnderstoodTag)
1457               {
1458                   if (MI_RESULT_OK != WSBuf_AddLit(&outBuf, 
1459                           LIT(MI_T("<SOAP-ENV:NotUnderstood qname=\""))))
1460                       goto failed;
1461           
1462                   if (MI_RESULT_OK != WSBuf_AddCharStringNoEncoding(&outBuf, notUnderstoodTag ))
1463                       goto failed;
1464           
1465                   if (MI_RESULT_OK != WSBuf_AddLit3(&outBuf, '"', '/', '>'))
1466                       goto failed;
1467               }
1468           
1469               if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1470                   LIT(
1471 mike  1.1         MI_T("</SOAP-ENV:Header>")      XML_CR  XML_CR
1472                   MI_T("<SOAP-ENV:Body>")         XML_CR
1473                   MI_T("<SOAP-ENV:Fault>")        XML_CR
1474                   MI_T("<SOAP-ENV:Code>")         XML_CR
1475                   MI_T("<SOAP-ENV:Value>")))  )
1476                   goto failed;
1477           
1478               if (MI_RESULT_OK != WSBuf_AddCharStringNoEncoding(&outBuf, fault->code))
1479                   goto failed;
1480                   //SOAP-ENV:Sender
1481           
1482               if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1483                   LIT(MI_T("</SOAP-ENV:Value>")       XML_CR)))
1484                   goto failed;
1485           
1486               if (fault->subCode)
1487               {
1488                   if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1489                       LIT(MI_T("<SOAP-ENV:Subcode>")      XML_CR
1490                       MI_T("<SOAP-ENV:Value>"))))
1491                       goto failed;
1492 mike  1.1 
1493                   if (MI_RESULT_OK != WSBuf_AddCharStringNoEncoding(&outBuf, fault->subCode))
1494                       goto failed;
1495           
1496                   if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1497                       LIT(MI_T("</SOAP-ENV:Value>")       XML_CR
1498                       MI_T("</SOAP-ENV:Subcode>")     XML_CR)))
1499                       goto failed;
1500               }
1501           
1502               if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1503                   LIT(MI_T("</SOAP-ENV:Code>")        XML_CR
1504                   MI_T("<SOAP-ENV:Reason>")       XML_CR
1505                   MI_T("<SOAP-ENV:Text xml:lang=\"en-US\">"))))
1506                   goto failed;
1507           
1508               if ( descriptionText )
1509               {
1510                   if (MI_RESULT_OK != WSBuf_AddString(&outBuf, descriptionText))
1511                       goto failed;
1512               }
1513 mike  1.1     else
1514               {
1515                   if (MI_RESULT_OK != WSBuf_AddCharStringNoEncoding(&outBuf, fault->defaultTest))
1516                       goto failed;
1517               }
1518           
1519               if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1520                   LIT( MI_T("</SOAP-ENV:Text>")      XML_CR
1521                   MI_T("</SOAP-ENV:Reason>")      XML_CR
1522                   MI_T("</SOAP-ENV:Fault>")       XML_CR
1523                   MI_T("</SOAP-ENV:Body>")        XML_CR
1524                   MI_T("</SOAP-ENV:Envelope>")    XML_CR)) )
1525                   goto failed;
1526           
1527           
1528               return WSBuf_StealPage(&outBuf);
1529           
1530           failed:
1531           
1532               WSBuf_Destroy(&outBuf);
1533               return 0;
1534 mike  1.1 }
1535           
1536           Page* WSBuf_CreateReleaseResponsePage(
1537               const char* requestMessageID)
1538           {
1539               WS_Buffer   outBuf;
1540           
1541               /* prepare soap response with error */
1542               if (WSBuf_Init(&outBuf, 1024) != MI_RESULT_OK)
1543                   return 0;
1544           
1545               /* fault header */
1546               if (MI_RESULT_OK != WSBuf_CreateSoapResponseHeader(&outBuf,
1547                   LIT(MI_T("http://schemas.xmlsoap.org/ws/2004/09/enumeration/ReleaseResponse")), 
1548                   requestMessageID))
1549                   goto failed;
1550           
1551               if (MI_RESULT_OK != WSBuf_AddLit(&outBuf,
1552                   LIT(
1553                   MI_T("</SOAP-ENV:Header>")      XML_CR  XML_CR
1554                   MI_T("<SOAP-ENV:Body/>")         XML_CR
1555 mike  1.1         MI_T("</SOAP-ENV:Envelope>")    XML_CR)) )
1556                   goto failed;
1557           
1558               return WSBuf_StealPage(&outBuf);
1559           
1560           failed:
1561           
1562               WSBuf_Destroy(&outBuf);
1563               return 0;
1564           }
1565           
1566           WSBUF_FAULT_CODE    WSBuf_CIMErrorToWSFault(
1567               MI_Uint32       cimErrorCode,
1568               const MI_Char** description )
1569           {
1570               MI_Uint32 index = cimErrorCode < MI_COUNT(s_cimerrors) ? cimErrorCode : MI_RESULT_FAILED;
1571           
1572               if ( description )
1573                   *description = s_cimerrors[index].description;
1574           
1575               return s_cimerrors[index].faultCode;
1576 mike  1.1 }

ViewCVS 0.9.2