quartz: Exclude unused headers.
[wine] / dlls / msxml3 / domdoc.c
1 /*
2  *    DOM Document implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
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"
37
38 #include "wine/debug.h"
39
40 #include "msxml_private.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43
44 #ifdef HAVE_LIBXML2
45
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};
49
50 typedef struct {
51     const struct IBindStatusCallbackVtbl *lpVtbl;
52 } bsc;
53
54 static HRESULT WINAPI bsc_QueryInterface(
55     IBindStatusCallback *iface,
56     REFIID riid,
57     LPVOID *ppobj )
58 {
59     if (IsEqualGUID(riid, &IID_IUnknown) ||
60         IsEqualGUID(riid, &IID_IBindStatusCallback))
61     {
62         IBindStatusCallback_AddRef( iface );
63         *ppobj = iface;
64         return S_OK;
65     }
66
67     FIXME("interface %s not implemented\n", debugstr_guid(riid));
68     return E_NOINTERFACE;
69 }
70
71 static ULONG WINAPI bsc_AddRef(
72     IBindStatusCallback *iface )
73 {
74     return 2;
75 }
76
77 static ULONG WINAPI bsc_Release(
78     IBindStatusCallback *iface )
79 {
80     return 1;
81 }
82
83 static HRESULT WINAPI bsc_OnStartBinding(
84         IBindStatusCallback* iface,
85         DWORD dwReserved,
86         IBinding* pib)
87 {
88     return S_OK;
89 }
90
91 static HRESULT WINAPI bsc_GetPriority(
92         IBindStatusCallback* iface,
93         LONG* pnPriority)
94 {
95     return S_OK;
96 }
97
98 static HRESULT WINAPI bsc_OnLowResource(
99         IBindStatusCallback* iface,
100         DWORD reserved)
101 {
102     return S_OK;
103 }
104
105 static HRESULT WINAPI bsc_OnProgress(
106         IBindStatusCallback* iface,
107         ULONG ulProgress,
108         ULONG ulProgressMax,
109         ULONG ulStatusCode,
110         LPCWSTR szStatusText)
111 {
112     return S_OK;
113 }
114
115 static HRESULT WINAPI bsc_OnStopBinding(
116         IBindStatusCallback* iface,
117         HRESULT hresult,
118         LPCWSTR szError)
119 {
120     return S_OK;
121 }
122
123 static HRESULT WINAPI bsc_GetBindInfo(
124         IBindStatusCallback* iface,
125         DWORD* grfBINDF,
126         BINDINFO* pbindinfo)
127 {
128     *grfBINDF = BINDF_RESYNCHRONIZE;
129     
130     return S_OK;
131 }
132
133 static HRESULT WINAPI bsc_OnDataAvailable(
134         IBindStatusCallback* iface,
135         DWORD grfBSCF,
136         DWORD dwSize,
137         FORMATETC* pformatetc,
138         STGMEDIUM* pstgmed)
139 {
140     return S_OK;
141 }
142
143 static HRESULT WINAPI bsc_OnObjectAvailable(
144         IBindStatusCallback* iface,
145         REFIID riid,
146         IUnknown* punk)
147 {
148     return S_OK;
149 }
150
151 static const struct IBindStatusCallbackVtbl bsc_vtbl =
152 {
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
164 };
165
166 static bsc domdoc_bsc = { &bsc_vtbl };
167
168 typedef struct _domdoc
169 {
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;
182
183 LONG xmldoc_add_ref(xmlDocPtr doc)
184 {
185     LONG ref = InterlockedIncrement((LONG*)&doc->_private);
186     TRACE("%d\n", ref);
187     return ref;
188 }
189
190 LONG xmldoc_release(xmlDocPtr doc)
191 {
192     LONG ref = InterlockedDecrement((LONG*)&doc->_private);
193     TRACE("%d\n", ref);
194     if(ref == 0)
195     {
196         TRACE("freeing docptr %p\n", doc);
197         xmlFreeDoc(doc);
198     }
199
200     return ref;
201 }
202
203 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
204 {
205     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
206 }
207
208 static inline xmlDocPtr get_doc( domdoc *This )
209 {
210     return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
211 }
212
213 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
214 {
215     domdoc *This = impl_from_IXMLDOMDocument2( iface );
216
217     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
218
219     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
220          IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
221          IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
222     {
223         *ppvObject = iface;
224     }
225     else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
226               IsEqualGUID( riid, &IID_IDispatch ) )
227     {
228         return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
229     }
230     else
231     {
232         FIXME("interface %s not implemented\n", debugstr_guid(riid));
233         return E_NOINTERFACE;
234     }
235
236     IXMLDOMDocument_AddRef( iface );
237
238     return S_OK;
239 }
240
241
242 static ULONG WINAPI domdoc_AddRef(
243      IXMLDOMDocument2 *iface )
244 {
245     domdoc *This = impl_from_IXMLDOMDocument2( iface );
246     TRACE("%p\n", This );
247     return InterlockedIncrement( &This->ref );
248 }
249
250
251 static ULONG WINAPI domdoc_Release(
252      IXMLDOMDocument2 *iface )
253 {
254     domdoc *This = impl_from_IXMLDOMDocument2( iface );
255     LONG ref;
256
257     TRACE("%p\n", This );
258
259     ref = InterlockedDecrement( &This->ref );
260     if ( ref == 0 )
261     {
262         IUnknown_Release( This->node_unk );
263         if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
264         HeapFree( GetProcessHeap(), 0, This );
265     }
266
267     return ref;
268 }
269
270 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
271 {
272     FIXME("\n");
273     return E_NOTIMPL;
274 }
275
276 static HRESULT WINAPI domdoc_GetTypeInfo(
277     IXMLDOMDocument2 *iface,
278     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
279 {
280     FIXME("\n");
281     return E_NOTIMPL;
282 }
283
284 static HRESULT WINAPI domdoc_GetIDsOfNames(
285     IXMLDOMDocument2 *iface,
286     REFIID riid,
287     LPOLESTR* rgszNames,
288     UINT cNames,
289     LCID lcid,
290     DISPID* rgDispId)
291 {
292     FIXME("\n");
293     return E_NOTIMPL;
294 }
295
296
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)
307 {
308     FIXME("\n");
309     return E_NOTIMPL;
310 }
311
312
313 static HRESULT WINAPI domdoc_get_nodeName(
314     IXMLDOMDocument2 *iface,
315     BSTR* name )
316 {
317     domdoc *This = impl_from_IXMLDOMDocument2( iface );
318     return IXMLDOMNode_get_nodeName( This->node, name );
319 }
320
321
322 static HRESULT WINAPI domdoc_get_nodeValue(
323     IXMLDOMDocument2 *iface,
324     VARIANT* value )
325 {
326     domdoc *This = impl_from_IXMLDOMDocument2( iface );
327     return IXMLDOMNode_get_nodeValue( This->node, value );
328 }
329
330
331 static HRESULT WINAPI domdoc_put_nodeValue(
332     IXMLDOMDocument2 *iface,
333     VARIANT value)
334 {
335     domdoc *This = impl_from_IXMLDOMDocument2( iface );
336     return IXMLDOMNode_put_nodeValue( This->node, value );
337 }
338
339
340 static HRESULT WINAPI domdoc_get_nodeType(
341     IXMLDOMDocument2 *iface,
342     DOMNodeType* type )
343 {
344     domdoc *This = impl_from_IXMLDOMDocument2( iface );
345     return IXMLDOMNode_get_nodeType( This->node, type );
346 }
347
348
349 static HRESULT WINAPI domdoc_get_parentNode(
350     IXMLDOMDocument2 *iface,
351     IXMLDOMNode** parent )
352 {
353     domdoc *This = impl_from_IXMLDOMDocument2( iface );
354     return IXMLDOMNode_get_parentNode( This->node, parent );
355 }
356
357
358 static HRESULT WINAPI domdoc_get_childNodes(
359     IXMLDOMDocument2 *iface,
360     IXMLDOMNodeList** childList )
361 {
362     domdoc *This = impl_from_IXMLDOMDocument2( iface );
363     return IXMLDOMNode_get_childNodes( This->node, childList );
364 }
365
366
367 static HRESULT WINAPI domdoc_get_firstChild(
368     IXMLDOMDocument2 *iface,
369     IXMLDOMNode** firstChild )
370 {
371     domdoc *This = impl_from_IXMLDOMDocument2( iface );
372     return IXMLDOMNode_get_firstChild( This->node, firstChild );
373 }
374
375
376 static HRESULT WINAPI domdoc_get_lastChild(
377     IXMLDOMDocument2 *iface,
378     IXMLDOMNode** lastChild )
379 {
380     domdoc *This = impl_from_IXMLDOMDocument2( iface );
381     return IXMLDOMNode_get_lastChild( This->node, lastChild );
382 }
383
384
385 static HRESULT WINAPI domdoc_get_previousSibling(
386     IXMLDOMDocument2 *iface,
387     IXMLDOMNode** previousSibling )
388 {
389     domdoc *This = impl_from_IXMLDOMDocument2( iface );
390     return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
391 }
392
393
394 static HRESULT WINAPI domdoc_get_nextSibling(
395     IXMLDOMDocument2 *iface,
396     IXMLDOMNode** nextSibling )
397 {
398     domdoc *This = impl_from_IXMLDOMDocument2( iface );
399     return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
400 }
401
402
403 static HRESULT WINAPI domdoc_get_attributes(
404     IXMLDOMDocument2 *iface,
405     IXMLDOMNamedNodeMap** attributeMap )
406 {
407     domdoc *This = impl_from_IXMLDOMDocument2( iface );
408     return IXMLDOMNode_get_attributes( This->node, attributeMap );
409 }
410
411
412 static HRESULT WINAPI domdoc_insertBefore(
413     IXMLDOMDocument2 *iface,
414     IXMLDOMNode* newChild,
415     VARIANT refChild,
416     IXMLDOMNode** outNewChild )
417 {
418     domdoc *This = impl_from_IXMLDOMDocument2( iface );
419     return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
420 }
421
422
423 static HRESULT WINAPI domdoc_replaceChild(
424     IXMLDOMDocument2 *iface,
425     IXMLDOMNode* newChild,
426     IXMLDOMNode* oldChild,
427     IXMLDOMNode** outOldChild)
428 {
429     domdoc *This = impl_from_IXMLDOMDocument2( iface );
430     return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
431 }
432
433
434 static HRESULT WINAPI domdoc_removeChild(
435     IXMLDOMDocument2 *iface,
436     IXMLDOMNode* childNode,
437     IXMLDOMNode** oldChild)
438 {
439     domdoc *This = impl_from_IXMLDOMDocument2( iface );
440     return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
441 }
442
443
444 static HRESULT WINAPI domdoc_appendChild(
445     IXMLDOMDocument2 *iface,
446     IXMLDOMNode* newChild,
447     IXMLDOMNode** outNewChild)
448 {
449     domdoc *This = impl_from_IXMLDOMDocument2( iface );
450     return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
451 }
452
453
454 static HRESULT WINAPI domdoc_hasChildNodes(
455     IXMLDOMDocument2 *iface,
456     VARIANT_BOOL* hasChild)
457 {
458     domdoc *This = impl_from_IXMLDOMDocument2( iface );
459     return IXMLDOMNode_hasChildNodes( This->node, hasChild );
460 }
461
462
463 static HRESULT WINAPI domdoc_get_ownerDocument(
464     IXMLDOMDocument2 *iface,
465     IXMLDOMDocument** DOMDocument)
466 {
467     domdoc *This = impl_from_IXMLDOMDocument2( iface );
468     return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
469 }
470
471
472 static HRESULT WINAPI domdoc_cloneNode(
473     IXMLDOMDocument2 *iface,
474     VARIANT_BOOL deep,
475     IXMLDOMNode** cloneRoot)
476 {
477     domdoc *This = impl_from_IXMLDOMDocument2( iface );
478     return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
479 }
480
481
482 static HRESULT WINAPI domdoc_get_nodeTypeString(
483     IXMLDOMDocument2 *iface,
484     BSTR* nodeType )
485 {
486     domdoc *This = impl_from_IXMLDOMDocument2( iface );
487     return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
488 }
489
490
491 static HRESULT WINAPI domdoc_get_text(
492     IXMLDOMDocument2 *iface,
493     BSTR* text )
494 {
495     domdoc *This = impl_from_IXMLDOMDocument2( iface );
496     return IXMLDOMNode_get_text( This->node, text );
497 }
498
499
500 static HRESULT WINAPI domdoc_put_text(
501     IXMLDOMDocument2 *iface,
502     BSTR text )
503 {
504     domdoc *This = impl_from_IXMLDOMDocument2( iface );
505     return IXMLDOMNode_put_text( This->node, text );
506 }
507
508
509 static HRESULT WINAPI domdoc_get_specified(
510     IXMLDOMDocument2 *iface,
511     VARIANT_BOOL* isSpecified )
512 {
513     domdoc *This = impl_from_IXMLDOMDocument2( iface );
514     return IXMLDOMNode_get_specified( This->node, isSpecified );
515 }
516
517
518 static HRESULT WINAPI domdoc_get_definition(
519     IXMLDOMDocument2 *iface,
520     IXMLDOMNode** definitionNode )
521 {
522     domdoc *This = impl_from_IXMLDOMDocument2( iface );
523     return IXMLDOMNode_get_definition( This->node, definitionNode );
524 }
525
526
527 static HRESULT WINAPI domdoc_get_nodeTypedValue(
528     IXMLDOMDocument2 *iface,
529     VARIANT* typedValue )
530 {
531     domdoc *This = impl_from_IXMLDOMDocument2( iface );
532     return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
533 }
534
535 static HRESULT WINAPI domdoc_put_nodeTypedValue(
536     IXMLDOMDocument2 *iface,
537     VARIANT typedValue )
538 {
539     domdoc *This = impl_from_IXMLDOMDocument2( iface );
540     return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
541 }
542
543
544 static HRESULT WINAPI domdoc_get_dataType(
545     IXMLDOMDocument2 *iface,
546     VARIANT* dataTypeName )
547 {
548     domdoc *This = impl_from_IXMLDOMDocument2( iface );
549     return IXMLDOMNode_get_dataType( This->node, dataTypeName );
550 }
551
552
553 static HRESULT WINAPI domdoc_put_dataType(
554     IXMLDOMDocument2 *iface,
555     BSTR dataTypeName )
556 {
557     domdoc *This = impl_from_IXMLDOMDocument2( iface );
558     return IXMLDOMNode_put_dataType( This->node, dataTypeName );
559 }
560
561
562 static HRESULT WINAPI domdoc_get_xml(
563     IXMLDOMDocument2 *iface,
564     BSTR* xmlString )
565 {
566     domdoc *This = impl_from_IXMLDOMDocument2( iface );
567     return IXMLDOMNode_get_xml( This->node, xmlString );
568 }
569
570
571 static HRESULT WINAPI domdoc_transformNode(
572     IXMLDOMDocument2 *iface,
573     IXMLDOMNode* styleSheet,
574     BSTR* xmlString )
575 {
576     domdoc *This = impl_from_IXMLDOMDocument2( iface );
577     return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
578 }
579
580
581 static HRESULT WINAPI domdoc_selectNodes(
582     IXMLDOMDocument2 *iface,
583     BSTR queryString,
584     IXMLDOMNodeList** resultList )
585 {
586     domdoc *This = impl_from_IXMLDOMDocument2( iface );
587     return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
588 }
589
590
591 static HRESULT WINAPI domdoc_selectSingleNode(
592     IXMLDOMDocument2 *iface,
593     BSTR queryString,
594     IXMLDOMNode** resultNode )
595 {
596     domdoc *This = impl_from_IXMLDOMDocument2( iface );
597     return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
598 }
599
600
601 static HRESULT WINAPI domdoc_get_parsed(
602     IXMLDOMDocument2 *iface,
603     VARIANT_BOOL* isParsed )
604 {
605     domdoc *This = impl_from_IXMLDOMDocument2( iface );
606     return IXMLDOMNode_get_parsed( This->node, isParsed );
607 }
608
609
610 static HRESULT WINAPI domdoc_get_namespaceURI(
611     IXMLDOMDocument2 *iface,
612     BSTR* namespaceURI )
613 {
614     domdoc *This = impl_from_IXMLDOMDocument2( iface );
615     return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
616 }
617
618
619 static HRESULT WINAPI domdoc_get_prefix(
620     IXMLDOMDocument2 *iface,
621     BSTR* prefixString )
622 {
623     domdoc *This = impl_from_IXMLDOMDocument2( iface );
624     return IXMLDOMNode_get_prefix( This->node, prefixString );
625 }
626
627
628 static HRESULT WINAPI domdoc_get_baseName(
629     IXMLDOMDocument2 *iface,
630     BSTR* nameString )
631 {
632     domdoc *This = impl_from_IXMLDOMDocument2( iface );
633     return IXMLDOMNode_get_baseName( This->node, nameString );
634 }
635
636
637 static HRESULT WINAPI domdoc_transformNodeToObject(
638     IXMLDOMDocument2 *iface,
639     IXMLDOMNode* stylesheet,
640     VARIANT outputObject)
641 {
642     domdoc *This = impl_from_IXMLDOMDocument2( iface );
643     return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
644 }
645
646
647 static HRESULT WINAPI domdoc_get_doctype(
648     IXMLDOMDocument2 *iface,
649     IXMLDOMDocumentType** documentType )
650 {
651     FIXME("\n");
652     return E_NOTIMPL;
653 }
654
655
656 static HRESULT WINAPI domdoc_get_implementation(
657     IXMLDOMDocument2 *iface,
658     IXMLDOMImplementation** impl )
659 {
660     FIXME("\n");
661     return E_NOTIMPL;
662 }
663
664 static HRESULT WINAPI domdoc_get_documentElement(
665     IXMLDOMDocument2 *iface,
666     IXMLDOMElement** DOMElement )
667 {
668     domdoc *This = impl_from_IXMLDOMDocument2( iface );
669     xmlDocPtr xmldoc = NULL;
670     xmlNodePtr root = NULL;
671     IXMLDOMNode *element_node;
672     HRESULT hr;
673
674     TRACE("%p\n", This);
675
676     *DOMElement = NULL;
677
678     xmldoc = get_doc( This );
679
680     root = xmlDocGetRootElement( xmldoc );
681     if ( !root )
682         return S_FALSE;
683
684     element_node = create_node( root );
685     if(!element_node) return S_FALSE;
686
687     hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
688     IXMLDOMNode_Release(element_node);
689
690     return hr;
691 }
692
693
694 static HRESULT WINAPI domdoc_documentElement(
695     IXMLDOMDocument2 *iface,
696     IXMLDOMElement* DOMElement )
697 {
698     FIXME("\n");
699     return E_NOTIMPL;
700 }
701
702
703 static HRESULT WINAPI domdoc_createElement(
704     IXMLDOMDocument2 *iface,
705     BSTR tagname,
706     IXMLDOMElement** element )
707 {
708     xmlNodePtr xmlnode;
709     domdoc *This = impl_from_IXMLDOMDocument2( iface );
710     xmlChar *xml_name;
711     IUnknown *elem_unk;
712     HRESULT hr;
713
714     TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
715
716     xml_name = xmlChar_from_wchar((WCHAR*)tagname);
717     xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
718
719     TRACE("created xmlptr %p\n", xmlnode);
720     elem_unk = create_element(xmlnode, NULL);
721     HeapFree(GetProcessHeap(), 0, xml_name);
722
723     hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
724     IUnknown_Release(elem_unk);
725     TRACE("returning %p\n", *element);
726     return hr;
727 }
728
729
730 static HRESULT WINAPI domdoc_createDocumentFragment(
731     IXMLDOMDocument2 *iface,
732     IXMLDOMDocumentFragment** docFrag )
733 {
734     FIXME("\n");
735     return E_NOTIMPL;
736 }
737
738
739 static HRESULT WINAPI domdoc_createTextNode(
740     IXMLDOMDocument2 *iface,
741     BSTR data,
742     IXMLDOMText** text )
743 {
744     FIXME("\n");
745     return E_NOTIMPL;
746 }
747
748
749 static HRESULT WINAPI domdoc_createComment(
750     IXMLDOMDocument2 *iface,
751     BSTR data,
752     IXMLDOMComment** comment )
753 {
754     FIXME("\n");
755     return E_NOTIMPL;
756 }
757
758
759 static HRESULT WINAPI domdoc_createCDATASection(
760     IXMLDOMDocument2 *iface,
761     BSTR data,
762     IXMLDOMCDATASection** cdata )
763 {
764     FIXME("\n");
765     return E_NOTIMPL;
766 }
767
768
769 static HRESULT WINAPI domdoc_createProcessingInstruction(
770     IXMLDOMDocument2 *iface,
771     BSTR target,
772     BSTR data,
773     IXMLDOMProcessingInstruction** pi )
774 {
775 #ifdef HAVE_XMLNEWDOCPI
776     xmlNodePtr xmlnode;
777     domdoc *This = impl_from_IXMLDOMDocument2( iface );
778     xmlChar *xml_target, *xml_content;
779
780     TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
781
782     xml_target = xmlChar_from_wchar((WCHAR*)target);
783     xml_content = xmlChar_from_wchar((WCHAR*)data);
784
785     xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
786     TRACE("created xmlptr %p\n", xmlnode);
787     *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
788
789     HeapFree(GetProcessHeap(), 0, xml_content);
790     HeapFree(GetProcessHeap(), 0, xml_target);
791
792     return S_OK;
793 #else
794     FIXME("Libxml 2.6.15 or greater required.\n");
795     return E_NOTIMPL;
796 #endif
797 }
798
799
800 static HRESULT WINAPI domdoc_createAttribute(
801     IXMLDOMDocument2 *iface,
802     BSTR name,
803     IXMLDOMAttribute** attribute )
804 {
805     FIXME("\n");
806     return E_NOTIMPL;
807 }
808
809
810 static HRESULT WINAPI domdoc_createEntityReference(
811     IXMLDOMDocument2 *iface,
812     BSTR name,
813     IXMLDOMEntityReference** entityRef )
814 {
815     FIXME("\n");
816     return E_NOTIMPL;
817 }
818
819
820 static HRESULT WINAPI domdoc_getElementsByTagName(
821     IXMLDOMDocument2 *iface,
822     BSTR tagName,
823     IXMLDOMNodeList** resultList )
824 {
825     domdoc *This = impl_from_IXMLDOMDocument2( iface );
826     xmlChar *name;
827     TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
828
829     name = xmlChar_from_wchar((WCHAR*)tagName);
830     *resultList = create_filtered_nodelist((xmlNodePtr)get_doc(This), name, TRUE);
831     HeapFree(GetProcessHeap(), 0, name);
832
833     if(!*resultList) return S_FALSE;
834     return S_OK;
835 }
836
837 static DOMNodeType get_node_type(VARIANT Type)
838 {
839     if(V_VT(&Type) == VT_I4)
840         return V_I4(&Type);
841
842     FIXME("Unsupported variant type %x\n", V_VT(&Type));
843     return 0;
844 }
845
846 static HRESULT WINAPI domdoc_createNode(
847     IXMLDOMDocument2 *iface,
848     VARIANT Type,
849     BSTR name,
850     BSTR namespaceURI,
851     IXMLDOMNode** node )
852 {
853     domdoc *This = impl_from_IXMLDOMDocument2( iface );
854     DOMNodeType node_type;
855     xmlNodePtr xmlnode = NULL;
856     xmlChar *xml_name;
857
858     TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
859
860     node_type = get_node_type(Type);
861     TRACE("node_type %d\n", node_type);
862
863     xml_name = xmlChar_from_wchar((WCHAR*)name);
864
865     switch(node_type)
866     {
867     case NODE_ELEMENT:
868         xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
869         *node = create_node(xmlnode);
870         TRACE("created %p\n", xmlnode);
871         break;
872
873     default:
874         FIXME("unhandled node type %d\n", node_type);
875         break;
876     }
877
878     HeapFree(GetProcessHeap(), 0, xml_name);
879
880     if(xmlnode && *node)
881         return S_OK;
882
883     return E_FAIL;
884 }
885
886 static HRESULT WINAPI domdoc_nodeFromID(
887     IXMLDOMDocument2 *iface,
888     BSTR idString,
889     IXMLDOMNode** node )
890 {
891     FIXME("\n");
892     return E_NOTIMPL;
893 }
894
895 static xmlDocPtr doparse( char *ptr, int len )
896 {
897 #ifdef HAVE_XMLREADMEMORY
898     /*
899      * use xmlReadMemory if possible so we can suppress
900      * writing errors to stderr
901      */
902     return xmlReadMemory( ptr, len, NULL, NULL,
903                           XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
904 #else
905     return xmlParseMemory( ptr, len );
906 #endif
907 }
908
909 static xmlDocPtr doread( LPWSTR filename )
910 {
911     xmlDocPtr xmldoc = NULL;
912     HRESULT hr;
913     IBindCtx *pbc;
914     IStream *stream, *memstream;
915     WCHAR url[INTERNET_MAX_URL_LENGTH];
916     BYTE buf[4096];
917     DWORD read, written;
918
919     TRACE("%s\n", debugstr_w( filename ));
920
921     if(!PathIsURLW(filename))
922     {
923         WCHAR fullpath[MAX_PATH];
924         DWORD needed = sizeof(url)/sizeof(WCHAR);
925
926         if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
927         {
928             WARN("can't find path\n");
929             return NULL;
930         }
931
932         if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
933         {
934             ERR("can't create url from path\n");
935             return NULL;
936         }
937         filename = url;
938     }
939
940     hr = CreateBindCtx(0, &pbc);
941     if(SUCCEEDED(hr))
942     {
943         hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
944         if(SUCCEEDED(hr))
945         {
946             IMoniker *moniker;
947             hr = CreateURLMoniker(NULL, filename, &moniker);
948             if(SUCCEEDED(hr))
949             {
950                 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
951                 IMoniker_Release(moniker);
952             }
953         }
954         IBindCtx_Release(pbc);
955     }
956     if(FAILED(hr))
957         return NULL;
958
959     hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
960     if(FAILED(hr))
961     {
962         IStream_Release(stream);
963         return NULL;
964     }
965
966     do
967     {
968         IStream_Read(stream, buf, sizeof(buf), &read);
969         hr = IStream_Write(memstream, buf, read, &written);
970     } while(SUCCEEDED(hr) && written != 0 && read != 0);
971
972     if(SUCCEEDED(hr))
973     {
974         HGLOBAL hglobal;
975         hr = GetHGlobalFromStream(memstream, &hglobal);
976         if(SUCCEEDED(hr))
977         {
978             DWORD len = GlobalSize(hglobal);
979             char *ptr = GlobalLock(hglobal);
980             if(len != 0)
981                 xmldoc = doparse( ptr, len );
982             GlobalUnlock(hglobal);
983         }
984     }
985     IStream_Release(memstream);
986     IStream_Release(stream);
987     return xmldoc;
988 }
989
990 static HRESULT WINAPI domdoc_load(
991     IXMLDOMDocument2 *iface,
992     VARIANT xmlSource,
993     VARIANT_BOOL* isSuccessful )
994 {
995     domdoc *This = impl_from_IXMLDOMDocument2( iface );
996     LPWSTR filename = NULL;
997     xmlDocPtr xmldoc = NULL;
998     HRESULT hr = S_FALSE;
999
1000     TRACE("type %d\n", V_VT(&xmlSource) );
1001
1002     *isSuccessful = VARIANT_FALSE;
1003
1004     assert( This->node );
1005
1006     attach_xmlnode(This->node, NULL);
1007
1008     switch( V_VT(&xmlSource) )
1009     {
1010     case VT_BSTR:
1011         filename = V_BSTR(&xmlSource);
1012     }
1013
1014     if ( filename )
1015     {
1016         xmldoc = doread( filename );
1017     
1018         if ( !xmldoc )
1019             This->error = E_FAIL;
1020         else
1021         {
1022             hr = This->error = S_OK;
1023             *isSuccessful = VARIANT_TRUE;
1024         }
1025     }
1026
1027     if(!xmldoc)
1028         xmldoc = xmlNewDoc(NULL);
1029
1030     xmldoc->_private = 0;
1031     attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1032
1033     return hr;
1034 }
1035
1036
1037 static HRESULT WINAPI domdoc_get_readyState(
1038     IXMLDOMDocument2 *iface,
1039     long* value )
1040 {
1041     FIXME("\n");
1042     return E_NOTIMPL;
1043 }
1044
1045
1046 static HRESULT WINAPI domdoc_get_parseError(
1047     IXMLDOMDocument2 *iface,
1048     IXMLDOMParseError** errorObj )
1049 {
1050     BSTR error_string = NULL;
1051     static const WCHAR err[] = {'e','r','r','o','r',0};
1052     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1053
1054     FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1055
1056     if(This->error)
1057         error_string = SysAllocString(err);
1058
1059     *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1060     if(!*errorObj) return E_OUTOFMEMORY;
1061     return S_OK;
1062 }
1063
1064
1065 static HRESULT WINAPI domdoc_get_url(
1066     IXMLDOMDocument2 *iface,
1067     BSTR* urlString )
1068 {
1069     FIXME("\n");
1070     return E_NOTIMPL;
1071 }
1072
1073
1074 static HRESULT WINAPI domdoc_get_async(
1075     IXMLDOMDocument2 *iface,
1076     VARIANT_BOOL* isAsync )
1077 {
1078     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1079
1080     TRACE("%p <- %d\n", isAsync, This->async);
1081     *isAsync = This->async;
1082     return S_OK;
1083 }
1084
1085
1086 static HRESULT WINAPI domdoc_put_async(
1087     IXMLDOMDocument2 *iface,
1088     VARIANT_BOOL isAsync )
1089 {
1090     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1091
1092     TRACE("%d\n", isAsync);
1093     This->async = isAsync;
1094     return S_OK;
1095 }
1096
1097
1098 static HRESULT WINAPI domdoc_abort(
1099     IXMLDOMDocument2 *iface )
1100 {
1101     FIXME("\n");
1102     return E_NOTIMPL;
1103 }
1104
1105
1106 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1107 {
1108     UINT len, blen = SysStringLen( bstr );
1109     LPSTR str;
1110
1111     len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1112     str = HeapAlloc( GetProcessHeap(), 0, len );
1113     if ( !str )
1114         return FALSE;
1115     WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1116     *plen = len;
1117     *pstr = str;
1118     return TRUE;
1119 }
1120
1121 static HRESULT WINAPI domdoc_loadXML(
1122     IXMLDOMDocument2 *iface,
1123     BSTR bstrXML,
1124     VARIANT_BOOL* isSuccessful )
1125 {
1126     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1127     xmlDocPtr xmldoc = NULL;
1128     char *str;
1129     int len;
1130     HRESULT hr = S_FALSE;
1131
1132     TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1133
1134     assert ( This->node );
1135
1136     attach_xmlnode( This->node, NULL );
1137
1138     if ( isSuccessful )
1139     {
1140         *isSuccessful = VARIANT_FALSE;
1141
1142         if ( bstrXML  && bstr_to_utf8( bstrXML, &str, &len ) )
1143         {
1144             xmldoc = doparse( str, len );
1145             HeapFree( GetProcessHeap(), 0, str );
1146             if ( !xmldoc )
1147                 This->error = E_FAIL;
1148             else
1149             {
1150                 hr = This->error = S_OK;
1151                 *isSuccessful = VARIANT_TRUE;
1152             }
1153         }
1154     }
1155     if(!xmldoc)
1156         xmldoc = xmlNewDoc(NULL);
1157
1158     xmldoc->_private = 0;
1159     attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1160
1161     return hr;
1162 }
1163
1164
1165 static HRESULT WINAPI domdoc_save(
1166     IXMLDOMDocument2 *iface,
1167     VARIANT destination )
1168 {
1169     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1170     HANDLE handle;
1171     xmlChar *mem;
1172     int size;
1173     HRESULT ret = S_OK;
1174     DWORD written;
1175
1176     TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1177           V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1178
1179     if(V_VT(&destination) != VT_BSTR)
1180     {
1181         FIXME("Unhandled vt %x\n", V_VT(&destination));
1182         return S_FALSE;
1183     }
1184
1185     handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1186                           NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1187     if( handle == INVALID_HANDLE_VALUE )
1188     {
1189         WARN("failed to create file\n");
1190         return S_FALSE;
1191     }
1192
1193     xmlDocDumpMemory(get_doc(This), &mem, &size);
1194     if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1195     {
1196         WARN("write error\n");
1197         ret = S_FALSE;
1198     }
1199
1200     xmlFree(mem);
1201     CloseHandle(handle);
1202     return ret;
1203 }
1204
1205 static HRESULT WINAPI domdoc_get_validateOnParse(
1206     IXMLDOMDocument2 *iface,
1207     VARIANT_BOOL* isValidating )
1208 {
1209     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1210
1211     TRACE("%p <- %d\n", isValidating, This->validating);
1212     *isValidating = This->validating;
1213     return S_OK;
1214 }
1215
1216
1217 static HRESULT WINAPI domdoc_put_validateOnParse(
1218     IXMLDOMDocument2 *iface,
1219     VARIANT_BOOL isValidating )
1220 {
1221     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1222
1223     TRACE("%d\n", isValidating);
1224     This->validating = isValidating;
1225     return S_OK;
1226 }
1227
1228
1229 static HRESULT WINAPI domdoc_get_resolveExternals(
1230     IXMLDOMDocument2 *iface,
1231     VARIANT_BOOL* isResolving )
1232 {
1233     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1234
1235     TRACE("%p <- %d\n", isResolving, This->resolving);
1236     *isResolving = This->resolving;
1237     return S_OK;
1238 }
1239
1240
1241 static HRESULT WINAPI domdoc_put_resolveExternals(
1242     IXMLDOMDocument2 *iface,
1243     VARIANT_BOOL isResolving )
1244 {
1245     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1246
1247     TRACE("%d\n", isResolving);
1248     This->resolving = isResolving;
1249     return S_OK;
1250 }
1251
1252
1253 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1254     IXMLDOMDocument2 *iface,
1255     VARIANT_BOOL* isPreserving )
1256 {
1257     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1258
1259     TRACE("%p <- %d\n", isPreserving, This->preserving);
1260     *isPreserving = This->preserving;
1261     return S_OK;
1262 }
1263
1264
1265 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1266     IXMLDOMDocument2 *iface,
1267     VARIANT_BOOL isPreserving )
1268 {
1269     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1270
1271     TRACE("%d\n", isPreserving);
1272     This->preserving = isPreserving;
1273     return S_OK;
1274 }
1275
1276
1277 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1278     IXMLDOMDocument2 *iface,
1279     VARIANT readyStateChangeSink )
1280 {
1281     FIXME("\n");
1282     return E_NOTIMPL;
1283 }
1284
1285
1286 static HRESULT WINAPI domdoc_put_onDataAvailable(
1287     IXMLDOMDocument2 *iface,
1288     VARIANT onDataAvailableSink )
1289 {
1290     FIXME("\n");
1291     return E_NOTIMPL;
1292 }
1293
1294 static HRESULT WINAPI domdoc_put_onTransformNode(
1295     IXMLDOMDocument2 *iface,
1296     VARIANT onTransformNodeSink )
1297 {
1298     FIXME("\n");
1299     return E_NOTIMPL;
1300 }
1301
1302 static HRESULT WINAPI domdoc_get_namespaces(
1303     IXMLDOMDocument2* iface,
1304     IXMLDOMSchemaCollection** schemaCollection )
1305 {
1306     FIXME("\n");
1307     return E_NOTIMPL;
1308 }
1309
1310 static HRESULT WINAPI domdoc_get_schemas(
1311     IXMLDOMDocument2* iface,
1312     VARIANT* var1 )
1313 {
1314     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1315     HRESULT hr = S_FALSE;
1316     IXMLDOMSchemaCollection *cur_schema = This->schema;
1317
1318     TRACE("(%p)->(%p)\n", This, var1);
1319
1320     VariantInit(var1); /* Test shows we don't call VariantClear here */
1321     V_VT(var1) = VT_NULL;
1322
1323     if(cur_schema)
1324     {
1325         hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1326         if(SUCCEEDED(hr))
1327             V_VT(var1) = VT_DISPATCH;
1328     }
1329     return hr;
1330 }
1331
1332 static HRESULT WINAPI domdoc_putref_schemas(
1333     IXMLDOMDocument2* iface,
1334     VARIANT var1)
1335 {
1336     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1337     HRESULT hr = E_FAIL;
1338     IXMLDOMSchemaCollection *new_schema = NULL;
1339
1340     FIXME("(%p): semi-stub\n", This);
1341     switch(V_VT(&var1))
1342     {
1343     case VT_UNKNOWN:
1344         hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1345         break;
1346
1347     case VT_DISPATCH:
1348         hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1349         break;
1350
1351     case VT_NULL:
1352     case VT_EMPTY:
1353         hr = S_OK;
1354         break;
1355
1356     default:
1357         WARN("Can't get schema from vt %x\n", V_VT(&var1));
1358     }
1359
1360     if(SUCCEEDED(hr))
1361     {
1362         IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1363         if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1364     }
1365
1366     return hr;
1367 }
1368
1369 static HRESULT WINAPI domdoc_validate(
1370     IXMLDOMDocument2* iface,
1371     IXMLDOMParseError** err)
1372 {
1373     FIXME("\n");
1374     return E_NOTIMPL;
1375 }
1376
1377 static HRESULT WINAPI domdoc_setProperty(
1378     IXMLDOMDocument2* iface,
1379     BSTR p,
1380     VARIANT var)
1381 {
1382     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1383
1384     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1385     {
1386         VARIANT varStr;
1387         HRESULT hr;
1388         BSTR bstr;
1389
1390         V_VT(&varStr) = VT_EMPTY;
1391         if (V_VT(&var) != VT_BSTR)
1392         {
1393             if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1394                 return hr;
1395             bstr = V_BSTR(&varStr);
1396         }
1397         else
1398             bstr = V_BSTR(&var);
1399
1400         hr = S_OK;
1401         if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1402             This->bUseXPath = TRUE;
1403         else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1404             This->bUseXPath = FALSE;
1405         else
1406             hr = E_FAIL;
1407
1408         VariantClear(&varStr);
1409         return hr;
1410     }
1411
1412     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1413     return E_FAIL;
1414 }
1415
1416 static HRESULT WINAPI domdoc_getProperty(
1417     IXMLDOMDocument2* iface,
1418     BSTR p,
1419     VARIANT* var)
1420 {
1421     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1422
1423     if (var == NULL)
1424         return E_INVALIDARG;
1425     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1426     {
1427         V_VT(var) = VT_BSTR;
1428         if (This->bUseXPath)
1429             V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1430         else
1431             V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1432         return S_OK;
1433     }
1434
1435     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1436     return E_FAIL;
1437 }
1438
1439 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1440 {
1441     domdoc_QueryInterface,
1442     domdoc_AddRef,
1443     domdoc_Release,
1444     domdoc_GetTypeInfoCount,
1445     domdoc_GetTypeInfo,
1446     domdoc_GetIDsOfNames,
1447     domdoc_Invoke,
1448     domdoc_get_nodeName,
1449     domdoc_get_nodeValue,
1450     domdoc_put_nodeValue,
1451     domdoc_get_nodeType,
1452     domdoc_get_parentNode,
1453     domdoc_get_childNodes,
1454     domdoc_get_firstChild,
1455     domdoc_get_lastChild,
1456     domdoc_get_previousSibling,
1457     domdoc_get_nextSibling,
1458     domdoc_get_attributes,
1459     domdoc_insertBefore,
1460     domdoc_replaceChild,
1461     domdoc_removeChild,
1462     domdoc_appendChild,
1463     domdoc_hasChildNodes,
1464     domdoc_get_ownerDocument,
1465     domdoc_cloneNode,
1466     domdoc_get_nodeTypeString,
1467     domdoc_get_text,
1468     domdoc_put_text,
1469     domdoc_get_specified,
1470     domdoc_get_definition,
1471     domdoc_get_nodeTypedValue,
1472     domdoc_put_nodeTypedValue,
1473     domdoc_get_dataType,
1474     domdoc_put_dataType,
1475     domdoc_get_xml,
1476     domdoc_transformNode,
1477     domdoc_selectNodes,
1478     domdoc_selectSingleNode,
1479     domdoc_get_parsed,
1480     domdoc_get_namespaceURI,
1481     domdoc_get_prefix,
1482     domdoc_get_baseName,
1483     domdoc_transformNodeToObject,
1484     domdoc_get_doctype,
1485     domdoc_get_implementation,
1486     domdoc_get_documentElement,
1487     domdoc_documentElement,
1488     domdoc_createElement,
1489     domdoc_createDocumentFragment,
1490     domdoc_createTextNode,
1491     domdoc_createComment,
1492     domdoc_createCDATASection,
1493     domdoc_createProcessingInstruction,
1494     domdoc_createAttribute,
1495     domdoc_createEntityReference,
1496     domdoc_getElementsByTagName,
1497     domdoc_createNode,
1498     domdoc_nodeFromID,
1499     domdoc_load,
1500     domdoc_get_readyState,
1501     domdoc_get_parseError,
1502     domdoc_get_url,
1503     domdoc_get_async,
1504     domdoc_put_async,
1505     domdoc_abort,
1506     domdoc_loadXML,
1507     domdoc_save,
1508     domdoc_get_validateOnParse,
1509     domdoc_put_validateOnParse,
1510     domdoc_get_resolveExternals,
1511     domdoc_put_resolveExternals,
1512     domdoc_get_preserveWhiteSpace,
1513     domdoc_put_preserveWhiteSpace,
1514     domdoc_put_onReadyStateChange,
1515     domdoc_put_onDataAvailable,
1516     domdoc_put_onTransformNode,
1517     domdoc_get_namespaces,
1518     domdoc_get_schemas,
1519     domdoc_putref_schemas,
1520     domdoc_validate,
1521     domdoc_setProperty,
1522     domdoc_getProperty
1523 };
1524
1525 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1526 {
1527     domdoc *doc;
1528     HRESULT hr;
1529     xmlDocPtr xmldoc;
1530
1531     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1532
1533     doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1534     if( !doc )
1535         return E_OUTOFMEMORY;
1536
1537     doc->lpVtbl = &domdoc_vtbl;
1538     doc->ref = 1;
1539     doc->async = 0;
1540     doc->validating = 0;
1541     doc->resolving = 0;
1542     doc->preserving = 0;
1543     doc->bUseXPath = FALSE;
1544     doc->error = S_OK;
1545     doc->schema = NULL;
1546
1547     xmldoc = xmlNewDoc(NULL);
1548     if(!xmldoc)
1549     {
1550         HeapFree(GetProcessHeap(), 0, doc);
1551         return E_OUTOFMEMORY;
1552     }
1553
1554     xmldoc->_private = 0;
1555
1556     doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1557     if(!doc->node_unk)
1558     {
1559         xmlFreeDoc(xmldoc);
1560         HeapFree(GetProcessHeap(), 0, doc);
1561         return E_FAIL;
1562     }
1563
1564     hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1565     if(FAILED(hr))
1566     {
1567         IUnknown_Release(doc->node_unk);
1568         HeapFree( GetProcessHeap(), 0, doc );
1569         return E_FAIL;
1570     }
1571     /* The ref on doc->node is actually looped back into this object, so release it */
1572     IXMLDOMNode_Release(doc->node);
1573
1574     *ppObj = &doc->lpVtbl;
1575
1576     TRACE("returning iface %p\n", *ppObj);
1577     return S_OK;
1578 }
1579
1580 #else
1581
1582 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1583 {
1584     MESSAGE("This program tried to use a DOMDocument object, but\n"
1585             "libxml2 support was not present at compile time.\n");
1586     return E_NOTIMPL;
1587 }
1588
1589 #endif