shell32/tests: End the lines with CR+LF otherwise the profile APIs are unable to...
[wine/wine-gecko.git] / dlls / msxml3 / domdoc.c
blob8b3f561dfb09ff59d46ebaba7eb690dccc168421
1 /*
2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #include <assert.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "ole2.h"
32 #include "msxml2.h"
33 #include "wininet.h"
34 #include "urlmon.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44 #ifdef HAVE_LIBXML2
46 typedef struct {
47 const struct IBindStatusCallbackVtbl *lpVtbl;
48 } bsc;
50 static HRESULT WINAPI bsc_QueryInterface(
51 IBindStatusCallback *iface,
52 REFIID riid,
53 LPVOID *ppobj )
55 if (IsEqualGUID(riid, &IID_IUnknown) ||
56 IsEqualGUID(riid, &IID_IBindStatusCallback))
58 IBindStatusCallback_AddRef( iface );
59 *ppobj = iface;
60 return S_OK;
63 FIXME("interface %s not implemented\n", debugstr_guid(riid));
64 return E_NOINTERFACE;
67 static ULONG WINAPI bsc_AddRef(
68 IBindStatusCallback *iface )
70 return 2;
73 static ULONG WINAPI bsc_Release(
74 IBindStatusCallback *iface )
76 return 1;
79 static HRESULT WINAPI bsc_OnStartBinding(
80 IBindStatusCallback* iface,
81 DWORD dwReserved,
82 IBinding* pib)
84 return S_OK;
87 static HRESULT WINAPI bsc_GetPriority(
88 IBindStatusCallback* iface,
89 LONG* pnPriority)
91 return S_OK;
94 static HRESULT WINAPI bsc_OnLowResource(
95 IBindStatusCallback* iface,
96 DWORD reserved)
98 return S_OK;
101 static HRESULT WINAPI bsc_OnProgress(
102 IBindStatusCallback* iface,
103 ULONG ulProgress,
104 ULONG ulProgressMax,
105 ULONG ulStatusCode,
106 LPCWSTR szStatusText)
108 return S_OK;
111 static HRESULT WINAPI bsc_OnStopBinding(
112 IBindStatusCallback* iface,
113 HRESULT hresult,
114 LPCWSTR szError)
116 return S_OK;
119 static HRESULT WINAPI bsc_GetBindInfo(
120 IBindStatusCallback* iface,
121 DWORD* grfBINDF,
122 BINDINFO* pbindinfo)
124 *grfBINDF = BINDF_RESYNCHRONIZE;
126 return S_OK;
129 static HRESULT WINAPI bsc_OnDataAvailable(
130 IBindStatusCallback* iface,
131 DWORD grfBSCF,
132 DWORD dwSize,
133 FORMATETC* pformatetc,
134 STGMEDIUM* pstgmed)
136 return S_OK;
139 static HRESULT WINAPI bsc_OnObjectAvailable(
140 IBindStatusCallback* iface,
141 REFIID riid,
142 IUnknown* punk)
144 return S_OK;
147 static const struct IBindStatusCallbackVtbl bsc_vtbl =
149 bsc_QueryInterface,
150 bsc_AddRef,
151 bsc_Release,
152 bsc_OnStartBinding,
153 bsc_GetPriority,
154 bsc_OnLowResource,
155 bsc_OnProgress,
156 bsc_OnStopBinding,
157 bsc_GetBindInfo,
158 bsc_OnDataAvailable,
159 bsc_OnObjectAvailable
162 static bsc domdoc_bsc = { &bsc_vtbl };
164 typedef struct _domdoc
166 const struct IXMLDOMDocument2Vtbl *lpVtbl;
167 LONG ref;
168 VARIANT_BOOL async;
169 VARIANT_BOOL validating;
170 VARIANT_BOOL resolving;
171 VARIANT_BOOL preserving;
172 IUnknown *node_unk;
173 IXMLDOMNode *node;
174 IXMLDOMSchemaCollection *schema;
175 HRESULT error;
176 } domdoc;
178 LONG xmldoc_add_ref(xmlDocPtr doc)
180 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
181 TRACE("%d\n", ref);
182 return ref;
185 LONG xmldoc_release(xmlDocPtr doc)
187 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
188 TRACE("%d\n", ref);
189 if(ref == 0)
191 TRACE("freeing docptr %p\n", doc);
192 xmlFreeDoc(doc);
195 return ref;
198 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
200 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
203 static inline xmlDocPtr get_doc( domdoc *This )
205 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
208 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
210 domdoc *This = impl_from_IXMLDOMDocument2( iface );
212 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
214 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
215 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
216 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
218 *ppvObject = iface;
220 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
221 IsEqualGUID( riid, &IID_IDispatch ) )
223 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
225 else
227 FIXME("interface %s not implemented\n", debugstr_guid(riid));
228 return E_NOINTERFACE;
231 IXMLDOMDocument_AddRef( iface );
233 return S_OK;
237 static ULONG WINAPI domdoc_AddRef(
238 IXMLDOMDocument2 *iface )
240 domdoc *This = impl_from_IXMLDOMDocument2( iface );
241 TRACE("%p\n", This );
242 return InterlockedIncrement( &This->ref );
246 static ULONG WINAPI domdoc_Release(
247 IXMLDOMDocument2 *iface )
249 domdoc *This = impl_from_IXMLDOMDocument2( iface );
250 LONG ref;
252 TRACE("%p\n", This );
254 ref = InterlockedDecrement( &This->ref );
255 if ( ref == 0 )
257 IUnknown_Release( This->node_unk );
258 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
259 HeapFree( GetProcessHeap(), 0, This );
262 return ref;
265 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
267 FIXME("\n");
268 return E_NOTIMPL;
271 static HRESULT WINAPI domdoc_GetTypeInfo(
272 IXMLDOMDocument2 *iface,
273 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
275 FIXME("\n");
276 return E_NOTIMPL;
279 static HRESULT WINAPI domdoc_GetIDsOfNames(
280 IXMLDOMDocument2 *iface,
281 REFIID riid,
282 LPOLESTR* rgszNames,
283 UINT cNames,
284 LCID lcid,
285 DISPID* rgDispId)
287 FIXME("\n");
288 return E_NOTIMPL;
292 static HRESULT WINAPI domdoc_Invoke(
293 IXMLDOMDocument2 *iface,
294 DISPID dispIdMember,
295 REFIID riid,
296 LCID lcid,
297 WORD wFlags,
298 DISPPARAMS* pDispParams,
299 VARIANT* pVarResult,
300 EXCEPINFO* pExcepInfo,
301 UINT* puArgErr)
303 FIXME("\n");
304 return E_NOTIMPL;
308 static HRESULT WINAPI domdoc_get_nodeName(
309 IXMLDOMDocument2 *iface,
310 BSTR* name )
312 domdoc *This = impl_from_IXMLDOMDocument2( iface );
313 return IXMLDOMNode_get_nodeName( This->node, name );
317 static HRESULT WINAPI domdoc_get_nodeValue(
318 IXMLDOMDocument2 *iface,
319 VARIANT* value )
321 domdoc *This = impl_from_IXMLDOMDocument2( iface );
322 return IXMLDOMNode_get_nodeValue( This->node, value );
326 static HRESULT WINAPI domdoc_put_nodeValue(
327 IXMLDOMDocument2 *iface,
328 VARIANT value)
330 domdoc *This = impl_from_IXMLDOMDocument2( iface );
331 return IXMLDOMNode_put_nodeValue( This->node, value );
335 static HRESULT WINAPI domdoc_get_nodeType(
336 IXMLDOMDocument2 *iface,
337 DOMNodeType* type )
339 domdoc *This = impl_from_IXMLDOMDocument2( iface );
340 return IXMLDOMNode_get_nodeType( This->node, type );
344 static HRESULT WINAPI domdoc_get_parentNode(
345 IXMLDOMDocument2 *iface,
346 IXMLDOMNode** parent )
348 domdoc *This = impl_from_IXMLDOMDocument2( iface );
349 return IXMLDOMNode_get_parentNode( This->node, parent );
353 static HRESULT WINAPI domdoc_get_childNodes(
354 IXMLDOMDocument2 *iface,
355 IXMLDOMNodeList** childList )
357 domdoc *This = impl_from_IXMLDOMDocument2( iface );
358 return IXMLDOMNode_get_childNodes( This->node, childList );
362 static HRESULT WINAPI domdoc_get_firstChild(
363 IXMLDOMDocument2 *iface,
364 IXMLDOMNode** firstChild )
366 domdoc *This = impl_from_IXMLDOMDocument2( iface );
367 return IXMLDOMNode_get_firstChild( This->node, firstChild );
371 static HRESULT WINAPI domdoc_get_lastChild(
372 IXMLDOMDocument2 *iface,
373 IXMLDOMNode** lastChild )
375 domdoc *This = impl_from_IXMLDOMDocument2( iface );
376 return IXMLDOMNode_get_lastChild( This->node, lastChild );
380 static HRESULT WINAPI domdoc_get_previousSibling(
381 IXMLDOMDocument2 *iface,
382 IXMLDOMNode** previousSibling )
384 domdoc *This = impl_from_IXMLDOMDocument2( iface );
385 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
389 static HRESULT WINAPI domdoc_get_nextSibling(
390 IXMLDOMDocument2 *iface,
391 IXMLDOMNode** nextSibling )
393 domdoc *This = impl_from_IXMLDOMDocument2( iface );
394 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
398 static HRESULT WINAPI domdoc_get_attributes(
399 IXMLDOMDocument2 *iface,
400 IXMLDOMNamedNodeMap** attributeMap )
402 domdoc *This = impl_from_IXMLDOMDocument2( iface );
403 return IXMLDOMNode_get_attributes( This->node, attributeMap );
407 static HRESULT WINAPI domdoc_insertBefore(
408 IXMLDOMDocument2 *iface,
409 IXMLDOMNode* newChild,
410 VARIANT refChild,
411 IXMLDOMNode** outNewChild )
413 domdoc *This = impl_from_IXMLDOMDocument2( iface );
414 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
418 static HRESULT WINAPI domdoc_replaceChild(
419 IXMLDOMDocument2 *iface,
420 IXMLDOMNode* newChild,
421 IXMLDOMNode* oldChild,
422 IXMLDOMNode** outOldChild)
424 domdoc *This = impl_from_IXMLDOMDocument2( iface );
425 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
429 static HRESULT WINAPI domdoc_removeChild(
430 IXMLDOMDocument2 *iface,
431 IXMLDOMNode* childNode,
432 IXMLDOMNode** oldChild)
434 domdoc *This = impl_from_IXMLDOMDocument2( iface );
435 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
439 static HRESULT WINAPI domdoc_appendChild(
440 IXMLDOMDocument2 *iface,
441 IXMLDOMNode* newChild,
442 IXMLDOMNode** outNewChild)
444 domdoc *This = impl_from_IXMLDOMDocument2( iface );
445 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
449 static HRESULT WINAPI domdoc_hasChildNodes(
450 IXMLDOMDocument2 *iface,
451 VARIANT_BOOL* hasChild)
453 domdoc *This = impl_from_IXMLDOMDocument2( iface );
454 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
458 static HRESULT WINAPI domdoc_get_ownerDocument(
459 IXMLDOMDocument2 *iface,
460 IXMLDOMDocument** DOMDocument)
462 domdoc *This = impl_from_IXMLDOMDocument2( iface );
463 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
467 static HRESULT WINAPI domdoc_cloneNode(
468 IXMLDOMDocument2 *iface,
469 VARIANT_BOOL deep,
470 IXMLDOMNode** cloneRoot)
472 domdoc *This = impl_from_IXMLDOMDocument2( iface );
473 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
477 static HRESULT WINAPI domdoc_get_nodeTypeString(
478 IXMLDOMDocument2 *iface,
479 BSTR* nodeType )
481 domdoc *This = impl_from_IXMLDOMDocument2( iface );
482 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
486 static HRESULT WINAPI domdoc_get_text(
487 IXMLDOMDocument2 *iface,
488 BSTR* text )
490 domdoc *This = impl_from_IXMLDOMDocument2( iface );
491 return IXMLDOMNode_get_text( This->node, text );
495 static HRESULT WINAPI domdoc_put_text(
496 IXMLDOMDocument2 *iface,
497 BSTR text )
499 domdoc *This = impl_from_IXMLDOMDocument2( iface );
500 return IXMLDOMNode_put_text( This->node, text );
504 static HRESULT WINAPI domdoc_get_specified(
505 IXMLDOMDocument2 *iface,
506 VARIANT_BOOL* isSpecified )
508 domdoc *This = impl_from_IXMLDOMDocument2( iface );
509 return IXMLDOMNode_get_specified( This->node, isSpecified );
513 static HRESULT WINAPI domdoc_get_definition(
514 IXMLDOMDocument2 *iface,
515 IXMLDOMNode** definitionNode )
517 domdoc *This = impl_from_IXMLDOMDocument2( iface );
518 return IXMLDOMNode_get_definition( This->node, definitionNode );
522 static HRESULT WINAPI domdoc_get_nodeTypedValue(
523 IXMLDOMDocument2 *iface,
524 VARIANT* typedValue )
526 domdoc *This = impl_from_IXMLDOMDocument2( iface );
527 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
530 static HRESULT WINAPI domdoc_put_nodeTypedValue(
531 IXMLDOMDocument2 *iface,
532 VARIANT typedValue )
534 domdoc *This = impl_from_IXMLDOMDocument2( iface );
535 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
539 static HRESULT WINAPI domdoc_get_dataType(
540 IXMLDOMDocument2 *iface,
541 VARIANT* dataTypeName )
543 domdoc *This = impl_from_IXMLDOMDocument2( iface );
544 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
548 static HRESULT WINAPI domdoc_put_dataType(
549 IXMLDOMDocument2 *iface,
550 BSTR dataTypeName )
552 domdoc *This = impl_from_IXMLDOMDocument2( iface );
553 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
557 static HRESULT WINAPI domdoc_get_xml(
558 IXMLDOMDocument2 *iface,
559 BSTR* xmlString )
561 domdoc *This = impl_from_IXMLDOMDocument2( iface );
562 return IXMLDOMNode_get_xml( This->node, xmlString );
566 static HRESULT WINAPI domdoc_transformNode(
567 IXMLDOMDocument2 *iface,
568 IXMLDOMNode* styleSheet,
569 BSTR* xmlString )
571 domdoc *This = impl_from_IXMLDOMDocument2( iface );
572 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
576 static HRESULT WINAPI domdoc_selectNodes(
577 IXMLDOMDocument2 *iface,
578 BSTR queryString,
579 IXMLDOMNodeList** resultList )
581 domdoc *This = impl_from_IXMLDOMDocument2( iface );
582 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
586 static HRESULT WINAPI domdoc_selectSingleNode(
587 IXMLDOMDocument2 *iface,
588 BSTR queryString,
589 IXMLDOMNode** resultNode )
591 domdoc *This = impl_from_IXMLDOMDocument2( iface );
592 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
596 static HRESULT WINAPI domdoc_get_parsed(
597 IXMLDOMDocument2 *iface,
598 VARIANT_BOOL* isParsed )
600 domdoc *This = impl_from_IXMLDOMDocument2( iface );
601 return IXMLDOMNode_get_parsed( This->node, isParsed );
605 static HRESULT WINAPI domdoc_get_namespaceURI(
606 IXMLDOMDocument2 *iface,
607 BSTR* namespaceURI )
609 domdoc *This = impl_from_IXMLDOMDocument2( iface );
610 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
614 static HRESULT WINAPI domdoc_get_prefix(
615 IXMLDOMDocument2 *iface,
616 BSTR* prefixString )
618 domdoc *This = impl_from_IXMLDOMDocument2( iface );
619 return IXMLDOMNode_get_prefix( This->node, prefixString );
623 static HRESULT WINAPI domdoc_get_baseName(
624 IXMLDOMDocument2 *iface,
625 BSTR* nameString )
627 domdoc *This = impl_from_IXMLDOMDocument2( iface );
628 return IXMLDOMNode_get_baseName( This->node, nameString );
632 static HRESULT WINAPI domdoc_transformNodeToObject(
633 IXMLDOMDocument2 *iface,
634 IXMLDOMNode* stylesheet,
635 VARIANT outputObject)
637 domdoc *This = impl_from_IXMLDOMDocument2( iface );
638 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
642 static HRESULT WINAPI domdoc_get_doctype(
643 IXMLDOMDocument2 *iface,
644 IXMLDOMDocumentType** documentType )
646 FIXME("\n");
647 return E_NOTIMPL;
651 static HRESULT WINAPI domdoc_get_implementation(
652 IXMLDOMDocument2 *iface,
653 IXMLDOMImplementation** impl )
655 FIXME("\n");
656 return E_NOTIMPL;
659 static HRESULT WINAPI domdoc_get_documentElement(
660 IXMLDOMDocument2 *iface,
661 IXMLDOMElement** DOMElement )
663 domdoc *This = impl_from_IXMLDOMDocument2( iface );
664 xmlDocPtr xmldoc = NULL;
665 xmlNodePtr root = NULL;
666 IXMLDOMNode *element_node;
667 HRESULT hr;
669 TRACE("%p\n", This);
671 *DOMElement = NULL;
673 xmldoc = get_doc( This );
675 root = xmlDocGetRootElement( xmldoc );
676 if ( !root )
677 return S_FALSE;
679 element_node = create_node( root );
680 if(!element_node) return S_FALSE;
682 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
683 IXMLDOMNode_Release(element_node);
685 return hr;
689 static HRESULT WINAPI domdoc_documentElement(
690 IXMLDOMDocument2 *iface,
691 IXMLDOMElement* DOMElement )
693 FIXME("\n");
694 return E_NOTIMPL;
698 static HRESULT WINAPI domdoc_createElement(
699 IXMLDOMDocument2 *iface,
700 BSTR tagname,
701 IXMLDOMElement** element )
703 xmlNodePtr xmlnode;
704 domdoc *This = impl_from_IXMLDOMDocument2( iface );
705 xmlChar *xml_name;
706 IUnknown *elem_unk;
707 HRESULT hr;
709 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
711 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
712 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
714 TRACE("created xmlptr %p\n", xmlnode);
715 elem_unk = create_element(xmlnode, NULL);
716 HeapFree(GetProcessHeap(), 0, xml_name);
718 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
719 IUnknown_Release(elem_unk);
720 TRACE("returning %p\n", *element);
721 return hr;
725 static HRESULT WINAPI domdoc_createDocumentFragment(
726 IXMLDOMDocument2 *iface,
727 IXMLDOMDocumentFragment** docFrag )
729 FIXME("\n");
730 return E_NOTIMPL;
734 static HRESULT WINAPI domdoc_createTextNode(
735 IXMLDOMDocument2 *iface,
736 BSTR data,
737 IXMLDOMText** text )
739 FIXME("\n");
740 return E_NOTIMPL;
744 static HRESULT WINAPI domdoc_createComment(
745 IXMLDOMDocument2 *iface,
746 BSTR data,
747 IXMLDOMComment** comment )
749 FIXME("\n");
750 return E_NOTIMPL;
754 static HRESULT WINAPI domdoc_createCDATASection(
755 IXMLDOMDocument2 *iface,
756 BSTR data,
757 IXMLDOMCDATASection** cdata )
759 FIXME("\n");
760 return E_NOTIMPL;
764 static HRESULT WINAPI domdoc_createProcessingInstruction(
765 IXMLDOMDocument2 *iface,
766 BSTR target,
767 BSTR data,
768 IXMLDOMProcessingInstruction** pi )
770 #ifdef HAVE_XMLNEWDOCPI
771 xmlNodePtr xmlnode;
772 domdoc *This = impl_from_IXMLDOMDocument2( iface );
773 xmlChar *xml_target, *xml_content;
775 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
777 xml_target = xmlChar_from_wchar((WCHAR*)target);
778 xml_content = xmlChar_from_wchar((WCHAR*)data);
780 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
781 TRACE("created xmlptr %p\n", xmlnode);
782 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
784 HeapFree(GetProcessHeap(), 0, xml_content);
785 HeapFree(GetProcessHeap(), 0, xml_target);
787 return S_OK;
788 #else
789 FIXME("Libxml 2.6.15 or greater required.\n");
790 return E_NOTIMPL;
791 #endif
795 static HRESULT WINAPI domdoc_createAttribute(
796 IXMLDOMDocument2 *iface,
797 BSTR name,
798 IXMLDOMAttribute** attribute )
800 FIXME("\n");
801 return E_NOTIMPL;
805 static HRESULT WINAPI domdoc_createEntityReference(
806 IXMLDOMDocument2 *iface,
807 BSTR name,
808 IXMLDOMEntityReference** entityRef )
810 FIXME("\n");
811 return E_NOTIMPL;
815 static HRESULT WINAPI domdoc_getElementsByTagName(
816 IXMLDOMDocument2 *iface,
817 BSTR tagName,
818 IXMLDOMNodeList** resultList )
820 domdoc *This = impl_from_IXMLDOMDocument2( iface );
821 xmlChar *name;
822 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
824 name = xmlChar_from_wchar((WCHAR*)tagName);
825 *resultList = create_filtered_nodelist((xmlNodePtr)get_doc(This), name, TRUE);
826 HeapFree(GetProcessHeap(), 0, name);
828 if(!*resultList) return S_FALSE;
829 return S_OK;
832 static DOMNodeType get_node_type(VARIANT Type)
834 if(V_VT(&Type) == VT_I4)
835 return V_I4(&Type);
837 FIXME("Unsupported variant type %x\n", V_VT(&Type));
838 return 0;
841 static HRESULT WINAPI domdoc_createNode(
842 IXMLDOMDocument2 *iface,
843 VARIANT Type,
844 BSTR name,
845 BSTR namespaceURI,
846 IXMLDOMNode** node )
848 domdoc *This = impl_from_IXMLDOMDocument2( iface );
849 DOMNodeType node_type;
850 xmlNodePtr xmlnode = NULL;
851 xmlChar *xml_name;
853 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
855 node_type = get_node_type(Type);
856 TRACE("node_type %d\n", node_type);
858 xml_name = xmlChar_from_wchar((WCHAR*)name);
860 switch(node_type)
862 case NODE_ELEMENT:
863 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
864 *node = create_node(xmlnode);
865 TRACE("created %p\n", xmlnode);
866 break;
868 default:
869 FIXME("unhandled node type %d\n", node_type);
870 break;
873 HeapFree(GetProcessHeap(), 0, xml_name);
875 if(xmlnode && *node)
876 return S_OK;
878 return E_FAIL;
881 static HRESULT WINAPI domdoc_nodeFromID(
882 IXMLDOMDocument2 *iface,
883 BSTR idString,
884 IXMLDOMNode** node )
886 FIXME("\n");
887 return E_NOTIMPL;
890 static xmlDocPtr doparse( char *ptr, int len )
892 #ifdef HAVE_XMLREADMEMORY
894 * use xmlReadMemory if possible so we can suppress
895 * writing errors to stderr
897 return xmlReadMemory( ptr, len, NULL, NULL,
898 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
899 #else
900 return xmlParseMemory( ptr, len );
901 #endif
904 static xmlDocPtr doread( LPWSTR filename )
906 xmlDocPtr xmldoc = NULL;
907 HRESULT hr;
908 IBindCtx *pbc;
909 IStream *stream, *memstream;
910 WCHAR url[INTERNET_MAX_URL_LENGTH];
911 BYTE buf[4096];
912 DWORD read, written;
914 TRACE("%s\n", debugstr_w( filename ));
916 if(!PathIsURLW(filename))
918 WCHAR fullpath[MAX_PATH];
919 DWORD needed = sizeof(url)/sizeof(WCHAR);
921 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
923 WARN("can't find path\n");
924 return NULL;
927 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
929 ERR("can't create url from path\n");
930 return NULL;
932 filename = url;
935 hr = CreateBindCtx(0, &pbc);
936 if(SUCCEEDED(hr))
938 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
939 if(SUCCEEDED(hr))
941 IMoniker *moniker;
942 hr = CreateURLMoniker(NULL, filename, &moniker);
943 if(SUCCEEDED(hr))
945 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
946 IMoniker_Release(moniker);
949 IBindCtx_Release(pbc);
951 if(FAILED(hr))
952 return NULL;
954 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
955 if(FAILED(hr))
957 IStream_Release(stream);
958 return NULL;
963 IStream_Read(stream, buf, sizeof(buf), &read);
964 hr = IStream_Write(memstream, buf, read, &written);
965 } while(SUCCEEDED(hr) && written != 0 && read != 0);
967 if(SUCCEEDED(hr))
969 HGLOBAL hglobal;
970 hr = GetHGlobalFromStream(memstream, &hglobal);
971 if(SUCCEEDED(hr))
973 DWORD len = GlobalSize(hglobal);
974 char *ptr = GlobalLock(hglobal);
975 if(len != 0)
976 xmldoc = doparse( ptr, len );
977 GlobalUnlock(hglobal);
980 IStream_Release(memstream);
981 IStream_Release(stream);
982 return xmldoc;
985 static HRESULT WINAPI domdoc_load(
986 IXMLDOMDocument2 *iface,
987 VARIANT xmlSource,
988 VARIANT_BOOL* isSuccessful )
990 domdoc *This = impl_from_IXMLDOMDocument2( iface );
991 LPWSTR filename = NULL;
992 xmlDocPtr xmldoc = NULL;
993 HRESULT hr = S_FALSE;
995 TRACE("type %d\n", V_VT(&xmlSource) );
997 *isSuccessful = VARIANT_FALSE;
999 assert( This->node );
1001 attach_xmlnode(This->node, NULL);
1003 switch( V_VT(&xmlSource) )
1005 case VT_BSTR:
1006 filename = V_BSTR(&xmlSource);
1009 if ( filename )
1011 xmldoc = doread( filename );
1013 if ( !xmldoc )
1014 This->error = E_FAIL;
1015 else
1017 hr = This->error = S_OK;
1018 *isSuccessful = VARIANT_TRUE;
1022 if(!xmldoc)
1023 xmldoc = xmlNewDoc(NULL);
1025 xmldoc->_private = 0;
1026 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1028 return hr;
1032 static HRESULT WINAPI domdoc_get_readyState(
1033 IXMLDOMDocument2 *iface,
1034 long* value )
1036 FIXME("\n");
1037 return E_NOTIMPL;
1041 static HRESULT WINAPI domdoc_get_parseError(
1042 IXMLDOMDocument2 *iface,
1043 IXMLDOMParseError** errorObj )
1045 BSTR error_string = NULL;
1046 static const WCHAR err[] = {'e','r','r','o','r',0};
1047 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1049 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1051 if(This->error)
1052 error_string = SysAllocString(err);
1054 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1055 if(!*errorObj) return E_OUTOFMEMORY;
1056 return S_OK;
1060 static HRESULT WINAPI domdoc_get_url(
1061 IXMLDOMDocument2 *iface,
1062 BSTR* urlString )
1064 FIXME("\n");
1065 return E_NOTIMPL;
1069 static HRESULT WINAPI domdoc_get_async(
1070 IXMLDOMDocument2 *iface,
1071 VARIANT_BOOL* isAsync )
1073 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1075 TRACE("%p <- %d\n", isAsync, This->async);
1076 *isAsync = This->async;
1077 return S_OK;
1081 static HRESULT WINAPI domdoc_put_async(
1082 IXMLDOMDocument2 *iface,
1083 VARIANT_BOOL isAsync )
1085 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1087 TRACE("%d\n", isAsync);
1088 This->async = isAsync;
1089 return S_OK;
1093 static HRESULT WINAPI domdoc_abort(
1094 IXMLDOMDocument2 *iface )
1096 FIXME("\n");
1097 return E_NOTIMPL;
1101 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1103 UINT len, blen = SysStringLen( bstr );
1104 LPSTR str;
1106 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1107 str = HeapAlloc( GetProcessHeap(), 0, len );
1108 if ( !str )
1109 return FALSE;
1110 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1111 *plen = len;
1112 *pstr = str;
1113 return TRUE;
1116 static HRESULT WINAPI domdoc_loadXML(
1117 IXMLDOMDocument2 *iface,
1118 BSTR bstrXML,
1119 VARIANT_BOOL* isSuccessful )
1121 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1122 xmlDocPtr xmldoc = NULL;
1123 char *str;
1124 int len;
1125 HRESULT hr = S_FALSE;
1127 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1129 assert ( This->node );
1131 attach_xmlnode( This->node, NULL );
1133 if ( isSuccessful )
1135 *isSuccessful = VARIANT_FALSE;
1137 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1139 xmldoc = doparse( str, len );
1140 HeapFree( GetProcessHeap(), 0, str );
1141 if ( !xmldoc )
1142 This->error = E_FAIL;
1143 else
1145 hr = This->error = S_OK;
1146 *isSuccessful = VARIANT_TRUE;
1150 if(!xmldoc)
1151 xmldoc = xmlNewDoc(NULL);
1153 xmldoc->_private = 0;
1154 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1156 return hr;
1160 static HRESULT WINAPI domdoc_save(
1161 IXMLDOMDocument2 *iface,
1162 VARIANT destination )
1164 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1165 HANDLE handle;
1166 xmlChar *mem;
1167 int size;
1168 HRESULT ret = S_OK;
1169 DWORD written;
1171 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1172 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1174 if(V_VT(&destination) != VT_BSTR)
1176 FIXME("Unhandled vt %x\n", V_VT(&destination));
1177 return S_FALSE;
1180 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1181 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1182 if( handle == INVALID_HANDLE_VALUE )
1184 WARN("failed to create file\n");
1185 return S_FALSE;
1188 xmlDocDumpMemory(get_doc(This), &mem, &size);
1189 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1191 WARN("write error\n");
1192 ret = S_FALSE;
1195 xmlFree(mem);
1196 CloseHandle(handle);
1197 return ret;
1200 static HRESULT WINAPI domdoc_get_validateOnParse(
1201 IXMLDOMDocument2 *iface,
1202 VARIANT_BOOL* isValidating )
1204 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1206 TRACE("%p <- %d\n", isValidating, This->validating);
1207 *isValidating = This->validating;
1208 return S_OK;
1212 static HRESULT WINAPI domdoc_put_validateOnParse(
1213 IXMLDOMDocument2 *iface,
1214 VARIANT_BOOL isValidating )
1216 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1218 TRACE("%d\n", isValidating);
1219 This->validating = isValidating;
1220 return S_OK;
1224 static HRESULT WINAPI domdoc_get_resolveExternals(
1225 IXMLDOMDocument2 *iface,
1226 VARIANT_BOOL* isResolving )
1228 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1230 TRACE("%p <- %d\n", isResolving, This->resolving);
1231 *isResolving = This->resolving;
1232 return S_OK;
1236 static HRESULT WINAPI domdoc_put_resolveExternals(
1237 IXMLDOMDocument2 *iface,
1238 VARIANT_BOOL isResolving )
1240 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1242 TRACE("%d\n", isResolving);
1243 This->resolving = isResolving;
1244 return S_OK;
1248 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1249 IXMLDOMDocument2 *iface,
1250 VARIANT_BOOL* isPreserving )
1252 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1254 TRACE("%p <- %d\n", isPreserving, This->preserving);
1255 *isPreserving = This->preserving;
1256 return S_OK;
1260 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1261 IXMLDOMDocument2 *iface,
1262 VARIANT_BOOL isPreserving )
1264 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1266 TRACE("%d\n", isPreserving);
1267 This->preserving = isPreserving;
1268 return S_OK;
1272 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1273 IXMLDOMDocument2 *iface,
1274 VARIANT readyStateChangeSink )
1276 FIXME("\n");
1277 return E_NOTIMPL;
1281 static HRESULT WINAPI domdoc_put_onDataAvailable(
1282 IXMLDOMDocument2 *iface,
1283 VARIANT onDataAvailableSink )
1285 FIXME("\n");
1286 return E_NOTIMPL;
1289 static HRESULT WINAPI domdoc_put_onTransformNode(
1290 IXMLDOMDocument2 *iface,
1291 VARIANT onTransformNodeSink )
1293 FIXME("\n");
1294 return E_NOTIMPL;
1297 static HRESULT WINAPI domdoc_get_namespaces(
1298 IXMLDOMDocument2* iface,
1299 IXMLDOMSchemaCollection** schemaCollection )
1301 FIXME("\n");
1302 return E_NOTIMPL;
1305 static HRESULT WINAPI domdoc_get_schemas(
1306 IXMLDOMDocument2* iface,
1307 VARIANT* var1 )
1309 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1310 HRESULT hr = S_FALSE;
1311 IXMLDOMSchemaCollection *cur_schema = This->schema;
1313 TRACE("(%p)->(%p)\n", This, var1);
1315 VariantInit(var1); /* Test shows we don't call VariantClear here */
1316 V_VT(var1) = VT_NULL;
1318 if(cur_schema)
1320 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1321 if(SUCCEEDED(hr))
1322 V_VT(var1) = VT_DISPATCH;
1324 return hr;
1327 static HRESULT WINAPI domdoc_putref_schemas(
1328 IXMLDOMDocument2* iface,
1329 VARIANT var1)
1331 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1332 HRESULT hr = E_FAIL;
1333 IXMLDOMSchemaCollection *new_schema = NULL;
1335 FIXME("(%p): semi-stub\n", This);
1336 switch(V_VT(&var1))
1338 case VT_UNKNOWN:
1339 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1340 break;
1342 case VT_DISPATCH:
1343 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1344 break;
1346 case VT_NULL:
1347 case VT_EMPTY:
1348 hr = S_OK;
1349 break;
1351 default:
1352 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1355 if(SUCCEEDED(hr))
1357 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1358 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1361 return hr;
1364 static HRESULT WINAPI domdoc_validate(
1365 IXMLDOMDocument2* iface,
1366 IXMLDOMParseError** err)
1368 FIXME("\n");
1369 return E_NOTIMPL;
1372 static HRESULT WINAPI domdoc_setProperty(
1373 IXMLDOMDocument2* iface,
1374 BSTR p,
1375 VARIANT var)
1377 FIXME("\n");
1378 return E_NOTIMPL;
1381 static HRESULT WINAPI domdoc_getProperty(
1382 IXMLDOMDocument2* iface,
1383 BSTR p,
1384 VARIANT* var)
1386 FIXME("\n");
1387 return E_NOTIMPL;
1390 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1392 domdoc_QueryInterface,
1393 domdoc_AddRef,
1394 domdoc_Release,
1395 domdoc_GetTypeInfoCount,
1396 domdoc_GetTypeInfo,
1397 domdoc_GetIDsOfNames,
1398 domdoc_Invoke,
1399 domdoc_get_nodeName,
1400 domdoc_get_nodeValue,
1401 domdoc_put_nodeValue,
1402 domdoc_get_nodeType,
1403 domdoc_get_parentNode,
1404 domdoc_get_childNodes,
1405 domdoc_get_firstChild,
1406 domdoc_get_lastChild,
1407 domdoc_get_previousSibling,
1408 domdoc_get_nextSibling,
1409 domdoc_get_attributes,
1410 domdoc_insertBefore,
1411 domdoc_replaceChild,
1412 domdoc_removeChild,
1413 domdoc_appendChild,
1414 domdoc_hasChildNodes,
1415 domdoc_get_ownerDocument,
1416 domdoc_cloneNode,
1417 domdoc_get_nodeTypeString,
1418 domdoc_get_text,
1419 domdoc_put_text,
1420 domdoc_get_specified,
1421 domdoc_get_definition,
1422 domdoc_get_nodeTypedValue,
1423 domdoc_put_nodeTypedValue,
1424 domdoc_get_dataType,
1425 domdoc_put_dataType,
1426 domdoc_get_xml,
1427 domdoc_transformNode,
1428 domdoc_selectNodes,
1429 domdoc_selectSingleNode,
1430 domdoc_get_parsed,
1431 domdoc_get_namespaceURI,
1432 domdoc_get_prefix,
1433 domdoc_get_baseName,
1434 domdoc_transformNodeToObject,
1435 domdoc_get_doctype,
1436 domdoc_get_implementation,
1437 domdoc_get_documentElement,
1438 domdoc_documentElement,
1439 domdoc_createElement,
1440 domdoc_createDocumentFragment,
1441 domdoc_createTextNode,
1442 domdoc_createComment,
1443 domdoc_createCDATASection,
1444 domdoc_createProcessingInstruction,
1445 domdoc_createAttribute,
1446 domdoc_createEntityReference,
1447 domdoc_getElementsByTagName,
1448 domdoc_createNode,
1449 domdoc_nodeFromID,
1450 domdoc_load,
1451 domdoc_get_readyState,
1452 domdoc_get_parseError,
1453 domdoc_get_url,
1454 domdoc_get_async,
1455 domdoc_put_async,
1456 domdoc_abort,
1457 domdoc_loadXML,
1458 domdoc_save,
1459 domdoc_get_validateOnParse,
1460 domdoc_put_validateOnParse,
1461 domdoc_get_resolveExternals,
1462 domdoc_put_resolveExternals,
1463 domdoc_get_preserveWhiteSpace,
1464 domdoc_put_preserveWhiteSpace,
1465 domdoc_put_onReadyStateChange,
1466 domdoc_put_onDataAvailable,
1467 domdoc_put_onTransformNode,
1468 domdoc_get_namespaces,
1469 domdoc_get_schemas,
1470 domdoc_putref_schemas,
1471 domdoc_validate,
1472 domdoc_setProperty,
1473 domdoc_getProperty
1476 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1478 domdoc *doc;
1479 HRESULT hr;
1480 xmlDocPtr xmldoc;
1482 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1484 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1485 if( !doc )
1486 return E_OUTOFMEMORY;
1488 doc->lpVtbl = &domdoc_vtbl;
1489 doc->ref = 1;
1490 doc->async = 0;
1491 doc->validating = 0;
1492 doc->resolving = 0;
1493 doc->preserving = 0;
1494 doc->error = S_OK;
1495 doc->schema = NULL;
1497 xmldoc = xmlNewDoc(NULL);
1498 if(!xmldoc)
1500 HeapFree(GetProcessHeap(), 0, doc);
1501 return E_OUTOFMEMORY;
1504 xmldoc->_private = 0;
1506 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1507 if(!doc->node_unk)
1509 xmlFreeDoc(xmldoc);
1510 HeapFree(GetProcessHeap(), 0, doc);
1511 return E_FAIL;
1514 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1515 if(FAILED(hr))
1517 IUnknown_Release(doc->node_unk);
1518 HeapFree( GetProcessHeap(), 0, doc );
1519 return E_FAIL;
1521 /* The ref on doc->node is actually looped back into this object, so release it */
1522 IXMLDOMNode_Release(doc->node);
1524 *ppObj = &doc->lpVtbl;
1526 TRACE("returning iface %p\n", *ppObj);
1527 return S_OK;
1530 #else
1532 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1534 MESSAGE("This program tried to use a DOMDocument object, but\n"
1535 "libxml2 support was not present at compile time.\n");
1536 return E_NOTIMPL;
1539 #endif