ReactOS 0.4.15-dev-7654-g6bc40d3
domdoc.c
Go to the documentation of this file.
1/*
2 * DOM Document implementation
3 *
4 * Copyright 2005 Mike McCormack
5 * Copyright 2010-2011 Adam Martinson for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#define COBJMACROS
23
24#include "config.h"
25
26#include <stdarg.h>
27#include <assert.h>
28#ifdef HAVE_LIBXML2
29# include <libxml/parser.h>
30# include <libxml/xmlerror.h>
32# include <libxml/xmlsave.h>
33# include <libxml/SAX2.h>
35#endif
36
37#include "windef.h"
38#include "winbase.h"
39#include "winuser.h"
40#include "winnls.h"
41#include "ole2.h"
42#include "olectl.h"
43#include "msxml6.h"
44#include "wininet.h"
45#include "winreg.h"
46#include "shlwapi.h"
47#include "ocidl.h"
48#include "objsafe.h"
49
50#include "wine/debug.h"
51
52#include "msxml_private.h"
53
54#ifdef HAVE_LIBXML2
55
57
58/* not defined in older versions */
59#define XML_SAVE_FORMAT 1
60#define XML_SAVE_NO_DECL 2
61#define XML_SAVE_NO_EMPTY 4
62#define XML_SAVE_NO_XHTML 8
63#define XML_SAVE_XHTML 16
64#define XML_SAVE_AS_XML 32
65#define XML_SAVE_AS_HTML 64
66
67static const WCHAR PropertySelectionLanguageW[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
68static const WCHAR PropertySelectionNamespacesW[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
69static const WCHAR PropertyProhibitDTDW[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
70static const WCHAR PropertyNewParserW[] = {'N','e','w','P','a','r','s','e','r',0};
71static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
72static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
73static const WCHAR PropertyResolveExternalsW[] = {'R','e','s','o','l','v','e','E','x','t','e','r','n','a','l','s',0};
74static const WCHAR PropertyAllowXsltScriptW[] = {'A','l','l','o','w','X','s','l','t','S','c','r','i','p','t',0};
75static const WCHAR PropertyAllowDocumentFunctionW[] = {'A','l','l','o','w','D','o','c','u','m','e','n','t','F','u','n','c','t','i','o','n',0};
76static const WCHAR PropertyNormalizeAttributeValuesW[] = {'N','o','r','m','a','l','i','z','e','A','t','t','r','i','b','u','t','e','V','a','l','u','e','s',0};
77
78/* Anything that passes the test_get_ownerDocument()
79 * tests can go here (data shared between all instances).
80 * We need to preserve this when reloading a document,
81 * and also need access to it from the libxml backend. */
82typedef struct {
84 VARIANT_BOOL preserving;
85 IXMLDOMSchemaCollection2* schemaCache;
86 struct list selectNsList;
87 xmlChar const* selectNsStr;
88 LONG selectNsStr_len;
89 BOOL XPath;
90 IUri *uri;
91} domdoc_properties;
92
93typedef struct ConnectionPoint ConnectionPoint;
94typedef struct domdoc domdoc;
95
96struct ConnectionPoint
97{
99 const IID *iid;
100
103 domdoc *doc;
104
105 union
106 {
107 IUnknown *unk;
110 } *sinks;
112};
113
114typedef enum {
117 EVENTID_TRANSFORMNODE,
119} eventid_t;
120
121struct domdoc
122{
123 xmlnode node;
124 IXMLDOMDocument3 IXMLDOMDocument3_iface;
125 IPersistStreamInit IPersistStreamInit_iface;
126 IObjectWithSite IObjectWithSite_iface;
127 IObjectSafety IObjectSafety_iface;
128 IConnectionPointContainer IConnectionPointContainer_iface;
129 LONG ref;
130 VARIANT_BOOL async;
131 VARIANT_BOOL validating;
132 VARIANT_BOOL resolving;
133 domdoc_properties* properties;
135
136 /* IObjectWithSite */
137 IUnknown *site;
138
139 /* IObjectSafety */
140 DWORD safeopt;
141
142 /* connection list */
143 ConnectionPoint *cp_list;
144 ConnectionPoint cp_domdocevents;
145 ConnectionPoint cp_propnotif;
146 ConnectionPoint cp_dispatch;
147
148 /* events */
150
151 IXMLDOMSchemaCollection2 *namespaces;
152};
153
154static HRESULT set_doc_event(domdoc *doc, eventid_t eid, const VARIANT *v)
155{
156 IDispatch *disp;
157
158 switch (V_VT(v))
159 {
160 case VT_UNKNOWN:
161 if (V_UNKNOWN(v))
162 IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, (void**)&disp);
163 else
164 disp = NULL;
165 break;
166 case VT_DISPATCH:
167 disp = V_DISPATCH(v);
168 if (disp) IDispatch_AddRef(disp);
169 break;
170 default:
171 return DISP_E_TYPEMISMATCH;
172 }
173
174 if (doc->events[eid]) IDispatch_Release(doc->events[eid]);
175 doc->events[eid] = disp;
176
177 return S_OK;
178}
179
181{
182 return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
183}
184
185/*
186 In native windows, the whole lifetime management of XMLDOMNodes is
187 managed automatically using reference counts. Wine emulates that by
188 maintaining a reference count to the document that is increased for
189 each IXMLDOMNode pointer passed out for this document. If all these
190 pointers are gone, the document is unreachable and gets freed, that
191 is, all nodes in the tree of the document get freed.
192
193 You are able to create nodes that are associated to a document (in
194 fact, in msxml's XMLDOM model, all nodes are associated to a document),
195 but not in the tree of that document, for example using the createFoo
196 functions from IXMLDOMDocument. These nodes do not get cleaned up
197 by libxml, so we have to do it ourselves.
198
199 To catch these nodes, a list of "orphan nodes" is introduced.
200 It contains pointers to all roots of node trees that are
201 associated with the document without being part of the document
202 tree. All nodes with parent==NULL (except for the document root nodes)
203 should be in the orphan node list of their document. All orphan nodes
204 get freed together with the document itself.
205 */
206
207typedef struct _xmldoc_priv {
208 LONG refs;
209 struct list orphans;
210 domdoc_properties* properties;
211} xmldoc_priv;
212
213typedef struct _orphan_entry {
214 struct list entry;
215 xmlNode * node;
216} orphan_entry;
217
218typedef struct _select_ns_entry {
219 struct list entry;
220 xmlChar const* prefix;
221 xmlChar prefix_end;
222 xmlChar const* href;
223 xmlChar href_end;
224} select_ns_entry;
225
226static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc)
227{
228 return doc->_private;
229}
230
231static inline domdoc_properties * properties_from_xmlDocPtr(xmlDocPtr doc)
232{
233 return priv_from_xmlDocPtr(doc)->properties;
234}
235
236BOOL is_xpathmode(const xmlDocPtr doc)
237{
238 return properties_from_xmlDocPtr(doc)->XPath;
239}
240
241void set_xpathmode(xmlDocPtr doc, BOOL xpath)
242{
243 properties_from_xmlDocPtr(doc)->XPath = xpath;
244}
245
246int registerNamespaces(xmlXPathContextPtr ctxt)
247{
248 int n = 0;
249 const select_ns_entry* ns = NULL;
250 const struct list* pNsList = &properties_from_xmlDocPtr(ctxt->doc)->selectNsList;
251
252 TRACE("(%p)\n", ctxt);
253
254 LIST_FOR_EACH_ENTRY( ns, pNsList, select_ns_entry, entry )
255 {
256 xmlXPathRegisterNs(ctxt, ns->prefix, ns->href);
257 ++n;
258 }
259
260 return n;
261}
262
263static inline void clear_selectNsList(struct list* pNsList)
264{
265 select_ns_entry *ns, *ns2;
266 LIST_FOR_EACH_ENTRY_SAFE( ns, ns2, pNsList, select_ns_entry, entry )
267 {
268 heap_free( ns );
269 }
270 list_init(pNsList);
271}
272
273static xmldoc_priv * create_priv(void)
274{
275 xmldoc_priv *priv;
276 priv = heap_alloc( sizeof (*priv) );
277
278 if (priv)
279 {
280 priv->refs = 0;
281 list_init( &priv->orphans );
282 priv->properties = NULL;
283 }
284
285 return priv;
286}
287
288static domdoc_properties *create_properties(MSXML_VERSION version)
289{
290 domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties));
291
292 list_init(&properties->selectNsList);
293 properties->preserving = VARIANT_FALSE;
294 properties->schemaCache = NULL;
295 properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
296 properties->selectNsStr_len = 0;
297
298 /* properties that are dependent on object versions */
299 properties->version = version;
300 properties->XPath = (version == MSXML4 || version == MSXML6);
301
302 /* document uri */
303 properties->uri = NULL;
304
305 return properties;
306}
307
308static domdoc_properties* copy_properties(domdoc_properties const* properties)
309{
310 domdoc_properties* pcopy = heap_alloc(sizeof(domdoc_properties));
311 select_ns_entry const* ns = NULL;
312 select_ns_entry* new_ns = NULL;
313 int len = (properties->selectNsStr_len+1)*sizeof(xmlChar);
315
316 if (pcopy)
317 {
318 pcopy->version = properties->version;
319 pcopy->preserving = properties->preserving;
320 pcopy->schemaCache = properties->schemaCache;
321 if (pcopy->schemaCache)
322 IXMLDOMSchemaCollection2_AddRef(pcopy->schemaCache);
323 pcopy->XPath = properties->XPath;
324 pcopy->selectNsStr_len = properties->selectNsStr_len;
325 list_init( &pcopy->selectNsList );
326 pcopy->selectNsStr = heap_alloc(len);
327 memcpy((xmlChar*)pcopy->selectNsStr, properties->selectNsStr, len);
328 offset = pcopy->selectNsStr - properties->selectNsStr;
329
330 LIST_FOR_EACH_ENTRY( ns, (&properties->selectNsList), select_ns_entry, entry )
331 {
332 new_ns = heap_alloc(sizeof(select_ns_entry));
333 memcpy(new_ns, ns, sizeof(select_ns_entry));
334 new_ns->href += offset;
335 new_ns->prefix += offset;
336 list_add_tail(&pcopy->selectNsList, &new_ns->entry);
337 }
338
339 pcopy->uri = properties->uri;
340 if (pcopy->uri)
341 IUri_AddRef(pcopy->uri);
342 }
343
344 return pcopy;
345}
346
347static void free_properties(domdoc_properties* properties)
348{
349 if (properties)
350 {
351 if (properties->schemaCache)
352 IXMLDOMSchemaCollection2_Release(properties->schemaCache);
353 clear_selectNsList(&properties->selectNsList);
354 heap_free((xmlChar*)properties->selectNsStr);
355 if (properties->uri)
356 IUri_Release(properties->uri);
357 heap_free(properties);
358 }
359}
360
361static void release_namespaces(domdoc *This)
362{
363 if (This->namespaces)
364 {
365 IXMLDOMSchemaCollection2_Release(This->namespaces);
366 This->namespaces = NULL;
367 }
368}
369
370/* links a "<?xml" node as a first child */
371void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
372{
373 assert(doc != NULL);
374 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
375}
376
377/* unlinks a first "<?xml" child if it was created */
378xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
379{
380 static const xmlChar xmlA[] = "xml";
381 xmlNodePtr node, first_child;
382
383 assert(doc != NULL);
384
385 /* xml declaration node could be created automatically after parsing or added
386 to a tree later */
387 first_child = doc->children;
388 if (first_child && first_child->type == XML_PI_NODE && xmlStrEqual(first_child->name, xmlA))
389 {
390 node = first_child;
392 }
393 else
394 node = NULL;
395
396 return node;
397}
398
399MSXML_VERSION xmldoc_version(xmlDocPtr doc)
400{
401 return properties_from_xmlDocPtr(doc)->version;
402}
403
404BOOL is_preserving_whitespace(xmlNodePtr node)
405{
406 domdoc_properties* properties = NULL;
407 /* during parsing the xmlDoc._private stuff is not there */
408 if (priv_from_xmlDocPtr(node->doc))
409 properties = properties_from_xmlDocPtr(node->doc);
410 return ((properties && properties->preserving == VARIANT_TRUE) ||
412}
413
414static inline BOOL strn_isspace(xmlChar const* str, int len)
415{
416 for (; str && len > 0 && *str; ++str, --len)
417 if (!isspace(*str))
418 break;
419
420 return len == 0;
421}
422
423static void sax_characters(void *ctx, const xmlChar *ch, int len)
424{
425 xmlParserCtxtPtr ctxt;
426 const domdoc *This;
427
428 ctxt = (xmlParserCtxtPtr) ctx;
429 This = (const domdoc*) ctxt->_private;
430
431 if (ctxt->node)
432 {
433 xmlChar cur = *(ctxt->input->cur);
434
435 /* Characters are reported with multiple calls, for example each charref is reported with a separate
436 call and then parser appends it to a single text node or creates a new node if not created.
437 It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be
438 space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
439 or whole node if it has nothing but space chars, so to detect leading space node->last is checked that
440 contains text node pointer if already created, trailing spaces are detected directly looking at parser input
441 for next '<' opening bracket - similar logic is used by libxml2 itself. Basically 'cur' == '<' means the last
442 chunk of char data, in case it's not the last chunk we check for previously added node type and if it's not
443 a text node it's safe to ignore.
444
445 Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */
446
447 if (!This->properties->preserving &&
448 !is_preserving_whitespace(ctxt->node) &&
449 strn_isspace(ch, len) &&
450 (!ctxt->node->last ||
451 ((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
452 )))
453 {
454 /* Keep information about ignorable whitespace text node in previous or parent node */
455 if (ctxt->node->last)
456 *(DWORD*)&ctxt->node->last->_private |= NODE_PRIV_TRAILING_IGNORABLE_WS;
457 else if (ctxt->node->type != XML_DOCUMENT_NODE)
459 return;
460 }
461 }
462
463 xmlSAX2Characters(ctxt, ch, len);
464}
465
466static void LIBXML2_LOG_CALLBACK sax_error(void* ctx, char const* msg, ...)
467{
468 va_list ap;
469 va_start(ap, msg);
470 LIBXML2_CALLBACK_ERR(doparse, msg, ap);
471 va_end(ap);
472}
473
474static void LIBXML2_LOG_CALLBACK sax_warning(void* ctx, char const* msg, ...)
475{
476 va_list ap;
477 va_start(ap, msg);
478 LIBXML2_CALLBACK_WARN(doparse, msg, ap);
479 va_end(ap);
480}
481
482static void sax_serror(void* ctx, xmlErrorPtr err)
483{
484 LIBXML2_CALLBACK_SERROR(doparse, err);
485}
486
487static xmlDocPtr doparse(domdoc* This, char const* ptr, int len, xmlCharEncoding encoding)
488{
489 xmlDocPtr doc = NULL;
490 xmlParserCtxtPtr pctx;
491 static xmlSAXHandler sax_handler = {
492 xmlSAX2InternalSubset, /* internalSubset */
493 xmlSAX2IsStandalone, /* isStandalone */
494 xmlSAX2HasInternalSubset, /* hasInternalSubset */
495 xmlSAX2HasExternalSubset, /* hasExternalSubset */
496 xmlSAX2ResolveEntity, /* resolveEntity */
497 xmlSAX2GetEntity, /* getEntity */
498 xmlSAX2EntityDecl, /* entityDecl */
499 xmlSAX2NotationDecl, /* notationDecl */
500 xmlSAX2AttributeDecl, /* attributeDecl */
501 xmlSAX2ElementDecl, /* elementDecl */
502 xmlSAX2UnparsedEntityDecl, /* unparsedEntityDecl */
503 xmlSAX2SetDocumentLocator, /* setDocumentLocator */
504 xmlSAX2StartDocument, /* startDocument */
505 xmlSAX2EndDocument, /* endDocument */
506 xmlSAX2StartElement, /* startElement */
507 xmlSAX2EndElement, /* endElement */
508 xmlSAX2Reference, /* reference */
509 sax_characters, /* characters */
510 sax_characters, /* ignorableWhitespace */
511 xmlSAX2ProcessingInstruction, /* processingInstruction */
512 xmlSAX2Comment, /* comment */
513 sax_warning, /* warning */
514 sax_error, /* error */
515 sax_error, /* fatalError */
516 xmlSAX2GetParameterEntity, /* getParameterEntity */
517 xmlSAX2CDataBlock, /* cdataBlock */
518 xmlSAX2ExternalSubset, /* externalSubset */
519 0, /* initialized */
520 NULL, /* _private */
521 xmlSAX2StartElementNs, /* startElementNs */
522 xmlSAX2EndElementNs, /* endElementNs */
523 sax_serror /* serror */
524 };
525
527 if (!pctx)
528 {
529 ERR("Failed to create parser context\n");
530 return NULL;
531 }
532
533 if (pctx->sax) xmlFree(pctx->sax);
534 pctx->sax = &sax_handler;
535 pctx->_private = This;
536 pctx->recovery = 0;
537
540
541 xmlParseDocument(pctx);
542
543 if (pctx->wellFormed)
544 {
545 doc = pctx->myDoc;
546 }
547 else
548 {
549 xmlFreeDoc(pctx->myDoc);
550 pctx->myDoc = NULL;
551 }
552 pctx->sax = NULL;
553 xmlFreeParserCtxt(pctx);
554
555 /* TODO: put this in one of the SAX callbacks */
556 /* create first child as a <?xml...?> */
557 if (doc && doc->standalone != -1)
558 {
560 char buff[30];
561 xmlChar *xmlbuff = (xmlChar*)buff;
562
563 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
564
565 /* version attribute can't be omitted */
566 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
567 xmlNodeAddContent( node, xmlbuff );
568
569 if (doc->encoding)
570 {
571 sprintf(buff, " encoding=\"%s\"", doc->encoding);
572 xmlNodeAddContent( node, xmlbuff );
573 }
574
575 if (doc->standalone != -2)
576 {
577 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
578 xmlNodeAddContent( node, xmlbuff );
579 }
580
581 xmldoc_link_xmldecl( doc, node );
582 }
583
584 return doc;
585}
586
587void xmldoc_init(xmlDocPtr doc, MSXML_VERSION version)
588{
589 doc->_private = create_priv();
590 priv_from_xmlDocPtr(doc)->properties = create_properties(version);
591}
592
593LONG xmldoc_add_refs(xmlDocPtr doc, LONG refs)
594{
595 LONG ref = InterlockedExchangeAdd(&priv_from_xmlDocPtr(doc)->refs, refs) + refs;
596 TRACE("(%p)->(%d)\n", doc, ref);
597 return ref;
598}
599
600LONG xmldoc_add_ref(xmlDocPtr doc)
601{
602 return xmldoc_add_refs(doc, 1);
603}
604
605LONG xmldoc_release_refs(xmlDocPtr doc, LONG refs)
606{
607 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
608 LONG ref = InterlockedExchangeAdd(&priv->refs, -refs) - refs;
609 TRACE("(%p)->(%d)\n", doc, ref);
610
611 if (ref < 0)
612 WARN("negative refcount, expect troubles\n");
613
614 if (ref == 0)
615 {
616 orphan_entry *orphan, *orphan2;
617 TRACE("freeing docptr %p\n", doc);
618
619 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
620 {
621 xmlFreeNode( orphan->node );
622 heap_free( orphan );
623 }
624 free_properties(priv->properties);
625 heap_free(doc->_private);
626
627 xmlFreeDoc(doc);
628 }
629
630 return ref;
631}
632
633LONG xmldoc_release(xmlDocPtr doc)
634{
635 return xmldoc_release_refs(doc, 1);
636}
637
638HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
639{
640 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
641 orphan_entry *entry;
642
643 entry = heap_alloc( sizeof (*entry) );
644 if(!entry)
645 return E_OUTOFMEMORY;
646
647 entry->node = node;
648 list_add_head( &priv->orphans, &entry->entry );
649 return S_OK;
650}
651
652HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
653{
654 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
655 orphan_entry *entry, *entry2;
656
657 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
658 {
659 if( entry->node == node )
660 {
661 list_remove( &entry->entry );
662 heap_free( entry );
663 return S_OK;
664 }
665 }
666
667 return S_FALSE;
668}
669
670static inline xmlDocPtr get_doc( domdoc *This )
671{
672 return This->node.node->doc;
673}
674
675static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml )
676{
677 release_namespaces(This);
678
679 if(This->node.node)
680 {
681 priv_from_xmlDocPtr(get_doc(This))->properties = NULL;
682 if (xmldoc_release(get_doc(This)) != 0)
683 priv_from_xmlDocPtr(get_doc(This))->properties =
684 copy_properties(This->properties);
685 }
686
687 This->node.node = (xmlNodePtr) xml;
688
689 if(This->node.node)
690 {
691 xmldoc_add_ref(get_doc(This));
692 priv_from_xmlDocPtr(get_doc(This))->properties = This->properties;
693 }
694
695 return S_OK;
696}
697
698static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
699{
700 return CONTAINING_RECORD(iface, domdoc, IXMLDOMDocument3_iface);
701}
702
703static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
704{
705 return CONTAINING_RECORD(iface, domdoc, IPersistStreamInit_iface);
706}
707
708static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
709{
710 return CONTAINING_RECORD(iface, domdoc, IObjectWithSite_iface);
711}
712
713static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
714{
715 return CONTAINING_RECORD(iface, domdoc, IObjectSafety_iface);
716}
717
719{
720 return CONTAINING_RECORD(iface, domdoc, IConnectionPointContainer_iface);
721}
722
723/************************************************************************
724 * domdoc implementation of IPersistStream.
725 */
727 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
728{
729 domdoc* This = impl_from_IPersistStreamInit(iface);
730 return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppvObj);
731}
732
734 IPersistStreamInit *iface)
735{
736 domdoc* This = impl_from_IPersistStreamInit(iface);
737 return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
738}
739
741 IPersistStreamInit *iface)
742{
743 domdoc* This = impl_from_IPersistStreamInit(iface);
744 return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
745}
746
748 IPersistStreamInit *iface, CLSID *classid)
749{
750 domdoc* This = impl_from_IPersistStreamInit(iface);
751 TRACE("(%p)->(%p)\n", This, classid);
752
753 if(!classid)
754 return E_POINTER;
755
756 *classid = *DOMDocument_version(This->properties->version);
757
758 return S_OK;
759}
760
762 IPersistStreamInit *iface)
763{
764 domdoc *This = impl_from_IPersistStreamInit(iface);
765 FIXME("(%p): stub!\n", This);
766 return S_FALSE;
767}
768
769static HRESULT domdoc_load_from_stream(domdoc *doc, ISequentialStream *stream)
770{
771 DWORD read, written, len;
772 xmlDocPtr xmldoc = NULL;
773 IStream *hstream;
774 HGLOBAL hglobal;
775 BYTE buf[4096];
776 HRESULT hr;
777 char *ptr;
778
779 hstream = NULL;
780 hr = CreateStreamOnHGlobal(NULL, TRUE, &hstream);
781 if (FAILED(hr))
782 return hr;
783
784 do
785 {
786 ISequentialStream_Read(stream, buf, sizeof(buf), &read);
787 hr = IStream_Write(hstream, buf, read, &written);
788 } while(SUCCEEDED(hr) && written != 0 && read != 0);
789
790 if (FAILED(hr))
791 {
792 ERR("failed to copy stream 0x%08x\n", hr);
793 IStream_Release(hstream);
794 return hr;
795 }
796
797 hr = GetHGlobalFromStream(hstream, &hglobal);
798 if (FAILED(hr))
799 return hr;
800
801 len = GlobalSize(hglobal);
802 ptr = GlobalLock(hglobal);
803 if (len)
804 xmldoc = doparse(doc, ptr, len, XML_CHAR_ENCODING_NONE);
805 GlobalUnlock(hglobal);
806
807 if (!xmldoc)
808 {
809 ERR("Failed to parse xml\n");
810 return E_FAIL;
811 }
812
813 xmldoc->_private = create_priv();
814
815 return attach_xmldoc(doc, xmldoc);
816}
817
819{
820 domdoc *This = impl_from_IPersistStreamInit(iface);
821
822 TRACE("(%p)->(%p)\n", This, stream);
823
824 if (!stream)
825 return E_INVALIDARG;
826
827 return domdoc_load_from_stream(This, (ISequentialStream*)stream);
828}
829
831 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
832{
833 domdoc *This = impl_from_IPersistStreamInit(iface);
834 BSTR xmlString;
835 HRESULT hr;
836
837 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
838
839 hr = IXMLDOMDocument3_get_xml(&This->IXMLDOMDocument3_iface, &xmlString);
840 if(hr == S_OK)
841 {
842 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
843
844 hr = IStream_Write( stream, xmlString, len, NULL );
845 SysFreeString(xmlString);
846 }
847
848 TRACE("ret 0x%08x\n", hr);
849
850 return hr;
851}
852
854 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
855{
856 domdoc *This = impl_from_IPersistStreamInit(iface);
857 TRACE("(%p)->(%p)\n", This, pcbSize);
858 return E_NOTIMPL;
859}
860
862 IPersistStreamInit *iface)
863{
864 domdoc *This = impl_from_IPersistStreamInit(iface);
865 TRACE("(%p)\n", This);
866 return S_OK;
867}
868
869static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
870{
880};
881
882/* IXMLDOMDocument3 interface */
883
884static const tid_t domdoc_se_tids[] = {
890};
891
892static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
893{
894 domdoc *This = impl_from_IXMLDOMDocument3( iface );
895
896 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
897
898 *ppvObject = NULL;
899
900 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
902 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
903 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
904 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
905 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
906 {
907 *ppvObject = iface;
908 }
909 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
911 {
912 *ppvObject = &This->IPersistStreamInit_iface;
913 }
915 {
916 *ppvObject = &This->IObjectWithSite_iface;
917 }
918 else if (IsEqualGUID(&IID_IObjectSafety, riid))
919 {
920 *ppvObject = &This->IObjectSafety_iface;
921 }
922 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
923 {
924 return node_create_supporterrorinfo(domdoc_se_tids, ppvObject);
925 }
926 else if(node_query_interface(&This->node, riid, ppvObject))
927 {
928 return *ppvObject ? S_OK : E_NOINTERFACE;
929 }
931 {
932 *ppvObject = &This->IConnectionPointContainer_iface;
933 }
934 else
935 {
936 TRACE("interface %s not implemented\n", debugstr_guid(riid));
937 return E_NOINTERFACE;
938 }
939
940 IUnknown_AddRef((IUnknown*)*ppvObject);
941
942 return S_OK;
943}
944
945static ULONG WINAPI domdoc_AddRef( IXMLDOMDocument3 *iface )
946{
947 domdoc *This = impl_from_IXMLDOMDocument3( iface );
949 TRACE("(%p)->(%d)\n", This, ref );
950 return ref;
951}
952
953static ULONG WINAPI domdoc_Release( IXMLDOMDocument3 *iface )
954{
955 domdoc *This = impl_from_IXMLDOMDocument3( iface );
957
958 TRACE("(%p)->(%d)\n", This, ref );
959
960 if ( ref == 0 )
961 {
962 int eid;
963
964 if (This->site)
965 IUnknown_Release( This->site );
966 destroy_xmlnode(&This->node);
967
968 for (eid = 0; eid < EVENTID_LAST; eid++)
969 if (This->events[eid]) IDispatch_Release(This->events[eid]);
970
971 release_namespaces(This);
973 }
974
975 return ref;
976}
977
978static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
979{
980 domdoc *This = impl_from_IXMLDOMDocument3( iface );
981 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
982}
983
984static HRESULT WINAPI domdoc_GetTypeInfo(
985 IXMLDOMDocument3 *iface,
986 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
987{
988 domdoc *This = impl_from_IXMLDOMDocument3( iface );
989 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
990}
991
992static HRESULT WINAPI domdoc_GetIDsOfNames(
993 IXMLDOMDocument3 *iface,
994 REFIID riid,
995 LPOLESTR* rgszNames,
996 UINT cNames,
997 LCID lcid,
998 DISPID* rgDispId)
999{
1000 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1001 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface,
1002 riid, rgszNames, cNames, lcid, rgDispId);
1003}
1004
1005static HRESULT WINAPI domdoc_Invoke(
1006 IXMLDOMDocument3 *iface,
1007 DISPID dispIdMember,
1008 REFIID riid,
1009 LCID lcid,
1010 WORD wFlags,
1011 DISPPARAMS* pDispParams,
1012 VARIANT* pVarResult,
1013 EXCEPINFO* pExcepInfo,
1014 UINT* puArgErr)
1015{
1016 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1017 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface,
1018 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1019}
1020
1021static HRESULT WINAPI domdoc_get_nodeName(
1022 IXMLDOMDocument3 *iface,
1023 BSTR* name )
1024{
1025 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1026
1027 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
1028
1029 TRACE("(%p)->(%p)\n", This, name);
1030
1031 return return_bstr(documentW, name);
1032}
1033
1034
1035static HRESULT WINAPI domdoc_get_nodeValue(
1036 IXMLDOMDocument3 *iface,
1037 VARIANT* value )
1038{
1039 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1040
1041 TRACE("(%p)->(%p)\n", This, value);
1042
1043 if(!value)
1044 return E_INVALIDARG;
1045
1046 V_VT(value) = VT_NULL;
1047 V_BSTR(value) = NULL; /* tests show that we should do this */
1048 return S_FALSE;
1049}
1050
1051
1052static HRESULT WINAPI domdoc_put_nodeValue(
1053 IXMLDOMDocument3 *iface,
1054 VARIANT value)
1055{
1056 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1057 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
1058 return E_FAIL;
1059}
1060
1061
1062static HRESULT WINAPI domdoc_get_nodeType(
1063 IXMLDOMDocument3 *iface,
1064 DOMNodeType* type )
1065{
1066 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1067
1068 TRACE("(%p)->(%p)\n", This, type);
1069
1071 return S_OK;
1072}
1073
1074
1075static HRESULT WINAPI domdoc_get_parentNode(
1076 IXMLDOMDocument3 *iface,
1078{
1079 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1080
1081 TRACE("(%p)->(%p)\n", This, parent);
1082
1083 return node_get_parent(&This->node, parent);
1084}
1085
1086
1087static HRESULT WINAPI domdoc_get_childNodes(
1088 IXMLDOMDocument3 *iface,
1089 IXMLDOMNodeList** childList )
1090{
1091 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1092
1093 TRACE("(%p)->(%p)\n", This, childList);
1094
1095 return node_get_child_nodes(&This->node, childList);
1096}
1097
1098
1099static HRESULT WINAPI domdoc_get_firstChild(
1100 IXMLDOMDocument3 *iface,
1101 IXMLDOMNode** firstChild )
1102{
1103 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1104
1105 TRACE("(%p)->(%p)\n", This, firstChild);
1106
1107 return node_get_first_child(&This->node, firstChild);
1108}
1109
1110
1111static HRESULT WINAPI domdoc_get_lastChild(
1112 IXMLDOMDocument3 *iface,
1113 IXMLDOMNode** lastChild )
1114{
1115 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1116
1117 TRACE("(%p)->(%p)\n", This, lastChild);
1118
1119 return node_get_last_child(&This->node, lastChild);
1120}
1121
1122
1123static HRESULT WINAPI domdoc_get_previousSibling(
1124 IXMLDOMDocument3 *iface,
1125 IXMLDOMNode** previousSibling )
1126{
1127 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1128
1129 TRACE("(%p)->(%p)\n", This, previousSibling);
1130
1131 return return_null_node(previousSibling);
1132}
1133
1134
1135static HRESULT WINAPI domdoc_get_nextSibling(
1136 IXMLDOMDocument3 *iface,
1137 IXMLDOMNode** nextSibling )
1138{
1139 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1140
1141 TRACE("(%p)->(%p)\n", This, nextSibling);
1142
1143 return return_null_node(nextSibling);
1144}
1145
1146
1147static HRESULT WINAPI domdoc_get_attributes(
1148 IXMLDOMDocument3 *iface,
1149 IXMLDOMNamedNodeMap** attributeMap )
1150{
1151 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1152
1153 TRACE("(%p)->(%p)\n", This, attributeMap);
1154
1155 return return_null_ptr((void**)attributeMap);
1156}
1157
1158
1159static HRESULT WINAPI domdoc_insertBefore(
1160 IXMLDOMDocument3 *iface,
1161 IXMLDOMNode* newChild,
1162 VARIANT refChild,
1163 IXMLDOMNode** outNewChild )
1164{
1165 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1167 HRESULT hr;
1168
1169 TRACE("(%p)->(%p %s %p)\n", This, newChild, debugstr_variant(&refChild), outNewChild);
1170
1171 hr = IXMLDOMNode_get_nodeType(newChild, &type);
1172 if (hr != S_OK) return hr;
1173
1174 TRACE("new node type %d\n", type);
1175 switch (type)
1176 {
1177 case NODE_ATTRIBUTE:
1178 case NODE_DOCUMENT:
1179 case NODE_CDATA_SECTION:
1180 if (outNewChild) *outNewChild = NULL;
1181 return E_FAIL;
1182 default:
1183 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
1184 }
1185}
1186
1187static HRESULT WINAPI domdoc_replaceChild(
1188 IXMLDOMDocument3 *iface,
1189 IXMLDOMNode* newChild,
1190 IXMLDOMNode* oldChild,
1191 IXMLDOMNode** outOldChild)
1192{
1193 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1194
1195 TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, outOldChild);
1196
1197 return node_replace_child(&This->node, newChild, oldChild, outOldChild);
1198}
1199
1200
1201static HRESULT WINAPI domdoc_removeChild(
1202 IXMLDOMDocument3 *iface,
1204 IXMLDOMNode **oldChild)
1205{
1206 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1207 TRACE("(%p)->(%p %p)\n", This, child, oldChild);
1208 return node_remove_child(&This->node, child, oldChild);
1209}
1210
1211
1212static HRESULT WINAPI domdoc_appendChild(
1213 IXMLDOMDocument3 *iface,
1215 IXMLDOMNode **outChild)
1216{
1217 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1218 TRACE("(%p)->(%p %p)\n", This, child, outChild);
1219 return node_append_child(&This->node, child, outChild);
1220}
1221
1222
1223static HRESULT WINAPI domdoc_hasChildNodes(
1224 IXMLDOMDocument3 *iface,
1226{
1227 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1228 TRACE("(%p)->(%p)\n", This, ret);
1229 return node_has_childnodes(&This->node, ret);
1230}
1231
1232
1233static HRESULT WINAPI domdoc_get_ownerDocument(
1234 IXMLDOMDocument3 *iface,
1235 IXMLDOMDocument **doc)
1236{
1237 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1238 TRACE("(%p)->(%p)\n", This, doc);
1239 return node_get_owner_doc(&This->node, doc);
1240}
1241
1242
1243static HRESULT WINAPI domdoc_cloneNode(
1244 IXMLDOMDocument3 *iface,
1245 VARIANT_BOOL deep,
1246 IXMLDOMNode** outNode)
1247{
1248 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1249 xmlNodePtr clone;
1250
1251 TRACE("(%p)->(%d %p)\n", This, deep, outNode);
1252
1253 if (!outNode)
1254 return E_INVALIDARG;
1255
1256 *outNode = NULL;
1257
1258 clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2);
1259 if (!clone)
1260 return E_FAIL;
1261
1262 clone->doc->_private = create_priv();
1263 xmldoc_add_orphan(clone->doc, clone);
1264 xmldoc_add_ref(clone->doc);
1265
1266 priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties);
1267 if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone)))
1268 {
1269 xmldoc_release(clone->doc);
1270 return E_FAIL;
1271 }
1272
1273 return S_OK;
1274}
1275
1276
1277static HRESULT WINAPI domdoc_get_nodeTypeString(
1278 IXMLDOMDocument3 *iface,
1279 BSTR *p)
1280{
1281 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1282 static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
1283
1284 TRACE("(%p)->(%p)\n", This, p);
1285
1286 return return_bstr(documentW, p);
1287}
1288
1289
1290static HRESULT WINAPI domdoc_get_text(
1291 IXMLDOMDocument3 *iface,
1292 BSTR *p)
1293{
1294 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1295 TRACE("(%p)->(%p)\n", This, p);
1296 return node_get_text(&This->node, p);
1297}
1298
1299
1300static HRESULT WINAPI domdoc_put_text(
1301 IXMLDOMDocument3 *iface,
1302 BSTR text )
1303{
1304 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1305 TRACE("(%p)->(%s)\n", This, debugstr_w(text));
1306 return E_FAIL;
1307}
1308
1309
1310static HRESULT WINAPI domdoc_get_specified(
1311 IXMLDOMDocument3 *iface,
1312 VARIANT_BOOL* isSpecified )
1313{
1314 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1315 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
1316 *isSpecified = VARIANT_TRUE;
1317 return S_OK;
1318}
1319
1320
1321static HRESULT WINAPI domdoc_get_definition(
1322 IXMLDOMDocument3 *iface,
1323 IXMLDOMNode** definitionNode )
1324{
1325 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1326 FIXME("(%p)->(%p)\n", This, definitionNode);
1327 return E_NOTIMPL;
1328}
1329
1330
1331static HRESULT WINAPI domdoc_get_nodeTypedValue(
1332 IXMLDOMDocument3 *iface,
1333 VARIANT* v )
1334{
1335 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1336 TRACE("(%p)->(%p)\n", This, v);
1337 return return_null_var(v);
1338}
1339
1340static HRESULT WINAPI domdoc_put_nodeTypedValue(
1341 IXMLDOMDocument3 *iface,
1342 VARIANT typedValue )
1343{
1344 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1345 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
1346 return E_NOTIMPL;
1347}
1348
1349
1350static HRESULT WINAPI domdoc_get_dataType(
1351 IXMLDOMDocument3 *iface,
1352 VARIANT* typename )
1353{
1354 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1355 TRACE("(%p)->(%p)\n", This, typename);
1356 return return_null_var( typename );
1357}
1358
1359
1360static HRESULT WINAPI domdoc_put_dataType(
1361 IXMLDOMDocument3 *iface,
1362 BSTR dataTypeName )
1363{
1364 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1365
1366 FIXME("(%p)->(%s)\n", This, debugstr_w(dataTypeName));
1367
1368 if(!dataTypeName)
1369 return E_INVALIDARG;
1370
1371 return E_FAIL;
1372}
1373
1374static int XMLCALL domdoc_get_xml_writecallback(void *ctx, const char *data, int len)
1375{
1376 return xmlBufferAdd((xmlBufferPtr)ctx, (xmlChar*)data, len) == 0 ? len : 0;
1377}
1378
1379static HRESULT WINAPI domdoc_get_xml(
1380 IXMLDOMDocument3 *iface,
1381 BSTR* p)
1382{
1383 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1384 xmlSaveCtxtPtr ctxt;
1386 int options;
1387 long ret;
1388
1389 TRACE("(%p)->(%p)\n", This, p);
1390
1391 if(!p)
1392 return E_INVALIDARG;
1393
1394 *p = NULL;
1395
1396 buf = xmlBufferCreate();
1397 if(!buf)
1398 return E_OUTOFMEMORY;
1399
1400 options = XML_SAVE_FORMAT | XML_SAVE_NO_DECL;
1401 ctxt = xmlSaveToIO(domdoc_get_xml_writecallback, NULL, buf, "UTF-8", options);
1402
1403 if(!ctxt)
1404 {
1406 return E_OUTOFMEMORY;
1407 }
1408
1409 ret = xmlSaveDoc(ctxt, get_doc(This));
1410 /* flushes on close */
1411 xmlSaveClose(ctxt);
1412
1413 TRACE("%ld, len=%d\n", ret, xmlBufferLength(buf));
1414 if(ret != -1 && xmlBufferLength(buf) > 0)
1415 {
1416 BSTR content;
1417
1418 content = bstr_from_xmlChar(xmlBufferContent(buf));
1419 content = EnsureCorrectEOL(content);
1420
1421 *p = content;
1422 }
1423 else
1424 {
1425 *p = SysAllocStringLen(NULL, 0);
1426 }
1427
1429
1430 return *p ? S_OK : E_OUTOFMEMORY;
1431}
1432
1433
1434static HRESULT WINAPI domdoc_transformNode(
1435 IXMLDOMDocument3 *iface,
1437 BSTR *p)
1438{
1439 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1440 TRACE("(%p)->(%p %p)\n", This, node, p);
1441 return node_transform_node(&This->node, node, p);
1442}
1443
1444
1445static HRESULT WINAPI domdoc_selectNodes(
1446 IXMLDOMDocument3 *iface,
1447 BSTR p,
1448 IXMLDOMNodeList **outList)
1449{
1450 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1451 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
1452 return node_select_nodes(&This->node, p, outList);
1453}
1454
1455
1456static HRESULT WINAPI domdoc_selectSingleNode(
1457 IXMLDOMDocument3 *iface,
1458 BSTR p,
1459 IXMLDOMNode **outNode)
1460{
1461 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1462 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
1463 return node_select_singlenode(&This->node, p, outNode);
1464}
1465
1466
1467static HRESULT WINAPI domdoc_get_parsed(
1468 IXMLDOMDocument3 *iface,
1469 VARIANT_BOOL* isParsed )
1470{
1471 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1472 FIXME("(%p)->(%p) stub!\n", This, isParsed);
1473 *isParsed = VARIANT_TRUE;
1474 return S_OK;
1475}
1476
1477static HRESULT WINAPI domdoc_get_namespaceURI(
1478 IXMLDOMDocument3 *iface,
1479 BSTR* namespaceURI )
1480{
1481 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1482 TRACE("(%p)->(%p)\n", This, namespaceURI);
1483 return return_null_bstr( namespaceURI );
1484}
1485
1486static HRESULT WINAPI domdoc_get_prefix(
1487 IXMLDOMDocument3 *iface,
1488 BSTR* prefix )
1489{
1490 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1491 TRACE("(%p)->(%p)\n", This, prefix);
1492 return return_null_bstr( prefix );
1493}
1494
1495
1496static HRESULT WINAPI domdoc_get_baseName(
1497 IXMLDOMDocument3 *iface,
1498 BSTR* name )
1499{
1500 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1501 TRACE("(%p)->(%p)\n", This, name);
1502 return return_null_bstr( name );
1503}
1504
1505
1506static HRESULT WINAPI domdoc_transformNodeToObject(
1507 IXMLDOMDocument3 *iface,
1508 IXMLDOMNode* stylesheet,
1509 VARIANT output)
1510{
1511 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1512
1513 TRACE("(%p)->(%p %s)\n", This, stylesheet, debugstr_variant(&output));
1514
1515 switch (V_VT(&output))
1516 {
1517 case VT_UNKNOWN:
1518 case VT_DISPATCH:
1519 {
1520 IXMLDOMDocument *doc;
1521 HRESULT hr;
1522
1523 if (!V_UNKNOWN(&output))
1524 return E_INVALIDARG;
1525
1526 /* FIXME: we're not supposed to query for document interface, should use IStream
1527 which we don't support currently. */
1528 if (IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IXMLDOMDocument, (void **)&doc) == S_OK)
1529 {
1531 BSTR str;
1532
1533 if (FAILED(hr = node_transform_node(&This->node, stylesheet, &str)))
1534 return hr;
1535
1536 hr = IXMLDOMDocument_loadXML(doc, str, &b);
1538 return hr;
1539 }
1540 else
1541 {
1542 FIXME("Unsupported destination type.\n");
1543 return E_INVALIDARG;
1544 }
1545 }
1546 default:
1547 FIXME("Output type %d not handled.\n", V_VT(&output));
1548 return E_NOTIMPL;
1549 }
1550
1551 return E_NOTIMPL;
1552}
1553
1554
1555static HRESULT WINAPI domdoc_get_doctype(
1556 IXMLDOMDocument3 *iface,
1557 IXMLDOMDocumentType** doctype )
1558{
1559 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1561 xmlDtdPtr dtd;
1562 HRESULT hr;
1563
1564 TRACE("(%p)->(%p)\n", This, doctype);
1565
1566 if (!doctype) return E_INVALIDARG;
1567
1568 *doctype = NULL;
1569
1570 dtd = xmlGetIntSubset(get_doc(This));
1571 if (!dtd) return S_FALSE;
1572
1573 node = create_node((xmlNodePtr)dtd);
1574 if (!node) return S_FALSE;
1575
1576 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentType, (void**)doctype);
1577 IXMLDOMNode_Release(node);
1578
1579 return hr;
1580}
1581
1582
1583static HRESULT WINAPI domdoc_get_implementation(
1584 IXMLDOMDocument3 *iface,
1585 IXMLDOMImplementation** impl )
1586{
1587 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1588
1589 TRACE("(%p)->(%p)\n", This, impl);
1590
1591 if(!impl)
1592 return E_INVALIDARG;
1593
1594 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1595
1596 return S_OK;
1597}
1598
1599static HRESULT WINAPI domdoc_get_documentElement(
1600 IXMLDOMDocument3 *iface,
1601 IXMLDOMElement** DOMElement )
1602{
1603 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1604 IXMLDOMNode *element_node;
1606 HRESULT hr;
1607
1608 TRACE("(%p)->(%p)\n", This, DOMElement);
1609
1610 if(!DOMElement)
1611 return E_INVALIDARG;
1612
1613 *DOMElement = NULL;
1614
1615 root = xmlDocGetRootElement( get_doc(This) );
1616 if ( !root )
1617 return S_FALSE;
1618
1619 element_node = create_node( root );
1620 if(!element_node) return S_FALSE;
1621
1622 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1623 IXMLDOMNode_Release(element_node);
1624
1625 return hr;
1626}
1627
1628
1629static HRESULT WINAPI domdoc_put_documentElement(
1630 IXMLDOMDocument3 *iface,
1631 IXMLDOMElement* DOMElement )
1632{
1633 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1634 IXMLDOMNode *elementNode;
1635 xmlNodePtr oldRoot;
1636 xmlDocPtr old_doc;
1637 xmlnode *xmlNode;
1638 int refcount = 0;
1639 HRESULT hr;
1640
1641 TRACE("(%p)->(%p)\n", This, DOMElement);
1642
1643 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1644 if(FAILED(hr))
1645 return hr;
1646
1647 xmlNode = get_node_obj( elementNode );
1648 if(!xmlNode) return E_FAIL;
1649
1650 if(!xmlNode->node->parent)
1651 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1652 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1653
1654 old_doc = xmlNode->node->doc;
1655 if (old_doc != get_doc(This))
1656 refcount = xmlnode_get_inst_cnt(xmlNode);
1657
1658 /* old root is still orphaned by its document, update refcount from new root */
1659 if (refcount) xmldoc_add_refs(get_doc(This), refcount);
1660 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1661 if (refcount) xmldoc_release_refs(old_doc, refcount);
1662 IXMLDOMNode_Release( elementNode );
1663
1664 if(oldRoot)
1665 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1666
1667 return S_OK;
1668}
1669
1670
1671static HRESULT WINAPI domdoc_createElement(
1672 IXMLDOMDocument3 *iface,
1673 BSTR tagname,
1675{
1676 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1678 VARIANT type;
1679 HRESULT hr;
1680
1681 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1682
1683 if (!element || !tagname) return E_INVALIDARG;
1684
1685 V_VT(&type) = VT_I1;
1687
1688 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1689 if (hr == S_OK)
1690 {
1691 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1692 IXMLDOMNode_Release(node);
1693 }
1694
1695 return hr;
1696}
1697
1698
1699static HRESULT WINAPI domdoc_createDocumentFragment(
1700 IXMLDOMDocument3 *iface,
1702{
1703 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1705 VARIANT type;
1706 HRESULT hr;
1707
1708 TRACE("(%p)->(%p)\n", This, frag);
1709
1710 if (!frag) return E_INVALIDARG;
1711
1712 *frag = NULL;
1713
1714 V_VT(&type) = VT_I1;
1716
1717 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1718 if (hr == S_OK)
1719 {
1720 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1721 IXMLDOMNode_Release(node);
1722 }
1723
1724 return hr;
1725}
1726
1727
1728static HRESULT WINAPI domdoc_createTextNode(
1729 IXMLDOMDocument3 *iface,
1730 BSTR data,
1731 IXMLDOMText** text )
1732{
1733 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1735 VARIANT type;
1736 HRESULT hr;
1737
1738 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1739
1740 if (!text) return E_INVALIDARG;
1741
1742 *text = NULL;
1743
1744 V_VT(&type) = VT_I1;
1745 V_I1(&type) = NODE_TEXT;
1746
1747 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1748 if (hr == S_OK)
1749 {
1750 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1751 IXMLDOMNode_Release(node);
1752 hr = IXMLDOMText_put_data(*text, data);
1753 }
1754
1755 return hr;
1756}
1757
1758
1759static HRESULT WINAPI domdoc_createComment(
1760 IXMLDOMDocument3 *iface,
1761 BSTR data,
1763{
1764 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1765 VARIANT type;
1766 HRESULT hr;
1768
1769 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1770
1771 if (!comment) return E_INVALIDARG;
1772
1773 *comment = NULL;
1774
1775 V_VT(&type) = VT_I1;
1777
1778 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1779 if (hr == S_OK)
1780 {
1781 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1782 IXMLDOMNode_Release(node);
1783 hr = IXMLDOMComment_put_data(*comment, data);
1784 }
1785
1786 return hr;
1787}
1788
1789
1790static HRESULT WINAPI domdoc_createCDATASection(
1791 IXMLDOMDocument3 *iface,
1792 BSTR data,
1793 IXMLDOMCDATASection** cdata )
1794{
1795 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1797 VARIANT type;
1798 HRESULT hr;
1799
1800 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1801
1802 if (!cdata) return E_INVALIDARG;
1803
1804 *cdata = NULL;
1805
1806 V_VT(&type) = VT_I1;
1808
1809 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1810 if (hr == S_OK)
1811 {
1812 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1813 IXMLDOMNode_Release(node);
1814 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1815 }
1816
1817 return hr;
1818}
1819
1820
1821static HRESULT WINAPI domdoc_createProcessingInstruction(
1822 IXMLDOMDocument3 *iface,
1823 BSTR target,
1824 BSTR data,
1826{
1827 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1829 VARIANT type;
1830 HRESULT hr;
1831
1832 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1833
1834 if (!pi) return E_INVALIDARG;
1835
1836 *pi = NULL;
1837
1838 V_VT(&type) = VT_I1;
1840
1841 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1842 if (hr == S_OK)
1843 {
1844 xmlnode *node_obj;
1845
1846 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1847 node_obj = get_node_obj(node);
1848 hr = node_set_content(node_obj, data);
1849
1850 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1851 IXMLDOMNode_Release(node);
1852 }
1853
1854 return hr;
1855}
1856
1857
1858static HRESULT WINAPI domdoc_createAttribute(
1859 IXMLDOMDocument3 *iface,
1860 BSTR name,
1862{
1863 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1865 VARIANT type;
1866 HRESULT hr;
1867
1868 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1869
1870 if (!attribute || !name) return E_INVALIDARG;
1871
1872 V_VT(&type) = VT_I1;
1874
1875 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1876 if (hr == S_OK)
1877 {
1878 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1879 IXMLDOMNode_Release(node);
1880 }
1881
1882 return hr;
1883}
1884
1885
1886static HRESULT WINAPI domdoc_createEntityReference(
1887 IXMLDOMDocument3 *iface,
1888 BSTR name,
1889 IXMLDOMEntityReference** entityref )
1890{
1891 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1893 VARIANT type;
1894 HRESULT hr;
1895
1896 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1897
1898 if (!entityref) return E_INVALIDARG;
1899
1900 *entityref = NULL;
1901
1902 V_VT(&type) = VT_I1;
1904
1905 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1906 if (hr == S_OK)
1907 {
1908 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1909 IXMLDOMNode_Release(node);
1910 }
1911
1912 return hr;
1913}
1914
1915xmlChar* tagName_to_XPath(const BSTR tagName)
1916{
1917 xmlChar *query, *tmp;
1918 static const xmlChar everything[] = "/descendant::node()";
1919 static const xmlChar mod_pre[] = "*[local-name()='";
1920 static const xmlChar mod_post[] = "']";
1921 static const xmlChar prefix[] = "descendant::";
1922 const WCHAR *tokBegin, *tokEnd;
1923 int len;
1924
1925 /* Special case - empty tagname - means select all nodes,
1926 except document itself. */
1927 if (!*tagName)
1928 return xmlStrdup(everything);
1929
1930 query = xmlStrdup(prefix);
1931
1932 tokBegin = tagName;
1933 while (tokBegin && *tokBegin)
1934 {
1935 switch (*tokBegin)
1936 {
1937 case '/':
1938 query = xmlStrcat(query, BAD_CAST "/");
1939 ++tokBegin;
1940 break;
1941 case '*':
1942 query = xmlStrcat(query, BAD_CAST "*");
1943 ++tokBegin;
1944 break;
1945 default:
1946 query = xmlStrcat(query, mod_pre);
1947 tokEnd = tokBegin;
1948 while (*tokEnd && *tokEnd != '/')
1949 ++tokEnd;
1950 len = WideCharToMultiByte(CP_UTF8, 0, tokBegin, tokEnd-tokBegin, NULL, 0, NULL, NULL);
1951 tmp = xmlMalloc(len);
1952 WideCharToMultiByte(CP_UTF8, 0, tokBegin, tokEnd-tokBegin, (char*)tmp, len, NULL, NULL);
1953 query = xmlStrncat(query, tmp, len);
1954 xmlFree(tmp);
1955 tokBegin = tokEnd;
1956 query = xmlStrcat(query, mod_post);
1957 }
1958 }
1959
1960 return query;
1961}
1962
1963static HRESULT WINAPI domdoc_getElementsByTagName(
1964 IXMLDOMDocument3 *iface,
1965 BSTR tagName,
1966 IXMLDOMNodeList** resultList )
1967{
1968 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1969 xmlChar *query;
1970 HRESULT hr;
1971 BOOL XPath;
1972
1973 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1974
1975 if (!tagName || !resultList) return E_INVALIDARG;
1976
1977 XPath = This->properties->XPath;
1978 This->properties->XPath = TRUE;
1979 query = tagName_to_XPath(tagName);
1980 hr = create_selection((xmlNodePtr)get_doc(This), query, resultList);
1981 xmlFree(query);
1982 This->properties->XPath = XPath;
1983
1984 return hr;
1985}
1986
1988{
1989 VARIANT tmp;
1990 HRESULT hr;
1991
1992 VariantInit(&tmp);
1993 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1994 if(FAILED(hr))
1995 return E_INVALIDARG;
1996
1997 *type = V_I4(&tmp);
1998
1999 return S_OK;
2000}
2001
2002static HRESULT WINAPI domdoc_createNode(
2003 IXMLDOMDocument3 *iface,
2004 VARIANT Type,
2005 BSTR name,
2006 BSTR namespaceURI,
2007 IXMLDOMNode** node )
2008{
2009 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2010 DOMNodeType node_type;
2011 xmlNodePtr xmlnode;
2012 xmlChar *xml_name, *href;
2013 HRESULT hr;
2014
2015 TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_variant(&Type), debugstr_w(name), debugstr_w(namespaceURI), node);
2016
2017 if(!node) return E_INVALIDARG;
2018
2019 hr = get_node_type(Type, &node_type);
2020 if(FAILED(hr)) return hr;
2021
2022 TRACE("node_type %d\n", node_type);
2023
2024 /* exit earlier for types that need name */
2025 switch(node_type)
2026 {
2027 case NODE_ELEMENT:
2028 case NODE_ATTRIBUTE:
2031 if (!name || *name == 0) return E_FAIL;
2032 break;
2033 default:
2034 break;
2035 }
2036
2037 xml_name = xmlchar_from_wchar(name);
2038 /* prevent empty href from being allocated */
2039 href = namespaceURI ? xmlchar_from_wchar(namespaceURI) : NULL;
2040
2041 switch(node_type)
2042 {
2043 case NODE_ELEMENT:
2044 {
2045 xmlChar *local, *prefix;
2046
2047 local = xmlSplitQName2(xml_name, &prefix);
2048
2049 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
2050
2051 /* allow creating the default namespace xmlns= */
2052 if (local || (href && *href))
2053 {
2054 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
2055 xmlSetNs(xmlnode, ns);
2056 }
2057
2058 xmlFree(local);
2059 xmlFree(prefix);
2060
2061 break;
2062 }
2063 case NODE_ATTRIBUTE:
2064 {
2065 xmlChar *local, *prefix;
2066
2067 local = xmlSplitQName2(xml_name, &prefix);
2068
2069 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), local ? local : xml_name, NULL);
2070
2071 if (local || (href && *href))
2072 {
2073 /* we need a floating namespace here, it can't be created linked to attribute from
2074 a start */
2075 xmlNsPtr ns = xmlNewNs(NULL, href, prefix);
2076 xmlSetNs(xmlnode, ns);
2077 }
2078
2079 xmlFree(local);
2080 xmlFree(prefix);
2081
2082 break;
2083 }
2084 case NODE_TEXT:
2085 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
2086 break;
2087 case NODE_CDATA_SECTION:
2088 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
2089 break;
2091 xmlnode = xmlNewReference(get_doc(This), xml_name);
2092 break;
2094#ifdef HAVE_XMLNEWDOCPI
2095 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
2096#else
2097 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
2098 xmlnode = NULL;
2099#endif
2100 break;
2101 case NODE_COMMENT:
2102 xmlnode = xmlNewDocComment(get_doc(This), NULL);
2103 break;
2105 xmlnode = xmlNewDocFragment(get_doc(This));
2106 break;
2107 /* unsupported types */
2108 case NODE_DOCUMENT:
2109 case NODE_DOCUMENT_TYPE:
2110 case NODE_ENTITY:
2111 case NODE_NOTATION:
2112 heap_free(xml_name);
2113 return E_INVALIDARG;
2114 default:
2115 FIXME("unhandled node type %d\n", node_type);
2116 xmlnode = NULL;
2117 break;
2118 }
2119
2120 *node = create_node(xmlnode);
2121 heap_free(xml_name);
2122 heap_free(href);
2123
2124 if(*node)
2125 {
2126 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
2127 xmldoc_add_orphan(xmlnode->doc, xmlnode);
2128 return S_OK;
2129 }
2130
2131 return E_FAIL;
2132}
2133
2134static HRESULT WINAPI domdoc_nodeFromID(
2135 IXMLDOMDocument3 *iface,
2136 BSTR idString,
2137 IXMLDOMNode** node )
2138{
2139 domdoc *This = impl_from_IXMLDOMDocument3(iface);
2140 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
2141 return E_NOTIMPL;
2142}
2143
2144static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
2145{
2146 domdoc *This = obj;
2147 xmlDocPtr xmldoc;
2148
2149 xmldoc = doparse(This, ptr, len, XML_CHAR_ENCODING_NONE);
2150 if(xmldoc) {
2151 xmldoc->_private = create_priv();
2152 return attach_xmldoc(This, xmldoc);
2153 }
2154
2155 return E_FAIL;
2156}
2157
2158static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon)
2159{
2160 bsc_t *bsc;
2161 HRESULT hr;
2162
2163 hr = bind_url(mon, domdoc_onDataAvailable, This, &bsc);
2164 if(FAILED(hr))
2165 return hr;
2166
2167 return detach_bsc(bsc);
2168}
2169
2170static HRESULT WINAPI domdoc_load(
2171 IXMLDOMDocument3 *iface,
2173 VARIANT_BOOL* isSuccessful )
2174{
2175 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2177 HRESULT hr = S_FALSE;
2178 xmlDocPtr xmldoc;
2179
2180 TRACE("(%p)->(%s)\n", This, debugstr_variant(&source));
2181
2182 if (!isSuccessful)
2183 return E_POINTER;
2184 *isSuccessful = VARIANT_FALSE;
2185
2186 assert( &This->node );
2187
2188 switch( V_VT(&source) )
2189 {
2190 case VT_BSTR:
2192 break;
2193 case VT_BSTR|VT_BYREF:
2194 if (!V_BSTRREF(&source)) return E_INVALIDARG;
2196 break;
2197 case VT_ARRAY|VT_UI1:
2198 {
2200 char *str;
2201 LONG len;
2202 UINT dim = SafeArrayGetDim(psa);
2203
2204 switch (dim)
2205 {
2206 case 0:
2207 ERR("SAFEARRAY == NULL\n");
2208 hr = This->error = E_INVALIDARG;
2209 break;
2210 case 1:
2211 /* Only takes UTF-8 strings.
2212 * NOT NULL-terminated. */
2213 hr = SafeArrayAccessData(psa, (void**)&str);
2214 if (FAILED(hr))
2215 {
2216 This->error = hr;
2217 WARN("failed to access array data, 0x%08x\n", hr);
2218 break;
2219 }
2221
2222 if ((xmldoc = doparse(This, str, ++len, XML_CHAR_ENCODING_UTF8)))
2223 {
2224 hr = This->error = S_OK;
2225 *isSuccessful = VARIANT_TRUE;
2226 TRACE("parsed document %p\n", xmldoc);
2227 }
2228 else
2229 {
2230 This->error = E_FAIL;
2231 TRACE("failed to parse document\n");
2232 }
2233
2235
2236 if(xmldoc)
2237 {
2238 xmldoc->_private = create_priv();
2239 return attach_xmldoc(This, xmldoc);
2240 }
2241 break;
2242 default:
2243 FIXME("unhandled SAFEARRAY dim: %d\n", dim);
2244 hr = This->error = E_NOTIMPL;
2245 }
2246 }
2247 break;
2248 case VT_UNKNOWN:
2249 {
2251 IXMLDOMDocument3 *newdoc = NULL;
2252
2253 if (!V_UNKNOWN(&source)) return E_INVALIDARG;
2254
2255 hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IXMLDOMDocument3, (void**)&newdoc);
2256 if(hr == S_OK)
2257 {
2258 if(newdoc)
2259 {
2260 domdoc *newDoc = impl_from_IXMLDOMDocument3( newdoc );
2261
2262 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
2263 xmldoc->_private = create_priv();
2264 hr = attach_xmldoc(This, xmldoc);
2265
2266 if(SUCCEEDED(hr))
2267 *isSuccessful = VARIANT_TRUE;
2268
2269 return hr;
2270 }
2271 }
2272
2273 hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IStream, (void**)&stream);
2274 if (FAILED(hr))
2275 hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_ISequentialStream, (void**)&stream);
2276
2277 if (hr == S_OK)
2278 {
2279 hr = domdoc_load_from_stream(This, stream);
2280 if (hr == S_OK)
2281 *isSuccessful = VARIANT_TRUE;
2282 ISequentialStream_Release(stream);
2283 return hr;
2284 }
2285
2286 FIXME("unsupported IUnknown type (0x%08x) (%p)\n", hr, V_UNKNOWN(&source)->lpVtbl);
2287 break;
2288 }
2289 default:
2290 FIXME("VT type not supported (%d)\n", V_VT(&source));
2291 }
2292
2293 if ( filename )
2294 {
2295 IUri *uri = NULL;
2296 IMoniker *mon;
2297
2298 if (This->properties->uri)
2299 {
2300 IUri_Release(This->properties->uri);
2301 This->properties->uri = NULL;
2302 }
2303
2305 if (SUCCEEDED(hr))
2306 hr = CreateURLMonikerEx2(NULL, uri, &mon, 0);
2307 if ( SUCCEEDED(hr) )
2308 {
2309 hr = domdoc_load_moniker( This, mon );
2310 IMoniker_Release(mon);
2311 }
2312
2313 if (SUCCEEDED(hr))
2314 {
2315 get_doc(This)->name = (char *)xmlchar_from_wcharn(filename, -1, TRUE);
2316 This->properties->uri = uri;
2317 hr = This->error = S_OK;
2318 *isSuccessful = VARIANT_TRUE;
2319 }
2320 else
2321 {
2322 if (uri)
2323 IUri_Release(uri);
2324 This->error = E_FAIL;
2325 }
2326 }
2327
2328 if(!filename || FAILED(hr)) {
2329 xmldoc = xmlNewDoc(NULL);
2330 xmldoc->_private = create_priv();
2331 hr = attach_xmldoc(This, xmldoc);
2332 if(SUCCEEDED(hr))
2333 hr = S_FALSE;
2334 }
2335
2336 TRACE("ret (%d)\n", hr);
2337
2338 return hr;
2339}
2340
2341
2342static HRESULT WINAPI domdoc_get_readyState(
2343 IXMLDOMDocument3 *iface,
2344 LONG *value )
2345{
2346 domdoc *This = impl_from_IXMLDOMDocument3(iface);
2347 FIXME("stub! (%p)->(%p)\n", This, value);
2348
2349 if (!value)
2350 return E_INVALIDARG;
2351
2352 *value = READYSTATE_COMPLETE;
2353 return S_OK;
2354}
2355
2356
2357static HRESULT WINAPI domdoc_get_parseError(
2358 IXMLDOMDocument3 *iface,
2359 IXMLDOMParseError** errorObj )
2360{
2361 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2362 static const WCHAR err[] = {'e','r','r','o','r',0};
2363 BSTR error_string = NULL;
2364
2365 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
2366
2367 if(This->error)
2368 error_string = SysAllocString(err);
2369
2370 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
2371 if(!*errorObj) return E_OUTOFMEMORY;
2372 return S_OK;
2373}
2374
2375
2376static HRESULT WINAPI domdoc_get_url(
2377 IXMLDOMDocument3 *iface,
2378 BSTR* url )
2379{
2380 domdoc *This = impl_from_IXMLDOMDocument3(iface);
2381
2382 TRACE("(%p)->(%p)\n", This, url);
2383
2384 if (!url)
2385 return E_INVALIDARG;
2386
2387 if (!This->properties->uri)
2388 return return_null_bstr(url);
2389
2390 return IUri_GetPropertyBSTR(This->properties->uri, Uri_PROPERTY_DISPLAY_URI, url, 0);
2391}
2392
2393
2394static HRESULT WINAPI domdoc_get_async(
2395 IXMLDOMDocument3 *iface,
2396 VARIANT_BOOL* isAsync )
2397{
2398 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2399
2400 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
2401 *isAsync = This->async;
2402 return S_OK;
2403}
2404
2405
2406static HRESULT WINAPI domdoc_put_async(
2407 IXMLDOMDocument3 *iface,
2408 VARIANT_BOOL isAsync )
2409{
2410 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2411
2412 TRACE("(%p)->(%d)\n", This, isAsync);
2413 This->async = isAsync;
2414 return S_OK;
2415}
2416
2417
2418static HRESULT WINAPI domdoc_abort(
2419 IXMLDOMDocument3 *iface )
2420{
2421 domdoc *This = impl_from_IXMLDOMDocument3(iface);
2422 FIXME("%p\n", This);
2423 return E_NOTIMPL;
2424}
2425
2426/* don't rely on data to be in BSTR format, treat it as WCHAR string */
2427static HRESULT WINAPI domdoc_loadXML(
2428 IXMLDOMDocument3 *iface,
2429 BSTR data,
2430 VARIANT_BOOL* isSuccessful )
2431{
2432 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2433 xmlDocPtr xmldoc = NULL;
2434 HRESULT hr = S_FALSE, hr2;
2435
2436 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), isSuccessful );
2437
2438 assert ( &This->node );
2439
2440 if ( isSuccessful )
2441 {
2442 *isSuccessful = VARIANT_FALSE;
2443
2444 if (data)
2445 {
2446 WCHAR *ptr = data;
2447
2448 /* skip leading spaces if needed */
2449 if (This->properties->version == MSXML_DEFAULT || This->properties->version == MSXML26)
2450 while (*ptr && isspaceW(*ptr)) ptr++;
2451
2452 xmldoc = doparse(This, (char*)ptr, strlenW(ptr)*sizeof(WCHAR), XML_CHAR_ENCODING_UTF16LE);
2453 if ( !xmldoc )
2454 {
2455 This->error = E_FAIL;
2456 TRACE("failed to parse document\n");
2457 }
2458 else
2459 {
2460 hr = This->error = S_OK;
2461 *isSuccessful = VARIANT_TRUE;
2462 TRACE("parsed document %p\n", xmldoc);
2463 }
2464 }
2465 }
2466
2467 if(!xmldoc)
2468 xmldoc = xmlNewDoc(NULL);
2469 xmldoc->_private = create_priv();
2470 hr2 = attach_xmldoc(This, xmldoc);
2471 if( FAILED(hr2) )
2472 hr = hr2;
2473
2474 return hr;
2475}
2476
2477static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer, int len)
2478{
2479 DWORD written = -1;
2480
2481 if(!WriteFile(ctx, buffer, len, &written, NULL))
2482 {
2483 WARN("write error\n");
2484 return -1;
2485 }
2486 else
2487 return written;
2488}
2489
2490static int XMLCALL domdoc_save_closecallback(void *ctx)
2491{
2492 return CloseHandle(ctx) ? 0 : -1;
2493}
2494
2495static int XMLCALL domdoc_stream_save_writecallback(void *ctx, const char *buffer, int len)
2496{
2497 ULONG written = 0;
2498 HRESULT hr;
2499
2500 hr = IStream_Write((IStream*)ctx, buffer, len, &written);
2501 TRACE("0x%08x %p %d %u\n", hr, buffer, len, written);
2502 if (hr != S_OK)
2503 {
2504 WARN("stream write error: 0x%08x\n", hr);
2505 return -1;
2506 }
2507 else
2508 return len;
2509}
2510
2511static int XMLCALL domdoc_stream_save_closecallback(void *ctx)
2512{
2513 IStream_Release((IStream*)ctx);
2514 return 0;
2515}
2516
2517static HRESULT WINAPI domdoc_save(
2518 IXMLDOMDocument3 *iface,
2519 VARIANT destination )
2520{
2521 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2522 xmlSaveCtxtPtr ctx = NULL;
2523 xmlNodePtr xmldecl;
2524 HRESULT ret = S_OK;
2525
2526 TRACE("(%p)->(%s)\n", This, debugstr_variant(&destination));
2527
2528 switch (V_VT(&destination))
2529 {
2530 case VT_UNKNOWN:
2531 {
2532 IUnknown *pUnk = V_UNKNOWN(&destination);
2533 IXMLDOMDocument3 *document;
2534 IStream *stream;
2535
2536 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&document);
2537 if(ret == S_OK)
2538 {
2540 BSTR xml;
2541
2542 ret = IXMLDOMDocument3_get_xml(iface, &xml);
2543 if(ret == S_OK)
2544 {
2545 ret = IXMLDOMDocument3_loadXML(document, xml, &success);
2546 SysFreeString(xml);
2547 }
2548
2549 IXMLDOMDocument3_Release(document);
2550 return ret;
2551 }
2552
2553 ret = IUnknown_QueryInterface(pUnk, &IID_IStream, (void**)&stream);
2554 if(ret == S_OK)
2555 {
2556 int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0;
2557 ctx = xmlSaveToIO(domdoc_stream_save_writecallback,
2558 domdoc_stream_save_closecallback, stream, NULL, options);
2559
2560 if(!ctx)
2561 {
2562 IStream_Release(stream);
2563 return E_FAIL;
2564 }
2565 }
2566 }
2567 break;
2568
2569 case VT_BSTR:
2570 case VT_BSTR | VT_BYREF:
2571 {
2572 int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0;
2573
2574 /* save with file path */
2575 HANDLE handle = CreateFileW( (V_VT(&destination) & VT_BYREF)? *V_BSTRREF(&destination) : V_BSTR(&destination),
2578 {
2579 WARN("failed to create file\n");
2580 return E_FAIL;
2581 }
2582
2583 /* disable top XML declaration */
2584 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
2585 handle, NULL, options);
2586 if (!ctx)
2587 {
2589 return E_FAIL;
2590 }
2591 }
2592 break;
2593
2594 default:
2595 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination));
2596 return S_FALSE;
2597 }
2598
2599 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
2600 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
2601 xmldoc_link_xmldecl(get_doc(This), xmldecl);
2602
2603 /* will release resources through close callback */
2604 xmlSaveClose(ctx);
2605
2606 return ret;
2607}
2608
2609static HRESULT WINAPI domdoc_get_validateOnParse(
2610 IXMLDOMDocument3 *iface,
2611 VARIANT_BOOL* isValidating )
2612{
2613 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2614 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
2615 *isValidating = This->validating;
2616 return S_OK;
2617}
2618
2619
2620static HRESULT WINAPI domdoc_put_validateOnParse(
2621 IXMLDOMDocument3 *iface,
2622 VARIANT_BOOL isValidating )
2623{
2624 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2625 TRACE("(%p)->(%d)\n", This, isValidating);
2626 This->validating = isValidating;
2627 return S_OK;
2628}
2629
2630
2631static HRESULT WINAPI domdoc_get_resolveExternals(
2632 IXMLDOMDocument3 *iface,
2633 VARIANT_BOOL* isResolving )
2634{
2635 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2636 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
2637 *isResolving = This->resolving;
2638 return S_OK;
2639}
2640
2641
2642static HRESULT WINAPI domdoc_put_resolveExternals(
2643 IXMLDOMDocument3 *iface,
2644 VARIANT_BOOL isResolving )
2645{
2646 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2647 TRACE("(%p)->(%d)\n", This, isResolving);
2648 This->resolving = isResolving;
2649 return S_OK;
2650}
2651
2652
2653static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
2654 IXMLDOMDocument3 *iface,
2655 VARIANT_BOOL* isPreserving )
2656{
2657 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2658 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->properties->preserving);
2659 *isPreserving = This->properties->preserving;
2660 return S_OK;
2661}
2662
2663
2664static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2665 IXMLDOMDocument3 *iface,
2666 VARIANT_BOOL isPreserving )
2667{
2668 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2669 TRACE("(%p)->(%d)\n", This, isPreserving);
2670 This->properties->preserving = isPreserving;
2671 return S_OK;
2672}
2673
2674
2675static HRESULT WINAPI domdoc_put_onreadystatechange(
2676 IXMLDOMDocument3 *iface,
2677 VARIANT event )
2678{
2679 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2680
2681 TRACE("(%p)->(%s)\n", This, debugstr_variant(&event));
2683}
2684
2685
2686static HRESULT WINAPI domdoc_put_onDataAvailable(IXMLDOMDocument3 *iface, VARIANT sink)
2687{
2688 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2689 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&sink));
2690 return E_NOTIMPL;
2691}
2692
2693static HRESULT WINAPI domdoc_put_onTransformNode(IXMLDOMDocument3 *iface, VARIANT sink )
2694{
2695 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2696 FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&sink));
2697 return E_NOTIMPL;
2698}
2699
2700static HRESULT WINAPI domdoc_get_namespaces(
2701 IXMLDOMDocument3* iface,
2702 IXMLDOMSchemaCollection** collection )
2703{
2704 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2705 HRESULT hr;
2706
2707 FIXME("(%p)->(%p): semi-stub\n", This, collection);
2708
2709 if (!collection) return E_POINTER;
2710
2711 if (!This->namespaces)
2712 {
2713 hr = SchemaCache_create(This->properties->version, (void**)&This->namespaces);
2714 if (hr != S_OK) return hr;
2715
2716 hr = cache_from_doc_ns(This->namespaces, &This->node);
2717 if (hr != S_OK)
2718 release_namespaces(This);
2719 }
2720
2721 if (This->namespaces)
2722 return IXMLDOMSchemaCollection2_QueryInterface(This->namespaces,
2723 &IID_IXMLDOMSchemaCollection, (void**)collection);
2724
2725 return hr;
2726}
2727
2728static HRESULT WINAPI domdoc_get_schemas(
2729 IXMLDOMDocument3* iface,
2730 VARIANT* schema )
2731{
2732 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2733 IXMLDOMSchemaCollection2* cur_schema = This->properties->schemaCache;
2734 HRESULT hr = S_FALSE;
2735
2736 TRACE("(%p)->(%p)\n", This, schema);
2737
2738 V_VT(schema) = VT_NULL;
2739 /* just to reset pointer part, cause that's what application is expected to use */
2741
2742 if(cur_schema)
2743 {
2744 hr = IXMLDOMSchemaCollection2_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(schema));
2745 if(SUCCEEDED(hr))
2747 }
2748 return hr;
2749}
2750
2751static HRESULT WINAPI domdoc_putref_schemas(
2752 IXMLDOMDocument3* iface,
2754{
2755 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2756 HRESULT hr = E_FAIL;
2757 IXMLDOMSchemaCollection2* new_schema = NULL;
2758
2759 FIXME("(%p)->(%s): semi-stub\n", This, debugstr_variant(&schema));
2760 switch(V_VT(&schema))
2761 {
2762 case VT_UNKNOWN:
2763 if (V_UNKNOWN(&schema))
2764 {
2765 hr = IUnknown_QueryInterface(V_UNKNOWN(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2766 break;
2767 }
2768 /* fallthrough */
2769 case VT_DISPATCH:
2770 if (V_DISPATCH(&schema))
2771 {
2772 hr = IDispatch_QueryInterface(V_DISPATCH(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2773 break;
2774 }
2775 /* fallthrough */
2776 case VT_NULL:
2777 case VT_EMPTY:
2778 hr = S_OK;
2779 break;
2780
2781 default:
2782 WARN("Can't get schema from vt %x\n", V_VT(&schema));
2783 }
2784
2785 if(SUCCEEDED(hr))
2786 {
2787 IXMLDOMSchemaCollection2* old_schema = InterlockedExchangePointer((void**)&This->properties->schemaCache, new_schema);
2788 if(old_schema) IXMLDOMSchemaCollection2_Release(old_schema);
2789 }
2790
2791 return hr;
2792}
2793
2794static inline BOOL is_wellformed(xmlDocPtr doc)
2795{
2796#ifdef HAVE_XMLDOC_PROPERTIES
2797 return doc->properties & XML_DOC_WELLFORMED;
2798#else
2799 /* Not a full check, but catches the worst violations */
2801 int root = 0;
2802
2803 for (child = doc->children; child != NULL; child = child->next)
2804 {
2805 switch (child->type)
2806 {
2807 case XML_ELEMENT_NODE:
2808 if (++root > 1)
2809 return FALSE;
2810 break;
2811 case XML_TEXT_NODE:
2813 return FALSE;
2814 break;
2815 default:
2816 break;
2817 }
2818 }
2819
2820 return root == 1;
2821#endif
2822}
2823
2824static void LIBXML2_LOG_CALLBACK validate_error(void* ctx, char const* msg, ...)
2825{
2826 va_list ap;
2827 va_start(ap, msg);
2828 LIBXML2_CALLBACK_ERR(domdoc_validateNode, msg, ap);
2829 va_end(ap);
2830}
2831
2832static void LIBXML2_LOG_CALLBACK validate_warning(void* ctx, char const* msg, ...)
2833{
2834 va_list ap;
2835 va_start(ap, msg);
2836 LIBXML2_CALLBACK_WARN(domdoc_validateNode, msg, ap);
2837 va_end(ap);
2838}
2839
2840static HRESULT WINAPI domdoc_validateNode(
2841 IXMLDOMDocument3* iface,
2844{
2845 domdoc* This = impl_from_IXMLDOMDocument3(iface);
2846 LONG state, err_code = 0;
2847 HRESULT hr = S_OK;
2848 int validated = 0;
2849
2850 TRACE("(%p)->(%p, %p)\n", This, node, err);
2851 IXMLDOMDocument3_get_readyState(iface, &state);
2852 if (state != READYSTATE_COMPLETE)
2853 {
2854 if (err)
2855 *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0);
2856 return E_PENDING;
2857 }
2858
2859 if (!node)
2860 {
2861 if (err)
2862 *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0);
2863 return E_POINTER;
2864 }
2865
2866 if (!get_node_obj(node)->node || get_node_obj(node)->node->doc != get_doc(This))
2867 {
2868 if (err)
2869 *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0);
2870 return E_FAIL;
2871 }
2872
2873 if (!is_wellformed(get_doc(This)))
2874 {
2875 ERR("doc not well-formed\n");
2876 if (err)
2877 *err = create_parseError(E_XML_NOTWF, NULL, NULL, NULL, 0, 0, 0);
2878 return S_FALSE;
2879 }
2880
2881 /* DTD validation */
2882 if (get_doc(This)->intSubset || get_doc(This)->extSubset)
2883 {
2884 xmlValidCtxtPtr vctx = xmlNewValidCtxt();
2885 vctx->error = validate_error;
2886 vctx->warning = validate_warning;
2887 ++validated;
2888
2889 if (!((node == (IXMLDOMNode*)iface)?
2890 xmlValidateDocument(vctx, get_doc(This)) :
2891 xmlValidateElement(vctx, get_doc(This), get_node_obj(node)->node)))
2892 {
2893 /* TODO: get a real error code here */
2894 TRACE("DTD validation failed\n");
2895 err_code = E_XML_INVALID;
2896 hr = S_FALSE;
2897 }
2898 xmlFreeValidCtxt(vctx);
2899 }
2900
2901 /* Schema validation */
2902 if (hr == S_OK && This->properties->schemaCache != NULL)
2903 {
2904
2905 hr = SchemaCache_validate_tree(This->properties->schemaCache, get_node_obj(node)->node);
2906 if (SUCCEEDED(hr))
2907 {
2908 ++validated;
2909 /* TODO: get a real error code here */
2910 if (hr == S_OK)
2911 {
2912 TRACE("schema validation succeeded\n");
2913 }
2914 else
2915 {
2916 ERR("schema validation failed\n");
2917 err_code = E_XML_INVALID;
2918 }
2919 }
2920 else
2921 {
2922 /* not really OK, just didn't find a schema for the ns */
2923 hr = S_OK;
2924 }
2925 }
2926
2927 if (!validated)
2928 {
2929 ERR("no DTD or schema found\n");
2930 err_code = E_XML_NODTD;
2931 hr = S_FALSE;
2932 }
2933
2934 if (err)
2935 *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0);
2936
2937 return hr;
2938}
2939
2940static HRESULT WINAPI domdoc_validate(
2941 IXMLDOMDocument3* iface,
2943{
2944 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2945 TRACE("(%p)->(%p)\n", This, err);
2946 return IXMLDOMDocument3_validateNode(iface, (IXMLDOMNode*)iface, err);
2947}
2948
2949static HRESULT WINAPI domdoc_setProperty(
2950 IXMLDOMDocument3* iface,
2951 BSTR p,
2952 VARIANT value)
2953{
2954 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2955
2956 TRACE("(%p)->(%s %s)\n", This, debugstr_w(p), debugstr_variant(&value));
2957
2958 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2959 {
2960 VARIANT varStr;
2961 HRESULT hr;
2962 BSTR bstr;
2963
2964 V_VT(&varStr) = VT_EMPTY;
2965 if (V_VT(&value) != VT_BSTR)
2966 {
2967 if (FAILED(hr = VariantChangeType(&varStr, &value, 0, VT_BSTR)))
2968 return hr;
2969 bstr = V_BSTR(&varStr);
2970 }
2971 else
2972 bstr = V_BSTR(&value);
2973
2974 hr = S_OK;
2975 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2976 This->properties->XPath = TRUE;
2977 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2978 This->properties->XPath = FALSE;
2979 else
2980 hr = E_FAIL;
2981
2982 VariantClear(&varStr);
2983 return hr;
2984 }
2985 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2986 {
2987 xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
2988 struct list *pNsList;
2989 VARIANT varStr;
2990 HRESULT hr;
2991 BSTR bstr;
2992
2993 V_VT(&varStr) = VT_EMPTY;
2994 if (V_VT(&value) != VT_BSTR)
2995 {
2996 if (FAILED(hr = VariantChangeType(&varStr, &value, 0, VT_BSTR)))
2997 return hr;
2998 bstr = V_BSTR(&varStr);
2999 }
3000 else
3001 bstr = V_BSTR(&value);
3002
3003 hr = S_OK;
3004
3005 pNsList = &(This->properties->selectNsList);
3006 clear_selectNsList(pNsList);
3007 heap_free(nsStr);
3008 nsStr = xmlchar_from_wchar(bstr);
3009
3010 TRACE("property value: \"%s\"\n", debugstr_w(bstr));
3011
3012 This->properties->selectNsStr = nsStr;
3013 This->properties->selectNsStr_len = xmlStrlen(nsStr);
3014 if (bstr && *bstr)
3015 {
3016 xmlChar *pTokBegin, *pTokEnd, *pTokInner;
3017 select_ns_entry* ns_entry = NULL;
3018 xmlXPathContextPtr ctx;
3019
3020 ctx = xmlXPathNewContext(This->node.node->doc);
3021 pTokBegin = nsStr;
3022
3023 /* skip leading spaces */
3024 while (*pTokBegin == ' ' || *pTokBegin == '\n' ||
3025 *pTokBegin == '\t' || *pTokBegin == '\r')
3026 ++pTokBegin;
3027
3028 for (; *pTokBegin; pTokBegin = pTokEnd)
3029 {
3030 if (ns_entry)
3031 memset(ns_entry, 0, sizeof(select_ns_entry));
3032 else
3033 ns_entry = heap_alloc_zero(sizeof(select_ns_entry));
3034
3035 while (*pTokBegin == ' ')
3036 ++pTokBegin;
3037 pTokEnd = pTokBegin;
3038 while (*pTokEnd != ' ' && *pTokEnd != 0)
3039 ++pTokEnd;
3040
3041 /* so it failed to advance which means we've got some trailing spaces */
3042 if (pTokEnd == pTokBegin) break;
3043
3044 if (xmlStrncmp(pTokBegin, (xmlChar const*)"xmlns", 5) != 0)
3045 {
3046 hr = E_FAIL;
3047 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
3048 debugstr_w(bstr), debugstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
3049 continue;
3050 }
3051
3052 pTokBegin += 5;
3053 if (*pTokBegin == '=')
3054 {
3055 /*valid for XSLPattern?*/
3056 FIXME("Setting default xmlns not supported - skipping.\n");
3057 continue;
3058 }
3059 else if (*pTokBegin == ':')
3060 {
3061 ns_entry->prefix = ++pTokBegin;
3062 for (pTokInner = pTokBegin; pTokInner != pTokEnd && *pTokInner != '='; ++pTokInner)
3063 ;
3064
3065 if (pTokInner == pTokEnd)
3066 {
3067 hr = E_FAIL;
3068 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
3069 debugstr_w(bstr), debugstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
3070 continue;
3071 }
3072
3073 ns_entry->prefix_end = *pTokInner;
3074 *pTokInner = 0;
3075 ++pTokInner;
3076
3077 if (pTokEnd-pTokInner > 1 &&
3078 ((*pTokInner == '\'' && *(pTokEnd-1) == '\'') ||
3079 (*pTokInner == '"' && *(pTokEnd-1) == '"')))
3080 {
3081 ns_entry->href = ++pTokInner;
3082 ns_entry->href_end = *(pTokEnd-1);
3083 *(pTokEnd-1) = 0;
3084 list_add_tail(pNsList, &ns_entry->entry);
3085 /*let libxml figure out if they're valid from here ;)*/
3086 if (xmlXPathRegisterNs(ctx, ns_entry->prefix, ns_entry->href) != 0)
3087 {
3088 hr = E_FAIL;
3089 }
3090 ns_entry = NULL;
3091 continue;
3092 }
3093 else
3094 {
3095 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
3096 debugstr_w(bstr), debugstr_an((const char*)pTokInner, pTokEnd-pTokInner));
3097 list_add_tail(pNsList, &ns_entry->entry);
3098
3099 ns_entry = NULL;
3100 hr = E_FAIL;
3101 continue;
3102 }
3103 }
3104 else
3105 {
3106 hr = E_FAIL;
3107 continue;
3108 }
3109 }
3110 heap_free(ns_entry);
3111 xmlXPathFreeContext(ctx);
3112 }
3113
3114 VariantClear(&varStr);
3115 return hr;
3116 }
3117 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0 ||
3118 lstrcmpiW(p, PropertyNewParserW) == 0 ||
3119 lstrcmpiW(p, PropertyResolveExternalsW) == 0 ||
3120 lstrcmpiW(p, PropertyAllowXsltScriptW) == 0 ||
3121 lstrcmpiW(p, PropertyNormalizeAttributeValuesW) == 0 ||
3122 lstrcmpiW(p, PropertyAllowDocumentFunctionW) == 0)
3123 {
3124 /* Ignore */
3125 FIXME("Ignoring property %s, value %s\n", debugstr_w(p), debugstr_variant(&value));
3126 return S_OK;
3127 }
3128
3129 FIXME("Unknown property %s\n", debugstr_w(p));
3130 return E_FAIL;
3131}
3132
3133static HRESULT WINAPI domdoc_getProperty(
3134 IXMLDOMDocument3* iface,
3135 BSTR p,
3136 VARIANT* var)
3137{
3138 domdoc *This = impl_from_IXMLDOMDocument3( iface );
3139
3140 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
3141
3142 if (!var)
3143 return E_INVALIDARG;
3144
3145 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
3146 {
3147 V_VT(var) = VT_BSTR;
3148 V_BSTR(var) = This->properties->XPath ?
3149 SysAllocString(PropValueXPathW) :
3150 SysAllocString(PropValueXSLPatternW);
3151 return V_BSTR(var) ? S_OK : E_OUTOFMEMORY;
3152 }
3153 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
3154 {
3155 int lenA, lenW;
3156 BSTR rebuiltStr, cur;
3157 const xmlChar *nsStr;
3158 struct list *pNsList;
3159 select_ns_entry* pNsEntry;
3160
3161 V_VT(var) = VT_BSTR;
3162 nsStr = This->properties->selectNsStr;
3163 pNsList = &This->properties->selectNsList;
3164 lenA = This->properties->selectNsStr_len;
3165 lenW = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, NULL, 0);
3166 rebuiltStr = heap_alloc(lenW*sizeof(WCHAR));
3167 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, rebuiltStr, lenW);
3168 cur = rebuiltStr;
3169 /* this is fine because all of the chars that end tokens are ASCII*/
3170 LIST_FOR_EACH_ENTRY(pNsEntry, pNsList, select_ns_entry, entry)
3171 {
3172 while (*cur != 0) ++cur;
3173 if (pNsEntry->prefix_end)
3174 {
3175 *cur = pNsEntry->prefix_end;
3176 while (*cur != 0) ++cur;
3177 }
3178
3179 if (pNsEntry->href_end)
3180 {
3181 *cur = pNsEntry->href_end;
3182 }
3183 }
3184 V_BSTR(var) = SysAllocString(rebuiltStr);
3185 heap_free(rebuiltStr);
3186 return S_OK;
3187 }
3188
3189 FIXME("Unknown property %s\n", debugstr_w(p));
3190 return E_FAIL;
3191}
3192
3193static HRESULT WINAPI domdoc_importNode(
3194 IXMLDOMDocument3* iface,
3196 VARIANT_BOOL deep,
3197 IXMLDOMNode** clone)
3198{
3199 domdoc *This = impl_from_IXMLDOMDocument3( iface );
3200 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
3201 return E_NOTIMPL;
3202}
3203
3204static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl =
3205{
3206 domdoc_QueryInterface,
3207 domdoc_AddRef,
3208 domdoc_Release,
3209 domdoc_GetTypeInfoCount,
3210 domdoc_GetTypeInfo,
3211 domdoc_GetIDsOfNames,
3212 domdoc_Invoke,
3213 domdoc_get_nodeName,
3214 domdoc_get_nodeValue,
3215 domdoc_put_nodeValue,
3216 domdoc_get_nodeType,
3217 domdoc_get_parentNode,
3218 domdoc_get_childNodes,
3219 domdoc_get_firstChild,
3220 domdoc_get_lastChild,
3221 domdoc_get_previousSibling,
3222 domdoc_get_nextSibling,
3223 domdoc_get_attributes,
3224 domdoc_insertBefore,
3225 domdoc_replaceChild,
3226 domdoc_removeChild,
3227 domdoc_appendChild,
3228 domdoc_hasChildNodes,
3229 domdoc_get_ownerDocument,
3230 domdoc_cloneNode,
3231 domdoc_get_nodeTypeString,
3232 domdoc_get_text,
3233 domdoc_put_text,
3234 domdoc_get_specified,
3235 domdoc_get_definition,
3236 domdoc_get_nodeTypedValue,
3237 domdoc_put_nodeTypedValue,
3238 domdoc_get_dataType,
3239 domdoc_put_dataType,
3240 domdoc_get_xml,
3241 domdoc_transformNode,
3242 domdoc_selectNodes,
3243 domdoc_selectSingleNode,
3244 domdoc_get_parsed,
3245 domdoc_get_namespaceURI,
3246 domdoc_get_prefix,
3247 domdoc_get_baseName,
3248 domdoc_transformNodeToObject,
3249 domdoc_get_doctype,
3250 domdoc_get_implementation,
3251 domdoc_get_documentElement,
3252 domdoc_put_documentElement,
3253 domdoc_createElement,
3254 domdoc_createDocumentFragment,
3255 domdoc_createTextNode,
3256 domdoc_createComment,
3257 domdoc_createCDATASection,
3258 domdoc_createProcessingInstruction,
3259 domdoc_createAttribute,
3260 domdoc_createEntityReference,
3261 domdoc_getElementsByTagName,
3262 domdoc_createNode,
3263 domdoc_nodeFromID,
3264 domdoc_load,
3265 domdoc_get_readyState,
3266 domdoc_get_parseError,
3267 domdoc_get_url,
3268 domdoc_get_async,
3269 domdoc_put_async,
3270 domdoc_abort,
3271 domdoc_loadXML,
3272 domdoc_save,
3273 domdoc_get_validateOnParse,
3274 domdoc_put_validateOnParse,
3275 domdoc_get_resolveExternals,
3276 domdoc_put_resolveExternals,
3277 domdoc_get_preserveWhiteSpace,
3278 domdoc_put_preserveWhiteSpace,
3279 domdoc_put_onreadystatechange,
3280 domdoc_put_onDataAvailable,
3281 domdoc_put_onTransformNode,
3282 domdoc_get_namespaces,
3283 domdoc_get_schemas,
3284 domdoc_putref_schemas,
3285 domdoc_validate,
3286 domdoc_setProperty,
3287 domdoc_getProperty,
3288 domdoc_validateNode,
3289 domdoc_importNode
3290};
3291
3292/* IConnectionPointContainer */
3294 REFIID riid, void **ppv)
3295{
3297 return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppv);
3298}
3299
3301{
3303 return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3304}
3305
3307{
3309 return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
3310}
3311
3313 IEnumConnectionPoints **ppEnum)
3314{
3316 FIXME("(%p)->(%p): stub\n", This, ppEnum);
3317 return E_NOTIMPL;
3318}
3319
3322{
3324 ConnectionPoint *iter;
3325
3326 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
3327
3328 *cp = NULL;
3329
3330 for(iter = This->cp_list; iter; iter = iter->next)
3331 {
3332 if (IsEqualGUID(iter->iid, riid))
3333 *cp = &iter->IConnectionPoint_iface;
3334 }
3335
3336 if (*cp)
3337 {
3338 IConnectionPoint_AddRef(*cp);
3339 return S_OK;
3340 }
3341
3342 FIXME("unsupported riid %s\n", debugstr_guid(riid));
3344
3345}
3346
3347static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl =
3348{
3354};
3355
3356/* IConnectionPoint */
3358 REFIID riid, void **ppv)
3359{
3361
3362 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv );
3363
3364 *ppv = NULL;
3365
3366 if (IsEqualGUID(&IID_IUnknown, riid) ||
3368 {
3369 *ppv = iface;
3370 }
3371
3372 if (*ppv)
3373 {
3374 IConnectionPoint_AddRef(iface);
3375 return S_OK;
3376 }
3377
3378 WARN("Unsupported interface %s\n", debugstr_guid(riid));
3379 return E_NOINTERFACE;
3380}
3381
3383{
3385 return IConnectionPointContainer_AddRef(This->container);
3386}
3387
3389{
3391 return IConnectionPointContainer_Release(This->container);
3392}
3393
3395{
3397
3398 TRACE("(%p)->(%p)\n", This, iid);
3399
3400 if (!iid) return E_POINTER;
3401
3402 *iid = *This->iid;
3403 return S_OK;
3404}
3405
3408{
3410
3411 TRACE("(%p)->(%p)\n", This, container);
3412
3413 if (!container) return E_POINTER;
3414
3415 *container = This->container;
3416 IConnectionPointContainer_AddRef(*container);
3417 return S_OK;
3418}
3419
3421 DWORD *cookie)
3422{
3424 IUnknown *sink;
3425 HRESULT hr;
3426 DWORD i;
3427
3428 TRACE("(%p)->(%p %p)\n", This, unk_sink, cookie);
3429
3430 hr = IUnknown_QueryInterface(unk_sink, This->iid, (void**)&sink);
3432 hr = IUnknown_QueryInterface(unk_sink, &IID_IDispatch, (void**)&sink);
3433 if(FAILED(hr))
3435
3436 if(This->sinks)
3437 {
3438 for (i = 0; i < This->sinks_size; i++)
3439 if (!This->sinks[i].unk)
3440 break;
3441
3442 if (i == This->sinks_size)
3443 This->sinks = heap_realloc(This->sinks,(++This->sinks_size)*sizeof(*This->sinks));
3444 }
3445 else
3446 {
3447 This->sinks = heap_alloc(sizeof(*This->sinks));
3448 This->sinks_size = 1;
3449 i = 0;
3450 }
3451
3452 This->sinks[i].unk = sink;
3453 if (cookie)
3454 *cookie = i+1;
3455
3456 return S_OK;
3457}
3458
3460{
3462
3463 TRACE("(%p)->(%d)\n", This, cookie);
3464
3465 if (cookie == 0 || cookie > This->sinks_size || !This->sinks[cookie-1].unk)
3467
3468 IUnknown_Release(This->sinks[cookie-1].unk);
3469 This->sinks[cookie-1].unk = NULL;
3470
3471 return S_OK;
3472}
3473
3475 IEnumConnections **ppEnum)
3476{
3478 FIXME("(%p)->(%p): stub\n", This, ppEnum);
3479 return E_NOTIMPL;
3480}
3481
3482static const IConnectionPointVtbl ConnectionPointVtbl =
3483{
3492};
3493
3494static void ConnectionPoint_Init(ConnectionPoint *cp, struct domdoc *doc, REFIID riid)
3495{
3496 cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
3497 cp->doc = doc;
3498 cp->iid = riid;
3499 cp->sinks = NULL;
3500 cp->sinks_size = 0;
3501
3502 cp->next = doc->cp_list;
3503 doc->cp_list = cp;
3504
3505 cp->container = &doc->IConnectionPointContainer_iface;
3506}
3507
3508/* domdoc implementation of IObjectWithSite */
3509static HRESULT WINAPI
3510domdoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
3511{
3512 domdoc *This = impl_from_IObjectWithSite(iface);
3513 return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppvObject);
3514}
3515
3516static ULONG WINAPI domdoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
3517{
3518 domdoc *This = impl_from_IObjectWithSite(iface);
3519 return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3520}
3521
3522static ULONG WINAPI domdoc_ObjectWithSite_Release( IObjectWithSite* iface )
3523{
3524 domdoc *This = impl_from_IObjectWithSite(iface);
3525 return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
3526}
3527
3528static HRESULT WINAPI domdoc_ObjectWithSite_GetSite( IObjectWithSite *iface, REFIID iid, void **ppvSite )
3529{
3530 domdoc *This = impl_from_IObjectWithSite(iface);
3531
3532 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
3533
3534 if ( !This->site )
3535 return E_FAIL;
3536
3537 return IUnknown_QueryInterface( This->site, iid, ppvSite );
3538}
3539
3540static HRESULT WINAPI domdoc_ObjectWithSite_SetSite( IObjectWithSite *iface, IUnknown *punk )
3541{
3542 domdoc *This = impl_from_IObjectWithSite(iface);
3543
3544 TRACE("(%p)->(%p)\n", iface, punk);
3545
3546 if(!punk)
3547 {
3548 if(This->site)
3549 {
3550 IUnknown_Release( This->site );
3551 This->site = NULL;
3552 }
3553
3554 return S_OK;
3555 }
3556
3557 IUnknown_AddRef( punk );
3558
3559 if(This->site)
3560 IUnknown_Release( This->site );
3561
3562 This->site = punk;
3563
3564 return S_OK;
3565}
3566
3567static const IObjectWithSiteVtbl domdocObjectSite =
3568{
3569 domdoc_ObjectWithSite_QueryInterface,
3570 domdoc_ObjectWithSite_AddRef,
3571 domdoc_ObjectWithSite_Release,
3572 domdoc_ObjectWithSite_SetSite,
3573 domdoc_ObjectWithSite_GetSite
3574};
3575
3576static HRESULT WINAPI domdoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
3577{
3578 domdoc *This = impl_from_IObjectSafety(iface);
3579 return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppv);
3580}
3581
3582static ULONG WINAPI domdoc_Safety_AddRef(IObjectSafety *iface)
3583{
3584 domdoc *This = impl_from_IObjectSafety(iface);
3585 return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3586}
3587
3588static ULONG WINAPI domdoc_Safety_Release(IObjectSafety *iface)
3589{
3590 domdoc *This = impl_from_IObjectSafety(iface);
3591 return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
3592}
3593
3594#define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3595
3596static HRESULT WINAPI domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
3597 DWORD *supported, DWORD *enabled)
3598{
3599 domdoc *This = impl_from_IObjectSafety(iface);
3600
3601 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), supported, enabled);
3602
3603 if(!supported || !enabled) return E_POINTER;
3604
3605 *supported = SAFETY_SUPPORTED_OPTIONS;
3606 *enabled = This->safeopt;
3607
3608 return S_OK;
3609}
3610
3611static HRESULT WINAPI domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
3613{
3614 domdoc *This = impl_from_IObjectSafety(iface);
3615 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), mask, enabled);
3616
3617 if ((mask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
3618 return E_FAIL;
3619
3620 This->safeopt = (This->safeopt & ~mask) | (mask & enabled);
3621
3622 return S_OK;
3623}
3624
3625#undef SAFETY_SUPPORTED_OPTIONS
3626
3627static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
3628 domdoc_Safety_QueryInterface,
3629 domdoc_Safety_AddRef,
3630 domdoc_Safety_Release,
3631 domdoc_Safety_GetInterfaceSafetyOptions,
3632 domdoc_Safety_SetInterfaceSafetyOptions
3633};
3634
3635static const tid_t domdoc_iface_tids[] = {
3637 0
3638};
3639
3640static dispex_static_data_t domdoc_dispex = {
3641 NULL,
3643 NULL,
3644 domdoc_iface_tids
3645};
3646
3647HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
3648{
3649 domdoc *doc;
3650
3651 doc = heap_alloc( sizeof (*doc) );
3652 if( !doc )
3653 return E_OUTOFMEMORY;
3654
3655 doc->IXMLDOMDocument3_iface.lpVtbl = &XMLDOMDocument3Vtbl;
3656 doc->IPersistStreamInit_iface.lpVtbl = &xmldoc_IPersistStreamInit_VTable;
3657 doc->IObjectWithSite_iface.lpVtbl = &domdocObjectSite;
3658 doc->IObjectSafety_iface.lpVtbl = &domdocObjectSafetyVtbl;
3659 doc->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
3660 doc->ref = 1;
3661 doc->async = VARIANT_TRUE;
3662 doc->validating = 0;
3663 doc->resolving = 0;
3664 doc->properties = properties_from_xmlDocPtr(xmldoc);
3665 doc->error = S_OK;
3666 doc->site = NULL;
3667 doc->safeopt = 0;
3668 doc->cp_list = NULL;
3669 doc->namespaces = NULL;
3670 memset(doc->events, 0, sizeof(doc->events));
3671
3672 /* events connection points */
3673 ConnectionPoint_Init(&doc->cp_dispatch, doc, &IID_IDispatch);
3674 ConnectionPoint_Init(&doc->cp_propnotif, doc, &IID_IPropertyNotifySink);
3675 ConnectionPoint_Init(&doc->cp_domdocevents, doc, &DIID_XMLDOMDocumentEvents);
3676
3677 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->IXMLDOMDocument3_iface,
3678 &domdoc_dispex);
3679
3680 *document = &doc->IXMLDOMDocument3_iface;
3681
3682 TRACE("returning iface %p\n", *document);
3683 return S_OK;
3684}
3685
3687{
3688 xmlDocPtr xmldoc;
3689 HRESULT hr;
3690
3691 TRACE("(%d, %p)\n", version, ppObj);
3692
3693 xmldoc = xmlNewDoc(NULL);
3694 if(!xmldoc)
3695 return E_OUTOFMEMORY;
3696
3697 xmldoc_init(xmldoc, version);
3698
3699 hr = get_domdoc_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
3700 if(FAILED(hr))
3701 {
3702 free_properties(properties_from_xmlDocPtr(xmldoc));
3703 heap_free(xmldoc->_private);
3704 xmlFreeDoc(xmldoc);
3705 return hr;
3706 }
3707
3708 return hr;
3709}
3710
3711IUnknown* create_domdoc( xmlNodePtr document )
3712{
3713 IUnknown *obj = NULL;
3714 HRESULT hr;
3715
3716 TRACE("(%p)\n", document);
3717
3718 hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&obj);
3719 if (FAILED(hr))
3720 return NULL;
3721
3722 return obj;
3723}
3724
3725#else
3726
3728{
3729 MESSAGE("This program tried to use a DOMDocument object, but\n"
3730 "libxml2 support was not present at compile time.\n");
3731 return E_NOTIMPL;
3732}
3733
3734#endif
XMLPUBFUN void XMLCALL xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
Definition: SAX2.c:2657
XMLPUBFUN void XMLCALL xmlSAX2EndDocument(void *ctx)
Definition: SAX2.c:998
XMLPUBFUN int XMLCALL xmlSAX2HasExternalSubset(void *ctx)
Definition: SAX2.c:307
XMLPUBFUN void XMLCALL xmlSAX2Comment(void *ctx, const xmlChar *value)
Definition: SAX2.c:2754
XMLPUBFUN void XMLCALL xmlSAX2SetDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
XMLPUBFUN void XMLCALL xmlSAX2EndElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI)
XMLPUBFUN void XMLCALL xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Definition: SAX2.c:604
XMLPUBFUN void XMLCALL xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName)
Definition: SAX2.c:849
XMLPUBFUN xmlParserInputPtr XMLCALL xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
Definition: SAX2.c:489
XMLPUBFUN void XMLCALL xmlSAX2NotationDecl(void *ctx, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId)
Definition: SAX2.c:795
XMLPUBFUN void XMLCALL xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, const xmlChar *data)
Definition: SAX2.c:2690
XMLPUBFUN void XMLCALL xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree)
Definition: SAX2.c:674
XMLPUBFUN void XMLCALL xmlSAX2InternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
Definition: SAX2.c:324
XMLPUBFUN xmlEntityPtr XMLCALL xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
Definition: SAX2.c:576
XMLPUBFUN xmlEntityPtr XMLCALL xmlSAX2GetEntity(void *ctx, const xmlChar *name)
Definition: SAX2.c:526
XMLPUBFUN void XMLCALL xmlSAX2StartDocument(void *ctx)
Definition: SAX2.c:933
XMLPUBFUN void XMLCALL xmlSAX2ExternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
Definition: SAX2.c:362
XMLPUBFUN int XMLCALL xmlSAX2IsStandalone(void *ctx)
Definition: SAX2.c:275
XMLPUBFUN void XMLCALL xmlSAX2ElementDecl(void *ctx, const xmlChar *name, int type, xmlElementContentPtr content)
Definition: SAX2.c:746
XMLPUBFUN void XMLCALL xmlSAX2Reference(void *ctx, const xmlChar *name)
Definition: SAX2.c:2488
XMLPUBFUN void XMLCALL xmlSAX2StartElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)
Definition: SAX2.c:2195
XMLPUBFUN int XMLCALL xmlSAX2HasInternalSubset(void *ctx)
Definition: SAX2.c:291
XMLPUBFUN void XMLCALL xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
Definition: SAX2.c:2816
Type
Definition: Type.h:7
#define isspace(c)
Definition: acclib.h:69
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define read
Definition: acwin.h:96
static int state
Definition: maze.c:121
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
const GUID IID_IUnknown
HRESULT create_uri(const WCHAR *, DWORD, IUri **) DECLSPEC_HIDDEN
Definition: persist.c:158
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
HRESULT detach_bsc(bsc_t *bsc)
Definition: bsc.c:331
HRESULT bind_url(IMoniker *mon, HRESULT(*onDataAvailable)(void *, char *, DWORD), void *obj, bsc_t **ret)
Definition: bsc.c:288
struct _root root
Definition: list.h:37
static void ConnectionPoint_Init(ConnectionPoint *cp, ConnectionPointContainer *container, REFIID riid, cp_static_data_t *data)
Definition: conpoint.c:290
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define E_PENDING
Definition: dinput.h:172
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static IFilterGraphImpl * impl_from_IObjectWithSite(IObjectWithSite *iface)
Definition: filtergraph.c:2896
content
Definition: atl_ax.c:994
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
OLECHAR * BSTR
Definition: compat.h:2293
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define WideCharToMultiByte
Definition: compat.h:111
short VARIANT_BOOL
Definition: compat.h:2290
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_BSTR
Definition: compat.h:2303
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_ARRAY
Definition: compat.h:2341
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
static const WCHAR version[]
Definition: asmname.c:66
static ConnectionPoint * impl_from_IConnectionPoint(IConnectionPoint *iface)
Definition: events.c:126
static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, DWORD *pdwCookie)
Definition: events.c:303
static ConnectionPointContainer * impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
Definition: events.c:48
static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
Definition: events.c:281
static const IConnectionPointVtbl ConnectionPointVtbl
Definition: events.c:379
static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, LPVOID *ppv)
Definition: events.c:245
static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
Definition: events.c:341
static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, LPVOID *ppv)
Definition: events.c:53
static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
Definition: events.c:112
static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
Definition: events.c:60
static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, LPENUMCONNECTIONPOINTS *ppEnum)
Definition: events.c:72
static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, LPCONNECTIONPOINT *ppCP)
Definition: events.c:80
static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface, IConnectionPointContainer **ppCPC)
Definition: events.c:291
static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, IEnumConnections **ppEnum)
Definition: events.c:356
static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
Definition: events.c:269
static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
Definition: events.c:66
static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
Definition: events.c:275
static JScript * impl_from_IObjectSafety(IObjectSafety *iface)
Definition: jscript.c:952
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static const WCHAR documentW[]
Definition: script.c:47
const WCHAR * text
Definition: package.c:1799
HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
Definition: domdoc.c:3727
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
#define assert(x)
Definition: debug.h:53
#define get_node_type(n)
Definition: dom.c:1111
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
r parent
Definition: btrfs.c:3010
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
xmlCharEncoding
Definition: encoding.h:56
@ XML_CHAR_ENCODING_UTF8
Definition: encoding.h:59
@ XML_CHAR_ENCODING_UTF16LE
Definition: encoding.h:60
@ XML_CHAR_ENCODING_NONE
Definition: encoding.h:58
#define XMLCALL
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define local
Definition: zutil.h:30
FxCollectionEntry * cur
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _cl_event * event
Definition: glext.h:7739
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
eventid_t
Definition: htmlevent.h:21
@ EVENTID_DATAAVAILABLE
Definition: htmlevent.h:28
@ EVENTID_LAST
Definition: htmlevent.h:52
@ EVENTID_READYSTATECHANGE
Definition: htmlevent.h:47
static HRESULT set_doc_event(HTMLDocument *doc, eventid_t eid, VARIANT *var)
Definition: htmlevent.h:90
static HRESULT create_node(HTMLDocumentNode *, nsIDOMNode *, HTMLDOMNode **)
Definition: htmlnode.c:1216
static HTMLDOMNode * get_node_obj(IHTMLDOMNode *)
Definition: htmlnode.c:1045
static WebBrowser * impl_from_IPersistStreamInit(IPersistStreamInit *iface)
Definition: persist.c:200
static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
Definition: persist.c:251
static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
Definition: persist.c:259
static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
Definition: persist.c:212
static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
Definition: persist.c:230
static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
Definition: persist.c:218
static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
Definition: persist.c:224
static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStg)
Definition: persist.c:236
static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStg, BOOL fSameAsLoad)
Definition: persist.c:243
static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, LPVOID *ppobj)
Definition: persist.c:205
tid_t
Definition: ieframe.h:311
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define b
Definition: ke_i.h:79
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
POINT cp
Definition: magnifier.c:59
const WCHAR * schema
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MESSAGE
Definition: options.h:86
#define CREATE_ALWAYS
Definition: disk.h:72
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HANDLE events[2]
Definition: event.c:4
#define comment(fmt, arg1)
Definition: rebar.c:820
const IID IID_IObjectWithSite
static const WCHAR url[]
Definition: encode.c:1432
const char * var
Definition: shader.c:5666
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static IActiveScriptSite * site
Definition: script.c:149
static LPOLESTR
Definition: stg_prop.c:27
static ICollection collection
Definition: typelib.c:184
static refpint_t pi[]
Definition: server.c:96
static VARIANTARG static DISPID
Definition: ordinal.c:52
const char * uri
Definition: sec_mgr.c:1588
static IBindStatusCallbackEx bsc
Definition: url.c:2150
static HWND child
Definition: cursoricon.c:298
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
MSXML_VERSION
Definition: msxml_private.h:34
@ MSXML_DEFAULT
Definition: msxml_private.h:35
@ MSXML4
Definition: msxml_private.h:39
@ MSXML6
Definition: msxml_private.h:40
@ MSXML26
Definition: msxml_private.h:37
#define NODE_PRIV_TRAILING_IGNORABLE_WS
@ IXMLDOMNode_tid
Definition: msxml_private.h:58
@ IXMLDOMDocument3_tid
Definition: msxml_private.h:51
@ IXMLDOMDocument2_tid
Definition: msxml_private.h:50
@ NULL_tid
Definition: msxml_private.h:45
@ IXMLDOMDocument_tid
Definition: msxml_private.h:49
static HRESULT return_null_bstr(BSTR *p)
static const CLSID * DOMDocument_version(MSXML_VERSION v)
static HRESULT return_null_var(VARIANT *p)
IXMLDOMParseError * create_parseError(LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos) DECLSPEC_HIDDEN
Definition: parseerror.c:329
static HRESULT return_bstr(const WCHAR *value, BSTR *p)
static HRESULT return_null_ptr(void **p)
#define NODE_PRIV_CHILD_IGNORABLE_WS
HRESULT SchemaCache_create(MSXML_VERSION, void **) DECLSPEC_HIDDEN
Definition: schema.c:1647
static HRESULT return_null_node(IXMLDOMNode **p)
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_WRITE
Definition: nt_native.h:90
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_I1(A)
Definition: oleauto.h:243
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define CONNECT_E_CANNOTCONNECT
Definition: olectl.h:253
#define CONNECT_E_NOCONNECTION
Definition: olectl.h:251
const GUID IID_IConnectionPointContainer
const GUID IID_IConnectionPoint
const GUID IID_IPropertyNotifySink
const GUID IID_IDispatch
const GUID IID_IPersistStreamInit
XMLPUBFUN int XMLCALL xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlCreateMemoryParserCtxt(const char *buffer, int size)
Definition: parser.c:14339
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
#define strlenW(s)
Definition: unicode.h:28
#define isspaceW(n)
Definition: unicode.h:52
#define err(...)
static char tagname[200]
Definition: rgenstat.c:63
const WCHAR * str
DWORD LCID
Definition: nls.h:13
#define CP_UTF8
Definition: nls.h:20
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10697
XMLPUBFUN xmlNodePtr XMLCALL xmlNewReference(const xmlDoc *doc, const xmlChar *name)
XMLPUBFUN void XMLCALL xmlBufferFree(xmlBufferPtr buf)
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
XMLPUBFUN int XMLCALL xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
XMLPUBFUN xmlNodePtr XMLCALL xmlCopyNode(xmlNodePtr node, int recursive)
XMLPUBFUN int XMLCALL xmlNodeGetSpacePreserve(const xmlNode *cur)
XMLPUBFUN void XMLCALL xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content)
xmlNode * xmlNodePtr
Definition: tree.h:488
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
XMLPUBFUN void XMLCALL xmlSetNs(xmlNodePtr node, xmlNsPtr ns)
XMLPUBFUN xmlAttrPtr XMLCALL xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value)
XMLPUBFUN xmlDtdPtr XMLCALL xmlGetIntSubset(const xmlDoc *doc)
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_PI_NODE
Definition: tree.h:166
@ XML_ELEMENT_NODE
Definition: tree.h:160
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
XMLPUBFUN xmlBufferPtr XMLCALL xmlBufferCreate(void)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content)
xmlParserCtxt * xmlParserCtxtPtr
Definition: tree.h:39
@ XML_DOC_WELLFORMED
Definition: tree.h:533
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocText(const xmlDoc *doc, const xmlChar *content)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocComment(xmlDocPtr doc, const xmlChar *content)
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
XMLPUBFUN int XMLCALL xmlBufferLength(const xmlBuffer *buf)
struct _xmlNode xmlNode
Definition: tree.h:487
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
XMLPUBFUN xmlChar *XMLCALL xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IConnectionPointContainer * container
Definition: events.c:36
IConnectionPoint IConnectionPoint_iface
Definition: events.c:34
DWORD sinks_size
Definition: events.c:39
IPropertyNotifySink * propnotif
IDispatch ** sinks
Definition: events.c:38
IDispatch * disp
Definition: tree.h:551
const xmlChar * encoding
Definition: tree.h:574
const xmlChar * version
Definition: tree.h:573
void * _private
Definition: tree.h:552
int properties
Definition: tree.h:584
int standalone
Definition: tree.h:564
struct _xmlNode * children
Definition: tree.h:555
Definition: tree.h:406
Definition: tree.h:489
void * _private
Definition: tree.h:490
struct _xmlDoc * doc
Definition: tree.h:498
const xmlChar * name
Definition: tree.h:492
struct _xmlNode * last
Definition: tree.h:494
xmlElementType type
Definition: tree.h:491
struct _xmlNode * parent
Definition: tree.h:495
Definition: tree.h:389
int wellFormed
Definition: parser.h:188
void * _private
Definition: parser.h:256
struct _xmlSAXHandler * sax
Definition: parser.h:185
xmlDocPtr myDoc
Definition: parser.h:187
int recovery
Definition: parser.h:261
xmlNodePtr node
Definition: parser.h:205
xmlParserInputPtr input
Definition: parser.h:199
const xmlChar * cur
Definition: parser.h:59
Definition: bsc.c:46
Definition: cookie.c:34
Definition: name.c:39
Definition: mxnamespace.c:45
BSTR prefix
Definition: mxnamespace.c:46
Definition: send.c:34
Definition: send.c:48
Definition: parse.h:23
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI CreateURLMonikerEx2(IMoniker *pmkContext, IUri *pUri, IMoniker **ppmk, DWORD dwFlags)
Definition: umon.c:668
Definition: dlist.c:348
Definition: pdh_main.c:94
xmlValidCtxt * xmlValidCtxtPtr
Definition: valid.h:81
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
int ret
#define success(from, fromstr, to, tostr)
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
enum tagDOMNodeType DOMNodeType
@ NODE_ENTITY_REFERENCE
Definition: xmldom.idl:57
@ NODE_TEXT
Definition: xmldom.idl:55
@ NODE_PROCESSING_INSTRUCTION
Definition: xmldom.idl:59
@ NODE_DOCUMENT_TYPE
Definition: xmldom.idl:62
@ NODE_ENTITY
Definition: xmldom.idl:58
@ NODE_ATTRIBUTE
Definition: xmldom.idl:54
@ NODE_DOCUMENT
Definition: xmldom.idl:61
@ NODE_DOCUMENT_FRAGMENT
Definition: xmldom.idl:63
@ NODE_COMMENT
Definition: xmldom.idl:60
@ NODE_ELEMENT
Definition: xmldom.idl:53
@ NODE_CDATA_SECTION
Definition: xmldom.idl:56
@ NODE_NOTATION
Definition: xmldom.idl:64
static char * encoding
Definition: xmllint.c:155
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN xmlChar *XMLCALL xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:446
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:213
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
unsigned char BYTE
Definition: xxhash.c:193