msxml3: Implement IXMLDOMImplementation Interface.
[wine.git] / dlls / msxml3 / domdoc.c
blob6a5b7a45c0c88cfee7ac17383358edae00f18632
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 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
47 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
48 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
50 typedef struct {
51 const struct IBindStatusCallbackVtbl *lpVtbl;
52 } bsc;
54 static HRESULT WINAPI bsc_QueryInterface(
55 IBindStatusCallback *iface,
56 REFIID riid,
57 LPVOID *ppobj )
59 if (IsEqualGUID(riid, &IID_IUnknown) ||
60 IsEqualGUID(riid, &IID_IBindStatusCallback))
62 IBindStatusCallback_AddRef( iface );
63 *ppobj = iface;
64 return S_OK;
67 FIXME("interface %s not implemented\n", debugstr_guid(riid));
68 return E_NOINTERFACE;
71 static ULONG WINAPI bsc_AddRef(
72 IBindStatusCallback *iface )
74 return 2;
77 static ULONG WINAPI bsc_Release(
78 IBindStatusCallback *iface )
80 return 1;
83 static HRESULT WINAPI bsc_OnStartBinding(
84 IBindStatusCallback* iface,
85 DWORD dwReserved,
86 IBinding* pib)
88 return S_OK;
91 static HRESULT WINAPI bsc_GetPriority(
92 IBindStatusCallback* iface,
93 LONG* pnPriority)
95 return S_OK;
98 static HRESULT WINAPI bsc_OnLowResource(
99 IBindStatusCallback* iface,
100 DWORD reserved)
102 return S_OK;
105 static HRESULT WINAPI bsc_OnProgress(
106 IBindStatusCallback* iface,
107 ULONG ulProgress,
108 ULONG ulProgressMax,
109 ULONG ulStatusCode,
110 LPCWSTR szStatusText)
112 return S_OK;
115 static HRESULT WINAPI bsc_OnStopBinding(
116 IBindStatusCallback* iface,
117 HRESULT hresult,
118 LPCWSTR szError)
120 return S_OK;
123 static HRESULT WINAPI bsc_GetBindInfo(
124 IBindStatusCallback* iface,
125 DWORD* grfBINDF,
126 BINDINFO* pbindinfo)
128 *grfBINDF = BINDF_RESYNCHRONIZE;
130 return S_OK;
133 static HRESULT WINAPI bsc_OnDataAvailable(
134 IBindStatusCallback* iface,
135 DWORD grfBSCF,
136 DWORD dwSize,
137 FORMATETC* pformatetc,
138 STGMEDIUM* pstgmed)
140 return S_OK;
143 static HRESULT WINAPI bsc_OnObjectAvailable(
144 IBindStatusCallback* iface,
145 REFIID riid,
146 IUnknown* punk)
148 return S_OK;
151 static const struct IBindStatusCallbackVtbl bsc_vtbl =
153 bsc_QueryInterface,
154 bsc_AddRef,
155 bsc_Release,
156 bsc_OnStartBinding,
157 bsc_GetPriority,
158 bsc_OnLowResource,
159 bsc_OnProgress,
160 bsc_OnStopBinding,
161 bsc_GetBindInfo,
162 bsc_OnDataAvailable,
163 bsc_OnObjectAvailable
166 static bsc domdoc_bsc = { &bsc_vtbl };
168 typedef struct _domdoc
170 const struct IXMLDOMDocument2Vtbl *lpVtbl;
171 const struct IPersistStreamVtbl *lpvtblIPersistStream;
172 LONG ref;
173 VARIANT_BOOL async;
174 VARIANT_BOOL validating;
175 VARIANT_BOOL resolving;
176 VARIANT_BOOL preserving;
177 BOOL bUseXPath;
178 IUnknown *node_unk;
179 IXMLDOMNode *node;
180 IXMLDOMSchemaCollection *schema;
181 HRESULT error;
183 /* IPersistStream */
184 IStream *stream;
185 } domdoc;
187 LONG xmldoc_add_ref(xmlDocPtr doc)
189 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
190 TRACE("%d\n", ref);
191 return ref;
194 LONG xmldoc_release(xmlDocPtr doc)
196 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
197 TRACE("%d\n", ref);
198 if(ref == 0)
200 TRACE("freeing docptr %p\n", doc);
201 xmlFreeDoc(doc);
204 return ref;
207 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
209 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
212 static inline xmlDocPtr get_doc( domdoc *This )
214 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
217 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
219 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
222 /************************************************************************
223 * xmldoc implementation of IPersistStream.
225 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
226 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
228 domdoc *this = impl_from_IPersistStream(iface);
229 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
232 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
233 IPersistStream *iface)
235 domdoc *this = impl_from_IPersistStream(iface);
236 return IXMLDocument_AddRef((IXMLDocument *)this);
239 static ULONG WINAPI xmldoc_IPersistStream_Release(
240 IPersistStream *iface)
242 domdoc *this = impl_from_IPersistStream(iface);
243 return IXMLDocument_Release((IXMLDocument *)this);
246 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
247 IPersistStream *iface, CLSID *classid)
249 TRACE("(%p,%p): stub!\n", iface, classid);
251 if(!classid)
252 return E_POINTER;
254 *classid = CLSID_DOMDocument2;
256 return S_OK;
259 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
260 IPersistStream *iface)
262 domdoc *This = impl_from_IPersistStream(iface);
264 FIXME("(%p->%p): stub!\n", iface, This);
266 return S_FALSE;
269 static HRESULT WINAPI xmldoc_IPersistStream_Load(
270 IPersistStream *iface, LPSTREAM pStm)
272 domdoc *This = impl_from_IPersistStream(iface);
273 HRESULT hr;
274 HGLOBAL hglobal;
275 DWORD read, written, len;
276 BYTE buf[4096];
277 char *ptr;
278 xmlDocPtr xmldoc = NULL;
280 TRACE("(%p, %p)\n", iface, pStm);
282 if (!pStm)
283 return E_INVALIDARG;
285 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
286 if (FAILED(hr))
287 return hr;
291 IStream_Read(pStm, buf, sizeof(buf), &read);
292 hr = IStream_Write(This->stream, buf, read, &written);
293 } while(SUCCEEDED(hr) && written != 0 && read != 0);
295 if (FAILED(hr))
297 ERR("Failed to copy stream\n");
298 return hr;
301 hr = GetHGlobalFromStream(This->stream, &hglobal);
302 if (FAILED(hr))
303 return hr;
305 len = GlobalSize(hglobal);
306 ptr = GlobalLock(hglobal);
307 if (len != 0)
308 xmldoc = parse_xml(ptr, len);
309 GlobalUnlock(hglobal);
311 if (!xmldoc)
313 ERR("Failed to parse xml\n");
314 return E_FAIL;
317 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
319 return S_OK;
322 static HRESULT WINAPI xmldoc_IPersistStream_Save(
323 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
325 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
326 return E_NOTIMPL;
329 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
330 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
332 TRACE("(%p, %p): stub!\n", iface, pcbSize);
333 return E_NOTIMPL;
336 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
338 xmldoc_IPersistStream_QueryInterface,
339 xmldoc_IPersistStream_AddRef,
340 xmldoc_IPersistStream_Release,
341 xmldoc_IPersistStream_GetClassID,
342 xmldoc_IPersistStream_IsDirty,
343 xmldoc_IPersistStream_Load,
344 xmldoc_IPersistStream_Save,
345 xmldoc_IPersistStream_GetSizeMax,
348 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
350 domdoc *This = impl_from_IXMLDOMDocument2( iface );
352 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
354 *ppvObject = NULL;
356 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
357 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
358 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
360 *ppvObject = iface;
362 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
363 IsEqualGUID( riid, &IID_IDispatch ) )
365 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
367 else if (IsEqualGUID(&IID_IPersistStream, riid))
369 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
371 else if(IsEqualGUID(&IID_IRunnableObject, riid))
373 TRACE("IID_IRunnableObject not supported returning NULL\n");
374 return E_NOINTERFACE;
376 else
378 FIXME("interface %s not implemented\n", debugstr_guid(riid));
379 return E_NOINTERFACE;
382 IXMLDOMDocument_AddRef( iface );
384 return S_OK;
388 static ULONG WINAPI domdoc_AddRef(
389 IXMLDOMDocument2 *iface )
391 domdoc *This = impl_from_IXMLDOMDocument2( iface );
392 TRACE("%p\n", This );
393 return InterlockedIncrement( &This->ref );
397 static ULONG WINAPI domdoc_Release(
398 IXMLDOMDocument2 *iface )
400 domdoc *This = impl_from_IXMLDOMDocument2( iface );
401 LONG ref;
403 TRACE("%p\n", This );
405 ref = InterlockedDecrement( &This->ref );
406 if ( ref == 0 )
408 IUnknown_Release( This->node_unk );
409 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
410 if (This->stream) IStream_Release(This->stream);
411 HeapFree( GetProcessHeap(), 0, This );
414 return ref;
417 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
419 FIXME("\n");
420 return E_NOTIMPL;
423 static HRESULT WINAPI domdoc_GetTypeInfo(
424 IXMLDOMDocument2 *iface,
425 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
427 FIXME("\n");
428 return E_NOTIMPL;
431 static HRESULT WINAPI domdoc_GetIDsOfNames(
432 IXMLDOMDocument2 *iface,
433 REFIID riid,
434 LPOLESTR* rgszNames,
435 UINT cNames,
436 LCID lcid,
437 DISPID* rgDispId)
439 FIXME("\n");
440 return E_NOTIMPL;
444 static HRESULT WINAPI domdoc_Invoke(
445 IXMLDOMDocument2 *iface,
446 DISPID dispIdMember,
447 REFIID riid,
448 LCID lcid,
449 WORD wFlags,
450 DISPPARAMS* pDispParams,
451 VARIANT* pVarResult,
452 EXCEPINFO* pExcepInfo,
453 UINT* puArgErr)
455 FIXME("\n");
456 return E_NOTIMPL;
460 static HRESULT WINAPI domdoc_get_nodeName(
461 IXMLDOMDocument2 *iface,
462 BSTR* name )
464 domdoc *This = impl_from_IXMLDOMDocument2( iface );
465 return IXMLDOMNode_get_nodeName( This->node, name );
469 static HRESULT WINAPI domdoc_get_nodeValue(
470 IXMLDOMDocument2 *iface,
471 VARIANT* value )
473 domdoc *This = impl_from_IXMLDOMDocument2( iface );
474 return IXMLDOMNode_get_nodeValue( This->node, value );
478 static HRESULT WINAPI domdoc_put_nodeValue(
479 IXMLDOMDocument2 *iface,
480 VARIANT value)
482 domdoc *This = impl_from_IXMLDOMDocument2( iface );
483 return IXMLDOMNode_put_nodeValue( This->node, value );
487 static HRESULT WINAPI domdoc_get_nodeType(
488 IXMLDOMDocument2 *iface,
489 DOMNodeType* type )
491 domdoc *This = impl_from_IXMLDOMDocument2( iface );
492 return IXMLDOMNode_get_nodeType( This->node, type );
496 static HRESULT WINAPI domdoc_get_parentNode(
497 IXMLDOMDocument2 *iface,
498 IXMLDOMNode** parent )
500 domdoc *This = impl_from_IXMLDOMDocument2( iface );
501 return IXMLDOMNode_get_parentNode( This->node, parent );
505 static HRESULT WINAPI domdoc_get_childNodes(
506 IXMLDOMDocument2 *iface,
507 IXMLDOMNodeList** childList )
509 domdoc *This = impl_from_IXMLDOMDocument2( iface );
510 return IXMLDOMNode_get_childNodes( This->node, childList );
514 static HRESULT WINAPI domdoc_get_firstChild(
515 IXMLDOMDocument2 *iface,
516 IXMLDOMNode** firstChild )
518 domdoc *This = impl_from_IXMLDOMDocument2( iface );
519 return IXMLDOMNode_get_firstChild( This->node, firstChild );
523 static HRESULT WINAPI domdoc_get_lastChild(
524 IXMLDOMDocument2 *iface,
525 IXMLDOMNode** lastChild )
527 domdoc *This = impl_from_IXMLDOMDocument2( iface );
528 return IXMLDOMNode_get_lastChild( This->node, lastChild );
532 static HRESULT WINAPI domdoc_get_previousSibling(
533 IXMLDOMDocument2 *iface,
534 IXMLDOMNode** previousSibling )
536 domdoc *This = impl_from_IXMLDOMDocument2( iface );
537 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
541 static HRESULT WINAPI domdoc_get_nextSibling(
542 IXMLDOMDocument2 *iface,
543 IXMLDOMNode** nextSibling )
545 domdoc *This = impl_from_IXMLDOMDocument2( iface );
546 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
550 static HRESULT WINAPI domdoc_get_attributes(
551 IXMLDOMDocument2 *iface,
552 IXMLDOMNamedNodeMap** attributeMap )
554 domdoc *This = impl_from_IXMLDOMDocument2( iface );
555 return IXMLDOMNode_get_attributes( This->node, attributeMap );
559 static HRESULT WINAPI domdoc_insertBefore(
560 IXMLDOMDocument2 *iface,
561 IXMLDOMNode* newChild,
562 VARIANT refChild,
563 IXMLDOMNode** outNewChild )
565 domdoc *This = impl_from_IXMLDOMDocument2( iface );
566 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
570 static HRESULT WINAPI domdoc_replaceChild(
571 IXMLDOMDocument2 *iface,
572 IXMLDOMNode* newChild,
573 IXMLDOMNode* oldChild,
574 IXMLDOMNode** outOldChild)
576 domdoc *This = impl_from_IXMLDOMDocument2( iface );
577 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
581 static HRESULT WINAPI domdoc_removeChild(
582 IXMLDOMDocument2 *iface,
583 IXMLDOMNode* childNode,
584 IXMLDOMNode** oldChild)
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
587 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
591 static HRESULT WINAPI domdoc_appendChild(
592 IXMLDOMDocument2 *iface,
593 IXMLDOMNode* newChild,
594 IXMLDOMNode** outNewChild)
596 domdoc *This = impl_from_IXMLDOMDocument2( iface );
597 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
601 static HRESULT WINAPI domdoc_hasChildNodes(
602 IXMLDOMDocument2 *iface,
603 VARIANT_BOOL* hasChild)
605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
610 static HRESULT WINAPI domdoc_get_ownerDocument(
611 IXMLDOMDocument2 *iface,
612 IXMLDOMDocument** DOMDocument)
614 domdoc *This = impl_from_IXMLDOMDocument2( iface );
615 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
619 static HRESULT WINAPI domdoc_cloneNode(
620 IXMLDOMDocument2 *iface,
621 VARIANT_BOOL deep,
622 IXMLDOMNode** cloneRoot)
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
629 static HRESULT WINAPI domdoc_get_nodeTypeString(
630 IXMLDOMDocument2 *iface,
631 BSTR* nodeType )
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
638 static HRESULT WINAPI domdoc_get_text(
639 IXMLDOMDocument2 *iface,
640 BSTR* text )
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_get_text( This->node, text );
647 static HRESULT WINAPI domdoc_put_text(
648 IXMLDOMDocument2 *iface,
649 BSTR text )
651 domdoc *This = impl_from_IXMLDOMDocument2( iface );
652 return IXMLDOMNode_put_text( This->node, text );
656 static HRESULT WINAPI domdoc_get_specified(
657 IXMLDOMDocument2 *iface,
658 VARIANT_BOOL* isSpecified )
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_get_specified( This->node, isSpecified );
665 static HRESULT WINAPI domdoc_get_definition(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode** definitionNode )
669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
670 return IXMLDOMNode_get_definition( This->node, definitionNode );
674 static HRESULT WINAPI domdoc_get_nodeTypedValue(
675 IXMLDOMDocument2 *iface,
676 VARIANT* typedValue )
678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
679 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
682 static HRESULT WINAPI domdoc_put_nodeTypedValue(
683 IXMLDOMDocument2 *iface,
684 VARIANT typedValue )
686 domdoc *This = impl_from_IXMLDOMDocument2( iface );
687 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
691 static HRESULT WINAPI domdoc_get_dataType(
692 IXMLDOMDocument2 *iface,
693 VARIANT* dataTypeName )
695 domdoc *This = impl_from_IXMLDOMDocument2( iface );
696 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
700 static HRESULT WINAPI domdoc_put_dataType(
701 IXMLDOMDocument2 *iface,
702 BSTR dataTypeName )
704 domdoc *This = impl_from_IXMLDOMDocument2( iface );
705 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
709 static HRESULT WINAPI domdoc_get_xml(
710 IXMLDOMDocument2 *iface,
711 BSTR* xmlString )
713 domdoc *This = impl_from_IXMLDOMDocument2( iface );
714 return IXMLDOMNode_get_xml( This->node, xmlString );
718 static HRESULT WINAPI domdoc_transformNode(
719 IXMLDOMDocument2 *iface,
720 IXMLDOMNode* styleSheet,
721 BSTR* xmlString )
723 domdoc *This = impl_from_IXMLDOMDocument2( iface );
724 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
728 static HRESULT WINAPI domdoc_selectNodes(
729 IXMLDOMDocument2 *iface,
730 BSTR queryString,
731 IXMLDOMNodeList** resultList )
733 domdoc *This = impl_from_IXMLDOMDocument2( iface );
734 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
738 static HRESULT WINAPI domdoc_selectSingleNode(
739 IXMLDOMDocument2 *iface,
740 BSTR queryString,
741 IXMLDOMNode** resultNode )
743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
744 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
748 static HRESULT WINAPI domdoc_get_parsed(
749 IXMLDOMDocument2 *iface,
750 VARIANT_BOOL* isParsed )
752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
753 return IXMLDOMNode_get_parsed( This->node, isParsed );
757 static HRESULT WINAPI domdoc_get_namespaceURI(
758 IXMLDOMDocument2 *iface,
759 BSTR* namespaceURI )
761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
762 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
766 static HRESULT WINAPI domdoc_get_prefix(
767 IXMLDOMDocument2 *iface,
768 BSTR* prefixString )
770 domdoc *This = impl_from_IXMLDOMDocument2( iface );
771 return IXMLDOMNode_get_prefix( This->node, prefixString );
775 static HRESULT WINAPI domdoc_get_baseName(
776 IXMLDOMDocument2 *iface,
777 BSTR* nameString )
779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
780 return IXMLDOMNode_get_baseName( This->node, nameString );
784 static HRESULT WINAPI domdoc_transformNodeToObject(
785 IXMLDOMDocument2 *iface,
786 IXMLDOMNode* stylesheet,
787 VARIANT outputObject)
789 domdoc *This = impl_from_IXMLDOMDocument2( iface );
790 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
794 static HRESULT WINAPI domdoc_get_doctype(
795 IXMLDOMDocument2 *iface,
796 IXMLDOMDocumentType** documentType )
798 FIXME("\n");
799 return E_NOTIMPL;
803 static HRESULT WINAPI domdoc_get_implementation(
804 IXMLDOMDocument2 *iface,
805 IXMLDOMImplementation** impl )
807 if(!impl)
808 return E_INVALIDARG;
810 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
812 return S_OK;
815 static HRESULT WINAPI domdoc_get_documentElement(
816 IXMLDOMDocument2 *iface,
817 IXMLDOMElement** DOMElement )
819 domdoc *This = impl_from_IXMLDOMDocument2( iface );
820 xmlDocPtr xmldoc = NULL;
821 xmlNodePtr root = NULL;
822 IXMLDOMNode *element_node;
823 HRESULT hr;
825 TRACE("%p %p\n", This, This->node);
827 if(!DOMElement)
828 return E_INVALIDARG;
830 *DOMElement = NULL;
832 xmldoc = get_doc( This );
834 root = xmlDocGetRootElement( xmldoc );
835 if ( !root )
836 return S_FALSE;
838 element_node = create_node( root );
839 if(!element_node) return S_FALSE;
841 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
842 IXMLDOMNode_Release(element_node);
844 return hr;
848 static HRESULT WINAPI domdoc_documentElement(
849 IXMLDOMDocument2 *iface,
850 IXMLDOMElement* DOMElement )
852 FIXME("\n");
853 return E_NOTIMPL;
857 static HRESULT WINAPI domdoc_createElement(
858 IXMLDOMDocument2 *iface,
859 BSTR tagname,
860 IXMLDOMElement** element )
862 xmlNodePtr xmlnode;
863 domdoc *This = impl_from_IXMLDOMDocument2( iface );
864 xmlChar *xml_name;
865 IUnknown *elem_unk;
866 HRESULT hr;
868 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
870 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
871 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
873 TRACE("created xmlptr %p\n", xmlnode);
874 elem_unk = create_element(xmlnode, NULL);
875 HeapFree(GetProcessHeap(), 0, xml_name);
877 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
878 IUnknown_Release(elem_unk);
879 TRACE("returning %p\n", *element);
880 return hr;
884 static HRESULT WINAPI domdoc_createDocumentFragment(
885 IXMLDOMDocument2 *iface,
886 IXMLDOMDocumentFragment** docFrag )
888 FIXME("\n");
889 return E_NOTIMPL;
893 static HRESULT WINAPI domdoc_createTextNode(
894 IXMLDOMDocument2 *iface,
895 BSTR data,
896 IXMLDOMText** text )
898 domdoc *This = impl_from_IXMLDOMDocument2( iface );
899 xmlNodePtr xmlnode;
900 xmlChar *xml_content;
902 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
904 if(!text)
905 return E_INVALIDARG;
907 *text = NULL;
909 xml_content = xmlChar_from_wchar((WCHAR*)data);
910 xmlnode = xmlNewText(xml_content);
911 HeapFree(GetProcessHeap(), 0, xml_content);
913 if(!xmlnode)
914 return E_FAIL;
916 xmlnode->doc = get_doc( This );
918 *text = (IXMLDOMText*)create_text(xmlnode);
920 return S_OK;
924 static HRESULT WINAPI domdoc_createComment(
925 IXMLDOMDocument2 *iface,
926 BSTR data,
927 IXMLDOMComment** comment )
929 domdoc *This = impl_from_IXMLDOMDocument2( iface );
930 xmlNodePtr xmlnode;
931 xmlChar *xml_content;
933 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
935 if(!comment)
936 return E_INVALIDARG;
938 *comment = NULL;
940 xml_content = xmlChar_from_wchar((WCHAR*)data);
941 xmlnode = xmlNewComment(xml_content);
942 HeapFree(GetProcessHeap(), 0, xml_content);
944 if(!xmlnode)
945 return E_FAIL;
947 xmlnode->doc = get_doc( This );
949 *comment = (IXMLDOMComment*)create_comment(xmlnode);
951 return S_OK;
955 static HRESULT WINAPI domdoc_createCDATASection(
956 IXMLDOMDocument2 *iface,
957 BSTR data,
958 IXMLDOMCDATASection** cdata )
960 domdoc *This = impl_from_IXMLDOMDocument2( iface );
961 xmlNodePtr xmlnode;
962 xmlChar *xml_content;
964 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
966 if(!cdata)
967 return E_INVALIDARG;
969 *cdata = NULL;
971 xml_content = xmlChar_from_wchar((WCHAR*)data);
972 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
973 HeapFree(GetProcessHeap(), 0, xml_content);
975 if(!xmlnode)
976 return E_FAIL;
978 xmlnode->doc = get_doc( This );
980 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
982 return S_OK;
986 static HRESULT WINAPI domdoc_createProcessingInstruction(
987 IXMLDOMDocument2 *iface,
988 BSTR target,
989 BSTR data,
990 IXMLDOMProcessingInstruction** pi )
992 #ifdef HAVE_XMLNEWDOCPI
993 xmlNodePtr xmlnode;
994 domdoc *This = impl_from_IXMLDOMDocument2( iface );
995 xmlChar *xml_target, *xml_content;
997 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
999 if(!pi)
1000 return E_INVALIDARG;
1002 if(!target || lstrlenW(target) == 0)
1003 return E_FAIL;
1005 xml_target = xmlChar_from_wchar((WCHAR*)target);
1006 xml_content = xmlChar_from_wchar((WCHAR*)data);
1008 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1009 TRACE("created xmlptr %p\n", xmlnode);
1010 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1012 HeapFree(GetProcessHeap(), 0, xml_content);
1013 HeapFree(GetProcessHeap(), 0, xml_target);
1015 return S_OK;
1016 #else
1017 FIXME("Libxml 2.6.15 or greater required.\n");
1018 return E_NOTIMPL;
1019 #endif
1023 static HRESULT WINAPI domdoc_createAttribute(
1024 IXMLDOMDocument2 *iface,
1025 BSTR name,
1026 IXMLDOMAttribute** attribute )
1028 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1029 xmlNodePtr xmlnode;
1030 xmlChar *xml_name;
1032 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1034 if(!attribute)
1035 return E_INVALIDARG;
1037 *attribute = NULL;
1039 xml_name = xmlChar_from_wchar((WCHAR*)name);
1040 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1041 HeapFree(GetProcessHeap(), 0, xml_name);
1043 if(!xmlnode)
1044 return E_FAIL;
1046 xmlnode->doc = get_doc( This );
1048 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1050 return S_OK;
1054 static HRESULT WINAPI domdoc_createEntityReference(
1055 IXMLDOMDocument2 *iface,
1056 BSTR name,
1057 IXMLDOMEntityReference** entityRef )
1059 FIXME("\n");
1060 return E_NOTIMPL;
1064 static HRESULT WINAPI domdoc_getElementsByTagName(
1065 IXMLDOMDocument2 *iface,
1066 BSTR tagName,
1067 IXMLDOMNodeList** resultList )
1069 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1070 LPWSTR szPattern;
1071 HRESULT hr;
1072 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1074 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1075 szPattern[0] = szPattern[1] = '/';
1076 lstrcpyW(szPattern + 2, tagName);
1078 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1079 HeapFree(GetProcessHeap(), 0, szPattern);
1081 return hr;
1084 static DOMNodeType get_node_type(VARIANT Type)
1086 if(V_VT(&Type) == VT_I4)
1087 return V_I4(&Type);
1089 FIXME("Unsupported variant type %x\n", V_VT(&Type));
1090 return 0;
1093 static HRESULT WINAPI domdoc_createNode(
1094 IXMLDOMDocument2 *iface,
1095 VARIANT Type,
1096 BSTR name,
1097 BSTR namespaceURI,
1098 IXMLDOMNode** node )
1100 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1101 DOMNodeType node_type;
1102 xmlNodePtr xmlnode = NULL;
1103 xmlChar *xml_name;
1105 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1107 node_type = get_node_type(Type);
1108 TRACE("node_type %d\n", node_type);
1110 xml_name = xmlChar_from_wchar((WCHAR*)name);
1112 switch(node_type)
1114 case NODE_ELEMENT:
1115 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1116 *node = create_node(xmlnode);
1117 TRACE("created %p\n", xmlnode);
1118 break;
1120 default:
1121 FIXME("unhandled node type %d\n", node_type);
1122 break;
1125 HeapFree(GetProcessHeap(), 0, xml_name);
1127 if(xmlnode && *node)
1128 return S_OK;
1130 return E_FAIL;
1133 static HRESULT WINAPI domdoc_nodeFromID(
1134 IXMLDOMDocument2 *iface,
1135 BSTR idString,
1136 IXMLDOMNode** node )
1138 FIXME("\n");
1139 return E_NOTIMPL;
1142 static xmlDocPtr doparse( char *ptr, int len )
1144 #ifdef HAVE_XMLREADMEMORY
1146 * use xmlReadMemory if possible so we can suppress
1147 * writing errors to stderr
1149 return xmlReadMemory( ptr, len, NULL, NULL,
1150 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
1151 #else
1152 return xmlParseMemory( ptr, len );
1153 #endif
1156 static xmlDocPtr doread( LPWSTR filename )
1158 xmlDocPtr xmldoc = NULL;
1159 HRESULT hr;
1160 IBindCtx *pbc;
1161 IStream *stream, *memstream;
1162 WCHAR url[INTERNET_MAX_URL_LENGTH];
1163 BYTE buf[4096];
1164 DWORD read, written;
1166 TRACE("%s\n", debugstr_w( filename ));
1168 if(!PathIsURLW(filename))
1170 WCHAR fullpath[MAX_PATH];
1171 DWORD needed = sizeof(url)/sizeof(WCHAR);
1173 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
1175 WARN("can't find path\n");
1176 return NULL;
1179 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
1181 ERR("can't create url from path\n");
1182 return NULL;
1184 filename = url;
1187 hr = CreateBindCtx(0, &pbc);
1188 if(SUCCEEDED(hr))
1190 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
1191 if(SUCCEEDED(hr))
1193 IMoniker *moniker;
1194 hr = CreateURLMoniker(NULL, filename, &moniker);
1195 if(SUCCEEDED(hr))
1197 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
1198 IMoniker_Release(moniker);
1201 IBindCtx_Release(pbc);
1203 if(FAILED(hr))
1204 return NULL;
1206 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
1207 if(FAILED(hr))
1209 IStream_Release(stream);
1210 return NULL;
1215 IStream_Read(stream, buf, sizeof(buf), &read);
1216 hr = IStream_Write(memstream, buf, read, &written);
1217 } while(SUCCEEDED(hr) && written != 0 && read != 0);
1219 if(SUCCEEDED(hr))
1221 HGLOBAL hglobal;
1222 hr = GetHGlobalFromStream(memstream, &hglobal);
1223 if(SUCCEEDED(hr))
1225 DWORD len = GlobalSize(hglobal);
1226 char *ptr = GlobalLock(hglobal);
1227 if(len != 0)
1228 xmldoc = doparse( ptr, len );
1229 GlobalUnlock(hglobal);
1232 IStream_Release(memstream);
1233 IStream_Release(stream);
1234 return xmldoc;
1237 static HRESULT WINAPI domdoc_load(
1238 IXMLDOMDocument2 *iface,
1239 VARIANT xmlSource,
1240 VARIANT_BOOL* isSuccessful )
1242 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1243 LPWSTR filename = NULL;
1244 xmlDocPtr xmldoc = NULL;
1245 HRESULT hr = S_FALSE;
1246 IXMLDOMDocument2 *pNewDoc = NULL;
1247 IStream *pStream = NULL;
1249 TRACE("type %d\n", V_VT(&xmlSource) );
1251 *isSuccessful = VARIANT_FALSE;
1253 assert( This->node );
1255 attach_xmlnode(This->node, NULL);
1257 switch( V_VT(&xmlSource) )
1259 case VT_BSTR:
1260 filename = V_BSTR(&xmlSource);
1261 break;
1262 case VT_UNKNOWN:
1263 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1264 if(hr == S_OK)
1266 if(pNewDoc)
1268 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1269 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1270 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1272 *isSuccessful = VARIANT_TRUE;
1274 return S_OK;
1277 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1278 if(hr == S_OK)
1280 IPersistStream *pDocStream;
1281 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1282 if(hr == S_OK)
1284 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1285 IStream_Release(pStream);
1286 if(hr == S_OK)
1288 *isSuccessful = VARIANT_TRUE;
1290 TRACE("Using ID_IStream to load Document\n");
1291 return S_OK;
1293 else
1295 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1298 else
1300 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1303 else
1305 /* ISequentialStream */
1306 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1308 break;
1309 default:
1310 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1313 TRACE("filename (%s)\n", debugstr_w(filename));
1315 if ( filename )
1317 xmldoc = doread( filename );
1319 if ( !xmldoc )
1320 This->error = E_FAIL;
1321 else
1323 hr = This->error = S_OK;
1324 *isSuccessful = VARIANT_TRUE;
1328 if(!xmldoc)
1329 xmldoc = xmlNewDoc(NULL);
1331 xmldoc->_private = 0;
1332 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1334 TRACE("ret (%d)\n", hr);
1336 return hr;
1340 static HRESULT WINAPI domdoc_get_readyState(
1341 IXMLDOMDocument2 *iface,
1342 long* value )
1344 FIXME("\n");
1345 return E_NOTIMPL;
1349 static HRESULT WINAPI domdoc_get_parseError(
1350 IXMLDOMDocument2 *iface,
1351 IXMLDOMParseError** errorObj )
1353 BSTR error_string = NULL;
1354 static const WCHAR err[] = {'e','r','r','o','r',0};
1355 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1357 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1359 if(This->error)
1360 error_string = SysAllocString(err);
1362 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1363 if(!*errorObj) return E_OUTOFMEMORY;
1364 return S_OK;
1368 static HRESULT WINAPI domdoc_get_url(
1369 IXMLDOMDocument2 *iface,
1370 BSTR* urlString )
1372 FIXME("\n");
1373 return E_NOTIMPL;
1377 static HRESULT WINAPI domdoc_get_async(
1378 IXMLDOMDocument2 *iface,
1379 VARIANT_BOOL* isAsync )
1381 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1383 TRACE("%p <- %d\n", isAsync, This->async);
1384 *isAsync = This->async;
1385 return S_OK;
1389 static HRESULT WINAPI domdoc_put_async(
1390 IXMLDOMDocument2 *iface,
1391 VARIANT_BOOL isAsync )
1393 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1395 TRACE("%d\n", isAsync);
1396 This->async = isAsync;
1397 return S_OK;
1401 static HRESULT WINAPI domdoc_abort(
1402 IXMLDOMDocument2 *iface )
1404 FIXME("\n");
1405 return E_NOTIMPL;
1409 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1411 UINT len, blen = SysStringLen( bstr );
1412 LPSTR str;
1414 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1415 str = HeapAlloc( GetProcessHeap(), 0, len );
1416 if ( !str )
1417 return FALSE;
1418 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1419 *plen = len;
1420 *pstr = str;
1421 return TRUE;
1424 static HRESULT WINAPI domdoc_loadXML(
1425 IXMLDOMDocument2 *iface,
1426 BSTR bstrXML,
1427 VARIANT_BOOL* isSuccessful )
1429 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1430 xmlDocPtr xmldoc = NULL;
1431 char *str;
1432 int len;
1433 HRESULT hr = S_FALSE;
1435 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1437 assert ( This->node );
1439 attach_xmlnode( This->node, NULL );
1441 if ( isSuccessful )
1443 *isSuccessful = VARIANT_FALSE;
1445 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1447 xmldoc = doparse( str, len );
1448 HeapFree( GetProcessHeap(), 0, str );
1449 if ( !xmldoc )
1450 This->error = E_FAIL;
1451 else
1453 hr = This->error = S_OK;
1454 *isSuccessful = VARIANT_TRUE;
1458 if(!xmldoc)
1459 xmldoc = xmlNewDoc(NULL);
1461 xmldoc->_private = 0;
1462 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1464 return hr;
1468 static HRESULT WINAPI domdoc_save(
1469 IXMLDOMDocument2 *iface,
1470 VARIANT destination )
1472 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1473 HANDLE handle;
1474 xmlChar *mem;
1475 int size;
1476 HRESULT ret = S_OK;
1477 DWORD written;
1479 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1480 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1482 if(V_VT(&destination) != VT_BSTR)
1484 FIXME("Unhandled vt %x\n", V_VT(&destination));
1485 return S_FALSE;
1488 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1489 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1490 if( handle == INVALID_HANDLE_VALUE )
1492 WARN("failed to create file\n");
1493 return S_FALSE;
1496 xmlDocDumpMemory(get_doc(This), &mem, &size);
1497 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1499 WARN("write error\n");
1500 ret = S_FALSE;
1503 xmlFree(mem);
1504 CloseHandle(handle);
1505 return ret;
1508 static HRESULT WINAPI domdoc_get_validateOnParse(
1509 IXMLDOMDocument2 *iface,
1510 VARIANT_BOOL* isValidating )
1512 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1514 TRACE("%p <- %d\n", isValidating, This->validating);
1515 *isValidating = This->validating;
1516 return S_OK;
1520 static HRESULT WINAPI domdoc_put_validateOnParse(
1521 IXMLDOMDocument2 *iface,
1522 VARIANT_BOOL isValidating )
1524 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1526 TRACE("%d\n", isValidating);
1527 This->validating = isValidating;
1528 return S_OK;
1532 static HRESULT WINAPI domdoc_get_resolveExternals(
1533 IXMLDOMDocument2 *iface,
1534 VARIANT_BOOL* isResolving )
1536 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1538 TRACE("%p <- %d\n", isResolving, This->resolving);
1539 *isResolving = This->resolving;
1540 return S_OK;
1544 static HRESULT WINAPI domdoc_put_resolveExternals(
1545 IXMLDOMDocument2 *iface,
1546 VARIANT_BOOL isResolving )
1548 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1550 TRACE("%d\n", isResolving);
1551 This->resolving = isResolving;
1552 return S_OK;
1556 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1557 IXMLDOMDocument2 *iface,
1558 VARIANT_BOOL* isPreserving )
1560 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1562 TRACE("%p <- %d\n", isPreserving, This->preserving);
1563 *isPreserving = This->preserving;
1564 return S_OK;
1568 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1569 IXMLDOMDocument2 *iface,
1570 VARIANT_BOOL isPreserving )
1572 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1574 TRACE("%d\n", isPreserving);
1575 This->preserving = isPreserving;
1576 return S_OK;
1580 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1581 IXMLDOMDocument2 *iface,
1582 VARIANT readyStateChangeSink )
1584 FIXME("\n");
1585 return E_NOTIMPL;
1589 static HRESULT WINAPI domdoc_put_onDataAvailable(
1590 IXMLDOMDocument2 *iface,
1591 VARIANT onDataAvailableSink )
1593 FIXME("\n");
1594 return E_NOTIMPL;
1597 static HRESULT WINAPI domdoc_put_onTransformNode(
1598 IXMLDOMDocument2 *iface,
1599 VARIANT onTransformNodeSink )
1601 FIXME("\n");
1602 return E_NOTIMPL;
1605 static HRESULT WINAPI domdoc_get_namespaces(
1606 IXMLDOMDocument2* iface,
1607 IXMLDOMSchemaCollection** schemaCollection )
1609 FIXME("\n");
1610 return E_NOTIMPL;
1613 static HRESULT WINAPI domdoc_get_schemas(
1614 IXMLDOMDocument2* iface,
1615 VARIANT* var1 )
1617 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1618 HRESULT hr = S_FALSE;
1619 IXMLDOMSchemaCollection *cur_schema = This->schema;
1621 TRACE("(%p)->(%p)\n", This, var1);
1623 VariantInit(var1); /* Test shows we don't call VariantClear here */
1624 V_VT(var1) = VT_NULL;
1626 if(cur_schema)
1628 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1629 if(SUCCEEDED(hr))
1630 V_VT(var1) = VT_DISPATCH;
1632 return hr;
1635 static HRESULT WINAPI domdoc_putref_schemas(
1636 IXMLDOMDocument2* iface,
1637 VARIANT var1)
1639 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1640 HRESULT hr = E_FAIL;
1641 IXMLDOMSchemaCollection *new_schema = NULL;
1643 FIXME("(%p): semi-stub\n", This);
1644 switch(V_VT(&var1))
1646 case VT_UNKNOWN:
1647 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1648 break;
1650 case VT_DISPATCH:
1651 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1652 break;
1654 case VT_NULL:
1655 case VT_EMPTY:
1656 hr = S_OK;
1657 break;
1659 default:
1660 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1663 if(SUCCEEDED(hr))
1665 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1666 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1669 return hr;
1672 static HRESULT WINAPI domdoc_validate(
1673 IXMLDOMDocument2* iface,
1674 IXMLDOMParseError** err)
1676 FIXME("\n");
1677 return E_NOTIMPL;
1680 static HRESULT WINAPI domdoc_setProperty(
1681 IXMLDOMDocument2* iface,
1682 BSTR p,
1683 VARIANT var)
1685 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1687 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1689 VARIANT varStr;
1690 HRESULT hr;
1691 BSTR bstr;
1693 V_VT(&varStr) = VT_EMPTY;
1694 if (V_VT(&var) != VT_BSTR)
1696 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1697 return hr;
1698 bstr = V_BSTR(&varStr);
1700 else
1701 bstr = V_BSTR(&var);
1703 hr = S_OK;
1704 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1705 This->bUseXPath = TRUE;
1706 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1707 This->bUseXPath = FALSE;
1708 else
1709 hr = E_FAIL;
1711 VariantClear(&varStr);
1712 return hr;
1715 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1716 return E_FAIL;
1719 static HRESULT WINAPI domdoc_getProperty(
1720 IXMLDOMDocument2* iface,
1721 BSTR p,
1722 VARIANT* var)
1724 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1726 if (var == NULL)
1727 return E_INVALIDARG;
1728 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1730 V_VT(var) = VT_BSTR;
1731 if (This->bUseXPath)
1732 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1733 else
1734 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1735 return S_OK;
1738 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1739 return E_FAIL;
1742 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1744 domdoc_QueryInterface,
1745 domdoc_AddRef,
1746 domdoc_Release,
1747 domdoc_GetTypeInfoCount,
1748 domdoc_GetTypeInfo,
1749 domdoc_GetIDsOfNames,
1750 domdoc_Invoke,
1751 domdoc_get_nodeName,
1752 domdoc_get_nodeValue,
1753 domdoc_put_nodeValue,
1754 domdoc_get_nodeType,
1755 domdoc_get_parentNode,
1756 domdoc_get_childNodes,
1757 domdoc_get_firstChild,
1758 domdoc_get_lastChild,
1759 domdoc_get_previousSibling,
1760 domdoc_get_nextSibling,
1761 domdoc_get_attributes,
1762 domdoc_insertBefore,
1763 domdoc_replaceChild,
1764 domdoc_removeChild,
1765 domdoc_appendChild,
1766 domdoc_hasChildNodes,
1767 domdoc_get_ownerDocument,
1768 domdoc_cloneNode,
1769 domdoc_get_nodeTypeString,
1770 domdoc_get_text,
1771 domdoc_put_text,
1772 domdoc_get_specified,
1773 domdoc_get_definition,
1774 domdoc_get_nodeTypedValue,
1775 domdoc_put_nodeTypedValue,
1776 domdoc_get_dataType,
1777 domdoc_put_dataType,
1778 domdoc_get_xml,
1779 domdoc_transformNode,
1780 domdoc_selectNodes,
1781 domdoc_selectSingleNode,
1782 domdoc_get_parsed,
1783 domdoc_get_namespaceURI,
1784 domdoc_get_prefix,
1785 domdoc_get_baseName,
1786 domdoc_transformNodeToObject,
1787 domdoc_get_doctype,
1788 domdoc_get_implementation,
1789 domdoc_get_documentElement,
1790 domdoc_documentElement,
1791 domdoc_createElement,
1792 domdoc_createDocumentFragment,
1793 domdoc_createTextNode,
1794 domdoc_createComment,
1795 domdoc_createCDATASection,
1796 domdoc_createProcessingInstruction,
1797 domdoc_createAttribute,
1798 domdoc_createEntityReference,
1799 domdoc_getElementsByTagName,
1800 domdoc_createNode,
1801 domdoc_nodeFromID,
1802 domdoc_load,
1803 domdoc_get_readyState,
1804 domdoc_get_parseError,
1805 domdoc_get_url,
1806 domdoc_get_async,
1807 domdoc_put_async,
1808 domdoc_abort,
1809 domdoc_loadXML,
1810 domdoc_save,
1811 domdoc_get_validateOnParse,
1812 domdoc_put_validateOnParse,
1813 domdoc_get_resolveExternals,
1814 domdoc_put_resolveExternals,
1815 domdoc_get_preserveWhiteSpace,
1816 domdoc_put_preserveWhiteSpace,
1817 domdoc_put_onReadyStateChange,
1818 domdoc_put_onDataAvailable,
1819 domdoc_put_onTransformNode,
1820 domdoc_get_namespaces,
1821 domdoc_get_schemas,
1822 domdoc_putref_schemas,
1823 domdoc_validate,
1824 domdoc_setProperty,
1825 domdoc_getProperty
1828 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1830 domdoc *doc;
1831 HRESULT hr;
1832 xmlDocPtr xmldoc;
1834 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1836 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1837 if( !doc )
1838 return E_OUTOFMEMORY;
1840 doc->lpVtbl = &domdoc_vtbl;
1841 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
1842 doc->ref = 1;
1843 doc->async = 0;
1844 doc->validating = 0;
1845 doc->resolving = 0;
1846 doc->preserving = 0;
1847 doc->bUseXPath = FALSE;
1848 doc->error = S_OK;
1849 doc->schema = NULL;
1850 doc->stream = NULL;
1852 xmldoc = xmlNewDoc(NULL);
1853 if(!xmldoc)
1855 HeapFree(GetProcessHeap(), 0, doc);
1856 return E_OUTOFMEMORY;
1859 xmldoc->_private = 0;
1861 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1862 if(!doc->node_unk)
1864 xmlFreeDoc(xmldoc);
1865 HeapFree(GetProcessHeap(), 0, doc);
1866 return E_FAIL;
1869 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1870 if(FAILED(hr))
1872 IUnknown_Release(doc->node_unk);
1873 HeapFree( GetProcessHeap(), 0, doc );
1874 return E_FAIL;
1876 /* The ref on doc->node is actually looped back into this object, so release it */
1877 IXMLDOMNode_Release(doc->node);
1879 *ppObj = &doc->lpVtbl;
1881 TRACE("returning iface %p\n", *ppObj);
1882 return S_OK;
1885 #else
1887 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1889 MESSAGE("This program tried to use a DOMDocument object, but\n"
1890 "libxml2 support was not present at compile time.\n");
1891 return E_NOTIMPL;
1894 #endif