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.

470 lines
12 KiB

  1. #if !defined(_FUSION_INC_DOMHELPER_H_INCLUDED_)
  2. #define _FUSION_INC_DOMHELPER_H_INCLUDED_
  3. #pragma once
  4. #include "smartref.h"
  5. #include "oleaut_d.h"
  6. #include "fusionparser.h"
  7. //
  8. // Be sure that you have a symbol named _Module in scope when you #include this header file
  9. // that has member functions for the OLEAUT32 functions:
  10. //
  11. // SysAllocString
  12. // SysFreeString
  13. // VariantClear
  14. // VariantInit
  15. // VariantCopy
  16. //
  17. class CDOMHelper
  18. {
  19. public:
  20. static HRESULT FindChild(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, DOMNodeType ntToMatch, LPCWSTR sz, bool fRecurse = false)
  21. {
  22. HRESULT hr = NOERROR;
  23. CSmartRef<IXMLDOMNode> srpIXMLDOMNode;
  24. if (ppIXMLDOMNode_Out != NULL)
  25. *ppIXMLDOMNode_Out = NULL;
  26. if ((ppIXMLDOMNode_Out == NULL) ||
  27. (pIXMLDOMNode_Root == NULL))
  28. {
  29. hr = E_POINTER;
  30. goto Exit;
  31. }
  32. hr = pIXMLDOMNode_Root->get_firstChild(&srpIXMLDOMNode);
  33. if (FAILED(hr))
  34. goto Exit;
  35. hr = CDOMHelper::FindSibling(ppIXMLDOMNode_Out, srpIXMLDOMNode, ntToMatch, sz, false, fRecurse);
  36. if (FAILED(hr))
  37. goto Exit;
  38. hr = ((*ppIXMLDOMNode_Out) != NULL) ? NOERROR : S_FALSE;
  39. Exit:
  40. return hr;
  41. }
  42. static HRESULT FindSibling(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, DOMNodeType ntToMatch, LPCWSTR sz, bool fSkipCurrent, bool fRecurse = false)
  43. {
  44. BSTR bstrName = NULL;
  45. DOMNodeType nt;
  46. HRESULT hr = NOERROR;
  47. CSmartRef<IXMLDOMNode> srpIXMLDOMNode, srpIXMLDOMNode_Next;
  48. if (ppIXMLDOMNode_Out != NULL)
  49. *ppIXMLDOMNode_Out = NULL;
  50. if ((ppIXMLDOMNode_Out == NULL) ||
  51. (pIXMLDOMNode_Root == NULL))
  52. {
  53. hr = E_POINTER;
  54. goto Exit;
  55. }
  56. if (fSkipCurrent)
  57. {
  58. hr = pIXMLDOMNode_Root->get_nextSibling(&srpIXMLDOMNode);
  59. if (FAILED(hr))
  60. goto Exit;
  61. }
  62. else
  63. srpIXMLDOMNode = pIXMLDOMNode_Root;
  64. while (srpIXMLDOMNode != NULL)
  65. {
  66. hr = srpIXMLDOMNode->get_nodeType(&nt);
  67. if (FAILED(hr))
  68. goto Exit;
  69. if (nt == ntToMatch)
  70. {
  71. hr = srpIXMLDOMNode->get_nodeName(&bstrName);
  72. if (FAILED(hr))
  73. goto Exit;
  74. if (StrCmpIW(bstrName, sz) == 0)
  75. {
  76. *ppIXMLDOMNode_Out = srpIXMLDOMNode.Disown();
  77. break;
  78. }
  79. _Module.SysFreeString(bstrName);
  80. bstrName = NULL;
  81. if (fRecurse)
  82. {
  83. hr = CDOMHelper::FindChild(ppIXMLDOMNode_Out, srpIXMLDOMNode, ntToMatch, sz, fRecurse);
  84. if (FAILED(hr))
  85. goto Exit;
  86. if ((*ppIXMLDOMNode_Out) != NULL)
  87. break;
  88. }
  89. }
  90. hr = srpIXMLDOMNode->get_nextSibling(&srpIXMLDOMNode_Next);
  91. if (FAILED(hr))
  92. goto Exit;
  93. if (hr == S_FALSE)
  94. break;
  95. srpIXMLDOMNode.Take(srpIXMLDOMNode_Next);
  96. }
  97. hr = ((*ppIXMLDOMNode_Out) != NULL) ? NOERROR : S_FALSE;
  98. Exit:
  99. if (bstrName != NULL)
  100. _Module.SysFreeString(bstrName);
  101. return hr;
  102. }
  103. static HRESULT CopyTextNodeValue(IXMLDOMNode *pIXMLDOMNode, LPWSTR sz, ULONG *pcch)
  104. {
  105. HRESULT hr = NOERROR;
  106. VARIANT varTemp;
  107. ULONG cch;
  108. varTemp.vt = VT_EMPTY;
  109. if (pcch == NULL)
  110. {
  111. hr = E_POINTER;
  112. goto Exit;
  113. }
  114. hr = pIXMLDOMNode->get_nodeValue(&varTemp);
  115. if (FAILED(hr))
  116. goto Exit;
  117. if (varTemp.vt != VT_BSTR)
  118. {
  119. hr = E_FAIL;
  120. goto Exit;
  121. }
  122. cch = ::wcslen(varTemp.bstrVal) + 1;
  123. if ((*pcch) < cch)
  124. {
  125. *pcch = cch;
  126. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  127. goto Exit;
  128. }
  129. memcpy(sz, varTemp.bstrVal, cch * sizeof(WCHAR));
  130. hr = NOERROR;
  131. Exit:
  132. _Module.VariantClear(&varTemp);
  133. return hr;
  134. }
  135. enum Relationship
  136. {
  137. eSibling,
  138. eChild,
  139. };
  140. static HRESULT FollowPath(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, ...)
  141. {
  142. HRESULT hr = NOERROR;
  143. va_list ap;
  144. bool fApInitialized = false;
  145. if (ppIXMLDOMNode_Out != NULL)
  146. *ppIXMLDOMNode_Out = NULL;
  147. if ((ppIXMLDOMNode_Out == NULL) ||
  148. (pIXMLDOMNode_Root == NULL))
  149. {
  150. hr = E_POINTER;
  151. goto Exit;
  152. }
  153. va_start(ap, sz);
  154. fApInitialized = true;
  155. hr = CDOMHelper::FollowPathVa(ppIXMLDOMNode_Out, pIXMLDOMNode_Root, nPathLength, r, nt, sz, ap);
  156. if (FAILED(hr))
  157. goto Exit;
  158. hr = NOERROR;
  159. Exit:
  160. if (fApInitialized)
  161. va_end(ap);
  162. return hr;
  163. }
  164. static HRESULT FollowPathVa(IXMLDOMNode **ppIXMLDOMNode_Out, IXMLDOMNode *pIXMLDOMNode_Root, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, va_list ap)
  165. {
  166. HRESULT hr = NOERROR;
  167. CSmartRef<IXMLDOMNode> srpIXMLDOMNode, srpIXMLDOMNode_Next;
  168. ULONG i;
  169. if (ppIXMLDOMNode_Out != NULL)
  170. *ppIXMLDOMNode_Out = NULL;
  171. if ((ppIXMLDOMNode_Out == NULL) ||
  172. (pIXMLDOMNode_Root == NULL))
  173. {
  174. hr = E_POINTER;
  175. goto Exit;
  176. }
  177. srpIXMLDOMNode = pIXMLDOMNode_Root;
  178. for (i=0; i<nPathLength; i++)
  179. {
  180. if (r == eChild)
  181. hr = CDOMHelper::FindChild(&srpIXMLDOMNode_Next, srpIXMLDOMNode, nt, sz);
  182. else if (r == eSibling)
  183. hr = CDOMHelper::FindSibling(&srpIXMLDOMNode_Next, srpIXMLDOMNode, nt, sz, false);
  184. else
  185. {
  186. hr = E_INVALIDARG;
  187. goto Exit;
  188. }
  189. if (FAILED(hr))
  190. goto Exit;
  191. srpIXMLDOMNode.Take(srpIXMLDOMNode_Next);
  192. if (hr == S_FALSE)
  193. break;
  194. r = va_arg(ap, Relationship);
  195. nt = va_arg(ap, DOMNodeType);
  196. sz = va_arg(ap, LPCWSTR);
  197. }
  198. *ppIXMLDOMNode_Out = srpIXMLDOMNode.Disown();
  199. hr = ((*ppIXMLDOMNode_Out) == NULL) ? S_FALSE : NOERROR;
  200. Exit:
  201. return hr;
  202. }
  203. static HRESULT GetAttributeValue(CBaseStringBuffer &rbuffOut, IXMLDOMNode *pIXMLDOMNode, LPCWSTR szAttributeName)
  204. {
  205. HRESULT hr = NOERROR;
  206. CSmartRef<IXMLDOMElement> srpIXMLDOMElement;
  207. BSTR bstrName = NULL;
  208. VARIANT varValue;
  209. varValue.vt = VT_EMPTY;
  210. if (pIXMLDOMNode == NULL)
  211. {
  212. hr = E_POINTER;
  213. goto Exit;
  214. }
  215. hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode);
  216. if (FAILED(hr))
  217. goto Exit;
  218. bstrName = _Module.SysAllocString(szAttributeName);
  219. if (bstrName == NULL)
  220. {
  221. hr = E_OUTOFMEMORY;
  222. goto Exit;
  223. }
  224. hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue);
  225. if (FAILED(hr))
  226. goto Exit;
  227. // If the attribute did not exist, return S_FALSE and ensure that the output
  228. // buffer is a blank string.
  229. if (hr == S_FALSE)
  230. {
  231. rbuffOut.GetBufferPtr()[0] = L'\0';
  232. goto Exit;
  233. }
  234. if (varValue.vt != VT_BSTR)
  235. {
  236. hr = E_FAIL;
  237. goto Exit;
  238. }
  239. hr = rbuffOut.Assign(varValue.bstrVal);
  240. if (FAILED(hr))
  241. goto Exit;
  242. hr = NOERROR;
  243. Exit:
  244. if (bstrName != NULL)
  245. _Module.SysFreeString(bstrName);
  246. _Module.VariantClear(&varValue);
  247. return hr;
  248. }
  249. static HRESULT GetAttributeValue(LPWSTR szOut, ULONG *pcch, IXMLDOMNode *pIXMLDOMNode, LPCWSTR szAttributeName)
  250. {
  251. HRESULT hr = NOERROR;
  252. CSmartRef<IXMLDOMElement> srpIXMLDOMElement;
  253. BSTR bstrName = NULL;
  254. VARIANT varValue;
  255. ULONG cch;
  256. varValue.vt = VT_EMPTY;
  257. if (pIXMLDOMNode == NULL)
  258. {
  259. hr = E_POINTER;
  260. goto Exit;
  261. }
  262. hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode);
  263. if (FAILED(hr))
  264. goto Exit;
  265. bstrName = _Module.SysAllocString(szAttributeName);
  266. if (bstrName == NULL)
  267. {
  268. hr = E_OUTOFMEMORY;
  269. goto Exit;
  270. }
  271. hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue);
  272. if (FAILED(hr))
  273. goto Exit;
  274. if (varValue.vt != VT_BSTR)
  275. {
  276. hr = E_FAIL;
  277. goto Exit;
  278. }
  279. cch = ::wcslen(varValue.bstrVal) + 1;
  280. if ((*pcch) < cch)
  281. {
  282. *pcch = cch;
  283. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  284. goto Exit;
  285. }
  286. memcpy(szOut, varValue.bstrVal, cch * sizeof(WCHAR));
  287. hr = NOERROR;
  288. Exit:
  289. if (bstrName != NULL)
  290. _Module.SysFreeString(bstrName);
  291. _Module.VariantClear(&varValue);
  292. return hr;
  293. }
  294. static HRESULT GetBooleanAttributeValue(BOOLEAN *pfValue, IXMLDOMNode *pIXMLDOMNode, LPCWSTR szAttributeName, BOOLEAN fDefaultValue)
  295. {
  296. HRESULT hr = NOERROR;
  297. CSmartRef<IXMLDOMElement> srpIXMLDOMElement;
  298. BSTR bstrName = NULL;
  299. VARIANT varValue;
  300. varValue.vt = VT_EMPTY;
  301. if ((pIXMLDOMNode == NULL) || (pfValue == NULL))
  302. {
  303. hr = E_POINTER;
  304. goto Exit;
  305. }
  306. hr = srpIXMLDOMElement.QueryInterfaceFrom(pIXMLDOMNode);
  307. if (FAILED(hr))
  308. goto Exit;
  309. bstrName = _Module.SysAllocString(szAttributeName);
  310. if (bstrName == NULL)
  311. {
  312. hr = E_OUTOFMEMORY;
  313. goto Exit;
  314. }
  315. hr = srpIXMLDOMElement->getAttribute(bstrName, &varValue);
  316. if (FAILED(hr))
  317. goto Exit;
  318. if (hr == S_FALSE)
  319. {
  320. *pfValue = fDefaultValue;
  321. goto Exit;
  322. }
  323. if (varValue.vt != VT_BSTR)
  324. {
  325. hr = E_FAIL;
  326. goto Exit;
  327. }
  328. hr = CFusionParser::ParseBoolean(*pfValue, varValue.bstrVal, ::wcslen(varValue.bstrVal));
  329. if (FAILED(hr))
  330. goto Exit;
  331. hr = NOERROR;
  332. Exit:
  333. if (bstrName != NULL)
  334. _Module.SysFreeString(bstrName);
  335. _Module.VariantClear(&varValue);
  336. return hr;
  337. }
  338. static HRESULT GetAttributeValue(CBaseStringBuffer &rbuffOut, IXMLDOMNode *pIXMLDOMNode_Root, LPCWSTR szAttributeName, ULONG nPathLength, Relationship r, DOMNodeType nt, LPCWSTR sz, ...)
  339. {
  340. HRESULT hr = NOERROR;
  341. va_list ap;
  342. bool fApInitialized = false;
  343. CSmartRef<IXMLDOMNode> srpIXMLDOMNode;
  344. if (pIXMLDOMNode_Root == NULL)
  345. {
  346. hr = E_POINTER;
  347. goto Exit;
  348. }
  349. va_start(ap, sz);
  350. fApInitialized = true;
  351. hr = CDOMHelper::FollowPathVa(&srpIXMLDOMNode, pIXMLDOMNode_Root, nPathLength, r, nt, sz, ap);
  352. if (FAILED(hr))
  353. goto Exit;
  354. hr = CDOMHelper::GetAttributeValue(rbuffOut, srpIXMLDOMNode, szAttributeName);
  355. if (FAILED(hr))
  356. goto Exit;
  357. hr = NOERROR;
  358. Exit:
  359. if (fApInitialized)
  360. va_end(ap);
  361. return hr;
  362. }
  363. };
  364. #endif