356 lines
8.6 KiB
C++
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;
|
||
|
}
|