quartz/tests: Add filtermapper aggregation tests.
[wine.git] / dlls / msxml3 / domdoc.c
blob3952b5e9e7c1e167bcccff2defeec5f7686e3335
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
22 #define NONAMELESSUNION
24 #include "config.h"
26 #include <stdarg.h>
27 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winnls.h"
32 #include "ole2.h"
33 #include "msxml2.h"
34 #include "wininet.h"
35 #include "urlmon.h"
36 #include "winreg.h"
37 #include "shlwapi.h"
38 #include "ocidl.h"
39 #include "objsafe.h"
41 #include "wine/debug.h"
43 #include "msxml_private.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
47 #ifdef HAVE_LIBXML2
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;
61 LONG ref;
62 VARIANT_BOOL async;
63 VARIANT_BOOL validating;
64 VARIANT_BOOL resolving;
65 VARIANT_BOOL preserving;
66 BOOL bUseXPath;
67 IUnknown *node_unk;
68 IXMLDOMNode *node;
69 IXMLDOMSchemaCollection *schema;
70 bsc_t *bsc;
71 HRESULT error;
73 /* IPersistStream */
74 IStream *stream;
76 /* IObjectWithSite*/
77 IUnknown *site;
79 /* IObjectSafety */
80 DWORD safeopt;
81 } domdoc;
83 struct bsc_t {
84 const struct IBindStatusCallbackVtbl *lpVtbl;
86 LONG ref;
88 domdoc *doc;
89 IBinding *binding;
90 IStream *memstream;
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 );
107 #else
108 return xmlParseMemory( ptr, len );
109 #endif
112 static HRESULT WINAPI bsc_QueryInterface(
113 IBindStatusCallback *iface,
114 REFIID riid,
115 LPVOID *ppobj )
117 if (IsEqualGUID(riid, &IID_IUnknown) ||
118 IsEqualGUID(riid, &IID_IBindStatusCallback))
120 IBindStatusCallback_AddRef( iface );
121 *ppobj = iface;
122 return S_OK;
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);
137 return 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);
148 if(!ref) {
149 if(This->binding)
150 IBinding_Release(This->binding);
151 if(This->doc && This->doc->bsc == This)
152 This->doc->bsc = NULL;
153 if(This->memstream)
154 IStream_Release(This->memstream);
155 HeapFree(GetProcessHeap(), 0, This);
158 return ref;
161 static HRESULT WINAPI bsc_OnStartBinding(
162 IBindStatusCallback* iface,
163 DWORD dwReserved,
164 IBinding* pib)
166 bsc_t *This = impl_from_IBindStatusCallback(iface);
167 HRESULT hr;
169 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
171 This->binding = pib;
172 IBindStatusCallback_AddRef(pib);
174 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
175 if(FAILED(hr))
176 return hr;
178 return S_OK;
181 static HRESULT WINAPI bsc_GetPriority(
182 IBindStatusCallback* iface,
183 LONG* pnPriority)
185 return S_OK;
188 static HRESULT WINAPI bsc_OnLowResource(
189 IBindStatusCallback* iface,
190 DWORD reserved)
192 return S_OK;
195 static HRESULT WINAPI bsc_OnProgress(
196 IBindStatusCallback* iface,
197 ULONG ulProgress,
198 ULONG ulProgressMax,
199 ULONG ulStatusCode,
200 LPCWSTR szStatusText)
202 return S_OK;
205 static HRESULT WINAPI bsc_OnStopBinding(
206 IBindStatusCallback* iface,
207 HRESULT hresult,
208 LPCWSTR szError)
210 bsc_t *This = impl_from_IBindStatusCallback(iface);
211 HRESULT hr;
213 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
215 if(This->binding) {
216 IBinding_Release(This->binding);
217 This->binding = NULL;
220 if(This->doc && SUCCEEDED(hresult)) {
221 HGLOBAL hglobal;
222 hr = GetHGlobalFromStream(This->memstream, &hglobal);
223 if(SUCCEEDED(hr))
225 DWORD len = GlobalSize(hglobal);
226 char *ptr = GlobalLock(hglobal);
227 xmlDocPtr xmldoc;
228 if(len != 0) {
229 xmldoc = doparse( ptr, len );
230 if(xmldoc) {
231 xmldoc->_private = 0;
232 attach_xmlnode(This->doc->node, (xmlNodePtr) xmldoc);
235 GlobalUnlock(hglobal);
239 return S_OK;
242 static HRESULT WINAPI bsc_GetBindInfo(
243 IBindStatusCallback* iface,
244 DWORD* grfBINDF,
245 BINDINFO* pbindinfo)
247 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
249 return S_OK;
252 static HRESULT WINAPI bsc_OnDataAvailable(
253 IBindStatusCallback* iface,
254 DWORD grfBSCF,
255 DWORD dwSize,
256 FORMATETC* pformatetc,
257 STGMEDIUM* pstgmed)
259 bsc_t *This = impl_from_IBindStatusCallback(iface);
260 BYTE buf[4096];
261 DWORD read, written;
262 HRESULT hr;
264 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
268 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
269 if(FAILED(hr))
270 break;
272 hr = IStream_Write(This->memstream, buf, read, &written);
273 } while(SUCCEEDED(hr) && written != 0 && read != 0);
275 return S_OK;
278 static HRESULT WINAPI bsc_OnObjectAvailable(
279 IBindStatusCallback* iface,
280 REFIID riid,
281 IUnknown* punk)
283 return S_OK;
286 static const struct IBindStatusCallbackVtbl bsc_vtbl =
288 bsc_QueryInterface,
289 bsc_AddRef,
290 bsc_Release,
291 bsc_OnStartBinding,
292 bsc_GetPriority,
293 bsc_OnLowResource,
294 bsc_OnProgress,
295 bsc_OnStopBinding,
296 bsc_GetBindInfo,
297 bsc_OnDataAvailable,
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;
306 bsc->ref = 1;
307 bsc->doc = doc;
308 bsc->binding = NULL;
309 bsc->memstream = NULL;
311 return bsc;
314 LONG xmldoc_add_ref(xmlDocPtr doc)
316 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
317 TRACE("%d\n", ref);
318 return ref;
321 LONG xmldoc_release(xmlDocPtr doc)
323 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
324 TRACE("%d\n", ref);
325 if(ref == 0)
327 TRACE("freeing docptr %p\n", doc);
328 xmlFreeDoc(doc);
331 return ref;
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);
389 if(!classid)
390 return E_POINTER;
392 *classid = CLSID_DOMDocument2;
394 return S_OK;
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);
404 return S_FALSE;
407 static HRESULT WINAPI xmldoc_IPersistStream_Load(
408 IPersistStream *iface, LPSTREAM pStm)
410 domdoc *This = impl_from_IPersistStream(iface);
411 HRESULT hr;
412 HGLOBAL hglobal;
413 DWORD read, written, len;
414 BYTE buf[4096];
415 char *ptr;
416 xmlDocPtr xmldoc = NULL;
418 TRACE("(%p, %p)\n", iface, pStm);
420 if (!pStm)
421 return E_INVALIDARG;
423 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
424 if (FAILED(hr))
425 return hr;
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);
433 if (FAILED(hr))
435 ERR("Failed to copy stream\n");
436 return hr;
439 hr = GetHGlobalFromStream(This->stream, &hglobal);
440 if (FAILED(hr))
441 return hr;
443 len = GlobalSize(hglobal);
444 ptr = GlobalLock(hglobal);
445 if (len != 0)
446 xmldoc = parse_xml(ptr, len);
447 GlobalUnlock(hglobal);
449 if (!xmldoc)
451 ERR("Failed to parse xml\n");
452 return E_FAIL;
455 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
457 return S_OK;
460 static HRESULT WINAPI xmldoc_IPersistStream_Save(
461 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
463 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
464 return E_NOTIMPL;
467 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
468 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
470 TRACE("(%p, %p): stub!\n", iface, pcbSize);
471 return E_NOTIMPL;
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 );
492 *ppvObject = NULL;
494 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
495 IsEqualGUID( riid, &IID_IDispatch ) ||
496 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
497 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
499 *ppvObject = iface;
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;
518 else
520 FIXME("interface %s not implemented\n", debugstr_guid(riid));
521 return E_NOINTERFACE;
524 IXMLDOMDocument_AddRef( iface );
526 return S_OK;
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 );
543 LONG ref;
545 TRACE("%p\n", This );
547 ref = InterlockedDecrement( &This->ref );
548 if ( ref == 0 )
550 if(This->bsc) {
551 if(This->bsc->binding)
552 IBinding_Abort(This->bsc->binding);
553 This->bsc->doc = NULL;
554 IBindStatusCallback_Release((IBindStatusCallback*)&This->bsc->lpVtbl);
557 if (This->site)
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 );
565 return ref;
568 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
572 TRACE("(%p)->(%p)\n", This, pctinfo);
574 *pctinfo = 1;
576 return S_OK;
579 static HRESULT WINAPI domdoc_GetTypeInfo(
580 IXMLDOMDocument2 *iface,
581 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
583 domdoc *This = impl_from_IXMLDOMDocument2( iface );
584 HRESULT hr;
586 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
588 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
590 return hr;
593 static HRESULT WINAPI domdoc_GetIDsOfNames(
594 IXMLDOMDocument2 *iface,
595 REFIID riid,
596 LPOLESTR* rgszNames,
597 UINT cNames,
598 LCID lcid,
599 DISPID* rgDispId)
601 domdoc *This = impl_from_IXMLDOMDocument2( iface );
602 ITypeInfo *typeinfo;
603 HRESULT hr;
605 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
606 lcid, rgDispId);
608 if(!rgszNames || cNames == 0 || !rgDispId)
609 return E_INVALIDARG;
611 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
612 if(SUCCEEDED(hr))
614 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
615 ITypeInfo_Release(typeinfo);
618 return hr;
622 static HRESULT WINAPI domdoc_Invoke(
623 IXMLDOMDocument2 *iface,
624 DISPID dispIdMember,
625 REFIID riid,
626 LCID lcid,
627 WORD wFlags,
628 DISPPARAMS* pDispParams,
629 VARIANT* pVarResult,
630 EXCEPINFO* pExcepInfo,
631 UINT* puArgErr)
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 ITypeInfo *typeinfo;
635 HRESULT hr;
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);
641 if(SUCCEEDED(hr))
643 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
644 pVarResult, pExcepInfo, puArgErr);
645 ITypeInfo_Release(typeinfo);
648 return hr;
652 static HRESULT WINAPI domdoc_get_nodeName(
653 IXMLDOMDocument2 *iface,
654 BSTR* name )
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,
663 VARIANT* value )
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,
672 VARIANT value)
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,
681 DOMNodeType* type )
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,
754 VARIANT refChild,
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,
813 VARIANT_BOOL deep,
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,
823 BSTR* nodeType )
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,
832 BSTR* text )
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,
841 BSTR text )
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,
876 VARIANT typedValue )
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,
894 BSTR dataTypeName )
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,
903 BSTR* xmlString )
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,
913 BSTR* xmlString )
915 domdoc *This = impl_from_IXMLDOMDocument2( iface );
916 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
920 static HRESULT WINAPI domdoc_selectNodes(
921 IXMLDOMDocument2 *iface,
922 BSTR queryString,
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,
932 BSTR queryString,
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,
951 BSTR* namespaceURI )
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,
960 BSTR* prefixString )
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,
969 BSTR* nameString )
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 )
990 FIXME("\n");
991 return E_NOTIMPL;
995 static HRESULT WINAPI domdoc_get_implementation(
996 IXMLDOMDocument2 *iface,
997 IXMLDOMImplementation** impl )
999 if(!impl)
1000 return E_INVALIDARG;
1002 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1004 return S_OK;
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;
1015 HRESULT hr;
1017 TRACE("%p %p\n", This, This->node);
1019 if(!DOMElement)
1020 return E_INVALIDARG;
1022 *DOMElement = NULL;
1024 xmldoc = get_doc( This );
1026 root = xmlDocGetRootElement( xmldoc );
1027 if ( !root )
1028 return S_FALSE;
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);
1036 return hr;
1040 static HRESULT WINAPI domdoc_put_documentElement(
1041 IXMLDOMDocument2 *iface,
1042 IXMLDOMElement* DOMElement )
1044 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1045 IXMLDOMNode *elementNode;
1046 xmlnode *xmlNode;
1047 HRESULT hr;
1049 TRACE("(%p)->(%p)\n", This, DOMElement);
1051 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1052 if(FAILED(hr))
1053 return hr;
1055 xmlNode = impl_from_IXMLDOMNode( elementNode );
1056 xmlDocSetRootElement( get_doc(This), xmlNode->node);
1057 IXMLDOMNode_Release( elementNode );
1059 return S_OK;
1063 static HRESULT WINAPI domdoc_createElement(
1064 IXMLDOMDocument2 *iface,
1065 BSTR tagname,
1066 IXMLDOMElement** element )
1068 xmlNodePtr xmlnode;
1069 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1070 xmlChar *xml_name;
1071 IUnknown *elem_unk;
1072 HRESULT hr;
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);
1086 return hr;
1090 static HRESULT WINAPI domdoc_createDocumentFragment(
1091 IXMLDOMDocument2 *iface,
1092 IXMLDOMDocumentFragment** docFrag )
1094 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1095 xmlNodePtr xmlnode;
1097 TRACE("%p\n", iface);
1099 if(!docFrag)
1100 return E_INVALIDARG;
1102 *docFrag = NULL;
1104 xmlnode = xmlNewDocFragment(get_doc( This ) );
1106 if(!xmlnode)
1107 return E_FAIL;
1109 xmlnode->doc = get_doc( This );
1111 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1113 return S_OK;
1117 static HRESULT WINAPI domdoc_createTextNode(
1118 IXMLDOMDocument2 *iface,
1119 BSTR data,
1120 IXMLDOMText** text )
1122 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1123 xmlNodePtr xmlnode;
1124 xmlChar *xml_content;
1126 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1128 if(!text)
1129 return E_INVALIDARG;
1131 *text = NULL;
1133 xml_content = xmlChar_from_wchar((WCHAR*)data);
1134 xmlnode = xmlNewText(xml_content);
1135 HeapFree(GetProcessHeap(), 0, xml_content);
1137 if(!xmlnode)
1138 return E_FAIL;
1140 xmlnode->doc = get_doc( This );
1142 *text = (IXMLDOMText*)create_text(xmlnode);
1144 return S_OK;
1148 static HRESULT WINAPI domdoc_createComment(
1149 IXMLDOMDocument2 *iface,
1150 BSTR data,
1151 IXMLDOMComment** comment )
1153 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1154 xmlNodePtr xmlnode;
1155 xmlChar *xml_content;
1157 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1159 if(!comment)
1160 return E_INVALIDARG;
1162 *comment = NULL;
1164 xml_content = xmlChar_from_wchar((WCHAR*)data);
1165 xmlnode = xmlNewComment(xml_content);
1166 HeapFree(GetProcessHeap(), 0, xml_content);
1168 if(!xmlnode)
1169 return E_FAIL;
1171 xmlnode->doc = get_doc( This );
1173 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1175 return S_OK;
1179 static HRESULT WINAPI domdoc_createCDATASection(
1180 IXMLDOMDocument2 *iface,
1181 BSTR data,
1182 IXMLDOMCDATASection** cdata )
1184 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1185 xmlNodePtr xmlnode;
1186 xmlChar *xml_content;
1188 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1190 if(!cdata)
1191 return E_INVALIDARG;
1193 *cdata = NULL;
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);
1199 if(!xmlnode)
1200 return E_FAIL;
1202 xmlnode->doc = get_doc( This );
1204 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1206 return S_OK;
1210 static HRESULT WINAPI domdoc_createProcessingInstruction(
1211 IXMLDOMDocument2 *iface,
1212 BSTR target,
1213 BSTR data,
1214 IXMLDOMProcessingInstruction** pi )
1216 #ifdef HAVE_XMLNEWDOCPI
1217 xmlNodePtr xmlnode;
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);
1223 if(!pi)
1224 return E_INVALIDARG;
1226 if(!target || lstrlenW(target) == 0)
1227 return E_FAIL;
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);
1239 return S_OK;
1240 #else
1241 FIXME("Libxml 2.6.15 or greater required.\n");
1242 return E_NOTIMPL;
1243 #endif
1247 static HRESULT WINAPI domdoc_createAttribute(
1248 IXMLDOMDocument2 *iface,
1249 BSTR name,
1250 IXMLDOMAttribute** attribute )
1252 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1253 xmlNodePtr xmlnode;
1254 xmlChar *xml_name;
1256 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1258 if(!attribute)
1259 return E_INVALIDARG;
1261 *attribute = NULL;
1263 xml_name = xmlChar_from_wchar((WCHAR*)name);
1264 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1265 HeapFree(GetProcessHeap(), 0, xml_name);
1267 if(!xmlnode)
1268 return E_FAIL;
1270 xmlnode->doc = get_doc( This );
1272 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1274 return S_OK;
1278 static HRESULT WINAPI domdoc_createEntityReference(
1279 IXMLDOMDocument2 *iface,
1280 BSTR name,
1281 IXMLDOMEntityReference** entityRef )
1283 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1284 xmlNodePtr xmlnode;
1285 xmlChar *xml_name;
1287 TRACE("%p\n", iface);
1289 if(!entityRef)
1290 return E_INVALIDARG;
1292 *entityRef = NULL;
1294 xml_name = xmlChar_from_wchar((WCHAR*)name);
1295 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1296 HeapFree(GetProcessHeap(), 0, xml_name);
1298 if(!xmlnode)
1299 return E_FAIL;
1301 xmlnode->doc = get_doc( This );
1303 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1305 return S_OK;
1309 static HRESULT WINAPI domdoc_getElementsByTagName(
1310 IXMLDOMDocument2 *iface,
1311 BSTR tagName,
1312 IXMLDOMNodeList** resultList )
1314 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1315 LPWSTR szPattern;
1316 HRESULT hr;
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);
1326 return hr;
1329 static DOMNodeType get_node_type(VARIANT Type)
1331 if(V_VT(&Type) == VT_I4)
1332 return V_I4(&Type);
1334 FIXME("Unsupported variant type %x\n", V_VT(&Type));
1335 return 0;
1338 static HRESULT WINAPI domdoc_createNode(
1339 IXMLDOMDocument2 *iface,
1340 VARIANT Type,
1341 BSTR name,
1342 BSTR namespaceURI,
1343 IXMLDOMNode** node )
1345 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1346 DOMNodeType node_type;
1347 xmlNodePtr xmlnode = NULL;
1348 xmlChar *xml_name;
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);
1357 switch(node_type)
1359 case NODE_ELEMENT:
1360 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1361 *node = create_node(xmlnode);
1362 TRACE("created %p\n", xmlnode);
1363 break;
1364 case NODE_ATTRIBUTE:
1365 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1366 if(xmlnode)
1368 xmlnode->doc = get_doc( This );
1370 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1373 TRACE("created %p\n", xmlnode);
1374 break;
1376 default:
1377 FIXME("unhandled node type %d\n", node_type);
1378 break;
1381 HeapFree(GetProcessHeap(), 0, xml_name);
1383 if(xmlnode && *node)
1384 return S_OK;
1386 return E_FAIL;
1389 static HRESULT WINAPI domdoc_nodeFromID(
1390 IXMLDOMDocument2 *iface,
1391 BSTR idString,
1392 IXMLDOMNode** node )
1394 FIXME("\n");
1395 return E_NOTIMPL;
1398 static HRESULT doread( domdoc *This, LPWSTR filename )
1400 HRESULT hr;
1401 IBindCtx *pbc;
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");
1414 return E_FAIL;
1417 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
1419 ERR("can't create url from path\n");
1420 return E_FAIL;
1422 filename = url;
1425 hr = CreateBindCtx(0, &pbc);
1426 if(SUCCEEDED(hr))
1428 if(This->bsc) {
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);
1438 if(SUCCEEDED(hr))
1440 IMoniker *moniker;
1441 hr = CreateURLMoniker(NULL, filename, &moniker);
1442 if(SUCCEEDED(hr))
1444 IStream *stream;
1445 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
1446 IMoniker_Release(moniker);
1447 if(stream)
1448 IStream_Release(stream);
1451 IBindCtx_Release(pbc);
1454 return hr;
1457 static HRESULT WINAPI domdoc_load(
1458 IXMLDOMDocument2 *iface,
1459 VARIANT xmlSource,
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;
1467 xmlDocPtr xmldoc;
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) )
1479 case VT_BSTR:
1480 filename = V_BSTR(&xmlSource);
1481 break;
1482 case VT_UNKNOWN:
1483 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1484 if(hr == S_OK)
1486 if(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;
1494 return S_OK;
1497 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1498 if(hr == S_OK)
1500 IPersistStream *pDocStream;
1501 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1502 if(hr == S_OK)
1504 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1505 IStream_Release(pStream);
1506 if(hr == S_OK)
1508 *isSuccessful = VARIANT_TRUE;
1510 TRACE("Using ID_IStream to load Document\n");
1511 return S_OK;
1513 else
1515 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1518 else
1520 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1523 else
1525 /* ISequentialStream */
1526 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1528 break;
1529 default:
1530 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1533 TRACE("filename (%s)\n", debugstr_w(filename));
1535 if ( filename )
1537 hr = doread( This, filename );
1539 if ( FAILED(hr) )
1540 This->error = E_FAIL;
1541 else
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);
1552 hr = S_FALSE;
1555 TRACE("ret (%d)\n", hr);
1557 return hr;
1561 static HRESULT WINAPI domdoc_get_readyState(
1562 IXMLDOMDocument2 *iface,
1563 long* value )
1565 FIXME("\n");
1566 return E_NOTIMPL;
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);
1580 if(This->error)
1581 error_string = SysAllocString(err);
1583 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1584 if(!*errorObj) return E_OUTOFMEMORY;
1585 return S_OK;
1589 static HRESULT WINAPI domdoc_get_url(
1590 IXMLDOMDocument2 *iface,
1591 BSTR* urlString )
1593 FIXME("\n");
1594 return E_NOTIMPL;
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;
1606 return S_OK;
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;
1618 return S_OK;
1622 static HRESULT WINAPI domdoc_abort(
1623 IXMLDOMDocument2 *iface )
1625 FIXME("\n");
1626 return E_NOTIMPL;
1630 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1632 UINT len, blen = SysStringLen( bstr );
1633 LPSTR str;
1635 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1636 str = HeapAlloc( GetProcessHeap(), 0, len );
1637 if ( !str )
1638 return FALSE;
1639 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1640 *plen = len;
1641 *pstr = str;
1642 return TRUE;
1645 static HRESULT WINAPI domdoc_loadXML(
1646 IXMLDOMDocument2 *iface,
1647 BSTR bstrXML,
1648 VARIANT_BOOL* isSuccessful )
1650 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1651 xmlDocPtr xmldoc = NULL;
1652 char *str;
1653 int len;
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 );
1662 if ( isSuccessful )
1664 *isSuccessful = VARIANT_FALSE;
1666 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1668 xmldoc = doparse( str, len );
1669 HeapFree( GetProcessHeap(), 0, str );
1670 if ( !xmldoc )
1671 This->error = E_FAIL;
1672 else
1674 hr = This->error = S_OK;
1675 *isSuccessful = VARIANT_TRUE;
1679 if(!xmldoc)
1680 xmldoc = xmlNewDoc(NULL);
1682 xmldoc->_private = 0;
1683 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1685 return hr;
1689 static HRESULT WINAPI domdoc_save(
1690 IXMLDOMDocument2 *iface,
1691 VARIANT destination )
1693 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1694 HANDLE handle;
1695 xmlChar *mem, *p;
1696 int size;
1697 HRESULT ret = S_OK;
1698 DWORD written;
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));
1706 return S_FALSE;
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);
1715 if(ret == S_OK)
1717 BSTR bXML;
1718 VARIANT_BOOL bSuccessful;
1720 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1721 if(ret == S_OK)
1723 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1725 SysFreeString(bXML);
1728 IXMLDOMDocument_Release(pDocument);
1731 return ret;
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");
1739 return S_FALSE;
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.
1749 p = mem;
1750 if(size > 2 && p[0] == '<' && p[1] == '?') {
1751 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1752 p++;
1753 p += 2;
1754 while(p < mem+size && isspace(*p))
1755 p++;
1756 size -= p-mem;
1759 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1761 WARN("write error\n");
1762 ret = S_FALSE;
1765 xmlFree(mem);
1766 CloseHandle(handle);
1767 return ret;
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;
1778 return S_OK;
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;
1790 return S_OK;
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;
1802 return S_OK;
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;
1814 return S_OK;
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;
1826 return S_OK;
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;
1838 return S_OK;
1842 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1843 IXMLDOMDocument2 *iface,
1844 VARIANT readyStateChangeSink )
1846 FIXME("\n");
1847 return E_NOTIMPL;
1851 static HRESULT WINAPI domdoc_put_onDataAvailable(
1852 IXMLDOMDocument2 *iface,
1853 VARIANT onDataAvailableSink )
1855 FIXME("\n");
1856 return E_NOTIMPL;
1859 static HRESULT WINAPI domdoc_put_onTransformNode(
1860 IXMLDOMDocument2 *iface,
1861 VARIANT onTransformNodeSink )
1863 FIXME("\n");
1864 return E_NOTIMPL;
1867 static HRESULT WINAPI domdoc_get_namespaces(
1868 IXMLDOMDocument2* iface,
1869 IXMLDOMSchemaCollection** schemaCollection )
1871 FIXME("\n");
1872 return E_NOTIMPL;
1875 static HRESULT WINAPI domdoc_get_schemas(
1876 IXMLDOMDocument2* iface,
1877 VARIANT* var1 )
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;
1888 if(cur_schema)
1890 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1891 if(SUCCEEDED(hr))
1892 V_VT(var1) = VT_DISPATCH;
1894 return hr;
1897 static HRESULT WINAPI domdoc_putref_schemas(
1898 IXMLDOMDocument2* iface,
1899 VARIANT var1)
1901 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1902 HRESULT hr = E_FAIL;
1903 IXMLDOMSchemaCollection *new_schema = NULL;
1905 FIXME("(%p): semi-stub\n", This);
1906 switch(V_VT(&var1))
1908 case VT_UNKNOWN:
1909 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1910 break;
1912 case VT_DISPATCH:
1913 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1914 break;
1916 case VT_NULL:
1917 case VT_EMPTY:
1918 hr = S_OK;
1919 break;
1921 default:
1922 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1925 if(SUCCEEDED(hr))
1927 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1928 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1931 return hr;
1934 static HRESULT WINAPI domdoc_validate(
1935 IXMLDOMDocument2* iface,
1936 IXMLDOMParseError** err)
1938 FIXME("\n");
1939 return E_NOTIMPL;
1942 static HRESULT WINAPI domdoc_setProperty(
1943 IXMLDOMDocument2* iface,
1944 BSTR p,
1945 VARIANT var)
1947 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1949 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1951 VARIANT varStr;
1952 HRESULT hr;
1953 BSTR bstr;
1955 V_VT(&varStr) = VT_EMPTY;
1956 if (V_VT(&var) != VT_BSTR)
1958 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1959 return hr;
1960 bstr = V_BSTR(&varStr);
1962 else
1963 bstr = V_BSTR(&var);
1965 hr = S_OK;
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;
1970 else
1971 hr = E_FAIL;
1973 VariantClear(&varStr);
1974 return hr;
1977 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1978 return E_FAIL;
1981 static HRESULT WINAPI domdoc_getProperty(
1982 IXMLDOMDocument2* iface,
1983 BSTR p,
1984 VARIANT* var)
1986 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1988 if (var == NULL)
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);
1995 else
1996 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1997 return S_OK;
2000 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2001 return E_FAIL;
2004 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2006 domdoc_QueryInterface,
2007 domdoc_AddRef,
2008 domdoc_Release,
2009 domdoc_GetTypeInfoCount,
2010 domdoc_GetTypeInfo,
2011 domdoc_GetIDsOfNames,
2012 domdoc_Invoke,
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,
2026 domdoc_removeChild,
2027 domdoc_appendChild,
2028 domdoc_hasChildNodes,
2029 domdoc_get_ownerDocument,
2030 domdoc_cloneNode,
2031 domdoc_get_nodeTypeString,
2032 domdoc_get_text,
2033 domdoc_put_text,
2034 domdoc_get_specified,
2035 domdoc_get_definition,
2036 domdoc_get_nodeTypedValue,
2037 domdoc_put_nodeTypedValue,
2038 domdoc_get_dataType,
2039 domdoc_put_dataType,
2040 domdoc_get_xml,
2041 domdoc_transformNode,
2042 domdoc_selectNodes,
2043 domdoc_selectSingleNode,
2044 domdoc_get_parsed,
2045 domdoc_get_namespaceURI,
2046 domdoc_get_prefix,
2047 domdoc_get_baseName,
2048 domdoc_transformNodeToObject,
2049 domdoc_get_doctype,
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,
2062 domdoc_createNode,
2063 domdoc_nodeFromID,
2064 domdoc_load,
2065 domdoc_get_readyState,
2066 domdoc_get_parseError,
2067 domdoc_get_url,
2068 domdoc_get_async,
2069 domdoc_put_async,
2070 domdoc_abort,
2071 domdoc_loadXML,
2072 domdoc_save,
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,
2083 domdoc_get_schemas,
2084 domdoc_putref_schemas,
2085 domdoc_validate,
2086 domdoc_setProperty,
2087 domdoc_getProperty
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 );
2098 static ULONG WINAPI
2099 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2101 domdoc *This = impl_from_IObjectWithSite(iface);
2102 return IXMLDocument_AddRef((IXMLDocument *)This);
2105 static ULONG WINAPI
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 );
2119 if ( !This->site )
2120 return E_FAIL;
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);
2132 if(!punk)
2134 if(This->site)
2136 IUnknown_Release( This->site );
2137 This->site = NULL;
2140 return S_OK;
2143 if ( punk )
2144 IUnknown_AddRef( punk );
2146 if(This->site)
2147 IUnknown_Release( This->site );
2149 This->site = punk;
2151 return S_OK;
2154 static const IObjectWithSiteVtbl domdocObjectSite =
2156 xmldoc_ObjectWithSite_QueryInterface,
2157 xmldoc_ObjectWithSite_AddRef,
2158 xmldoc_ObjectWithSite_Release,
2159 xmldoc_SetSite,
2160 xmldoc_GetSite,
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)
2191 return E_POINTER;
2193 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2194 *pdwEnabledOptions = This->safeopt;
2196 return S_OK;
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)
2207 return E_FAIL;
2209 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2210 return S_OK;
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)
2223 domdoc *doc;
2224 HRESULT hr;
2226 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2227 if( !doc )
2228 return E_OUTOFMEMORY;
2230 doc->lpVtbl = &domdoc_vtbl;
2231 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2232 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2233 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2234 doc->ref = 1;
2235 doc->async = 0;
2236 doc->validating = 0;
2237 doc->resolving = 0;
2238 doc->preserving = 0;
2239 doc->bUseXPath = FALSE;
2240 doc->error = S_OK;
2241 doc->schema = NULL;
2242 doc->stream = NULL;
2243 doc->site = NULL;
2244 doc->safeopt = 0;
2245 doc->bsc = NULL;
2247 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2248 if(!doc->node_unk)
2250 HeapFree(GetProcessHeap(), 0, doc);
2251 return E_FAIL;
2254 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2255 if(FAILED(hr))
2257 IUnknown_Release(doc->node_unk);
2258 HeapFree( GetProcessHeap(), 0, doc );
2259 return E_FAIL;
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);
2267 return S_OK;
2270 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2272 xmlDocPtr xmldoc;
2273 HRESULT hr;
2275 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2277 xmldoc = xmlNewDoc(NULL);
2278 if(!xmldoc)
2279 return E_OUTOFMEMORY;
2281 xmldoc->_private = 0;
2283 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2284 if(FAILED(hr))
2285 xmlFreeDoc(xmldoc);
2287 return hr;
2290 IUnknown* create_domdoc( xmlNodePtr document )
2292 HRESULT hr;
2293 LPVOID pObj = NULL;
2295 TRACE("(%p)\n", document);
2297 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2298 if (FAILED(hr))
2299 return NULL;
2301 return (IUnknown*)pObj;
2304 #else
2306 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2308 MESSAGE("This program tried to use a DOMDocument object, but\n"
2309 "libxml2 support was not present at compile time.\n");
2310 return E_NOTIMPL;
2313 #endif