ReactOS  0.4.14-dev-998-g623dd26
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>
31 # include <libxml/xpathInternals.h>
32 # include <libxml/xmlsave.h>
33 # include <libxml/SAX2.h>
34 # include <libxml/parserInternals.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 
67 static const WCHAR PropertySelectionLanguageW[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
68 static const WCHAR PropertySelectionNamespacesW[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
69 static const WCHAR PropertyProhibitDTDW[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
70 static const WCHAR PropertyNewParserW[] = {'N','e','w','P','a','r','s','e','r',0};
71 static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
72 static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
73 static const WCHAR PropertyResolveExternalsW[] = {'R','e','s','o','l','v','e','E','x','t','e','r','n','a','l','s',0};
74 static const WCHAR PropertyAllowXsltScriptW[] = {'A','l','l','o','w','X','s','l','t','S','c','r','i','p','t',0};
75 static 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};
76 static 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. */
82 typedef 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 
93 typedef struct ConnectionPoint ConnectionPoint;
94 typedef struct domdoc domdoc;
95 
96 struct ConnectionPoint
97 {
99  const IID *iid;
100 
103  domdoc *doc;
104 
105  union
106  {
107  IUnknown *unk;
108  IDispatch *disp;
110  } *sinks;
112 };
113 
114 typedef enum {
117  EVENTID_TRANSFORMNODE,
119 } eventid_t;
120 
121 struct 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;
134  HRESULT error;
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 
154 static 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 
207 typedef struct _xmldoc_priv {
208  LONG refs;
209  struct list orphans;
210  domdoc_properties* properties;
211 } xmldoc_priv;
212 
213 typedef struct _orphan_entry {
214  struct list entry;
215  xmlNode * node;
216 } orphan_entry;
217 
218 typedef 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 
226 static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc)
227 {
228  return doc->_private;
229 }
230 
231 static inline domdoc_properties * properties_from_xmlDocPtr(xmlDocPtr doc)
232 {
233  return priv_from_xmlDocPtr(doc)->properties;
234 }
235 
236 BOOL is_xpathmode(const xmlDocPtr doc)
237 {
238  return properties_from_xmlDocPtr(doc)->XPath;
239 }
240 
241 void set_xpathmode(xmlDocPtr doc, BOOL xpath)
242 {
243  properties_from_xmlDocPtr(doc)->XPath = xpath;
244 }
245 
246 int 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 
263 static 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 
273 static 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 
288 static 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 
308 static 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 
347 static 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 
361 static 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 */
371 void 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 */
378 xmlNodePtr 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;
391  xmlUnlinkNode( node );
392  }
393  else
394  node = NULL;
395 
396  return node;
397 }
398 
399 MSXML_VERSION xmldoc_version(xmlDocPtr doc)
400 {
401  return properties_from_xmlDocPtr(doc)->version;
402 }
403 
404 BOOL 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 
414 static 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 
423 static 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 
466 static 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 
474 static 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 
482 static void sax_serror(void* ctx, xmlErrorPtr err)
483 {
484  LIBXML2_CALLBACK_SERROR(doparse, err);
485 }
486 
487 static 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 
587 void xmldoc_init(xmlDocPtr doc, MSXML_VERSION version)
588 {
589  doc->_private = create_priv();
590  priv_from_xmlDocPtr(doc)->properties = create_properties(version);
591 }
592 
593 LONG 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 
600 LONG xmldoc_add_ref(xmlDocPtr doc)
601 {
602  return xmldoc_add_refs(doc, 1);
603 }
604 
605 LONG 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 
633 LONG xmldoc_release(xmlDocPtr doc)
634 {
635  return xmldoc_release_refs(doc, 1);
636 }
637 
638 HRESULT 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 
652 HRESULT 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 
670 static inline xmlDocPtr get_doc( domdoc *This )
671 {
672  return This->node.node->doc;
673 }
674 
675 static 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 
698 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
699 {
700  return CONTAINING_RECORD(iface, domdoc, IXMLDOMDocument3_iface);
701 }
702 
703 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
704 {
705  return CONTAINING_RECORD(iface, domdoc, IPersistStreamInit_iface);
706 }
707 
708 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
709 {
710  return CONTAINING_RECORD(iface, domdoc, IObjectWithSite_iface);
711 }
712 
713 static 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 
769 static 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 
869 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
870 {
880 };
881 
882 /* IXMLDOMDocument3 interface */
883 
884 static const tid_t domdoc_se_tids[] = {
889  NULL_tid
890 };
891 
892 static 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 
945 static ULONG WINAPI domdoc_AddRef( IXMLDOMDocument3 *iface )
946 {
947  domdoc *This = impl_from_IXMLDOMDocument3( iface );
948  ULONG ref = InterlockedIncrement( &This->ref );
949  TRACE("(%p)->(%d)\n", This, ref );
950  return ref;
951 }
952 
953 static ULONG WINAPI domdoc_Release( IXMLDOMDocument3 *iface )
954 {
955  domdoc *This = impl_from_IXMLDOMDocument3( iface );
956  LONG ref = InterlockedDecrement( &This->ref );
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);
972  heap_free(This);
973  }
974 
975  return ref;
976 }
977 
978 static 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 
984 static 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 
992 static 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 
1005 static 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 
1021 static 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 
1035 static 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 
1052 static 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 
1062 static 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 
1070  *type = NODE_DOCUMENT;
1071  return S_OK;
1072 }
1073 
1074 
1075 static HRESULT WINAPI domdoc_get_parentNode(
1076  IXMLDOMDocument3 *iface,
1077  IXMLDOMNode** parent )
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 
1087 static 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 
1099 static 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 
1111 static 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 
1123 static 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 
1135 static 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 
1147 static 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 
1159 static HRESULT WINAPI domdoc_insertBefore(
1160  IXMLDOMDocument3 *iface,
1161  IXMLDOMNode* newChild,
1162  VARIANT refChild,
1163  IXMLDOMNode** outNewChild )
1164 {
1165  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1166  DOMNodeType type;
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 
1187 static 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 
1201 static HRESULT WINAPI domdoc_removeChild(
1202  IXMLDOMDocument3 *iface,
1203  IXMLDOMNode *child,
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 
1212 static HRESULT WINAPI domdoc_appendChild(
1213  IXMLDOMDocument3 *iface,
1214  IXMLDOMNode *child,
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 
1223 static HRESULT WINAPI domdoc_hasChildNodes(
1224  IXMLDOMDocument3 *iface,
1225  VARIANT_BOOL *ret)
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 
1233 static 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 
1243 static 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 
1277 static 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 
1290 static 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 
1300 static 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 
1310 static 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 
1321 static 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 
1331 static 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 
1340 static 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 
1350 static 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 
1360 static 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 
1374 static 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 
1379 static HRESULT WINAPI domdoc_get_xml(
1380  IXMLDOMDocument3 *iface,
1381  BSTR* p)
1382 {
1383  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1384  xmlSaveCtxtPtr ctxt;
1385  xmlBufferPtr buf;
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  {
1405  xmlBufferFree(buf);
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 
1428  xmlBufferFree(buf);
1429 
1430  return *p ? S_OK : E_OUTOFMEMORY;
1431 }
1432 
1433 
1434 static HRESULT WINAPI domdoc_transformNode(
1435  IXMLDOMDocument3 *iface,
1436  IXMLDOMNode *node,
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 
1445 static 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 
1456 static 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 
1467 static 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 
1477 static 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 
1486 static 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 
1496 static 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 
1506 static 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  {
1530  VARIANT_BOOL b;
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);
1537  SysFreeString(str);
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 
1555 static HRESULT WINAPI domdoc_get_doctype(
1556  IXMLDOMDocument3 *iface,
1557  IXMLDOMDocumentType** doctype )
1558 {
1559  domdoc *This = impl_from_IXMLDOMDocument3(iface);
1560  IXMLDOMNode *node;
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 
1583 static 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 
1599 static HRESULT WINAPI domdoc_get_documentElement(
1600  IXMLDOMDocument3 *iface,
1601  IXMLDOMElement** DOMElement )
1602 {
1603  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1604  IXMLDOMNode *element_node;
1605  xmlNodePtr root;
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 
1629 static 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 
1671 static HRESULT WINAPI domdoc_createElement(
1672  IXMLDOMDocument3 *iface,
1673  BSTR tagname,
1675 {
1676  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1677  IXMLDOMNode *node;
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;
1686  V_I1(&type) = NODE_ELEMENT;
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 
1699 static HRESULT WINAPI domdoc_createDocumentFragment(
1700  IXMLDOMDocument3 *iface,
1701  IXMLDOMDocumentFragment** frag )
1702 {
1703  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1704  IXMLDOMNode *node;
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 
1728 static HRESULT WINAPI domdoc_createTextNode(
1729  IXMLDOMDocument3 *iface,
1730  BSTR data,
1731  IXMLDOMText** text )
1732 {
1733  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1734  IXMLDOMNode *node;
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 
1759 static HRESULT WINAPI domdoc_createComment(
1760  IXMLDOMDocument3 *iface,
1761  BSTR data,
1763 {
1764  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1765  VARIANT type;
1766  HRESULT hr;
1767  IXMLDOMNode *node;
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;
1776  V_I1(&type) = NODE_COMMENT;
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 
1790 static HRESULT WINAPI domdoc_createCDATASection(
1791  IXMLDOMDocument3 *iface,
1792  BSTR data,
1793  IXMLDOMCDATASection** cdata )
1794 {
1795  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1796  IXMLDOMNode *node;
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 
1821 static HRESULT WINAPI domdoc_createProcessingInstruction(
1822  IXMLDOMDocument3 *iface,
1823  BSTR target,
1824  BSTR data,
1826 {
1827  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1828  IXMLDOMNode *node;
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 
1858 static HRESULT WINAPI domdoc_createAttribute(
1859  IXMLDOMDocument3 *iface,
1860  BSTR name,
1862 {
1863  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1864  IXMLDOMNode *node;
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;
1873  V_I1(&type) = NODE_ATTRIBUTE;
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 
1886 static HRESULT WINAPI domdoc_createEntityReference(
1887  IXMLDOMDocument3 *iface,
1888  BSTR name,
1889  IXMLDOMEntityReference** entityref )
1890 {
1891  domdoc *This = impl_from_IXMLDOMDocument3( iface );
1892  IXMLDOMNode *node;
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 
1915 xmlChar* 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 
1963 static 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 
2002 static 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:
2029  case NODE_ENTITY_REFERENCE:
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;
2090  case NODE_ENTITY_REFERENCE:
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 
2134 static 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 
2144 static 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 
2158 static 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 
2170 static HRESULT WINAPI domdoc_load(
2171  IXMLDOMDocument3 *iface,
2172  VARIANT source,
2173  VARIANT_BOOL* isSuccessful )
2174 {
2175  domdoc *This = impl_from_IXMLDOMDocument3( iface );
2176  LPWSTR filename = NULL;
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:
2191  filename = V_BSTR(&source);
2192  break;
2193  case VT_BSTR|VT_BYREF:
2194  if (!V_BSTRREF(&source)) return E_INVALIDARG;
2195  filename = *V_BSTRREF(&source);
2196  break;
2197  case VT_ARRAY|VT_UI1:
2198  {
2199  SAFEARRAY *psa = V_ARRAY(&source);
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  }
2220  SafeArrayGetUBound(psa, 1, &len);
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 
2304  hr = create_uri(filename, &uri);
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 
2342 static 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 
2357 static 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 
2376 static 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 
2394 static 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 
2406 static 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 
2418 static 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 */
2427 static 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 
2477 static 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 
2490 static int XMLCALL domdoc_save_closecallback(void *ctx)
2491 {
2492  return CloseHandle(ctx) ? 0 : -1;
2493 }
2494 
2495 static 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 
2511 static int XMLCALL domdoc_stream_save_closecallback(void *ctx)
2512 {
2513  IStream_Release((IStream*)ctx);
2514  return 0;
2515 }
2516 
2517 static 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),
2577  if( handle == INVALID_HANDLE_VALUE )
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 
2609 static 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 
2620 static 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 
2631 static 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 
2642 static 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 
2653 static 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 
2664 static 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 
2675 static 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 
2686 static 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 
2693 static 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 
2700 static 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 
2728 static 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 */
2740  V_DISPATCH(schema) = NULL;
2741 
2742  if(cur_schema)
2743  {
2744  hr = IXMLDOMSchemaCollection2_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(schema));
2745  if(SUCCEEDED(hr))
2746  V_VT(schema) = VT_DISPATCH;
2747  }
2748  return hr;
2749 }
2750 
2751 static HRESULT WINAPI domdoc_putref_schemas(
2752  IXMLDOMDocument3* iface,
2753  VARIANT schema)
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 
2794 static 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 */
2800  xmlNodePtr child;
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 
2824 static 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 
2832 static 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 
2840 static HRESULT WINAPI domdoc_validateNode(
2841  IXMLDOMDocument3* iface,
2842  IXMLDOMNode* node,
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 
2940 static 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 
2949 static 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 
3133 static 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 
3193 static HRESULT WINAPI domdoc_importNode(
3194  IXMLDOMDocument3* iface,
3195  IXMLDOMNode* node,
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 
3204 static 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 {
3296  domdoc *This = impl_from_IConnectionPointContainer(iface);
3297  return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppv);
3298 }
3299 
3301 {
3302  domdoc *This = impl_from_IConnectionPointContainer(iface);
3303  return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3304 }
3305 
3307 {
3308  domdoc *This = impl_from_IConnectionPointContainer(iface);
3309  return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
3310 }
3311 
3313  IEnumConnectionPoints **ppEnum)
3314 {
3315  domdoc *This = impl_from_IConnectionPointContainer(iface);
3316  FIXME("(%p)->(%p): stub\n", This, ppEnum);
3317  return E_NOTIMPL;
3318 }
3319 
3322 {
3323  domdoc *This = impl_from_IConnectionPointContainer(iface);
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));
3343  return CONNECT_E_NOCONNECTION;
3344 
3345 }
3346 
3347 static 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))
3434  return CONNECT_E_CANNOTCONNECT;
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)
3466  return CONNECT_E_NOCONNECTION;
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 
3482 static const IConnectionPointVtbl ConnectionPointVtbl =
3483 {
3492 };
3493 
3494 static 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 */
3509 static HRESULT WINAPI
3510 domdoc_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 
3516 static ULONG WINAPI domdoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
3517 {
3518  domdoc *This = impl_from_IObjectWithSite(iface);
3519  return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3520 }
3521 
3522 static ULONG WINAPI domdoc_ObjectWithSite_Release( IObjectWithSite* iface )
3523 {
3524  domdoc *This = impl_from_IObjectWithSite(iface);
3525  return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface);
3526 }
3527 
3528 static 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 
3540 static 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 
3567 static 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 
3576 static 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 
3582 static ULONG WINAPI domdoc_Safety_AddRef(IObjectSafety *iface)
3583 {
3584  domdoc *This = impl_from_IObjectSafety(iface);
3585  return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface);
3586 }
3587 
3588 static 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 
3596 static 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 
3611 static 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 
3627 static 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 
3635 static const tid_t domdoc_iface_tids[] = {
3637  0
3638 };
3639 
3640 static dispex_static_data_t domdoc_dispex = {
3641  NULL,
3643  NULL,
3644  domdoc_iface_tids
3645 };
3646 
3647 HRESULT 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 
3711 IUnknown* 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
static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
Definition: persist.c:251
XMLPUBFUN void XMLCALL xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content)
static HRESULT return_bstr(const WCHAR *value, BSTR *p)
disp
Definition: i386-dis.c:3181
XMLPUBFUN void XMLCALL xmlSAX2Comment(void *ctx, const xmlChar *value)
Definition: SAX2.c:2742
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 ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
Definition: persist.c:212
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
#define isspace(c)
Definition: acclib.h:69
static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStg, BOOL fSameAsLoad)
Definition: persist.c:243
IConnectionPointContainer * container
Definition: events.c:36
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define CloseHandle
Definition: compat.h:406
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
static const IConnectionPointVtbl ConnectionPointVtbl
Definition: events.c:379
#define E_NOINTERFACE
Definition: winerror.h:2364
XMLPUBFUN xmlAttrPtr XMLCALL xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value)
Definition: compat.h:1947
int properties
Definition: tree.h:584
XMLPUBFUN int XMLCALL xmlSAX2HasExternalSubset(void *ctx)
Definition: SAX2.c:337
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
Definition: send.c:33
XMLPUBFUN const xmlChar *XMLCALL xmlBufferContent(const xmlBuffer *buf)
Type
Definition: Type.h:6
static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl
Definition: events.c:112
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
#define MESSAGE
Definition: options.h:86
const xmlChar * name
Definition: tree.h:492
const xmlChar * version
Definition: tree.h:573
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
static IActiveScriptSite * site
Definition: script.c:149
Definition: compat.h:1959
XMLPUBFUN void XMLCALL xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target, const xmlChar *data)
Definition: SAX2.c:2678
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CONNECT_E_CANNOTCONNECT
Definition: olectl.h:253
IConnectionPoint IConnectionPoint_iface
Definition: events.c:34
const char * uri
Definition: sec_mgr.c:1594
REFIID riid
Definition: precomp.h:44
Definition: tree.h:389
void * _private
Definition: tree.h:490
XMLPUBFUN void XMLCALL xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
Definition: SAX2.c:2532
const WCHAR * text
Definition: package.c:1827
HRESULT SchemaCache_create(MSXML_VERSION, void **) DECLSPEC_HIDDEN
Definition: schema.c:1647
WINE_UNICODE_INLINE int isspaceW(WCHAR wc)
Definition: unicode.h:165
XMLPUBFUN xmlNodePtr XMLCALL xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len)
tid_t
Definition: ieframe.h:311
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:422
struct _root root
#define V_ARRAY(A)
Definition: oleauto.h:222
#define WARN(fmt,...)
Definition: debug.h:111
#define CONNECT_E_NOCONNECTION
Definition: olectl.h:251
#define get_node_type(n)
Definition: dom.c:1111
XMLPUBFUN void XMLCALL xmlBufferFree(xmlBufferPtr buf)
XMLPUBFUN void XMLCALL xmlSAX2StartDocument(void *ctx)
Definition: SAX2.c:983
GLintptr offset
Definition: glext.h:5920
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
REFIID LPVOID * ppv
Definition: atlbase.h:39
const GUID IID_IConnectionPointContainer
const xmlChar * cur
Definition: parser.h:61
GLdouble n
Definition: glext.h:7729
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define assert(x)
Definition: debug.h:53
xmlValidityErrorFunc error
Definition: valid.h:84
XMLPUBFUN void XMLCALL xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
GLuint buffer
Definition: glext.h:5915
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
xmlCharEncoding
Definition: encoding.h:58
static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
Definition: persist.c:259
DWORD LCID
Definition: nls.h:13
XMLPUBFUN void XMLCALL xmlSAX2EndDocument(void *ctx)
Definition: SAX2.c:1048
static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface, IConnectionPointContainer **ppCPC)
Definition: events.c:291
OLECHAR * BSTR
Definition: compat.h:1942
XMLPUBFUN void XMLCALL xmlSAX2ElementDecl(void *ctx, const xmlChar *name, int type, xmlElementContentPtr content)
Definition: SAX2.c:802
XMLPUBFUN void XMLCALL xmlSAX2NotationDecl(void *ctx, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId)
Definition: SAX2.c:848
static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
Definition: persist.c:230
XMLPUBFUN void XMLCALL xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
Definition: SAX2.c:664
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
const char * filename
Definition: ioapi.h:135
static LPOLESTR
Definition: stg_prop.c:27
#define E_FAIL
Definition: ddrawi.h:102
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
short VARIANT_BOOL
Definition: compat.h:1939
Definition: send.c:47
static HWND child
Definition: cursoricon.c:298
XMLPUBFUN xmlBufferPtr XMLCALL xmlBufferCreate(void)
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, LPVOID *ppobj)
Definition: persist.c:205
IPropertyNotifySink * propnotif
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlCreateMemoryParserCtxt(const char *buffer, int size)
Definition: parser.c:14369
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
XMLPUBFUN xmlNodePtr XMLCALL xmlCopyNode(xmlNodePtr node, int recursive)
#define V_I4(A)
Definition: oleauto.h:247
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
struct _xmlDoc * doc
Definition: tree.h:498
Definition: tree.h:406
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
#define V_DISPATCH(A)
Definition: oleauto.h:239
xmlParserInputPtr input
Definition: parser.h:199
static const CLSID * DOMDocument_version(MSXML_VERSION v)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
struct node node
int recovery
Definition: parser.h:261
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
XMLPUBFUN int XMLCALL xmlSAX2HasInternalSubset(void *ctx)
Definition: SAX2.c:321
XMLPUBFUN void XMLCALL xmlSAX2ExternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
Definition: SAX2.c:392
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
static WebBrowser * impl_from_IPersistStreamInit(IPersistStreamInit *iface)
Definition: persist.c:200
GLenum GLint GLuint mask
Definition: glext.h:6028
static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
Definition: persist.c:218
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define va_end(ap)
Definition: acmsvcex.h:90
#define CP_UTF8
Definition: nls.h:20
static void ConnectionPoint_Init(ConnectionPoint *cp, ConnectionPointContainer *container, REFIID riid, cp_static_data_t *data)
Definition: conpoint.c:290
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
unsigned int BOOL
Definition: ntddk_ex.h:94
int standalone
Definition: tree.h:564
long LONG
Definition: pedump.c:60
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:526
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
Definition: bsc.c:46
static HRESULT return_null_ptr(void **p)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocText(const xmlDoc *doc, const xmlChar *content)
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
content
Definition: atl_ax.c:993
HRESULT detach_bsc(bsc_t *bsc)
Definition: bsc.c:331
#define S_FALSE
Definition: winerror.h:2357
static IBindStatusCallbackEx bsc
Definition: url.c:2150
#define E_INVALIDARG
Definition: ddrawi.h:101
IDispatch * disp
const WCHAR * str
struct _xmlNode * last
Definition: tree.h:494
IDispatch ** sinks
Definition: events.c:38
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:2208
HRESULT bind_url(IMoniker *mon, HRESULT(*onDataAvailable)(void *, char *, DWORD), void *obj, bsc_t **ret)
Definition: bsc.c:288
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
static HRESULT return_null_node(IXMLDOMNode **p)
void * _private
Definition: parser.h:256
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
#define V_I1(A)
Definition: oleauto.h:243
char * va_list
Definition: acmsvcex.h:78
xmlNode * xmlNodePtr
Definition: tree.h:488
XMLPUBFUN void XMLCALL xmlSAX2SetDocumentLocator(void *ctx, xmlSAXLocatorPtr loc)
#define BAD_CAST
Definition: xmlstring.h:35
static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, DWORD *pdwCookie)
Definition: events.c:303
const char * LPCSTR
Definition: xmlstorage.h:183
#define debugstr_guid
Definition: kernel32.h:35
#define InterlockedExchangeAdd
Definition: interlocked.h:181
static IFilterGraphImpl * impl_from_IObjectWithSite(IObjectWithSite *iface)
Definition: filtergraph.c:2896
int options
Definition: main.c:106
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define b
Definition: ke_i.h:79
XMLPUBFUN void XMLCALL xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree)
Definition: SAX2.c:734
struct _xmlNode * parent
Definition: tree.h:495
static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, IEnumConnections **ppEnum)
Definition: events.c:356
static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
Definition: events.c:275
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
int wellFormed
Definition: parser.h:188
static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
Definition: events.c:269
void * _private
Definition: tree.h:552
xmlNodePtr node
Definition: parser.h:205
r parent
Definition: btrfs.c:2869
XMLPUBFUN xmlChar *XMLCALL xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:448
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD sinks_size
Definition: events.c:39
static refpint_t pi[]
Definition: server.c:96
LONG HRESULT
Definition: typedefs.h:78
static const WCHAR url[]
Definition: encode.c:1432
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content)
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
const GUID IID_IUnknown
XMLPUBFUN int XMLCALL xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len)
static ConnectionPointContainer * impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
Definition: events.c:48
static HRESULT create_node(HTMLDocumentNode *, nsIDOMNode *, HTMLDOMNode **)
Definition: htmlnode.c:1216
XMLPUBFUN void XMLCALL xmlSAX2InternalSubset(void *ctx, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
Definition: SAX2.c:354
#define WINAPI
Definition: msvc.h:6
const IID IID_IObjectWithSite
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
static char tagname[200]
Definition: rgenstat.c:63
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
XMLPUBFUN void XMLCALL xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName)
Definition: SAX2.c:899
#define success(from, fromstr, to, tostr)
XMLPUBFUN int XMLCALL xmlNodeGetSpacePreserve(const xmlNode *cur)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
XMLPUBFUN int XMLCALL xmlParseDocument(xmlParserCtxtPtr ctxt)
Definition: parser.c:10579
const GUID IID_IPersistStream
Definition: proxy.cpp:13
Definition: tree.h:489
XMLPUBFUN void XMLCALL xmlSAX2Reference(void *ctx, const xmlChar *name)
Definition: SAX2.c:2500
const GUID IID_IDispatch
int ret
xmlDocPtr myDoc
Definition: parser.h:187
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static HRESULT return_null_bstr(BSTR *p)
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
Definition: mxnamespace.c:44
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
const GUID IID_IPersistStreamInit
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:47
GLuint GLuint stream
Definition: glext.h:7522
#define V_VT(A)
Definition: oleauto.h:211
Definition: id3.c:18
HRESULT WINAPI CreateURLMonikerEx2(IMoniker *pmkContext, IUri *pUri, IMoniker **ppmk, DWORD dwFlags)
Definition: umon.c:668
static int state
Definition: maze.c:121
static const WCHAR documentW[]
Definition: script.c:47
uint32_t entry
Definition: isohybrid.c:63
unsigned char xmlChar
Definition: xmlstring.h:28
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
XMLPUBFUN int XMLCALL xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len)
Definition: xmlstring.c:206
Definition: _list.h:228
REFIID LPVOID * ppvObject
Definition: precomp.h:44
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
struct _xmlSAXHandler * sax
Definition: parser.h:185
MSXML_VERSION
Definition: msxml_private.h:34
#define err(...)
struct _cl_event * event
Definition: glext.h:7739
#define V_UNKNOWN(A)
Definition: oleauto.h:281
BSTR prefix
Definition: mxnamespace.c:46
#define V_BSTR(A)
Definition: oleauto.h:226
static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
Definition: events.c:60
const xmlChar * encoding
Definition: tree.h:574
xmlElementType type
Definition: tree.h:491
ed encoding
Definition: write.c:2839
XMLPUBFUN xmlNsPtr XMLCALL xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix)
#define local
Definition: zutil.h:30
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocComment(xmlDocPtr doc, const xmlChar *content)
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:534
#define ERR(fmt,...)
Definition: debug.h:109
XMLPUBFUN xmlParserInputPtr XMLCALL xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
Definition: SAX2.c:519
const GUID IID_IConnectionPoint
struct stdole::EXCEPINFO EXCEPINFO
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
XMLPUBFUN int XMLCALL xmlBufferLength(const xmlBuffer *buf)
#define InterlockedIncrement
Definition: armddk.h:53
const GLdouble * v
Definition: gl.h:2040
XMLPUBFUN int XMLCALL xmlSAX2IsStandalone(void *ctx)
Definition: SAX2.c:305
static ICollection collection
Definition: typelib.c:184
eventid_t
Definition: htmlevent.h:21
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT return_null_var(VARIANT *p)
#define NODE_PRIV_CHILD_IGNORABLE_WS
Definition: cookie.c:33
XMLPUBFUN int XMLCALL xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
const GUID IID_IPropertyNotifySink
#define va_start(ap, A)
Definition: acmsvcex.h:91
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
const WCHAR * schema
xmlParserCtxt * xmlParserCtxtPtr
Definition: tree.h:39
static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
Definition: events.c:281
Definition: tree.h:551
#define MultiByteToWideChar
Definition: compat.h:100
static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, LPCONNECTIONPOINT *ppCP)
Definition: events.c:80
XMLPUBFUN xmlDtdPtr XMLCALL xmlGetIntSubset(const xmlDoc *doc)
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
#define CreateFileW
Definition: compat.h:408
static HRESULT set_doc_event(HTMLDocument *doc, eventid_t eid, VARIANT *var)
Definition: htmlevent.h:90
struct _xmlNode xmlNode
Definition: tree.h:487
HANDLE events[2]
Definition: event.c:4
static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, LPVOID *ppv)
Definition: events.c:53
#define msg(x)
Definition: auth_time.c:54
XMLPUBFUN void XMLCALL xmlSAX2EndElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI)
#define XMLCALL
POINT cp
Definition: magnifier.c:59
Definition: name.c:38
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
struct stdole::DISPPARAMS DISPPARAMS
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
XMLPUBFUN void XMLCALL xmlSetNs(xmlNodePtr node, xmlNsPtr ns)
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
XMLPUBFUN xmlEntityPtr XMLCALL xmlSAX2GetEntity(void *ctx, const xmlChar *name)
Definition: SAX2.c:556
static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
Definition: events.c:66
struct _xmlNode * children
Definition: tree.h:555
static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStg)
Definition: persist.c:236
static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, LPENUMCONNECTIONPOINTS *ppEnum)
Definition: events.c:72
__MSXML_DOMNODETYPE_DEFINED enum tagDOMNodeType DOMNodeType
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
XMLPUBFUN void XMLCALL xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
Definition: SAX2.c:2804
#define NODE_PRIV_TRAILING_IGNORABLE_WS
#define E_POINTER
Definition: winerror.h:2365
#define E_PENDING
Definition: dinput.h:172
static JScript * impl_from_IObjectSafety(IObjectSafety *iface)
Definition: jscript.c:952
static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
Definition: persist.c:224
XMLPUBFUN xmlEntityPtr XMLCALL xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
Definition: SAX2.c:636
#define memset(x, y, z)
Definition: compat.h:39
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, LPVOID *ppv)
Definition: events.c:245
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
static unsigned char buff[32768]
Definition: fatten.c:17
GLenum query
Definition: glext.h:7781
xmlValidityWarningFunc warning
Definition: valid.h:85
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
static ConnectionPoint * impl_from_IConnectionPoint(IConnectionPoint *iface)
Definition: events.c:126
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
IXMLDOMParseError * create_parseError(LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos) DECLSPEC_HIDDEN
Definition: parseerror.c:329
XMLPUBFUN xmlNodePtr XMLCALL xmlNewReference(const xmlDoc *doc, const xmlChar *name)
static HTMLDOMNode * get_node_obj(IHTMLDOMNode *)
Definition: htmlnode.c:1045
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: dlist.c:348
HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
Definition: domdoc.c:3727
HRESULT create_uri(const WCHAR *, DWORD, IUri **) DECLSPEC_HIDDEN
Definition: persist.c:158
XMLPUBFUN xmlChar *XMLCALL xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
#define V_BSTRREF(A)
Definition: oleauto.h:227
static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
Definition: events.c:341