/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** Licensed under the Apache License, Version 2.0 (the "License"); you may not ** use this file except in compliance with the License. You may obtain a copy ** of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ #include #include "wsmanparser.h" #include "wsmanbuffer.h" //#include "http.h" //#include "time.h" //#include //#include #include #include #include #include "wstags.h" #include "wstags.inc" #include "uri.h" #define T MI_T #if 0 #define ENABLE_TRACING #endif #ifdef ENABLE_TRACING #define PRINTF(a) printf a #else #define PRINTF(a) #endif /* **============================================================================== ** ** Local definitions: ** **============================================================================== */ static int _GetInstance( XML* xml, XML_Elem *start, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams); /****************************************************************************************/ /* soap processing */ static int _MustUnderstandCanBeIgnored( const XML_Elem* e) { size_t i; for (i = 0; i < e->attrsSize; i++) { if (strcmp(e->attrs[i].name, "s:mustUnderstand") == 0 && strcmp(e->attrs[i].value, "true") == 0) { return -1; } } return 0; } static int _GetSelector( XML* xml, XML_Elem *e, const char** ns, const char* classname, MI_Instance** instance, Batch** batch) { size_t i; /* expecting namespace or key */ for (i = 0; i < e->attrsSize; i++) { if (strcmp(e->attrs[i].name, "Name") == 0 && strcmp(e->attrs[i].value, "__cimnamespace") == 0) { /* namespace */ if (XML_Expect(xml, e, XML_CHARS, NULL) != 0) return -1; PRINTF(("a:Selector:namespace{%s}\n", e->data)); *ns = e->data; } else if (strcmp(e->attrs[i].name, "Name") == 0) { /* keys */ const char* propName = e->attrs[i].value; if (XML_Expect(xml, e, XML_CHARS, NULL) != 0) return -1; PRINTF(("a:Selector:namespace{%s}\n", e->data)); /* allocate batch and instance if needed */ if (!(*instance)) { MI_Result r; MI_Char* cn; /* verify that we already received classname */ if (!classname) { XML_Raise(xml, "class-name was not found druing selector parsing"); return -1; } /* Destroy old batch if it exists (from previous operation) */ if (*batch) { Batch_Destroy(*batch); } *batch = Batch_New(BATCH_MAX_PAGES); if (!(*batch)) return -1; cn = Batch_Strdup2(*batch, classname); r = Instance_NewDynamic(instance, cn, MI_FLAG_CLASS, *batch); if (MI_RESULT_OK != r) return -1; } /* add next property to the instance */ { const MI_Char* wpropName = Batch_Strdup2(*batch, propName); MI_Result r; MI_Value value; value.string = Batch_Strdup2(*batch, e->data); // Set the property. r = MI_Instance_AddElement(*instance, wpropName, &value, MI_STRING, MI_FLAG_BORROW | MI_FLAG_KEY); if (MI_RESULT_OK != r) return -1; } } else continue; if (XML_Expect(xml, e, XML_END, "w:Selector") != 0) return -1; break; } return 0; } static int _GetSelectorSet( XML* xml, WSMAN_WSHeader* wsheader) { XML_Elem e; if (XML_Expect(xml, &e, XML_START, "w:Selector") != 0) return -1; /* iterate through all selector tags */ for (;;) { if (0 != _GetSelector( xml, &e, &wsheader->rqtNamespace, wsheader->rqtClassname, &wsheader->instance, &wsheader->instanceBatch)) return -1; /**/ if (XML_Next(xml, &e) != 0) return -1; if (XML_END == e.type) break; } return 0; } static int _GetReferenceParameters( XML* xml, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams) { XML_Elem e; const char* classname = 0; const char* nameSpace = NULL; /* extract ResourceURI and SelectorSet */ for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (XML_END == e.type) break; if (0 == strcmp("w:ResourceURI", e.data)) { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; classname = strrchr(e.data, '/'); /* skip '/' */ if (classname) classname++; if (XML_Expect(xml, &e, XML_END, "w:ResourceURI") != 0) return -1; continue; } if (0 == strcmp("w:SelectorSet", e.data)) { /* Allocate an instance */ if (!*dynamicInstanceParams) { MI_Result r; const MI_Char* cn; if (!classname) { XML_Raise(xml, "ResourceURI tag expected"); return -1; } cn = Batch_Strdup2(dynamicBatch, classname); r = Instance_NewDynamic(dynamicInstanceParams, cn, MI_FLAG_CLASS, dynamicBatch); if (MI_RESULT_OK != r) return -1; } /* iterate through all selector tags */ for (;;) { const char* ns = NULL; if (_GetSelector( xml, &e, &ns, classname, dynamicInstanceParams, &dynamicBatch) != 0) { return -1; } if (ns) { nameSpace = ns; } /**/ if (XML_Next(xml, &e) != 0) return -1; if (XML_END == e.type) break; } continue; } } if (nameSpace) (*dynamicInstanceParams)->nameSpace = nameSpace; return 0; } static int _GetReference( XML* xml, XML_Elem *start, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams) { XML_Elem e; e = *start; /* extract all parameters */ for (;;) { if (0 != strcmp("a:ReferenceParameters", e.data)) { if (XML_Skip(xml) != 0) return -1; if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) break; continue; } if (0 != _GetReferenceParameters(xml, dynamicBatch, dynamicInstanceParams)) return -1; if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) break; } return 0; } static int _GetSingleProperty( XML* xml, Batch* dynamicBatch, const char* propNameChar, MI_Value* value, MI_Type* type) { XML_Elem e; if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_CHARS) { /* Plain string property */ value->string = Batch_Strdup2(dynamicBatch, e.data); *type = MI_STRING; if (XML_Expect(xml, &e, XML_END, propNameChar) != 0) return -1; } else if ('a' == e.data[0]) { /* Reference as */ value->instance = 0; if (0 != _GetReference(xml, &e, dynamicBatch, &value->instance)) return -1; *type = MI_REFERENCE; } else { /* Embedded instance */ value->instance = 0; if (0 != _GetInstance(xml, &e, dynamicBatch, &value->instance)) return -1; *type = MI_INSTANCE; if (XML_Expect(xml, &e, XML_END, propNameChar) != 0) return -1; } return 0; } static int _AddValueToArray( Batch* dynamicBatch, MI_Value* valueA, MI_Type typeA, const MI_Value* value, MI_Type type) { /* does type match? */ if ((type | MI_ARRAY_BIT) != typeA) return -1; /* do we need to realloc array? */ if ((valueA->array.size % 16) == 0) { void* newData = Batch_Get(dynamicBatch, (valueA->array.size + 16) * sizeof(void*)); if (!newData) return -1; if (valueA->array.size) memcpy(newData, valueA->array.data, valueA->array.size * sizeof(void*)); valueA->array.data = newData; } if (type == MI_STRING) valueA->stringa.data[valueA->stringa.size] = value->string; else valueA->instancea.data[valueA->instancea.size] = value->instance; valueA->array.size++; return 0; } static int _GetInstance( XML* xml, XML_Elem *start, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams) { XML_Elem e; const MI_Char* propNameA = 0; MI_Value valueA; MI_Type typeA = MI_BOOLEAN; const MI_Char* propNamePrev = 0; MI_Value valuePrev; MI_Type typePrev = MI_BOOLEAN; memset(&valueA, 0, sizeof(valueA)); /* extract all parameters */ for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) break; /* skip possible comments */ if (e.type != XML_START) continue; /* allocate new instance if needed */ if (!*dynamicInstanceParams) { MI_Result r; const MI_Char* cn = Batch_Strdup2(dynamicBatch, start->data + 2); r = Instance_NewDynamic(dynamicInstanceParams, cn, MI_FLAG_CLASS, dynamicBatch); if (MI_RESULT_OK != r) return -1; } /* add next property to the instance */ if (e.size > 2) /* ?: */ { MI_Result r; MI_Value value; MI_Type type = MI_BOOLEAN; const char* propNameChar; const MI_Char* propName; propNameChar = e.data; propName = Batch_Strdup2(dynamicBatch, propNameChar + 2); type = MI_BOOLEAN; if (0 != _GetSingleProperty(xml, dynamicBatch, propNameChar, &value, &type)) return -1; /* Did we collect array's items? */ if (propNameA) { /* if we have array and new property matches array - add new item to the array */ if (0 == Zcmp(propNameA, propName)) { if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type)) return -1; } else { r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA, typeA, MI_FLAG_BORROW); if (MI_RESULT_OK != r) return -1; /* Clear array prop name */ propNameA = 0; propNamePrev = propName; valuePrev = value; typePrev = type; } } else if (propNamePrev) { /* Check if name is the same and we need to create an array */ if (0 == Zcmp(propNamePrev, propName)) { /* create array */ valueA.array.size = 0; valueA.array.data = 0; typeA = type | MI_ARRAY_BIT; propNameA = propName; if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &valuePrev, typePrev)) return -1; if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type)) return -1; } else { r = MI_Instance_AddElement(*dynamicInstanceParams, propNamePrev, &valuePrev, typePrev, MI_FLAG_BORROW); if (MI_RESULT_OK != r) return -1; propNamePrev = propName; valuePrev = value; typePrev = type; } } else { /* collecting first item */ propNamePrev = propName; valuePrev = value; typePrev = type; } } } /* if last property was array - add it */ if (propNameA) { MI_Result r; r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA, typeA, MI_FLAG_BORROW); if (MI_RESULT_OK != r) return -1; } else if (propNamePrev) { MI_Result r; r = MI_Instance_AddElement(*dynamicInstanceParams, propNamePrev, &valuePrev, typePrev, MI_FLAG_BORROW); if (MI_RESULT_OK != r) return -1; } /* check closing tag */ if (strcmp(e.data, start->data) != 0) return -1; return 0; } int WS_ParseWSHeader( XML* xml, WSMAN_WSHeader* wsheader) { XML_Elem e; memset(wsheader, 0, sizeof(WSMAN_WSHeader)); /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Header") != 0) return -1; for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END)// && strcmp(e.data, "s:Header") == 0) { int tag = HashStr(e.data, e.size); if (WSMANTAG_HEADER != tag) { LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data )); return -1; } //printf("DONE\n"); break; } /* skip possible comments */ if (e.type != XML_START) continue; switch (HashStr(e.data, e.size)) { case WSMANTAG_TO: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; PRINTF(("a:To{%s}\n", e.data)); if (XML_Expect(xml, &e, XML_END, "a:To") != 0) return -1; } break; case WSMANTAG_RESOURCE_URI: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; PRINTF(("w:ResourceURI{%s}\n", e.data)); wsheader->rqtClassname = strrchr(e.data, '/'); /* skip '/' */ if (wsheader->rqtClassname) wsheader->rqtClassname++; if (XML_Expect(xml, &e, XML_END, "w:ResourceURI") != 0) return -1; } break; case WSMANTAG_REPLY_TO: { if (XML_Expect(xml, &e, XML_START, "a:Address") != 0) return -1; if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; if (XML_Expect(xml, &e, XML_END, "a:Address") != 0) return -1; if (XML_Expect(xml, &e, XML_END, "a:ReplyTo") != 0) return -1; } break; case WSMANTAG_ACTION: { wsheader->foundAction = MI_TRUE; if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsheader->rqtAction = HashStr(e.data, e.size); if (0 == wsheader->rqtAction) { char* s; /* DSP0226; 9: Custom Actions (Methods) just need to have unique URI. We are assuming it has format like http:///wbem/wscim/1/cim-schema/2// */ if (0 != strncmp(e.data, "http://", 7)) return -1; wsheader->rqtServer = e.data + 7; s = strchr(wsheader->rqtServer, '/'); if (!s) return -1; *s = 0; s++; if (0 != strncmp(s, "wbem/wscim/1/cim-schema/2/", 26)) return -1; s += 26; wsheader->rqtClassname = s; s = strchr(s, '/'); if (!s) return -1; *s = 0; s++; wsheader->rqtMethod = s; } if (XML_Expect(xml, &e, XML_END, "a:Action") != 0) return -1; } break; case WSMANTAG_SELECTOR_SET: { if (_GetSelectorSet(xml, wsheader) != 0) return -1; } break; case WSMANTAG_MESSAGE_ID: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsheader->rqtMessageID = e.data; if (XML_Expect(xml, &e, XML_END, "a:MessageID") != 0) return -1; } break; case WSMANTAG_MAX_ENVELOPE_SIZE: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsheader->maxEnvelopeSize = (MI_Uint32)Strtoull(e.data, NULL, 10); PRINTF(("maxEnvelopeSize{%d}\n", wsheader->maxEnvelopeSize)); if (XML_Expect(xml, &e, XML_END, "w:MaxEnvelopeSize") != 0) return -1; } break; default: { if (_MustUnderstandCanBeIgnored(&e) != 0) { wsheader->unknownMandatoryTag = e.data; LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data )); /* validate header will send correct repsonse to the client */ } if (XML_Skip(xml) != 0) return -1; } break; } } return 0; } int WS_ParseSoapEnvelope(XML* xml) { XML_Elem e; /* Ignore the processing instruction (if any) */ { if (XML_Next(xml, &e) != 0) { XML_Raise(xml, "missing root element"); return -1; } if (e.type != XML_INSTRUCTION) { if (XML_PutBack(xml, &e) != 0) return -1; } } /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Envelope") != 0) return -1; return 0; } static const char* _ExpectCharsAndEnd( XML* xml, const char* name) { XML_Elem e; const char* chars; if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return NULL; chars = e.data; if (XML_Expect(xml, &e, XML_END, name) != 0) return NULL; return chars; } /* **============================================================================== ** ** _ParseAssociationFilterObject() ** ** Example: ** ** ** http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous ** ** ** ** http://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/ABC_Widget ** ** ** ** root/cimv2 ** ** ** 1001 ** ** ** ** * **============================================================================== */ static int _ParseAssociationFilterObject( XML* xml, Batch* batch, WSMAN_AssociationFilter* filter) { XML_Elem e; /* Parse child elements */ for (;;) { /* Get next element */ if (XML_Next(xml, &e) != 0) return -1; /* Put it back and break out if not a start tag */ if (e.type != XML_START) { if (XML_PutBack(xml, &e) != 0) return -1; break; } /* Handle "Object" tag */ if (strcmp(e.data, "a:ReferenceParameters") == 0) { if (_GetReferenceParameters( xml, batch, &filter->referenceParameters) != 0) { return -1; } } else if (strcmp(e.data, "a:Address") == 0) { filter->address = _ExpectCharsAndEnd(xml, "a:Address"); if (!filter->address) return -1; } else { if (XML_Skip(xml) != 0) return -1; } } /* Expect */ if (XML_Expect(xml, &e, XML_END, "b:Object") != 0) return -1; return 0; } /* **============================================================================== ** ** _ParseAssociationFilter() ** ** Example: ** ** ** ** http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous ** ** ** ** http://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/ABC_Widget ** ** ** ** root/cimv2 ** ** ** 1001 ** ** ** ** ** ** ABC_Connector ** ** ** Component ** ** ** ABC_Gadget ** ** ** Part ** ** ** **============================================================================== */ static int _ParseAssociationFilter( XML* xml, Batch* batch, WSMAN_AssociationFilter* filter) { XML_Elem e; /* Expect */ if (XML_Expect(xml, &e, XML_START, "b:AssociatedInstances") != 0) return -1; /* Parse child elements */ for (;;) { /* Get next element */ if (XML_Next(xml, &e) != 0) return -1; /* Put it back and break out if not a start tag */ if (e.type != XML_START) { if (XML_PutBack(xml, &e) != 0) return -1; break; } /* Handle "Object" tag */ if (strcmp(e.data, "b:Object") == 0) { if (_ParseAssociationFilterObject(xml, batch, filter) != 0) return -1; } else if (strcmp(e.data, "b:AssociationClassName") == 0) { filter->associationClassName = _ExpectCharsAndEnd( xml, "b:AssociationClassName"); if (!filter->associationClassName) return -1; } else if (strcmp(e.data, "b:Role") == 0) { filter->role = _ExpectCharsAndEnd(xml, "b:Role"); if (!filter->role) return -1; } else if (strcmp(e.data, "b:ResultClassName") == 0) { filter->resultClassName = _ExpectCharsAndEnd( xml, "b:ResultClassName"); if (!filter->resultClassName) return -1; } else if (strcmp(e.data, "b:ResultRole") == 0) { filter->resultRole = _ExpectCharsAndEnd( xml, "b:ResultRole"); if (!filter->resultRole) return -1; } else { if (XML_Skip(xml) != 0) return -1; } } #if 0 printf("AssociationFilter\n"); printf("{\n"); Instance_Print(filter->referenceParameters, stdout, 1, MI_TRUE); printf(" nameSpace{%s}\n", filter->referenceParameters->nameSpace); printf(" address{%s}\n", filter->address); printf(" associationClassName{%s}\n", filter->associationClassName); printf(" resultClassName{%s}\n", filter->resultClassName); printf(" role{%s}\n", filter->role); printf(" resultRole{%s}\n", filter->resultRole); printf("}\n"); #endif /* Expect */ if (XML_Expect(xml, &e, XML_END, "b:AssociatedInstances") != 0) return -1; return 0; } int WS_ParseEnumerateBody( XML* xml, Batch** batch, WSMAN_WSEnumeratePullBody* wsenumbody) { XML_Elem e; memset(wsenumbody, 0, sizeof(WSMAN_WSEnumeratePullBody)); /* Allocate batch (owned by WSMAN_ConnectionData object */ if (*batch == NULL) { *batch = Batch_New(BATCH_MAX_PAGES); if (!*batch) return -1; } /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_START, "n:Enumerate") != 0) return -1; for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) { int tag = HashStr(e.data, e.size); if (WSMANTAG_ENUM_ENUMERATE != tag) { LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data )); return -1; } break; } /* skip possible comments */ if (e.type != XML_START) continue; switch (HashStr(e.data, e.size)) { case WSMANTAG_ENUM_MAX_ELEMENTS: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumbody->maxElements = (MI_Uint32)Strtoull(e.data, NULL, 10); PRINTF(("maxElements{%d}\n", wsenumbody->maxElements)); if (XML_Expect(xml, &e, XML_END, "w:MaxElements") != 0) return -1; } break; case WSMANTAG_ENUM_OPTIMIZE_ENUMERATION: { wsenumbody->allowOptimization = MI_TRUE; if (XML_Skip(xml) != 0) return -1; } break; case WSMANTAG_ENUM_POLYMORPHISM_MODE: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumbody->polymorphismMode = HashStr(e.data, e.size); if (XML_Expect(xml, &e, XML_END, "b:PolymorphismMode") != 0) return -1; } break; case WSMANTAG_ENUM_MODE: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumbody->enumerationMode = HashStr(e.data, e.size); if (XML_Expect(xml, &e, XML_END, "w:EnumerationMode") != 0) return -1; } break; /* * Examples: * * SELECT Weight FROM Widget WHERE Key = 1001 * * * * * ... * * */ case WSMANTAG_ENUM_FILTER: { const char* dialect; const char* p; /* Get 'Dialect' attribute? */ dialect = XML_Elem_GetAttr(&e, "Dialect"); if (!dialect) { LOGW_CHAR(("wsman: Filter tag missing Dialect attribute")); return -1; } /* Reduce long dialect name to final component of path */ p = strrchr(dialect, '/'); if (p) wsenumbody->dialect = p + 1; else wsenumbody->dialect = dialect; /* Parse the association filter */ if (strcmp(dialect, URI_CIMBINDING "/associationFilter") == 0) { wsenumbody->foundAssociationFilter = MI_TRUE; if (_ParseAssociationFilter(xml, *batch, &wsenumbody->associationFilter) != 0) { return -1; } } else { /* Get the filter text */ if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumbody->filter = e.data; } /* Check for closing tag */ if (XML_Expect(xml, &e, XML_END, "w:Filter") != 0) return -1; } break; default: { if (_MustUnderstandCanBeIgnored(&e) != 0) { LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data )); return -1; } if (XML_Skip(xml) != 0) return -1; } break; } } /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; } int WS_ParseInvokeBody( XML* xml, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams) { XML_Elem e; *dynamicInstanceParams = 0; /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; /* Expect parameter's tag */ for (;;) { if (XML_Next(xml, &e) != 0) return -1; /* empty body? can be valid for methods without parameters */ if (e.type == XML_END) return 0; if (e.type == XML_START) break; } if (0 != _GetInstance(xml, &e, dynamicBatch, dynamicInstanceParams)) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; } int WS_ParseCreateBody( XML* xml, Batch* dynamicBatch, MI_Instance** dynamicInstanceParams) { XML_Elem e; /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; /* Expect parameter's tag */ if (XML_Next(xml, &e) != 0) return -1; if (0 != _GetInstance(xml, &e, dynamicBatch, dynamicInstanceParams)) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; } int WS_ParsePullBody( XML* xml, WSMAN_WSEnumeratePullBody* wsenumpullbody) { XML_Elem e; memset(wsenumpullbody, 0, sizeof(WSMAN_WSEnumeratePullBody)); /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_START, "n:Pull") != 0) return -1; for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) { int tag = HashStr(e.data, e.size); if (WSMANTAG_ENUM_PULL != tag) { LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data )); return -1; } break; } /* skip possible comments */ if (e.type != XML_START) continue; switch (HashStr(e.data, e.size)) { case WSMANTAG_PULL_MAX_ELEMENTS: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumpullbody->maxElements = (MI_Uint32)Strtoull(e.data, NULL, 10); PRINTF(("maxElements{%d}\n", wsenumpullbody->maxElements)); if (XML_Expect(xml, &e, XML_END, "n:MaxElements") != 0) return -1; } break; case WSMANTAG_PULL_ENUMERATION_CONTEXT: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumpullbody->enumerationContextID = (MI_Uint32)Strtoull(e.data, NULL, 10); if (XML_Expect(xml, &e, XML_END, "n:EnumerationContext") != 0) return -1; } break; default: { if (_MustUnderstandCanBeIgnored(&e) != 0) { LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data )); return -1; } if (XML_Skip(xml) != 0) return -1; } break; } } /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; } int WS_ParseReleaseBody( XML* xml, WSMAN_WSEnumeratePullBody* wsenumpullbody) { XML_Elem e; memset(wsenumpullbody, 0, sizeof(WSMAN_WSEnumeratePullBody)); /* Expect */ if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_START, "n:Release") != 0) return -1; for (;;) { if (XML_Next(xml, &e) != 0) return -1; if (e.type == XML_END) { int tag = HashStr(e.data, e.size); if (WSMANTAG_ENUM_RELEASE != tag) { LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data )); return -1; } break; } /* skip possible comments */ if (e.type != XML_START) continue; switch (HashStr(e.data, e.size)) { case WSMANTAG_PULL_ENUMERATION_CONTEXT: { if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0) return -1; wsenumpullbody->enumerationContextID = (MI_Uint32)Strtoull(e.data, NULL, 10); if (XML_Expect(xml, &e, XML_END, "n:EnumerationContext") != 0) return -1; } break; default: { if (_MustUnderstandCanBeIgnored(&e) != 0) { LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data )); return -1; } if (XML_Skip(xml) != 0) return -1; } break; } } /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; /* Expect */ if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; } int WS_ParseIdentifyBody( XML* xml) { XML_Elem e; if (XML_Expect(xml, &e, XML_START, "s:Body") != 0) return -1; if (XML_Expect(xml, &e, XML_START, "i:Identify") != 0) return -1; if (XML_Expect(xml, &e, XML_END, "i:Identify") != 0) return -1; if (XML_Expect(xml, &e, XML_END, "s:Body") != 0) return -1; if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0) return -1; return 0; }