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.

272 lines
6.3 KiB

  1. #include <wininetp.h>
  2. #include "xmlwrapper.h"
  3. IXMLDOMDocument *createXMLDocument() {
  4. IXMLDOMDocument *pDocument = NULL;
  5. HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**) &pDocument);
  6. /* if COM library was not initialized, retry after init */
  7. if (hr==CO_E_NOTINITIALIZED) {
  8. CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  9. hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**) &pDocument);
  10. }
  11. return pDocument;
  12. }
  13. IXMLDOMDocument *parseXMLDocument(char *pszFileName) {
  14. IXMLDOMDocument *document = createXMLDocument();
  15. if (!document)
  16. return NULL;
  17. /* Do not perform DTD or schema validation on P3P files */
  18. document->put_validateOnParse(FALSE);
  19. /* Open the file */
  20. HANDLE hf = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ,
  21. NULL, OPEN_EXISTING, 0, NULL);
  22. if (hf!=INVALID_HANDLE_VALUE) {
  23. /* Obtain stream from the XML document and write out
  24. contents of the file to stream */
  25. IStream *pStream = NULL;
  26. HRESULT hr = document->QueryInterface(IID_IStream, (void**) &pStream);
  27. if (SUCCEEDED(hr))
  28. {
  29. unsigned char xmldata[1024];
  30. DWORD dwBytes, dwWritten;
  31. do {
  32. ReadFile(hf, xmldata, sizeof(xmldata), &dwBytes, NULL);
  33. pStream->Write(xmldata, dwBytes, &dwWritten);
  34. if (dwBytes!=dwWritten)
  35. break;
  36. }
  37. while (dwBytes>0);
  38. pStream->Release();
  39. }
  40. CloseHandle(hf);
  41. }
  42. return document;
  43. };
  44. int defineAttributes(TreeNode *pCurrent, IXMLDOMNode *pXMLnode) {
  45. int cAttribute = 0;
  46. IXMLDOMNamedNodeMap *pAttributeMap = NULL;
  47. HRESULT hr = pXMLnode->get_attributes(&pAttributeMap);
  48. if (SUCCEEDED(hr) && pAttributeMap) {
  49. long cItems;
  50. IXMLDOMNode *pNode;
  51. IXMLDOMAttribute *pAttribute;
  52. pAttributeMap->get_length(&cItems);
  53. for (int i=0; i<cItems; i++) {
  54. pNode = pAttribute = NULL;
  55. pAttributeMap->get_item(i, &pNode);
  56. if (pNode) {
  57. pNode->QueryInterface(IID_IXMLDOMAttribute, (void**) &pAttribute);
  58. if (pAttribute) {
  59. BSTR bsName = NULL;
  60. pAttribute->get_name(&bsName);
  61. VARIANT var;
  62. VariantInit(&var);
  63. pAttribute->get_value(&var);
  64. char *pszName = unicode2ASCII(bsName);
  65. char *pszValue = (var.vt==VT_BSTR) ? unicode2ASCII(var.bstrVal) : NULL;
  66. pCurrent->defineAttribute(pszName, pszValue);
  67. delete [] pszName;
  68. delete [] pszValue;
  69. SysFreeString(bsName);
  70. VariantClear(&var);
  71. pAttribute->Release();
  72. cAttribute++;
  73. }
  74. pNode->Release();
  75. }
  76. }
  77. pAttributeMap->Release();
  78. }
  79. return cAttribute;
  80. }
  81. TreeNode *createXMLtree(IXMLDOMNode *pXMLnode, TreeNode *pParent = NULL) {
  82. HRESULT hr;
  83. if (!pXMLnode)
  84. return NULL;
  85. DOMNodeType dt;
  86. pXMLnode->get_nodeType(&dt);
  87. if (dt!=NODE_ELEMENT &&
  88. dt!=NODE_TEXT &&
  89. dt!=NODE_CDATA_SECTION)
  90. return NULL;
  91. TreeNode *pTree = new TreeNode();
  92. pTree->nodetype = dt;
  93. switch (dt) {
  94. case NODE_ELEMENT: {
  95. IXMLDOMElement *pElement;
  96. hr = pXMLnode->QueryInterface(IID_IXMLDOMElement, (void**) &pElement);
  97. if (SUCCEEDED(hr)) {
  98. BSTR bsName = NULL;
  99. pElement->get_tagName(&bsName);
  100. if (bsName) {
  101. char *pszTagName = unicode2ASCII(bsName);
  102. pTree->setContent(pszTagName);
  103. delete [] pszTagName;
  104. SysFreeString(bsName);
  105. }
  106. pElement->Release();
  107. }
  108. break;
  109. }
  110. case NODE_TEXT:
  111. case NODE_CDATA_SECTION: {
  112. IXMLDOMCharacterData *pCharData = NULL;
  113. hr = pXMLnode->QueryInterface(IID_IXMLDOMCharacterData, (void**) &pCharData);
  114. if (SUCCEEDED(hr)) {
  115. BSTR bsData = NULL;
  116. pCharData->get_data(&bsData);
  117. if (bsData) {
  118. pTree->pszContents = unicode2ASCII(bsData);
  119. SysFreeString(bsData);
  120. }
  121. pCharData->Release();
  122. }
  123. break;
  124. }
  125. }
  126. /* Enumerate attributes */
  127. defineAttributes(pTree, pXMLnode);
  128. /* Recursively create nodes for descendants */
  129. TreeNode *pLast = NULL;
  130. IXMLDOMNode *pChild = NULL;
  131. pXMLnode->get_firstChild(&pChild);
  132. while (pChild) {
  133. if (TreeNode *pDescendant = createXMLtree(pChild, pTree)) {
  134. if (pLast)
  135. pLast->pSibling = pDescendant;
  136. pLast = pDescendant;
  137. if (! pTree->pDescendant)
  138. pTree->pDescendant = pDescendant;
  139. }
  140. IXMLDOMNode *pTemp = pChild;
  141. hr = pChild->get_nextSibling(&pChild);
  142. pTemp->Release();
  143. if (!SUCCEEDED(hr))
  144. break;
  145. }
  146. return pTree;
  147. }
  148. TreeNode *createXMLtree(IXMLDOMDocument *pDocument) {
  149. IXMLDOMElement *pElement = NULL;
  150. TreeNode *pRoot = NULL;
  151. HRESULT hr = pDocument->get_documentElement(&pElement);
  152. if (pElement) {
  153. pRoot = createXMLtree(pElement);
  154. pElement->Release();
  155. }
  156. return pRoot;
  157. }
  158. /*
  159. Utility functions
  160. */
  161. char *unicode2ASCII(XMLchar *pwszSource) {
  162. if (!pwszSource)
  163. return NULL;
  164. char *pszDestination = NULL;
  165. int cRequired = WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, pszDestination, 0, NULL, NULL);
  166. if (cRequired>0 && (pszDestination = new char[cRequired]))
  167. WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, pszDestination, cRequired, NULL, NULL);
  168. return pszDestination;
  169. }
  170. BSTR ASCII2unicode(const char *pszSource) {
  171. int cRequired = MultiByteToWideChar(CP_ACP, 0, pszSource, -1, NULL, 0);
  172. if (cRequired==0)
  173. return NULL;
  174. BSTR bsResult = SysAllocStringLen(NULL, cRequired);
  175. if (bsResult)
  176. MultiByteToWideChar(CP_ACP, 0, pszSource, -1, bsResult, cRequired);
  177. return bsResult;
  178. }