push 0a13058ed4a6dc8d24e679bb2b178108eeb07303
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blob8f5f3cbc5680a49528ec186d72f0b2516fd26bc4
1 /*
2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #include <assert.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "ole2.h"
32 #include "msxml2.h"
33 #include "wininet.h"
34 #include "urlmon.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44 #ifdef HAVE_LIBXML2
46 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
47 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
48 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
50 typedef struct {
51 const struct IBindStatusCallbackVtbl *lpVtbl;
52 } bsc;
54 static HRESULT WINAPI bsc_QueryInterface(
55 IBindStatusCallback *iface,
56 REFIID riid,
57 LPVOID *ppobj )
59 if (IsEqualGUID(riid, &IID_IUnknown) ||
60 IsEqualGUID(riid, &IID_IBindStatusCallback))
62 IBindStatusCallback_AddRef( iface );
63 *ppobj = iface;
64 return S_OK;
67 FIXME("interface %s not implemented\n", debugstr_guid(riid));
68 return E_NOINTERFACE;
71 static ULONG WINAPI bsc_AddRef(
72 IBindStatusCallback *iface )
74 return 2;
77 static ULONG WINAPI bsc_Release(
78 IBindStatusCallback *iface )
80 return 1;
83 static HRESULT WINAPI bsc_OnStartBinding(
84 IBindStatusCallback* iface,
85 DWORD dwReserved,
86 IBinding* pib)
88 return S_OK;
91 static HRESULT WINAPI bsc_GetPriority(
92 IBindStatusCallback* iface,
93 LONG* pnPriority)
95 return S_OK;
98 static HRESULT WINAPI bsc_OnLowResource(
99 IBindStatusCallback* iface,
100 DWORD reserved)
102 return S_OK;
105 static HRESULT WINAPI bsc_OnProgress(
106 IBindStatusCallback* iface,
107 ULONG ulProgress,
108 ULONG ulProgressMax,
109 ULONG ulStatusCode,
110 LPCWSTR szStatusText)
112 return S_OK;
115 static HRESULT WINAPI bsc_OnStopBinding(
116 IBindStatusCallback* iface,
117 HRESULT hresult,
118 LPCWSTR szError)
120 return S_OK;
123 static HRESULT WINAPI bsc_GetBindInfo(
124 IBindStatusCallback* iface,
125 DWORD* grfBINDF,
126 BINDINFO* pbindinfo)
128 *grfBINDF = BINDF_RESYNCHRONIZE;
130 return S_OK;
133 static HRESULT WINAPI bsc_OnDataAvailable(
134 IBindStatusCallback* iface,
135 DWORD grfBSCF,
136 DWORD dwSize,
137 FORMATETC* pformatetc,
138 STGMEDIUM* pstgmed)
140 return S_OK;
143 static HRESULT WINAPI bsc_OnObjectAvailable(
144 IBindStatusCallback* iface,
145 REFIID riid,
146 IUnknown* punk)
148 return S_OK;
151 static const struct IBindStatusCallbackVtbl bsc_vtbl =
153 bsc_QueryInterface,
154 bsc_AddRef,
155 bsc_Release,
156 bsc_OnStartBinding,
157 bsc_GetPriority,
158 bsc_OnLowResource,
159 bsc_OnProgress,
160 bsc_OnStopBinding,
161 bsc_GetBindInfo,
162 bsc_OnDataAvailable,
163 bsc_OnObjectAvailable
166 static bsc domdoc_bsc = { &bsc_vtbl };
168 typedef struct _domdoc
170 const struct IXMLDOMDocument2Vtbl *lpVtbl;
171 LONG ref;
172 VARIANT_BOOL async;
173 VARIANT_BOOL validating;
174 VARIANT_BOOL resolving;
175 VARIANT_BOOL preserving;
176 BOOL bUseXPath;
177 IUnknown *node_unk;
178 IXMLDOMNode *node;
179 IXMLDOMSchemaCollection *schema;
180 HRESULT error;
181 } domdoc;
183 LONG xmldoc_add_ref(xmlDocPtr doc)
185 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
186 TRACE("%d\n", ref);
187 return ref;
190 LONG xmldoc_release(xmlDocPtr doc)
192 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
193 TRACE("%d\n", ref);
194 if(ref == 0)
196 TRACE("freeing docptr %p\n", doc);
197 xmlFreeDoc(doc);
200 return ref;
203 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
205 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
208 static inline xmlDocPtr get_doc( domdoc *This )
210 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
213 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
215 domdoc *This = impl_from_IXMLDOMDocument2( iface );
217 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
219 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
220 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
221 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
223 *ppvObject = iface;
225 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
226 IsEqualGUID( riid, &IID_IDispatch ) )
228 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
230 else
232 FIXME("interface %s not implemented\n", debugstr_guid(riid));
233 return E_NOINTERFACE;
236 IXMLDOMDocument_AddRef( iface );
238 return S_OK;
242 static ULONG WINAPI domdoc_AddRef(
243 IXMLDOMDocument2 *iface )
245 domdoc *This = impl_from_IXMLDOMDocument2( iface );
246 TRACE("%p\n", This );
247 return InterlockedIncrement( &This->ref );
251 static ULONG WINAPI domdoc_Release(
252 IXMLDOMDocument2 *iface )
254 domdoc *This = impl_from_IXMLDOMDocument2( iface );
255 LONG ref;
257 TRACE("%p\n", This );
259 ref = InterlockedDecrement( &This->ref );
260 if ( ref == 0 )
262 IUnknown_Release( This->node_unk );
263 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
264 HeapFree( GetProcessHeap(), 0, This );
267 return ref;
270 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
272 FIXME("\n");
273 return E_NOTIMPL;
276 static HRESULT WINAPI domdoc_GetTypeInfo(
277 IXMLDOMDocument2 *iface,
278 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
280 FIXME("\n");
281 return E_NOTIMPL;
284 static HRESULT WINAPI domdoc_GetIDsOfNames(
285 IXMLDOMDocument2 *iface,
286 REFIID riid,
287 LPOLESTR* rgszNames,
288 UINT cNames,
289 LCID lcid,
290 DISPID* rgDispId)
292 FIXME("\n");
293 return E_NOTIMPL;
297 static HRESULT WINAPI domdoc_Invoke(
298 IXMLDOMDocument2 *iface,
299 DISPID dispIdMember,
300 REFIID riid,
301 LCID lcid,
302 WORD wFlags,
303 DISPPARAMS* pDispParams,
304 VARIANT* pVarResult,
305 EXCEPINFO* pExcepInfo,
306 UINT* puArgErr)
308 FIXME("\n");
309 return E_NOTIMPL;
313 static HRESULT WINAPI domdoc_get_nodeName(
314 IXMLDOMDocument2 *iface,
315 BSTR* name )
317 domdoc *This = impl_from_IXMLDOMDocument2( iface );
318 return IXMLDOMNode_get_nodeName( This->node, name );
322 static HRESULT WINAPI domdoc_get_nodeValue(
323 IXMLDOMDocument2 *iface,
324 VARIANT* value )
326 domdoc *This = impl_from_IXMLDOMDocument2( iface );
327 return IXMLDOMNode_get_nodeValue( This->node, value );
331 static HRESULT WINAPI domdoc_put_nodeValue(
332 IXMLDOMDocument2 *iface,
333 VARIANT value)
335 domdoc *This = impl_from_IXMLDOMDocument2( iface );
336 return IXMLDOMNode_put_nodeValue( This->node, value );
340 static HRESULT WINAPI domdoc_get_nodeType(
341 IXMLDOMDocument2 *iface,
342 DOMNodeType* type )
344 domdoc *This = impl_from_IXMLDOMDocument2( iface );
345 return IXMLDOMNode_get_nodeType( This->node, type );
349 static HRESULT WINAPI domdoc_get_parentNode(
350 IXMLDOMDocument2 *iface,
351 IXMLDOMNode** parent )
353 domdoc *This = impl_from_IXMLDOMDocument2( iface );
354 return IXMLDOMNode_get_parentNode( This->node, parent );
358 static HRESULT WINAPI domdoc_get_childNodes(
359 IXMLDOMDocument2 *iface,
360 IXMLDOMNodeList** childList )
362 domdoc *This = impl_from_IXMLDOMDocument2( iface );
363 return IXMLDOMNode_get_childNodes( This->node, childList );
367 static HRESULT WINAPI domdoc_get_firstChild(
368 IXMLDOMDocument2 *iface,
369 IXMLDOMNode** firstChild )
371 domdoc *This = impl_from_IXMLDOMDocument2( iface );
372 return IXMLDOMNode_get_firstChild( This->node, firstChild );
376 static HRESULT WINAPI domdoc_get_lastChild(
377 IXMLDOMDocument2 *iface,
378 IXMLDOMNode** lastChild )
380 domdoc *This = impl_from_IXMLDOMDocument2( iface );
381 return IXMLDOMNode_get_lastChild( This->node, lastChild );
385 static HRESULT WINAPI domdoc_get_previousSibling(
386 IXMLDOMDocument2 *iface,
387 IXMLDOMNode** previousSibling )
389 domdoc *This = impl_from_IXMLDOMDocument2( iface );
390 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
394 static HRESULT WINAPI domdoc_get_nextSibling(
395 IXMLDOMDocument2 *iface,
396 IXMLDOMNode** nextSibling )
398 domdoc *This = impl_from_IXMLDOMDocument2( iface );
399 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
403 static HRESULT WINAPI domdoc_get_attributes(
404 IXMLDOMDocument2 *iface,
405 IXMLDOMNamedNodeMap** attributeMap )
407 domdoc *This = impl_from_IXMLDOMDocument2( iface );
408 return IXMLDOMNode_get_attributes( This->node, attributeMap );
412 static HRESULT WINAPI domdoc_insertBefore(
413 IXMLDOMDocument2 *iface,
414 IXMLDOMNode* newChild,
415 VARIANT refChild,
416 IXMLDOMNode** outNewChild )
418 domdoc *This = impl_from_IXMLDOMDocument2( iface );
419 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
423 static HRESULT WINAPI domdoc_replaceChild(
424 IXMLDOMDocument2 *iface,
425 IXMLDOMNode* newChild,
426 IXMLDOMNode* oldChild,
427 IXMLDOMNode** outOldChild)
429 domdoc *This = impl_from_IXMLDOMDocument2( iface );
430 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
434 static HRESULT WINAPI domdoc_removeChild(
435 IXMLDOMDocument2 *iface,
436 IXMLDOMNode* childNode,
437 IXMLDOMNode** oldChild)
439 domdoc *This = impl_from_IXMLDOMDocument2( iface );
440 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
444 static HRESULT WINAPI domdoc_appendChild(
445 IXMLDOMDocument2 *iface,
446 IXMLDOMNode* newChild,
447 IXMLDOMNode** outNewChild)
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
454 static HRESULT WINAPI domdoc_hasChildNodes(
455 IXMLDOMDocument2 *iface,
456 VARIANT_BOOL* hasChild)
458 domdoc *This = impl_from_IXMLDOMDocument2( iface );
459 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
463 static HRESULT WINAPI domdoc_get_ownerDocument(
464 IXMLDOMDocument2 *iface,
465 IXMLDOMDocument** DOMDocument)
467 domdoc *This = impl_from_IXMLDOMDocument2( iface );
468 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
472 static HRESULT WINAPI domdoc_cloneNode(
473 IXMLDOMDocument2 *iface,
474 VARIANT_BOOL deep,
475 IXMLDOMNode** cloneRoot)
477 domdoc *This = impl_from_IXMLDOMDocument2( iface );
478 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
482 static HRESULT WINAPI domdoc_get_nodeTypeString(
483 IXMLDOMDocument2 *iface,
484 BSTR* nodeType )
486 domdoc *This = impl_from_IXMLDOMDocument2( iface );
487 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
491 static HRESULT WINAPI domdoc_get_text(
492 IXMLDOMDocument2 *iface,
493 BSTR* text )
495 domdoc *This = impl_from_IXMLDOMDocument2( iface );
496 return IXMLDOMNode_get_text( This->node, text );
500 static HRESULT WINAPI domdoc_put_text(
501 IXMLDOMDocument2 *iface,
502 BSTR text )
504 domdoc *This = impl_from_IXMLDOMDocument2( iface );
505 return IXMLDOMNode_put_text( This->node, text );
509 static HRESULT WINAPI domdoc_get_specified(
510 IXMLDOMDocument2 *iface,
511 VARIANT_BOOL* isSpecified )
513 domdoc *This = impl_from_IXMLDOMDocument2( iface );
514 return IXMLDOMNode_get_specified( This->node, isSpecified );
518 static HRESULT WINAPI domdoc_get_definition(
519 IXMLDOMDocument2 *iface,
520 IXMLDOMNode** definitionNode )
522 domdoc *This = impl_from_IXMLDOMDocument2( iface );
523 return IXMLDOMNode_get_definition( This->node, definitionNode );
527 static HRESULT WINAPI domdoc_get_nodeTypedValue(
528 IXMLDOMDocument2 *iface,
529 VARIANT* typedValue )
531 domdoc *This = impl_from_IXMLDOMDocument2( iface );
532 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
535 static HRESULT WINAPI domdoc_put_nodeTypedValue(
536 IXMLDOMDocument2 *iface,
537 VARIANT typedValue )
539 domdoc *This = impl_from_IXMLDOMDocument2( iface );
540 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
544 static HRESULT WINAPI domdoc_get_dataType(
545 IXMLDOMDocument2 *iface,
546 VARIANT* dataTypeName )
548 domdoc *This = impl_from_IXMLDOMDocument2( iface );
549 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
553 static HRESULT WINAPI domdoc_put_dataType(
554 IXMLDOMDocument2 *iface,
555 BSTR dataTypeName )
557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
558 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
562 static HRESULT WINAPI domdoc_get_xml(
563 IXMLDOMDocument2 *iface,
564 BSTR* xmlString )
566 domdoc *This = impl_from_IXMLDOMDocument2( iface );
567 return IXMLDOMNode_get_xml( This->node, xmlString );
571 static HRESULT WINAPI domdoc_transformNode(
572 IXMLDOMDocument2 *iface,
573 IXMLDOMNode* styleSheet,
574 BSTR* xmlString )
576 domdoc *This = impl_from_IXMLDOMDocument2( iface );
577 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
581 static HRESULT WINAPI domdoc_selectNodes(
582 IXMLDOMDocument2 *iface,
583 BSTR queryString,
584 IXMLDOMNodeList** resultList )
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
587 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
591 static HRESULT WINAPI domdoc_selectSingleNode(
592 IXMLDOMDocument2 *iface,
593 BSTR queryString,
594 IXMLDOMNode** resultNode )
596 domdoc *This = impl_from_IXMLDOMDocument2( iface );
597 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
601 static HRESULT WINAPI domdoc_get_parsed(
602 IXMLDOMDocument2 *iface,
603 VARIANT_BOOL* isParsed )
605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 return IXMLDOMNode_get_parsed( This->node, isParsed );
610 static HRESULT WINAPI domdoc_get_namespaceURI(
611 IXMLDOMDocument2 *iface,
612 BSTR* namespaceURI )
614 domdoc *This = impl_from_IXMLDOMDocument2( iface );
615 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
619 static HRESULT WINAPI domdoc_get_prefix(
620 IXMLDOMDocument2 *iface,
621 BSTR* prefixString )
623 domdoc *This = impl_from_IXMLDOMDocument2( iface );
624 return IXMLDOMNode_get_prefix( This->node, prefixString );
628 static HRESULT WINAPI domdoc_get_baseName(
629 IXMLDOMDocument2 *iface,
630 BSTR* nameString )
632 domdoc *This = impl_from_IXMLDOMDocument2( iface );
633 return IXMLDOMNode_get_baseName( This->node, nameString );
637 static HRESULT WINAPI domdoc_transformNodeToObject(
638 IXMLDOMDocument2 *iface,
639 IXMLDOMNode* stylesheet,
640 VARIANT outputObject)
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
647 static HRESULT WINAPI domdoc_get_doctype(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMDocumentType** documentType )
651 FIXME("\n");
652 return E_NOTIMPL;
656 static HRESULT WINAPI domdoc_get_implementation(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMImplementation** impl )
660 FIXME("\n");
661 return E_NOTIMPL;
664 static HRESULT WINAPI domdoc_get_documentElement(
665 IXMLDOMDocument2 *iface,
666 IXMLDOMElement** DOMElement )
668 domdoc *This = impl_from_IXMLDOMDocument2( iface );
669 xmlDocPtr xmldoc = NULL;
670 xmlNodePtr root = NULL;
671 IXMLDOMNode *element_node;
672 HRESULT hr;
674 TRACE("%p\n", This);
676 *DOMElement = NULL;
678 xmldoc = get_doc( This );
680 root = xmlDocGetRootElement( xmldoc );
681 if ( !root )
682 return S_FALSE;
684 element_node = create_node( root );
685 if(!element_node) return S_FALSE;
687 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
688 IXMLDOMNode_Release(element_node);
690 return hr;
694 static HRESULT WINAPI domdoc_documentElement(
695 IXMLDOMDocument2 *iface,
696 IXMLDOMElement* DOMElement )
698 FIXME("\n");
699 return E_NOTIMPL;
703 static HRESULT WINAPI domdoc_createElement(
704 IXMLDOMDocument2 *iface,
705 BSTR tagname,
706 IXMLDOMElement** element )
708 xmlNodePtr xmlnode;
709 domdoc *This = impl_from_IXMLDOMDocument2( iface );
710 xmlChar *xml_name;
711 IUnknown *elem_unk;
712 HRESULT hr;
714 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
716 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
717 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
719 TRACE("created xmlptr %p\n", xmlnode);
720 elem_unk = create_element(xmlnode, NULL);
721 HeapFree(GetProcessHeap(), 0, xml_name);
723 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
724 IUnknown_Release(elem_unk);
725 TRACE("returning %p\n", *element);
726 return hr;
730 static HRESULT WINAPI domdoc_createDocumentFragment(
731 IXMLDOMDocument2 *iface,
732 IXMLDOMDocumentFragment** docFrag )
734 FIXME("\n");
735 return E_NOTIMPL;
739 static HRESULT WINAPI domdoc_createTextNode(
740 IXMLDOMDocument2 *iface,
741 BSTR data,
742 IXMLDOMText** text )
744 FIXME("\n");
745 return E_NOTIMPL;
749 static HRESULT WINAPI domdoc_createComment(
750 IXMLDOMDocument2 *iface,
751 BSTR data,
752 IXMLDOMComment** comment )
754 FIXME("\n");
755 return E_NOTIMPL;
759 static HRESULT WINAPI domdoc_createCDATASection(
760 IXMLDOMDocument2 *iface,
761 BSTR data,
762 IXMLDOMCDATASection** cdata )
764 FIXME("\n");
765 return E_NOTIMPL;
769 static HRESULT WINAPI domdoc_createProcessingInstruction(
770 IXMLDOMDocument2 *iface,
771 BSTR target,
772 BSTR data,
773 IXMLDOMProcessingInstruction** pi )
775 #ifdef HAVE_XMLNEWDOCPI
776 xmlNodePtr xmlnode;
777 domdoc *This = impl_from_IXMLDOMDocument2( iface );
778 xmlChar *xml_target, *xml_content;
780 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
782 xml_target = xmlChar_from_wchar((WCHAR*)target);
783 xml_content = xmlChar_from_wchar((WCHAR*)data);
785 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
786 TRACE("created xmlptr %p\n", xmlnode);
787 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
789 HeapFree(GetProcessHeap(), 0, xml_content);
790 HeapFree(GetProcessHeap(), 0, xml_target);
792 return S_OK;
793 #else
794 FIXME("Libxml 2.6.15 or greater required.\n");
795 return E_NOTIMPL;
796 #endif
800 static HRESULT WINAPI domdoc_createAttribute(
801 IXMLDOMDocument2 *iface,
802 BSTR name,
803 IXMLDOMAttribute** attribute )
805 FIXME("\n");
806 return E_NOTIMPL;
810 static HRESULT WINAPI domdoc_createEntityReference(
811 IXMLDOMDocument2 *iface,
812 BSTR name,
813 IXMLDOMEntityReference** entityRef )
815 FIXME("\n");
816 return E_NOTIMPL;
820 static HRESULT WINAPI domdoc_getElementsByTagName(
821 IXMLDOMDocument2 *iface,
822 BSTR tagName,
823 IXMLDOMNodeList** resultList )
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
826 LPWSTR szPattern;
827 HRESULT hr;
828 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
830 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
831 szPattern[0] = szPattern[1] = '/';
832 lstrcpyW(szPattern + 2, tagName);
834 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
835 HeapFree(GetProcessHeap(), 0, szPattern);
837 return hr;
840 static DOMNodeType get_node_type(VARIANT Type)
842 if(V_VT(&Type) == VT_I4)
843 return V_I4(&Type);
845 FIXME("Unsupported variant type %x\n", V_VT(&Type));
846 return 0;
849 static HRESULT WINAPI domdoc_createNode(
850 IXMLDOMDocument2 *iface,
851 VARIANT Type,
852 BSTR name,
853 BSTR namespaceURI,
854 IXMLDOMNode** node )
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 DOMNodeType node_type;
858 xmlNodePtr xmlnode = NULL;
859 xmlChar *xml_name;
861 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
863 node_type = get_node_type(Type);
864 TRACE("node_type %d\n", node_type);
866 xml_name = xmlChar_from_wchar((WCHAR*)name);
868 switch(node_type)
870 case NODE_ELEMENT:
871 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
872 *node = create_node(xmlnode);
873 TRACE("created %p\n", xmlnode);
874 break;
876 default:
877 FIXME("unhandled node type %d\n", node_type);
878 break;
881 HeapFree(GetProcessHeap(), 0, xml_name);
883 if(xmlnode && *node)
884 return S_OK;
886 return E_FAIL;
889 static HRESULT WINAPI domdoc_nodeFromID(
890 IXMLDOMDocument2 *iface,
891 BSTR idString,
892 IXMLDOMNode** node )
894 FIXME("\n");
895 return E_NOTIMPL;
898 static xmlDocPtr doparse( char *ptr, int len )
900 #ifdef HAVE_XMLREADMEMORY
902 * use xmlReadMemory if possible so we can suppress
903 * writing errors to stderr
905 return xmlReadMemory( ptr, len, NULL, NULL,
906 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
907 #else
908 return xmlParseMemory( ptr, len );
909 #endif
912 static xmlDocPtr doread( LPWSTR filename )
914 xmlDocPtr xmldoc = NULL;
915 HRESULT hr;
916 IBindCtx *pbc;
917 IStream *stream, *memstream;
918 WCHAR url[INTERNET_MAX_URL_LENGTH];
919 BYTE buf[4096];
920 DWORD read, written;
922 TRACE("%s\n", debugstr_w( filename ));
924 if(!PathIsURLW(filename))
926 WCHAR fullpath[MAX_PATH];
927 DWORD needed = sizeof(url)/sizeof(WCHAR);
929 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
931 WARN("can't find path\n");
932 return NULL;
935 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
937 ERR("can't create url from path\n");
938 return NULL;
940 filename = url;
943 hr = CreateBindCtx(0, &pbc);
944 if(SUCCEEDED(hr))
946 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
947 if(SUCCEEDED(hr))
949 IMoniker *moniker;
950 hr = CreateURLMoniker(NULL, filename, &moniker);
951 if(SUCCEEDED(hr))
953 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
954 IMoniker_Release(moniker);
957 IBindCtx_Release(pbc);
959 if(FAILED(hr))
960 return NULL;
962 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
963 if(FAILED(hr))
965 IStream_Release(stream);
966 return NULL;
971 IStream_Read(stream, buf, sizeof(buf), &read);
972 hr = IStream_Write(memstream, buf, read, &written);
973 } while(SUCCEEDED(hr) && written != 0 && read != 0);
975 if(SUCCEEDED(hr))
977 HGLOBAL hglobal;
978 hr = GetHGlobalFromStream(memstream, &hglobal);
979 if(SUCCEEDED(hr))
981 DWORD len = GlobalSize(hglobal);
982 char *ptr = GlobalLock(hglobal);
983 if(len != 0)
984 xmldoc = doparse( ptr, len );
985 GlobalUnlock(hglobal);
988 IStream_Release(memstream);
989 IStream_Release(stream);
990 return xmldoc;
993 static HRESULT WINAPI domdoc_load(
994 IXMLDOMDocument2 *iface,
995 VARIANT xmlSource,
996 VARIANT_BOOL* isSuccessful )
998 domdoc *This = impl_from_IXMLDOMDocument2( iface );
999 LPWSTR filename = NULL;
1000 xmlDocPtr xmldoc = NULL;
1001 HRESULT hr = S_FALSE;
1003 TRACE("type %d\n", V_VT(&xmlSource) );
1005 *isSuccessful = VARIANT_FALSE;
1007 assert( This->node );
1009 attach_xmlnode(This->node, NULL);
1011 switch( V_VT(&xmlSource) )
1013 case VT_BSTR:
1014 filename = V_BSTR(&xmlSource);
1017 if ( filename )
1019 xmldoc = doread( filename );
1021 if ( !xmldoc )
1022 This->error = E_FAIL;
1023 else
1025 hr = This->error = S_OK;
1026 *isSuccessful = VARIANT_TRUE;
1030 if(!xmldoc)
1031 xmldoc = xmlNewDoc(NULL);
1033 xmldoc->_private = 0;
1034 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1036 return hr;
1040 static HRESULT WINAPI domdoc_get_readyState(
1041 IXMLDOMDocument2 *iface,
1042 long* value )
1044 FIXME("\n");
1045 return E_NOTIMPL;
1049 static HRESULT WINAPI domdoc_get_parseError(
1050 IXMLDOMDocument2 *iface,
1051 IXMLDOMParseError** errorObj )
1053 BSTR error_string = NULL;
1054 static const WCHAR err[] = {'e','r','r','o','r',0};
1055 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1057 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1059 if(This->error)
1060 error_string = SysAllocString(err);
1062 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1063 if(!*errorObj) return E_OUTOFMEMORY;
1064 return S_OK;
1068 static HRESULT WINAPI domdoc_get_url(
1069 IXMLDOMDocument2 *iface,
1070 BSTR* urlString )
1072 FIXME("\n");
1073 return E_NOTIMPL;
1077 static HRESULT WINAPI domdoc_get_async(
1078 IXMLDOMDocument2 *iface,
1079 VARIANT_BOOL* isAsync )
1081 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1083 TRACE("%p <- %d\n", isAsync, This->async);
1084 *isAsync = This->async;
1085 return S_OK;
1089 static HRESULT WINAPI domdoc_put_async(
1090 IXMLDOMDocument2 *iface,
1091 VARIANT_BOOL isAsync )
1093 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1095 TRACE("%d\n", isAsync);
1096 This->async = isAsync;
1097 return S_OK;
1101 static HRESULT WINAPI domdoc_abort(
1102 IXMLDOMDocument2 *iface )
1104 FIXME("\n");
1105 return E_NOTIMPL;
1109 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1111 UINT len, blen = SysStringLen( bstr );
1112 LPSTR str;
1114 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1115 str = HeapAlloc( GetProcessHeap(), 0, len );
1116 if ( !str )
1117 return FALSE;
1118 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1119 *plen = len;
1120 *pstr = str;
1121 return TRUE;
1124 static HRESULT WINAPI domdoc_loadXML(
1125 IXMLDOMDocument2 *iface,
1126 BSTR bstrXML,
1127 VARIANT_BOOL* isSuccessful )
1129 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1130 xmlDocPtr xmldoc = NULL;
1131 char *str;
1132 int len;
1133 HRESULT hr = S_FALSE;
1135 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1137 assert ( This->node );
1139 attach_xmlnode( This->node, NULL );
1141 if ( isSuccessful )
1143 *isSuccessful = VARIANT_FALSE;
1145 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1147 xmldoc = doparse( str, len );
1148 HeapFree( GetProcessHeap(), 0, str );
1149 if ( !xmldoc )
1150 This->error = E_FAIL;
1151 else
1153 hr = This->error = S_OK;
1154 *isSuccessful = VARIANT_TRUE;
1158 if(!xmldoc)
1159 xmldoc = xmlNewDoc(NULL);
1161 xmldoc->_private = 0;
1162 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1164 return hr;
1168 static HRESULT WINAPI domdoc_save(
1169 IXMLDOMDocument2 *iface,
1170 VARIANT destination )
1172 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1173 HANDLE handle;
1174 xmlChar *mem;
1175 int size;
1176 HRESULT ret = S_OK;
1177 DWORD written;
1179 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1180 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1182 if(V_VT(&destination) != VT_BSTR)
1184 FIXME("Unhandled vt %x\n", V_VT(&destination));
1185 return S_FALSE;
1188 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1189 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1190 if( handle == INVALID_HANDLE_VALUE )
1192 WARN("failed to create file\n");
1193 return S_FALSE;
1196 xmlDocDumpMemory(get_doc(This), &mem, &size);
1197 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1199 WARN("write error\n");
1200 ret = S_FALSE;
1203 xmlFree(mem);
1204 CloseHandle(handle);
1205 return ret;
1208 static HRESULT WINAPI domdoc_get_validateOnParse(
1209 IXMLDOMDocument2 *iface,
1210 VARIANT_BOOL* isValidating )
1212 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1214 TRACE("%p <- %d\n", isValidating, This->validating);
1215 *isValidating = This->validating;
1216 return S_OK;
1220 static HRESULT WINAPI domdoc_put_validateOnParse(
1221 IXMLDOMDocument2 *iface,
1222 VARIANT_BOOL isValidating )
1224 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1226 TRACE("%d\n", isValidating);
1227 This->validating = isValidating;
1228 return S_OK;
1232 static HRESULT WINAPI domdoc_get_resolveExternals(
1233 IXMLDOMDocument2 *iface,
1234 VARIANT_BOOL* isResolving )
1236 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1238 TRACE("%p <- %d\n", isResolving, This->resolving);
1239 *isResolving = This->resolving;
1240 return S_OK;
1244 static HRESULT WINAPI domdoc_put_resolveExternals(
1245 IXMLDOMDocument2 *iface,
1246 VARIANT_BOOL isResolving )
1248 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1250 TRACE("%d\n", isResolving);
1251 This->resolving = isResolving;
1252 return S_OK;
1256 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1257 IXMLDOMDocument2 *iface,
1258 VARIANT_BOOL* isPreserving )
1260 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1262 TRACE("%p <- %d\n", isPreserving, This->preserving);
1263 *isPreserving = This->preserving;
1264 return S_OK;
1268 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1269 IXMLDOMDocument2 *iface,
1270 VARIANT_BOOL isPreserving )
1272 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1274 TRACE("%d\n", isPreserving);
1275 This->preserving = isPreserving;
1276 return S_OK;
1280 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1281 IXMLDOMDocument2 *iface,
1282 VARIANT readyStateChangeSink )
1284 FIXME("\n");
1285 return E_NOTIMPL;
1289 static HRESULT WINAPI domdoc_put_onDataAvailable(
1290 IXMLDOMDocument2 *iface,
1291 VARIANT onDataAvailableSink )
1293 FIXME("\n");
1294 return E_NOTIMPL;
1297 static HRESULT WINAPI domdoc_put_onTransformNode(
1298 IXMLDOMDocument2 *iface,
1299 VARIANT onTransformNodeSink )
1301 FIXME("\n");
1302 return E_NOTIMPL;
1305 static HRESULT WINAPI domdoc_get_namespaces(
1306 IXMLDOMDocument2* iface,
1307 IXMLDOMSchemaCollection** schemaCollection )
1309 FIXME("\n");
1310 return E_NOTIMPL;
1313 static HRESULT WINAPI domdoc_get_schemas(
1314 IXMLDOMDocument2* iface,
1315 VARIANT* var1 )
1317 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1318 HRESULT hr = S_FALSE;
1319 IXMLDOMSchemaCollection *cur_schema = This->schema;
1321 TRACE("(%p)->(%p)\n", This, var1);
1323 VariantInit(var1); /* Test shows we don't call VariantClear here */
1324 V_VT(var1) = VT_NULL;
1326 if(cur_schema)
1328 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1329 if(SUCCEEDED(hr))
1330 V_VT(var1) = VT_DISPATCH;
1332 return hr;
1335 static HRESULT WINAPI domdoc_putref_schemas(
1336 IXMLDOMDocument2* iface,
1337 VARIANT var1)
1339 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1340 HRESULT hr = E_FAIL;
1341 IXMLDOMSchemaCollection *new_schema = NULL;
1343 FIXME("(%p): semi-stub\n", This);
1344 switch(V_VT(&var1))
1346 case VT_UNKNOWN:
1347 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1348 break;
1350 case VT_DISPATCH:
1351 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1352 break;
1354 case VT_NULL:
1355 case VT_EMPTY:
1356 hr = S_OK;
1357 break;
1359 default:
1360 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1363 if(SUCCEEDED(hr))
1365 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1366 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1369 return hr;
1372 static HRESULT WINAPI domdoc_validate(
1373 IXMLDOMDocument2* iface,
1374 IXMLDOMParseError** err)
1376 FIXME("\n");
1377 return E_NOTIMPL;
1380 static HRESULT WINAPI domdoc_setProperty(
1381 IXMLDOMDocument2* iface,
1382 BSTR p,
1383 VARIANT var)
1385 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1387 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1389 VARIANT varStr;
1390 HRESULT hr;
1391 BSTR bstr;
1393 V_VT(&varStr) = VT_EMPTY;
1394 if (V_VT(&var) != VT_BSTR)
1396 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1397 return hr;
1398 bstr = V_BSTR(&varStr);
1400 else
1401 bstr = V_BSTR(&var);
1403 hr = S_OK;
1404 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1405 This->bUseXPath = TRUE;
1406 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1407 This->bUseXPath = FALSE;
1408 else
1409 hr = E_FAIL;
1411 VariantClear(&varStr);
1412 return hr;
1415 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1416 return E_FAIL;
1419 static HRESULT WINAPI domdoc_getProperty(
1420 IXMLDOMDocument2* iface,
1421 BSTR p,
1422 VARIANT* var)
1424 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1426 if (var == NULL)
1427 return E_INVALIDARG;
1428 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1430 V_VT(var) = VT_BSTR;
1431 if (This->bUseXPath)
1432 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1433 else
1434 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1435 return S_OK;
1438 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1439 return E_FAIL;
1442 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1444 domdoc_QueryInterface,
1445 domdoc_AddRef,
1446 domdoc_Release,
1447 domdoc_GetTypeInfoCount,
1448 domdoc_GetTypeInfo,
1449 domdoc_GetIDsOfNames,
1450 domdoc_Invoke,
1451 domdoc_get_nodeName,
1452 domdoc_get_nodeValue,
1453 domdoc_put_nodeValue,
1454 domdoc_get_nodeType,
1455 domdoc_get_parentNode,
1456 domdoc_get_childNodes,
1457 domdoc_get_firstChild,
1458 domdoc_get_lastChild,
1459 domdoc_get_previousSibling,
1460 domdoc_get_nextSibling,
1461 domdoc_get_attributes,
1462 domdoc_insertBefore,
1463 domdoc_replaceChild,
1464 domdoc_removeChild,
1465 domdoc_appendChild,
1466 domdoc_hasChildNodes,
1467 domdoc_get_ownerDocument,
1468 domdoc_cloneNode,
1469 domdoc_get_nodeTypeString,
1470 domdoc_get_text,
1471 domdoc_put_text,
1472 domdoc_get_specified,
1473 domdoc_get_definition,
1474 domdoc_get_nodeTypedValue,
1475 domdoc_put_nodeTypedValue,
1476 domdoc_get_dataType,
1477 domdoc_put_dataType,
1478 domdoc_get_xml,
1479 domdoc_transformNode,
1480 domdoc_selectNodes,
1481 domdoc_selectSingleNode,
1482 domdoc_get_parsed,
1483 domdoc_get_namespaceURI,
1484 domdoc_get_prefix,
1485 domdoc_get_baseName,
1486 domdoc_transformNodeToObject,
1487 domdoc_get_doctype,
1488 domdoc_get_implementation,
1489 domdoc_get_documentElement,
1490 domdoc_documentElement,
1491 domdoc_createElement,
1492 domdoc_createDocumentFragment,
1493 domdoc_createTextNode,
1494 domdoc_createComment,
1495 domdoc_createCDATASection,
1496 domdoc_createProcessingInstruction,
1497 domdoc_createAttribute,
1498 domdoc_createEntityReference,
1499 domdoc_getElementsByTagName,
1500 domdoc_createNode,
1501 domdoc_nodeFromID,
1502 domdoc_load,
1503 domdoc_get_readyState,
1504 domdoc_get_parseError,
1505 domdoc_get_url,
1506 domdoc_get_async,
1507 domdoc_put_async,
1508 domdoc_abort,
1509 domdoc_loadXML,
1510 domdoc_save,
1511 domdoc_get_validateOnParse,
1512 domdoc_put_validateOnParse,
1513 domdoc_get_resolveExternals,
1514 domdoc_put_resolveExternals,
1515 domdoc_get_preserveWhiteSpace,
1516 domdoc_put_preserveWhiteSpace,
1517 domdoc_put_onReadyStateChange,
1518 domdoc_put_onDataAvailable,
1519 domdoc_put_onTransformNode,
1520 domdoc_get_namespaces,
1521 domdoc_get_schemas,
1522 domdoc_putref_schemas,
1523 domdoc_validate,
1524 domdoc_setProperty,
1525 domdoc_getProperty
1528 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1530 domdoc *doc;
1531 HRESULT hr;
1532 xmlDocPtr xmldoc;
1534 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1536 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1537 if( !doc )
1538 return E_OUTOFMEMORY;
1540 doc->lpVtbl = &domdoc_vtbl;
1541 doc->ref = 1;
1542 doc->async = 0;
1543 doc->validating = 0;
1544 doc->resolving = 0;
1545 doc->preserving = 0;
1546 doc->bUseXPath = FALSE;
1547 doc->error = S_OK;
1548 doc->schema = NULL;
1550 xmldoc = xmlNewDoc(NULL);
1551 if(!xmldoc)
1553 HeapFree(GetProcessHeap(), 0, doc);
1554 return E_OUTOFMEMORY;
1557 xmldoc->_private = 0;
1559 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1560 if(!doc->node_unk)
1562 xmlFreeDoc(xmldoc);
1563 HeapFree(GetProcessHeap(), 0, doc);
1564 return E_FAIL;
1567 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1568 if(FAILED(hr))
1570 IUnknown_Release(doc->node_unk);
1571 HeapFree( GetProcessHeap(), 0, doc );
1572 return E_FAIL;
1574 /* The ref on doc->node is actually looped back into this object, so release it */
1575 IXMLDOMNode_Release(doc->node);
1577 *ppObj = &doc->lpVtbl;
1579 TRACE("returning iface %p\n", *ppObj);
1580 return S_OK;
1583 #else
1585 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1587 MESSAGE("This program tried to use a DOMDocument object, but\n"
1588 "libxml2 support was not present at compile time.\n");
1589 return E_NOTIMPL;
1592 #endif