ReactOS 0.4.16-dev-13-ge2fc578
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
49DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
50DEFINE_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
76static 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 < ARRAY_SIZE(table->ifaces) && 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 < ARRAY_SIZE(table->ifaces) && 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
136typedef struct
137{
140} dispevent;
141
143{
144 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
145}
146
148{
149 *ppvObject = NULL;
150
151 if ( IsEqualGUID( riid, &IID_IDispatch) ||
153 {
154 *ppvObject = iface;
155 }
156 else
157 return E_NOINTERFACE;
158
159 IDispatch_AddRef( iface );
160
161 return S_OK;
162}
163
165{
167 return InterlockedIncrement( &This->ref );
168}
169
171{
174
175 if (ref == 0)
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
203 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
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
220 return E_FAIL;
221}
222
223static 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) ||
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
274static 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
325static 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
337static const IStreamVtbl StreamVtbl = {
352};
353
355
357{
358 if (IsEqualIID(&IID_IResponse, 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
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
401 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr)
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
419static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet)
420{
421 ok(0, "unexpected call\n");
422 return E_NOTIMPL;
423}
424
425static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType)
426{
427 ok(0, "unexpected call\n");
428 return E_NOTIMPL;
429}
430
431static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet)
432{
433 ok(0, "unexpected call\n");
434 return E_NOTIMPL;
435}
436
437static 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
461static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet)
462{
463 ok(0, "unexpected call\n");
464 return E_NOTIMPL;
465}
466
468{
469 ok(0, "unexpected call\n");
470 return E_NOTIMPL;
471}
472
473static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName)
474{
475 ok(0, "unexpected call\n");
476 return E_NOTIMPL;
477}
478
479static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue)
480{
481 ok(0, "unexpected call\n");
482 return E_NOTIMPL;
483}
484
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
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
545static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber)
546{
547 ok(0, "unexpected call\n");
548 return E_NOTIMPL;
549}
550
552{
553 ok(0, "unexpected call\n");
554 return E_NOTIMPL;
555}
556
557static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet)
558{
559 ok(0, "unexpected call\n");
560 return E_NOTIMPL;
561}
562
564{
565 ok(0, "unexpected call\n");
566 return E_NOTIMPL;
567}
568
569static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue)
570{
571 ok(0, "unexpected call\n");
572 return E_NOTIMPL;
573}
574
575static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl)
576{
577 ok(0, "unexpected call\n");
578 return E_NOTIMPL;
579}
580
581static 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
611static const IResponseVtbl testresponsevtbl =
612{
651};
652
654
655#define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
657{
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{
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__)
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
708static const WCHAR szEmpty[] = { 0 };
709static const WCHAR szIncomplete[] = {
710 '<','?','x','m','l',' ',
711 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
712};
713static 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};
718static const WCHAR szComplete2[] = {
719 '<','?','x','m','l',' ',
720 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
721 '<','a','>','<','/','a','>','\n',0
722};
723static 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
740static 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
754static 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
760static 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
772static const char win1252xml[] =
774"<open></open>";
775
776static const char win1252decl[] =
778;
779
780static const char nocontent[] = "no xml content here";
781
782static 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
821static 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
828static 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
852static const CHAR szTransformXML[] =
853"<?xml version=\"1.0\"?>\n"
854"<greeting>\n"
855"Hello World\n"
856"</greeting>";
857
858static 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
875static const CHAR szTransformOutput[] =
876"<html><body><h1>"
877"Hello World"
878"</h1></body></html>";
879
880static 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
936static const CHAR szBasicTransformXML[] =
937"<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
938
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
963static 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
978static 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
994static 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
1009static 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
1023static 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
1038static 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
1051static 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
1066static 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
1081static 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
1096static 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
1112static 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
1127static 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
1136static 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
1142static const char attributes_map[] = {
1143 "<?xml version=\"1.0\"?>"
1144 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
1145};
1146
1147static const WCHAR nonexistent_fileW[] = {
1148 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
1149};
1150static 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};
1153static const WCHAR szDocument[] = {
1154 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
1155};
1156
1157static const WCHAR szOpen[] = { 'o','p','e','n',0 };
1158static const WCHAR szdl[] = { 'd','l',0 };
1159static const WCHAR szvr[] = { 'v','r',0 };
1160static const WCHAR szlc[] = { 'l','c',0 };
1161static const WCHAR szbs[] = { 'b','s',0 };
1162static const WCHAR szstr1[] = { 's','t','r','1',0 };
1163static const WCHAR szstr2[] = { 's','t','r','2',0 };
1164static const WCHAR szstar[] = { '*',0 };
1165static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
1166
1167static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
1168static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
1169static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
1170
1171static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
1172static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
1173static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
1174static 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 };
1176static 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
1179static const WCHAR szAttribute[] = {'A','t','t','r',0 };
1180static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
1181
1182static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
1183 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
1184static 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};
1187static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
1188static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
1189
1190static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
1191static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
1192static 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
1215static 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
1233static 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 */
1238 return ret;
1239}
1240
1243
1244static BSTR _bstr_(const char *str)
1245{
1249}
1250
1251static void free_bstrs(void)
1252{
1253 int i;
1254 for (i = 0; i < alloced_bstrs_count; i++)
1257}
1258
1259static 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
1267static 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
1327{
1328 HRESULT r = S_OK;
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));
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);
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 {
1393 if (i > 0)
1394 *(pos++) = ' ';
1395 ole_check(IXMLDOMNodeList_nextNode(list, &node));
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
1428static 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
1439static void test_domdoc( void )
1440{
1441 HRESULT r, hr;
1442 IXMLDOMDocument *doc;
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;
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
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);
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
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
1526if (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 );
1535
1536 b = VARIANT_TRUE;
1537 hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
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;
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;
1578 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1579 ok( r == S_FALSE, "ret %08x\n", r );
1580 SysFreeString( str );
1581
1582 b = VARIANT_TRUE;
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;
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;
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;
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
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");
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");
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");
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");
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");
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");
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) );
1809
1810 /* test insertData */
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 );
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) );
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) );
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) );
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) );
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;
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) );
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) );
1944
1945 /* ::replaceData() */
1946 V_VT(&var) = VT_BSTR;
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) );
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) );
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) );
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) );
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) );
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) );
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) );
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) );
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);
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);
2042
2044 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
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 */
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);
2075
2076 /* test Processing Instruction */
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 );
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");
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");
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");
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");
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 );
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
2150static 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
2194static void test_domnode( void )
2195{
2196 HRESULT r;
2197 IXMLDOMDocument *doc, *owner = NULL;
2200 IXMLDOMNode *node = NULL, *next = NULL;
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
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");
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);
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
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 */
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 {
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 {
2429
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");
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;
2481 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2483 ok( r == S_FALSE, "ret %08x\n", r );
2484 ok( node == NULL, "node %p\n", node );
2485
2487 r = IXMLDOMElement_selectSingleNode( element, str, &node );
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 {
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
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");
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;
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
2577typedef struct {
2581
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 },
2592};
2593
2594static 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;
2604 HRESULT hr;
2605 LONG ref;
2606
2607 doc = create_document(&IID_IXMLDOMDocument);
2608
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);
2630todo_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);
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);
2715todo_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);
2736todo_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);
2749todo_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);
2785todo_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);
2791todo_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
2798todo_wine {
2799 EXPECT_REF(doc, 1);
2800 EXPECT_REF(element, 2);
2801 EXPECT_REF(elem2, 2);
2802}
2803 IXMLDOMElement_AddRef(element);
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);
2811todo_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);
2817todo_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
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
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);
2876 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2877 EXPECT_HR(hr, S_OK);
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 );
2886
2887 IXMLDOMElement_Release( element );
2888
2889 free_bstrs();
2890}
2891
2892static 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;
2903 IXMLDOMCDATASection *cdata;
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;
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;
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;
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);
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);
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);
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);
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);
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);
3040
3041 /* NODE_CDATA_SECTION */
3042 V_VT(&var) = VT_I1;
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);
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);
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);
3089
3090 /* NODE_ATTRIBUTE */
3091 V_VT(&var) = VT_I1;
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;
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;
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 );
3112
3113 /* a name is required for attribute, try a BSTR with first null wchar */
3114 V_VT(&var) = VT_I1;
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);
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;
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;
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;
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;
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;
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;
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);
3300
3301 V_VT(&var) = VT_BSTR;
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);
3314
3315 V_VT(&var) = VT_I4;
3316 V_I4(&var) = 10;
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"