ReactOS  0.4.10-dev-234-g15c29d0
domdoc.c
Go to the documentation of this file.
1 /*
2  * XML test
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2007-2008 Alistair Leslie-Hughes
6  * Copyright 2010-2011 Adam Martinson for CodeWeavers
7  * Copyright 2010-2013 Nikolay Sivov for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #define COBJMACROS
26 #define CONST_VTABLE
27 
28 #include <stdio.h>
29 #include <assert.h>
30 
31 #include "windows.h"
32 
33 #include "msxml.h"
34 #include "msxml2.h"
35 #include "msxml2did.h"
36 #include "ole2.h"
37 #include "dispex.h"
38 #include "objsafe.h"
39 #include "mshtml.h"
40 #include "initguid.h"
41 #include "asptlb.h"
42 
43 #include "wine/heap.h"
44 #include "wine/test.h"
45 
46 /* undef the #define in msxml2 so that we can access all versions */
47 #undef CLSID_DOMDocument
48 
49 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
50 DEFINE_GUID(IID_transformdest_unknown,0xf5078f3a,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21);
51 
53 
55 {
56  const GUID *clsid;
57  const char *name;
58  const IID *ifaces[3];
60 };
61 
63 {
64  { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
65  { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
66  { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
67  { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
68  { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
69  { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
70  { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
71  { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} },
72  { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
73  { NULL }
74 };
75 
76 static const char *debugstr_msxml_guid(REFIID riid)
77 {
78  if(!riid)
79  return "(null)";
80 
81  if (IsEqualIID(&IID_IXMLDOMDocument, riid))
82  return "IXMLDOMDocument";
83  else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
84  return "IXMLDOMDocument2";
85  else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
86  return "IXMLDOMDocument3";
87  else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
88  return "IXMLDOMSchemaCollection";
89  else if (IsEqualIID(&IID_IXSLTemplate, riid))
90  return "IXSLTemplate";
91  else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
92  return "IMXNamespaceManager";
93  else
94  return wine_dbgstr_guid(riid);
95 }
96 
98 {
99  while (table->clsid)
100  {
101  IUnknown *unk;
102  HRESULT hr;
103  int i;
104 
105  for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
106  {
107  hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
108  if (hr == S_OK) IUnknown_Release(unk);
109 
110  table->supported[i] = hr == S_OK;
111  if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
112  }
113 
114  table++;
115  }
116 }
117 
119 {
121  while (table->clsid)
122  {
123  if (table->clsid == clsid)
124  {
125  int i;
126 
127  for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
128  if (table->ifaces[i] == riid) return table->supported[i];
129  }
130 
131  table++;
132  }
133  return FALSE;
134 }
135 
136 typedef struct
137 {
140 } dispevent;
141 
142 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
143 {
144  return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
145 }
146 
148 {
149  *ppvObject = NULL;
150 
151  if ( IsEqualGUID( riid, &IID_IDispatch) ||
152  IsEqualGUID( riid, &IID_IUnknown) )
153  {
154  *ppvObject = iface;
155  }
156  else
157  return E_NOINTERFACE;
158 
159  IDispatch_AddRef( iface );
160 
161  return S_OK;
162 }
163 
165 {
166  dispevent *This = impl_from_IDispatch( iface );
167  return InterlockedIncrement( &This->ref );
168 }
169 
171 {
172  dispevent *This = impl_from_IDispatch( iface );
173  ULONG ref = InterlockedDecrement( &This->ref );
174 
175  if (ref == 0)
176  heap_free(This);
177 
178  return ref;
179 }
180 
182 {
184  *pctinfo = 0;
185  return S_OK;
186 }
187 
189  LCID lcid, ITypeInfo **ppTInfo)
190 {
192  return S_OK;
193 }
194 
196  LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
197 {
199  return S_OK;
200 }
201 
204  EXCEPINFO *excepInfo, UINT *argErr)
205 {
206  ok(member == 0, "expected 0 member, got %d\n", member);
207  ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
208  ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
209 
210  ok(params->cArgs == 0, "got %d\n", params->cArgs);
211  ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
212  ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
213  ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
214 
215  ok(result == NULL, "got %p\n", result);
216  ok(excepInfo == NULL, "got %p\n", excepInfo);
217  ok(argErr == NULL, "got %p\n", argErr);
218 
219  g_expectedcall++;
220  return E_FAIL;
221 }
222 
223 static const IDispatchVtbl dispeventVtbl =
224 {
232 };
233 
235 {
236  dispevent *event = heap_alloc(sizeof(*event));
237 
238  event->IDispatch_iface.lpVtbl = &dispeventVtbl;
239  event->ref = 1;
240 
241  return (IDispatch*)&event->IDispatch_iface;
242 }
243 
244 /* IStream */
246 {
247  *ppvObject = NULL;
248 
249  if (IsEqualGUID(riid, &IID_IStream) ||
250  IsEqualGUID(riid, &IID_IUnknown))
251  *ppvObject = iface;
252  else
253  return E_NOINTERFACE;
254 
255  return S_OK;
256 }
257 
259 {
260  return 2;
261 }
262 
264 {
265  return 1;
266 }
267 
269 {
270  ok(0, "unexpected call\n");
271  return E_NOTIMPL;
272 }
273 
274 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
275 {
276  *written = len/2;
277  return S_OK;
278 }
279 
281 {
282  ok(0, "unexpected call\n");
283  return E_NOTIMPL;
284 }
285 
287 {
288  ok(0, "unexpected call\n");
289  return E_NOTIMPL;
290 }
291 
294 {
295  ok(0, "unexpected call\n");
296  return E_NOTIMPL;
297 }
298 
300 {
301  ok(0, "unexpected call\n");
302  return E_NOTIMPL;
303 }
304 
306 {
307  ok(0, "unexpected call\n");
308  return E_NOTIMPL;
309 }
310 
312  ULARGE_INTEGER len, DWORD locktype)
313 {
314  ok(0, "unexpected call\n");
315  return E_NOTIMPL;
316 }
317 
319  ULARGE_INTEGER len, DWORD locktype)
320 {
321  ok(0, "unexpected call\n");
322  return E_NOTIMPL;
323 }
324 
325 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
326 {
327  ok(0, "unexpected call\n");
328  return E_NOTIMPL;
329 }
330 
332 {
333  ok(0, "unexpected call\n");
334  return E_NOTIMPL;
335 }
336 
337 static const IStreamVtbl StreamVtbl = {
341  istream_Read,
343  istream_Seek,
350  istream_Stat,
352 };
353 
355 
357 {
358  if (IsEqualIID(&IID_IResponse, riid) ||
359  IsEqualIID(&IID_IDispatch, riid) ||
360  IsEqualIID(&IID_IUnknown, riid))
361  {
362  *obj = iface;
363  return S_OK;
364  }
365 
366  if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid))
367  ok(0, "unexpected call\n");
368  return E_NOINTERFACE;
369 }
370 
372 {
373  return 2;
374 }
375 
377 {
378  return 1;
379 }
380 
382 {
383  ok(0, "unexpected call\n");
384  return E_NOTIMPL;
385 }
386 
387 static HRESULT WINAPI response_GetTypeInfo(IResponse *iface, UINT ti, LCID lcid, ITypeInfo **tinfo)
388 {
389  ok(0, "unexpected call\n");
390  return E_NOTIMPL;
391 }
392 
394  UINT cnames, LCID lcid, DISPID *rgDispId)
395 {
396  ok(0, "unexpected call\n");
397  return E_NOTIMPL;
398 }
399 
402 {
403  ok(0, "unexpected call\n");
404  return E_NOTIMPL;
405 }
406 
408 {
409  ok(0, "unexpected call\n");
410  return E_NOTIMPL;
411 }
412 
414 {
415  ok(0, "unexpected call\n");
416  return E_NOTIMPL;
417 }
418 
419 static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet)
420 {
421  ok(0, "unexpected call\n");
422  return E_NOTIMPL;
423 }
424 
425 static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType)
426 {
427  ok(0, "unexpected call\n");
428  return E_NOTIMPL;
429 }
430 
431 static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet)
432 {
433  ok(0, "unexpected call\n");
434  return E_NOTIMPL;
435 }
436 
437 static HRESULT WINAPI response_put_Expires(IResponse *iface, LONG lExpiresMinutes)
438 {
439  ok(0, "unexpected call\n");
440  return E_NOTIMPL;
441 }
442 
444 {
445  ok(0, "unexpected call\n");
446  return E_NOTIMPL;
447 }
448 
450 {
451  ok(0, "unexpected call\n");
452  return E_NOTIMPL;
453 }
454 
456 {
457  ok(0, "unexpected call\n");
458  return E_NOTIMPL;
459 }
460 
461 static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet)
462 {
463  ok(0, "unexpected call\n");
464  return E_NOTIMPL;
465 }
466 
467 static HRESULT WINAPI response_put_Status(IResponse *iface, BSTR bstrStatus)
468 {
469  ok(0, "unexpected call\n");
470  return E_NOTIMPL;
471 }
472 
473 static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName)
474 {
475  ok(0, "unexpected call\n");
476  return E_NOTIMPL;
477 }
478 
479 static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue)
480 {
481  ok(0, "unexpected call\n");
482  return E_NOTIMPL;
483 }
484 
485 static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry)
486 {
487  ok(0, "unexpected call\n");
488  return E_NOTIMPL;
489 }
490 
492 {
493  HRESULT hr;
494  LONG bound;
495  UINT dim;
496 
497  ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input));
498 
499  dim = SafeArrayGetDim(V_ARRAY(&input));
500  ok(dim == 1, "got wrong array dimensions %u\n", dim);
501 
502  bound = 1;
503  hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound);
504  ok(hr == S_OK, "got %#x\n", hr);
505  ok(bound == 0, "wrong array low bound %d\n", bound);
506 
507  bound = 0;
508  hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound);
509  ok(hr == S_OK, "got %#x\n", hr);
510  ok(bound > 0, "wrong array high bound %d\n", bound);
511 
512  return E_NOTIMPL;
513 }
514 
516 {
517  ok(0, "unexpected call\n");
518  return E_NOTIMPL;
519 }
520 
522 {
523  ok(0, "unexpected call\n");
524  return E_NOTIMPL;
525 }
526 
528 {
529  ok(0, "unexpected call\n");
530  return E_NOTIMPL;
531 }
532 
534 {
535  ok(0, "unexpected call\n");
536  return E_NOTIMPL;
537 }
538 
540 {
541  ok(0, "unexpected call\n");
542  return E_NOTIMPL;
543 }
544 
545 static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber)
546 {
547  ok(0, "unexpected call\n");
548  return E_NOTIMPL;
549 }
550 
551 static HRESULT WINAPI response_IsClientConnected(IResponse *iface, VARIANT_BOOL *pfIsClientConnected)
552 {
553  ok(0, "unexpected call\n");
554  return E_NOTIMPL;
555 }
556 
557 static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet)
558 {
559  ok(0, "unexpected call\n");
560  return E_NOTIMPL;
561 }
562 
563 static HRESULT WINAPI response_put_CharSet(IResponse *iface, BSTR bstrCharSet)
564 {
565  ok(0, "unexpected call\n");
566  return E_NOTIMPL;
567 }
568 
569 static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue)
570 {
571  ok(0, "unexpected call\n");
572  return E_NOTIMPL;
573 }
574 
575 static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl)
576 {
577  ok(0, "unexpected call\n");
578  return E_NOTIMPL;
579 }
580 
581 static HRESULT WINAPI response_put_CacheControl(IResponse *iface, BSTR bstrCacheControl)
582 {
583  ok(0, "unexpected call\n");
584  return E_NOTIMPL;
585 }
586 
588 {
589  ok(0, "unexpected call\n");
590  return E_NOTIMPL;
591 }
592 
594 {
595  ok(0, "unexpected call\n");
596  return E_NOTIMPL;
597 }
598 
600 {
601  ok(0, "unexpected call\n");
602  return E_NOTIMPL;
603 }
604 
606 {
607  ok(0, "unexpected call\n");
608  return E_NOTIMPL;
609 }
610 
611 static const IResponseVtbl testresponsevtbl =
612 {
613  response_QI,
631  response_Add,
636  response_End,
651 };
652 
654 
655 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
657 {
658  VARIANT_BOOL b;
659  HRESULT hr;
660 
661  b = VARIANT_FALSE;
662  hr = IXMLDOMNode_hasChildNodes(node, &b);
663  ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
664  ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
665 }
666 
667 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
669 {
670  VARIANT_BOOL b;
671  HRESULT hr;
672 
673  b = VARIANT_TRUE;
674  hr = IXMLDOMNode_hasChildNodes(node, &b);
675  ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
676  ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
677 }
678 
679 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
680 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
681 {
682  ULONG rc;
683  IUnknown_AddRef(obj);
684  rc = IUnknown_Release(obj);
685  ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
686 }
687 
688 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
690 {
691  LONG length;
692  HRESULT hr;
693 
694  length = 0;
695  hr = IXMLDOMNodeList_get_length(list, &length);
696  ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
697  ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
698 }
699 
700 #define EXPECT_HR(hr,hr_exp) \
701  ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
702 
703 #ifdef __REACTOS__
704 #define EXPECT_NOT_HR(hr,hr_exp) \
705  ok(hr != hr_exp, "got 0x%08x, expected not 0x%08x\n", hr, hr_exp)
706 #endif
707 
708 static const WCHAR szEmpty[] = { 0 };
709 static const WCHAR szIncomplete[] = {
710  '<','?','x','m','l',' ',
711  'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
712 };
713 static const WCHAR szComplete1[] = {
714  '<','?','x','m','l',' ',
715  'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
716  '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
717 };
718 static const WCHAR szComplete2[] = {
719  '<','?','x','m','l',' ',
720  'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
721  '<','a','>','<','/','a','>','\n',0
722 };
723 static const char complete4A[] =
724  "<?xml version=\'1.0\'?>\n"
725  "<lc dl=\'str1\'>\n"
726  "<bs vr=\'str2\' sz=\'1234\'>"
727  "fn1.txt\n"
728  "</bs>\n"
729  "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
730  "fn2.txt\n"
731  "</pr>\n"
732  "<empty></empty>\n"
733  "<fo>\n"
734  "<ba>\n"
735  "f1\n"
736  "</ba>\n"
737  "</fo>\n"
738  "</lc>\n";
739 
740 static const WCHAR szComplete5[] = {
741  '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
742  'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
743  ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
744  '<','S',':','s','c','o','p','e','>',
745  '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
746  '<','/','S',':','s','c','o','p','e','>',
747  '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
748  '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
749  'c','o','m','p','u','t','e','r',
750  '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
751  '<','/','S',':','s','e','a','r','c','h','>',0
752 };
753 
754 static const WCHAR szComplete6[] = {
755  '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
756  'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
757  '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
758 };
759 
760 static const char complete7[] = {
761  "<?xml version=\"1.0\"?>\n\t"
762  "<root>\n"
763  "\t<a/>\n"
764  "\t<b/>\n"
765  "\t<c/>\n"
766  "</root>"
767 };
768 
769 #define DECL_WIN_1252 \
770 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
771 
772 static const char win1252xml[] =
774 "<open></open>";
775 
776 static const char win1252decl[] =
778 ;
779 
780 static const char nocontent[] = "no xml content here";
781 
782 static const char szExampleXML[] =
783 "<?xml version='1.0' encoding='utf-8'?>\n"
784 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
785 " <elem>\n"
786 " <a>A1 field</a>\n"
787 " <b>B1 field</b>\n"
788 " <c>C1 field</c>\n"
789 " <d>D1 field</d>\n"
790 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
791 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
792 " <![CDATA[]]> This is<strong> a</strong> <i>description</i><dot>. </dot><bar:x/>\n"
793 " </html>\n"
794 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
795 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
796 " </html>\n"
797 " </description>\n"
798 " </elem>\n"
799 "\n"
800 " <elem a='a'>\n"
801 " <a>A2 field</a>\n"
802 " <b>B2 field</b>\n"
803 " <c type=\"old\">C2 field</c>\n"
804 " <d>D2 field</d>\n"
805 " </elem>\n"
806 "\n"
807 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
808 " <a>A3 field</a>\n"
809 " <b>B3 field</b>\n"
810 " <c>C3 field</c>\n"
811 " </elem>\n"
812 "\n"
813 " <elem>\n"
814 " <a>A4 field</a>\n"
815 " <b>B4 field</b>\n"
816 " <foo:c>C4 field</foo:c>\n"
817 " <d>D4 field</d>\n"
818 " </elem>\n"
819 "</root>\n";
820 
821 static const char charrefsxml[] =
822 "<?xml version='1.0'?>"
823 "<a>"
824 "<b1> Text &#65; end </b1>"
825 "<b2>&#65;&#66; &#67; </b2>"
826 "</a>";
827 
828 static const CHAR szNodeTypesXML[] =
829 "<?xml version='1.0'?>"
830 "<!-- comment node 0 -->"
831 "<root id='0' depth='0'>"
832 " <!-- comment node 1 -->"
833 " text node 0"
834 " <x id='1' depth='1'>"
835 " <?foo value='PI for x'?>"
836 " <!-- comment node 2 -->"
837 " text node 1"
838 " <a id='3' depth='2'/>"
839 " <b id='4' depth='2'/>"
840 " <c id='5' depth='2'/>"
841 " </x>"
842 " <y id='2' depth='1'>"
843 " <?bar value='PI for y'?>"
844 " <!-- comment node 3 -->"
845 " text node 2"
846 " <a id='6' depth='2'/>"
847 " <b id='7' depth='2'/>"
848 " <c id='8' depth='2'/>"
849 " </y>"
850 "</root>";
851 
852 static const CHAR szTransformXML[] =
853 "<?xml version=\"1.0\"?>\n"
854 "<greeting>\n"
855 "Hello World\n"
856 "</greeting>";
857 
858 static const CHAR szTransformSSXML[] =
859 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
860 " <xsl:output method=\"html\"/>\n"
861 " <xsl:template match=\"/\">\n"
862 " <xsl:apply-templates select=\"greeting\"/>\n"
863 " </xsl:template>\n"
864 " <xsl:template match=\"greeting\">\n"
865 " <html>\n"
866 " <body>\n"
867 " <h1>\n"
868 " <xsl:value-of select=\".\"/>\n"
869 " </h1>\n"
870 " </body>\n"
871 " </html>\n"
872 " </xsl:template>\n"
873 "</xsl:stylesheet>";
874 
875 static const CHAR szTransformOutput[] =
876 "<html><body><h1>"
877 "Hello World"
878 "</h1></body></html>";
879 
880 static const CHAR szTypeValueXML[] =
881 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
882 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
883 " <string>Wine</string>\n"
884 " <string2 dt:dt=\"string\">String</string2>\n"
885 " <number dt:dt=\"number\">12.44</number>\n"
886 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
887 " <int dt:dt=\"int\">-13</int>\n"
888 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
889 " <bool dt:dt=\"boolean\">1</bool>\n"
890 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
891 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
892 " <date dt:dt=\"date\">3721-11-01</date>\n"
893 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
894 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
895 " <i1 dt:dt=\"i1\">-13</i1>\n"
896 " <i2 dt:dt=\"i2\">31915</i2>\n"
897 " <i4 dt:dt=\"i4\">-312232</i4>\n"
898 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
899 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
900 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
901 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
902 " <r8 dt:dt=\"r8\">0.412</r8>\n"
903 " <float dt:dt=\"float\">41221.421</float>\n"
904 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
905 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
906 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
907 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
908 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
909 "</root>";
910 
912 "<?xml version=\"1.0\"?>"
913 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
914 "<xsl:output method=\"html\"/>\n"
915 "<xsl:template match=\"/\">"
916 "<HTML><BODY><TABLE>"
917 " <xsl:apply-templates select='document(\"";
918 
920 "\")/bottle/wine'>"
921 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
922 " </xsl:apply-templates>"
923 "</TABLE></BODY></HTML>"
924 "</xsl:template>"
925 "<xsl:template match=\"bottle\">"
926 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
927 "</xsl:template>"
928 "<xsl:template match=\"name\">"
929 " <TD><xsl:apply-templates /></TD>"
930 "</xsl:template>"
931 "<xsl:template match=\"cost\">"
932 " <TD><xsl:apply-templates /></TD>"
933 "</xsl:template>"
934 "</xsl:stylesheet>";
935 
936 static const CHAR szBasicTransformXML[] =
937 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
938 
939 static const CHAR szBasicTransformOutput[] =
940 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
941 
942 #define SZ_EMAIL_DTD \
943 "<!DOCTYPE email ["\
944 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
945 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
946 " <!ATTLIST email sent (yes|no) \"no\">"\
947 " <!ELEMENT recipients (to+,cc*)>"\
948 " <!ELEMENT to (#PCDATA)>"\
949 " <!ATTLIST to name CDATA #IMPLIED>"\
950 " <!ELEMENT cc (#PCDATA)>"\
951 " <!ATTLIST cc name CDATA #IMPLIED>"\
952 " <!ELEMENT from (#PCDATA)>"\
953 " <!ATTLIST from name CDATA #IMPLIED>"\
954 " <!ELEMENT reply-to (#PCDATA)>"\
955 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
956 " <!ELEMENT subject ANY>"\
957 " <!ELEMENT body ANY>"\
958 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
959 " <!ELEMENT attachment (#PCDATA)>"\
960 " <!ATTLIST attachment id ID #REQUIRED>"\
961 "]>"
962 
963 static const CHAR szEmailXML[] =
964 "<?xml version=\"1.0\"?>"
966 "<email attachments=\"patch1\">"
967 " <recipients>"
968 " <to>wine-patches@winehq.org</to>"
969 " </recipients>"
970 " <from name=\"Anonymous\">user@localhost</from>"
971 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
972 " <body>"
973 " It no longer causes spontaneous combustion..."
974 " </body>"
975 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
976 "</email>";
977 
978 static const CHAR szEmailXML_0D[] =
979 "<?xml version=\"1.0\"?>"
981 "<email attachments=\"patch1\">"
982 " <recipients>"
983 " <to>wine-patches@winehq.org</to>"
984 " </recipients>"
985 " <from name=\"Anonymous\">user@localhost</from>"
986 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
987 " <body>"
988 " <undecl />"
989 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
990 " </body>"
991 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
992 "</email>";
993 
994 static const CHAR szEmailXML_0E[] =
995 "<?xml version=\"1.0\"?>"
997 "<email attachments=\"patch1\">"
998 " <recipients>"
999 " <to>wine-patches@winehq.org</to>"
1000 " </recipients>"
1001 " <from name=\"Anonymous\">user@localhost</from>"
1002 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
1003 " <body>"
1004 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
1005 " </body>"
1006 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1007 "</email>";
1008 
1009 static const CHAR szEmailXML_11[] =
1010 "<?xml version=\"1.0\"?>"
1012 "<email attachments=\"patch1\">"
1013 " <recipients>"
1014 " </recipients>"
1015 " <from name=\"Anonymous\">user@localhost</from>"
1016 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
1017 " <body>"
1018 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
1019 " </body>"
1020 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1021 "</email>";
1022 
1023 static const CHAR szEmailXML_13[] =
1024 "<?xml version=\"1.0\"?>"
1026 "<msg attachments=\"patch1\">"
1027 " <recipients>"
1028 " <to>wine-patches@winehq.org</to>"
1029 " </recipients>"
1030 " <from name=\"Anonymous\">user@localhost</from>"
1031 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
1032 " <body>"
1033 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
1034 " </body>"
1035 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1036 "</msg>";
1037 
1038 static const CHAR szEmailXML_14[] =
1039 "<?xml version=\"1.0\"?>"
1041 "<email attachments=\"patch1\">"
1042 " <to>wine-patches@winehq.org</to>"
1043 " <from name=\"Anonymous\">user@localhost</from>"
1044 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
1045 " <body>"
1046 " XML_INVALID_CONTENT 0xC00CE014"
1047 " </body>"
1048 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1049 "</email>";
1050 
1051 static const CHAR szEmailXML_15[] =
1052 "<?xml version=\"1.0\"?>"
1054 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
1055 " <recipients>"
1056 " <to>wine-patches@winehq.org</to>"
1057 " </recipients>"
1058 " <from name=\"Anonymous\">user@localhost</from>"
1059 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
1060 " <body>"
1061 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
1062 " </body>"
1063 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1064 "</email>";
1065 
1066 static const CHAR szEmailXML_16[] =
1067 "<?xml version=\"1.0\"?>"
1069 "<email attachments=\"patch1\">"
1070 " <recipients>"
1071 " <to>wine-patches@winehq.org</to>"
1072 " </recipients>"
1073 " <from name=\"Anonymous\">user@localhost</from>"
1074 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
1075 " <body enc=\"ASCII\">"
1076 " XML_ATTRIBUTE_FIXED 0xC00CE016"
1077 " </body>"
1078 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1079 "</email>";
1080 
1081 static const CHAR szEmailXML_17[] =
1082 "<?xml version=\"1.0\"?>"
1084 "<email attachments=\"patch1\" sent=\"true\">"
1085 " <recipients>"
1086 " <to>wine-patches@winehq.org</to>"
1087 " </recipients>"
1088 " <from name=\"Anonymous\">user@localhost</from>"
1089 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
1090 " <body>"
1091 " XML_ATTRIBUTE_VALUE 0xC00CE017"
1092 " </body>"
1093 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1094 "</email>";
1095 
1096 static const CHAR szEmailXML_18[] =
1097 "<?xml version=\"1.0\"?>"
1099 "<email attachments=\"patch1\">"
1100 " oops"
1101 " <recipients>"
1102 " <to>wine-patches@winehq.org</to>"
1103 " </recipients>"
1104 " <from name=\"Anonymous\">user@localhost</from>"
1105 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
1106 " <body>"
1107 " XML_ILLEGAL_TEXT 0xC00CE018"
1108 " </body>"
1109 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1110 "</email>";
1111 
1112 static const CHAR szEmailXML_20[] =
1113 "<?xml version=\"1.0\"?>"
1115 "<email>"
1116 " <recipients>"
1117 " <to>wine-patches@winehq.org</to>"
1118 " </recipients>"
1119 " <from name=\"Anonymous\">user@localhost</from>"
1120 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
1121 " <body>"
1122 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
1123 " </body>"
1124 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
1125 "</email>";
1126 
1127 static const char xpath_simple_list[] =
1128 "<?xml version=\"1.0\"?>"
1129 "<root>"
1130 " <a attr1=\"1\" attr2=\"2\" />"
1131 " <b/>"
1132 " <c/>"
1133 " <d/>"
1134 "</root>";
1135 
1136 static const char default_ns_doc[] = {
1137  "<?xml version=\"1.0\"?>"
1138  "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
1139  " d=\"d attr\" />"
1140 };
1141 
1142 static const char attributes_map[] = {
1143  "<?xml version=\"1.0\"?>"
1144  "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1145 };
1146 
1147 static const WCHAR nonexistent_fileW[] = {
1148  'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1149 };
1150 static const WCHAR nonexistent_attrW[] = {
1151  'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
1152 };
1153 static const WCHAR szDocument[] = {
1154  '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1155 };
1156 
1157 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1158 static const WCHAR szdl[] = { 'd','l',0 };
1159 static const WCHAR szvr[] = { 'v','r',0 };
1160 static const WCHAR szlc[] = { 'l','c',0 };
1161 static const WCHAR szbs[] = { 'b','s',0 };
1162 static const WCHAR szstr1[] = { 's','t','r','1',0 };
1163 static const WCHAR szstr2[] = { 's','t','r','2',0 };
1164 static const WCHAR szstar[] = { '*',0 };
1165 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1166 
1167 static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1168 static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1169 static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1170 
1171 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1172 static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
1173 static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1174 static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1175  'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
1176 static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
1177  '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
1178 
1179 static const WCHAR szAttribute[] = {'A','t','t','r',0 };
1180 static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1181 
1182 static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1183  ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1184 static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
1185  'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
1186  '!',']',']','>',0};
1187 static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1188 static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1189 
1190 static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1191 static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1192 static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
1193 
1194 #define expect_bstr_eq_and_free(bstr, expect) { \
1195  BSTR bstrExp = alloc_str_from_narrow(expect); \
1196  ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
1197  SysFreeString(bstr); \
1198  SysFreeString(bstrExp); \
1199 }
1200 
1201 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
1202 
1203 #define ole_check(expr) { \
1204  HRESULT r = expr; \
1205  ok(r == S_OK, #expr " returned %x\n", r); \
1206 }
1207 
1208 #define ole_expect(expr, expect) { \
1209  HRESULT r = expr; \
1210  ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
1211 }
1212 
1213 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
1214 
1215 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
1216 {
1217  void *obj = NULL;
1218  HRESULT hr;
1219 
1220  hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
1221  ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr);
1222 
1223  return obj;
1224 }
1225 
1226 #define _create(cls) cls, #cls
1227 
1228 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
1229 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
1230 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
1231 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
1232 
1233 static BSTR alloc_str_from_narrow(const char *str)
1234 {
1235  int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
1236  BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
1237  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
1238  return ret;
1239 }
1240 
1241 static BSTR alloced_bstrs[256];
1243 
1244 static BSTR _bstr_(const char *str)
1245 {
1246  assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
1249 }
1250 
1251 static void free_bstrs(void)
1252 {
1253  int i;
1254  for (i = 0; i < alloced_bstrs_count; i++)
1256  alloced_bstrs_count = 0;
1257 }
1258 
1259 static VARIANT _variantbstr_(const char *str)
1260 {
1261  VARIANT v;
1262  V_VT(&v) = VT_BSTR;
1263  V_BSTR(&v) = _bstr_(str);
1264  return v;
1265 }
1266 
1267 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
1268 {
1269  for (;;)
1270  {
1271  while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
1272  while (*sRight == '\r' || *sRight == '\n') sRight++;
1273  if (*sLeft != *sRight) return FALSE;
1274  if (!*sLeft) return TRUE;
1275  sLeft++;
1276  sRight++;
1277  }
1278 }
1279 
1281 {
1282  switch (type)
1283  {
1284  case NODE_ATTRIBUTE:
1285  strcpy(buf, "A");
1286  break;
1287  case NODE_ELEMENT:
1288  strcpy(buf, "E");
1289  break;
1290  case NODE_DOCUMENT:
1291  strcpy(buf, "D");
1292  break;
1293  case NODE_TEXT:
1294  strcpy(buf, "T");
1295  break;
1296  case NODE_COMMENT:
1297  strcpy(buf, "C");
1298  break;
1300  strcpy(buf, "P");
1301  break;
1302  default:
1303  wsprintfA(buf, "[%d]", type);
1304  }
1305 }
1306 
1308 {
1309  HRESULT r;
1310  int pos = 0;
1311 
1312  IXMLDOMNode_AddRef(node);
1313  do
1314  {
1315  IXMLDOMNode *new_node;
1316 
1317  pos++;
1318  r = IXMLDOMNode_get_previousSibling(node, &new_node);
1319  ok(SUCCEEDED(r), "get_previousSibling failed\n");
1320  IXMLDOMNode_Release(node);
1321  node = new_node;
1322  } while (r == S_OK);
1323  return pos;
1324 }
1325 
1326 static void node_to_string(IXMLDOMNode *node, char *buf)
1327 {
1328  HRESULT r = S_OK;
1329  DOMNodeType type;
1330 
1331  if (node == NULL)
1332  {
1333  lstrcpyA(buf, "(null)");
1334  return;
1335  }
1336 
1337  IXMLDOMNode_AddRef(node);
1338  while (r == S_OK)
1339  {
1340  IXMLDOMNode *new_node;
1341 
1342  ole_check(IXMLDOMNode_get_nodeType(node, &type));
1343  get_str_for_type(type, buf);
1344  buf+=strlen(buf);
1345 
1346  if (type == NODE_ATTRIBUTE)
1347  {
1348  BSTR bstr;
1349  ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1350  *(buf++) = '\'';
1351  wsprintfA(buf, "%ws", bstr);
1352  buf += strlen(buf);
1353  *(buf++) = '\'';
1354  SysFreeString(bstr);
1355 
1356  r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1357  }
1358  else
1359  {
1360  r = IXMLDOMNode_get_parentNode(node, &new_node);
1361  sprintf(buf, "%d", get_node_position(node));
1362  buf += strlen(buf);
1363  }
1364 
1365  ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1366  IXMLDOMNode_Release(node);
1367  node = new_node;
1368  if (r == S_OK)
1369  *(buf++) = '.';
1370  }
1371 
1372  *buf = 0;
1373 }
1374 
1376 {
1377  static char buf[4096];
1378  char *pos = buf;
1379  LONG len = 0;
1380  HRESULT hr;
1381  int i;
1382 
1383  if (list == NULL)
1384  {
1385  strcpy(buf, "(null)");
1386  return buf;
1387  }
1388  hr = IXMLDOMNodeList_get_length(list, &len);
1389  ok(hr == S_OK, "got 0x%08x\n", hr);
1390  for (i = 0; i < len; i++)
1391  {
1392  IXMLDOMNode *node;
1393  if (i > 0)
1394  *(pos++) = ' ';
1395  ole_check(IXMLDOMNodeList_nextNode(list, &node));
1396  node_to_string(node, pos);
1397  pos += strlen(pos);
1398  IXMLDOMNode_Release(node);
1399  }
1400  *pos = 0;
1401  return buf;
1402 }
1403 
1404 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
1405 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
1406 
1410 };
1411 
1413  const CLSID *clsid;
1414  const char *name;
1415  struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
1416 };
1417 
1419  { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1420  { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1421  { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1422  { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1423  { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1424  { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1425  { NULL }
1426 };
1427 
1428 static const char* leading_spaces_xmldata[] = {
1429  "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1430  " <?xml version=\"1.0\"?><root/>",
1431  "\n<?xml version=\"1.0\"?><root/>",
1432  "\t<?xml version=\"1.0\"?><root/>",
1433  "\r\n<?xml version=\"1.0\"?><root/>",
1434  "\r<?xml version=\"1.0\"?><root/>",
1435  "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1436  0
1437 };
1438 
1439 static void test_domdoc( void )
1440 {
1441  HRESULT r, hr;
1442  IXMLDOMDocument *doc;
1445  IXMLDOMNode *node;
1446  IXMLDOMText *nodetext = NULL;
1447  IXMLDOMComment *node_comment = NULL;
1448  IXMLDOMAttribute *node_attr = NULL;
1449  IXMLDOMNode *nodeChild = NULL;
1451  const struct leading_spaces_t *class_ptr;
1452  const char **data_ptr;
1453  VARIANT_BOOL b;
1454  VARIANT var;
1455  BSTR str;
1456  LONG code, ref;
1457  LONG nLength = 0;
1458  WCHAR buff[100];
1459  char path[MAX_PATH];
1460  int index;
1461 
1462  GetTempPathA(MAX_PATH, path);
1463  strcat(path, "leading_spaces.xml");
1464 
1465  /* Load document with leading spaces
1466  *
1467  * Test all CLSIDs with all test data XML strings
1468  */
1469  class_ptr = leading_spaces_classdata;
1470  index = 0;
1471  while (class_ptr->clsid)
1472  {
1473  HRESULT hr;
1474  int i;
1475 
1476  if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
1477  {
1478  hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
1479  }
1480  else
1481  {
1482  class_ptr++;
1483  index++;
1484  continue;
1485  }
1486 
1487  data_ptr = leading_spaces_xmldata;
1488  i = 0;
1489  while (*data_ptr) {
1490  BSTR data = _bstr_(*data_ptr);
1491  DWORD written;
1492  HANDLE file;
1493 
1495  ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
1496 
1497  WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
1498  CloseHandle(file);
1499 
1500  b = 0xc;
1501  V_VT(&var) = VT_BSTR;
1502  V_BSTR(&var) = _bstr_(path);
1503  hr = IXMLDOMDocument_load(doc, var, &b);
1504  EXPECT_HR(hr, class_ptr->ret[0].hr);
1505  ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
1506 
1507  DeleteFileA(path);
1508 
1509  b = 0xc;
1510  hr = IXMLDOMDocument_loadXML(doc, data, &b);
1511  EXPECT_HR(hr, class_ptr->ret[1].hr);
1512  ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
1513 
1514  data_ptr++;
1515  i++;
1516  }
1517 
1518  class_ptr++;
1519  index++;
1520  free_bstrs();
1521  }
1522 
1523  doc = create_document(&IID_IXMLDOMDocument);
1524  if (!doc) return;
1525 
1526 if (0)
1527 {
1528  /* crashes on native */
1529  IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
1530 }
1531 
1532  /* try some stupid things */
1533  hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1534  EXPECT_HR(hr, S_FALSE);
1535 
1536  b = VARIANT_TRUE;
1537  hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
1538  EXPECT_HR(hr, S_FALSE);
1539  ok( b == VARIANT_FALSE, "failed to load XML string\n");
1540 
1541  /* try to load a document from a nonexistent file */
1542  b = VARIANT_TRUE;
1544  VariantInit(&var);
1545  V_VT(&var) = VT_BSTR;
1546  V_BSTR(&var) = str;
1547 
1548  r = IXMLDOMDocument_load( doc, var, &b);
1549  ok( r == S_FALSE, "loadXML succeeded\n");
1550  ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1551  SysFreeString( str );
1552 
1553  str = (void *)0xdeadbeef;
1554  hr = IXMLDOMDocument_get_url(doc, &str);
1555  ok(hr == S_FALSE, "got 0x%08x\n", hr);
1556  ok(str == NULL, "got %p\n", str);
1557 
1558  /* try load an empty document */
1559  b = VARIANT_TRUE;
1560  str = SysAllocString( szEmpty );
1561  r = IXMLDOMDocument_loadXML( doc, str, &b );
1562  ok( r == S_FALSE, "loadXML succeeded\n");
1563  ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1564  SysFreeString( str );
1565 
1566  r = IXMLDOMDocument_get_async( doc, &b );
1567  ok( r == S_OK, "get_async failed (%08x)\n", r);
1568  ok( b == VARIANT_TRUE, "Wrong default value\n");
1569 
1570  /* check that there's no document element */
1571  element = NULL;
1572  r = IXMLDOMDocument_get_documentElement( doc, &element );
1573  ok( r == S_FALSE, "should be no document element\n");
1574 
1575  /* try finding a node */
1576  node = NULL;
1577  str = SysAllocString( szstr1 );
1578  r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1579  ok( r == S_FALSE, "ret %08x\n", r );
1580  SysFreeString( str );
1581 
1582  b = VARIANT_TRUE;
1583  str = SysAllocString( szIncomplete );
1584  r = IXMLDOMDocument_loadXML( doc, str, &b );
1585  ok( r == S_FALSE, "loadXML succeeded\n");
1586  ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1587  SysFreeString( str );
1588 
1589  /* check that there's no document element */
1590  element = (IXMLDOMElement*)1;
1591  r = IXMLDOMDocument_get_documentElement( doc, &element );
1592  ok( r == S_FALSE, "should be no document element\n");
1593  ok( element == NULL, "Element should be NULL\n");
1594 
1595  /* test for BSTR handling, pass broken BSTR */
1596  memcpy(&buff[2], szComplete1, sizeof(szComplete1));
1597  /* just a big length */
1598  *(DWORD*)buff = 0xf0f0;
1599  b = VARIANT_FALSE;
1600  r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1601  ok( r == S_OK, "loadXML failed\n");
1602  ok( b == VARIANT_TRUE, "failed to load XML string\n");
1603 
1604  /* loadXML ignores the encoding attribute and always expects Unicode */
1605  b = VARIANT_FALSE;
1606  str = SysAllocString( szComplete6 );
1607  r = IXMLDOMDocument_loadXML( doc, str, &b );
1608  ok( r == S_OK, "loadXML failed\n");
1609  ok( b == VARIANT_TRUE, "failed to load XML string\n");
1610  SysFreeString( str );
1611 
1612  /* try a BSTR containing a Windows-1252 document */
1613  b = VARIANT_TRUE;
1615  r = IXMLDOMDocument_loadXML( doc, str, &b );
1616  ok( r == S_FALSE, "loadXML succeeded\n");
1617  ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1618  SysFreeString( str );
1619 
1620  /* try to load something valid */
1621  b = VARIANT_FALSE;
1622  str = SysAllocString( szComplete1 );
1623  r = IXMLDOMDocument_loadXML( doc, str, &b );
1624  ok( r == S_OK, "loadXML failed\n");
1625  ok( b == VARIANT_TRUE, "failed to load XML string\n");
1626  SysFreeString( str );
1627 
1628  /* check if nodename is correct */
1629  r = IXMLDOMDocument_get_nodeName( doc, NULL );
1630  ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1631 
1632  str = (void *)0xdeadbeef;
1633  r = IXMLDOMDocument_get_baseName( doc, &str );
1634  ok ( r == S_FALSE, "got 0x%08x\n", r);
1635  ok (str == NULL, "got %p\n", str);
1636 
1637  /* content doesn't matter here */
1638  str = NULL;
1639  r = IXMLDOMDocument_get_nodeName( doc, &str );
1640  ok ( r == S_OK, "get_nodeName wrong code\n");
1641  ok ( str != NULL, "str is null\n");
1642  ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1643  SysFreeString( str );
1644 
1645  /* test put_text */
1646  r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
1647  ok( r == E_FAIL, "ret %08x\n", r );
1648 
1649  /* check that there's a document element */
1650  element = NULL;
1651  r = IXMLDOMDocument_get_documentElement( doc, &element );
1652  ok( r == S_OK, "should be a document element\n");
1653  if( element )
1654  {
1656 
1657  r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1658  ok( r == E_NOINTERFACE, "ret %08x\n", r);
1659 
1660  IXMLDOMElement_Release( element );
1661  element = NULL;
1662  }
1663 
1664  /* as soon as we call loadXML again, the document element will disappear */
1665  b = 2;
1666  r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1667  ok( r == S_FALSE, "loadXML failed\n");
1668  ok( b == 2, "variant modified\n");
1669  r = IXMLDOMDocument_get_documentElement( doc, &element );
1670  ok( r == S_FALSE, "should be no document element\n");
1671 
1672  /* try to load something else simple and valid */
1673  b = VARIANT_FALSE;
1674  str = SysAllocString( szComplete2 );
1675  r = IXMLDOMDocument_loadXML( doc, str, &b );
1676  ok( r == S_OK, "loadXML failed\n");
1677  ok( b == VARIANT_TRUE, "failed to load XML string\n");
1678  SysFreeString( str );
1679 
1680  /* try something a little more complicated */
1681  b = FALSE;
1682  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1683  ok( r == S_OK, "loadXML failed\n");
1684  ok( b == VARIANT_TRUE, "failed to load XML string\n");
1685 
1686  r = IXMLDOMDocument_get_parseError( doc, &error );
1687  ok( r == S_OK, "returns %08x\n", r );
1688 
1689  r = IXMLDOMParseError_get_errorCode( error, &code );
1690  ok( r == S_FALSE, "returns %08x\n", r );
1691  ok( code == 0, "code %d\n", code );
1692  IXMLDOMParseError_Release( error );
1693 
1694  /* test createTextNode */
1695  r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1696  ok( r == S_OK, "returns %08x\n", r );
1697  IXMLDOMText_Release(nodetext);
1698 
1699  str = SysAllocString( szOpen );
1700  r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1701  ok( r == E_INVALIDARG, "returns %08x\n", r );
1702  r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1703  ok( r == S_OK, "returns %08x\n", r );
1704  SysFreeString( str );
1705  if(nodetext)
1706  {
1707  r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1708  ok(r == E_NOINTERFACE, "ret %08x\n", r );
1709 
1710  /* Text Last Child Checks */
1711  r = IXMLDOMText_get_lastChild(nodetext, NULL);
1712  ok(r == E_INVALIDARG, "ret %08x\n", r );
1713 
1714  nodeChild = (IXMLDOMNode*)0x1;
1715  r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1716  ok(r == S_FALSE, "ret %08x\n", r );
1717  ok(nodeChild == NULL, "nodeChild not NULL\n");
1718 
1719  /* test length property */
1720  r = IXMLDOMText_get_length(nodetext, NULL);
1721  ok(r == E_INVALIDARG, "ret %08x\n", r );
1722 
1723  r = IXMLDOMText_get_length(nodetext, &nLength);
1724  ok(r == S_OK, "ret %08x\n", r );
1725  ok(nLength == 4, "expected 4 got %d\n", nLength);
1726 
1727  /* put data Tests */
1728  r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1729  ok(r == S_OK, "ret %08x\n", r );
1730 
1731  /* get data Tests */
1732  r = IXMLDOMText_get_data(nodetext, &str);
1733  ok(r == S_OK, "ret %08x\n", r );
1734  ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1735  SysFreeString(str);
1736 
1737  /* Confirm XML text is good */
1738  r = IXMLDOMText_get_xml(nodetext, &str);
1739  ok(r == S_OK, "ret %08x\n", r );
1740  ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
1741  SysFreeString(str);
1742 
1743  /* Confirm we get the put_data Text back */
1744  r = IXMLDOMText_get_text(nodetext, &str);
1745  ok(r == S_OK, "ret %08x\n", r );
1746  ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1747  SysFreeString(str);
1748 
1749  /* test substringData */
1750  r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1751  ok(r == E_INVALIDARG, "ret %08x\n", r );
1752 
1753  /* test substringData - Invalid offset */
1754  str = (void *)0xdeadbeef;
1755  r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1756  ok(r == E_INVALIDARG, "ret %08x\n", r );
1757  ok( str == NULL, "incorrect string\n");
1758 
1759  /* test substringData - Invalid offset */
1760  str = (void *)0xdeadbeef;
1761  r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1762  ok(r == S_FALSE, "ret %08x\n", r );
1763  ok( str == NULL, "incorrect string\n");
1764 
1765  /* test substringData - Invalid size */
1766  str = (void *)0xdeadbeef;
1767  r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1768  ok(r == E_INVALIDARG, "ret %08x\n", r );
1769  ok( str == NULL, "incorrect string\n");
1770 
1771  /* test substringData - Invalid size */
1772  str = (void *)0xdeadbeef;
1773  r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1774  ok(r == S_FALSE, "ret %08x\n", r );
1775  ok( str == NULL, "incorrect string\n");
1776 
1777  /* test substringData - Start of string */
1778  r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1779  ok(r == S_OK, "ret %08x\n", r );
1780  ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1781  SysFreeString(str);
1782 
1783  /* test substringData - Middle of string */
1784  r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1785  ok(r == S_OK, "ret %08x\n", r );
1786  ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1787  SysFreeString(str);
1788 
1789  /* test substringData - End of string */
1790  r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1791  ok(r == S_OK, "ret %08x\n", r );
1792  ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1793  SysFreeString(str);
1794 
1795  /* test appendData */
1796  r = IXMLDOMText_appendData(nodetext, NULL);
1797  ok(r == S_OK, "ret %08x\n", r );
1798 
1799  r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1800  ok(r == S_OK, "ret %08x\n", r );
1801 
1802  r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1803  ok(r == S_OK, "ret %08x\n", r );
1804 
1805  r = IXMLDOMText_get_text(nodetext, &str);
1806  ok(r == S_OK, "ret %08x\n", r );
1807  ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1808  SysFreeString(str);
1809 
1810  /* test insertData */
1811  str = SysAllocStringLen(NULL, 0);
1812  r = IXMLDOMText_insertData(nodetext, -1, str);
1813  ok(r == S_OK, "ret %08x\n", r );
1814 
1815  r = IXMLDOMText_insertData(nodetext, -1, NULL);
1816  ok(r == S_OK, "ret %08x\n", r );
1817 
1818  r = IXMLDOMText_insertData(nodetext, 1000, str);
1819  ok(r == S_OK, "ret %08x\n", r );
1820 
1821  r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1822  ok(r == S_OK, "ret %08x\n", r );
1823 
1824  r = IXMLDOMText_insertData(nodetext, 0, NULL);
1825  ok(r == S_OK, "ret %08x\n", r );
1826 
1827  r = IXMLDOMText_insertData(nodetext, 0, str);
1828  ok(r == S_OK, "ret %08x\n", r );
1829  SysFreeString(str);
1830 
1831  r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1832  ok(r == E_INVALIDARG, "ret %08x\n", r );
1833 
1834  r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1835  ok(r == E_INVALIDARG, "ret %08x\n", r );
1836 
1837  r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1838  ok(r == S_OK, "ret %08x\n", r );
1839 
1840  r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1841  ok(r == S_OK, "ret %08x\n", r );
1842 
1843  r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1844  ok(r == S_OK, "ret %08x\n", r );
1845 
1846  r = IXMLDOMText_get_text(nodetext, &str);
1847  ok(r == S_OK, "ret %08x\n", r );
1848  ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1849  SysFreeString(str);
1850 
1851  /* delete data */
1852  /* invalid arguments */
1853  r = IXMLDOMText_deleteData(nodetext, -1, 1);
1854  ok(r == E_INVALIDARG, "ret %08x\n", r );
1855 
1856  r = IXMLDOMText_deleteData(nodetext, 0, 0);
1857  ok(r == S_OK, "ret %08x\n", r );
1858 
1859  r = IXMLDOMText_deleteData(nodetext, 0, -1);
1860  ok(r == E_INVALIDARG, "ret %08x\n", r );
1861 
1862  r = IXMLDOMText_get_length(nodetext, &nLength);
1863  ok(r == S_OK, "ret %08x\n", r );
1864  ok(nLength == 43, "expected 43 got %d\n", nLength);
1865 
1866  r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1867  ok(r == S_OK, "ret %08x\n", r );
1868 
1869  r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1870  ok(r == E_INVALIDARG, "ret %08x\n", r );
1871 
1872  /* delete from start */
1873  r = IXMLDOMText_deleteData(nodetext, 0, 5);
1874  ok(r == S_OK, "ret %08x\n", r );
1875 
1876  r = IXMLDOMText_get_length(nodetext, &nLength);
1877  ok(r == S_OK, "ret %08x\n", r );
1878  ok(nLength == 38, "expected 38 got %d\n", nLength);
1879 
1880  r = IXMLDOMText_get_text(nodetext, &str);
1881  ok(r == S_OK, "ret %08x\n", r );
1882  ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1883  SysFreeString(str);
1884 
1885  /* delete from end */
1886  r = IXMLDOMText_deleteData(nodetext, 35, 3);
1887  ok(r == S_OK, "ret %08x\n", r );
1888 
1889  r = IXMLDOMText_get_length(nodetext, &nLength);
1890  ok(r == S_OK, "ret %08x\n", r );
1891  ok(nLength == 35, "expected 35 got %d\n", nLength);
1892 
1893  r = IXMLDOMText_get_text(nodetext, &str);
1894  ok(r == S_OK, "ret %08x\n", r );
1895  ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1896  SysFreeString(str);
1897 
1898  /* delete from inside */
1899  r = IXMLDOMText_deleteData(nodetext, 1, 33);
1900  ok(r == S_OK, "ret %08x\n", r );
1901 
1902  r = IXMLDOMText_get_length(nodetext, &nLength);
1903  ok(r == S_OK, "ret %08x\n", r );
1904  ok(nLength == 2, "expected 2 got %d\n", nLength);
1905 
1906  r = IXMLDOMText_get_text(nodetext, &str);
1907  ok(r == S_OK, "ret %08x\n", r );
1908  ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1909  SysFreeString(str);
1910 
1911  /* delete whole data ... */
1912  r = IXMLDOMText_get_length(nodetext, &nLength);
1913  ok(r == S_OK, "ret %08x\n", r );
1914 
1915  r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1916  ok(r == S_OK, "ret %08x\n", r );
1917  /* ... and try again with empty string */
1918  r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1919  ok(r == S_OK, "ret %08x\n", r );
1920 
1921  /* test put_data */
1922  V_VT(&var) = VT_BSTR;
1923  V_BSTR(&var) = SysAllocString(szstr1);
1924  r = IXMLDOMText_put_nodeValue(nodetext, var);
1925  ok(r == S_OK, "ret %08x\n", r );
1926  VariantClear(&var);
1927 
1928  r = IXMLDOMText_get_text(nodetext, &str);
1929  ok(r == S_OK, "ret %08x\n", r );
1930  ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1931  SysFreeString(str);
1932 
1933  /* test put_data */
1934  V_VT(&var) = VT_I4;
1935  V_I4(&var) = 99;
1936  r = IXMLDOMText_put_nodeValue(nodetext, var);
1937  ok(r == S_OK, "ret %08x\n", r );
1938  VariantClear(&var);
1939 
1940  r = IXMLDOMText_get_text(nodetext, &str);
1941  ok(r == S_OK, "ret %08x\n", r );
1942  ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1943  SysFreeString(str);
1944 
1945  /* ::replaceData() */
1946  V_VT(&var) = VT_BSTR;
1947  V_BSTR(&var) = SysAllocString(szstr1);
1948  r = IXMLDOMText_put_nodeValue(nodetext, var);
1949  ok(r == S_OK, "ret %08x\n", r );
1950  VariantClear(&var);
1951 
1952  r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1953  ok(r == E_INVALIDARG, "ret %08x\n", r );
1954  r = IXMLDOMText_get_text(nodetext, &str);
1955  ok(r == S_OK, "ret %08x\n", r );
1956  ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1957  SysFreeString(str);
1958 
1959  r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1960  ok(r == S_OK, "ret %08x\n", r );
1961  r = IXMLDOMText_get_text(nodetext, &str);
1962  ok(r == S_OK, "ret %08x\n", r );
1963  ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1964  SysFreeString(str);
1965 
1966  /* NULL pointer means delete */
1967  r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1968  ok(r == S_OK, "ret %08x\n", r );
1969  r = IXMLDOMText_get_text(nodetext, &str);
1970  ok(r == S_OK, "ret %08x\n", r );
1971  ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1972  SysFreeString(str);
1973 
1974  /* empty string means delete */
1975  r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1976  ok(r == S_OK, "ret %08x\n", r );
1977  r = IXMLDOMText_get_text(nodetext, &str);
1978  ok(r == S_OK, "ret %08x\n", r );
1979  ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1980  SysFreeString(str);
1981 
1982  /* zero count means insert */
1983  r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1984  ok(r == S_OK, "ret %08x\n", r );
1985  r = IXMLDOMText_get_text(nodetext, &str);
1986  ok(r == S_OK, "ret %08x\n", r );
1987  ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1988  SysFreeString(str);
1989 
1990  r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1991  ok(r == S_OK, "ret %08x\n", r );
1992 
1993  r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1994  ok(r == S_OK, "ret %08x\n", r );
1995  r = IXMLDOMText_get_text(nodetext, &str);
1996  ok(r == S_OK, "ret %08x\n", r );
1997  ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1998  SysFreeString(str);
1999 
2000  /* nonempty string, count greater than its length */
2001  r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
2002  ok(r == S_OK, "ret %08x\n", r );
2003  r = IXMLDOMText_get_text(nodetext, &str);
2004  ok(r == S_OK, "ret %08x\n", r );
2005  ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2006  SysFreeString(str);
2007 
2008  /* nonempty string, count less than its length */
2009  r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
2010  ok(r == S_OK, "ret %08x\n", r );
2011  r = IXMLDOMText_get_text(nodetext, &str);
2012  ok(r == S_OK, "ret %08x\n", r );
2013  ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
2014  SysFreeString(str);
2015 
2016  IXMLDOMText_Release( nodetext );
2017  }
2018 
2019  /* test Create Comment */
2020  r = IXMLDOMDocument_createComment(doc, NULL, NULL);
2021  ok( r == E_INVALIDARG, "returns %08x\n", r );
2022  node_comment = (IXMLDOMComment*)0x1;
2023 
2024  /* empty comment */
2025  r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
2026  ok( r == S_OK, "returns %08x\n", r );
2027  str = NULL;
2028  r = IXMLDOMComment_get_data(node_comment, &str);
2029  ok( r == S_OK, "returns %08x\n", r );
2030  ok( str && SysStringLen(str) == 0, "expected empty string data\n");
2031  IXMLDOMComment_Release(node_comment);
2032  SysFreeString(str);
2033 
2034  r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
2035  ok( r == S_OK, "returns %08x\n", r );
2036  str = NULL;
2037  r = IXMLDOMComment_get_data(node_comment, &str);
2038  ok( r == S_OK, "returns %08x\n", r );
2039  ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
2040  IXMLDOMComment_Release(node_comment);
2041  SysFreeString(str);
2042 
2043  str = SysAllocString(szComment);
2044  r = IXMLDOMDocument_createComment(doc, str, &node_comment);
2045  SysFreeString(str);
2046  ok( r == S_OK, "returns %08x\n", r );
2047  if(node_comment)
2048  {
2049  /* Last Child Checks */
2050  r = IXMLDOMComment_get_lastChild(node_comment, NULL);
2051  ok(r == E_INVALIDARG, "ret %08x\n", r );
2052 
2053  nodeChild = (IXMLDOMNode*)0x1;
2054  r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
2055  ok(r == S_FALSE, "ret %08x\n", r );
2056  ok(nodeChild == NULL, "pLastChild not NULL\n");
2057 
2058  /* baseName */
2059  str = (void *)0xdeadbeef;
2060  r = IXMLDOMComment_get_baseName(node_comment, &str);
2061  ok(r == S_FALSE, "ret %08x\n", r );
2062  ok(str == NULL, "Expected NULL\n");
2063 
2064  IXMLDOMComment_Release( node_comment );
2065  }
2066 
2067  /* test Create Attribute */
2068  str = SysAllocString(szAttribute);
2069  r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
2070  ok( r == E_INVALIDARG, "returns %08x\n", r );
2071  r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
2072  ok( r == S_OK, "returns %08x\n", r );
2073  IXMLDOMAttribute_Release( node_attr);
2074  SysFreeString(str);
2075 
2076  /* test Processing Instruction */
2077  str = SysAllocStringLen(NULL, 0);
2078  r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
2079  ok( r == E_INVALIDARG, "returns %08x\n", r );
2080  r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
2081  ok( r == E_FAIL, "returns %08x\n", r );
2082  r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
2083  ok( r == E_FAIL, "returns %08x\n", r );
2084  SysFreeString(str);
2085 
2086  r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
2087  ok( r == S_OK, "returns %08x\n", r );
2088  if(nodePI)
2089  {
2090  /* Last Child Checks */
2091  r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
2092  ok(r == E_INVALIDARG, "ret %08x\n", r );
2093 
2094  nodeChild = (IXMLDOMNode*)0x1;
2095  r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
2096  ok(r == S_FALSE, "ret %08x\n", r );
2097  ok(nodeChild == NULL, "nodeChild not NULL\n");
2098 
2099  /* test nodeName */
2100  r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2101  ok(r == S_OK, "ret %08x\n", r );
2102  ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2103  SysFreeString(str);
2104 
2105  /* test baseName */
2106  str = NULL;
2107  r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
2108  ok(r == S_OK, "ret %08x\n", r );
2109  ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2110  SysFreeString(str);
2111 
2112  /* test Target */
2113  r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
2114  ok(r == S_OK, "ret %08x\n", r );
2115  ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
2116  SysFreeString(str);
2117 
2118  /* test get_data */
2119  r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
2120  ok(r == S_OK, "ret %08x\n", r );
2121  ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
2122  SysFreeString(str);
2123 
2124  /* test put_data */
2125  r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
2126  ok(r == E_FAIL, "ret %08x\n", r );
2127 
2128  /* test put_data */
2129  V_VT(&var) = VT_BSTR;
2130  V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
2131  r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
2132  ok(r == E_FAIL, "ret %08x\n", r );
2133  VariantClear(&var);
2134 
2135  /* test get nodeName */
2136  r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
2137  ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
2138  ok(r == S_OK, "ret %08x\n", r );
2139  SysFreeString(str);
2140 
2141  IXMLDOMProcessingInstruction_Release(nodePI);
2142  }
2143 
2144  ref = IXMLDOMDocument_Release( doc );
2145  ok( ref == 0, "got %d\n", ref);
2146 
2147  free_bstrs();
2148 }
2149 
2150 static void test_persiststream(void)
2151 {
2152  IPersistStreamInit *streaminit;
2154  IXMLDOMDocument *doc;
2156  IPersist *persist;
2157  HRESULT hr;
2158  CLSID clsid;
2159 
2160  doc = create_document(&IID_IXMLDOMDocument);
2161 
2162  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
2163  ok(hr == S_OK, "got 0x%08x\n", hr);
2164 
2165  hr = IPersistStreamInit_InitNew(streaminit);
2166  ok(hr == S_OK, "got 0x%08x\n", hr);
2167 
2168  hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
2169  ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
2170 
2171  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStream, (void **)&stream);
2172  ok(hr == S_OK, "got 0x%08x\n", hr);
2173  ok((IUnknown *)stream == (IUnknown *)streaminit, "got %p, %p\n", stream, streaminit);
2174 
2175  hr = IPersistStream_QueryInterface(stream, &IID_IPersist, (void **)&persist);
2176  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2177 
2178  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersist, (void **)&persist);
2179  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2180 
2181  hr = IPersistStreamInit_GetClassID(streaminit, NULL);
2182  ok(hr == E_POINTER, "got 0x%08x\n", hr);
2183 
2184  memset(&clsid, 0, sizeof(clsid));
2185  hr = IPersistStreamInit_GetClassID(streaminit, &clsid);
2186  ok(hr == S_OK, "got 0x%08x\n", hr);
2187  ok(IsEqualGUID(&clsid, &CLSID_DOMDocument2), "wrong clsid %s\n", wine_dbgstr_guid(&clsid));
2188 
2189  IPersistStream_Release(stream);
2190  IPersistStreamInit_Release(streaminit);
2191  IXMLDOMDocument_Release(doc);
2192 }
2193 
2194 static void test_domnode( void )
2195 {
2196  HRESULT r;
2197  IXMLDOMDocument *doc, *owner = NULL;
2200  IXMLDOMNode *node = NULL, *next = NULL;
2204  VARIANT_BOOL b;
2205  BSTR str;
2206  VARIANT var;
2207  LONG count;
2208 
2209  doc = create_document(&IID_IXMLDOMDocument);
2210 
2211  b = FALSE;
2212  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2213  ok( r == S_OK, "loadXML failed\n");
2214  ok( b == VARIANT_TRUE, "failed to load XML string\n");
2215 
2216  EXPECT_CHILDREN(doc);
2217 
2218  r = IXMLDOMDocument_get_documentElement( doc, &element );
2219  ok( r == S_OK, "should be a document element\n");
2220  ok( element != NULL, "should be an element\n");
2221 
2222  VariantInit(&var);
2223  ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
2224 
2225  r = IXMLDOMDocument_get_nodeValue( doc, NULL );
2226  ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
2227 
2228  r = IXMLDOMDocument_get_nodeValue( doc, &var );
2229  ok( r == S_FALSE, "nextNode returned wrong code\n");
2230  ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
2231  ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
2232 
2233  if (element)
2234  {
2235  owner = NULL;
2236  r = IXMLDOMElement_get_ownerDocument( element, &owner );
2237  ok( r == S_OK, "get_ownerDocument return code\n");
2238  ok( owner != doc, "get_ownerDocument return\n");
2239  IXMLDOMDocument_Release(owner);
2240 
2241  type = NODE_INVALID;
2242  r = IXMLDOMElement_get_nodeType( element, &type);
2243  ok( r == S_OK, "got %08x\n", r);
2244  ok( type == NODE_ELEMENT, "node not an element\n");
2245 
2246  str = NULL;
2247  r = IXMLDOMElement_get_baseName( element, &str );
2248  ok( r == S_OK, "get_baseName returned wrong code\n");
2249  ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
2250  SysFreeString(str);
2251 
2252  /* check if nodename is correct */
2253  r = IXMLDOMElement_get_nodeName( element, NULL );
2254  ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2255 
2256  /* content doesn't matter here */
2257  str = NULL;
2258  r = IXMLDOMElement_get_nodeName( element, &str );
2259  ok ( r == S_OK, "get_nodeName wrong code\n");
2260  ok ( str != NULL, "str is null\n");
2261  ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
2262  SysFreeString( str );
2263 
2265  V_VT(&var) = VT_I4;
2266  V_I4(&var) = 0x1234;
2267  r = IXMLDOMElement_getAttribute( element, str, &var );
2268  ok( r == E_FAIL, "getAttribute ret %08x\n", r );
2269  ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
2270  VariantClear(&var);
2271  SysFreeString(str);
2272 
2273  str = SysAllocString( szdl );
2274  V_VT(&var) = VT_I4;
2275  V_I4(&var) = 0x1234;
2276  r = IXMLDOMElement_getAttribute( element, str, &var );
2277  ok( r == S_OK, "getAttribute ret %08x\n", r );
2278  ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
2279  ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
2280  VariantClear( &var );
2281 
2282  r = IXMLDOMElement_getAttribute( element, NULL, &var );
2283  ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2284 
2285  r = IXMLDOMElement_getAttribute( element, str, NULL );
2286  ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
2287 
2288  attr = NULL;
2289  r = IXMLDOMElement_getAttributeNode( element, str, &attr);
2290  ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
2291  ok( attr != NULL, "getAttributeNode returned NULL\n" );
2292  if (attr)
2293  {
2294  r = IXMLDOMAttribute_get_parentNode( attr, NULL );
2295  ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
2296 
2297  /* attribute doesn't have a parent in msxml interpretation */
2298  node = (IXMLDOMNode*)0xdeadbeef;
2299  r = IXMLDOMAttribute_get_parentNode( attr, &node );
2300  ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
2301  ok( node == NULL, "Expected NULL, got %p\n", node );
2302 
2303  IXMLDOMAttribute_Release(attr);
2304  }
2305 
2306  SysFreeString( str );
2307 
2308  r = IXMLDOMElement_get_attributes( element, &map );
2309  ok( r == S_OK, "get_attributes returned wrong code\n");
2310  ok( map != NULL, "should be attributes\n");
2311 
2312  EXPECT_CHILDREN(element);
2313  }
2314  else
2315  ok( FALSE, "no element\n");
2316 
2317  if (map)
2318  {
2319  str = SysAllocString( szdl );
2320  r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2321  ok( r == S_OK, "getNamedItem returned wrong code\n");
2322  ok( node != NULL, "should be attributes\n");
2323  IXMLDOMNode_Release(node);
2324  SysFreeString( str );
2325 
2326  str = SysAllocString( szdl );
2327  r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2328  ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2329  SysFreeString( str );
2330 
2331  /* something that isn't in complete4A */
2332  str = SysAllocString( szOpen );
2333  node = (IXMLDOMNode *) 1;
2334  r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2335  ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2336  ok( node == NULL, "getNamedItem should have returned NULL\n");
2337  SysFreeString( str );
2338 
2339  /* test indexed access of attributes */
2340  r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2341  ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2342 
2343  r = IXMLDOMNamedNodeMap_get_length( map, &count );
2344  ok ( r == S_OK, "get_length wrong code\n");
2345  ok ( count == 1, "get_length != 1\n");
2346 
2347  node = NULL;
2348  r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2349  ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2350  ok ( node == NULL, "there is no node\n");
2351 
2352  node = NULL;
2353  r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2354  ok ( r == S_FALSE, "get_item (1) wrong code\n");
2355  ok ( node == NULL, "there is no attribute\n");
2356 
2357  node = NULL;
2358  r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2359  ok ( r == S_OK, "get_item (0) wrong code\n");
2360  ok ( node != NULL, "should be attribute\n");
2361 
2362  r = IXMLDOMNode_get_nodeName( node, NULL );
2363  ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2364 
2365  /* content doesn't matter here */
2366  str = NULL;
2367  r = IXMLDOMNode_get_nodeName( node, &str );
2368  ok ( r == S_OK, "get_nodeName wrong code\n");
2369  ok ( str != NULL, "str is null\n");
2370  ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2371  SysFreeString( str );
2372  IXMLDOMNode_Release( node );
2373 
2374  /* test sequential access of attributes */
2375  node = NULL;
2376  r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2377  ok ( r == S_OK, "nextNode (first time) wrong code\n");
2378  ok ( node != NULL, "nextNode, should be attribute\n");
2379  IXMLDOMNode_Release( node );
2380 
2381  r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2382  ok ( r != S_OK, "nextNode (second time) wrong code\n");
2383  ok ( node == NULL, "nextNode, there is no attribute\n");
2384 
2385  r = IXMLDOMNamedNodeMap_reset( map );
2386  ok ( r == S_OK, "reset should return S_OK\n");
2387 
2388  r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2389  ok ( r == S_OK, "nextNode (third time) wrong code\n");
2390  ok ( node != NULL, "nextNode, should be attribute\n");
2391  }
2392  else
2393  ok( FALSE, "no map\n");
2394 
2395  if (node)
2396  {
2397  type = NODE_INVALID;
2398  r = IXMLDOMNode_get_nodeType( node, &type);
2399  ok( r == S_OK, "getNamedItem returned wrong code\n");
2400  ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2401 
2402  str = NULL;
2403  r = IXMLDOMNode_get_baseName( node, NULL );
2404  ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2405 
2406  str = NULL;
2407  r = IXMLDOMNode_get_baseName( node, &str );
2408  ok( r == S_OK, "get_baseName returned wrong code\n");
2409  ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2410  SysFreeString( str );
2411 
2412  r = IXMLDOMNode_get_childNodes( node, NULL );
2413  ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2414 
2415  r = IXMLDOMNode_get_childNodes( node, &list );
2416  ok( r == S_OK, "get_childNodes returned wrong code\n");
2417 
2418  if (list)
2419  {
2420  r = IXMLDOMNodeList_nextNode( list, &next );
2421  ok( r == S_OK, "nextNode returned wrong code\n");
2422  }
2423  else
2424  ok( FALSE, "no childlist\n");
2425 
2426  if (next)
2427  {
2428  EXPECT_NO_CHILDREN(next);
2429 
2430  type = NODE_INVALID;
2431  r = IXMLDOMNode_get_nodeType( next, &type);
2432  ok( r == S_OK, "getNamedItem returned wrong code\n");
2433  ok( type == NODE_TEXT, "node not text\n");
2434 
2435  str = (void *)0xdeadbeef;
2436  r = IXMLDOMNode_get_baseName( next, &str );
2437  ok( r == S_FALSE, "get_baseName returned wrong code\n");
2438  ok( str == NULL, "basename was wrong\n");
2439  SysFreeString(str);
2440  }
2441  else
2442  ok( FALSE, "no next\n");
2443 
2444  if (next)
2445  IXMLDOMNode_Release( next );
2446  next = NULL;
2447  if (list)
2448  IXMLDOMNodeList_Release( list );
2449  list = NULL;
2450  if (node)
2451  IXMLDOMNode_Release( node );
2452  }
2453  else
2454  ok( FALSE, "no node\n");
2455  node = NULL;
2456 
2457  if (map)
2458  IXMLDOMNamedNodeMap_Release( map );
2459 
2460  /* now traverse the tree from the root element */
2461  if (element)
2462  {
2463  r = IXMLDOMElement_get_childNodes( element, &list );
2464  ok( r == S_OK, "get_childNodes returned wrong code\n");
2465 
2466  /* using get_item for child list doesn't advance the position */
2467  ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2468  expect_node(node, "E2.E2.D1");
2469  IXMLDOMNode_Release(node);
2470  ole_check(IXMLDOMNodeList_nextNode(list, &node));
2471  expect_node(node, "E1.E2.D1");
2472  IXMLDOMNode_Release(node);
2473  ole_check(IXMLDOMNodeList_reset(list));
2474 
2475  IXMLDOMNodeList_AddRef(list);
2476  expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2477  ole_check(IXMLDOMNodeList_reset(list));
2478 
2479  node = (void*)0xdeadbeef;
2480  str = SysAllocString(szdl);
2481  r = IXMLDOMElement_selectSingleNode( element, str, &node );
2482  SysFreeString(str);
2483  ok( r == S_FALSE, "ret %08x\n", r );
2484  ok( node == NULL, "node %p\n", node );
2485 
2486  str = SysAllocString(szbs);
2487  r = IXMLDOMElement_selectSingleNode( element, str, &node );
2488  SysFreeString(str);
2489  ok( r == S_OK, "ret %08x\n", r );
2490  r = IXMLDOMNode_Release( node );
2491  ok( r == 0, "ret %08x\n", r );
2492  }
2493  else
2494  ok( FALSE, "no element\n");
2495 
2496  if (list)
2497  {
2498  r = IXMLDOMNodeList_get_item(list, 0, NULL);
2499  ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2500 
2501  r = IXMLDOMNodeList_get_length(list, NULL);
2502  ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2503 
2504  r = IXMLDOMNodeList_get_length( list, &count );
2505  ok( r == S_OK, "get_length returns %08x\n", r );
2506  ok( count == 4, "get_length got %d\n", count );
2507 
2508  r = IXMLDOMNodeList_nextNode(list, NULL);
2509  ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2510 
2511  r = IXMLDOMNodeList_nextNode( list, &node );
2512  ok( r == S_OK, "nextNode returned wrong code\n");
2513  }
2514  else
2515  ok( FALSE, "no list\n");
2516 
2517  if (node)
2518  {
2519  type = NODE_INVALID;
2520  r = IXMLDOMNode_get_nodeType( node, &type);
2521  ok( r == S_OK, "getNamedItem returned wrong code\n");
2522  ok( type == NODE_ELEMENT, "node not text\n");
2523 
2524  r = IXMLDOMNode_hasChildNodes( node, NULL );
2525  ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
2526 
2527  EXPECT_CHILDREN(node);
2528 
2529  str = NULL;
2530  r = IXMLDOMNode_get_baseName( node, &str );
2531  ok( r == S_OK, "get_baseName returned wrong code\n");
2532  ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
2533  SysFreeString(str);
2534  }
2535  else
2536  ok( FALSE, "no node\n");
2537 
2538  if (node)
2539  IXMLDOMNode_Release( node );
2540  if (list)
2541  IXMLDOMNodeList_Release( list );
2542  if (element)
2543  IXMLDOMElement_Release( element );
2544 
2545  b = FALSE;
2546  str = SysAllocString( szComplete5 );
2547  r = IXMLDOMDocument_loadXML( doc, str, &b );
2548  ok( r == S_OK, "loadXML failed\n");
2549  ok( b == VARIANT_TRUE, "failed to load XML string\n");
2550  SysFreeString( str );
2551 
2552  EXPECT_CHILDREN(doc);
2553 
2554  r = IXMLDOMDocument_get_documentElement( doc, &element );
2555  ok( r == S_OK, "should be a document element\n");
2556  ok( element != NULL, "should be an element\n");
2557 
2558  if (element)
2559  {
2560  static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
2561  BSTR tag = NULL;
2562 
2563  /* check if the tag is correct */
2564  r = IXMLDOMElement_get_tagName( element, &tag );
2565  ok( r == S_OK, "couldn't get tag name\n");
2566  ok( tag != NULL, "tag was null\n");
2567  ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
2568  SysFreeString( tag );
2569 
2570  IXMLDOMElement_Release( element );
2571  }
2572  ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2573 
2574  free_bstrs();
2575 }
2576 
2577 typedef struct {
2580 } refcount_test_t;
2581 
2582 static const refcount_test_t refcount_test[] = {
2583  { NODE_ELEMENT, &IID_IXMLDOMElement },
2584  { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute },
2585  { NODE_TEXT, &IID_IXMLDOMText },
2586  { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection },
2587  { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference },
2588  { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
2589  { NODE_COMMENT, &IID_IXMLDOMComment },
2590  { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment },
2591  { NODE_INVALID, &IID_NULL }
2592 };
2593 
2594 static void test_refs(void)
2595 {
2596  IXMLDOMImplementation *impl, *impl2;
2597  IXMLDOMElement *element, *elem2;
2598  IXMLDOMNodeList *node_list = NULL;
2599  IXMLDOMNode *node, *node2, *node3;
2600  const refcount_test_t *ptr;
2601  IXMLDOMDocument *doc;
2602  IUnknown *unk, *unk2;
2603  VARIANT_BOOL b;
2604  HRESULT hr;
2605  LONG ref;
2606 
2607  doc = create_document(&IID_IXMLDOMDocument);
2608 
2609  ptr = refcount_test;
2610  while (ptr->type != NODE_INVALID)
2611  {
2612  IUnknown *node_typed, *node_typed2;
2613  IDispatchEx *dispex, *dispex2;
2614  IDispatch *disp, *disp2;
2615  VARIANT type;
2616 
2617  V_VT(&type) = VT_I1;
2618  V_I1(&type) = ptr->type;
2619 
2620  EXPECT_REF(doc, 1);
2621  hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
2622  EXPECT_HR(hr, S_OK);
2623  EXPECT_REF(doc, 1);
2624  EXPECT_REF(node, 1);
2625 
2626  /* try IDispatch and IUnknown from IXMLDOMNode */
2627  hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
2628  EXPECT_HR(hr, S_OK);
2629  EXPECT_REF(unk, 2);
2630 todo_wine {
2631  EXPECT_REF(node, 1);
2632  ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
2633 }
2634  EXPECT_REF(unk, 2);
2635  hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2636  EXPECT_HR(hr, S_OK);
2637  todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
2638  EXPECT_REF(unk, 3);
2639  todo_wine EXPECT_REF(disp, 1);
2640 
2641  EXPECT_REF(unk, 3);
2642  hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
2643  EXPECT_HR(hr, S_OK);
2644  todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
2645  EXPECT_REF(unk, 4);
2646  todo_wine EXPECT_REF(disp2, 1);
2647 
2648  IDispatch_Release(disp);
2649  IDispatch_Release(disp2);
2650 
2651  /* get IXMLDOMNode from this IUnknown */
2652  EXPECT_REF(unk, 2);
2653  hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
2654  EXPECT_HR(hr, S_OK);
2655  todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
2656  EXPECT_REF(unk, 3);
2657  todo_wine EXPECT_REF(node2, 1);
2658 
2659  EXPECT_REF(unk, 3);
2660  hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
2661  EXPECT_HR(hr, S_OK);
2662  todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
2663  EXPECT_REF(unk, 4);
2664  todo_wine EXPECT_REF(node3, 1);
2665 
2666  IXMLDOMNode_Release(node2);
2667  IXMLDOMNode_Release(node3);
2668 
2669  /* try IDispatchEx from IUnknown */
2670  EXPECT_REF(unk, 2);
2671  hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
2672  EXPECT_HR(hr, S_OK);
2673  ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
2674  EXPECT_REF(unk, 3);
2675  todo_wine EXPECT_REF(dispex, 1);
2676 
2677  EXPECT_REF(unk, 3);
2678  hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
2679  EXPECT_HR(hr, S_OK);
2680  todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
2681  EXPECT_REF(unk, 4);
2682  todo_wine EXPECT_REF(dispex2, 1);
2683 
2684  IDispatchEx_Release(dispex);
2685  IDispatchEx_Release(dispex2);
2686 
2687  /* try corresponding IXMLDOM* */
2688  EXPECT_REF(unk, 2);
2689  hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
2690  EXPECT_HR(hr, S_OK);
2691  EXPECT_REF(unk, 3);
2692  hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
2693  EXPECT_HR(hr, S_OK);
2694  EXPECT_REF(unk, 4);
2695  todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
2696  IUnknown_Release(node_typed);
2697  IUnknown_Release(node_typed2);
2698 
2699  /* try invalid IXMLDOM* */
2700  hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
2701  EXPECT_HR(hr, E_NOINTERFACE);
2702 
2703  IUnknown_Release(unk);
2704 
2705  EXPECT_REF(node, 1);
2706  hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
2707  EXPECT_HR(hr, S_OK);
2708  EXPECT_REF(node, 2);
2709  ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
2710 
2711  EXPECT_REF(node, 2);
2712  hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
2713  EXPECT_HR(hr, S_OK);
2714  EXPECT_REF(node, 3);
2715 todo_wine {
2716  EXPECT_REF(node_typed, 2);
2717  ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
2718 }
2719  IUnknown_Release(node_typed);
2720 
2721  IXMLDOMNode_Release(node2);
2722  IXMLDOMNode_Release(node);
2723 
2724  ptr++;
2725  }
2726 
2727  EXPECT_REF(doc, 1);
2728  ref = IXMLDOMDocument_Release(doc);
2729  ok( ref == 0, "ref %d\n", ref);
2730 
2731  /* check IUnknown after releasing DOM iface */
2732  doc = create_document(&IID_IXMLDOMDocument);
2733  EXPECT_REF(doc, 1);
2734  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2735  EXPECT_HR(hr, S_OK);
2736 todo_wine {
2737  EXPECT_REF(unk, 3);
2738  EXPECT_REF(doc, 1);
2739 }
2740  IXMLDOMDocument_Release(doc);
2741  EXPECT_REF(unk, 1);
2742  IUnknown_Release(unk);
2743 
2744  doc = create_document(&IID_IXMLDOMDocument);
2745 
2746  EXPECT_REF(doc, 1);
2747  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2748  EXPECT_HR(hr, S_OK);
2749 todo_wine {
2750  EXPECT_REF(unk, 3);
2751  EXPECT_REF(doc, 1);
2752 }
2753  IUnknown_Release(unk);
2754 
2755  /* IXMLDOMImplementation */
2756  EXPECT_REF(doc, 1);
2757  hr = IXMLDOMDocument_get_implementation(doc, &impl);
2758  EXPECT_HR(hr, S_OK);
2759  EXPECT_REF(doc, 1);
2760  EXPECT_REF(impl, 1);
2761  hr = IXMLDOMDocument_get_implementation(doc, &impl2);
2762  EXPECT_HR(hr, S_OK);
2763  EXPECT_REF(doc, 1);
2764  EXPECT_REF(impl2, 1);
2765  ok(impl != impl2, "got %p, %p\n", impl, impl2);
2766  IXMLDOMImplementation_Release(impl);
2767  IXMLDOMImplementation_Release(impl2);
2768 
2769  hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2770  EXPECT_HR(hr, S_OK);
2771  ok( b == VARIANT_TRUE, "failed to load XML string\n");
2772 
2773  EXPECT_REF(doc, 1);
2774  IXMLDOMDocument_AddRef( doc );
2775  EXPECT_REF(doc, 2);
2776  IXMLDOMDocument_AddRef( doc );
2777  EXPECT_REF(doc, 3);
2778 
2779  IXMLDOMDocument_Release( doc );
2780  IXMLDOMDocument_Release( doc );
2781 
2782  EXPECT_REF(doc, 1);
2783  hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2784  EXPECT_HR(hr, S_OK);
2785 todo_wine {
2786  EXPECT_REF(unk, 3);
2787  EXPECT_REF(doc, 1);
2788 }
2789  hr = IXMLDOMDocument_get_documentElement(doc, &element);
2790  EXPECT_HR(hr, S_OK);
2791 todo_wine {
2792  EXPECT_REF(doc, 1);
2793  EXPECT_REF(element, 2);
2794 }
2795  hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
2796  EXPECT_HR(hr, S_OK);
2797 
2798 todo_wine {
2799  EXPECT_REF(doc, 1);
2800  EXPECT_REF(element, 2);
2801  EXPECT_REF(elem2, 2);
2802 }
2803  IXMLDOMElement_AddRef(element);
2804  todo_wine EXPECT_REF(element, 3);
2805  IXMLDOMElement_Release(element);
2806 
2807  /* get IUnknown from a node doesn't touch node instance refcount */
2808  hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2809  EXPECT_HR(hr, S_OK);
2810  EXPECT_REF(element, 2);
2811 todo_wine {
2812  EXPECT_REF(unk, 4);
2813  EXPECT_REF(elem2, 2);
2814 }
2815  hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
2816  EXPECT_HR(hr, S_OK);
2817 todo_wine {
2818  EXPECT_REF(unk, 5);
2819  EXPECT_REF(unk2, 5);
2820 }
2821  EXPECT_REF(element, 2);
2822  EXPECT_REF(elem2, 2);
2823 
2824  todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
2825  IUnknown_Release(unk);
2826 
2827  /* IUnknown refcount is not affected by node refcount */
2828  todo_wine EXPECT_REF(unk2, 4);
2829  IXMLDOMElement_AddRef(elem2);
2830  todo_wine EXPECT_REF(unk2, 4);
2831  IXMLDOMElement_Release(elem2);
2832 
2833  IXMLDOMElement_Release(elem2);
2834  todo_wine EXPECT_REF(unk2, 3);
2835 
2836  IUnknown_Release(unk2);
2837 
2838  hr = IXMLDOMElement_get_childNodes( element, &node_list );
2839  EXPECT_HR(hr, S_OK);
2840 
2841  todo_wine EXPECT_REF(element, 2);
2842  EXPECT_REF(node_list, 1);
2843 
2844  hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
2845  EXPECT_HR(hr, S_OK);
2846  EXPECT_REF(node_list, 1);
2847  EXPECT_REF(node, 1);
2848 
2849  hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2850  EXPECT_HR(hr, S_OK);
2851  EXPECT_REF(node_list, 1);
2852  EXPECT_REF(node2, 1);
2853 
2854  ref = IXMLDOMNode_Release( node );
2855  ok( ref == 0, "ref %d\n", ref );
2856  ref = IXMLDOMNode_Release( node2 );
2857  ok( ref == 0, "ref %d\n", ref );
2858 
2859  ref = IXMLDOMNodeList_Release( node_list );
2860  ok( ref == 0, "ref %d\n", ref );
2861 
2862  ok( node != node2, "node %p node2 %p\n", node, node2 );
2863 
2864  ref = IXMLDOMDocument_Release( doc );
2865  todo_wine ok( ref == 0, "ref %d\n", ref );
2866 
2867  todo_wine EXPECT_REF(element, 2);
2868 
2869  /* IUnknown must be unique however we obtain it */
2870  hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2871  EXPECT_HR(hr, S_OK);
2872  EXPECT_REF(element, 2);
2873  hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
2874  EXPECT_HR(hr, S_OK);
2875  todo_wine EXPECT_REF(element, 2);
2876  hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2877  EXPECT_HR(hr, S_OK);
2878  todo_wine EXPECT_REF(element, 2);
2879  ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
2880  todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
2881 
2882  IUnknown_Release( unk2 );
2883  IUnknown_Release( unk );
2884  IXMLDOMNode_Release( node );
2885  todo_wine EXPECT_REF(element, 2);
2886 
2887  IXMLDOMElement_Release( element );
2888 
2889  free_bstrs();
2890 }
2891 
2892 static void test_create(void)
2893 {
2894  static const WCHAR szOne[] = {'1',0};
2895  static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2896  HRESULT r;
2897  VARIANT var;
2898  BSTR str, name;
2899  IXMLDOMDocument *doc;
2902  IXMLDOMText *text;
2903  IXMLDOMCDATASection *cdata;
2904  IXMLDOMNode *root, *node, *child;
2905  IXMLDOMNamedNodeMap *attr_map;
2906  IUnknown *unk;
2907  LONG ref;
2908  LONG num;
2909 
2910  doc = create_document(&IID_IXMLDOMDocument);
2911 
2912  EXPECT_REF(doc, 1);
2913 
2914  /* types not supported for creation */
2915  V_VT(&var) = VT_I1;
2916  V_I1(&var) = NODE_DOCUMENT;
2917  node = (IXMLDOMNode*)0x1;
2918  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2919  ok( r == E_INVALIDARG, "returns %08x\n", r );
2920  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2921 
2922  V_VT(&var) = VT_I1;
2923  V_I1(&var) = NODE_DOCUMENT_TYPE;
2924  node = (IXMLDOMNode*)0x1;
2925  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2926  ok( r == E_INVALIDARG, "returns %08x\n", r );
2927  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2928 
2929  V_VT(&var) = VT_I1;
2930  V_I1(&var) = NODE_ENTITY;
2931  node = (IXMLDOMNode*)0x1;
2932  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2933  ok( r == E_INVALIDARG, "returns %08x\n", r );
2934  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2935 
2936  V_VT(&var) = VT_I1;
2937  V_I1(&var) = NODE_NOTATION;
2938  node = (IXMLDOMNode*)0x1;
2939  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2940  ok( r == E_INVALIDARG, "returns %08x\n", r );
2941  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2942 
2943  /* NODE_COMMENT */
2944  V_VT(&var) = VT_I1;
2945  V_I1(&var) = NODE_COMMENT;
2946  node = NULL;
2947  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2948  ok( r == S_OK, "returns %08x\n", r );
2949  ok( node != NULL, "\n");
2950 
2951  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2952  ok( r == S_OK, "returns %08x\n", r );
2953  IXMLDOMNode_Release(node);
2954 
2955  str = NULL;
2956  r = IXMLDOMComment_get_data(comment, &str);
2957  ok( r == S_OK, "returns %08x\n", r );
2958  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2959  IXMLDOMComment_Release(comment);
2960  SysFreeString(str);
2961 
2962  node = (IXMLDOMNode*)0x1;
2963  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2964  ok( r == S_OK, "returns %08x\n", r );
2965 
2966  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2967  ok( r == S_OK, "returns %08x\n", r );
2968  IXMLDOMNode_Release(node);
2969 
2970  str = NULL;
2971  r = IXMLDOMComment_get_data(comment, &str);
2972  ok( r == S_OK, "returns %08x\n", r );
2973  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2974  IXMLDOMComment_Release(comment);
2975  SysFreeString(str);
2976 
2977  node = (IXMLDOMNode*)0x1;
2978  r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2979  ok( r == S_OK, "returns %08x\n", r );
2980 
2981  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2982  ok( r == S_OK, "returns %08x\n", r );
2983  IXMLDOMNode_Release(node);
2984 
2985  str = NULL;
2986  r = IXMLDOMComment_get_data(comment, &str);
2987  ok( r == S_OK, "returns %08x\n", r );
2988  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2989  IXMLDOMComment_Release(comment);
2990  SysFreeString(str);
2991 
2992  /* NODE_TEXT */
2993  V_VT(&var) = VT_I1;
2994  V_I1(&var) = NODE_TEXT;
2995  node = NULL;
2996  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2997  ok( r == S_OK, "returns %08x\n", r );
2998  ok( node != NULL, "\n");
2999 
3000  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3001  ok( r == S_OK, "returns %08x\n", r );
3002  IXMLDOMNode_Release(node);
3003 
3004  str = NULL;
3005  r = IXMLDOMText_get_data(text, &str);
3006  ok( r == S_OK, "returns %08x\n", r );
3007  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3008  IXMLDOMText_Release(text);
3009  SysFreeString(str);
3010 
3011  node = (IXMLDOMNode*)0x1;
3012  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3013  ok( r == S_OK, "returns %08x\n", r );
3014 
3015  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3016  ok( r == S_OK, "returns %08x\n", r );
3017  IXMLDOMNode_Release(node);
3018 
3019  str = NULL;
3020  r = IXMLDOMText_get_data(text, &str);
3021  ok( r == S_OK, "returns %08x\n", r );
3022  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3023  IXMLDOMText_Release(text);
3024  SysFreeString(str);
3025 
3026  node = (IXMLDOMNode*)0x1;
3027  r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3028  ok( r == S_OK, "returns %08x\n", r );
3029 
3030  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
3031  ok( r == S_OK, "returns %08x\n", r );
3032  IXMLDOMNode_Release(node);
3033 
3034  str = NULL;
3035  r = IXMLDOMText_get_data(text, &str);
3036  ok( r == S_OK, "returns %08x\n", r );
3037  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3038  IXMLDOMText_Release(text);
3039  SysFreeString(str);
3040 
3041  /* NODE_CDATA_SECTION */
3042  V_VT(&var) = VT_I1;
3043  V_I1(&var) = NODE_CDATA_SECTION;
3044  node = NULL;
3045  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3046  ok( r == S_OK, "returns %08x\n", r );
3047  ok( node != NULL, "\n");
3048 
3049  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3050  ok( r == S_OK, "returns %08x\n", r );
3051  IXMLDOMNode_Release(node);
3052 
3053  str = NULL;
3054  r = IXMLDOMCDATASection_get_data(cdata, &str);
3055  ok( r == S_OK, "returns %08x\n", r );
3056  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3057  IXMLDOMCDATASection_Release(cdata);
3058  SysFreeString(str);
3059 
3060  node = (IXMLDOMNode*)0x1;
3061  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3062  ok( r == S_OK, "returns %08x\n", r );
3063 
3064  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3065  ok( r == S_OK, "returns %08x\n", r );
3066  IXMLDOMNode_Release(node);
3067 
3068  str = NULL;
3069  r = IXMLDOMCDATASection_get_data(cdata, &str);
3070  ok( r == S_OK, "returns %08x\n", r );
3071  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3072  IXMLDOMCDATASection_Release(cdata);
3073  SysFreeString(str);
3074 
3075  node = (IXMLDOMNode*)0x1;
3076  r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
3077  ok( r == S_OK, "returns %08x\n", r );
3078 
3079  r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
3080  ok( r == S_OK, "returns %08x\n", r );
3081  IXMLDOMNode_Release(node);
3082 
3083  str = NULL;
3084  r = IXMLDOMCDATASection_get_data(cdata, &str);
3085  ok( r == S_OK, "returns %08x\n", r );
3086  ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
3087  IXMLDOMCDATASection_Release(cdata);
3088  SysFreeString(str);
3089 
3090  /* NODE_ATTRIBUTE */
3091  V_VT(&var) = VT_I1;
3092  V_I1(&var) = NODE_ATTRIBUTE;
3093  node = (IXMLDOMNode*)0x1;
3094  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3095  ok( r == E_FAIL, "returns %08x\n", r );
3096  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3097 
3098  V_VT(&var) = VT_I1;
3099  V_I1(&var) = NODE_ATTRIBUTE;
3100  node = (IXMLDOMNode*)0x1;
3101  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3102  ok( r == E_FAIL, "returns %08x\n", r );
3103  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3104 
3105  V_VT(&var) = VT_I1;
3106  V_I1(&var) = NODE_ATTRIBUTE;
3107  str = SysAllocString( szlc );
3108  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3109  ok( r == S_OK, "returns %08x\n", r );
3110  if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3111  SysFreeString(str);
3112 
3113  /* a name is required for attribute, try a BSTR with first null wchar */
3114  V_VT(&var) = VT_I1;
3115  V_I1(&var) = NODE_ATTRIBUTE;
3116  str = SysAllocString( szstr1 );
3117  str[0] = 0;
3118  node = (IXMLDOMNode*)0x1;
3119  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3120  ok( r == E_FAIL, "returns %08x\n", r );
3121  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3122  SysFreeString(str);
3123 
3124  /* NODE_PROCESSING_INSTRUCTION */
3125  V_VT(&var) = VT_I1;
3127  node = (IXMLDOMNode*)0x1;
3128  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3129  ok( r == E_FAIL, "returns %08x\n", r );
3130  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3131 
3132  V_VT(&var) = VT_I1;
3134  node = (IXMLDOMNode*)0x1;
3135  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3136  ok( r == E_FAIL, "returns %08x\n", r );
3137  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3138 
3139  V_VT(&var) = VT_I1;
3141  r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
3142  ok( r == E_INVALIDARG, "returns %08x\n", r );
3143 
3144  /* NODE_ENTITY_REFERENCE */
3145  V_VT(&var) = VT_I1;
3146  V_I1(&var) = NODE_ENTITY_REFERENCE;
3147  node = (IXMLDOMNode*)0x1;
3148  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3149  ok( r == E_FAIL, "returns %08x\n", r );
3150  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3151 
3152  V_VT(&var) = VT_I1;
3153  V_I1(&var) = NODE_ENTITY_REFERENCE;
3154  node = (IXMLDOMNode*)0x1;
3155  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3156  ok( r == E_FAIL, "returns %08x\n", r );
3157  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3158 
3159  /* NODE_ELEMENT */
3160  V_VT(&var) = VT_I1;
3161  V_I1(&var) = NODE_ELEMENT;
3162  node = (IXMLDOMNode*)0x1;
3163  r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
3164  ok( r == E_FAIL, "returns %08x\n", r );
3165  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3166 
3167  V_VT(&var) = VT_I1;
3168  V_I1(&var) = NODE_ELEMENT;
3169  node = (IXMLDOMNode*)0x1;
3170  r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
3171  ok( r == E_FAIL, "returns %08x\n", r );
3172  ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
3173 
3174  V_VT(&var) = VT_I1;
3175  V_I1(&var) = NODE_ELEMENT;
3176  str = SysAllocString( szlc );
3177  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3178  ok( r == S_OK, "returns %08x\n", r );
3179  if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3180 
3181  V_VT(&var) = VT_I1;
3182  V_I1(&var) = NODE_ELEMENT;
3183  r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
3184  ok( r == E_INVALIDARG, "returns %08x\n", r );
3185 
3186  V_VT(&var) = VT_R4;
3187  V_R4(&var) = NODE_ELEMENT;
3188  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3189  ok( r == S_OK, "returns %08x\n", r );
3190  if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3191 
3192  V_VT(&var) = VT_BSTR;
3193  V_BSTR(&var) = SysAllocString( szOne );
3194  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3195  ok( r == S_OK, "returns %08x\n", r );
3196  if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3197  VariantClear(&var);
3198 
3199  V_VT(&var) = VT_BSTR;
3200  V_BSTR(&var) = SysAllocString( szOneGarbage );
3201  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3202  ok( r == E_INVALIDARG, "returns %08x\n", r );
3203  if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
3204  VariantClear(&var);
3205 
3206  V_VT(&var) = VT_I4;
3207  V_I4(&var) = NODE_ELEMENT;
3208  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3209  ok( r == S_OK, "returns %08x\n", r );
3210 
3211  EXPECT_REF(doc, 1);
3212  r = IXMLDOMDocument_appendChild( doc, node, &root );
3213  ok( r == S_OK, "returns %08x\n", r );
3214  ok( node == root, "%p %p\n", node, root );
3215  EXPECT_REF(doc, 1);
3216 
3217  EXPECT_REF(node, 2);
3218 
3219  ref = IXMLDOMNode_Release( node );
3220  ok(ref == 1, "ref %d\n", ref);
3221  SysFreeString( str );
3222 
3223  V_VT(&var) = VT_I4;
3224  V_I4(&var) = NODE_ELEMENT;
3225  str = SysAllocString( szbs );
3226  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3227  ok( r == S_OK, "returns %08x\n", r );
3228  SysFreeString( str );
3229 
3230  EXPECT_REF(node, 1);
3231 
3232  r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
3233  ok( r == S_OK, "returns %08x\n", r );
3234 
3235  EXPECT_REF(unk, 2);
3236 
3237  V_VT(&var) = VT_EMPTY;
3238  child = NULL;
3239  r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
3240  ok( r == S_OK, "returns %08x\n", r );
3241  ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
3242 
3243  todo_wine EXPECT_REF(unk, 4);
3244 
3245  IXMLDOMNode_Release( child );
3246  IUnknown_Release( unk );
3247 
3248  V_VT(&var) = VT_NULL;
3249  V_DISPATCH(&var) = (IDispatch*)node;
3250  r = IXMLDOMNode_insertBefore( root, node, var, &child );
3251  ok( r == S_OK, "returns %08x\n", r );
3252  ok( node == child, "%p %p\n", node, child );
3253  IXMLDOMNode_Release( child );
3254 
3255  V_VT(&var) = VT_NULL;
3256  V_DISPATCH(&var) = (IDispatch*)node;
3257  r = IXMLDOMNode_insertBefore( root, node, var, NULL );
3258  ok( r == S_OK, "returns %08x\n", r );
3259  IXMLDOMNode_Release( node );
3260 
3261  r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
3262  ok( r == S_OK, "returns %08x\n", r );
3263 
3264  r = IXMLDOMElement_get_attributes( element, &attr_map );
3265  ok( r == S_OK, "returns %08x\n", r );
3266  r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3267  ok( r == S_OK, "returns %08x\n", r );
3268  ok( num == 0, "num %d\n", num );
3269  IXMLDOMNamedNodeMap_Release( attr_map );
3270 
3271  V_VT(&var) = VT_BSTR;
3272  V_BSTR(&var) = SysAllocString( szstr1 );
3273  name = SysAllocString( szdl );
3274  r = IXMLDOMElement_setAttribute( element, name, var );
3275  ok( r == S_OK, "returns %08x\n", r );
3276  r = IXMLDOMElement_get_attributes( element, &attr_map );
3277  ok( r == S_OK, "returns %08x\n", r );
3278  r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3279  ok( r == S_OK, "returns %08x\n", r );
3280  ok( num == 1, "num %d\n", num );
3281  IXMLDOMNamedNodeMap_Release( attr_map );
3282  VariantClear(&var);
3283 
3284  V_VT(&var) = VT_BSTR;
3285  V_BSTR(&var) = SysAllocString( szstr2 );
3286  r = IXMLDOMElement_setAttribute( element, name, var );
3287  ok( r == S_OK, "returns %08x\n", r );
3288  r = IXMLDOMElement_get_attributes( element, &attr_map );
3289  ok( r == S_OK, "returns %08x\n", r );
3290  r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3291  ok( r == S_OK, "returns %08x\n", r );
3292  ok( num == 1, "num %d\n", num );
3293  IXMLDOMNamedNodeMap_Release( attr_map );
3294  VariantClear(&var);
3295  r = IXMLDOMElement_getAttribute( element, name, &var );
3296  ok( r == S_OK, "returns %08x\n", r );
3297  ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
3298  VariantClear(&var);
3299  SysFreeString(name);
3300 
3301  V_VT(&var) = VT_BSTR;
3302  V_BSTR(&var) = SysAllocString( szstr1 );
3303  name = SysAllocString( szlc );
3304  r = IXMLDOMElement_setAttribute( element, name, var );
3305  ok( r == S_OK, "returns %08x\n", r );
3306  r = IXMLDOMElement_get_attributes( element, &attr_map );
3307  ok( r == S_OK, "returns %08x\n", r );
3308  r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
3309  ok( r == S_OK, "returns %08x\n", r );
3310  ok( num == 2, "num %d\n", num );
3311  IXMLDOMNamedNodeMap_Release( attr_map );
3312  VariantClear(&var);
3313  SysFreeString(name);
3314 
3315  V_VT(&var) = VT_I4;
3316  V_I4(&var) = 10;
3317  name = SysAllocString( szbs );
3318  r = IXMLDOMElement_setAttribute( element, name, var );
3319  ok( r == S_OK, "returns %08x\n", r );
3320  VariantClear(&var);
3321  r = IXMLDOMElement_getAttribute( element, name, &var );
3322  ok( r == S_OK, "returns %08x\n", r );
3323  ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
3324  VariantClear(&var);
3325  SysFreeString(name);
3326 
3327  /* Create an Attribute */
3328  V_VT(&var) = VT_I4;
3329  V_I4(&var) = NODE_ATTRIBUTE;
3330  str = SysAllocString( szAttribute );
3331  r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
3332  ok( r == S_OK, "returns %08x\n", r );
3333  ok( node != NULL, "node was null\n");
3334  SysFreeString(str);
3335 
3336  IXMLDOMElement_Release( element );
3337  IXMLDOMNode_Release( root );
3338  IXMLDOMDocument_Release( doc );
3339 }
3340 
3342  const char *query;
3343  const char *result;
3344  int len;
3345 };
3346 
3347 static const struct queryresult_t elementsbytagname[] = {
3348  { "", "P1.D1 E2.D1 E1.E2.D1 T1.E1.E2.D1 E2.E2.D1 T1.E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1 T1.E1.E4.E2.D1", 10 },
3349  { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
3350  { "bs", "E1.E2.D1", 1 },
3351  { "dl", "", 0 },
3352  { "str1","", 0 },
3353  { NULL }
3354 };
3355 
3356 static void test_getElementsByTagName(void)
3357 {
3358  const struct queryresult_t *ptr = elementsbytagname;
3359  IXMLDOMNodeList *node_list;
3360  IXMLDOMDocument *doc;
3362  WCHAR buff[100];
3363  VARIANT_BOOL b;
3364  HRESULT r;
3365  LONG len;
3366  BSTR str;
3367 
3368  doc = create_document(&IID_IXMLDOMDocument);
3369 
3370  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3371  ok( r == S_OK, "loadXML failed\n");
3372  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3373 
3374  /* null arguments cases */
3375  r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
3376  ok( r == E_INVALIDARG, "ret %08x\n", r );
3377  r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL);
3378  ok( r == E_INVALIDARG, "ret %08x\n", r );
3379 
3380  while (ptr->query)
3381  {
3382  r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list);
3383  ok(r == S_OK, "ret %08x\n", r);
3384  r = IXMLDOMNodeList_get_length(node_list, &len);
3385  ok(r == S_OK, "ret %08x\n", r);
3386  ok(len == ptr->len, "%s: got len %d, expected %d\n", ptr->query, len, ptr->len);
3387  expect_list_and_release(node_list, ptr->result);
3388 
3389  free_bstrs();
3390  ptr++;
3391  }
3392 
3393  /* broken query BSTR */
3394  memcpy(&buff[2], szstar, sizeof(szstar));
3395  /* just a big length */
3396  *(DWORD*)buff = 0xf0f0;
3397  r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
3398  ok( r == S_OK, "ret %08x\n", r );
3399  r = IXMLDOMNodeList_get_length( node_list, &len );
3400  ok( r == S_OK, "ret %08x\n", r );
3401  ok( len == 6, "len %d\n", len );
3402  IXMLDOMNodeList_Release( node_list );
3403 
3404  /* test for element */
3405  r = IXMLDOMDocument_get_documentElement(doc, &elem);
3406  ok( r == S_OK, "ret %08x\n", r );
3407 
3408  str = SysAllocString( szstar );
3409 
3410  /* null arguments cases */
3411  r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
3412  ok( r == E_INVALIDARG, "ret %08x\n", r );
3413  r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
3414  ok( r == E_INVALIDARG, "ret %08x\n", r );
3415 
3416  r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
3417  ok( r == S_OK, "ret %08x\n", r );
3418  r = IXMLDOMNodeList_get_length( node_list, &len );
3419  ok( r == S_OK, "ret %08x\n", r );
3420  ok( len == 5, "len %d\n", len );
3421  expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
3422  SysFreeString( str );
3423 
3424  /* broken query BSTR */
3425  memcpy(&buff[2], szstar, sizeof(szstar));
3426  /* just a big length */
3427  *(DWORD*)buff = 0xf0f0;
3428  r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
3429  ok( r == S_OK, "ret %08x\n", r );
3430  r = IXMLDOMNodeList_get_length( node_list, &len );
3431  ok( r == S_OK, "ret %08x\n", r );
3432  ok( len == 5, "len %d\n", len );
3433  IXMLDOMNodeList_Release( node_list );
3434 
3435  IXMLDOMElement_Release(elem);
3436 
3437  IXMLDOMDocument_Release( doc );
3438 
3439  free_bstrs();
3440 }
3441 
3442 static void test_get_text(void)
3443 {
3444  HRESULT r;
3445  BSTR str;
3446  VARIANT_BOOL b;
3447  IXMLDOMDocument *doc;
3448  IXMLDOMNode *node, *node2, *node3;
3449  IXMLDOMNode *nodeRoot;
3450  IXMLDOMNodeList *node_list;
3451  IXMLDOMNamedNodeMap *node_map;
3452  LONG len;
3453 
3454  doc = create_document(&IID_IXMLDOMDocument);
3455 
3456  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3457  ok( r == S_OK, "loadXML failed\n");
3458  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3459 
3460  str = SysAllocString( szbs );
3461  r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
3462  ok( r == S_OK, "ret %08x\n", r );
3463  SysFreeString(str);
3464 
3465  /* Test to get all child node text. */
3466  r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
3467  ok( r == S_OK, "ret %08x\n", r );
3468  if(r == S_OK)
3469  {
3470  r = IXMLDOMNode_get_text( nodeRoot, &str );
3471  ok( r == S_OK, "ret %08x\n", r );
3472  expect_bstr_eq_and_free(str, "fn1.txt\n \nfn2.txt\n \nf1");
3473 
3474  IXMLDOMNode_Release(nodeRoot);
3475  }
3476 
3477  r = IXMLDOMNodeList_get_length( node_list, NULL );
3478  ok( r == E_INVALIDARG, "ret %08x\n", r );
3479 
3480  r = IXMLDOMNodeList_get_length( node_list, &len );
3481  ok( r == S_OK, "ret %08x\n", r );
3482  ok( len == 1, "expect 1 got %d\n", len );
3483 
3484  r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
3485  ok( r == E_INVALIDARG, "ret %08x\n", r );
3486 
3487  r = IXMLDOMNodeList_nextNode( node_list, NULL );
3488  ok( r == E_INVALIDARG, "ret %08x\n", r );
3489 
3490  r = IXMLDOMNodeList_get_item( node_list, 0, &node );
3491  ok( r == S_OK, "ret %08x\n", r );
3492  IXMLDOMNodeList_Release( node_list );
3493 
3494  /* Invalid output parameter*/
3495  r = IXMLDOMNode_get_text( node, NULL );
3496  ok( r == E_INVALIDARG, "ret %08x\n", r );
3497 
3498  r = IXMLDOMNode_get_text( node, &str );
3499  ok( r == S_OK, "ret %08x\n", r );
3500  ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
3501  SysFreeString(str);
3502 
3503  r = IXMLDOMNode_get_attributes( node, &node_map );
3504  ok( r == S_OK, "ret %08x\n", r );
3505 
3506  str = SysAllocString( szvr );
3507  r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
3508  ok( r == S_OK, "ret %08x\n", r );
3509  SysFreeString(str);
3510 
3511  r = IXMLDOMNode_get_text( node2, &str );
3512  ok( r == S_OK, "ret %08x\n", r );
3513  ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3514  SysFreeString(str);
3515 
3516  r = IXMLDOMNode_get_firstChild( node2, &node3 );
3517  ok( r == S_OK, "ret %08x\n", r );
3518 
3519  r = IXMLDOMNode_get_text( node3, &str );
3520  ok( r == S_OK, "ret %08x\n", r );
3521  ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
3522  SysFreeString(str);
3523 
3524 
3525  IXMLDOMNode_Release( node3 );
3526  IXMLDOMNode_Release( node2 );
3527  IXMLDOMNamedNodeMap_Release( node_map );
3528  IXMLDOMNode_Release( node );
3529  IXMLDOMDocument_Release( doc );
3530 
3531  free_bstrs();
3532 }
3533 
3534 #ifdef __REACTOS__
3535 /*
3536  * This function is to display that xmlnodelist_QueryInterface
3537  * generates SEGV for these conditions, and once fixed make sure
3538  * it never does it again.
3539  */
3540 static void verify_nodelist_query_interface(IXMLDOMNodeList *node_list)
3541 {
3542  HRESULT hr;
3543  /*
3544  * NOTE: The following calls are supposed to test wine's
3545  * xmlnodelist_QueryInterface behaving properly.
3546  * While we should be able to expect E_POINTER (due to the NULL pointer),
3547  * it seems MS' own implementation(s) violate the spec and return
3548  * E_INVALIDARG. To not get cought be a potentially correct implementation
3549  * in the future, we check for NOT S_OK.
3550  */
3551  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, NULL);
3552  EXPECT_NOT_HR(hr, S_OK);
3553  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL);
3554  EXPECT_NOT_HR(hr, S_OK);
3555  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IXMLDOMNodeList, NULL);
3556  EXPECT_NOT_HR(hr, S_OK);
3557 }
3558 #endif
3559 
3560 static void test_get_childNodes(void)
3561 {
3562  IXMLDOMNodeList *node_list, *node_list2;
3563  IEnumVARIANT *enum1, *enum2, *enum3;
3564  VARIANT_BOOL b;
3565  IXMLDOMDocument *doc;
3566  IXMLDOMNode *node, *node2;
3568  IUnknown *unk1, *unk2;
3569  HRESULT hr;
3570  VARIANT v;
3571  BSTR str;
3572  LONG len;
3573 
3574  doc = create_document(&IID_IXMLDOMDocument);
3575 
3576  hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3577  EXPECT_HR(hr, S_OK);
3578  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3579 
3580  hr = IXMLDOMDocument_get_documentElement( doc, &element );
3581  EXPECT_HR(hr, S_OK);
3582 
3583  hr = IXMLDOMElement_get_childNodes( element, &node_list );
3584  EXPECT_HR(hr, S_OK);
3585 
3586 #ifdef __REACTOS__
3587  verify_nodelist_query_interface(node_list);
3588 #endif
3589 
3590  hr = IXMLDOMNodeList_get_length( node_list, &len );
3591  EXPECT_HR(hr, S_OK);
3592  ok( len == 4, "len %d\n", len);
3593 
3594  /* refcount tests for IEnumVARIANT support */
3595  EXPECT_REF(node_list, 1);
3596  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
3597  EXPECT_HR(hr, S_OK);
3598  EXPECT_REF(node_list, 1);
3599  EXPECT_REF(enum1, 2);
3600 
3601  EXPECT_REF(node_list, 1);
3602  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
3603  EXPECT_HR(hr, S_OK);
3604  EXPECT_REF(node_list, 1);
3605  ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
3606  IEnumVARIANT_Release(enum2);
3607 
3608  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3609  EXPECT_HR(hr, S_OK);
3610  hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
3611  EXPECT_HR(hr, S_OK);
3612  EXPECT_REF(node_list, 3);
3613  EXPECT_REF(enum1, 2);
3614  ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
3615  IUnknown_Release(unk1);
3616  IUnknown_Release(unk2);
3617 
3618  EXPECT_REF(node_list, 1);
3619  hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
3620  EXPECT_HR(hr, S_OK);
3621  EXPECT_REF(node_list, 2);
3622  EXPECT_REF(enum2, 1);
3623  ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
3624 
3625  /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
3626  hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
3627  EXPECT_HR(hr, S_OK);
3628  hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
3629  EXPECT_HR(hr, S_OK);
3630  EXPECT_REF(node_list, 3);
3631  EXPECT_REF(enum2, 2);
3632  ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
3633  IUnknown_Release(unk1);
3634  IUnknown_Release(unk2);
3635 
3636  hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
3637  EXPECT_HR(hr, S_OK);
3638  ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
3639  IEnumVARIANT_Release(enum3);
3640  IEnumVARIANT_Release(enum2);
3641 
3642  /* iteration tests */
3643  hr = IXMLDOMNodeList_get_item(node_list, 0, &node);
3644  EXPECT_HR(hr, S_OK);
3645  hr = IXMLDOMNode_get_nodeName(node, &str);
3646  EXPECT_HR(hr, S_OK);
3647  ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3648  SysFreeString(str);
3649  IXMLDOMNode_Release(node);
3650 
3651  hr = IXMLDOMNodeList_nextNode(node_list, &node);
3652  EXPECT_HR(hr, S_OK);
3653  hr = IXMLDOMNode_get_nodeName(node, &str);
3654  EXPECT_HR(hr, S_OK);
3655  ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str));
3656  SysFreeString(str);
3657  IXMLDOMNode_Release(node);
3658 
3659  V_VT(&v) = VT_EMPTY;
3660  hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
3661  EXPECT_HR(hr, S_OK);
3662  ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
3663  hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
3664  EXPECT_HR(hr, S_OK);
3665  hr = IXMLDOMNode_get_nodeName(node, &str);
3666  EXPECT_HR(hr, S_OK);
3667  ok(!lstrcmpW(str, _bstr_("bs")), "got node name %s\n", wine_dbgstr_w(str));
3668  SysFreeString(str);
3669  IXMLDOMNode_Release(node);
3670  VariantClear(&v);
3671 
3672  hr = IXMLDOMNodeList_nextNode(node_list, &node);
3673  EXPECT_HR(hr, S_OK);
3674  hr = IXMLDOMNode_get_nodeName(node, &str);
3675  EXPECT_HR(hr, S_OK);
3676  ok(!lstrcmpW(str, _bstr_("pr")), "got %s\n", wine_dbgstr_w(str));
3677  SysFreeString(str);
3678  IXMLDOMNode_Release(node);
3679 
3680  IEnumVARIANT_Release(enum1);
3681 
3682  hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
3683  EXPECT_HR(hr, S_OK);
3684 
3685  hr = IXMLDOMNode_get_childNodes( node, &node_list2 );
3686  EXPECT_HR(hr, S_OK);
3687 
3688  hr = IXMLDOMNodeList_get_length( node_list2, &len );
3689  EXPECT_HR(hr, S_OK);
3690  ok( len == 0, "len %d\n", len);
3691 
3692  hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
3693  EXPECT_HR(hr, S_FALSE);
3694 
3695  IXMLDOMNodeList_Release( node_list2 );
3696  IXMLDOMNode_Release( node );
3697  IXMLDOMNodeList_Release( node_list );
3698  IXMLDOMElement_Release( element );
3699 
3700  /* test for children of <?xml ..?> node */
3701  hr = IXMLDOMDocument_get_firstChild(doc, &node);
3702  EXPECT_HR(hr, S_OK);
3703 
3704  str = NULL;
3705  hr = IXMLDOMNode_get_nodeName(node, &str);
3706  EXPECT_HR(hr, S_OK);
3707  ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str));
3708  SysFreeString(str);
3709 
3710  /* it returns empty but valid node list */
3711  node_list = (void*)0xdeadbeef;
3712  hr = IXMLDOMNode_get_childNodes(node, &node_list);
3713  EXPECT_HR(hr, S_OK);
3714 
3715  len = -1;
3716  hr = IXMLDOMNodeList_get_length(node_list, &len);
3717  EXPECT_HR(hr, S_OK);
3718  ok(len == 0, "got %d\n", len);
3719 
3720  IXMLDOMNodeList_Release( node_list );
3721  IXMLDOMNode_Release(node);
3722 
3723  IXMLDOMDocument_Release( doc );
3724  free_bstrs();
3725 }
3726 
3727 static void test_get_firstChild(void)
3728 {
3729  static const WCHAR xmlW[] = {'x','m','l',0};
3730  IXMLDOMDocument *doc;
3731  IXMLDOMNode *node;
3732  VARIANT_BOOL b;
3733  HRESULT r;
3734  BSTR str;
3735 
3736  doc = create_document(&IID_IXMLDOMDocument);
3737 
3738  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3739  ok( r == S_OK, "loadXML failed\n");
3740  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3741 
3742  r = IXMLDOMDocument_get_firstChild( doc, &node );
3743  ok( r == S_OK, "ret %08x\n", r);
3744 
3745  r = IXMLDOMNode_get_nodeName( node, &str );
3746  ok( r == S_OK, "ret %08x\n", r);
3747 
3748  ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str));
3749 
3750  SysFreeString(str);
3751  IXMLDOMNode_Release( node );
3752  IXMLDOMDocument_Release( doc );
3753 
3754  free_bstrs();
3755 }
3756 
3757 static void test_get_lastChild(void)
3758 {
3759  static const WCHAR lcW[] = {'l','c',0};
3760  static const WCHAR foW[] = {'f','o',0};
3761  IXMLDOMDocument *doc;
3762  IXMLDOMNode *node, *child;
3763  VARIANT_BOOL b;
3764  HRESULT r;
3765  BSTR str;
3766 
3767  doc = create_document(&IID_IXMLDOMDocument);
3768 
3769  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3770  ok( r == S_OK, "loadXML failed\n");
3771  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3772 
3773  r = IXMLDOMDocument_get_lastChild( doc, &node );
3774  ok( r == S_OK, "ret %08x\n", r);
3775 
3776  r = IXMLDOMNode_get_nodeName( node, &str );
3777  ok( r == S_OK, "ret %08x\n", r);
3778 
3779  ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
3780  SysFreeString(str);
3781 
3782  r = IXMLDOMNode_get_lastChild( node, &child );
3783  ok( r == S_OK, "ret %08x\n", r);
3784 
3785  r = IXMLDOMNode_get_nodeName( child, &str );
3786  ok( r == S_OK, "ret %08x\n", r);
3787 
3788  ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
3789  SysFreeString(str);
3790 
3791  IXMLDOMNode_Release( child );
3792  IXMLDOMNode_Release( node );
3793  IXMLDOMDocument_Release( doc );
3794 
3795  free_bstrs();
3796 }
3797 
3798 static void test_removeChild(void)
3799 {
3800  HRESULT r;
3801  VARIANT_BOOL b;
3802  IXMLDOMDocument *doc;
3803  IXMLDOMElement *element, *lc_element;
3804  IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
3805  IXMLDOMNodeList *root_list, *fo_list;
3806 
3807  doc = create_document(&IID_IXMLDOMDocument);
3808 
3809  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3810  ok( r == S_OK, "loadXML failed\n");
3811  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3812 
3813  r = IXMLDOMDocument_get_documentElement( doc, &element );
3814  ok( r == S_OK, "ret %08x\n", r);
3815  todo_wine EXPECT_REF(element, 2);
3816 
3817  r = IXMLDOMElement_get_childNodes( element, &root_list );
3818  ok( r == S_OK, "ret %08x\n", r);
3819  EXPECT_REF(root_list, 1);
3820 
3821  r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3822  ok( r == S_OK, "ret %08x\n", r);
3823  EXPECT_REF(fo_node, 1);
3824 
3825  r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3826  ok( r == S_OK, "ret %08x\n", r);
3827  EXPECT_REF(fo_list, 1);
3828 
3829  r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3830  ok( r == S_OK, "ret %08x\n", r);
3831  EXPECT_REF(ba_node, 1);
3832 
3833  /* invalid parameter: NULL ptr */
3834  removed_node = (void*)0xdeadbeef;
3835  r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
3836  ok( r == E_INVALIDARG, "ret %08x\n", r );
3837  ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3838 
3839  /* ba_node is a descendant of element, but not a direct child. */
3840  removed_node = (void*)0xdeadbeef;
3841  EXPECT_REF(ba_node, 1);
3842  EXPECT_CHILDREN(fo_node);
3843  r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
3844  ok( r == E_INVALIDARG, "ret %08x\n", r );
3845  ok( removed_node == NULL, "%p\n", removed_node );
3846  EXPECT_REF(ba_node, 1);
3847  EXPECT_CHILDREN(fo_node);
3848 
3849  EXPECT_REF(ba_node, 1);
3850  EXPECT_REF(fo_node, 1);
3851  r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
3852  ok( r == S_OK, "ret %08x\n", r);
3853  ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
3854  EXPECT_REF(fo_node, 2);
3855  EXPECT_REF(ba_node, 1);
3856 
3857  /* try removing already removed child */
3858  temp_node = (void*)0xdeadbeef;
3859  r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
3860  ok( r == E_INVALIDARG, "ret %08x\n", r);
3861  ok( temp_node == NULL, "%p\n", temp_node );
3862  IXMLDOMNode_Release( fo_node );
3863 
3864  /* the removed node has no parent anymore */
3865  r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
3866  ok( r == S_FALSE, "ret %08x\n", r);
3867  ok( temp_node == NULL, "%p\n", temp_node );
3868 
3869  IXMLDOMNode_Release( removed_node );
3870  IXMLDOMNode_Release( ba_node );
3871  IXMLDOMNodeList_Release( fo_list );
3872 
3873  r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3874  ok( r == S_OK, "ret %08x\n", r);
3875 
3876  r = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
3877  ok( r == S_OK, "ret %08x\n", r);
3878 
3879  /* MS quirk: passing wrong interface pointer works, too */
3880  r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
3881  ok( r == S_OK, "ret %08x\n", r);
3882  IXMLDOMElement_Release( lc_element );
3883 
3884  temp_node = (void*)0xdeadbeef;
3885  r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
3886  ok( r == S_FALSE, "ret %08x\n", r);
3887  ok( temp_node == NULL, "%p\n", temp_node );
3888 
3889  IXMLDOMNode_Release( lc_node );
3890  IXMLDOMNodeList_Release( root_list );
3891  IXMLDOMElement_Release( element );
3892  IXMLDOMDocument_Release( doc );
3893 
3894  free_bstrs();
3895 }
3896 
3897 static void test_replaceChild(void)
3898 {
3899  HRESULT r;
3900  VARIANT_BOOL b;
3901  IXMLDOMDocument *doc;
3902  IXMLDOMElement *element, *ba_element;
3903  IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
3904  IXMLDOMNodeList *root_list, *fo_list;
3905  IUnknown * unk1, *unk2;
3906  LONG len;
3907 
3908  doc = create_document(&IID_IXMLDOMDocument);
3909 
3910  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
3911  ok( r == S_OK, "loadXML failed\n");
3912  ok( b == VARIANT_TRUE, "failed to load XML string\n");
3913 
3914  r = IXMLDOMDocument_get_documentElement( doc, &element );
3915  ok( r == S_OK, "ret %08x\n", r);
3916 
3917  r = IXMLDOMElement_get_childNodes( element, &root_list );
3918  ok( r == S_OK, "ret %08x\n", r);
3919 
3920  r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3921  ok( r == S_OK, "ret %08x\n", r);
3922 
3923  r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3924  ok( r == S_OK, "ret %08x\n", r);
3925 
3926  r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3927  ok( r == S_OK, "ret %08x\n", r);
3928 
3929  r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3930  ok( r == S_OK, "ret %08x\n", r);
3931 
3932  IXMLDOMNodeList_Release( fo_list );
3933 
3934  /* invalid parameter: NULL ptr for element to remove */
3935  removed_node = (void*)0xdeadbeef;
3936  r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3937  ok( r == E_INVALIDARG, "ret %08x\n", r );
3938  ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3939 
3940  /* invalid parameter: NULL for replacement element. (Sic!) */
3941  removed_node = (void*)0xdeadbeef;
3942  r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3943  ok( r == E_INVALIDARG, "ret %08x\n", r );
3944  ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3945 
3946  /* invalid parameter: OldNode is not a child */
3947  removed_node = (void*)0xdeadbeef;
3948  r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3949  ok( r == E_INVALIDARG, "ret %08x\n", r );
3950  ok( removed_node == NULL, "%p\n", removed_node );
3951  IXMLDOMNode_Release( lc_node );
3952 
3953  /* invalid parameter: would create loop */
3954  removed_node = (void*)0xdeadbeef;
3955  r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3956  ok( r == E_FAIL, "ret %08x\n", r );
3957  ok( removed_node == NULL, "%p\n", removed_node );
3958 
3959  r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
3960  ok( r == S_OK, "ret %08x\n", r );
3961 
3962  r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
3963  ok( r == S_OK, "ret %08x\n", r );
3964 
3965  /* ba_node and temp_node refer to the same node, yet they
3966  are different interface pointers */
3967  ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
3968  r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
3969  ok( r == S_OK, "ret %08x\n", r );
3970  r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
3971  ok( r == S_OK, "ret %08x\n", r );
3972  todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
3973 
3974  IUnknown_Release( unk1 );
3975  IUnknown_Release( unk2 );
3976 
3977  /* ba_node should have been removed from below fo_node */
3978  r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3979  ok( r == S_OK, "ret %08x\n", r );
3980 
3981  /* MS quirk: replaceChild also accepts elements instead of nodes */
3982  r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
3983  ok( r == S_OK, "ret %08x\n", r );
3984  EXPECT_REF(ba_element, 2);
3985 
3986  removed_node = NULL;
3987  r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
3988  ok( r == S_OK, "ret %08x\n", r );
3989  ok( removed_node != NULL, "got %p\n", removed_node);
3990  EXPECT_REF(ba_element, 3);
3991  IXMLDOMElement_Release( ba_element );
3992 
3993  r = IXMLDOMNodeList_get_length( fo_list, &len);
3994  ok( r == S_OK, "ret %08x\n", r );
3995  ok( len == 0, "len %d\n", len);
3996 
3997  IXMLDOMNodeList_Release( fo_list );
3998 
3999  IXMLDOMNode_Release(ba_node);
4000  IXMLDOMNode_Release(fo_node);
4001  IXMLDOMNode_Release(temp_node);
4002  IXMLDOMNodeList_Release( root_list );
4003  IXMLDOMElement_Release( element );
4004  IXMLDOMDocument_Release( doc );
4005 
4006  free_bstrs();
4007 }
4008 
4009 static void test_removeNamedItem(void)
4010 {
4011  IXMLDOMDocument *doc;
4013  IXMLDOMNode *pr_node, *removed_node, *removed_node2;
4014  IXMLDOMNodeList *root_list;
4015  IXMLDOMNamedNodeMap * pr_attrs;
4016  VARIANT_BOOL b;
4017  BSTR str;
4018  LONG len;
4019  HRESULT r;
4020 
4021  doc = create_document(&IID_IXMLDOMDocument);
4022 
4023  r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
4024  ok( r == S_OK, "loadXML failed\n");
4025  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4026 
4027  r = IXMLDOMDocument_get_documentElement( doc, &element );
4028  ok( r == S_OK, "ret %08x\n", r);
4029 
4030  r = IXMLDOMElement_get_childNodes( element, &root_list );
4031  ok( r == S_OK, "ret %08x\n", r);
4032 
4033  r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
4034  ok( r == S_OK, "ret %08x\n", r);
4035 
4036  r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
4037  ok( r == S_OK, "ret %08x\n", r);
4038 
4039  r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4040  ok( r == S_OK, "ret %08x\n", r);
4041  ok( len == 3, "length %d\n", len);
4042 
4043  removed_node = (void*)0xdeadbeef;
4044  r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
4045  ok ( r == E_INVALIDARG, "ret %08x\n", r);
4046  ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
4047 
4048  removed_node = (void*)0xdeadbeef;
4049  str = SysAllocString(szvr);
4050  r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
4051  ok ( r == S_OK, "ret %08x\n", r);
4052 
4053  removed_node2 = (void*)0xdeadbeef;
4054  r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
4055  ok ( r == S_FALSE, "ret %08x\n", r);
4056  ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
4057 
4058  r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4059  ok( r == S_OK, "ret %08x\n", r);
4060  ok( len == 2, "length %d\n", len);
4061 
4062  r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
4063  ok ( r == S_OK, "ret %08x\n", r);
4064  IXMLDOMNode_Release(removed_node);
4065 
4066  r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4067  ok( r == S_OK, "ret %08x\n", r);
4068  ok( len == 3, "length %d\n", len);
4069 
4070  r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4071  ok ( r == S_OK, "ret %08x\n", r);
4072 
4073  r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
4074  ok( r == S_OK, "ret %08x\n", r);
4075  ok( len == 2, "length %d\n", len);
4076 
4077  r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
4078  ok ( r == S_FALSE, "ret %08x\n", r);
4079 
4080  SysFreeString(str);
4081 
4082  IXMLDOMNamedNodeMap_Release( pr_attrs );
4083  IXMLDOMNode_Release( pr_node );
4084  IXMLDOMNodeList_Release( root_list );
4085  IXMLDOMElement_Release( element );
4086  IXMLDOMDocument_Release( doc );
4087 
4088  free_bstrs();
4089 }
4090 
4091 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
4093  HRESULT result2, DWORD set, DWORD mask, DWORD expected,
4094  DWORD expected2)
4095 {
4096  DWORD enabled, supported;
4097  HRESULT hr;
4098 
4099  hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
4100  if (result == result2)
4101  ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
4102  else
4103  ok_(__FILE__,line)(broken(hr == result) || hr == result2,
4104  "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
4105 
4106  supported = enabled = 0xCAFECAFE;
4107  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4108  ok(hr == S_OK, "ret %08x\n", hr );
4109  if (expected == expected2)
4110  ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
4111  else
4112  ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
4113  "Expected %08x, got %08x\n", expected2, enabled);
4114 
4115  /* reset the safety options */
4116 
4117  hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4118  INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
4119  0);
4120  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4121 
4122  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4123  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4124  ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4125 }
4126 
4127 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
4128 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
4129 {
4130  DWORD enabled = 0, supported = 0;
4131  HRESULT hr;
4132 
4133  /* get */
4134  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
4135  ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4136  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
4137  ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
4138 
4139  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4140  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4141  ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4142  supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4143  "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4144  "got %08x\n", supported);
4145  ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
4146 
4147  /* set -- individual flags */
4148 
4149  test_IObjectSafety_set(safety, S_OK, S_OK,
4150  INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4151  INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4152 
4153  test_IObjectSafety_set(safety, S_OK, S_OK,
4154  INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
4155  INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
4156 
4157  test_IObjectSafety_set(safety, S_OK, S_OK,
4158  INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
4159  0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
4160 
4161  /* set INTERFACE_USES_DISPEX */
4162 
4163  test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4164  INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
4165  0, 0);
4166 
4167  test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
4168  INTERFACE_USES_DISPEX, 0,
4169  0, 0);
4170 
4171  test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
4172  0, INTERFACE_USES_DISPEX,
4173  0, 0);
4174 
4175  /* set option masking */
4176 
4177  test_IObjectSafety_set(safety, S_OK, S_OK,
4178  INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4179  INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4180  INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4181  INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4182 
4183  test_IObjectSafety_set(safety, S_OK, S_OK,
4184  INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4185  INTERFACESAFE_FOR_UNTRUSTED_DATA,
4186  INTERFACESAFE_FOR_UNTRUSTED_DATA,
4187  INTERFACESAFE_FOR_UNTRUSTED_DATA);
4188 
4189  test_IObjectSafety_set(safety, S_OK, S_OK,
4190  INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
4191  INTERFACE_USES_SECURITY_MANAGER,
4192  0,
4193  0);
4194 
4195  /* set -- inheriting previous settings */
4196 
4197  hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4198  INTERFACESAFE_FOR_UNTRUSTED_CALLER,
4199  INTERFACESAFE_FOR_UNTRUSTED_CALLER);
4200  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4201  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4202  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4203  ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled);
4204  ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4205  supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4206  "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4207  "got %08x\n", supported);
4208 
4209  hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
4210  INTERFACESAFE_FOR_UNTRUSTED_DATA,
4211  INTERFACESAFE_FOR_UNTRUSTED_DATA);
4212  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4213  hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
4214  ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
4215  ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
4216  enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA),
4217  "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled);
4218  ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
4219  supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
4220  "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
4221  "got %08x\n", supported);
4222 }
4223 
4224 static void test_IXMLDOMDocument2(void)
4225 {
4226  static const WCHAR emptyW[] = {0};
4227  IXMLDOMDocument2 *doc2, *dtddoc2;
4228  IXMLDOMDocument *doc;
4230  IDispatchEx *dispex;
4231  VARIANT_BOOL b;
4232  VARIANT var;
4233  HRESULT r;
4234  LONG res;
4235 
4236  if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
4237 
4238  doc = create_document(&IID_IXMLDOMDocument);
4239  dtddoc2 = create_document(&IID_IXMLDOMDocument2);
4240 
4241  r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
4242  ok( r == S_OK, "ret %08x\n", r );
4243  ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
4244 
4245  ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
4246  ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
4247  ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4248 
4249  err = NULL;
4250  ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
4251  ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4252  ok(err != NULL, "expected a pointer\n");
4253  if (err)
4254  {
4255  res = 0;
4256  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4257  /* XML_E_NOTWF */
4258  ok(res == E_XML_NOTWF, "got %08x\n", res);
4259  IXMLDOMParseError_Release(err);
4260  }
4261 
4262  r = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b );
4263  ok( r == S_OK, "loadXML failed\n");
4264  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4265 
4266  ole_check(IXMLDOMDocument_get_readyState(doc, &res));
4267  ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
4268 
4269  err = NULL;
4270  ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
4271  ok(err != NULL, "expected a pointer\n");
4272  if (err)
4273  {
4274  res = 0;
4275  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4276  /* XML_E_NODTD */
4277  ok(res == E_XML_NODTD, "got %08x\n", res);
4278  IXMLDOMParseError_Release(err);
4279  }
4280 
4281  r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
4282  ok( r == S_OK, "ret %08x\n", r );
4283  if(r == S_OK)
4284  {
4285  IDispatchEx_Release(dispex);
4286  }
4287 
4288  /* we will check if the variant got cleared */
4289  IXMLDOMDocument2_AddRef(doc2);
4290  EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
4291 
4292  V_VT(&var) = VT_UNKNOWN;
4293  V_UNKNOWN(&var) = (IUnknown *)doc2;
4294 
4295  /* invalid calls */
4296  ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
4297  expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
4298  ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
4299 
4300  /* valid call */
4301  ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4302  expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4303  expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4304  V_VT(&var) = VT_R4;
4305 
4306  /* the variant didn't get cleared*/
4307  expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
4308 
4309  /* setProperty tests */
4310  ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
4311  ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
4312  ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
4313  ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4314  ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4315  ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
4316 
4317  V_VT(&var) = VT_BSTR;
4318  V_BSTR(&var) = SysAllocString(emptyW);
4319  r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4320  ok(r == S_OK, "got 0x%08x\n", r);
4321  VariantClear(&var);
4322 
4323  V_VT(&var) = VT_I2;
4324  V_I2(&var) = 0;
4325  r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
4326  ok(r == E_FAIL, "got 0x%08x\n", r);
4327 
4328  /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
4329  ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
4330  expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4331  expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
4332 
4333  IXMLDOMDocument2_Release( doc2 );
4334  IXMLDOMDocument_Release( doc );
4335 
4336  /* DTD validation */
4337  ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
4338  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
4339  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4340  err = NULL;
4341  ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
4342  ok(err != NULL, "expected pointer\n");
4343  if (err)
4344  {
4345  res = 0;
4346  ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
4347  ok(res == 0, "got %08x\n", res);
4348  IXMLDOMParseError_Release(err);
4349  }
4350 
4351  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
4352  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4353  err = NULL;
4354  ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4355  ok(err != NULL, "expected pointer\n");
4356  if (err)
4357  {
4358  res = 0;
4359  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4360  /* XML_ELEMENT_UNDECLARED */
4361  todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
4362  IXMLDOMParseError_Release(err);
4363  }
4364 
4365  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
4366  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4367  err = NULL;
4368  ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4369  ok(err != NULL, "expected pointer\n");
4370  if (err)
4371  {
4372  res = 0;
4373  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4374  /* XML_ELEMENT_ID_NOT_FOUND */
4375  todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
4376  IXMLDOMParseError_Release(err);
4377  }
4378 
4379  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
4380  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4381  err = NULL;
4382  ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4383  ok(err != NULL, "expected pointer\n");
4384  if (err)
4385  {
4386  res = 0;
4387  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4388  /* XML_EMPTY_NOT_ALLOWED */
4389  todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
4390  IXMLDOMParseError_Release(err);
4391  }
4392 
4393  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
4394  ok( b == VARIANT_TRUE, "failed to load XML string\n");
4395  err = NULL;
4396  ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
4397  ok(err != NULL, "expected pointer\n");
4398  if (err)
4399  {
4400  res = 0;
4401  ole_check(IXMLDOMParseError_get_errorCode(err, &res));
4402  /* XML_ROOT_NAME_MISMATCH */
4403  todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
4404  IXMLDOMParseError_Release(err);
4405  }
4406 
4407  ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
4408  ok( b == VARIANT_TRUE,