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.

380 lines
10 KiB

  1. #include "pch.h"
  2. #include "comptree.h"
  3. #include "tagtab.h"
  4. ////////////////////////////////////////////////////////////////////////////////
  5. HRESULT TraverseXMLDoc( const CComPtr<IXMLElement>& spxmlElt ,
  6. TagInformation* pTagTable ,
  7. const CTagHandler* pthParent ,
  8. CTagData& tdRoot );
  9. ////////////////////////////////////////////////////////////////////////////////
  10. // ((!pszTagName) || pszTagName == spxmlElt.parent.tagName) ? S_OK : S_FALSE
  11. HRESULT TagNameMatchesParent( LPCWSTR pszTagName ,
  12. const CComPtr<IXMLElement>& spxmlElt )
  13. {
  14. HRESULT hr = S_OK;
  15. if(pszTagName != NULL)
  16. {
  17. CComPtr<IXMLElement> spParent;
  18. hr = spxmlElt->get_parent( &spParent ); // S_FALSE if no parent
  19. ASSERT((hr != S_FALSE) || (!spParent));
  20. if(hr == S_OK)
  21. {
  22. CComBSTR bstrParentName;
  23. if(SUCCEEDED(hr = spParent->get_tagName( &bstrParentName )))
  24. {
  25. hr = (_wcsicmp( bstrParentName, pszTagName )) ? S_FALSE : S_OK;
  26. }
  27. }
  28. }
  29. return hr;
  30. }
  31. // looks up the tagName in pTagTable and calls the appropriate
  32. // CreateInstance function to create pTagHndlr
  33. HRESULT VisitElement( const CComPtr<IXMLElement>& spxmlElt ,
  34. TagInformation * pTagTable ,
  35. CTagHandler*& pTagHandler )
  36. {
  37. HRESULT hr;
  38. CComBSTR bstrTagName;
  39. pTagHandler = NULL;
  40. if(SUCCEEDED(hr = spxmlElt->get_tagName( &bstrTagName )))
  41. {
  42. TagInformation* ptiElt;
  43. for(ptiElt = pTagTable; ptiElt->pszTagName; ++ptiElt)
  44. {
  45. if(!_wcsicmp( ptiElt->pszTagName, bstrTagName ))
  46. {
  47. if(SUCCEEDED(hr = TagNameMatchesParent( ptiElt->pszParent, spxmlElt )))
  48. {
  49. if(hr == S_OK)
  50. {
  51. // call the CreateInstance function for the tag
  52. pTagHandler = ptiElt->pfnTag();
  53. break;
  54. }
  55. else
  56. {
  57. // these are not the droids you're looking for
  58. }
  59. }
  60. else
  61. {
  62. break;
  63. }
  64. }
  65. }
  66. }
  67. else if(hr == E_NOTIMPL) // this is a node without tag information (comment)
  68. {
  69. hr = S_FALSE;
  70. }
  71. return hr;
  72. }
  73. HRESULT GetChild( const CComVariant& varChild ,
  74. const CComPtr<IXMLElementCollection>& spcol ,
  75. CComPtr<IXMLElement>& spEltOut )
  76. {
  77. HRESULT hr;
  78. CComPtr<IDispatch> spDisp;
  79. CComVariant varEmpty;
  80. hr = spcol->item( varChild, varEmpty, &spDisp );
  81. if(hr == S_OK)
  82. {
  83. hr = spDisp.QueryInterface( &spEltOut );
  84. }
  85. return hr;
  86. }
  87. // return (spcol.item(lChildID));
  88. // gets an IXMLElement from an IXMLElementCollection
  89. HRESULT GetChild( LONG lChildID ,
  90. const CComPtr<IXMLElementCollection>& spcol ,
  91. CComPtr<IXMLElement>& spEltOut )
  92. {
  93. CComVariant varItem( lChildID );
  94. return GetChild( varItem, spcol, spEltOut );
  95. }
  96. // for (obj in spxmlElt.children)
  97. // {
  98. // phs = TraverseXMLDoc(obj);
  99. // pthVisitor->AddChild(obj, phs);
  100. // }
  101. HRESULT VisitChildren( const CComPtr<IXMLElement>& spxmlElt ,
  102. TagInformation* pTagTable ,
  103. const CTagHandler* pthParent ,
  104. CTagHandler* pthVisitor )
  105. {
  106. HRESULT hr;
  107. CComPtr<IXMLElementCollection> spcolChildren;
  108. if(SUCCEEDED(hr = spxmlElt->get_children( &spcolChildren )) && spcolChildren)
  109. {
  110. long lChildren;
  111. if(SUCCEEDED(hr = spcolChildren->get_length( &lChildren )))
  112. {
  113. for(long l = 0; l < lChildren; ++l)
  114. {
  115. CComPtr<IXMLElement> spxmlChild;
  116. if(SUCCEEDED(hr = GetChild( l, spcolChildren, spxmlChild )))
  117. {
  118. CTagData td;
  119. hr = TraverseXMLDoc( spxmlChild, pTagTable, pthVisitor, td );
  120. if(hr == S_OK)
  121. {
  122. hr = pthVisitor->AddChild( spxmlChild, td );
  123. }
  124. }
  125. if(FAILED(hr)) break;
  126. }
  127. // convert return value from TraverseXMLDoc
  128. if(hr == S_FALSE) hr = S_OK;
  129. }
  130. }
  131. return hr;
  132. }
  133. // return S_FALSE when no element found
  134. HRESULT TraverseXMLDoc( const CComPtr<IXMLElement>& spxmlElt ,
  135. TagInformation* pTagTable ,
  136. const CTagHandler* pthParent , //TODO: Get rid of this parameter
  137. CTagData& tdRoot )
  138. {
  139. HRESULT hr;
  140. CTagHandler *pTagHandler;
  141. if(SUCCEEDED(hr = VisitElement( spxmlElt, pTagTable, pTagHandler )))
  142. {
  143. // skip children we have no TagHandler for
  144. if(pTagHandler)
  145. {
  146. if(SUCCEEDED(hr = pTagHandler->BeginChildren( spxmlElt )))
  147. {
  148. if(SUCCEEDED(hr = VisitChildren( spxmlElt, pTagTable, pthParent, pTagHandler )))
  149. {
  150. hr = pTagHandler->EndChildren( tdRoot );
  151. if(SUCCEEDED(hr)) hr = S_OK;
  152. }
  153. }
  154. }
  155. else
  156. {
  157. hr = S_FALSE;
  158. }
  159. }
  160. return hr;
  161. }
  162. ////////////////////////////////////////////////////////////////////////////////
  163. unsigned int WriteBlobToFileHandle( LPCWSTR pszFileName, int fh, const void *pvBlob, DWORD dwSize )
  164. {
  165. unsigned int bytesWritten;
  166. if ((bytesWritten = _write(fh, pvBlob, dwSize)) != -1)
  167. {
  168. if (bytesWritten == dwSize)
  169. {
  170. // S_OK!!!
  171. }
  172. else
  173. {
  174. wprintf(L"%s File %s wasn't totally written: "
  175. L"Are you out of disk space?\n", g_szErrorPrefix,
  176. pszFileName);
  177. bytesWritten = (unsigned int)-1;
  178. }
  179. }
  180. else
  181. {
  182. ERRMSG(L"%s Cannot write to %s\n", g_szErrorPrefix, pszFileName);
  183. bytesWritten = (unsigned int)-1;
  184. }
  185. return bytesWritten;
  186. }
  187. HRESULT WriteBlobToFile( LPCWSTR pszFileName, const char *pszCookie, void *pvBlob, DWORD dwSize, unsigned int &cbWritten )
  188. {
  189. HRESULT hr = E_FAIL;
  190. cbWritten = 0;
  191. int fh;
  192. unsigned int _cbWritten = 0;
  193. USES_CONVERSION;
  194. if ( (fh = _open(W2A(pszFileName), _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY,
  195. _S_IREAD | _S_IWRITE)) > 0)
  196. {
  197. if (pszCookie)
  198. {
  199. hr = ((_cbWritten =
  200. WriteBlobToFileHandle(pszFileName, fh, pszCookie,
  201. lstrlenA(pszCookie) + 1)) == -1)
  202. ? E_FAIL : S_OK;
  203. }
  204. unsigned int _cbWritten2;
  205. if (SUCCEEDED(hr))
  206. {
  207. hr = ((_cbWritten2 =
  208. WriteBlobToFileHandle(pszFileName, fh, pvBlob, dwSize)) == -1)
  209. ? E_FAIL : S_OK;
  210. cbWritten = _cbWritten + _cbWritten2;
  211. }
  212. }
  213. return hr;
  214. }
  215. HRESULT DoTraverse( const CComPtr<IXMLDocument>& spxmlDoc ,
  216. TagInformation* pTagTable ,
  217. LPCWSTR pszOutputFileName )
  218. {
  219. HRESULT hr;
  220. CComPtr<IXMLElement> spxmlRoot;
  221. if(SUCCEEDED(hr = spxmlDoc->get_root( &spxmlRoot )))
  222. {
  223. CTagData tdRoot;
  224. hr = TraverseXMLDoc( spxmlRoot, pTagTable, NULL, tdRoot );
  225. ASSERT(tdRoot.pData && "No Root Data!!!");
  226. if(SUCCEEDED(hr))
  227. {
  228. if(hr == S_OK)
  229. {
  230. unsigned int cbWritten;
  231. hr = WriteBlobToFile( pszOutputFileName, g_szMMFCookie, tdRoot.pData, tdRoot.dwSize, cbWritten );
  232. if(SUCCEEDED(hr))
  233. {
  234. STATUSMSG( L"Wrote %d bytes to %s.\n", cbWritten, pszOutputFileName );
  235. }
  236. }
  237. }
  238. }
  239. return hr;
  240. }
  241. HRESULT GetXMLDoc( const CComBSTR& bstrUrl ,
  242. CComPtr<IXMLDocument>& spxmlDoc )
  243. {
  244. HRESULT hr;
  245. if(SUCCEEDED(hr = spxmlDoc.CoCreateInstance( CLSID_XMLDocument )))
  246. {
  247. hr = spxmlDoc->put_URL( bstrUrl );
  248. }
  249. return hr;
  250. }
  251. HRESULT GetXMLDocFromFile( const CComBSTR& bstrFileName ,
  252. CComPtr<IXMLDocument>& spxmlDoc )
  253. {
  254. HRESULT hr;
  255. if(SUCCEEDED(hr = spxmlDoc.CoCreateInstance( CLSID_XMLDocument )))
  256. {
  257. CComPtr<IStream> spstm;
  258. if(SUCCEEDED(hr = SHCreateStreamOnFileW( bstrFileName, 0, &spstm )))
  259. {
  260. CComPtr<IPersistStream> sppsPersist;
  261. if(SUCCEEDED(hr = spxmlDoc.QueryInterface( &sppsPersist )))
  262. {
  263. hr = sppsPersist->Load( spstm );
  264. }
  265. }
  266. }
  267. return hr;
  268. }
  269. ////////////////////////////////////////////////////////////////////////////////
  270. int usage(char *progName)
  271. {
  272. printf("Usage: %s inputFileName outputFileName\n", progName);
  273. return 1;
  274. }
  275. int __cdecl main(int argc, char *argv[])
  276. {
  277. int retCode = 0;
  278. CoInitialize(NULL);
  279. {
  280. CComPtr<IXMLDocument> spxmlDoc;
  281. USES_CONVERSION;
  282. if (argc == 3)
  283. {
  284. //if (SUCCEEDED(GetXMLDoc(A2W(argv[1]), spxmlDoc)))
  285. if (SUCCEEDED(GetXMLDocFromFile(A2W(argv[1]), spxmlDoc)))
  286. {
  287. if (FAILED(DoTraverse(spxmlDoc, g_rgMasterTagTable, A2W(argv[2]))))
  288. retCode = 1;
  289. }
  290. else
  291. {
  292. ERRMSG(L"Failed to load FILE: %s\n", A2W(argv[1]));
  293. }
  294. }
  295. else
  296. retCode = usage(argv[0]);
  297. // this scope calls Release on spxmlDoc *before* CoUnitialize()
  298. }
  299. CoUninitialize();
  300. return retCode;
  301. }