wined3d: Remove superfluous casts of void pointers to other pointer types.
[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     LPWSTR szPattern;
827     HRESULT hr;
828     TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
829
830     szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
831     szPattern[0] = szPattern[1] = '/';
832     lstrcpyW(szPattern + 2, tagName);
833
834     hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
835     HeapFree(GetProcessHeap(), 0, szPattern);
836
837     return hr;
838 }
839
840 static DOMNodeType get_node_type(VARIANT Type)
841 {
842     if(V_VT(&Type) == VT_I4)
843         return V_I4(&Type);
844
845     FIXME("Unsupported variant type %x\n", V_VT(&Type));
846     return 0;
847 }
848
849 static HRESULT WINAPI domdoc_createNode(
850     IXMLDOMDocument2 *iface,
851     VARIANT Type,
852     BSTR name,
853     BSTR namespaceURI,
854     IXMLDOMNode** node )
855 {
856     domdoc *This = impl_from_IXMLDOMDocument2( iface );
857     DOMNodeType node_type;
858     xmlNodePtr xmlnode = NULL;
859     xmlChar *xml_name;
860
861     TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
862
863     node_type = get_node_type(Type);
864     TRACE("node_type %d\n", node_type);
865
866     xml_name = xmlChar_from_wchar((WCHAR*)name);
867
868     switch(node_type)
869     {
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;
875
876     default:
877         FIXME("unhandled node type %d\n", node_type);
878         break;
879     }
880
881     HeapFree(GetProcessHeap(), 0, xml_name);
882
883     if(xmlnode && *node)
884         return S_OK;
885
886     return E_FAIL;
887 }
888
889 static HRESULT WINAPI domdoc_nodeFromID(
890     IXMLDOMDocument2 *iface,
891     BSTR idString,
892     IXMLDOMNode** node )
893 {
894     FIXME("\n");
895     return E_NOTIMPL;
896 }
897
898 static xmlDocPtr doparse( char *ptr, int len )
899 {
900 #ifdef HAVE_XMLREADMEMORY
901     /*
902      * use xmlReadMemory if possible so we can suppress
903      * writing errors to stderr
904      */
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
910 }
911
912 static xmlDocPtr doread( LPWSTR filename )
913 {
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;
921
922     TRACE("%s\n", debugstr_w( filename ));
923
924     if(!PathIsURLW(filename))
925     {
926         WCHAR fullpath[MAX_PATH];
927         DWORD needed = sizeof(url)/sizeof(WCHAR);
928
929         if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
930         {
931             WARN("can't find path\n");
932             return NULL;
933         }
934
935         if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
936         {
937             ERR("can't create url from path\n");
938             return NULL;
939         }
940         filename = url;
941     }
942
943     hr = CreateBindCtx(0, &pbc);
944     if(SUCCEEDED(hr))
945     {
946         hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
947         if(SUCCEEDED(hr))
948         {
949             IMoniker *moniker;
950             hr = CreateURLMoniker(NULL, filename, &moniker);
951             if(SUCCEEDED(hr))
952             {
953                 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
954                 IMoniker_Release(moniker);
955             }
956         }
957         IBindCtx_Release(pbc);
958     }
959     if(FAILED(hr))
960         return NULL;
961
962     hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
963     if(FAILED(hr))
964     {
965         IStream_Release(stream);
966         return NULL;
967     }
968
969     do
970     {
971         IStream_Read(stream, buf, sizeof(buf), &read);
972         hr = IStream_Write(memstream, buf, read, &written);
973     } while(SUCCEEDED(hr) && written != 0 && read != 0);
974
975     if(SUCCEEDED(hr))
976     {
977         HGLOBAL hglobal;
978         hr = GetHGlobalFromStream(memstream, &hglobal);
979         if(SUCCEEDED(hr))
980         {
981             DWORD len = GlobalSize(hglobal);
982             char *ptr = GlobalLock(hglobal);
983             if(len != 0)
984                 xmldoc = doparse( ptr, len );
985             GlobalUnlock(hglobal);
986         }
987     }
988     IStream_Release(memstream);
989     IStream_Release(stream);
990     return xmldoc;
991 }
992
993 static HRESULT WINAPI domdoc_load(
994     IXMLDOMDocument2 *iface,
995     VARIANT xmlSource,
996     VARIANT_BOOL* isSuccessful )
997 {
998     domdoc *This = impl_from_IXMLDOMDocument2( iface );
999     LPWSTR filename = NULL;
1000     xmlDocPtr xmldoc = NULL;
1001     HRESULT hr = S_FALSE;
1002
1003     TRACE("type %d\n", V_VT(&xmlSource) );
1004
1005     *isSuccessful = VARIANT_FALSE;
1006
1007     assert( This->node );
1008
1009     attach_xmlnode(This->node, NULL);
1010
1011     switch( V_VT(&xmlSource) )
1012     {
1013     case VT_BSTR:
1014         filename = V_BSTR(&xmlSource);
1015     }
1016
1017     if ( filename )
1018     {
1019         xmldoc = doread( filename );
1020     
1021         if ( !xmldoc )
1022             This->error = E_FAIL;
1023         else
1024         {
1025             hr = This->error = S_OK;
1026             *isSuccessful = VARIANT_TRUE;
1027         }
1028     }
1029
1030     if(!xmldoc)
1031         xmldoc = xmlNewDoc(NULL);
1032
1033     xmldoc->_private = 0;
1034     attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1035
1036     return hr;
1037 }
1038
1039
1040 static HRESULT WINAPI domdoc_get_readyState(
1041     IXMLDOMDocument2 *iface,
1042     long* value )
1043 {
1044     FIXME("\n");
1045     return E_NOTIMPL;
1046 }
1047
1048
1049 static HRESULT WINAPI domdoc_get_parseError(
1050     IXMLDOMDocument2 *iface,
1051     IXMLDOMParseError** errorObj )
1052 {
1053     BSTR error_string = NULL;
1054     static const WCHAR err[] = {'e','r','r','o','r',0};
1055     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1056
1057     FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1058
1059     if(This->error)
1060         error_string = SysAllocString(err);
1061
1062     *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1063     if(!*errorObj) return E_OUTOFMEMORY;
1064     return S_OK;
1065 }
1066
1067
1068 static HRESULT WINAPI domdoc_get_url(
1069     IXMLDOMDocument2 *iface,
1070     BSTR* urlString )
1071 {
1072     FIXME("\n");
1073     return E_NOTIMPL;
1074 }
1075
1076
1077 static HRESULT WINAPI domdoc_get_async(
1078     IXMLDOMDocument2 *iface,
1079     VARIANT_BOOL* isAsync )
1080 {
1081     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1082
1083     TRACE("%p <- %d\n", isAsync, This->async);
1084     *isAsync = This->async;
1085     return S_OK;
1086 }
1087
1088
1089 static HRESULT WINAPI domdoc_put_async(
1090     IXMLDOMDocument2 *iface,
1091     VARIANT_BOOL isAsync )
1092 {
1093     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1094
1095     TRACE("%d\n", isAsync);
1096     This->async = isAsync;
1097     return S_OK;
1098 }
1099
1100
1101 static HRESULT WINAPI domdoc_abort(
1102     IXMLDOMDocument2 *iface )
1103 {
1104     FIXME("\n");
1105     return E_NOTIMPL;
1106 }
1107
1108
1109 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1110 {
1111     UINT len, blen = SysStringLen( bstr );
1112     LPSTR str;
1113
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;
1122 }
1123
1124 static HRESULT WINAPI domdoc_loadXML(
1125     IXMLDOMDocument2 *iface,
1126     BSTR bstrXML,
1127     VARIANT_BOOL* isSuccessful )
1128 {
1129     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1130     xmlDocPtr xmldoc = NULL;
1131     char *str;
1132     int len;
1133     HRESULT hr = S_FALSE;
1134
1135     TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1136
1137     assert ( This->node );
1138
1139     attach_xmlnode( This->node, NULL );
1140
1141     if ( isSuccessful )
1142     {
1143         *isSuccessful = VARIANT_FALSE;
1144
1145         if ( bstrXML  && bstr_to_utf8( bstrXML, &str, &len ) )
1146         {
1147             xmldoc = doparse( str, len );
1148             HeapFree( GetProcessHeap(), 0, str );
1149             if ( !xmldoc )
1150                 This->error = E_FAIL;
1151             else
1152             {
1153                 hr = This->error = S_OK;
1154                 *isSuccessful = VARIANT_TRUE;
1155             }
1156         }
1157     }
1158     if(!xmldoc)
1159         xmldoc = xmlNewDoc(NULL);
1160
1161     xmldoc->_private = 0;
1162     attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1163
1164     return hr;
1165 }
1166
1167
1168 static HRESULT WINAPI domdoc_save(
1169     IXMLDOMDocument2 *iface,
1170     VARIANT destination )
1171 {
1172     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1173     HANDLE handle;
1174     xmlChar *mem;
1175     int size;
1176     HRESULT ret = S_OK;
1177     DWORD written;
1178
1179     TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1180           V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1181
1182     if(V_VT(&destination) != VT_BSTR)
1183     {
1184         FIXME("Unhandled vt %x\n", V_VT(&destination));
1185         return S_FALSE;
1186     }
1187
1188     handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1189                           NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1190     if( handle == INVALID_HANDLE_VALUE )
1191     {
1192         WARN("failed to create file\n");
1193         return S_FALSE;
1194     }
1195
1196     xmlDocDumpMemory(get_doc(This), &mem, &size);
1197     if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1198     {
1199         WARN("write error\n");
1200         ret = S_FALSE;
1201     }
1202
1203     xmlFree(mem);
1204     CloseHandle(handle);
1205     return ret;
1206 }
1207
1208 static HRESULT WINAPI domdoc_get_validateOnParse(
1209     IXMLDOMDocument2 *iface,
1210     VARIANT_BOOL* isValidating )
1211 {
1212     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1213
1214     TRACE("%p <- %d\n", isValidating, This->validating);
1215     *isValidating = This->validating;
1216     return S_OK;
1217 }
1218
1219
1220 static HRESULT WINAPI domdoc_put_validateOnParse(
1221     IXMLDOMDocument2 *iface,
1222     VARIANT_BOOL isValidating )
1223 {
1224     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1225
1226     TRACE("%d\n", isValidating);
1227     This->validating = isValidating;
1228     return S_OK;
1229 }
1230
1231
1232 static HRESULT WINAPI domdoc_get_resolveExternals(
1233     IXMLDOMDocument2 *iface,
1234     VARIANT_BOOL* isResolving )
1235 {
1236     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1237
1238     TRACE("%p <- %d\n", isResolving, This->resolving);
1239     *isResolving = This->resolving;
1240     return S_OK;
1241 }
1242
1243
1244 static HRESULT WINAPI domdoc_put_resolveExternals(
1245     IXMLDOMDocument2 *iface,
1246     VARIANT_BOOL isResolving )
1247 {
1248     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1249
1250     TRACE("%d\n", isResolving);
1251     This->resolving = isResolving;
1252     return S_OK;
1253 }
1254
1255
1256 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1257     IXMLDOMDocument2 *iface,
1258     VARIANT_BOOL* isPreserving )
1259 {
1260     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1261
1262     TRACE("%p <- %d\n", isPreserving, This->preserving);
1263     *isPreserving = This->preserving;
1264     return S_OK;
1265 }
1266
1267
1268 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1269     IXMLDOMDocument2 *iface,
1270     VARIANT_BOOL isPreserving )
1271 {
1272     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1273
1274     TRACE("%d\n", isPreserving);
1275     This->preserving = isPreserving;
1276     return S_OK;
1277 }
1278
1279
1280 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1281     IXMLDOMDocument2 *iface,
1282     VARIANT readyStateChangeSink )
1283 {
1284     FIXME("\n");
1285     return E_NOTIMPL;
1286 }
1287
1288
1289 static HRESULT WINAPI domdoc_put_onDataAvailable(
1290     IXMLDOMDocument2 *iface,
1291     VARIANT onDataAvailableSink )
1292 {
1293     FIXME("\n");
1294     return E_NOTIMPL;
1295 }
1296
1297 static HRESULT WINAPI domdoc_put_onTransformNode(
1298     IXMLDOMDocument2 *iface,
1299     VARIANT onTransformNodeSink )
1300 {
1301     FIXME("\n");
1302     return E_NOTIMPL;
1303 }
1304
1305 static HRESULT WINAPI domdoc_get_namespaces(
1306     IXMLDOMDocument2* iface,
1307     IXMLDOMSchemaCollection** schemaCollection )
1308 {
1309     FIXME("\n");
1310     return E_NOTIMPL;
1311 }
1312
1313 static HRESULT WINAPI domdoc_get_schemas(
1314     IXMLDOMDocument2* iface,
1315     VARIANT* var1 )
1316 {
1317     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1318     HRESULT hr = S_FALSE;
1319     IXMLDOMSchemaCollection *cur_schema = This->schema;
1320
1321     TRACE("(%p)->(%p)\n", This, var1);
1322
1323     VariantInit(var1); /* Test shows we don't call VariantClear here */
1324     V_VT(var1) = VT_NULL;
1325
1326     if(cur_schema)
1327     {
1328         hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1329         if(SUCCEEDED(hr))
1330             V_VT(var1) = VT_DISPATCH;
1331     }
1332     return hr;
1333 }
1334
1335 static HRESULT WINAPI domdoc_putref_schemas(
1336     IXMLDOMDocument2* iface,
1337     VARIANT var1)
1338 {
1339     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1340     HRESULT hr = E_FAIL;
1341     IXMLDOMSchemaCollection *new_schema = NULL;
1342
1343     FIXME("(%p): semi-stub\n", This);
1344     switch(V_VT(&var1))
1345     {
1346     case VT_UNKNOWN:
1347         hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1348         break;
1349
1350     case VT_DISPATCH:
1351         hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1352         break;
1353
1354     case VT_NULL:
1355     case VT_EMPTY:
1356         hr = S_OK;
1357         break;
1358
1359     default:
1360         WARN("Can't get schema from vt %x\n", V_VT(&var1));
1361     }
1362
1363     if(SUCCEEDED(hr))
1364     {
1365         IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1366         if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1367     }
1368
1369     return hr;
1370 }
1371
1372 static HRESULT WINAPI domdoc_validate(
1373     IXMLDOMDocument2* iface,
1374     IXMLDOMParseError** err)
1375 {
1376     FIXME("\n");
1377     return E_NOTIMPL;
1378 }
1379
1380 static HRESULT WINAPI domdoc_setProperty(
1381     IXMLDOMDocument2* iface,
1382     BSTR p,
1383     VARIANT var)
1384 {
1385     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1386
1387     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1388     {
1389         VARIANT varStr;
1390         HRESULT hr;
1391         BSTR bstr;
1392
1393         V_VT(&varStr) = VT_EMPTY;
1394         if (V_VT(&var) != VT_BSTR)
1395         {
1396             if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1397                 return hr;
1398             bstr = V_BSTR(&varStr);
1399         }
1400         else
1401             bstr = V_BSTR(&var);
1402
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;
1410
1411         VariantClear(&varStr);
1412         return hr;
1413     }
1414
1415     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1416     return E_FAIL;
1417 }
1418
1419 static HRESULT WINAPI domdoc_getProperty(
1420     IXMLDOMDocument2* iface,
1421     BSTR p,
1422     VARIANT* var)
1423 {
1424     domdoc *This = impl_from_IXMLDOMDocument2( iface );
1425
1426     if (var == NULL)
1427         return E_INVALIDARG;
1428     if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1429     {
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;
1436     }
1437
1438     FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1439     return E_FAIL;
1440 }
1441
1442 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1443 {
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
1526 };
1527
1528 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1529 {
1530     domdoc *doc;
1531     HRESULT hr;
1532     xmlDocPtr xmldoc;
1533
1534     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1535
1536     doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1537     if( !doc )
1538         return E_OUTOFMEMORY;
1539
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;
1549
1550     xmldoc = xmlNewDoc(NULL);
1551     if(!xmldoc)
1552     {
1553         HeapFree(GetProcessHeap(), 0, doc);
1554         return E_OUTOFMEMORY;
1555     }
1556
1557     xmldoc->_private = 0;
1558
1559     doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1560     if(!doc->node_unk)
1561     {
1562         xmlFreeDoc(xmldoc);
1563         HeapFree(GetProcessHeap(), 0, doc);
1564         return E_FAIL;
1565     }
1566
1567     hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1568     if(FAILED(hr))
1569     {
1570         IUnknown_Release(doc->node_unk);
1571         HeapFree( GetProcessHeap(), 0, doc );
1572         return E_FAIL;
1573     }
1574     /* The ref on doc->node is actually looped back into this object, so release it */
1575     IXMLDOMNode_Release(doc->node);
1576
1577     *ppObj = &doc->lpVtbl;
1578
1579     TRACE("returning iface %p\n", *ppObj);
1580     return S_OK;
1581 }
1582
1583 #else
1584
1585 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1586 {
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;
1590 }
1591
1592 #endif