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
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
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};
51 const struct IBindStatusCallbackVtbl *lpVtbl;
54 static HRESULT WINAPI bsc_QueryInterface(
55 IBindStatusCallback *iface,
59 if (IsEqualGUID(riid, &IID_IUnknown) ||
60 IsEqualGUID(riid, &IID_IBindStatusCallback))
62 IBindStatusCallback_AddRef( iface );
67 FIXME("interface %s not implemented\n", debugstr_guid(riid));
71 static ULONG WINAPI bsc_AddRef(
72 IBindStatusCallback *iface )
77 static ULONG WINAPI bsc_Release(
78 IBindStatusCallback *iface )
83 static HRESULT WINAPI bsc_OnStartBinding(
84 IBindStatusCallback* iface,
91 static HRESULT WINAPI bsc_GetPriority(
92 IBindStatusCallback* iface,
98 static HRESULT WINAPI bsc_OnLowResource(
99 IBindStatusCallback* iface,
105 static HRESULT WINAPI bsc_OnProgress(
106 IBindStatusCallback* iface,
110 LPCWSTR szStatusText)
115 static HRESULT WINAPI bsc_OnStopBinding(
116 IBindStatusCallback* iface,
123 static HRESULT WINAPI bsc_GetBindInfo(
124 IBindStatusCallback* iface,
128 *grfBINDF = BINDF_RESYNCHRONIZE;
133 static HRESULT WINAPI bsc_OnDataAvailable(
134 IBindStatusCallback* iface,
137 FORMATETC* pformatetc,
143 static HRESULT WINAPI bsc_OnObjectAvailable(
144 IBindStatusCallback* iface,
151 static const struct IBindStatusCallbackVtbl bsc_vtbl =
163 bsc_OnObjectAvailable
166 static bsc domdoc_bsc = { &bsc_vtbl };
168 typedef struct _domdoc
170 const struct IXMLDOMDocument2Vtbl *lpVtbl;
173 VARIANT_BOOL validating;
174 VARIANT_BOOL resolving;
175 VARIANT_BOOL preserving;
179 IXMLDOMSchemaCollection *schema;
183 LONG xmldoc_add_ref(xmlDocPtr doc)
185 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
190 LONG xmldoc_release(xmlDocPtr doc)
192 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
196 TRACE("freeing docptr %p\n", doc);
203 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
205 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
208 static inline xmlDocPtr get_doc( domdoc *This )
210 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
213 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
215 domdoc *This = impl_from_IXMLDOMDocument2( iface );
217 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
219 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
220 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
221 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
225 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
226 IsEqualGUID( riid, &IID_IDispatch ) )
228 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
232 FIXME("interface %s not implemented\n", debugstr_guid(riid));
233 return E_NOINTERFACE;
236 IXMLDOMDocument_AddRef( iface );
242 static ULONG WINAPI domdoc_AddRef(
243 IXMLDOMDocument2 *iface )
245 domdoc *This = impl_from_IXMLDOMDocument2( iface );
246 TRACE("%p\n", This );
247 return InterlockedIncrement( &This->ref );
251 static ULONG WINAPI domdoc_Release(
252 IXMLDOMDocument2 *iface )
254 domdoc *This = impl_from_IXMLDOMDocument2( iface );
257 TRACE("%p\n", This );
259 ref = InterlockedDecrement( &This->ref );
262 IUnknown_Release( This->node_unk );
263 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
264 HeapFree( GetProcessHeap(), 0, This );
270 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
276 static HRESULT WINAPI domdoc_GetTypeInfo(
277 IXMLDOMDocument2 *iface,
278 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
284 static HRESULT WINAPI domdoc_GetIDsOfNames(
285 IXMLDOMDocument2 *iface,
297 static HRESULT WINAPI domdoc_Invoke(
298 IXMLDOMDocument2 *iface,
303 DISPPARAMS* pDispParams,
305 EXCEPINFO* pExcepInfo,
313 static HRESULT WINAPI domdoc_get_nodeName(
314 IXMLDOMDocument2 *iface,
317 domdoc *This = impl_from_IXMLDOMDocument2( iface );
318 return IXMLDOMNode_get_nodeName( This->node, name );
322 static HRESULT WINAPI domdoc_get_nodeValue(
323 IXMLDOMDocument2 *iface,
326 domdoc *This = impl_from_IXMLDOMDocument2( iface );
327 return IXMLDOMNode_get_nodeValue( This->node, value );
331 static HRESULT WINAPI domdoc_put_nodeValue(
332 IXMLDOMDocument2 *iface,
335 domdoc *This = impl_from_IXMLDOMDocument2( iface );
336 return IXMLDOMNode_put_nodeValue( This->node, value );
340 static HRESULT WINAPI domdoc_get_nodeType(
341 IXMLDOMDocument2 *iface,
344 domdoc *This = impl_from_IXMLDOMDocument2( iface );
345 return IXMLDOMNode_get_nodeType( This->node, type );
349 static HRESULT WINAPI domdoc_get_parentNode(
350 IXMLDOMDocument2 *iface,
351 IXMLDOMNode** parent )
353 domdoc *This = impl_from_IXMLDOMDocument2( iface );
354 return IXMLDOMNode_get_parentNode( This->node, parent );
358 static HRESULT WINAPI domdoc_get_childNodes(
359 IXMLDOMDocument2 *iface,
360 IXMLDOMNodeList** childList )
362 domdoc *This = impl_from_IXMLDOMDocument2( iface );
363 return IXMLDOMNode_get_childNodes( This->node, childList );
367 static HRESULT WINAPI domdoc_get_firstChild(
368 IXMLDOMDocument2 *iface,
369 IXMLDOMNode** firstChild )
371 domdoc *This = impl_from_IXMLDOMDocument2( iface );
372 return IXMLDOMNode_get_firstChild( This->node, firstChild );
376 static HRESULT WINAPI domdoc_get_lastChild(
377 IXMLDOMDocument2 *iface,
378 IXMLDOMNode** lastChild )
380 domdoc *This = impl_from_IXMLDOMDocument2( iface );
381 return IXMLDOMNode_get_lastChild( This->node, lastChild );
385 static HRESULT WINAPI domdoc_get_previousSibling(
386 IXMLDOMDocument2 *iface,
387 IXMLDOMNode** previousSibling )
389 domdoc *This = impl_from_IXMLDOMDocument2( iface );
390 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
394 static HRESULT WINAPI domdoc_get_nextSibling(
395 IXMLDOMDocument2 *iface,
396 IXMLDOMNode** nextSibling )
398 domdoc *This = impl_from_IXMLDOMDocument2( iface );
399 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
403 static HRESULT WINAPI domdoc_get_attributes(
404 IXMLDOMDocument2 *iface,
405 IXMLDOMNamedNodeMap** attributeMap )
407 domdoc *This = impl_from_IXMLDOMDocument2( iface );
408 return IXMLDOMNode_get_attributes( This->node, attributeMap );
412 static HRESULT WINAPI domdoc_insertBefore(
413 IXMLDOMDocument2 *iface,
414 IXMLDOMNode* newChild,
416 IXMLDOMNode** outNewChild )
418 domdoc *This = impl_from_IXMLDOMDocument2( iface );
419 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
423 static HRESULT WINAPI domdoc_replaceChild(
424 IXMLDOMDocument2 *iface,
425 IXMLDOMNode* newChild,
426 IXMLDOMNode* oldChild,
427 IXMLDOMNode** outOldChild)
429 domdoc *This = impl_from_IXMLDOMDocument2( iface );
430 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
434 static HRESULT WINAPI domdoc_removeChild(
435 IXMLDOMDocument2 *iface,
436 IXMLDOMNode* childNode,
437 IXMLDOMNode** oldChild)
439 domdoc *This = impl_from_IXMLDOMDocument2( iface );
440 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
444 static HRESULT WINAPI domdoc_appendChild(
445 IXMLDOMDocument2 *iface,
446 IXMLDOMNode* newChild,
447 IXMLDOMNode** outNewChild)
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
454 static HRESULT WINAPI domdoc_hasChildNodes(
455 IXMLDOMDocument2 *iface,
456 VARIANT_BOOL* hasChild)
458 domdoc *This = impl_from_IXMLDOMDocument2( iface );
459 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
463 static HRESULT WINAPI domdoc_get_ownerDocument(
464 IXMLDOMDocument2 *iface,
465 IXMLDOMDocument** DOMDocument)
467 domdoc *This = impl_from_IXMLDOMDocument2( iface );
468 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
472 static HRESULT WINAPI domdoc_cloneNode(
473 IXMLDOMDocument2 *iface,
475 IXMLDOMNode** cloneRoot)
477 domdoc *This = impl_from_IXMLDOMDocument2( iface );
478 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
482 static HRESULT WINAPI domdoc_get_nodeTypeString(
483 IXMLDOMDocument2 *iface,
486 domdoc *This = impl_from_IXMLDOMDocument2( iface );
487 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
491 static HRESULT WINAPI domdoc_get_text(
492 IXMLDOMDocument2 *iface,
495 domdoc *This = impl_from_IXMLDOMDocument2( iface );
496 return IXMLDOMNode_get_text( This->node, text );
500 static HRESULT WINAPI domdoc_put_text(
501 IXMLDOMDocument2 *iface,
504 domdoc *This = impl_from_IXMLDOMDocument2( iface );
505 return IXMLDOMNode_put_text( This->node, text );
509 static HRESULT WINAPI domdoc_get_specified(
510 IXMLDOMDocument2 *iface,
511 VARIANT_BOOL* isSpecified )
513 domdoc *This = impl_from_IXMLDOMDocument2( iface );
514 return IXMLDOMNode_get_specified( This->node, isSpecified );
518 static HRESULT WINAPI domdoc_get_definition(
519 IXMLDOMDocument2 *iface,
520 IXMLDOMNode** definitionNode )
522 domdoc *This = impl_from_IXMLDOMDocument2( iface );
523 return IXMLDOMNode_get_definition( This->node, definitionNode );
527 static HRESULT WINAPI domdoc_get_nodeTypedValue(
528 IXMLDOMDocument2 *iface,
529 VARIANT* typedValue )
531 domdoc *This = impl_from_IXMLDOMDocument2( iface );
532 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
535 static HRESULT WINAPI domdoc_put_nodeTypedValue(
536 IXMLDOMDocument2 *iface,
539 domdoc *This = impl_from_IXMLDOMDocument2( iface );
540 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
544 static HRESULT WINAPI domdoc_get_dataType(
545 IXMLDOMDocument2 *iface,
546 VARIANT* dataTypeName )
548 domdoc *This = impl_from_IXMLDOMDocument2( iface );
549 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
553 static HRESULT WINAPI domdoc_put_dataType(
554 IXMLDOMDocument2 *iface,
557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
558 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
562 static HRESULT WINAPI domdoc_get_xml(
563 IXMLDOMDocument2 *iface,
566 domdoc *This = impl_from_IXMLDOMDocument2( iface );
567 return IXMLDOMNode_get_xml( This->node, xmlString );
571 static HRESULT WINAPI domdoc_transformNode(
572 IXMLDOMDocument2 *iface,
573 IXMLDOMNode* styleSheet,
576 domdoc *This = impl_from_IXMLDOMDocument2( iface );
577 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
581 static HRESULT WINAPI domdoc_selectNodes(
582 IXMLDOMDocument2 *iface,
584 IXMLDOMNodeList** resultList )
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
587 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
591 static HRESULT WINAPI domdoc_selectSingleNode(
592 IXMLDOMDocument2 *iface,
594 IXMLDOMNode** resultNode )
596 domdoc *This = impl_from_IXMLDOMDocument2( iface );
597 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
601 static HRESULT WINAPI domdoc_get_parsed(
602 IXMLDOMDocument2 *iface,
603 VARIANT_BOOL* isParsed )
605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 return IXMLDOMNode_get_parsed( This->node, isParsed );
610 static HRESULT WINAPI domdoc_get_namespaceURI(
611 IXMLDOMDocument2 *iface,
614 domdoc *This = impl_from_IXMLDOMDocument2( iface );
615 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
619 static HRESULT WINAPI domdoc_get_prefix(
620 IXMLDOMDocument2 *iface,
623 domdoc *This = impl_from_IXMLDOMDocument2( iface );
624 return IXMLDOMNode_get_prefix( This->node, prefixString );
628 static HRESULT WINAPI domdoc_get_baseName(
629 IXMLDOMDocument2 *iface,
632 domdoc *This = impl_from_IXMLDOMDocument2( iface );
633 return IXMLDOMNode_get_baseName( This->node, nameString );
637 static HRESULT WINAPI domdoc_transformNodeToObject(
638 IXMLDOMDocument2 *iface,
639 IXMLDOMNode* stylesheet,
640 VARIANT outputObject)
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
647 static HRESULT WINAPI domdoc_get_doctype(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMDocumentType** documentType )
656 static HRESULT WINAPI domdoc_get_implementation(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMImplementation** impl )
664 static HRESULT WINAPI domdoc_get_documentElement(
665 IXMLDOMDocument2 *iface,
666 IXMLDOMElement** DOMElement )
668 domdoc *This = impl_from_IXMLDOMDocument2( iface );
669 xmlDocPtr xmldoc = NULL;
670 xmlNodePtr root = NULL;
671 IXMLDOMNode *element_node;
678 xmldoc = get_doc( This );
680 root = xmlDocGetRootElement( xmldoc );
684 element_node = create_node( root );
685 if(!element_node) return S_FALSE;
687 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
688 IXMLDOMNode_Release(element_node);
694 static HRESULT WINAPI domdoc_documentElement(
695 IXMLDOMDocument2 *iface,
696 IXMLDOMElement* DOMElement )
703 static HRESULT WINAPI domdoc_createElement(
704 IXMLDOMDocument2 *iface,
706 IXMLDOMElement** element )
709 domdoc *This = impl_from_IXMLDOMDocument2( iface );
714 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
716 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
717 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
719 TRACE("created xmlptr %p\n", xmlnode);
720 elem_unk = create_element(xmlnode, NULL);
721 HeapFree(GetProcessHeap(), 0, xml_name);
723 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
724 IUnknown_Release(elem_unk);
725 TRACE("returning %p\n", *element);
730 static HRESULT WINAPI domdoc_createDocumentFragment(
731 IXMLDOMDocument2 *iface,
732 IXMLDOMDocumentFragment** docFrag )
739 static HRESULT WINAPI domdoc_createTextNode(
740 IXMLDOMDocument2 *iface,
749 static HRESULT WINAPI domdoc_createComment(
750 IXMLDOMDocument2 *iface,
752 IXMLDOMComment** comment )
759 static HRESULT WINAPI domdoc_createCDATASection(
760 IXMLDOMDocument2 *iface,
762 IXMLDOMCDATASection** cdata )
769 static HRESULT WINAPI domdoc_createProcessingInstruction(
770 IXMLDOMDocument2 *iface,
773 IXMLDOMProcessingInstruction** pi )
775 #ifdef HAVE_XMLNEWDOCPI
777 domdoc *This = impl_from_IXMLDOMDocument2( iface );
778 xmlChar *xml_target, *xml_content;
780 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
782 xml_target = xmlChar_from_wchar((WCHAR*)target);
783 xml_content = xmlChar_from_wchar((WCHAR*)data);
785 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
786 TRACE("created xmlptr %p\n", xmlnode);
787 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
789 HeapFree(GetProcessHeap(), 0, xml_content);
790 HeapFree(GetProcessHeap(), 0, xml_target);
794 FIXME("Libxml 2.6.15 or greater required.\n");
800 static HRESULT WINAPI domdoc_createAttribute(
801 IXMLDOMDocument2 *iface,
803 IXMLDOMAttribute** attribute )
810 static HRESULT WINAPI domdoc_createEntityReference(
811 IXMLDOMDocument2 *iface,
813 IXMLDOMEntityReference** entityRef )
820 static HRESULT WINAPI domdoc_getElementsByTagName(
821 IXMLDOMDocument2 *iface,
823 IXMLDOMNodeList** resultList )
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
827 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
829 name = xmlChar_from_wchar((WCHAR*)tagName);
830 *resultList = create_filtered_nodelist((xmlNodePtr)get_doc(This), name, TRUE);
831 HeapFree(GetProcessHeap(), 0, name);
833 if(!*resultList) return S_FALSE;
837 static DOMNodeType get_node_type(VARIANT Type)
839 if(V_VT(&Type) == VT_I4)
842 FIXME("Unsupported variant type %x\n", V_VT(&Type));
846 static HRESULT WINAPI domdoc_createNode(
847 IXMLDOMDocument2 *iface,
853 domdoc *This = impl_from_IXMLDOMDocument2( iface );
854 DOMNodeType node_type;
855 xmlNodePtr xmlnode = NULL;
858 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
860 node_type = get_node_type(Type);
861 TRACE("node_type %d\n", node_type);
863 xml_name = xmlChar_from_wchar((WCHAR*)name);
868 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
869 *node = create_node(xmlnode);
870 TRACE("created %p\n", xmlnode);
874 FIXME("unhandled node type %d\n", node_type);
878 HeapFree(GetProcessHeap(), 0, xml_name);
886 static HRESULT WINAPI domdoc_nodeFromID(
887 IXMLDOMDocument2 *iface,
895 static xmlDocPtr doparse( char *ptr, int len )
897 #ifdef HAVE_XMLREADMEMORY
899 * use xmlReadMemory if possible so we can suppress
900 * writing errors to stderr
902 return xmlReadMemory( ptr, len, NULL, NULL,
903 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
905 return xmlParseMemory( ptr, len );
909 static xmlDocPtr doread( LPWSTR filename )
911 xmlDocPtr xmldoc = NULL;
914 IStream *stream, *memstream;
915 WCHAR url[INTERNET_MAX_URL_LENGTH];
919 TRACE("%s\n", debugstr_w( filename ));
921 if(!PathIsURLW(filename))
923 WCHAR fullpath[MAX_PATH];
924 DWORD needed = sizeof(url)/sizeof(WCHAR);
926 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
928 WARN("can't find path\n");
932 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
934 ERR("can't create url from path\n");
940 hr = CreateBindCtx(0, &pbc);
943 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
947 hr = CreateURLMoniker(NULL, filename, &moniker);
950 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
951 IMoniker_Release(moniker);
954 IBindCtx_Release(pbc);
959 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
962 IStream_Release(stream);
968 IStream_Read(stream, buf, sizeof(buf), &read);
969 hr = IStream_Write(memstream, buf, read, &written);
970 } while(SUCCEEDED(hr) && written != 0 && read != 0);
975 hr = GetHGlobalFromStream(memstream, &hglobal);
978 DWORD len = GlobalSize(hglobal);
979 char *ptr = GlobalLock(hglobal);
981 xmldoc = doparse( ptr, len );
982 GlobalUnlock(hglobal);
985 IStream_Release(memstream);
986 IStream_Release(stream);
990 static HRESULT WINAPI domdoc_load(
991 IXMLDOMDocument2 *iface,
993 VARIANT_BOOL* isSuccessful )
995 domdoc *This = impl_from_IXMLDOMDocument2( iface );
996 LPWSTR filename = NULL;
997 xmlDocPtr xmldoc = NULL;
998 HRESULT hr = S_FALSE;
1000 TRACE("type %d\n", V_VT(&xmlSource) );
1002 *isSuccessful = VARIANT_FALSE;
1004 assert( This->node );
1006 attach_xmlnode(This->node, NULL);
1008 switch( V_VT(&xmlSource) )
1011 filename = V_BSTR(&xmlSource);
1016 xmldoc = doread( filename );
1019 This->error = E_FAIL;
1022 hr = This->error = S_OK;
1023 *isSuccessful = VARIANT_TRUE;
1028 xmldoc = xmlNewDoc(NULL);
1030 xmldoc->_private = 0;
1031 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1037 static HRESULT WINAPI domdoc_get_readyState(
1038 IXMLDOMDocument2 *iface,
1046 static HRESULT WINAPI domdoc_get_parseError(
1047 IXMLDOMDocument2 *iface,
1048 IXMLDOMParseError** errorObj )
1050 BSTR error_string = NULL;
1051 static const WCHAR err[] = {'e','r','r','o','r',0};
1052 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1054 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1057 error_string = SysAllocString(err);
1059 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1060 if(!*errorObj) return E_OUTOFMEMORY;
1065 static HRESULT WINAPI domdoc_get_url(
1066 IXMLDOMDocument2 *iface,
1074 static HRESULT WINAPI domdoc_get_async(
1075 IXMLDOMDocument2 *iface,
1076 VARIANT_BOOL* isAsync )
1078 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1080 TRACE("%p <- %d\n", isAsync, This->async);
1081 *isAsync = This->async;
1086 static HRESULT WINAPI domdoc_put_async(
1087 IXMLDOMDocument2 *iface,
1088 VARIANT_BOOL isAsync )
1090 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1092 TRACE("%d\n", isAsync);
1093 This->async = isAsync;
1098 static HRESULT WINAPI domdoc_abort(
1099 IXMLDOMDocument2 *iface )
1106 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1108 UINT len, blen = SysStringLen( bstr );
1111 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1112 str = HeapAlloc( GetProcessHeap(), 0, len );
1115 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1121 static HRESULT WINAPI domdoc_loadXML(
1122 IXMLDOMDocument2 *iface,
1124 VARIANT_BOOL* isSuccessful )
1126 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1127 xmlDocPtr xmldoc = NULL;
1130 HRESULT hr = S_FALSE;
1132 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1134 assert ( This->node );
1136 attach_xmlnode( This->node, NULL );
1140 *isSuccessful = VARIANT_FALSE;
1142 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1144 xmldoc = doparse( str, len );
1145 HeapFree( GetProcessHeap(), 0, str );
1147 This->error = E_FAIL;
1150 hr = This->error = S_OK;
1151 *isSuccessful = VARIANT_TRUE;
1156 xmldoc = xmlNewDoc(NULL);
1158 xmldoc->_private = 0;
1159 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1165 static HRESULT WINAPI domdoc_save(
1166 IXMLDOMDocument2 *iface,
1167 VARIANT destination )
1169 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1176 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1177 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1179 if(V_VT(&destination) != VT_BSTR)
1181 FIXME("Unhandled vt %x\n", V_VT(&destination));
1185 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1186 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1187 if( handle == INVALID_HANDLE_VALUE )
1189 WARN("failed to create file\n");
1193 xmlDocDumpMemory(get_doc(This), &mem, &size);
1194 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1196 WARN("write error\n");
1201 CloseHandle(handle);
1205 static HRESULT WINAPI domdoc_get_validateOnParse(
1206 IXMLDOMDocument2 *iface,
1207 VARIANT_BOOL* isValidating )
1209 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1211 TRACE("%p <- %d\n", isValidating, This->validating);
1212 *isValidating = This->validating;
1217 static HRESULT WINAPI domdoc_put_validateOnParse(
1218 IXMLDOMDocument2 *iface,
1219 VARIANT_BOOL isValidating )
1221 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1223 TRACE("%d\n", isValidating);
1224 This->validating = isValidating;
1229 static HRESULT WINAPI domdoc_get_resolveExternals(
1230 IXMLDOMDocument2 *iface,
1231 VARIANT_BOOL* isResolving )
1233 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1235 TRACE("%p <- %d\n", isResolving, This->resolving);
1236 *isResolving = This->resolving;
1241 static HRESULT WINAPI domdoc_put_resolveExternals(
1242 IXMLDOMDocument2 *iface,
1243 VARIANT_BOOL isResolving )
1245 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1247 TRACE("%d\n", isResolving);
1248 This->resolving = isResolving;
1253 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1254 IXMLDOMDocument2 *iface,
1255 VARIANT_BOOL* isPreserving )
1257 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1259 TRACE("%p <- %d\n", isPreserving, This->preserving);
1260 *isPreserving = This->preserving;
1265 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1266 IXMLDOMDocument2 *iface,
1267 VARIANT_BOOL isPreserving )
1269 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1271 TRACE("%d\n", isPreserving);
1272 This->preserving = isPreserving;
1277 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1278 IXMLDOMDocument2 *iface,
1279 VARIANT readyStateChangeSink )
1286 static HRESULT WINAPI domdoc_put_onDataAvailable(
1287 IXMLDOMDocument2 *iface,
1288 VARIANT onDataAvailableSink )
1294 static HRESULT WINAPI domdoc_put_onTransformNode(
1295 IXMLDOMDocument2 *iface,
1296 VARIANT onTransformNodeSink )
1302 static HRESULT WINAPI domdoc_get_namespaces(
1303 IXMLDOMDocument2* iface,
1304 IXMLDOMSchemaCollection** schemaCollection )
1310 static HRESULT WINAPI domdoc_get_schemas(
1311 IXMLDOMDocument2* iface,
1314 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1315 HRESULT hr = S_FALSE;
1316 IXMLDOMSchemaCollection *cur_schema = This->schema;
1318 TRACE("(%p)->(%p)\n", This, var1);
1320 VariantInit(var1); /* Test shows we don't call VariantClear here */
1321 V_VT(var1) = VT_NULL;
1325 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1327 V_VT(var1) = VT_DISPATCH;
1332 static HRESULT WINAPI domdoc_putref_schemas(
1333 IXMLDOMDocument2* iface,
1336 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1337 HRESULT hr = E_FAIL;
1338 IXMLDOMSchemaCollection *new_schema = NULL;
1340 FIXME("(%p): semi-stub\n", This);
1344 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1348 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1357 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1362 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1363 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1369 static HRESULT WINAPI domdoc_validate(
1370 IXMLDOMDocument2* iface,
1371 IXMLDOMParseError** err)
1377 static HRESULT WINAPI domdoc_setProperty(
1378 IXMLDOMDocument2* iface,
1382 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1384 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1390 V_VT(&varStr) = VT_EMPTY;
1391 if (V_VT(&var) != VT_BSTR)
1393 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1395 bstr = V_BSTR(&varStr);
1398 bstr = V_BSTR(&var);
1401 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1402 This->bUseXPath = TRUE;
1403 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1404 This->bUseXPath = FALSE;
1408 VariantClear(&varStr);
1412 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1416 static HRESULT WINAPI domdoc_getProperty(
1417 IXMLDOMDocument2* iface,
1421 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1424 return E_INVALIDARG;
1425 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1427 V_VT(var) = VT_BSTR;
1428 if (This->bUseXPath)
1429 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1431 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1435 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1439 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1441 domdoc_QueryInterface,
1444 domdoc_GetTypeInfoCount,
1446 domdoc_GetIDsOfNames,
1448 domdoc_get_nodeName,
1449 domdoc_get_nodeValue,
1450 domdoc_put_nodeValue,
1451 domdoc_get_nodeType,
1452 domdoc_get_parentNode,
1453 domdoc_get_childNodes,
1454 domdoc_get_firstChild,
1455 domdoc_get_lastChild,
1456 domdoc_get_previousSibling,
1457 domdoc_get_nextSibling,
1458 domdoc_get_attributes,
1459 domdoc_insertBefore,
1460 domdoc_replaceChild,
1463 domdoc_hasChildNodes,
1464 domdoc_get_ownerDocument,
1466 domdoc_get_nodeTypeString,
1469 domdoc_get_specified,
1470 domdoc_get_definition,
1471 domdoc_get_nodeTypedValue,
1472 domdoc_put_nodeTypedValue,
1473 domdoc_get_dataType,
1474 domdoc_put_dataType,
1476 domdoc_transformNode,
1478 domdoc_selectSingleNode,
1480 domdoc_get_namespaceURI,
1482 domdoc_get_baseName,
1483 domdoc_transformNodeToObject,
1485 domdoc_get_implementation,
1486 domdoc_get_documentElement,
1487 domdoc_documentElement,
1488 domdoc_createElement,
1489 domdoc_createDocumentFragment,
1490 domdoc_createTextNode,
1491 domdoc_createComment,
1492 domdoc_createCDATASection,
1493 domdoc_createProcessingInstruction,
1494 domdoc_createAttribute,
1495 domdoc_createEntityReference,
1496 domdoc_getElementsByTagName,
1500 domdoc_get_readyState,
1501 domdoc_get_parseError,
1508 domdoc_get_validateOnParse,
1509 domdoc_put_validateOnParse,
1510 domdoc_get_resolveExternals,
1511 domdoc_put_resolveExternals,
1512 domdoc_get_preserveWhiteSpace,
1513 domdoc_put_preserveWhiteSpace,
1514 domdoc_put_onReadyStateChange,
1515 domdoc_put_onDataAvailable,
1516 domdoc_put_onTransformNode,
1517 domdoc_get_namespaces,
1519 domdoc_putref_schemas,
1525 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1531 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1533 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1535 return E_OUTOFMEMORY;
1537 doc->lpVtbl = &domdoc_vtbl;
1540 doc->validating = 0;
1542 doc->preserving = 0;
1543 doc->bUseXPath = FALSE;
1547 xmldoc = xmlNewDoc(NULL);
1550 HeapFree(GetProcessHeap(), 0, doc);
1551 return E_OUTOFMEMORY;
1554 xmldoc->_private = 0;
1556 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1560 HeapFree(GetProcessHeap(), 0, doc);
1564 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1567 IUnknown_Release(doc->node_unk);
1568 HeapFree( GetProcessHeap(), 0, doc );
1571 /* The ref on doc->node is actually looped back into this object, so release it */
1572 IXMLDOMNode_Release(doc->node);
1574 *ppObj = &doc->lpVtbl;
1576 TRACE("returning iface %p\n", *ppObj);
1582 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1584 MESSAGE("This program tried to use a DOMDocument object, but\n"
1585 "libxml2 support was not present at compile time.\n");