Use a single function to create all IXMLDOMNode implementations.
[wine] / dlls / msxml3 / domdoc.c
1 /*
2  *    DOM Document implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
6  * iface 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  * iface 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "ocidl.h"
32 #include "msxml.h"
33 #include "xmldom.h"
34
35 #include "wine/debug.h"
36
37 #include "msxml_private.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
40
41 #ifdef HAVE_LIBXML2
42
43 typedef struct _domdoc
44 {
45     const struct IXMLDOMDocumentVtbl *lpVtbl;
46     LONG ref;
47     VARIANT_BOOL async;
48     IXMLDOMNode *node;
49 } domdoc;
50
51 static inline domdoc *impl_from_IXMLDOMDocument( IXMLDOMDocument *iface )
52 {
53     return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
54 }
55
56 static inline xmlDocPtr get_doc( domdoc *This )
57 {
58     return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
59 }
60
61 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument *iface, REFIID riid, void** ppvObject )
62 {
63     domdoc *This = impl_from_IXMLDOMDocument( iface );
64
65     TRACE("%p %p %p\n", This, debugstr_guid( riid ), ppvObject );
66
67     if ( IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
68          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
69          IsEqualGUID( riid, &IID_IDispatch ) ||
70          IsEqualGUID( riid, &IID_IUnknown ) )
71     {
72         *ppvObject = iface;
73     }
74     else
75         return E_NOINTERFACE;
76
77     IXMLDOMDocument_AddRef( iface );
78
79     return S_OK;
80 }
81
82
83 static ULONG WINAPI domdoc_AddRef(
84      IXMLDOMDocument *iface )
85 {
86     domdoc *This = impl_from_IXMLDOMDocument( iface );
87     TRACE("%p\n", This );
88     return InterlockedIncrement( &This->ref );
89 }
90
91
92 static ULONG WINAPI domdoc_Release(
93      IXMLDOMDocument *iface )
94 {
95     domdoc *This = impl_from_IXMLDOMDocument( iface );
96     LONG ref;
97
98     TRACE("%p\n", This );
99
100     ref = InterlockedDecrement( &This->ref );
101     if ( ref == 0 )
102     {
103         IXMLDOMElement_Release( This->node );
104         HeapFree( GetProcessHeap(), 0, This );
105     }
106
107     return ref;
108 }
109
110 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument *iface, UINT* pctinfo )
111 {
112     FIXME("\n");
113     return E_NOTIMPL;
114 }
115
116 static HRESULT WINAPI domdoc_GetTypeInfo(
117     IXMLDOMDocument *iface,
118     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
119 {
120     FIXME("\n");
121     return E_NOTIMPL;
122 }
123
124 static HRESULT WINAPI domdoc_GetIDsOfNames(
125     IXMLDOMDocument *iface,
126     REFIID riid,
127     LPOLESTR* rgszNames,
128     UINT cNames,
129     LCID lcid,
130     DISPID* rgDispId)
131 {
132     FIXME("\n");
133     return E_NOTIMPL;
134 }
135
136
137 static HRESULT WINAPI domdoc_Invoke(
138     IXMLDOMDocument *iface,
139     DISPID dispIdMember,
140     REFIID riid,
141     LCID lcid,
142     WORD wFlags,
143     DISPPARAMS* pDispParams,
144     VARIANT* pVarResult,
145     EXCEPINFO* pExcepInfo,
146     UINT* puArgErr)
147 {
148     FIXME("\n");
149     return E_NOTIMPL;
150 }
151
152
153 static HRESULT WINAPI domdoc_get_nodeName(
154     IXMLDOMDocument *iface,
155     BSTR* name )
156 {
157     FIXME("\n");
158     return E_NOTIMPL;
159 }
160
161
162 static HRESULT WINAPI domdoc_get_nodeValue(
163     IXMLDOMDocument *iface,
164     VARIANT* value )
165 {
166     FIXME("\n");
167     return E_NOTIMPL;
168 }
169
170
171 static HRESULT WINAPI domdoc_put_nodeValue(
172     IXMLDOMDocument *iface,
173     VARIANT value)
174 {
175     FIXME("\n");
176     return E_NOTIMPL;
177 }
178
179
180 static HRESULT WINAPI domdoc_get_nodeType(
181     IXMLDOMDocument *iface,
182     DOMNodeType* type )
183 {
184     FIXME("\n");
185     return E_NOTIMPL;
186 }
187
188
189 static HRESULT WINAPI domdoc_get_parentNode(
190     IXMLDOMDocument *iface,
191     IXMLDOMNode** parent )
192 {
193     FIXME("\n");
194     return E_NOTIMPL;
195 }
196
197
198 static HRESULT WINAPI domdoc_get_childNodes(
199     IXMLDOMDocument *iface,
200     IXMLDOMNodeList** childList )
201 {
202     FIXME("\n");
203     return E_NOTIMPL;
204 }
205
206
207 static HRESULT WINAPI domdoc_get_firstChild(
208     IXMLDOMDocument *iface,
209     IXMLDOMNode** firstChild )
210 {
211     FIXME("\n");
212     return E_NOTIMPL;
213 }
214
215
216 static HRESULT WINAPI domdoc_get_lastChild(
217     IXMLDOMDocument *iface,
218     IXMLDOMNode** lastChild )
219 {
220     FIXME("\n");
221     return E_NOTIMPL;
222 }
223
224
225 static HRESULT WINAPI domdoc_get_previousSibling(
226     IXMLDOMDocument *iface,
227     IXMLDOMNode** previousSibling )
228 {
229     FIXME("\n");
230     return E_NOTIMPL;
231 }
232
233
234 static HRESULT WINAPI domdoc_get_nextSibling(
235     IXMLDOMDocument *iface,
236     IXMLDOMNode** nextSibling )
237 {
238     FIXME("\n");
239     return E_NOTIMPL;
240 }
241
242
243 static HRESULT WINAPI domdoc_get_attributes(
244     IXMLDOMDocument *iface,
245     IXMLDOMNamedNodeMap** attributeMap )
246 {
247     FIXME("\n");
248     return E_NOTIMPL;
249 }
250
251
252 static HRESULT WINAPI domdoc_insertBefore(
253     IXMLDOMDocument *iface,
254     IXMLDOMNode* newChild,
255     VARIANT refChild,
256     IXMLDOMNode** outNewChild )
257 {
258     FIXME("\n");
259     return E_NOTIMPL;
260 }
261
262
263 static HRESULT WINAPI domdoc_replaceChild(
264     IXMLDOMDocument *iface,
265     IXMLDOMNode* newChild,
266     IXMLDOMNode* oldChild,
267     IXMLDOMNode** outOldChild)
268 {
269     FIXME("\n");
270     return E_NOTIMPL;
271 }
272
273
274 static HRESULT WINAPI domdoc_removeChild(
275     IXMLDOMDocument *iface,
276     IXMLDOMNode* childNode,
277     IXMLDOMNode** oldChild)
278 {
279     FIXME("\n");
280     return E_NOTIMPL;
281 }
282
283
284 static HRESULT WINAPI domdoc_appendChild(
285     IXMLDOMDocument *iface,
286     IXMLDOMNode* newChild,
287     IXMLDOMNode** outNewChild)
288 {
289     FIXME("\n");
290     return E_NOTIMPL;
291 }
292
293
294 static HRESULT WINAPI domdoc_hasChildNodes(
295     IXMLDOMDocument *iface,
296     VARIANT_BOOL* hasChild)
297 {
298     FIXME("\n");
299     return E_NOTIMPL;
300 }
301
302
303 static HRESULT WINAPI domdoc_get_ownerDocument(
304     IXMLDOMDocument *iface,
305     IXMLDOMDocument** DOMDocument)
306 {
307     FIXME("\n");
308     return E_NOTIMPL;
309 }
310
311
312 static HRESULT WINAPI domdoc_cloneNode(
313     IXMLDOMDocument *iface,
314     VARIANT_BOOL deep,
315     IXMLDOMNode** cloneRoot)
316 {
317     FIXME("\n");
318     return E_NOTIMPL;
319 }
320
321
322 static HRESULT WINAPI domdoc_get_nodeTypeString(
323     IXMLDOMDocument *iface,
324     BSTR* nodeType )
325 {
326     FIXME("\n");
327     return E_NOTIMPL;
328 }
329
330
331 static HRESULT WINAPI domdoc_get_text(
332     IXMLDOMDocument *iface,
333     BSTR* text )
334 {
335     FIXME("\n");
336     return E_NOTIMPL;
337 }
338
339
340 static HRESULT WINAPI domdoc_put_text(
341     IXMLDOMDocument *iface,
342     BSTR text )
343 {
344     FIXME("\n");
345     return E_NOTIMPL;
346 }
347
348
349 static HRESULT WINAPI domdoc_get_specified(
350     IXMLDOMDocument *iface,
351     VARIANT_BOOL* isSpecified )
352 {
353     FIXME("\n");
354     return E_NOTIMPL;
355 }
356
357
358 static HRESULT WINAPI domdoc_get_definition(
359     IXMLDOMDocument *iface,
360     IXMLDOMNode** definitionNode )
361 {
362     FIXME("\n");
363     return E_NOTIMPL;
364 }
365
366
367 static HRESULT WINAPI domdoc_get_nodeTypedValue(
368     IXMLDOMDocument *iface,
369     VARIANT* typedValue )
370 {
371     FIXME("\n");
372     return E_NOTIMPL;
373 }
374
375 static HRESULT WINAPI domdoc_put_nodeTypedValue(
376     IXMLDOMDocument *iface,
377     VARIANT typedValue )
378 {
379     FIXME("\n");
380     return E_NOTIMPL;
381 }
382
383
384 static HRESULT WINAPI domdoc_get_dataType(
385     IXMLDOMDocument *iface,
386     VARIANT* dataTypeName )
387 {
388     FIXME("\n");
389     return E_NOTIMPL;
390 }
391
392
393 static HRESULT WINAPI domdoc_put_dataType(
394     IXMLDOMDocument *iface,
395     BSTR dataTypeName )
396 {
397     FIXME("\n");
398     return E_NOTIMPL;
399 }
400
401
402 static HRESULT WINAPI domdoc_get_xml(
403     IXMLDOMDocument *iface,
404     BSTR* xmlString )
405 {
406     FIXME("\n");
407     return E_NOTIMPL;
408 }
409
410
411 static HRESULT WINAPI domdoc_transformNode(
412     IXMLDOMDocument *iface,
413     IXMLDOMNode* styleSheet,
414     BSTR* xmlString )
415 {
416     FIXME("\n");
417     return E_NOTIMPL;
418 }
419
420
421 static HRESULT WINAPI domdoc_selectNodes(
422     IXMLDOMDocument *iface,
423     BSTR queryString,
424     IXMLDOMNodeList** resultList )
425 {
426     FIXME("\n");
427     return E_NOTIMPL;
428 }
429
430
431 static HRESULT WINAPI domdoc_selectSingleNode(
432     IXMLDOMDocument *iface,
433     BSTR queryString,
434     IXMLDOMNode** resultNode )
435 {
436     FIXME("\n");
437     return E_NOTIMPL;
438 }
439
440
441 static HRESULT WINAPI domdoc_get_parsed(
442     IXMLDOMDocument *iface,
443     VARIANT_BOOL* isParsed )
444 {
445     FIXME("\n");
446     return E_NOTIMPL;
447 }
448
449
450 static HRESULT WINAPI domdoc_get_namespaceURI(
451     IXMLDOMDocument *iface,
452     BSTR* namespaceURI )
453 {
454     FIXME("\n");
455     return E_NOTIMPL;
456 }
457
458
459 static HRESULT WINAPI domdoc_get_prefix(
460     IXMLDOMDocument *iface,
461     BSTR* prefixString )
462 {
463     FIXME("\n");
464     return E_NOTIMPL;
465 }
466
467
468 static HRESULT WINAPI domdoc_get_baseName(
469     IXMLDOMDocument *iface,
470     BSTR* nameString )
471 {
472     FIXME("\n");
473     return E_NOTIMPL;
474 }
475
476
477 static HRESULT WINAPI domdoc_transformNodeToObject(
478     IXMLDOMDocument *iface,
479     IXMLDOMNode* stylesheet,
480     VARIANT outputObject)
481 {
482     FIXME("\n");
483     return E_NOTIMPL;
484 }
485
486
487 static HRESULT WINAPI domdoc_get_doctype(
488     IXMLDOMDocument *iface,
489     IXMLDOMDocument** documentType )
490 {
491     FIXME("\n");
492     return E_NOTIMPL;
493 }
494
495
496 static HRESULT WINAPI domdoc_get_implementation(
497     IXMLDOMDocument *iface,
498     IXMLDOMImplementation** impl )
499 {
500     FIXME("\n");
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI domdoc_get_documentElement(
505     IXMLDOMDocument *iface,
506     IXMLDOMElement** DOMElement )
507 {
508     domdoc *This = impl_from_IXMLDOMDocument( iface );
509     xmlDocPtr xmldoc = NULL;
510     xmlNodePtr root = NULL;
511
512     TRACE("%p\n", This);
513
514     *DOMElement = NULL;
515
516     if ( !This->node )
517         return S_FALSE;
518
519     xmldoc = get_doc( This );
520     if ( !xmldoc )
521         return S_FALSE;
522
523     root = xmlDocGetRootElement( xmldoc );
524     if ( !root )
525         return S_FALSE;
526
527     *DOMElement = create_element( root );
528  
529     return S_OK;
530 }
531
532
533 static HRESULT WINAPI domdoc_documentElement(
534     IXMLDOMDocument *iface,
535     IXMLDOMElement* DOMElement )
536 {
537     FIXME("\n");
538     return E_NOTIMPL;
539 }
540
541
542 static HRESULT WINAPI domdoc_createElement(
543     IXMLDOMDocument *iface,
544     BSTR tagname,
545     IXMLDOMElement** element )
546 {
547     FIXME("\n");
548     return E_NOTIMPL;
549 }
550
551
552 static HRESULT WINAPI domdoc_createDocumentFragment(
553     IXMLDOMDocument *iface,
554     IXMLDOMDocumentFragment** docFrag )
555 {
556     FIXME("\n");
557     return E_NOTIMPL;
558 }
559
560
561 static HRESULT WINAPI domdoc_createTextNode(
562     IXMLDOMDocument *iface,
563     BSTR data,
564     IXMLDOMText** text )
565 {
566     FIXME("\n");
567     return E_NOTIMPL;
568 }
569
570
571 static HRESULT WINAPI domdoc_createComment(
572     IXMLDOMDocument *iface,
573     BSTR data,
574     IXMLDOMComment** comment )
575 {
576     FIXME("\n");
577     return E_NOTIMPL;
578 }
579
580
581 static HRESULT WINAPI domdoc_createCDATASection(
582     IXMLDOMDocument *iface,
583     BSTR data,
584     IXMLDOMCDATASection** cdata )
585 {
586     FIXME("\n");
587     return E_NOTIMPL;
588 }
589
590
591 static HRESULT WINAPI domdoc_createProcessingInstruction(
592     IXMLDOMDocument *iface,
593     BSTR target,
594     BSTR data,
595     IXMLDOMProcessingInstruction** pi )
596 {
597     FIXME("\n");
598     return E_NOTIMPL;
599 }
600
601
602 static HRESULT WINAPI domdoc_createAttribute(
603     IXMLDOMDocument *iface,
604     BSTR name,
605     IXMLDOMAttribute** attribute )
606 {
607     FIXME("\n");
608     return E_NOTIMPL;
609 }
610
611
612 static HRESULT WINAPI domdoc_createEntityReference(
613     IXMLDOMDocument *iface,
614     BSTR name,
615     IXMLDOMEntityReference** entityRef )
616 {
617     FIXME("\n");
618     return E_NOTIMPL;
619 }
620
621
622 static HRESULT WINAPI domdoc_getElementsByTagName(
623     IXMLDOMDocument *iface,
624     BSTR tagName,
625     IXMLDOMNodeList** resultList )
626 {
627     FIXME("\n");
628     return E_NOTIMPL;
629 }
630
631
632 static HRESULT WINAPI domdoc_createNode(
633     IXMLDOMDocument *iface,
634     VARIANT Type,
635     BSTR name,
636     BSTR namespaceURI,
637     IXMLDOMNode** node )
638 {
639     FIXME("\n");
640     return E_NOTIMPL;
641 }
642
643
644 static HRESULT WINAPI domdoc_nodeFromID(
645     IXMLDOMDocument *iface,
646     BSTR idString,
647     IXMLDOMNode** node )
648 {
649     FIXME("\n");
650     return E_NOTIMPL;
651 }
652
653 static xmlDocPtr doparse( char *ptr, int len )
654 {
655 #ifdef HAVE_XMLREADMEMORY
656     /*
657      * use xmlReadMemory if possible so we can suppress
658      * writing errors to stderr
659      */
660     return xmlReadMemory( ptr, len, NULL, NULL,
661                           XML_PARSE_NOERROR | XML_PARSE_NOWARNING );
662 #else
663     return xmlParseMemory( ptr, len );
664 #endif
665 }
666
667 static xmlDocPtr doread( LPWSTR filename )
668 {
669     HANDLE handle, mapping;
670     DWORD len;
671     xmlDocPtr xmldoc = NULL;
672     char *ptr;
673
674     TRACE("%s\n", debugstr_w( filename ));
675
676     handle = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ,
677                          NULL, OPEN_EXISTING, 0, NULL );
678     if( handle == INVALID_HANDLE_VALUE )
679         return xmldoc;
680
681     len = GetFileSize( handle, NULL );
682     if( len != INVALID_FILE_SIZE || GetLastError() == NO_ERROR )
683     {
684         mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
685         if ( mapping )
686         {
687             ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, len );
688             if ( ptr )
689             {
690                 xmldoc = doparse( ptr, len );
691                 UnmapViewOfFile( ptr );
692             }
693             CloseHandle( mapping );
694         }
695     }
696     CloseHandle( handle );
697
698     return xmldoc;
699 }
700
701
702 static HRESULT WINAPI domdoc_load(
703     IXMLDOMDocument *iface,
704     VARIANT xmlSource,
705     VARIANT_BOOL* isSuccessful )
706 {
707     domdoc *This = impl_from_IXMLDOMDocument( iface );
708     LPWSTR filename = NULL;
709     xmlDocPtr xmldoc;
710
711     TRACE("type %d\n", V_VT(&xmlSource) );
712
713     if ( This->node )
714     {
715         IXMLDOMNode_Release( This->node );
716         This->node = NULL;
717     }
718
719     switch( V_VT(&xmlSource) )
720     {
721     case VT_BSTR:
722         filename = V_BSTR(&xmlSource);
723     }
724
725     if ( !filename )
726         return S_FALSE;
727
728     xmldoc = doread( filename );
729     if ( !xmldoc )
730         return S_FALSE;
731
732     This->node = create_node( (xmlNodePtr) xmldoc );
733     if ( !This->node )
734     {
735         *isSuccessful = VARIANT_FALSE;
736         return S_FALSE;
737     }
738
739     *isSuccessful = VARIANT_TRUE;
740     return S_OK;
741 }
742
743
744 static HRESULT WINAPI domdoc_get_readyState(
745     IXMLDOMDocument *iface,
746     long* value )
747 {
748     FIXME("\n");
749     return E_NOTIMPL;
750 }
751
752
753 static HRESULT WINAPI domdoc_get_parseError(
754     IXMLDOMDocument *iface,
755     IXMLDOMParseError** errorObj )
756 {
757     FIXME("\n");
758     return E_NOTIMPL;
759 }
760
761
762 static HRESULT WINAPI domdoc_get_url(
763     IXMLDOMDocument *iface,
764     BSTR* urlString )
765 {
766     FIXME("\n");
767     return E_NOTIMPL;
768 }
769
770
771 static HRESULT WINAPI domdoc_get_async(
772     IXMLDOMDocument *iface,
773     VARIANT_BOOL* isAsync )
774 {
775     domdoc *This = impl_from_IXMLDOMDocument( iface );
776
777     TRACE("%p <- %d\n", isAsync, This->async);
778     *isAsync = This->async;
779     return S_OK;
780 }
781
782
783 static HRESULT WINAPI domdoc_put_async(
784     IXMLDOMDocument *iface,
785     VARIANT_BOOL isAsync )
786 {
787     domdoc *This = impl_from_IXMLDOMDocument( iface );
788
789     TRACE("%d\n", isAsync);
790     This->async = isAsync;
791     return S_OK;
792 }
793
794
795 static HRESULT WINAPI domdoc_abort(
796     IXMLDOMDocument *iface )
797 {
798     FIXME("\n");
799     return E_NOTIMPL;
800 }
801
802
803 BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
804 {
805     UINT len, blen = SysStringLen( bstr );
806     LPSTR str;
807
808     len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
809     str = HeapAlloc( GetProcessHeap(), 0, len );
810     if ( !str )
811         return FALSE;
812     WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
813     *plen = len;
814     *pstr = str;
815     return TRUE;
816 }
817
818 static HRESULT WINAPI domdoc_loadXML(
819     IXMLDOMDocument *iface,
820     BSTR bstrXML,
821     VARIANT_BOOL* isSuccessful )
822 {
823     domdoc *This = impl_from_IXMLDOMDocument( iface );
824     xmlDocPtr xmldoc;
825     char *str;
826     int len;
827
828     TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
829
830     if ( This->node )
831     {
832         IXMLDOMNode_Release( This->node );
833         This->node = NULL;
834     }
835
836     if ( !isSuccessful )
837         return S_FALSE;
838
839     *isSuccessful = VARIANT_FALSE;
840
841     if ( !bstrXML )
842         return S_FALSE;
843
844     if ( !bstr_to_utf8( bstrXML, &str, &len ) )
845         return S_FALSE;
846
847     xmldoc = doparse( str, len );
848     HeapFree( GetProcessHeap(), 0, str );
849
850     This->node = create_node( (xmlNodePtr) xmldoc );
851     if( !This->node )
852         return S_FALSE;
853
854     *isSuccessful = VARIANT_TRUE;
855     return S_OK;
856 }
857
858
859 static HRESULT WINAPI domdoc_save(
860     IXMLDOMDocument *iface,
861     VARIANT destination )
862 {
863     FIXME("\n");
864     return E_NOTIMPL;
865 }
866
867 static HRESULT WINAPI domdoc_get_validateOnParse(
868     IXMLDOMDocument *iface,
869     VARIANT_BOOL* isValidating )
870 {
871     FIXME("\n");
872     return E_NOTIMPL;
873 }
874
875
876 static HRESULT WINAPI domdoc_put_validateOnParse(
877     IXMLDOMDocument *iface,
878     VARIANT_BOOL isValidating )
879 {
880     FIXME("\n");
881     return E_NOTIMPL;
882 }
883
884
885 static HRESULT WINAPI domdoc_get_resolveExternals(
886     IXMLDOMDocument *iface,
887     VARIANT_BOOL* isResolving )
888 {
889     FIXME("\n");
890     return E_NOTIMPL;
891 }
892
893
894 static HRESULT WINAPI domdoc_put_resolveExternals(
895     IXMLDOMDocument *iface,
896     VARIANT_BOOL isValidating )
897 {
898     FIXME("\n");
899     return E_NOTIMPL;
900 }
901
902
903 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
904     IXMLDOMDocument *iface,
905     VARIANT_BOOL* isPreserving )
906 {
907     FIXME("\n");
908     return E_NOTIMPL;
909 }
910
911
912 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
913     IXMLDOMDocument *iface,
914     VARIANT_BOOL isPreserving )
915 {
916     FIXME("\n");
917     return E_NOTIMPL;
918 }
919
920
921 static HRESULT WINAPI domdoc_put_onReadyStateChange(
922     IXMLDOMDocument *iface,
923     VARIANT readyStateChangeSink )
924 {
925     FIXME("\n");
926     return E_NOTIMPL;
927 }
928
929
930 static HRESULT WINAPI domdoc_put_onDataAvailable(
931     IXMLDOMDocument *iface,
932     VARIANT onDataAvailableSink )
933 {
934     FIXME("\n");
935     return E_NOTIMPL;
936 }
937
938 static HRESULT WINAPI domdoc_put_onTransformNode(
939     IXMLDOMDocument *iface,
940     VARIANT onTransformNodeSink )
941 {
942     FIXME("\n");
943     return E_NOTIMPL;
944 }
945
946 const struct IXMLDOMDocumentVtbl domdoc_vtbl =
947 {
948     domdoc_QueryInterface,
949     domdoc_AddRef,
950     domdoc_Release,
951     domdoc_GetTypeInfoCount,
952     domdoc_GetTypeInfo,
953     domdoc_GetIDsOfNames,
954     domdoc_Invoke,
955     domdoc_get_nodeName,
956     domdoc_get_nodeValue,
957     domdoc_put_nodeValue,
958     domdoc_get_nodeType,
959     domdoc_get_parentNode,
960     domdoc_get_childNodes,
961     domdoc_get_firstChild,
962     domdoc_get_lastChild,
963     domdoc_get_previousSibling,
964     domdoc_get_nextSibling,
965     domdoc_get_attributes,
966     domdoc_insertBefore,
967     domdoc_replaceChild,
968     domdoc_removeChild,
969     domdoc_appendChild,
970     domdoc_hasChildNodes,
971     domdoc_get_ownerDocument,
972     domdoc_cloneNode,
973     domdoc_get_nodeTypeString,
974     domdoc_get_text,
975     domdoc_put_text,
976     domdoc_get_specified,
977     domdoc_get_definition,
978     domdoc_get_nodeTypedValue,
979     domdoc_put_nodeTypedValue,
980     domdoc_get_dataType,
981     domdoc_put_dataType,
982     domdoc_get_xml,
983     domdoc_transformNode,
984     domdoc_selectNodes,
985     domdoc_selectSingleNode,
986     domdoc_get_parsed,
987     domdoc_get_namespaceURI,
988     domdoc_get_prefix,
989     domdoc_get_baseName,
990     domdoc_transformNodeToObject,
991     domdoc_get_doctype,
992     domdoc_get_implementation,
993     domdoc_get_documentElement,
994     domdoc_documentElement,
995     domdoc_createElement,
996     domdoc_createDocumentFragment,
997     domdoc_createTextNode,
998     domdoc_createComment,
999     domdoc_createCDATASection,
1000     domdoc_createProcessingInstruction,
1001     domdoc_createAttribute,
1002     domdoc_createEntityReference,
1003     domdoc_getElementsByTagName,
1004     domdoc_createNode,
1005     domdoc_nodeFromID,
1006     domdoc_load,
1007     domdoc_get_readyState,
1008     domdoc_get_parseError,
1009     domdoc_get_url,
1010     domdoc_get_async,
1011     domdoc_put_async,
1012     domdoc_abort,
1013     domdoc_loadXML,
1014     domdoc_save,
1015     domdoc_get_validateOnParse,
1016     domdoc_put_validateOnParse,
1017     domdoc_get_resolveExternals,
1018     domdoc_put_resolveExternals,
1019     domdoc_get_preserveWhiteSpace,
1020     domdoc_put_preserveWhiteSpace,
1021     domdoc_put_onReadyStateChange,
1022     domdoc_put_onDataAvailable,
1023     domdoc_put_onTransformNode,
1024 };
1025
1026 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1027 {
1028     domdoc *doc;
1029
1030     doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1031     if( !doc )
1032         return E_OUTOFMEMORY;
1033
1034     doc->lpVtbl = &domdoc_vtbl;
1035     doc->ref = 1;
1036     doc->async = 0;
1037     doc->node = NULL;
1038
1039     *ppObj = &doc->lpVtbl;
1040
1041     return S_OK;
1042 }
1043
1044 #else
1045
1046 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1047 {
1048     MESSAGE("This program tried to use a DOMDocument object, but\n"
1049             "libxml2 support was not present at compile time.\n");
1050     return E_NOTIMPL;
1051 }
1052
1053 #endif