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