Leaked source code of windows server 2003
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.

281 lines
7.9 KiB

  1. //*******************************
  2. // XML OM test code
  3. //
  4. // *******************************
  5. #include <windows.h>
  6. #include <windowsx.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <crtdbg.h>
  10. #include <io.h>
  11. #include <urlmon.h>
  12. #include <hlink.h>
  13. #include <dispex.h>
  14. #include <shlobj.h>
  15. #include "mshtml.h"
  16. #include "msxml.h"
  17. #include "Utility.h"
  18. #include "EnumIDL.h"
  19. #include "ParseXML.h"
  20. //
  21. // Dump an element attribute member if present.
  22. //
  23. void DumpAttrib(IXMLElement *pElem, BSTR bstrAttribName)
  24. {
  25. VARIANT vProp;
  26. VariantInit(&vProp);
  27. if (SUCCEEDED(pElem->getAttribute(bstrAttribName, &vProp)))
  28. {
  29. if (vProp.vt == VT_BSTR)
  30. {
  31. printf(" %S=\"%S\"", bstrAttribName, vProp.bstrVal);
  32. }
  33. VariantClear(&vProp);
  34. }
  35. }
  36. //
  37. // Helper routine to quickly find out if this is a named element
  38. // currently only used to improve the format of the output.
  39. //
  40. BOOL IsNamedElement(IXMLElement *pElem)
  41. {
  42. BSTR bstrName;
  43. if (SUCCEEDED(pElem->get_tagName(&bstrName)))
  44. {
  45. if (bstrName)
  46. {
  47. SysFreeString(bstrName);
  48. return TRUE;
  49. }
  50. }
  51. return FALSE;
  52. }
  53. void DumpElement
  54. (
  55. LPITEMIDLIST pidl,
  56. CPidlMgr *pCPidlMgr,
  57. CEnumIDList *pCEnumIDList,
  58. IXMLElement * pElem,
  59. XMLTAG tag
  60. )
  61. {
  62. BSTR bstrTagName = NULL;
  63. BSTR bstrContent = NULL;
  64. IXMLElementCollection * pChildren;
  65. BSTR bstrITEM = L"ITEM";
  66. BSTR bstrNAME = L"NAME";
  67. BSTR bstrTYPE = L"TYPE";
  68. BSTR bstrFOLDER = L"Folder";
  69. BSTR bstrICON = L"ICON";
  70. BSTR bstrBASE_URL = L"BASE-URL";
  71. //
  72. // Dump the NODE.
  73. //
  74. pElem->get_tagName(&bstrTagName);
  75. if (bstrTagName)
  76. {
  77. if (!_wcsicmp(bstrTagName, bstrITEM))
  78. {
  79. if (tag == T_ITEM)
  80. {
  81. // Skip internal ITEMs
  82. SysFreeString(bstrTagName);
  83. return;
  84. }
  85. else if (tag == T_ROOT)
  86. {
  87. // We are at the root
  88. // Drill down and look for ITEMs
  89. tag = T_NONE;
  90. }
  91. else
  92. {
  93. // Drill down
  94. tag = T_ITEM;
  95. // Create new PIDL
  96. pidl = pCPidlMgr->Create();
  97. if(pidl)
  98. pCEnumIDList->AddToEnumList(pidl);
  99. }
  100. }
  101. else if (!_wcsicmp(bstrTagName, bstrNAME))
  102. // Drill down
  103. tag = T_NAME;
  104. else if (!_wcsicmp(bstrTagName, bstrTYPE))
  105. // Drill down
  106. tag =T_TYPE;
  107. else if (!_wcsicmp(bstrTagName, bstrICON))
  108. // Drill down
  109. tag = T_ICON;
  110. else if (!_wcsicmp(bstrTagName, bstrBASE_URL))
  111. // Drill down
  112. tag = T_BASE_URL;
  113. else
  114. {
  115. // We are not interested
  116. SysFreeString(bstrTagName);
  117. return;
  118. }
  119. }
  120. else
  121. {
  122. // Build PIDL
  123. XMLELEM_TYPE xmlElemType;
  124. PIDLDATA pidldata;
  125. if (SUCCEEDED(pElem->get_type((long *)&xmlElemType)))
  126. {
  127. if (xmlElemType == XMLELEMTYPE_TEXT)
  128. {
  129. if (SUCCEEDED(pElem->get_text(&bstrContent)))
  130. {
  131. if (bstrContent)
  132. {
  133. if (tag == T_TYPE)
  134. {
  135. if ( !_wcsicmp(bstrContent, bstrFOLDER)) // Later check on SHCONTF_FOLDERS
  136. pidldata.fFolder = TRUE;
  137. else
  138. pidldata.fFolder = FALSE;
  139. pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, FOLDER);
  140. }
  141. else if (tag == T_NAME)
  142. {
  143. WideCharToLocal(pidldata.szName, bstrContent, MAX_NAME);
  144. pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, NAME);
  145. }
  146. else if (tag == T_ICON)
  147. {
  148. TCHAR szIcon[MAX_NAME];
  149. WideCharToLocal(szIcon, bstrContent, MAX_NAME);
  150. int index = AddIconImageList(g_himlLarge, szIcon);
  151. AddIconImageList(g_himlSmall, szIcon);
  152. pidldata.iIcon = index;
  153. pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, ICON);
  154. }
  155. else if (tag == T_BASE_URL)
  156. {
  157. WideCharToLocal(pidldata.szUrl, bstrContent, MAX_NAME);
  158. pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, URL);
  159. }
  160. }
  161. SysFreeString(bstrContent);
  162. }
  163. }
  164. }
  165. return; // no need to free bstrTagName
  166. }
  167. //
  168. // Find the children if they exist.
  169. //
  170. if (SUCCEEDED(pElem->get_children(&pChildren)) && pChildren)
  171. {
  172. WALK_ELEMENT_COLLECTION(pChildren, pDisp)
  173. {
  174. //
  175. // pDisp will iterate over an IDispatch for each item in the collection.
  176. //
  177. IXMLElement * pChild;
  178. if (SUCCEEDED(pDisp->QueryInterface(IID_IXMLElement, (void **)&pChild)))
  179. {
  180. DumpElement(pidl, pCPidlMgr, pCEnumIDList, pChild, tag );
  181. pChild->Release();
  182. }
  183. }
  184. END_WALK_ELEMENT_COLLECTION(pDisp);
  185. pChildren->Release();
  186. }
  187. if (bstrTagName)
  188. SysFreeString(bstrTagName);
  189. }
  190. int MyStrToOleStrN(LPOLESTR pwsz, int cchWideChar, LPCTSTR psz)
  191. {
  192. int i;
  193. i=MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cchWideChar);
  194. if (!i)
  195. {
  196. //DBG_WARN("MyStrToOleStrN string too long; truncated");
  197. pwsz[cchWideChar-1]=0;
  198. }
  199. else
  200. ZeroMemory(pwsz+i, sizeof(OLECHAR)*(cchWideChar-i));
  201. return i;
  202. }
  203. HRESULT GetSourceXML(IXMLDocument **ppDoc, TCHAR *pszURL)
  204. {
  205. PSTR pszErr = NULL;
  206. IStream *pStm = NULL;
  207. IPersistStreamInit *pPSI = NULL;
  208. IXMLElement *pElem = NULL;
  209. WCHAR *pwszURL=NULL;
  210. BSTR pBURL=NULL;
  211. HRESULT hr;
  212. int cszURL = 0;
  213. //
  214. // Create an empty XML document.
  215. //
  216. hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
  217. IID_IXMLDocument, (void**)ppDoc);
  218. CHECK_ERROR (*ppDoc, "CoCreateInstance Failed");
  219. pwszURL = (WCHAR *)LocalAlloc(LMEM_FIXED, ((sizeof(WCHAR))*(strlen(pszURL) + 2)));
  220. CHECK_ERROR(pwszURL, "Mem Alloc Failure");
  221. cszURL = MyStrToOleStrN(pwszURL, (strlen(pszURL) + 1), pszURL);
  222. CHECK_ERROR(cszURL, "Failed to convert to UNICODE");
  223. pBURL = SysAllocString(pwszURL);
  224. CHECK_ERROR(pBURL, "Mem Alloc Failure");
  225. LocalFree(pwszURL);
  226. hr = (*ppDoc)->put_URL(pBURL);
  227. if (! SUCCEEDED(hr))
  228. {
  229. //
  230. // Failed to parse stream, output error information.
  231. //
  232. IXMLError *pXMLError = NULL ;
  233. XML_ERROR xmle;
  234. hr = (*ppDoc)->QueryInterface(IID_IXMLError, (void **)&pXMLError);
  235. CHECK_ERROR(SUCCEEDED(hr), "Couldn't get IXMLError");
  236. // ASSERT(pXMLError);
  237. hr = pXMLError->GetErrorInfo(&xmle);
  238. SAFERELEASE(pXMLError);
  239. CHECK_ERROR(SUCCEEDED(hr), "GetErrorInfo Failed");
  240. SysFreeString(xmle._pszFound);
  241. SysFreeString(xmle._pszExpected);
  242. SysFreeString(xmle._pchBuf);
  243. }
  244. done: // Clean up.
  245. //
  246. // Release any used interfaces.
  247. //
  248. SAFERELEASE(pPSI);
  249. SAFERELEASE(pStm);
  250. // SAFERELEASE(*ppDoc); Do it in the caller!!!!!!!!!!!!!!!!!!
  251. SysFreeString(pBURL);
  252. return hr;
  253. }