Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

355 lines
8.6 KiB

  1. #include <pch.h>
  2. #pragma hdrstop
  3. #include <msxml2.h>
  4. #include <objbase.h>
  5. #include <stdio.h>
  6. #include <oleauto.h>
  7. #include "validate.h"
  8. #include "ncbase.h"
  9. // ISSUE-2000/10/29-spather: Add support for XML Parse Errors
  10. HRESULT
  11. HrLoadXMLFromFile(LPCWSTR pszFileName,
  12. IXMLDOMDocument ** ppxdd,
  13. IXMLDOMParseError ** ppxdpe)
  14. {
  15. HRESULT hr = S_OK;
  16. IXMLDOMDocument * pxdd = NULL;
  17. IXMLDOMParseError * pxdpe = NULL;
  18. hr = CoCreateInstance(CLSID_DOMDocument30,
  19. NULL,
  20. CLSCTX_INPROC_SERVER,
  21. IID_IXMLDOMDocument,
  22. (void **) &pxdd);
  23. if (SUCCEEDED(hr))
  24. {
  25. VARIANT varFileName;
  26. VARIANT_BOOL vbSuccess = VARIANT_FALSE;
  27. VariantInit(&varFileName);
  28. V_BSTR(&varFileName) = SysAllocString(pszFileName);
  29. if (V_BSTR(&varFileName))
  30. {
  31. varFileName.vt = VT_BSTR;
  32. hr = pxdd->load(varFileName, &vbSuccess);
  33. if (SUCCEEDED(hr))
  34. {
  35. if (VARIANT_FALSE == vbSuccess)
  36. {
  37. // There was an XML parse error.
  38. hr = pxdd->get_parseError(&pxdpe);
  39. if (SUCCEEDED(hr))
  40. {
  41. hr = S_FALSE; // Indicates parse error.
  42. }
  43. else
  44. {
  45. TraceError("HrLoadXMLFromFile(): "
  46. "Failed to get XML DOM parse error",
  47. hr);
  48. }
  49. }
  50. }
  51. else
  52. {
  53. TraceError("HrLoadXMLFromFile(): "
  54. "Failed to load XML",
  55. hr);
  56. }
  57. VariantClear(&varFileName);
  58. }
  59. else
  60. {
  61. hr = E_OUTOFMEMORY;
  62. TraceError("HrLoadXMLFromFile(): "
  63. "Failed to allocate BSTR for filename",
  64. hr);
  65. }
  66. }
  67. else
  68. {
  69. TraceError("HrLoadXMLFromFile(): "
  70. "Could not create DOM document",
  71. hr);
  72. }
  73. // If everything succeeded, copy the out parameters, otherwise clean up
  74. // what would have been put in the out parameters.
  75. if (SUCCEEDED(hr))
  76. {
  77. *ppxdd = pxdd;
  78. *ppxdpe = pxdpe;
  79. }
  80. else
  81. {
  82. if (pxdd)
  83. {
  84. pxdd->Release();
  85. pxdd = NULL;
  86. }
  87. if (pxdpe)
  88. {
  89. pxdpe->Release();
  90. pxdpe = NULL;
  91. }
  92. }
  93. TraceError("HrLoadXMLFromFile(): "
  94. "Exiting",
  95. hr);
  96. return hr;
  97. }
  98. HRESULT
  99. HrReportParseError(
  100. IN IXMLDOMParseError * pxdpe)
  101. {
  102. HRESULT hr = S_OK;
  103. LONG lErrorCode = 0;
  104. LONG lLineNum = 0;
  105. LONG lLinePos = 0;
  106. BSTR bstrReason = NULL;
  107. BSTR bstrSrcText = NULL;
  108. DWORD cchError = 0;
  109. LPWSTR szError = NULL;
  110. hr = pxdpe->get_errorCode(&lErrorCode);
  111. if (SUCCEEDED(hr))
  112. {
  113. hr = pxdpe->get_line(&lLineNum);
  114. if (SUCCEEDED(hr))
  115. {
  116. hr = pxdpe->get_linepos(&lLinePos);
  117. if (SUCCEEDED(hr))
  118. {
  119. hr = pxdpe->get_reason(&bstrReason);
  120. if (SUCCEEDED(hr))
  121. {
  122. hr = pxdpe->get_srcText(&bstrSrcText);
  123. if (FAILED(hr))
  124. {
  125. TraceError("HrReportParseError(): "
  126. "Failed to get source text",
  127. hr);
  128. }
  129. }
  130. else
  131. {
  132. TraceError("HrReportParseError(): "
  133. "Failed to get reason",
  134. hr);
  135. }
  136. }
  137. else
  138. {
  139. TraceError("HrReportParseError(): "
  140. "Failed to get line position",
  141. hr);
  142. }
  143. }
  144. else
  145. {
  146. TraceError("HrReportParseError(): "
  147. "Failed to get line number",
  148. hr);
  149. }
  150. }
  151. else
  152. {
  153. TraceError("HrReportParseError(): "
  154. "Failed to get error code",
  155. hr);
  156. }
  157. if (SUCCEEDED(hr))
  158. {
  159. // Final error string will look like this:
  160. // XML Error <errorCode>: line <lineNum>, col <linePos>: "<srcText>": <reason>
  161. // Allow 10 digits each for error code, line number and line position.
  162. cchError = lstrlenW(L"XML Error : line , col : \"\": ")+
  163. 10 + 10 + 10 +
  164. SysStringLen(bstrSrcText) +
  165. SysStringLen(bstrReason);
  166. szError = new WCHAR[cchError+1];
  167. if (szError)
  168. {
  169. wsprintfW(szError,
  170. L"XML Error %ld: line %ld, col %ld: \"%s\": %s",
  171. lErrorCode,
  172. lLineNum,
  173. lLinePos,
  174. bstrSrcText,
  175. bstrReason);
  176. fprintf(stderr,
  177. "%S",
  178. szError);
  179. }
  180. else
  181. {
  182. hr = E_OUTOFMEMORY;
  183. TraceError("HrReportParseError(): "
  184. "Failed to allocate error string",
  185. hr);
  186. }
  187. }
  188. // Cleanup.
  189. if (bstrReason)
  190. {
  191. SysFreeString(bstrReason);
  192. bstrReason = NULL;
  193. }
  194. if (bstrSrcText)
  195. {
  196. SysFreeString(bstrSrcText);
  197. bstrSrcText = NULL;
  198. }
  199. if (szError)
  200. {
  201. delete [] szError;
  202. szError = NULL;
  203. cchError = 0;
  204. }
  205. TraceError("HrReportParseError(): "
  206. "Exiting",
  207. hr);
  208. return hr;
  209. }
  210. EXTERN_C
  211. INT
  212. __cdecl
  213. wmain(
  214. int argc,
  215. PCWSTR argv[])
  216. {
  217. HRESULT hr = S_OK;
  218. int iRet = 0;
  219. if (argc != 2)
  220. {
  221. fprintf(stderr, "Usage: %S <filename>\n"
  222. "where <filename> specifies a file containing a service "
  223. "description",
  224. argv[0]);
  225. return -1;
  226. }
  227. hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  228. if (SUCCEEDED(hr))
  229. {
  230. IXMLDOMDocument * pxdd = NULL;
  231. IXMLDOMParseError * pxdpe = NULL;
  232. hr = HrLoadXMLFromFile(argv[1], &pxdd, &pxdpe);
  233. if (SUCCEEDED(hr))
  234. {
  235. if (S_FALSE == hr)
  236. {
  237. Assert(pxdpe);
  238. hr = HrReportParseError(pxdpe);
  239. pxdpe->Release();
  240. }
  241. else
  242. {
  243. IXMLDOMElement * pxdeRoot = NULL;
  244. hr = pxdd->get_documentElement(&pxdeRoot);
  245. if (SUCCEEDED(hr))
  246. {
  247. LPWSTR szError = NULL;
  248. hr = HrValidateServiceDescription(pxdeRoot, &szError);
  249. if (SUCCEEDED(hr))
  250. {
  251. printf("%S: Document is valid!\n",
  252. argv[0]);
  253. }
  254. else if (UPNP_E_INVALID_DOCUMENT == hr)
  255. {
  256. printf("%S: %S\n",
  257. argv[0], szError);
  258. delete [] szError;
  259. }
  260. else
  261. {
  262. fprintf(stderr,
  263. "%S: Service description validation FAILED\n",
  264. argv[0]);
  265. TraceError("wmain(): "
  266. "Failed to validate document",
  267. hr);
  268. }
  269. pxdeRoot->Release();
  270. }
  271. else
  272. {
  273. fprintf(stderr,
  274. "%S: An error occured while processing the XML\n",
  275. argv[0]);
  276. }
  277. }
  278. pxdd->Release();
  279. }
  280. else
  281. {
  282. fprintf(stderr,
  283. "%S: Unable to load file %S\n",
  284. argv[0], argv[1]);
  285. }
  286. CoUninitialize();
  287. }
  288. else
  289. {
  290. TraceError("wmain(): CoInitialized failed",
  291. hr);
  292. fprintf(stderr,
  293. "%S: Initialization failed\n",
  294. argv[0]);
  295. }
  296. if (FAILED(hr))
  297. iRet = -1;
  298. fprintf(stdout, "%S: Exiting, returning %d\n",
  299. argv[0], iRet);
  300. return iRet;
  301. }