windows-nt/Source/XPSP1/NT/net/upnp/tools/validatesd/validatesd.cpp
2020-09-26 16:20:57 +08:00

356 lines
8.6 KiB
C++

#include <pch.h>
#pragma hdrstop
#include <msxml2.h>
#include <objbase.h>
#include <stdio.h>
#include <oleauto.h>
#include "validate.h"
#include "ncbase.h"
// ISSUE-2000/10/29-spather: Add support for XML Parse Errors
HRESULT
HrLoadXMLFromFile(LPCWSTR pszFileName,
IXMLDOMDocument ** ppxdd,
IXMLDOMParseError ** ppxdpe)
{
HRESULT hr = S_OK;
IXMLDOMDocument * pxdd = NULL;
IXMLDOMParseError * pxdpe = NULL;
hr = CoCreateInstance(CLSID_DOMDocument30,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument,
(void **) &pxdd);
if (SUCCEEDED(hr))
{
VARIANT varFileName;
VARIANT_BOOL vbSuccess = VARIANT_FALSE;
VariantInit(&varFileName);
V_BSTR(&varFileName) = SysAllocString(pszFileName);
if (V_BSTR(&varFileName))
{
varFileName.vt = VT_BSTR;
hr = pxdd->load(varFileName, &vbSuccess);
if (SUCCEEDED(hr))
{
if (VARIANT_FALSE == vbSuccess)
{
// There was an XML parse error.
hr = pxdd->get_parseError(&pxdpe);
if (SUCCEEDED(hr))
{
hr = S_FALSE; // Indicates parse error.
}
else
{
TraceError("HrLoadXMLFromFile(): "
"Failed to get XML DOM parse error",
hr);
}
}
}
else
{
TraceError("HrLoadXMLFromFile(): "
"Failed to load XML",
hr);
}
VariantClear(&varFileName);
}
else
{
hr = E_OUTOFMEMORY;
TraceError("HrLoadXMLFromFile(): "
"Failed to allocate BSTR for filename",
hr);
}
}
else
{
TraceError("HrLoadXMLFromFile(): "
"Could not create DOM document",
hr);
}
// If everything succeeded, copy the out parameters, otherwise clean up
// what would have been put in the out parameters.
if (SUCCEEDED(hr))
{
*ppxdd = pxdd;
*ppxdpe = pxdpe;
}
else
{
if (pxdd)
{
pxdd->Release();
pxdd = NULL;
}
if (pxdpe)
{
pxdpe->Release();
pxdpe = NULL;
}
}
TraceError("HrLoadXMLFromFile(): "
"Exiting",
hr);
return hr;
}
HRESULT
HrReportParseError(
IN IXMLDOMParseError * pxdpe)
{
HRESULT hr = S_OK;
LONG lErrorCode = 0;
LONG lLineNum = 0;
LONG lLinePos = 0;
BSTR bstrReason = NULL;
BSTR bstrSrcText = NULL;
DWORD cchError = 0;
LPWSTR szError = NULL;
hr = pxdpe->get_errorCode(&lErrorCode);
if (SUCCEEDED(hr))
{
hr = pxdpe->get_line(&lLineNum);
if (SUCCEEDED(hr))
{
hr = pxdpe->get_linepos(&lLinePos);
if (SUCCEEDED(hr))
{
hr = pxdpe->get_reason(&bstrReason);
if (SUCCEEDED(hr))
{
hr = pxdpe->get_srcText(&bstrSrcText);
if (FAILED(hr))
{
TraceError("HrReportParseError(): "
"Failed to get source text",
hr);
}
}
else
{
TraceError("HrReportParseError(): "
"Failed to get reason",
hr);
}
}
else
{
TraceError("HrReportParseError(): "
"Failed to get line position",
hr);
}
}
else
{
TraceError("HrReportParseError(): "
"Failed to get line number",
hr);
}
}
else
{
TraceError("HrReportParseError(): "
"Failed to get error code",
hr);
}
if (SUCCEEDED(hr))
{
// Final error string will look like this:
// XML Error <errorCode>: line <lineNum>, col <linePos>: "<srcText>": <reason>
// Allow 10 digits each for error code, line number and line position.
cchError = lstrlenW(L"XML Error : line , col : \"\": ")+
10 + 10 + 10 +
SysStringLen(bstrSrcText) +
SysStringLen(bstrReason);
szError = new WCHAR[cchError+1];
if (szError)
{
wsprintfW(szError,
L"XML Error %ld: line %ld, col %ld: \"%s\": %s",
lErrorCode,
lLineNum,
lLinePos,
bstrSrcText,
bstrReason);
fprintf(stderr,
"%S",
szError);
}
else
{
hr = E_OUTOFMEMORY;
TraceError("HrReportParseError(): "
"Failed to allocate error string",
hr);
}
}
// Cleanup.
if (bstrReason)
{
SysFreeString(bstrReason);
bstrReason = NULL;
}
if (bstrSrcText)
{
SysFreeString(bstrSrcText);
bstrSrcText = NULL;
}
if (szError)
{
delete [] szError;
szError = NULL;
cchError = 0;
}
TraceError("HrReportParseError(): "
"Exiting",
hr);
return hr;
}
EXTERN_C
INT
__cdecl
wmain(
int argc,
PCWSTR argv[])
{
HRESULT hr = S_OK;
int iRet = 0;
if (argc != 2)
{
fprintf(stderr, "Usage: %S <filename>\n"
"where <filename> specifies a file containing a service "
"description",
argv[0]);
return -1;
}
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
IXMLDOMDocument * pxdd = NULL;
IXMLDOMParseError * pxdpe = NULL;
hr = HrLoadXMLFromFile(argv[1], &pxdd, &pxdpe);
if (SUCCEEDED(hr))
{
if (S_FALSE == hr)
{
Assert(pxdpe);
hr = HrReportParseError(pxdpe);
pxdpe->Release();
}
else
{
IXMLDOMElement * pxdeRoot = NULL;
hr = pxdd->get_documentElement(&pxdeRoot);
if (SUCCEEDED(hr))
{
LPWSTR szError = NULL;
hr = HrValidateServiceDescription(pxdeRoot, &szError);
if (SUCCEEDED(hr))
{
printf("%S: Document is valid!\n",
argv[0]);
}
else if (UPNP_E_INVALID_DOCUMENT == hr)
{
printf("%S: %S\n",
argv[0], szError);
delete [] szError;
}
else
{
fprintf(stderr,
"%S: Service description validation FAILED\n",
argv[0]);
TraceError("wmain(): "
"Failed to validate document",
hr);
}
pxdeRoot->Release();
}
else
{
fprintf(stderr,
"%S: An error occured while processing the XML\n",
argv[0]);
}
}
pxdd->Release();
}
else
{
fprintf(stderr,
"%S: Unable to load file %S\n",
argv[0], argv[1]);
}
CoUninitialize();
}
else
{
TraceError("wmain(): CoInitialized failed",
hr);
fprintf(stderr,
"%S: Initialization failed\n",
argv[0]);
}
if (FAILED(hr))
iRet = -1;
fprintf(stdout, "%S: Exiting, returning %d\n",
argv[0], iRet);
return iRet;
}