in Unix/wsman/wsmanparser.c [3073:3318]
int WS_ParseFaultBody(
XML* xml,
WSMAN_WSFault *fault)
{
XML_Elem e;
fault->code[0] = '\0';
fault->subcode[0] = '\0';
fault->reason = NULL;
fault->detail = NULL;
fault->mi_result = 0;
fault->mi_message = NULL;
/* Expect <s:Body> */
if (XML_Expect(xml, &e, XML_START, PAL_T('s'), PAL_T("Body")) != 0)
RETURN(-1);
/* Expect <s:Body> */
if (XML_Expect(xml, &e, XML_START, PAL_T('s'), PAL_T("Fault")) != 0)
RETURN(-1);
for (;;)
{
if (GetNextSkipCharsAndComments(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_END && (Tcscmp(e.data.data, ZT("Fault")) == 0))
break;
if (e.type != XML_START)
continue;
if (ZT('s') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("Code")) == 0))
{
for (;;)
{
if (GetNextSkipCharsAndComments(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_END && (Tcscmp(e.data.data, ZT("Code")) == 0))
break;
if (e.type != XML_START)
continue;
if (ZT('s') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("Value")) == 0))
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_ParseCharFault(xml, e.data.data, fault->code, sizeof(fault->code)/sizeof(MI_Char)) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Value")) != 0)
RETURN(-1);
}
else if (ZT('s') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("Subcode")) == 0))
{
if (XML_Expect(xml, &e, XML_START, PAL_T('s'), PAL_T("Value")) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_ParseCharFault(xml, e.data.data, fault->subcode, sizeof(fault->subcode)/sizeof(MI_Char)) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Value")) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Subcode")) != 0)
RETURN(-1);
}
}
}
else if (ZT('s') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("Reason")) == 0))
{
if (XML_Expect(xml, &e, XML_START, PAL_T('s'), PAL_T("Text")) != 0)
RETURN(-1);
if (XML_Next(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_CHARS)
{
fault->reason = e.data.data;
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Text")) != 0)
RETURN(-1);
}
else if (e.type != XML_END || (Tcscmp(e.data.data, ZT("Text")) != 0))
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Reason")) != 0)
RETURN(-1);
}
else if (ZT('s') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("Detail")) == 0))
{
for (;;)
{
if (XML_Next(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_END && (Tcscmp(e.data.data, ZT("Detail")) == 0))
break;
if (e.type != XML_START)
continue;
if (ZT('w') == e.data.namespaceId && (Tcscmp(e.data.data, ZT("FaultDetail")) == 0))
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
fault->detail = e.data.data;
if (XML_Expect(xml, &e, XML_END, PAL_T('w'), PAL_T("FaultDetail")) != 0)
RETURN(-1);
}
else if (Tcscmp(e.data.data, ZT("OMI_Error")) == 0)
{
const XML_Char* value = XML_Elem_GetAttr(&e, PAL_T('b'), ZT("IsCIM_Error"));
if (value != NULL && Tcscmp(value, ZT("true")) == 0)
{
// CIM Error
for (;;)
{
if (XML_Next(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_END && (Tcscmp(e.data.data, ZT("OMI_Error")) == 0))
break;
if (e.type != XML_START)
continue;
if (Tcscmp(e.data.data, ZT("MessageID")) == 0)
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (Tcsncmp(e.data.data, ZT("OMI:MI_Result:"), 14) == 0)
{
fault->mi_result = Tcstol(&e.data.data[14], NULL, 10);
}
if (XML_Expect(xml, &e, XML_END, 0, PAL_T("MessageID")) != 0)
RETURN(-1);
}
else if (Tcscmp(e.data.data, ZT("Message")) == 0)
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
fault->mi_message = e.data.data;
if (XML_Expect(xml, &e, XML_END, 0, PAL_T("Message")) != 0)
RETURN(-1);
}
}
}
}
else if (Tcscmp(e.data.data, ZT("WSManFault")) == 0)
{
/* fault->mi_result should be MI_RESULT_FAILED for WSManFault */
fault->mi_result = MI_RESULT_FAILED;
if (XML_Expect(xml, &e, XML_START, 0, PAL_T("Message")) != 0)
RETURN(-1);
/* ProviderFault from Windows response:
WSMANTAG_ACTION_FAULT_ADDRESSING case:
<f:WSManFault>
<f:Message>
<f:ProviderFault>
<f:WSManFault>
<f:Message>...</f:Message>
</f:WSManFault>
<f:ExtendedError>...</f:ExtendedError>
</f:ProviderFault>
</f:Message>
</f:WSManFault>
Normal ProviderFault respones:
ERROR_INTERNAL_ERROR case:
<f:WSManFault>
<f:Message>
<f:ProviderFault>...</f:ProviderFault>
</f:Message>
</f:WSManFault>
ERROR_WSMAN_OPERATION_TIMEDOUT case:
<f:WSManFault>
<f:Message>...</f:Message>
</f:WSManFault>
*/
MI_Result providerFault = MI_FALSE;
MI_Result isSetDetail = MI_FALSE;
for (;;)
{
if (XML_Next(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_CHARS)
{
if(isSetDetail == MI_FALSE)
{
/*we will not set detail again once it is setted.*/
fault->detail = e.data.data;
isSetDetail = MI_TRUE;
}
if(providerFault == MI_FALSE)
{
/*providerFault doesn't exist and the current element is a message string.*/
break;
}
}
else if (e.type == XML_START && Tcscmp(e.data.data, ZT("ProviderFault")) == 0)
{
providerFault = MI_TRUE;
}
else if (e.type == XML_END && Tcscmp(e.data.data, ZT("ProviderFault")) == 0)
{
break;
}
}
if (XML_Expect(xml, &e, XML_END, 0, PAL_T("Message")) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, 0, PAL_T("WSManFault")) != 0)
RETURN(-1);
}
}
}
}
/* Expect <s:Body> */
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Body")) != 0)
RETURN(-1);
/* Expect </s:Envelope> */
if (XML_Expect(xml, &e, XML_END, PAL_T('s'), PAL_T("Envelope")) != 0)
RETURN(-1);
return 0;
}