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
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
43 #include "msxml_private.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
49 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};
50 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
51 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
53 typedef struct bsc_t bsc_t;
55 typedef struct _domdoc
57 const struct IXMLDOMDocument2Vtbl *lpVtbl;
58 const struct IPersistStreamVtbl *lpvtblIPersistStream;
59 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
60 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
63 VARIANT_BOOL validating;
64 VARIANT_BOOL resolving;
65 VARIANT_BOOL preserving;
69 IXMLDOMSchemaCollection *schema;
84 const struct IBindStatusCallbackVtbl *lpVtbl;
93 static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
95 return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl));
98 static xmlDocPtr doparse( char *ptr, int len )
100 #ifdef HAVE_XMLREADMEMORY
102 * use xmlReadMemory if possible so we can suppress
103 * writing errors to stderr
105 return xmlReadMemory( ptr, len, NULL, NULL,
106 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
108 return xmlParseMemory( ptr, len );
112 static HRESULT WINAPI bsc_QueryInterface(
113 IBindStatusCallback *iface,
117 if (IsEqualGUID(riid, &IID_IUnknown) ||
118 IsEqualGUID(riid, &IID_IBindStatusCallback))
120 IBindStatusCallback_AddRef( iface );
125 FIXME("interface %s not implemented\n", debugstr_guid(riid));
126 return E_NOINTERFACE;
129 static ULONG WINAPI bsc_AddRef(
130 IBindStatusCallback *iface )
132 bsc_t *This = impl_from_IBindStatusCallback(iface);
133 LONG ref = InterlockedIncrement(&This->ref);
135 TRACE("(%p) ref=%d\n", This, ref);
140 static ULONG WINAPI bsc_Release(
141 IBindStatusCallback *iface )
143 bsc_t *This = impl_from_IBindStatusCallback(iface);
144 LONG ref = InterlockedDecrement(&This->ref);
146 TRACE("(%p) ref=%d\n", This, ref);
150 IBinding_Release(This->binding);
151 if(This->doc && This->doc->bsc == This)
152 This->doc->bsc = NULL;
154 IStream_Release(This->memstream);
155 HeapFree(GetProcessHeap(), 0, This);
161 static HRESULT WINAPI bsc_OnStartBinding(
162 IBindStatusCallback* iface,
166 bsc_t *This = impl_from_IBindStatusCallback(iface);
169 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
172 IBindStatusCallback_AddRef(pib);
174 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
181 static HRESULT WINAPI bsc_GetPriority(
182 IBindStatusCallback* iface,
188 static HRESULT WINAPI bsc_OnLowResource(
189 IBindStatusCallback* iface,
195 static HRESULT WINAPI bsc_OnProgress(
196 IBindStatusCallback* iface,
200 LPCWSTR szStatusText)
205 static HRESULT WINAPI bsc_OnStopBinding(
206 IBindStatusCallback* iface,
210 bsc_t *This = impl_from_IBindStatusCallback(iface);
213 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
216 IBinding_Release(This->binding);
217 This->binding = NULL;
220 if(This->doc && SUCCEEDED(hresult)) {
222 hr = GetHGlobalFromStream(This->memstream, &hglobal);
225 DWORD len = GlobalSize(hglobal);
226 char *ptr = GlobalLock(hglobal);
229 xmldoc = doparse( ptr, len );
231 xmldoc->_private = 0;
232 attach_xmlnode(This->doc->node, (xmlNodePtr) xmldoc);
235 GlobalUnlock(hglobal);
242 static HRESULT WINAPI bsc_GetBindInfo(
243 IBindStatusCallback* iface,
247 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
252 static HRESULT WINAPI bsc_OnDataAvailable(
253 IBindStatusCallback* iface,
256 FORMATETC* pformatetc,
259 bsc_t *This = impl_from_IBindStatusCallback(iface);
264 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
268 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
272 hr = IStream_Write(This->memstream, buf, read, &written);
273 } while(SUCCEEDED(hr) && written != 0 && read != 0);
278 static HRESULT WINAPI bsc_OnObjectAvailable(
279 IBindStatusCallback* iface,
286 static const struct IBindStatusCallbackVtbl bsc_vtbl =
298 bsc_OnObjectAvailable
301 static bsc_t *create_bsc(domdoc *doc)
303 bsc_t *bsc = HeapAlloc(GetProcessHeap(), 0, sizeof(bsc_t));
305 bsc->lpVtbl = &bsc_vtbl;
309 bsc->memstream = NULL;
314 LONG xmldoc_add_ref(xmlDocPtr doc)
316 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
321 LONG xmldoc_release(xmlDocPtr doc)
323 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
327 TRACE("freeing docptr %p\n", doc);
334 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
336 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
339 static inline xmlDocPtr get_doc( domdoc *This )
341 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
344 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
346 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
349 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
351 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
354 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
356 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
360 /************************************************************************
361 * xmldoc implementation of IPersistStream.
363 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
364 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
366 domdoc *this = impl_from_IPersistStream(iface);
367 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
370 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
371 IPersistStream *iface)
373 domdoc *this = impl_from_IPersistStream(iface);
374 return IXMLDocument_AddRef((IXMLDocument *)this);
377 static ULONG WINAPI xmldoc_IPersistStream_Release(
378 IPersistStream *iface)
380 domdoc *this = impl_from_IPersistStream(iface);
381 return IXMLDocument_Release((IXMLDocument *)this);
384 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
385 IPersistStream *iface, CLSID *classid)
387 TRACE("(%p,%p): stub!\n", iface, classid);
392 *classid = CLSID_DOMDocument2;
397 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
398 IPersistStream *iface)
400 domdoc *This = impl_from_IPersistStream(iface);
402 FIXME("(%p->%p): stub!\n", iface, This);
407 static HRESULT WINAPI xmldoc_IPersistStream_Load(
408 IPersistStream *iface, LPSTREAM pStm)
410 domdoc *This = impl_from_IPersistStream(iface);
413 DWORD read, written, len;
416 xmlDocPtr xmldoc = NULL;
418 TRACE("(%p, %p)\n", iface, pStm);
423 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
429 IStream_Read(pStm, buf, sizeof(buf), &read);
430 hr = IStream_Write(This->stream, buf, read, &written);
431 } while(SUCCEEDED(hr) && written != 0 && read != 0);
435 ERR("Failed to copy stream\n");
439 hr = GetHGlobalFromStream(This->stream, &hglobal);
443 len = GlobalSize(hglobal);
444 ptr = GlobalLock(hglobal);
446 xmldoc = parse_xml(ptr, len);
447 GlobalUnlock(hglobal);
451 ERR("Failed to parse xml\n");
455 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
460 static HRESULT WINAPI xmldoc_IPersistStream_Save(
461 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
463 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
467 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
468 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
470 TRACE("(%p, %p): stub!\n", iface, pcbSize);
474 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
476 xmldoc_IPersistStream_QueryInterface,
477 xmldoc_IPersistStream_AddRef,
478 xmldoc_IPersistStream_Release,
479 xmldoc_IPersistStream_GetClassID,
480 xmldoc_IPersistStream_IsDirty,
481 xmldoc_IPersistStream_Load,
482 xmldoc_IPersistStream_Save,
483 xmldoc_IPersistStream_GetSizeMax,
486 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
488 domdoc *This = impl_from_IXMLDOMDocument2( iface );
490 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
494 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
495 IsEqualGUID( riid, &IID_IDispatch ) ||
496 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
497 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
501 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
503 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
505 else if (IsEqualGUID(&IID_IPersistStream, riid))
507 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
509 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
511 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
513 else if(IsEqualGUID(&IID_IRunnableObject, riid))
515 TRACE("IID_IRunnableObject not supported returning NULL\n");
516 return E_NOINTERFACE;
520 FIXME("interface %s not implemented\n", debugstr_guid(riid));
521 return E_NOINTERFACE;
524 IXMLDOMDocument_AddRef( iface );
530 static ULONG WINAPI domdoc_AddRef(
531 IXMLDOMDocument2 *iface )
533 domdoc *This = impl_from_IXMLDOMDocument2( iface );
534 TRACE("%p\n", This );
535 return InterlockedIncrement( &This->ref );
539 static ULONG WINAPI domdoc_Release(
540 IXMLDOMDocument2 *iface )
542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
545 TRACE("%p\n", This );
547 ref = InterlockedDecrement( &This->ref );
551 if(This->bsc->binding)
552 IBinding_Abort(This->bsc->binding);
553 This->bsc->doc = NULL;
554 IBindStatusCallback_Release((IBindStatusCallback*)&This->bsc->lpVtbl);
558 IUnknown_Release( This->site );
559 IUnknown_Release( This->node_unk );
560 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
561 if (This->stream) IStream_Release(This->stream);
562 HeapFree( GetProcessHeap(), 0, This );
568 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
572 TRACE("(%p)->(%p)\n", This, pctinfo);
579 static HRESULT WINAPI domdoc_GetTypeInfo(
580 IXMLDOMDocument2 *iface,
581 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
583 domdoc *This = impl_from_IXMLDOMDocument2( iface );
586 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
588 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
593 static HRESULT WINAPI domdoc_GetIDsOfNames(
594 IXMLDOMDocument2 *iface,
601 domdoc *This = impl_from_IXMLDOMDocument2( iface );
605 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
608 if(!rgszNames || cNames == 0 || !rgDispId)
611 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
614 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
615 ITypeInfo_Release(typeinfo);
622 static HRESULT WINAPI domdoc_Invoke(
623 IXMLDOMDocument2 *iface,
628 DISPPARAMS* pDispParams,
630 EXCEPINFO* pExcepInfo,
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
637 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
638 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
640 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
643 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
644 pVarResult, pExcepInfo, puArgErr);
645 ITypeInfo_Release(typeinfo);
652 static HRESULT WINAPI domdoc_get_nodeName(
653 IXMLDOMDocument2 *iface,
656 domdoc *This = impl_from_IXMLDOMDocument2( iface );
657 return IXMLDOMNode_get_nodeName( This->node, name );
661 static HRESULT WINAPI domdoc_get_nodeValue(
662 IXMLDOMDocument2 *iface,
665 domdoc *This = impl_from_IXMLDOMDocument2( iface );
666 return IXMLDOMNode_get_nodeValue( This->node, value );
670 static HRESULT WINAPI domdoc_put_nodeValue(
671 IXMLDOMDocument2 *iface,
674 domdoc *This = impl_from_IXMLDOMDocument2( iface );
675 return IXMLDOMNode_put_nodeValue( This->node, value );
679 static HRESULT WINAPI domdoc_get_nodeType(
680 IXMLDOMDocument2 *iface,
683 domdoc *This = impl_from_IXMLDOMDocument2( iface );
684 return IXMLDOMNode_get_nodeType( This->node, type );
688 static HRESULT WINAPI domdoc_get_parentNode(
689 IXMLDOMDocument2 *iface,
690 IXMLDOMNode** parent )
692 domdoc *This = impl_from_IXMLDOMDocument2( iface );
693 return IXMLDOMNode_get_parentNode( This->node, parent );
697 static HRESULT WINAPI domdoc_get_childNodes(
698 IXMLDOMDocument2 *iface,
699 IXMLDOMNodeList** childList )
701 domdoc *This = impl_from_IXMLDOMDocument2( iface );
702 return IXMLDOMNode_get_childNodes( This->node, childList );
706 static HRESULT WINAPI domdoc_get_firstChild(
707 IXMLDOMDocument2 *iface,
708 IXMLDOMNode** firstChild )
710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
711 return IXMLDOMNode_get_firstChild( This->node, firstChild );
715 static HRESULT WINAPI domdoc_get_lastChild(
716 IXMLDOMDocument2 *iface,
717 IXMLDOMNode** lastChild )
719 domdoc *This = impl_from_IXMLDOMDocument2( iface );
720 return IXMLDOMNode_get_lastChild( This->node, lastChild );
724 static HRESULT WINAPI domdoc_get_previousSibling(
725 IXMLDOMDocument2 *iface,
726 IXMLDOMNode** previousSibling )
728 domdoc *This = impl_from_IXMLDOMDocument2( iface );
729 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
733 static HRESULT WINAPI domdoc_get_nextSibling(
734 IXMLDOMDocument2 *iface,
735 IXMLDOMNode** nextSibling )
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
742 static HRESULT WINAPI domdoc_get_attributes(
743 IXMLDOMDocument2 *iface,
744 IXMLDOMNamedNodeMap** attributeMap )
746 domdoc *This = impl_from_IXMLDOMDocument2( iface );
747 return IXMLDOMNode_get_attributes( This->node, attributeMap );
751 static HRESULT WINAPI domdoc_insertBefore(
752 IXMLDOMDocument2 *iface,
753 IXMLDOMNode* newChild,
755 IXMLDOMNode** outNewChild )
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
762 static HRESULT WINAPI domdoc_replaceChild(
763 IXMLDOMDocument2 *iface,
764 IXMLDOMNode* newChild,
765 IXMLDOMNode* oldChild,
766 IXMLDOMNode** outOldChild)
768 domdoc *This = impl_from_IXMLDOMDocument2( iface );
769 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
773 static HRESULT WINAPI domdoc_removeChild(
774 IXMLDOMDocument2 *iface,
775 IXMLDOMNode* childNode,
776 IXMLDOMNode** oldChild)
778 domdoc *This = impl_from_IXMLDOMDocument2( iface );
779 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
783 static HRESULT WINAPI domdoc_appendChild(
784 IXMLDOMDocument2 *iface,
785 IXMLDOMNode* newChild,
786 IXMLDOMNode** outNewChild)
788 domdoc *This = impl_from_IXMLDOMDocument2( iface );
789 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
793 static HRESULT WINAPI domdoc_hasChildNodes(
794 IXMLDOMDocument2 *iface,
795 VARIANT_BOOL* hasChild)
797 domdoc *This = impl_from_IXMLDOMDocument2( iface );
798 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
802 static HRESULT WINAPI domdoc_get_ownerDocument(
803 IXMLDOMDocument2 *iface,
804 IXMLDOMDocument** DOMDocument)
806 domdoc *This = impl_from_IXMLDOMDocument2( iface );
807 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
811 static HRESULT WINAPI domdoc_cloneNode(
812 IXMLDOMDocument2 *iface,
814 IXMLDOMNode** cloneRoot)
816 domdoc *This = impl_from_IXMLDOMDocument2( iface );
817 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
821 static HRESULT WINAPI domdoc_get_nodeTypeString(
822 IXMLDOMDocument2 *iface,
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
826 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
830 static HRESULT WINAPI domdoc_get_text(
831 IXMLDOMDocument2 *iface,
834 domdoc *This = impl_from_IXMLDOMDocument2( iface );
835 return IXMLDOMNode_get_text( This->node, text );
839 static HRESULT WINAPI domdoc_put_text(
840 IXMLDOMDocument2 *iface,
843 domdoc *This = impl_from_IXMLDOMDocument2( iface );
844 return IXMLDOMNode_put_text( This->node, text );
848 static HRESULT WINAPI domdoc_get_specified(
849 IXMLDOMDocument2 *iface,
850 VARIANT_BOOL* isSpecified )
852 domdoc *This = impl_from_IXMLDOMDocument2( iface );
853 return IXMLDOMNode_get_specified( This->node, isSpecified );
857 static HRESULT WINAPI domdoc_get_definition(
858 IXMLDOMDocument2 *iface,
859 IXMLDOMNode** definitionNode )
861 domdoc *This = impl_from_IXMLDOMDocument2( iface );
862 return IXMLDOMNode_get_definition( This->node, definitionNode );
866 static HRESULT WINAPI domdoc_get_nodeTypedValue(
867 IXMLDOMDocument2 *iface,
868 VARIANT* typedValue )
870 domdoc *This = impl_from_IXMLDOMDocument2( iface );
871 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
874 static HRESULT WINAPI domdoc_put_nodeTypedValue(
875 IXMLDOMDocument2 *iface,
878 domdoc *This = impl_from_IXMLDOMDocument2( iface );
879 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
883 static HRESULT WINAPI domdoc_get_dataType(
884 IXMLDOMDocument2 *iface,
885 VARIANT* dataTypeName )
887 domdoc *This = impl_from_IXMLDOMDocument2( iface );
888 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
892 static HRESULT WINAPI domdoc_put_dataType(
893 IXMLDOMDocument2 *iface,
896 domdoc *This = impl_from_IXMLDOMDocument2( iface );
897 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
901 static HRESULT WINAPI domdoc_get_xml(
902 IXMLDOMDocument2 *iface,
905 domdoc *This = impl_from_IXMLDOMDocument2( iface );
906 return IXMLDOMNode_get_xml( This->node, xmlString );
910 static HRESULT WINAPI domdoc_transformNode(
911 IXMLDOMDocument2 *iface,
912 IXMLDOMNode* styleSheet,
915 domdoc *This = impl_from_IXMLDOMDocument2( iface );
916 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
920 static HRESULT WINAPI domdoc_selectNodes(
921 IXMLDOMDocument2 *iface,
923 IXMLDOMNodeList** resultList )
925 domdoc *This = impl_from_IXMLDOMDocument2( iface );
926 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
930 static HRESULT WINAPI domdoc_selectSingleNode(
931 IXMLDOMDocument2 *iface,
933 IXMLDOMNode** resultNode )
935 domdoc *This = impl_from_IXMLDOMDocument2( iface );
936 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
940 static HRESULT WINAPI domdoc_get_parsed(
941 IXMLDOMDocument2 *iface,
942 VARIANT_BOOL* isParsed )
944 domdoc *This = impl_from_IXMLDOMDocument2( iface );
945 return IXMLDOMNode_get_parsed( This->node, isParsed );
949 static HRESULT WINAPI domdoc_get_namespaceURI(
950 IXMLDOMDocument2 *iface,
953 domdoc *This = impl_from_IXMLDOMDocument2( iface );
954 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
958 static HRESULT WINAPI domdoc_get_prefix(
959 IXMLDOMDocument2 *iface,
962 domdoc *This = impl_from_IXMLDOMDocument2( iface );
963 return IXMLDOMNode_get_prefix( This->node, prefixString );
967 static HRESULT WINAPI domdoc_get_baseName(
968 IXMLDOMDocument2 *iface,
971 domdoc *This = impl_from_IXMLDOMDocument2( iface );
972 return IXMLDOMNode_get_baseName( This->node, nameString );
976 static HRESULT WINAPI domdoc_transformNodeToObject(
977 IXMLDOMDocument2 *iface,
978 IXMLDOMNode* stylesheet,
979 VARIANT outputObject)
981 domdoc *This = impl_from_IXMLDOMDocument2( iface );
982 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
986 static HRESULT WINAPI domdoc_get_doctype(
987 IXMLDOMDocument2 *iface,
988 IXMLDOMDocumentType** documentType )
995 static HRESULT WINAPI domdoc_get_implementation(
996 IXMLDOMDocument2 *iface,
997 IXMLDOMImplementation** impl )
1000 return E_INVALIDARG;
1002 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1007 static HRESULT WINAPI domdoc_get_documentElement(
1008 IXMLDOMDocument2 *iface,
1009 IXMLDOMElement** DOMElement )
1011 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1012 xmlDocPtr xmldoc = NULL;
1013 xmlNodePtr root = NULL;
1014 IXMLDOMNode *element_node;
1017 TRACE("%p %p\n", This, This->node);
1020 return E_INVALIDARG;
1024 xmldoc = get_doc( This );
1026 root = xmlDocGetRootElement( xmldoc );
1030 element_node = create_node( root );
1031 if(!element_node) return S_FALSE;
1033 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
1034 IXMLDOMNode_Release(element_node);
1040 static HRESULT WINAPI domdoc_put_documentElement(
1041 IXMLDOMDocument2 *iface,
1042 IXMLDOMElement* DOMElement )
1044 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1045 IXMLDOMNode *elementNode;
1049 TRACE("(%p)->(%p)\n", This, DOMElement);
1051 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1055 xmlNode = impl_from_IXMLDOMNode( elementNode );
1056 xmlDocSetRootElement( get_doc(This), xmlNode->node);
1057 IXMLDOMNode_Release( elementNode );
1063 static HRESULT WINAPI domdoc_createElement(
1064 IXMLDOMDocument2 *iface,
1066 IXMLDOMElement** element )
1069 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1074 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1076 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
1077 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1079 TRACE("created xmlptr %p\n", xmlnode);
1080 elem_unk = create_element(xmlnode, NULL);
1081 HeapFree(GetProcessHeap(), 0, xml_name);
1083 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1084 IUnknown_Release(elem_unk);
1085 TRACE("returning %p\n", *element);
1090 static HRESULT WINAPI domdoc_createDocumentFragment(
1091 IXMLDOMDocument2 *iface,
1092 IXMLDOMDocumentFragment** docFrag )
1094 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1097 TRACE("%p\n", iface);
1100 return E_INVALIDARG;
1104 xmlnode = xmlNewDocFragment(get_doc( This ) );
1109 xmlnode->doc = get_doc( This );
1111 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1117 static HRESULT WINAPI domdoc_createTextNode(
1118 IXMLDOMDocument2 *iface,
1120 IXMLDOMText** text )
1122 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1124 xmlChar *xml_content;
1126 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1129 return E_INVALIDARG;
1133 xml_content = xmlChar_from_wchar((WCHAR*)data);
1134 xmlnode = xmlNewText(xml_content);
1135 HeapFree(GetProcessHeap(), 0, xml_content);
1140 xmlnode->doc = get_doc( This );
1142 *text = (IXMLDOMText*)create_text(xmlnode);
1148 static HRESULT WINAPI domdoc_createComment(
1149 IXMLDOMDocument2 *iface,
1151 IXMLDOMComment** comment )
1153 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1155 xmlChar *xml_content;
1157 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1160 return E_INVALIDARG;
1164 xml_content = xmlChar_from_wchar((WCHAR*)data);
1165 xmlnode = xmlNewComment(xml_content);
1166 HeapFree(GetProcessHeap(), 0, xml_content);
1171 xmlnode->doc = get_doc( This );
1173 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1179 static HRESULT WINAPI domdoc_createCDATASection(
1180 IXMLDOMDocument2 *iface,
1182 IXMLDOMCDATASection** cdata )
1184 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1186 xmlChar *xml_content;
1188 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1191 return E_INVALIDARG;
1195 xml_content = xmlChar_from_wchar((WCHAR*)data);
1196 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1197 HeapFree(GetProcessHeap(), 0, xml_content);
1202 xmlnode->doc = get_doc( This );
1204 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1210 static HRESULT WINAPI domdoc_createProcessingInstruction(
1211 IXMLDOMDocument2 *iface,
1214 IXMLDOMProcessingInstruction** pi )
1216 #ifdef HAVE_XMLNEWDOCPI
1218 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1219 xmlChar *xml_target, *xml_content;
1221 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1224 return E_INVALIDARG;
1226 if(!target || lstrlenW(target) == 0)
1229 xml_target = xmlChar_from_wchar((WCHAR*)target);
1230 xml_content = xmlChar_from_wchar((WCHAR*)data);
1232 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1233 TRACE("created xmlptr %p\n", xmlnode);
1234 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1236 HeapFree(GetProcessHeap(), 0, xml_content);
1237 HeapFree(GetProcessHeap(), 0, xml_target);
1241 FIXME("Libxml 2.6.15 or greater required.\n");
1247 static HRESULT WINAPI domdoc_createAttribute(
1248 IXMLDOMDocument2 *iface,
1250 IXMLDOMAttribute** attribute )
1252 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1256 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1259 return E_INVALIDARG;
1263 xml_name = xmlChar_from_wchar((WCHAR*)name);
1264 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1265 HeapFree(GetProcessHeap(), 0, xml_name);
1270 xmlnode->doc = get_doc( This );
1272 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1278 static HRESULT WINAPI domdoc_createEntityReference(
1279 IXMLDOMDocument2 *iface,
1281 IXMLDOMEntityReference** entityRef )
1283 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1287 TRACE("%p\n", iface);
1290 return E_INVALIDARG;
1294 xml_name = xmlChar_from_wchar((WCHAR*)name);
1295 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1296 HeapFree(GetProcessHeap(), 0, xml_name);
1301 xmlnode->doc = get_doc( This );
1303 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1309 static HRESULT WINAPI domdoc_getElementsByTagName(
1310 IXMLDOMDocument2 *iface,
1312 IXMLDOMNodeList** resultList )
1314 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1317 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1319 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1320 szPattern[0] = szPattern[1] = '/';
1321 lstrcpyW(szPattern + 2, tagName);
1323 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1324 HeapFree(GetProcessHeap(), 0, szPattern);
1329 static DOMNodeType get_node_type(VARIANT Type)
1331 if(V_VT(&Type) == VT_I4)
1334 FIXME("Unsupported variant type %x\n", V_VT(&Type));
1338 static HRESULT WINAPI domdoc_createNode(
1339 IXMLDOMDocument2 *iface,
1343 IXMLDOMNode** node )
1345 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1346 DOMNodeType node_type;
1347 xmlNodePtr xmlnode = NULL;
1350 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1352 node_type = get_node_type(Type);
1353 TRACE("node_type %d\n", node_type);
1355 xml_name = xmlChar_from_wchar((WCHAR*)name);
1360 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1361 *node = create_node(xmlnode);
1362 TRACE("created %p\n", xmlnode);
1364 case NODE_ATTRIBUTE:
1365 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1368 xmlnode->doc = get_doc( This );
1370 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1373 TRACE("created %p\n", xmlnode);
1377 FIXME("unhandled node type %d\n", node_type);
1381 HeapFree(GetProcessHeap(), 0, xml_name);
1383 if(xmlnode && *node)
1389 static HRESULT WINAPI domdoc_nodeFromID(
1390 IXMLDOMDocument2 *iface,
1392 IXMLDOMNode** node )
1398 static HRESULT doread( domdoc *This, LPWSTR filename )
1402 WCHAR url[INTERNET_MAX_URL_LENGTH];
1404 TRACE("%s\n", debugstr_w( filename ));
1406 if(!PathIsURLW(filename))
1408 WCHAR fullpath[MAX_PATH];
1409 DWORD needed = sizeof(url)/sizeof(WCHAR);
1411 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
1413 WARN("can't find path\n");
1417 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
1419 ERR("can't create url from path\n");
1425 hr = CreateBindCtx(0, &pbc);
1429 if(This->bsc->binding)
1430 IBinding_Abort(This->bsc->binding);
1431 This->bsc->doc = NULL;
1432 IBindStatusCallback_Release((IBindStatusCallback*)&This->bsc->lpVtbl);
1435 This->bsc = create_bsc(This);
1437 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&This->bsc->lpVtbl, NULL, 0);
1441 hr = CreateURLMoniker(NULL, filename, &moniker);
1445 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
1446 IMoniker_Release(moniker);
1448 IStream_Release(stream);
1451 IBindCtx_Release(pbc);
1457 static HRESULT WINAPI domdoc_load(
1458 IXMLDOMDocument2 *iface,
1460 VARIANT_BOOL* isSuccessful )
1462 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1463 LPWSTR filename = NULL;
1464 HRESULT hr = S_FALSE;
1465 IXMLDOMDocument2 *pNewDoc = NULL;
1466 IStream *pStream = NULL;
1469 TRACE("type %d\n", V_VT(&xmlSource) );
1471 *isSuccessful = VARIANT_FALSE;
1473 assert( This->node );
1475 attach_xmlnode(This->node, NULL);
1477 switch( V_VT(&xmlSource) )
1480 filename = V_BSTR(&xmlSource);
1483 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1488 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1489 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1490 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1492 *isSuccessful = VARIANT_TRUE;
1497 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1500 IPersistStream *pDocStream;
1501 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1504 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1505 IStream_Release(pStream);
1508 *isSuccessful = VARIANT_TRUE;
1510 TRACE("Using ID_IStream to load Document\n");
1515 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1520 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1525 /* ISequentialStream */
1526 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1530 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1533 TRACE("filename (%s)\n", debugstr_w(filename));
1537 hr = doread( This, filename );
1540 This->error = E_FAIL;
1543 hr = This->error = S_OK;
1544 *isSuccessful = VARIANT_TRUE;
1548 if(!filename || FAILED(hr)) {
1549 xmldoc = xmlNewDoc(NULL);
1550 xmldoc->_private = 0;
1551 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1555 TRACE("ret (%d)\n", hr);
1561 static HRESULT WINAPI domdoc_get_readyState(
1562 IXMLDOMDocument2 *iface,
1570 static HRESULT WINAPI domdoc_get_parseError(
1571 IXMLDOMDocument2 *iface,
1572 IXMLDOMParseError** errorObj )
1574 BSTR error_string = NULL;
1575 static const WCHAR err[] = {'e','r','r','o','r',0};
1576 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1578 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1581 error_string = SysAllocString(err);
1583 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1584 if(!*errorObj) return E_OUTOFMEMORY;
1589 static HRESULT WINAPI domdoc_get_url(
1590 IXMLDOMDocument2 *iface,
1598 static HRESULT WINAPI domdoc_get_async(
1599 IXMLDOMDocument2 *iface,
1600 VARIANT_BOOL* isAsync )
1602 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1604 TRACE("%p <- %d\n", isAsync, This->async);
1605 *isAsync = This->async;
1610 static HRESULT WINAPI domdoc_put_async(
1611 IXMLDOMDocument2 *iface,
1612 VARIANT_BOOL isAsync )
1614 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1616 TRACE("%d\n", isAsync);
1617 This->async = isAsync;
1622 static HRESULT WINAPI domdoc_abort(
1623 IXMLDOMDocument2 *iface )
1630 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1632 UINT len, blen = SysStringLen( bstr );
1635 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1636 str = HeapAlloc( GetProcessHeap(), 0, len );
1639 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1645 static HRESULT WINAPI domdoc_loadXML(
1646 IXMLDOMDocument2 *iface,
1648 VARIANT_BOOL* isSuccessful )
1650 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1651 xmlDocPtr xmldoc = NULL;
1654 HRESULT hr = S_FALSE;
1656 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1658 assert ( This->node );
1660 attach_xmlnode( This->node, NULL );
1664 *isSuccessful = VARIANT_FALSE;
1666 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1668 xmldoc = doparse( str, len );
1669 HeapFree( GetProcessHeap(), 0, str );
1671 This->error = E_FAIL;
1674 hr = This->error = S_OK;
1675 *isSuccessful = VARIANT_TRUE;
1680 xmldoc = xmlNewDoc(NULL);
1682 xmldoc->_private = 0;
1683 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1689 static HRESULT WINAPI domdoc_save(
1690 IXMLDOMDocument2 *iface,
1691 VARIANT destination )
1693 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1700 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1701 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1703 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1705 FIXME("Unhandled vt %d\n", V_VT(&destination));
1709 if(V_VT(&destination) == VT_UNKNOWN)
1711 IUnknown *pUnk = V_UNKNOWN(&destination);
1712 IXMLDOMDocument *pDocument;
1714 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1718 VARIANT_BOOL bSuccessful;
1720 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1723 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1725 SysFreeString(bXML);
1728 IXMLDOMDocument_Release(pDocument);
1734 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1735 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1736 if( handle == INVALID_HANDLE_VALUE )
1738 WARN("failed to create file\n");
1742 xmlDocDumpMemory(get_doc(This), &mem, &size);
1745 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1746 * MSXML adds XML declaration only for processing instruction nodes.
1747 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1750 if(size > 2 && p[0] == '<' && p[1] == '?') {
1751 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1754 while(p < mem+size && isspace(*p))
1759 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1761 WARN("write error\n");
1766 CloseHandle(handle);
1770 static HRESULT WINAPI domdoc_get_validateOnParse(
1771 IXMLDOMDocument2 *iface,
1772 VARIANT_BOOL* isValidating )
1774 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1776 TRACE("%p <- %d\n", isValidating, This->validating);
1777 *isValidating = This->validating;
1782 static HRESULT WINAPI domdoc_put_validateOnParse(
1783 IXMLDOMDocument2 *iface,
1784 VARIANT_BOOL isValidating )
1786 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1788 TRACE("%d\n", isValidating);
1789 This->validating = isValidating;
1794 static HRESULT WINAPI domdoc_get_resolveExternals(
1795 IXMLDOMDocument2 *iface,
1796 VARIANT_BOOL* isResolving )
1798 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1800 TRACE("%p <- %d\n", isResolving, This->resolving);
1801 *isResolving = This->resolving;
1806 static HRESULT WINAPI domdoc_put_resolveExternals(
1807 IXMLDOMDocument2 *iface,
1808 VARIANT_BOOL isResolving )
1810 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1812 TRACE("%d\n", isResolving);
1813 This->resolving = isResolving;
1818 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1819 IXMLDOMDocument2 *iface,
1820 VARIANT_BOOL* isPreserving )
1822 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1824 TRACE("%p <- %d\n", isPreserving, This->preserving);
1825 *isPreserving = This->preserving;
1830 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1831 IXMLDOMDocument2 *iface,
1832 VARIANT_BOOL isPreserving )
1834 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1836 TRACE("%d\n", isPreserving);
1837 This->preserving = isPreserving;
1842 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1843 IXMLDOMDocument2 *iface,
1844 VARIANT readyStateChangeSink )
1851 static HRESULT WINAPI domdoc_put_onDataAvailable(
1852 IXMLDOMDocument2 *iface,
1853 VARIANT onDataAvailableSink )
1859 static HRESULT WINAPI domdoc_put_onTransformNode(
1860 IXMLDOMDocument2 *iface,
1861 VARIANT onTransformNodeSink )
1867 static HRESULT WINAPI domdoc_get_namespaces(
1868 IXMLDOMDocument2* iface,
1869 IXMLDOMSchemaCollection** schemaCollection )
1875 static HRESULT WINAPI domdoc_get_schemas(
1876 IXMLDOMDocument2* iface,
1879 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1880 HRESULT hr = S_FALSE;
1881 IXMLDOMSchemaCollection *cur_schema = This->schema;
1883 TRACE("(%p)->(%p)\n", This, var1);
1885 VariantInit(var1); /* Test shows we don't call VariantClear here */
1886 V_VT(var1) = VT_NULL;
1890 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1892 V_VT(var1) = VT_DISPATCH;
1897 static HRESULT WINAPI domdoc_putref_schemas(
1898 IXMLDOMDocument2* iface,
1901 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1902 HRESULT hr = E_FAIL;
1903 IXMLDOMSchemaCollection *new_schema = NULL;
1905 FIXME("(%p): semi-stub\n", This);
1909 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1913 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1922 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1927 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1928 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1934 static HRESULT WINAPI domdoc_validate(
1935 IXMLDOMDocument2* iface,
1936 IXMLDOMParseError** err)
1942 static HRESULT WINAPI domdoc_setProperty(
1943 IXMLDOMDocument2* iface,
1947 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1949 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1955 V_VT(&varStr) = VT_EMPTY;
1956 if (V_VT(&var) != VT_BSTR)
1958 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1960 bstr = V_BSTR(&varStr);
1963 bstr = V_BSTR(&var);
1966 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1967 This->bUseXPath = TRUE;
1968 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1969 This->bUseXPath = FALSE;
1973 VariantClear(&varStr);
1977 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1981 static HRESULT WINAPI domdoc_getProperty(
1982 IXMLDOMDocument2* iface,
1986 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1989 return E_INVALIDARG;
1990 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1992 V_VT(var) = VT_BSTR;
1993 if (This->bUseXPath)
1994 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1996 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2000 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2004 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2006 domdoc_QueryInterface,
2009 domdoc_GetTypeInfoCount,
2011 domdoc_GetIDsOfNames,
2013 domdoc_get_nodeName,
2014 domdoc_get_nodeValue,
2015 domdoc_put_nodeValue,
2016 domdoc_get_nodeType,
2017 domdoc_get_parentNode,
2018 domdoc_get_childNodes,
2019 domdoc_get_firstChild,
2020 domdoc_get_lastChild,
2021 domdoc_get_previousSibling,
2022 domdoc_get_nextSibling,
2023 domdoc_get_attributes,
2024 domdoc_insertBefore,
2025 domdoc_replaceChild,
2028 domdoc_hasChildNodes,
2029 domdoc_get_ownerDocument,
2031 domdoc_get_nodeTypeString,
2034 domdoc_get_specified,
2035 domdoc_get_definition,
2036 domdoc_get_nodeTypedValue,
2037 domdoc_put_nodeTypedValue,
2038 domdoc_get_dataType,
2039 domdoc_put_dataType,
2041 domdoc_transformNode,
2043 domdoc_selectSingleNode,
2045 domdoc_get_namespaceURI,
2047 domdoc_get_baseName,
2048 domdoc_transformNodeToObject,
2050 domdoc_get_implementation,
2051 domdoc_get_documentElement,
2052 domdoc_put_documentElement,
2053 domdoc_createElement,
2054 domdoc_createDocumentFragment,
2055 domdoc_createTextNode,
2056 domdoc_createComment,
2057 domdoc_createCDATASection,
2058 domdoc_createProcessingInstruction,
2059 domdoc_createAttribute,
2060 domdoc_createEntityReference,
2061 domdoc_getElementsByTagName,
2065 domdoc_get_readyState,
2066 domdoc_get_parseError,
2073 domdoc_get_validateOnParse,
2074 domdoc_put_validateOnParse,
2075 domdoc_get_resolveExternals,
2076 domdoc_put_resolveExternals,
2077 domdoc_get_preserveWhiteSpace,
2078 domdoc_put_preserveWhiteSpace,
2079 domdoc_put_onReadyStateChange,
2080 domdoc_put_onDataAvailable,
2081 domdoc_put_onTransformNode,
2082 domdoc_get_namespaces,
2084 domdoc_putref_schemas,
2090 /* xmldoc implementation of IObjectWithSite */
2091 static HRESULT WINAPI
2092 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2094 domdoc *This = impl_from_IObjectWithSite(iface);
2095 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2099 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2101 domdoc *This = impl_from_IObjectWithSite(iface);
2102 return IXMLDocument_AddRef((IXMLDocument *)This);
2106 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2108 domdoc *This = impl_from_IObjectWithSite(iface);
2109 return IXMLDocument_Release((IXMLDocument *)This);
2112 static HRESULT WINAPI
2113 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2115 domdoc *This = impl_from_IObjectWithSite(iface);
2117 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2122 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2125 static HRESULT WINAPI
2126 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2128 domdoc *This = impl_from_IObjectWithSite(iface);
2130 TRACE("%p %p\n", iface, punk);
2136 IUnknown_Release( This->site );
2144 IUnknown_AddRef( punk );
2147 IUnknown_Release( This->site );
2154 static const IObjectWithSiteVtbl domdocObjectSite =
2156 xmldoc_ObjectWithSite_QueryInterface,
2157 xmldoc_ObjectWithSite_AddRef,
2158 xmldoc_ObjectWithSite_Release,
2163 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2165 domdoc *This = impl_from_IObjectSafety(iface);
2166 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2169 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2171 domdoc *This = impl_from_IObjectSafety(iface);
2172 return IXMLDocument_AddRef((IXMLDocument *)This);
2175 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2177 domdoc *This = impl_from_IObjectSafety(iface);
2178 return IXMLDocument_Release((IXMLDocument *)This);
2181 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2183 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2184 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2186 domdoc *This = impl_from_IObjectSafety(iface);
2188 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2190 if(!pdwSupportedOptions || !pdwEnabledOptions)
2193 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2194 *pdwEnabledOptions = This->safeopt;
2199 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2200 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2202 domdoc *This = impl_from_IObjectSafety(iface);
2204 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2206 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2209 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2213 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2214 xmldoc_Safety_QueryInterface,
2215 xmldoc_Safety_AddRef,
2216 xmldoc_Safety_Release,
2217 xmldoc_Safety_GetInterfaceSafetyOptions,
2218 xmldoc_Safety_SetInterfaceSafetyOptions
2221 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2226 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2228 return E_OUTOFMEMORY;
2230 doc->lpVtbl = &domdoc_vtbl;
2231 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2232 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2233 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2236 doc->validating = 0;
2238 doc->preserving = 0;
2239 doc->bUseXPath = FALSE;
2247 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2250 HeapFree(GetProcessHeap(), 0, doc);
2254 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2257 IUnknown_Release(doc->node_unk);
2258 HeapFree( GetProcessHeap(), 0, doc );
2261 /* The ref on doc->node is actually looped back into this object, so release it */
2262 IXMLDOMNode_Release(doc->node);
2264 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2266 TRACE("returning iface %p\n", *document);
2270 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2275 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2277 xmldoc = xmlNewDoc(NULL);
2279 return E_OUTOFMEMORY;
2281 xmldoc->_private = 0;
2283 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2292 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2294 MESSAGE("This program tried to use a DOMDocument object, but\n"
2295 "libxml2 support was not present at compile time.\n");