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 );
828 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
830 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
831 szPattern[0] = szPattern[1] = '/';
832 lstrcpyW(szPattern + 2, tagName);
834 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
835 HeapFree(GetProcessHeap(), 0, szPattern);
840 static DOMNodeType get_node_type(VARIANT Type)
842 if(V_VT(&Type) == VT_I4)
845 FIXME("Unsupported variant type %x\n", V_VT(&Type));
849 static HRESULT WINAPI domdoc_createNode(
850 IXMLDOMDocument2 *iface,
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 DOMNodeType node_type;
858 xmlNodePtr xmlnode = NULL;
861 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
863 node_type = get_node_type(Type);
864 TRACE("node_type %d\n", node_type);
866 xml_name = xmlChar_from_wchar((WCHAR*)name);
871 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
872 *node = create_node(xmlnode);
873 TRACE("created %p\n", xmlnode);
877 FIXME("unhandled node type %d\n", node_type);
881 HeapFree(GetProcessHeap(), 0, xml_name);
889 static HRESULT WINAPI domdoc_nodeFromID(
890 IXMLDOMDocument2 *iface,
898 static xmlDocPtr doparse( char *ptr, int len )
900 #ifdef HAVE_XMLREADMEMORY
902 * use xmlReadMemory if possible so we can suppress
903 * writing errors to stderr
905 return xmlReadMemory( ptr, len, NULL, NULL,
906 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
908 return xmlParseMemory( ptr, len );
912 static xmlDocPtr doread( LPWSTR filename )
914 xmlDocPtr xmldoc = NULL;
917 IStream *stream, *memstream;
918 WCHAR url[INTERNET_MAX_URL_LENGTH];
922 TRACE("%s\n", debugstr_w( filename ));
924 if(!PathIsURLW(filename))
926 WCHAR fullpath[MAX_PATH];
927 DWORD needed = sizeof(url)/sizeof(WCHAR);
929 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
931 WARN("can't find path\n");
935 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
937 ERR("can't create url from path\n");
943 hr = CreateBindCtx(0, &pbc);
946 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
950 hr = CreateURLMoniker(NULL, filename, &moniker);
953 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
954 IMoniker_Release(moniker);
957 IBindCtx_Release(pbc);
962 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
965 IStream_Release(stream);
971 IStream_Read(stream, buf, sizeof(buf), &read);
972 hr = IStream_Write(memstream, buf, read, &written);
973 } while(SUCCEEDED(hr) && written != 0 && read != 0);
978 hr = GetHGlobalFromStream(memstream, &hglobal);
981 DWORD len = GlobalSize(hglobal);
982 char *ptr = GlobalLock(hglobal);
984 xmldoc = doparse( ptr, len );
985 GlobalUnlock(hglobal);
988 IStream_Release(memstream);
989 IStream_Release(stream);
993 static HRESULT WINAPI domdoc_load(
994 IXMLDOMDocument2 *iface,
996 VARIANT_BOOL* isSuccessful )
998 domdoc *This = impl_from_IXMLDOMDocument2( iface );
999 LPWSTR filename = NULL;
1000 xmlDocPtr xmldoc = NULL;
1001 HRESULT hr = S_FALSE;
1003 TRACE("type %d\n", V_VT(&xmlSource) );
1005 *isSuccessful = VARIANT_FALSE;
1007 assert( This->node );
1009 attach_xmlnode(This->node, NULL);
1011 switch( V_VT(&xmlSource) )
1014 filename = V_BSTR(&xmlSource);
1019 xmldoc = doread( filename );
1022 This->error = E_FAIL;
1025 hr = This->error = S_OK;
1026 *isSuccessful = VARIANT_TRUE;
1031 xmldoc = xmlNewDoc(NULL);
1033 xmldoc->_private = 0;
1034 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1040 static HRESULT WINAPI domdoc_get_readyState(
1041 IXMLDOMDocument2 *iface,
1049 static HRESULT WINAPI domdoc_get_parseError(
1050 IXMLDOMDocument2 *iface,
1051 IXMLDOMParseError** errorObj )
1053 BSTR error_string = NULL;
1054 static const WCHAR err[] = {'e','r','r','o','r',0};
1055 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1057 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1060 error_string = SysAllocString(err);
1062 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1063 if(!*errorObj) return E_OUTOFMEMORY;
1068 static HRESULT WINAPI domdoc_get_url(
1069 IXMLDOMDocument2 *iface,
1077 static HRESULT WINAPI domdoc_get_async(
1078 IXMLDOMDocument2 *iface,
1079 VARIANT_BOOL* isAsync )
1081 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1083 TRACE("%p <- %d\n", isAsync, This->async);
1084 *isAsync = This->async;
1089 static HRESULT WINAPI domdoc_put_async(
1090 IXMLDOMDocument2 *iface,
1091 VARIANT_BOOL isAsync )
1093 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1095 TRACE("%d\n", isAsync);
1096 This->async = isAsync;
1101 static HRESULT WINAPI domdoc_abort(
1102 IXMLDOMDocument2 *iface )
1109 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1111 UINT len, blen = SysStringLen( bstr );
1114 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1115 str = HeapAlloc( GetProcessHeap(), 0, len );
1118 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1124 static HRESULT WINAPI domdoc_loadXML(
1125 IXMLDOMDocument2 *iface,
1127 VARIANT_BOOL* isSuccessful )
1129 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1130 xmlDocPtr xmldoc = NULL;
1133 HRESULT hr = S_FALSE;
1135 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1137 assert ( This->node );
1139 attach_xmlnode( This->node, NULL );
1143 *isSuccessful = VARIANT_FALSE;
1145 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1147 xmldoc = doparse( str, len );
1148 HeapFree( GetProcessHeap(), 0, str );
1150 This->error = E_FAIL;
1153 hr = This->error = S_OK;
1154 *isSuccessful = VARIANT_TRUE;
1159 xmldoc = xmlNewDoc(NULL);
1161 xmldoc->_private = 0;
1162 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1168 static HRESULT WINAPI domdoc_save(
1169 IXMLDOMDocument2 *iface,
1170 VARIANT destination )
1172 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1179 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1180 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1182 if(V_VT(&destination) != VT_BSTR)
1184 FIXME("Unhandled vt %x\n", V_VT(&destination));
1188 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1189 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1190 if( handle == INVALID_HANDLE_VALUE )
1192 WARN("failed to create file\n");
1196 xmlDocDumpMemory(get_doc(This), &mem, &size);
1197 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1199 WARN("write error\n");
1204 CloseHandle(handle);
1208 static HRESULT WINAPI domdoc_get_validateOnParse(
1209 IXMLDOMDocument2 *iface,
1210 VARIANT_BOOL* isValidating )
1212 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1214 TRACE("%p <- %d\n", isValidating, This->validating);
1215 *isValidating = This->validating;
1220 static HRESULT WINAPI domdoc_put_validateOnParse(
1221 IXMLDOMDocument2 *iface,
1222 VARIANT_BOOL isValidating )
1224 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1226 TRACE("%d\n", isValidating);
1227 This->validating = isValidating;
1232 static HRESULT WINAPI domdoc_get_resolveExternals(
1233 IXMLDOMDocument2 *iface,
1234 VARIANT_BOOL* isResolving )
1236 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1238 TRACE("%p <- %d\n", isResolving, This->resolving);
1239 *isResolving = This->resolving;
1244 static HRESULT WINAPI domdoc_put_resolveExternals(
1245 IXMLDOMDocument2 *iface,
1246 VARIANT_BOOL isResolving )
1248 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1250 TRACE("%d\n", isResolving);
1251 This->resolving = isResolving;
1256 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1257 IXMLDOMDocument2 *iface,
1258 VARIANT_BOOL* isPreserving )
1260 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1262 TRACE("%p <- %d\n", isPreserving, This->preserving);
1263 *isPreserving = This->preserving;
1268 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1269 IXMLDOMDocument2 *iface,
1270 VARIANT_BOOL isPreserving )
1272 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1274 TRACE("%d\n", isPreserving);
1275 This->preserving = isPreserving;
1280 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1281 IXMLDOMDocument2 *iface,
1282 VARIANT readyStateChangeSink )
1289 static HRESULT WINAPI domdoc_put_onDataAvailable(
1290 IXMLDOMDocument2 *iface,
1291 VARIANT onDataAvailableSink )
1297 static HRESULT WINAPI domdoc_put_onTransformNode(
1298 IXMLDOMDocument2 *iface,
1299 VARIANT onTransformNodeSink )
1305 static HRESULT WINAPI domdoc_get_namespaces(
1306 IXMLDOMDocument2* iface,
1307 IXMLDOMSchemaCollection** schemaCollection )
1313 static HRESULT WINAPI domdoc_get_schemas(
1314 IXMLDOMDocument2* iface,
1317 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1318 HRESULT hr = S_FALSE;
1319 IXMLDOMSchemaCollection *cur_schema = This->schema;
1321 TRACE("(%p)->(%p)\n", This, var1);
1323 VariantInit(var1); /* Test shows we don't call VariantClear here */
1324 V_VT(var1) = VT_NULL;
1328 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1330 V_VT(var1) = VT_DISPATCH;
1335 static HRESULT WINAPI domdoc_putref_schemas(
1336 IXMLDOMDocument2* iface,
1339 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1340 HRESULT hr = E_FAIL;
1341 IXMLDOMSchemaCollection *new_schema = NULL;
1343 FIXME("(%p): semi-stub\n", This);
1347 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1351 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1360 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1365 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1366 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1372 static HRESULT WINAPI domdoc_validate(
1373 IXMLDOMDocument2* iface,
1374 IXMLDOMParseError** err)
1380 static HRESULT WINAPI domdoc_setProperty(
1381 IXMLDOMDocument2* iface,
1385 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1387 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1393 V_VT(&varStr) = VT_EMPTY;
1394 if (V_VT(&var) != VT_BSTR)
1396 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1398 bstr = V_BSTR(&varStr);
1401 bstr = V_BSTR(&var);
1404 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1405 This->bUseXPath = TRUE;
1406 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1407 This->bUseXPath = FALSE;
1411 VariantClear(&varStr);
1415 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1419 static HRESULT WINAPI domdoc_getProperty(
1420 IXMLDOMDocument2* iface,
1424 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1427 return E_INVALIDARG;
1428 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1430 V_VT(var) = VT_BSTR;
1431 if (This->bUseXPath)
1432 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1434 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1438 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1442 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1444 domdoc_QueryInterface,
1447 domdoc_GetTypeInfoCount,
1449 domdoc_GetIDsOfNames,
1451 domdoc_get_nodeName,
1452 domdoc_get_nodeValue,
1453 domdoc_put_nodeValue,
1454 domdoc_get_nodeType,
1455 domdoc_get_parentNode,
1456 domdoc_get_childNodes,
1457 domdoc_get_firstChild,
1458 domdoc_get_lastChild,
1459 domdoc_get_previousSibling,
1460 domdoc_get_nextSibling,
1461 domdoc_get_attributes,
1462 domdoc_insertBefore,
1463 domdoc_replaceChild,
1466 domdoc_hasChildNodes,
1467 domdoc_get_ownerDocument,
1469 domdoc_get_nodeTypeString,
1472 domdoc_get_specified,
1473 domdoc_get_definition,
1474 domdoc_get_nodeTypedValue,
1475 domdoc_put_nodeTypedValue,
1476 domdoc_get_dataType,
1477 domdoc_put_dataType,
1479 domdoc_transformNode,
1481 domdoc_selectSingleNode,
1483 domdoc_get_namespaceURI,
1485 domdoc_get_baseName,
1486 domdoc_transformNodeToObject,
1488 domdoc_get_implementation,
1489 domdoc_get_documentElement,
1490 domdoc_documentElement,
1491 domdoc_createElement,
1492 domdoc_createDocumentFragment,
1493 domdoc_createTextNode,
1494 domdoc_createComment,
1495 domdoc_createCDATASection,
1496 domdoc_createProcessingInstruction,
1497 domdoc_createAttribute,
1498 domdoc_createEntityReference,
1499 domdoc_getElementsByTagName,
1503 domdoc_get_readyState,
1504 domdoc_get_parseError,
1511 domdoc_get_validateOnParse,
1512 domdoc_put_validateOnParse,
1513 domdoc_get_resolveExternals,
1514 domdoc_put_resolveExternals,
1515 domdoc_get_preserveWhiteSpace,
1516 domdoc_put_preserveWhiteSpace,
1517 domdoc_put_onReadyStateChange,
1518 domdoc_put_onDataAvailable,
1519 domdoc_put_onTransformNode,
1520 domdoc_get_namespaces,
1522 domdoc_putref_schemas,
1528 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1534 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1536 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1538 return E_OUTOFMEMORY;
1540 doc->lpVtbl = &domdoc_vtbl;
1543 doc->validating = 0;
1545 doc->preserving = 0;
1546 doc->bUseXPath = FALSE;
1550 xmldoc = xmlNewDoc(NULL);
1553 HeapFree(GetProcessHeap(), 0, doc);
1554 return E_OUTOFMEMORY;
1557 xmldoc->_private = 0;
1559 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1563 HeapFree(GetProcessHeap(), 0, doc);
1567 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1570 IUnknown_Release(doc->node_unk);
1571 HeapFree( GetProcessHeap(), 0, doc );
1574 /* The ref on doc->node is actually looped back into this object, so release it */
1575 IXMLDOMNode_Release(doc->node);
1577 *ppObj = &doc->lpVtbl;
1579 TRACE("returning iface %p\n", *ppObj);
1585 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1587 MESSAGE("This program tried to use a DOMDocument object, but\n"
1588 "libxml2 support was not present at compile time.\n");